Question

I followed this answer,

How can I supply a List<int> to a SQL parameter?

Please see these questions of mine for understanding scenario,

How can I update Crate IDs of List of Fruits in single SQL query in c#

how can i update SQL table logic

What I am trying and not working

private void relate_fruit_crate(List<string> selectedFruitIDs, int selectedCrateID)
{
    string updateStatement = "UPDATE relate_fruit_crate set CrateID = @selectedCrateID where FruitID = @selectedFruitIDs";

    using (SqlConnection connection = new SqlConnection(ConnectionString()))
    using (SqlCommand cmd = new SqlCommand(updateStatement, connection))
    {
        connection.Open();
        cmd.Parameters.Add(new SqlParameter("@selectedCrateID", selectedCrateID.ToString()));
        cmd.Parameters.Add(new SqlParameter("@selectedFruitIDs", String.Join(",",selectedFruitIDs.ToArray())));

        cmd.ExecuteNonQuery();
    }
}

My code runs without any error,

Was it helpful?

Solution

You need to use the IN keyword in your scenario. The problem is that the SqlCommand.Parameters pattern does not build the query itself, but calls a stored procedure on the database:

exec sp_executesql N'UPDATE relate_fruit_crate set CrateID = @selectedCrateID where FruitID in(''@selectedFruitIDs'')', N'@selectedCrateID nvarchar(1),@selectedFruitIDs nvarchar(5)', @selectedCrateID = N'1', @selectedFruitIDs = N'1,2'

This will not work as the array is escaped.

The workaround would be to either use a normal StringBuilder to create the query. (Warning! SQL Injection) or to call the query for each ID separately.

Maybe there's a way to do this with the SqlCommand.Parameters, but I could not find one.

OLD POST::

string updateStatement = "UPDATE relate_fruit_crate set CrateID IN ('@selectedCrateID') where FruitID = '@selectedFruitIDs'";

[....]

cmd.Parameters.Add(new SqlParameter("@selectedFruitIDs", String.Join("','",selectedFruitIDs.ToArray())));

and equals (=) query will only match a single value.

OTHER TIPS

Multi-value parameter queries are a bit of a pain in TSQL. There are options like table-valued parameters, or "split" UDFs - otherwise... it is a bit tricky. You end up having to add multiple parameters (depending on the data), and change the query to suit. If I may suggest... a library like "dapper" may help you here - it is designed to make scenarios like this easy:

using Dapper; // at the top of your code file, to enable dapper
...
private void relate_fruit_crate(List<string> selectedFruitIDs, int selectedCrateID)
{
    // note the slightly unusual "in" here (no paranethesis) - that is because
    // dapper is going to do some voodoo...    
    using (SqlConnection connection = new SqlConnection(ConnectionString()))
    {
        connection.Open();
        connection.Execute(
            "UPDATE relate_fruit_crate set CrateID = @selectedCrateID where FruitID in @selectedFruitIDs",
            new { selectedFruitIDs, selectedCrateID });
    }
}

here "dapper" does all the work of figuring out how to express that in using multiple parameters, adding the correct number of parameters. It is also just much easier (in particular, look at how little work we did with commands and parameters; it handles readers nicely too).

Dapper is freely available from NuGet

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top