我一直试图弄清楚这个动态SQL插入语句有什么问题。显然,当我向其传递一串要插入的值时,它导致的错误使其看起来像是正确解析,但它表示它与该语句中指定的列数不匹配。我已经附加了表格定义,我将数据插入,动态语句和值参数如下:
M2016_Field_ID
列是一个标识列,不需要插入,与Enabled_ON列相同,该列具有指定当前日期的默认约束。
@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语句中指定的列数相匹配。
答案 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
。