安全上下文中的动态TSQL

Pet*_*nge 1 t-sql sql-server dynamic-sql

我有一个数据库,其中登录数据库的主用户没有直接对任何表的权限.用户需要执行已明确授予它的存储过程.这涵盖了所需的任何简单的CRUD操作.但是现在,我需要动态执行SQL,但我希望在用户上保持相同的安全级别.一个例子是

UPDATE [Table] SET [Column 1] = @Column1 
Run Code Online (Sandbox Code Playgroud)

但在这种情况下[第1列]及其值将在运行时设置.

我知道在存储过程中执行动态代码的唯一方法是使用sp_runsql,但是出于安全原因,创建使用sp_runsql执行动态查询的存储过程会失败(并且通常不是很聪明)

任何人都可以想到一种实现这种功能和安全性的方法吗?

OMG*_*ies 5

在TSQL中动态定义列名的唯一方法是使用字符串连接:

DECLARE @SQL = 'UPDATE [your_table] 
                   SET '+ @ColumnName + ' = @ColumnValue '

BEGIN

  EXEC sp_executesql @SQL, 
                     N'@ColumnValue INT',
                     @ColumnValue        

END
Run Code Online (Sandbox Code Playgroud)

...因为你使用过:

DECLARE @SQL = 'UPDATE [your_table] 
                   SET @ColumnName = @ColumnValue '
Run Code Online (Sandbox Code Playgroud)

...你会发现动态SQL会以逗号分隔@ColumnName值.

需要注意的是,虽然存储过程意味着参数化查询,但不会使您与SQL注入隔离.

考虑的替代方案

EXECUTE AS可能是一个更好的选择,所以存储过程可以用别人的特权来执行.它更安全,不会提供SQL注入的风险.