3

我在尝试执行以下代码时遇到错误,寻找类似的解决方案但无法弄清楚。

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吗?

一些答复会有所帮助。

4

3 回答 3

2

你为什么要传递变量?在您的情况下,您不必这样做。使用串联尝试以下操作:

声明 @SQL NVARCHAR(100)
  声明 @TEMPLATE_NAME NVARCHAR(50)
  SET @TEMPLATE_NAME = 'mytable'
  SET @SQL = N'SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '''+ @TEMPLATE_NAME + ''''
  打印@SQL
 执行 sp_executesql @SQL

但是,如果必须参数化,可以通过以下方式使用 sp_executesql

声明 @SQL NVARCHAR(100)
  声明 @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
于 2013-07-16T10:37:54.600 回答
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;

博客:动态 SQL 和 SQL 注入

于 2013-07-16T10:41:23.520 回答
1

将 N 添加到 sp_executesql 的第二个参数以使常量 nvarchar

EXEC sp_executesql @SQL,
               N'@TEMPLATE_NAME Nvarchar(50)',
                @TEMPLATE_NAME = @TEMPLATE_NAM
于 2013-07-16T10:37:31.223 回答