动态SQL插入语句的问题无法识别作为参数传递的值

时间:2017-01-19 14:54:32

标签: sql sql-server sql-server-2016

我一直试图弄清楚这个动态SQL插入语句有什么问题。显然,当我向其传递一串要插入的值时,它导致的错误使其看起来像是正确解析,但它表示它与该语句中指定的列数不匹配。我已经附加了表格定义,我将数据插入,动态语句和值参数如下:

M2016_Field_ID列是一个标识列,不需要插入,与Enabled_ON列相同,该列具有指定当前日期的默认约束。

enter image description here

@valuesList = '(''description'', ''0,0'')'

SET @sql = N' INSERT INTO tblM2016_MetaData_Fields ' +
                   N' (Name, FieldNum) ' +
                   N' VALUES (@values);';
SET @params = N'@values nvarchar(max)';

IF @debug = 1
BEGIN
    PRINT @sql;
    PRINT @params;
    PRINT @valuesList;
END
ELSE
    EXEC sp_executesql @sql, @params, @values = @valuesList;

当我尝试执行语句时,它会抛出以下错误:

  

Msg 109,Level 15,State 1,Line 3
  INSERT语句中的列多于VALUES子句中指定的值。 VALUES子句中的值数必须与INSERT语句中指定的列数相匹配。

4 个答案:

答案 0 :(得分:1)

您无法像这样参数化查询。试试这种方式

SET @valuesList = '''description'', ''0,0'''

SET @sql = N' INSERT INTO tblM2016_MetaData_Fields ' +
                   N' (Name, FieldNum) ' +
                   N' VALUES ('+@valuesList+');';

答案 1 :(得分:1)

我不相信你可以将值列表作为字符串传递到单个参数中,它可能运行的是:

插入tblM2016_MetaData_Fields (name,fieldnum) values('(''description'',''0.0'')')所以它试图将name设置为你设置值列表的字符串。为了做你正在尝试的事情,你可能只需将该字符串直接添加到sql语句中或创建两个参数(每个字段一个)。

答案 2 :(得分:1)

幸运或遗憾的是,单个参数仅表示查询中的单个值。 T-SQL没有列表的概念。

解决此问题的一种方法是将值列表填充到查询字符串中:

@valuesList = '(''description'', ''0,0'')'
SET @sql = N'
INSERT INTO tblM2016_MetaData_Fields (Name, FieldNum) 
     VALUES (@values)';

SET @sql = REPLACE(@sql, '@values', @valuesList);
IF @debug = 1
BEGIN
    PRINT @sql;
END;
ELSE
    EXEC sp_executesql @sql;

答案 3 :(得分:0)

最好的方法确实是使用参数,但您需要将参数分开。另外,SQL Server会以这种方式处理引号的转义,最好永远不要自己动手,因为你迟早会把它弄得一团糟。

结果:

SET @value1 = 'description'
SET @value2 = '0,0'

SET @sql = N' INSERT INTO tblM2016_MetaData_Fields ' +
           N' (Name, FieldNum) ' +
           N' VALUES (@NameV, @FieldNumV);';

SET @params = N'@NameV varchar(50), @FieldNumV varchar(max)';

EXEC sp_executesql @sql, @params, @NameV = @value1, @FieldNumV = @value2;

请注意,您还需要为Enabled_ON提供一个值,因为它在表格截图中定义为NOT NULL