有人可以解释为什么这不起作用:
DECLARE @PROCESS_TABLE varchar(100) = 'Table Name'
DECLARE @SRIDCount int
EXEC('SELECT ' + @SRIDCount + ' = COUNT(DISTINCT Geom.STSrid) FROM ' + @PROCESS_TABLE + '')
Print @SRIDCount
Incorrect syntax near '='.
但这样做:
DECLARE @PROCESS_TABLE varchar(100) = 'Table Name'
DECLARE @SRIDCount int
DECLARE @SQLString nvarchar(max)
SET @SQLString = 'SELECT @SRIDCount = COUNT(DISTINCT Geom.STSrid) FROM ' + @PROCESS_TABLE + ''
EXECUTE SP_executesql @SQLString, N'@SRIDCount int OUTPUT', @SRIDCount = @SRIDCount OUTPUT
Print @SRIDCount
1
大多数情况下,我想了解为什么我不能在exec()中设置变量。通过比较使用SP_executesql似乎很麻烦和复杂,到目前为止我已经没有使用它了。
答案 0 :(得分:1)
首先,请尽量避免使用动态sql。想想sql注入,可读性,错误处理,可维护性......有很多理由可以避免动态sql。我声称可以在不使用动态sql的情况下解决上述用例。
接下来,您需要了解'SELECT ' + @SRIDCount
正在尝试将@SRIDCount(即NULL btw)的值添加到前导varchar,而不是变量的名称。您可以通过将变量添加到查询字符串来轻松修复:SELECT @SRIDCount = COUNT(DISTINCT Geom.STSrid)...
您的第二个错误是假设EXEC()
可以干扰内部批处理之外的变量,这些变量被视为自己的事务,并且无法访问您声明的变量。
使用SP_executesql
提供的示例也是一个封闭的事务,通过指定您可以使用查询结果的输出。
如果您将变量包含在:
中,则重写您的第一个查询将起作用DECLARE @PROCESS_TABLE VARCHAR(100) = QUOTENAME('Table Name')
EXEC(N'DECLARE @SRIDCount INT
SELECT @SRIDCount = COUNT(DISTINCT Geom.STSrid)
FROM ' + @PROCESS_TABLE + '
PRINT @SRIDCount')
但我假设你想在另一个查询中使用count。因此,下面的解决方法应该完成这项工作:
DECLARE @PROCESS_TABLE VARCHAR(100) = 'Table Name'
DECLARE @SRID TABLE (SRIDCount int)
DECLARE @SRIDCount INT
INSERT @SRID
INSERT INTO @SRID
EXEC(N'SELECT COUNT(DISTINCT Geom.STSrid)
FROM ' + @PROCESS_TABLE )
SELECT @SRIDCount = SRIDCount
FROM @SRID
但是,就像我在开始时所说的那样,重新思考一下你试图实现什么以及如何在没有动态sql的情况下实现它。
答案 1 :(得分:0)
它不起作用,因为exec
在一个批处理中运行你的sql命令,并且变量不存在于它自己的批处理之外。
在Transact-SQL中执行命令字符串或字符串 批次...
变量的范围是Transact-SQL语句的范围 可以引用变量。变量的范围持续时间 指出它是在批处理或存储过程结束之前声明的 它被声明...
答案 2 :(得分:0)
请注意您(必须)使@SRIDCount
与查询一起工作的不同之处:
'SELECT ' + @SRIDCount + ' = COUNT....'
会将字符串SELECT
与 @SRIDCount
和'COUNT ...'
的 VALUE 连接起来。
由于变量是新实例化的,因此您最有可能最终得到一行:
'SELECT 0 = COUNT ...
另一方面,后面的示例是一个仍然包含变量 NAME 的字符串,而不是 VALUE ,因此这个字符串按预期工作。这也,但不仅,因为
N'@SRIDCount int OUTPUT'
您明确将此变量标记为要从查询返回的某个值。
答案 3 :(得分:0)
DECLARE @PROCESS_TABLE varchar(100) = 'Table Name'
DECLARE @SRIDCount int
EXEC('SELECT ' + @SRIDCount + ' = COUNT(DISTINCT Geom.STSrid) FROM ' + @PROCESS_TABLE + '')
Print @SRIDCount
Incorrect syntax near '='.
由于您尚未为SRIDCount分配值,因此该语句实际上是
'SELECT ' + NULL + ' = Count(...'
连接字符串和null会产生Null。你本质上是试图运行
Exec (null);
如果要为SRIDCount分配值,则会收到数据类型转换错误,因为无法将数字添加到字符串(string + int + string)。如果将SRIDCount转换为字符数据类型,则可以在字符串中正确替换。但是,这不太可能是你想要做的。
Exec在新批处理中运行查询。批处理之间不共享内存,Exec语句中的批处理对外部语句没有可见性。
在执行之前尝试打印@SRIDCount。一旦打印的语句看起来很好,添加Execute语句并再次运行。如果在验证语句之前包含Exec,则可能会运行不符合预期的查询。