在动态SQL中声明标量变量时出错

时间:2015-02-05 17:52:32

标签: sql-server

我在SQL Server 2008中工作。我有以下存储过程,其中包含动态SQL语句:

CREATE PROCEDURE dbo.test
@list_of_codes varchar(255) = NULL,
@test_ID int = NULL
AS

DECLARE @sql1 nvarchar(max)
SELECT @sql1 =
'
INSERT INTO some_table
SELECT
some_col AS Some_Column,
@test_ID AS Testing_Identifier
FROM some_table
WHERE
testing_number_col = @test_ID
AND
test_col NOT IN (''' + REPLACE( @list_of_codes, ',', ''',''') + ''')
'

EXEC sp_executesql @sql1
'

我使用以下语句执行此存储过程:

EXEC dbo.test @list_of_codes = 'x,y,z', @test_ID = 10

当我执行此语句时,会抛出一个错误,说明

Must declare the scalar variable ''test_ID''.

我确定我的错误就像在动态SQL语句中转义@test_ID标量变量一样简单,但我不知道我需要在哪里转义它(如果这确实是我的问题) 。我做错了什么?

2 个答案:

答案 0 :(得分:0)

您缺少quotes

考虑@test_ID属于Integer类型。如果@test_ID属于varchar类型,则可能需要添加其他引号

SELECT @sql1 =
'
INSERT INTO some_table
SELECT
some_col AS Some_Column,
'+convert(varchar(20),@test_ID)+' AS Testing_Identifier
FROM some_table
WHERE
testing_number_col = '+ convert(varchar(20),@test_ID) + '
AND
test_col NOT IN (''' + REPLACE( @list_of_codes, ',', ''',''') + ''')
'

答案 1 :(得分:0)

查询的动态部分对外部存储过程中的参数一无所知,因此在调用sp_executesql时必须声明它们

documentation

中介绍了这一点

在您的示例中,您可以使用

DECLARE @sql1 nvarchar(max)
DECLARE @Params NVARCHAR(MAX) = '@test_ID INT'
SELECT @sql1 =
'
INSERT INTO some_table
SELECT
some_col AS Some_Column,
@test_ID AS Testing_Identifier
FROM some_table
WHERE
testing_number_col = @test_ID
AND
test_col NOT IN (''' + REPLACE( @list_of_codes, ',', ''',''') + ''')'

EXEC sp_executesql @sql1, @Params, @Test_ID=@Test_ID