如何执行存储在表(查询)中的查询(更新)?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何执行存储在表(查询)中的查询(更新)?相关的知识,希望对你有一定的参考价值。
我正在尝试执行此查询的结果。
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
它返回更多一行。例如:
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) = '"'
现在,我如何以编程方式执行此行?没有我写存储过程中的每一行?
谢谢,我等了回答。
答案
你在这里要做的是动态SQL;动态构建您的查询。有很多方法可以做到这一点。由于您正在构建多个语句,因此您需要能够一次执行一个语句。 McNets的回答建议使用光标,这是一种常用的方式来完成你所追求的目标。另一种方法是用循环分解你的语句,然后一个接一个地执行它们。
下面的代码首先获取一个表名列表,定义我们最终可能会有多少语句。大多数情况下,ID列是我们在这里关心的。然后有一个WHILE循环为每个表运行一次查询,并检查以确保我们需要执行该表的语句。
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
另一答案
我建议使用CURSOR逐行执行它。
看看我在dba.stackexchange.com上的答案中的一个类似问题。
Restore all IDENTITY seeds (out of sync since database restore)
另一答案
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()函数以将对象名称包装在引号中,而不是在表达式中对它们进行硬编码。您还需要检查错误(TRY / CATCH)并验证您的用户权限以更新结果行。
如果您有多个数据库,INFORMATION_SCHEMA.COLUMNS将仅列出当前连接中的数据库。
以上是关于如何执行存储在表(查询)中的查询(更新)?的主要内容,如果未能解决你的问题,请参考以下文章
PostgreSQL PL/pgSQL:存储在表中的查询(营业时间)