views:

218

answers:

3

I am writing a C# application that will update the fields in a SQL Server database. The current algorithm I am testing simply pulls the data from a "State" field, stores each value in an ArrayList, capitalizes it, and then writes it back to the database. I am having a problem with logic.

I pull all of the values into the ArrayList and capitalize them. This is working fine. I now have an array with, for instance, 100 values (i.e., myArray[0] - myArray[99] ). I then use a FOR loop to write the values back to the database:

for (int i = 0; i <= (myArray.Count - 1); i++)
{
   SqlCommand myCommand = 
      new SqlCommand("UPDATE myList SET State = '" + recordArray[i].ToString() + 
                     "' WHERE uniqueID = '" + (i + 1) + "'", dbConnection);
   myCommand.ExecuteNonQuery();
}

I am using "uniqueID" in the above example to place these values according to primary key. However, the problem is that the primary key is only nearly sequential; there are a few missing numbers in the sequence. Thus, even though I have exactly the number of values that I need, and they are in the correct order in the array to be pushed back out to the database, once I reach a lapse in the sequence, the rest of the data is placed in the wrong field. I know this is a lapse in my logic, but I am at a loss as to how I can ensure that every individual value is being placed correctly.

Thanks in advance for the help.

A: 

You need to grab the primary key values for the same rows, and keep track of that along with the data, so that you can update the correct row in the end.

Lasse V. Karlsen
Thank you! I figured that was part of it, which Joel's solution above included.
Geo Ego
+5  A: 

Unless you're doing this purely as an exercise, you do know you can just execute the update directly?

UPDATE myList SET State = Upper(State)
Charles Bretana
It is an exercise, but it's one aimed at learning how to interact with SQL Server via C# the proper way. Thanks for pointing that out!
Geo Ego
+6  A: 

So many things wrong here...

  1. Never NEVER NEVER use dynamic SQL like that. What if one of your "state" has an apostrophe in it?
  2. Unless this is .Net 1.0 or 1.1, you should NOT be using an ArrayList. Use System.Collections.Generic.List<string> instead.
  3. Don't create 99 SqlCommand objects. Create 1 SqlCommand object, and update the parameter value on each iteration through the loop.
  4. Create your SqlCommand (and even more importantly, SqlConnection) object with a using statement, to make sure the unmanaged resources are released promptly if an exception is thrown.
  5. Most of all, all this becomes moot when you realize you can update multiple records in one sql statement, and that sql has a nice easy "UPPER" function.

Since it looks like you could use an example of the correct way to build this kind of query, I'll assume for a moment that #5 is somehow not an option and that you really do need to pull all this data down to the application and then update it back record by record (hint: you don't). Here is how you should build that code:

using (SqlConnection cn1 = new SqlConnection("connection string here")) //inbound data
using (SqlCommand cmd1 = new SqlCommand("SELECT uniqueid, State FROM myList", cn1)) 
using (SqlConnection cn2 = new SqlConnection("connection string here"))
using (SqlCommand cmd2 = new SqlCommand("UPDATE myList SET State= @State WHERE uniqueID= @ID", cn2))
{
    SqlParameter StateParam = cmd2.Parameters.Add("@State", SqlDbType.VarChar, 50);
    SqlParameter IDParam = cmd2.Parameters.Add("@ID", SqlDbType.Int);

    cn1.Open();
    cn2.Open();

    using (SqlDataReader rdr = cmd1.ExecuteReader())
    {
        while (rdr.Read())
        {
            StateParam  = rdr["State"].ToString().ToUpper();
            IDParam = rdr["uniqueID"];
            cmd2.ExecuteNonReader();
        }
    }
}

Note that this is just to demonstrate using blocks and parameterized queries. You should NOT use this code. Instead, take a good look at my point #5. This can and should all be done in a single sql UPDATE statement.

Joel Coehoorn
+1 yup, you're right - this code is pretty bad - wish I could upvote your answer more than once !
marc_s
Thanks very much for your help. I was really looking for the proper way to do this, as I knew I was going the "hacky" route, and this works perfectly.
Geo Ego
I have the UPDATE command working now. Clearly the problem was my lack of familiarity with the UPDATE syntax. However, your other comments about dealing with SQL have given me much more insight into best practices. Thanks again.
Geo Ego
Wow - I'm with Marc - I wish I could upvote this answer more than once. Geo - take it as a given that NOTHING the user types in should EVER be inserted directly into a SQL Command. In fact, to be safe you may well want to A) ALWAYS use parameterized queries (to avoid SQL Injection attacks) and B) ALWAYS HTMLEncode any Request arguments before reflecting them back to the page (to avoid cross-site scripting attacks).
Mark Brittingham
Thank you guys for all your help. I have been using what you said here as a base to research the proper way to interact with SQL Server via C# and realize just how wrong (and dangerous) how I was going about it was.
Geo Ego