首页 > 解决方案 > 如何使用变量创建动态更新查询?

问题描述

我正在尝试使用一些变量创建以下动态更新查询,并且由于某种原因,它在存储过程中不起作用。有人可以向我建议我在哪里做错了,以及避免 SQL 注入的最佳做法是什么?

    DECLARE @SQL NVARCHAR(MAX)
    DECLARE @COLUMN1 NVARCHAR(10)
    DECLARE @COLUMN2 NVARCHAR(10)
    DECLARE @TABLENAME NVARCHAR(10)

    SET @SQL = 'UPDATE TL
                SET '+ @COLUMN1 + '= AB.COLUMN1,'
                    + @COLUMN2 + '= AB.COLUMN2
                FROM' + @TABLENAME + ' TL
                JOIN ABACUS AB
                ON TL.REF = AB.REF
                AND TL.SUBS = AB.SUBS
                WHERE ' + @COLUMN1 + ' IS NULL
                AND ' + @COLUMN2 +' IS NULL';

    SET @COLUMN1 = (SELECT CONCAT('USER_ID', '8'))
    SET @COLUMN2 = (SELECT CONCAT('USER_ID', '6'))
    SET @TABLENAME = 'POLICYREF';
    EXEC sys.sp_executesql @SQL, @TABLENAME, @COLUMN1, @COLUMN2;

    SET @TABLENAME = 'USERREF';
    EXEC sys.sp_executesql @SQL, @TABLENAME, @COLUMN1, @COLUMN2;

标签: sqlsql-server

解决方案


您需要动态 SQL,而不是参数。您不能参数化列名或表名。所以像:

DECLARE @SQL NVARCHAR(MAX)
DECLARE @COLUMN1 NVARCHAR(10) = 'USER_ID8'
DECLARE @COLUMN2 NVARCHAR(10) = 'USER_ID6'
DECLARE @TABLENAME NVARCHAR(10) = 'POLICYREF'

SET @SQL = 'UPDATE TL
            SET '+ quotename(@COLUMN1) + '= AB.COLUMN1,'
                 + quotename(@COLUMN2) + '= AB.COLUMN2
            FROM ' + quotename(@TABLENAME) + ' TL
            JOIN ABACUS AB
            ON TL.REF = AB.REF
            AND TL.SUBS = AB.SUBS
            WHERE ' + quotename(@COLUMN1) + ' IS NULL
            AND ' + quotename(@COLUMN2) +' IS NULL';

EXEC (@SQL)

SET @TABLENAME NVARCHAR(10) = 'USERREF'
SET @SQL = 'UPDATE TL
            SET '+ quotename(@COLUMN1) + '= AB.COLUMN1,'
                 + quotename(@COLUMN2) + '= AB.COLUMN2
            FROM ' + quotename(@TABLENAME) + ' TL
            JOIN ABACUS AB
            ON TL.REF = AB.REF
            AND TL.SUBS = AB.SUBS
            WHERE ' + quotename(@COLUMN1) + ' IS NULL
            AND ' + quotename(@COLUMN2) +' IS NULL';


EXEC (@SQL)

推荐阅读