用光标和变量更新表

时间:2016-01-22 16:07:50

标签: sql sql-server sql-update cursor

我想使用游标来更新我拥有的表,但我没有运气。这就是为什么我想使用一个游标,我不必花费数小时编写100个更新语句。这是我目前的代码:

DECLARE @COLUMN_NAME VARCHAR(10)
DECLARE A_Cursor CURSOR
    FOR
        SELECT column_name
        FROM TPP_DB.INFORMATION_SCHEMA.columns
        WHERE table_name = 'Master File'
            AND column_name LIKE 'F%'
            AND LEN(column_name) <= 4
            AND column_name NOT IN ('F61', 'F62') --FOR UPDATE OF [TPP_DB].[dbo].[Master File]

OPEN A_Cursor
FETCH NEXT FROM A_Cursor INTO @COLUMN_NAME

WHILE @@fetch_status = 0
BEGIN

    PRINT @COLUMN_NAME

    UPDATE TPP_DB.dbo.[Master File]
    SET @COLUMN_NAME = NULL
    WHERE @COLUMN_NAME = ''

    FETCH NEXT FROM A_Cursor INTO @COLUMN_NAME

END

CLOSE A_Cursor
DEALLOCATE A_Cursor

我遇到的主要问题是我的变量@COLUMN_NAME没有加载到更新语句中,但是当我打印它时,我得到了正确的值。我希望将变量读入SETWHERE子句,以便我可以一次更新所需的所有表。任何其他建议也会很精彩。

2 个答案:

答案 0 :(得分:1)

USE TPP_DB
GO

DECLARE @SQL NVARCHAR(MAX)

SELECT @SQL = (
    SELECT '
UPDATE ' + QUOTENAME(SCHEMA_NAME(o.[schema_id])) + '.' + QUOTENAME(o.name) + '
SET ' + QUOTENAME(c.name) + ' = NULL
WHERE ' + QUOTENAME(c.name) + ' = ''''' 
    FROM sys.columns c
    JOIN sys.objects o ON c.[object_id] = o.[object_id]
    WHERE o.name = 'MasterFile' 
        AND c.name LIKE 'F%' 
        AND c.name NOT IN ('F61','F62')
        AND o.[type] = 'U'
    FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')

PRINT @SQL
EXEC sys.sp_executesql @SQL

输出 -

UPDATE [dbo].[tbl]
SET col = NULL
WHERE col = ''
...

答案 1 :(得分:1)

你需要动态的sql,比如......

DECLARE @Sql NVARCHAR(MAX) , @COLUMN_NAME SYSNAME;
DECLARE A_Cursor CURSOR FOR 

SELECT COLUMN_NAME 
FROM TPP_DB.INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME = 'Master File' 
    AND COLUMN_NAME LIKE 'F%' 
    AND LEN(COLUMN_NAME) <= 4 
    AND COLUMN_NAME NOT IN ('F61','F62') --FOR UPDATE OF [TPP_DB].[dbo].[Master File]

OPEN A_Cursor
FETCH NEXT FROM A_Cursor  INTO @COLUMN_NAME

WHILE @@FETCH_STATUS = 0
BEGIN 

PRINT @COLUMN_NAME

SET @Sql = N' UPDATE TPP_DB.dbo.[Master File]
               SET ' + QUOTENAME(@COLUMN_NAME) + ' = NULL
              WHERE ' + QUOTENAME(@COLUMN_NAME) + ' = '''' '

  Exec sp_executesql @Sql

FETCH NEXT FROM A_Cursor INTO @COLUMN_NAME

END


CLOSE A_Cursor
DEALLOCATE A_Cursor