动态SQL insert语句无法识别作为参数传递的值时出现问题
我一直在试图找出这个动态SQL insert语句的错误。显然,当我向它传递一个要插入的值字符串时,它引起的错误使它看起来像是正确地解析了,但它说它与语句中指定的列数不匹配。我已经附上了要插入数据的表定义、动态语句和下面的values参数:动态SQL insert语句无法识别作为参数传递的值时出现问题,sql,sql-server,sql-server-2016,Sql,Sql Server,Sql Server 2016,我一直在试图找出这个动态SQL insert语句的错误。显然,当我向它传递一个要插入的值字符串时,它引起的错误使它看起来像是正确地解析了,但它说它与语句中指定的列数不匹配。我已经附上了要插入数据的表定义、动态语句和下面的values参数: M2016\u Field\u ID列是一个标识列,不需要插入,与Enabled\u ON列相同,Enabled\u ON列具有分配当前日期的默认约束 当我尝试执行该语句时,它抛出以下错误: 味精109,第15级,状态1,第3行 INSERT语句中的列多于v
M2016\u Field\u ID
列是一个标识列,不需要插入,与Enabled\u ON列相同,Enabled\u ON列具有分配当前日期的默认约束
当我尝试执行该语句时,它抛出以下错误:
味精109,第15级,状态1,第3行INSERT语句中的列多于values子句中指定的值。values子句中的值数必须与INSERT语句中指定的列数匹配
不能像那样参数化查询。这样试试
SET @valuesList = '''description'', ''0,0'''
SET @sql = N' INSERT INTO tblM2016_MetaData_Fields ' +
N' (Name, FieldNum) ' +
N' VALUES ('+@valuesList+');';
不能像那样参数化查询。这样试试
SET @valuesList = '''description'', ''0,0'''
SET @sql = N' INSERT INTO tblM2016_MetaData_Fields ' +
N' (Name, FieldNum) ' +
N' VALUES ('+@valuesList+');';
我不相信可以将值列表作为字符串传递到单个参数中,它可能正在运行的是: 插入tblM2016_元数据_字段 (名称,fieldnum)
值(“(“'description”“,'0.0”“)”),因此它试图将名称设置为等于您将值列表设置为的字符串。为了完成您正在尝试的操作,您可能需要直接将该字符串添加到sql语句中,或者创建两个参数(每个字段一个)。我不相信您可以将值列表作为字符串传递到单个参数中。它可能正在运行的是: 插入tblM2016_元数据_字段 (名称,fieldnum)
值(“(“'description”“,'0.0”“)”),因此它试图将名称设置为等于您将值列表设置为的字符串。为了完成您正在尝试的操作,您可能需要直接将该字符串添加到sql语句中,或者创建两个参数(每个字段一个)。幸运或不幸的是,单个参数只表示查询中的单个值。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;
幸运或不幸的是,单个参数只表示查询中的单个值。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;
最好的方法确实是使用参数,但需要将参数分开。另外,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\u提供一个值,因为它在表屏幕截图中定义为NOT NULL
。最好的方法确实是使用参数,但您需要将参数分开。另外,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;
请注意,您还需要在
上为启用的提供一个值,因为它在表屏幕截图中定义为非空
。在插入中有两列,在值
中只有一列。仅仅因为字符串可能包含逗号并不能将其转换为多个值。我现在明白了。谢谢。insert
中有两列,而values
中只有一列。仅仅因为字符串可能包含逗号并不能将其转换为多个值。我现在明白了。谢谢。你是说替换中的@values
应该是@valuesList
?你是说替换中的@values
应该是@valuesList
?真的。。。否决票?我想知道为什么。到目前为止,这是唯一一个保留参数的答案,从而避免了sql注入或损坏的所有机会。我没有投你反对票,这是肯定的。你的答案不是我想要的。顺便说一句,我在问题中提到,启用的_ON有一个默认约束,因此它不需要包含在insert中。真的。。。否决票?我想知道为什么。到目前为止,这是唯一一个保留参数的答案,从而避免了sql注入或损坏的所有机会。我没有投你反对票,这是肯定的。你的答案不是我想要的。顺便说一句,我在问题中说过,Enabled_ON有一个默认约束,因此它不需要包含在insert中。