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);
}
}
}
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.
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.
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.
The ExecuteNonQuery method is used to execute the command and return the number of rows affected.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With