我在尝试执行以下代码时遇到错误,寻找类似的解决方案,但无法弄清楚。
DECLARE @TAB_COL_NAME TABLE(idx int identity(1,1), COLUMNNAME VARCHAR(MAX))
DECLARE @TEMPLATE_NAME NVARCHAR(50)
SET @TEMPLATE_NAME = 'MYTABLE1'
INSERT INTO @TAB_COL_NAME EXEC('SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '+@TEMPLATE_NAME)
由于我看到很多人说使用sp_executesql,
,我尝试了sp_executesql
,
DECLARE @SQL NVARCHAR(100)
DECLARE @TEMPLATE_NAM NVARCHAR(50)
SET @TEMPLATE_NAM = 'MYTABLE1'
SET @SQL = N'SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '+ '@TEMPLATE_NAME'
EXEC sp_executesql @SQL,
'@TEMPLATE_NAME Nvarchar(50)',
@TEMPLATE_NAME = @TEMPLATE_NAM
这会发出错误:Procedure expects parameter '@parameters' of type 'ntext/nchar/nvarchar'.
对此有什么正确的解决方案?
我无法实现这一目标在EXEC SQL
?
一些回复会有所帮助。
答案 0 :(得分:2)
为什么要尝试传递变量?在您的情况下,您不一定要这样做。使用串联尝试以下操作:
DECLARE @SQL NVARCHAR(100) DECLARE @TEMPLATE_NAME NVARCHAR(50) SET @TEMPLATE_NAME = 'mytable' SET @SQL = N'SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '''+ @TEMPLATE_NAME + '''' print @SQL EXEC sp_executesql @SQL
但是,如果必须参数化,则可以按以下方式使用sp_executesql
DECLARE @SQL NVARCHAR(100) DECLARE @TEMPLATE_NAME NVARCHAR(50) SET @TEMPLATE_NAME = 'mytable'; SET @SQL = N'SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @TEMPLATE_NAME'; EXEC sp_executesql @SQL , N'@TEMPLATE_NAME NVARCHAR(50)', @TEMPLATE_NAME
答案 1 :(得分:1)
将N添加到sp_executesql的第二个参数以生成常量nvarchar
EXEC sp_executesql @SQL,
N'@TEMPLATE_NAME Nvarchar(50)',
@TEMPLATE_NAME = @TEMPLATE_NAM
答案 2 :(得分:1)
虽然在给定的示例中不会发生,但用于通过连接字符串来执行sp_executesql
的方法会受到sql注入的影响。这个答案正确使用参数。参数2定义了传递给字符串的参数,3 +是您传递的参数。
此外,如果您的参数中包含撇号,那么它将使连接版本失败:SET @TEMPLATE_NAME = '[MYTABLE''1]';
。在这种情况下不太现实,但通常需要注意动态sql。
DECLARE @SQL NVARCHAR(100);
DECLARE @TEMPLATE_NAME NVARCHAR(50);
SET @TEMPLATE_NAME = 'MYTABLE1';
SET @SQL = N'SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @TEMPLATE_NAME';
EXEC sp_executesql @SQL , N'@TEMPLATE_NAME NVARCHAR(50)', @TEMPLATE_NAME;