如何执行存储在table(查询)中的查询(更新)?
How to execute query (update) stored in table (query)?
我正在尝试执行此查询的结果。
SELECT 'UPDATE [' + TABLE_SCHEMA + '].[' + TABLE_NAME + '] ' + 'SET [' + COLUMN_NAME + '] = RTRIM(LTRIM(SUBSTRING ([' + COLUMN_NAME + '], 2 , LEN ([' + COLUMN_NAME + ']) - 2) )) WHERE LEFT([' + COLUMN_NAME + '], 1) = ' + '''"''' + ' AND RIGHT([' + COLUMN_NAME + '], 1) = ' + '''"'''
FROM INFORMATION_SCHEMA.COLUMNS
WHERE DATA_TYPE IN ('varchar', 'nvarchar')
ORDER BY TABLE_NAME, COLUMN_NAME
它return多了一行。例如:
UPDATE [dbo].[ACCDB] SET [ACODI] = RTRIM(LTRIM(SUBSTRING ([ACODI], 2 , LEN ([ACODI]) - 2) )) WHERE LEFT([ACODI], 1) = '"' AND RIGHT([ACODI], 1) = '"'
UPDATE [dbo].[ANAGP] SET [CDIVA] = RTRIM(LTRIM(SUBSTRING ([CDIVA], 2 , LEN ([CDIVA]) - 2) )) WHERE LEFT([CDIVA], 1) = '"' AND RIGHT([CDIVA], 1) = '"'
现在,我如何以编程方式执行这一行?没有我在存储过程中写每一行?
谢谢,我等答案。
我建议使用 CURSOR 逐行执行。
看看我在 dba.stackexchange.com 上对类似问题的回答。
Restore all IDENTITY seeds (out of sync since database restore)
您在这里尝试做的是动态的SQL;即时构建您的查询。有很多方法可以做到这一点。由于您正在构建多个语句,因此您需要能够一次执行一个。 McNets 的回答建议使用游标,这是一种常用的方法来完成您想要的操作。另一种方法是用循环分解语句,然后一个接一个地执行它们。
下面的代码首先获取 table 个名称的列表,定义我们最终可能有多少语句。大多数情况下,ID 列是我们在这里关心的。然后有一个 WHILE 循环到 运行 你的查询,每个 table,并检查以确保我们需要为那个 table 执行语句。
DECLARE @SqlText NVARCHAR(2000) --Variable to hold your query
,@Counter INT --Counter to keep track of where we are in the loop
,@EndLoop INT; --Value to stop the loop
DECLARE @TblList TABLE (
[ID] INT IDENTITY(1,1)
,[Schema] NVARCHAR(128)
,[Table] NVARCHAR(128));
INSERT INTO @TblList ([Schema],[Table])
SELECT
TABLE_SCHEMA
,TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES;
SELECT @Counter = MIN([ID]), @EndLoop = MAX([ID])
FROM @TblList;
WHILE @Counter <= @EndLoop
BEGIN
IF EXISTS ( --If there are no character columns, skip the table
SELECT 1
FROM INFORMATION_SCHEMA.COLUMNS AS col JOIN @TblList AS tbl
ON tbl.[Schema] = col.TABLE_SCHEMA
AND tbl.[Table] = col.TABLE_NAME
AND tbl.[ID] = @Counter
AND col.DATA_TYPE IN ('varchar', 'nvarchar')
)
BEGIN
--Construct the query
SELECT @SqlText = CAST('UPDATE [' + col.TABLE_SCHEMA + '].[' + col.TABLE_NAME + '] ' + 'SET [' + col.COLUMN_NAME + '] = RTRIM(LTRIM(SUBSTRING ([' + col.COLUMN_NAME + '], 2 , LEN ([' + col.COLUMN_NAME + ']) - 2) )) WHERE LEFT([' + col.COLUMN_NAME + '], 1) = ' + '''"''' + ' AND RIGHT([' + col.COLUMN_NAME + '], 1) = ' + '''"''' AS NVARCHAR(2000))
FROM INFORMATION_SCHEMA.COLUMNS AS col
JOIN @TblList AS tbl
ON tbl.[Schema] = col.TABLE_SCHEMA
AND tbl.[Table] = col.TABLE_NAME
AND tbl.[ID] = @Counter
AND col.DATA_TYPE IN ('varchar', 'nvarchar');
--Run the query
EXEC sp_executesql @SQL;
END
--Increment the counter to move through the table list
SET @Counter = @Counter + 1;
END
DECLARE @c_Statement VARCHAR(MAX)
DECLARE StatementCursor CURSOR FOR
SELECT 'UPDATE [' + TABLE_SCHEMA + '].[' + TABLE_NAME + '] ' + 'SET [' + COLUMN_NAME + '] = RTRIM(LTRIM(SUBSTRING ([' + COLUMN_NAME + '], 2 , LEN ([' + COLUMN_NAME + ']) - 2) )) WHERE LEFT([' + COLUMN_NAME + '], 1) = ' + '''"''' + ' AND RIGHT([' + COLUMN_NAME + '], 1) = ' + '''"'''
FROM INFORMATION_SCHEMA.COLUMNS
WHERE DATA_TYPE IN ('varchar', 'nvarchar')
ORDER BY TABLE_NAME, COLUMN_NAME
OPEN StatementCursor
FETCH NEXT FROM StatementCursor INTO @c_Statement
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC(@c_Statement)
FETCH NEXT FROM StatementCursor INTO @c_Statement
END
CLOSE StatementCursor
DEALLOCATE StatementCursor
您可能想要检查 QUOTENAME() 函数以将对象名称用引号引起来而不是 hard-coding 在表达式中。您还需要检查错误 (TRY/CATCH) 并验证您的用户权限以更新结果行。
如果您有多个数据库,INFORMATION_SCHEMA.COLUMNS 只会列出当前连接中的数据库。
我正在尝试执行此查询的结果。
SELECT 'UPDATE [' + TABLE_SCHEMA + '].[' + TABLE_NAME + '] ' + 'SET [' + COLUMN_NAME + '] = RTRIM(LTRIM(SUBSTRING ([' + COLUMN_NAME + '], 2 , LEN ([' + COLUMN_NAME + ']) - 2) )) WHERE LEFT([' + COLUMN_NAME + '], 1) = ' + '''"''' + ' AND RIGHT([' + COLUMN_NAME + '], 1) = ' + '''"'''
FROM INFORMATION_SCHEMA.COLUMNS
WHERE DATA_TYPE IN ('varchar', 'nvarchar')
ORDER BY TABLE_NAME, COLUMN_NAME
它return多了一行。例如:
UPDATE [dbo].[ACCDB] SET [ACODI] = RTRIM(LTRIM(SUBSTRING ([ACODI], 2 , LEN ([ACODI]) - 2) )) WHERE LEFT([ACODI], 1) = '"' AND RIGHT([ACODI], 1) = '"'
UPDATE [dbo].[ANAGP] SET [CDIVA] = RTRIM(LTRIM(SUBSTRING ([CDIVA], 2 , LEN ([CDIVA]) - 2) )) WHERE LEFT([CDIVA], 1) = '"' AND RIGHT([CDIVA], 1) = '"'
现在,我如何以编程方式执行这一行?没有我在存储过程中写每一行?
谢谢,我等答案。
我建议使用 CURSOR 逐行执行。
看看我在 dba.stackexchange.com 上对类似问题的回答。
Restore all IDENTITY seeds (out of sync since database restore)
您在这里尝试做的是动态的SQL;即时构建您的查询。有很多方法可以做到这一点。由于您正在构建多个语句,因此您需要能够一次执行一个。 McNets 的回答建议使用游标,这是一种常用的方法来完成您想要的操作。另一种方法是用循环分解语句,然后一个接一个地执行它们。
下面的代码首先获取 table 个名称的列表,定义我们最终可能有多少语句。大多数情况下,ID 列是我们在这里关心的。然后有一个 WHILE 循环到 运行 你的查询,每个 table,并检查以确保我们需要为那个 table 执行语句。
DECLARE @SqlText NVARCHAR(2000) --Variable to hold your query
,@Counter INT --Counter to keep track of where we are in the loop
,@EndLoop INT; --Value to stop the loop
DECLARE @TblList TABLE (
[ID] INT IDENTITY(1,1)
,[Schema] NVARCHAR(128)
,[Table] NVARCHAR(128));
INSERT INTO @TblList ([Schema],[Table])
SELECT
TABLE_SCHEMA
,TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES;
SELECT @Counter = MIN([ID]), @EndLoop = MAX([ID])
FROM @TblList;
WHILE @Counter <= @EndLoop
BEGIN
IF EXISTS ( --If there are no character columns, skip the table
SELECT 1
FROM INFORMATION_SCHEMA.COLUMNS AS col JOIN @TblList AS tbl
ON tbl.[Schema] = col.TABLE_SCHEMA
AND tbl.[Table] = col.TABLE_NAME
AND tbl.[ID] = @Counter
AND col.DATA_TYPE IN ('varchar', 'nvarchar')
)
BEGIN
--Construct the query
SELECT @SqlText = CAST('UPDATE [' + col.TABLE_SCHEMA + '].[' + col.TABLE_NAME + '] ' + 'SET [' + col.COLUMN_NAME + '] = RTRIM(LTRIM(SUBSTRING ([' + col.COLUMN_NAME + '], 2 , LEN ([' + col.COLUMN_NAME + ']) - 2) )) WHERE LEFT([' + col.COLUMN_NAME + '], 1) = ' + '''"''' + ' AND RIGHT([' + col.COLUMN_NAME + '], 1) = ' + '''"''' AS NVARCHAR(2000))
FROM INFORMATION_SCHEMA.COLUMNS AS col
JOIN @TblList AS tbl
ON tbl.[Schema] = col.TABLE_SCHEMA
AND tbl.[Table] = col.TABLE_NAME
AND tbl.[ID] = @Counter
AND col.DATA_TYPE IN ('varchar', 'nvarchar');
--Run the query
EXEC sp_executesql @SQL;
END
--Increment the counter to move through the table list
SET @Counter = @Counter + 1;
END
DECLARE @c_Statement VARCHAR(MAX)
DECLARE StatementCursor CURSOR FOR
SELECT 'UPDATE [' + TABLE_SCHEMA + '].[' + TABLE_NAME + '] ' + 'SET [' + COLUMN_NAME + '] = RTRIM(LTRIM(SUBSTRING ([' + COLUMN_NAME + '], 2 , LEN ([' + COLUMN_NAME + ']) - 2) )) WHERE LEFT([' + COLUMN_NAME + '], 1) = ' + '''"''' + ' AND RIGHT([' + COLUMN_NAME + '], 1) = ' + '''"'''
FROM INFORMATION_SCHEMA.COLUMNS
WHERE DATA_TYPE IN ('varchar', 'nvarchar')
ORDER BY TABLE_NAME, COLUMN_NAME
OPEN StatementCursor
FETCH NEXT FROM StatementCursor INTO @c_Statement
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC(@c_Statement)
FETCH NEXT FROM StatementCursor INTO @c_Statement
END
CLOSE StatementCursor
DEALLOCATE StatementCursor
您可能想要检查 QUOTENAME() 函数以将对象名称用引号引起来而不是 hard-coding 在表达式中。您还需要检查错误 (TRY/CATCH) 并验证您的用户权限以更新结果行。
如果您有多个数据库,INFORMATION_SCHEMA.COLUMNS 只会列出当前连接中的数据库。