I've been searching on the internet, but I just can't seem to find anything that explain my question (could be that I'm not using the correct search string), so I'm posting here hoping that someone can help me with this. (My program is written is C# using Visual Studio 2010)
I notice that in C#, there are multiple ways of constructing a SQL command.
SqlConnection connection = GetAndOpenConnection(); //function containing connection string and open connection
SqlCommand command = connection.CreateCommand();
Up to this point, I have no questions. The problem I have is with CommandText
. I am using several different commands in my code(SELECT
/INSERT
/UPDATE
/DELETE
), but lets take SELECT
for example.
//Example 1:
command.CommandText = String.Format("SELECT * FROM myTable WHERE name = '{0}'", "bob");
//Example 2:
command.CommandText = "SELECT * FROM myTable WHERE name = @myName";
command.Parameters.Add(new SqlParameter("myName", "bob"));
What are the differences between the above 2 examples? (performance wise/structure wise/etc)
The reason I'm asking is because within the same .cs file, when I use the method in Example 2, sometime the code works properly and sometime it doesn't, then I eventually makes everything like in Example 1, which works every single time.
Is there a significant gain/loss using either method? Which is the more proper way of completing a task like this?
ADDITIONAL QUESTION
Okay, so I see that method 2 is the more appropriate way to do this.
However, there's a problem if I use method 2.
I have a loop that loop through a List<string> names
. Inside the loop, when I use method 2 and add name as parameters, I got an error saying that the parameter already exist and cannot be added.
How can I go about solving this?
List<string> names = new List<string> {"adam", "bob", "john"};
foreach(string name in names)
{
command.CommandText = "SELECT * FROM myTable WHERE name = @myName";
command.Parameters.Add(new SqlParameter("myName", name));
reader = command.ExecuteReader();
while(reader.Read())
{
//loop through each cell and print on the Console
}
}
Also, I know that people mentioned that in the parameter it should be "@myName"
instead of "myName"
. I remember having this issue as I was confused which way to use and had to just test it. "@myName"
was not working for me but "myName"
is, and this is how it's in the code right now in the parts where I still use method 2. I'm using .Net 4.0, don't know if this will make a difference.
Simply using String. Format does not protect against SQL injection attacks.
Accepts a query string with placeholders for values, and returns a string with the values embedded. The function is careful to quote all of its inputs with dbQuoteLiteral() to protect against SQL injection attacks.
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.
Parameters exist to prevent SQL Injection. For example, consider what happens in case of string.Format
if instead of bob
there was TextBox1.Text
which contained 1';DROP TABLE myTable;'
.
SQL Injection is not possible if you have complete control over the parameters, like in your case with string literal for parameter. However you never know how your code might change in future, so as a rule of thumb you should always stick to safer approach with parameters.
If you are facing some particular problems with second approach - search and maybe post here, there is most likely a solution already. For example, in your code snippet actual parameter name is @myName
with @ symbol, and that is what should be supplied to the SqlParameter
constructor.
Update. In your additional question problem is exactly in parameters naming - it should be @myName
:
command.Parameters.Add(new SqlParameter("@myName", name));
Also you should clear parameters collection on each iteration:
command.Parameters.Clear();
Although it would be better to create new command on every iteration to avoid mess - check this thread for details.
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