【问题标题】:Setting SQL Variable via Dynamic SQL通过动态 SQL 设置 SQL 变量
【发布时间】:2021-12-02 06:07:53
【问题描述】:

我知道我想太多了,但我已经反对这个太久了,所以我正在寻求帮助。

这是我要运行的语句:SELECT @cntMax = MAX(id) FROM [Raw_Item-FieldReport] 但是,表名是变量@reportTable

这不起作用:

SET @sql = 'SELECT @cntMax = MAX(id) FROM @reportTable'
EXEC sp_executesql @sql

我什至尝试在SET @sql 中使用实际的表名,但这也不起作用。 我没想到会这么难,请告诉我我遗漏了一些简单/明显的东西。

这里有完整的代码供需要的人使用:

DECLARE
    @inTable nvarchar(255) = 'Raw_Item',
    @reportTable nvarchar(255),
    @fieldName nvarchar(255),
    @cnt int,
    @cntMax int,
    @sql nvarchar(max)

SET @reportTable = @inTable + '-FieldReport'

SET @cnt = 1
SELECT @cntMax = MAX(id) FROM [Raw_Item-FieldReport]
PRINT @cntMax
SET @cntMax = 0

SET @sql = 'SELECT @cntMax = MAX(id) FROM [Raw_Item-FieldReport]'
EXEC sp_executesql @sql
PRINT @cntMax

SQL Server 12.0.2008.8(在 Azure 上)

【问题讨论】:

  • 动态表名肯定有问题。您不能参数化对象名称。您必须创建一个具有正确表名的字符串。这通常是一些设计问题的迹象。

标签: sql sql-server variables dynamic-sql


【解决方案1】:

您需要使用输出参数,否则SQL Server 不知道如何将动态SQL 中的@cntMax 连接到动态SQL 中的@cntMax ,因为它们是不同的范围。为了保护自己免受 SQL 注入(一些提示 herehere),请始终检查您的对象是否存在,并使用 QUOTENAME() 而不是手动添加方括号(并且在构建对象时应该始终使用 QUOTENAME()来自用户输入或变量的名称,即使它们没有破折号等坏字符):

DECLARE @sql         nvarchar(max),
        @inTable     nvarchar(255) = N'Raw_Item',
        @reportTable nvarchar(255);

SET @reportTable = N'dbo.' + QUOTENAME(@inTable + '-FieldReport');

IF OBJECT_ID(@reportTable) IS NOT NULL
BEGIN
  SET @sql = N'SELECT @cntMax = MAX(id) FROM ' + @reportTable + N';';

  EXEC sys.sp_executesql @sql,
           N'@cntMax int output', 
           @cntMax = @cntMax OUTPUT;

  PRINT @cntMax;
END
ELSE
BEGIN
  PRINT 'Nice try, h@xx0rs!';
END

Always use schema reference (dbo)、always use statement terminators,请尽量避免使用破折号 (-) 等无效标识符字符命名事物。还有一个提示:始终在N'nvarchar string literals' 上使用N 前缀。

【讨论】:

  • 谢谢,效果很好。感谢您的提示,我已将它们合并到项目中:D
猜你喜欢
  • 1970-01-01
  • 2019-04-08
  • 2015-03-13
  • 2014-08-16
  • 1970-01-01
  • 1970-01-01
  • 2016-10-27
  • 2010-10-16
  • 1970-01-01
相关资源
最近更新 更多