简体   繁体   中英

Issue with dynamic SQL insert statement not recognizing values passed as parameter

I've been trying to figure out what's wrong with this dynamic SQL insert statement. Apparently, when I pass it a string of values to insert, the error it causes makes it seem like its parsing correctly, but it says it doesn't match the number of columns specified in the statement. I've attached the table definition I'm inserting the data into, the dynamic statement, and the values parameter below:

The M2016_Field_ID column is an identity column and shouldn't need to be inserted, the same with the Enabled_ON column which has a default constraint that assigns the current date.

在此处输入图片说明

@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;

It throws the following error when I try to execute the statement:

Msg 109, Level 15, State 1, Line 3
There are more columns in the INSERT statement than values specified in the VALUES clause. The number of values in the VALUES clause must match the number of columns specified in the INSERT statement.

You cannot parameterize the query like that. Try this way

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

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

I don't believe you can pass in a list of values as a string into a single parameter what it is probably running is something like:

insert into tblM2016_MetaData_Fields (name, fieldnum) values ('(''description'',''0.0'')') so it's trying to set name equal to the string you've set values list to. In order to do what you are trying, you'd probably have to just add that string directly into your sql statement or create two parameters (one for each field).

Fortunately or unfortunately, a single parameter only represents a single value in the query. T-SQL doesn't have the concept of lists.

One way around this problem is to stuff the value list inside the query string:

@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;

The best approach indeed is to use parameters, but you need to keep the parameters separate. Also, that way SQL Server will handle the escaping of quotes, best to never do it yourself because it's inevitable that you'll mess it up sooner or later.

The result:

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;

Note that you'd also need to provide a value for Enabled_ON because it is defined as NOT NULL in the table screenshot.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM