我有一个存储过程,我以这种方式进行了简化:
DECLARE @variable1 INT
DECLARE @SQL VARCHAR(MAX)
SET @SQL = '
DECLARE @variable2 INT
SET @variable2 = 1
SET '+CAST(@variable1 AS VARCHAR)+' = @variable2
SELECT @variable1 as V1, @variable2 as V2
'
EXEC(@SQL)
Run Code Online (Sandbox Code Playgroud)
但是这个脚本没有给我任何东西!我很确定这与范围有关。问题是我需要在动态查询之外声明变量。
感谢帮助 !
编辑 :
WHILE LOOP UNTIL SELECT COUNT xxx = 0
BEGIN
DECLARE @variable1 INT
DECLARE @SQL VARCHAR(MAX)
SET @SQL = '
EXEC STORE PROC WITH PARAMETER @Param1 = @variable1 (first loop @Param1 is null)
STORE PROC RETURN A VALUE
SET @variable1 with return value of store proc
and use it in second loop, third loop...
'
EXEC(@SQL)
END
Run Code Online (Sandbox Code Playgroud)
值得一提的三件事:
PRINT
每当您使用动态 SQL 时,始终使用来查看生成的动态 SQL。您将看到 SQL 变量实际上包含NULL
.
DECLARE @variable1 INT
DECLARE @SQL VARCHAR(MAX)
SET @SQL = '
DECLARE @variable2 INT
SET @variable2 = 1
SET ' + CAST(@variable1 AS VARCHAR) + ' = @variable2
SELECT @variable1 as V1, @variable2 as V2
'
PRINT(@SQL)
-- EXEC(@SQL)
Run Code Online (Sandbox Code Playgroud)动态 SQL 的原因NULL
是因为您正在连接作为@variable1
内容的 NULL 值。我相信你想把文字'@variable1'
写成文字:
DECLARE @variable1 INT
DECLARE @SQL VARCHAR(MAX)
SET @SQL = '
DECLARE @variable2 INT
SET @variable2 = 1
SET @variable1 = @variable2
SELECT @variable1 as V1, @variable2 as V2
'
PRINT(@SQL)
Run Code Online (Sandbox Code Playgroud)@variable1
因为它没有在任何地方声明。如果我们执行动态 SQL:您可以在动态执行中设置变量值并能够从外部读取它们的方法是通过OUTPUT
选项提供参数。这将需要使用 SP sp_executesql而不是直接EXEC
:
DECLARE @externalVariable INT
DECLARE @SQL NVARCHAR(MAX)
SET @SQL = '
DECLARE @variable2 INT = 1
SET @resultVariable = @variable2'
EXEC sp_executesql
@stmt = @SQL,
@params = N'@resultVariable INT OUTPUT', -- Declare the "input" parameters for the dynamic SQL
@resultVariable = @externalVariable OUTPUT -- Supply the "input" parameters for the dynamic SQL
SELECT
Result = @externalVariable -- Read the updated value
Run Code Online (Sandbox Code Playgroud)
请注意,我将数据类型更改为NVARCHAR
因为sp_executesql
适用于 unicode 输入。
另一个带有更多参数的示例:
DECLARE @firstNumber INT = 15
DECLARE @secondNumber INT = 3
DECLARE @result INT
DECLARE @SQL NVARCHAR(MAX) = '
SET @multiplicationResult = @inputFactor1 * @inputFactor2'
EXEC sp_executesql
@stmt = @SQL,
@params = N'
@multiplicationResult INT OUTPUT,
@inputFactor1 INT,
@inputFactor2 INT',
@multiplicationResult = @result OUTPUT,
@inputFactor1 = @firstNumber,
@inputFactor2 = @secondNumber
SELECT
Result = @result -- 45!
Run Code Online (Sandbox Code Playgroud)
如果您不必从变量读回结果,则可以通过将变量值直接“硬编码”到脚本中来构建动态 SQL。确保在脚本中正确使用数据类型转换以及转义NULL
和文字值:
DECLARE @DateVariable DATETIME = GETDATE()
DECLARE @StringVariable VARCHAR(100) = NULL
DECLARE @FloatVariable FLOAT = 15.14
DECLARE @DynamicSQL VARCHAR(MAX) = '
SELECT
DateVariableContents = CONVERT(DATETIME, ''' + ISNULL(CONVERT(VARCHAR(100), @DateVariable), '') + '''),
StringVariableContents = ' + ISNULL('''' + @StringVariable + '''', '''''') + ',
FloatVariableContents = CONVERT(FLOAT, ''' + ISNULL(CONVERT(VARCHAR(100), @FloatVariable), '') + ''') '
PRINT(@DynamicSQL)
EXEC(@DynamicSQL)
Run Code Online (Sandbox Code Playgroud)
打印:
SELECT
DateVariableContents = CONVERT(DATETIME, 'Mar 21 2019 3:27PM'),
StringVariableContents = '',
FloatVariableContents = CONVERT(FLOAT, '15.124')
Run Code Online (Sandbox Code Playgroud)
结果:
DateVariableContents StringVariableContents FloatVariableContents
2019-03-21 15:28:00.000 15.124
Run Code Online (Sandbox Code Playgroud)