Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

An issue of SqlCommand with parameters for IN [duplicate]

Tags:

c#

sql

sql-server

Apparently, the following code does not print anything out as it is expected.. I am sure it is to do with the fact that I tried to put a list of items in to @namelist. Clearly, it is not just a text replacement.

How can I solve this problem? Thanks

using (var connection = new SqlConnection(_connectionString))
{
    connection.Open();

    using (var cmd = connection.CreateCommand())
    {
        cmd.CommandText = @"select column_name, table_name from information_schema.columns where table_name in (@namelist)";
        cmd.Parameters.AddWithValue("@namelist",  "'tableOne', 'tableTwo'");

        var reader = cmd.ExecuteReader();

        while (reader.Read())
        {
            var a = reader[0];
            Console.WriteLine(a);
        }
    }
}
like image 240
hong pei Avatar asked May 30 '13 17:05

hong pei


People also ask

What is SqlCommand parameters AddWithValue?

AddWithValue replaces the SqlParameterCollection. Add method that takes a String and an Object. The overload of Add that takes a string and an object was deprecated because of possible ambiguity with the SqlParameterCollection.

What does SqlCommand mean?

SQL stands for Structured Query Language. SQL commands are the instructions used to communicate with a database to perform tasks, functions, and queries with data. SQL commands can be used to search the database and to do other functions like creating tables, adding data to tables, modifying data, and dropping tables.

Which object is used to pass variable to SqlCommand?

Command objects use parameters to pass values to SQL statements or stored procedures, providing type checking and validation. Unlike command text, parameter input is treated as a literal value, not as executable code.

Which method of SqlCommand class returns the number of records affected in the table?

The ExecuteNonQuery method is used to execute the command and return the number of rows affected.


2 Answers

Unfortunately, SQL parameters aren't resolved that way, in other words, the backend doesn't just build a safe-string replacing each parameter with its value. Instead, you'll have to dynamically build a parameter list:

cmd.CommandText = @"select column_name, table_name from information_schema.columns where table_name in (@p1, @p2, @p3)"; // This can be built dynamically

And then add each parameter:

cmd.Parameters.AddWithValue("@p1", "tableOne");
cmd.Parameters.AddWithValue("@p2", "tableTwo");
cmd.Parameters.AddWithValue("@p3", "tableThree");

You could of course add these parameters in a loop if the number was unknown until runtime:

for(var i = 0; i < myParams.length; i++)
{
   cmd.Parameters.AddWithValue("@p" + i.ToString(), myParams[i]);
}

If your list of tables were stored in an enum, or you could escape them or validate them with a regular expression, it would also be fairly safe to just build the raw SQL yourself and not use parameters at all.

This is, of course, one of the big reasons I use PostgreSQL; native support for arrays.

like image 155
Mike Christensen Avatar answered Oct 01 '22 20:10

Mike Christensen


As has been noted, "in" lists etc are notoriously awkward in ado.net; because of this, some tools offer convenience methods to help. For example, Dapper offers a variant on the "in" syntax which it automatically expands to the correct parameterized form (still retaining injection safety etc) - in both type-bound and "dynamic" usage. For example:

string[] namelist = ...
foreach(var row in conn.Query(@"
    select column_name, table_name
    from information_schema.columns
    where table_name in @namelist",
        new { namelist } ))
{
    string col = row.column_name,
         table = row.table_name;
    // .. 
}

This also avoids the need to mess around with db-command/parameter/reader. Note the "in" without brackets which it uses to recognise this pattern.

like image 27
Marc Gravell Avatar answered Oct 01 '22 21:10

Marc Gravell