views:

70

answers:

4

I'm creating an auditting table, and I have the easy Insert and Delete auditting methods done. I'm a bit stuck on the Update method - I need to be able to get the current values in the database, the new values in the query parameters, and compare the two so I can input the old values and changed values into a table in the database.

Here is my code:

    protected void SqlDataSource1_Updating(object sender, SqlDataSourceCommandEventArgs e)
    {
        string[] fields = null;
        string fieldsstring = null;
        string fieldID = e.Command.Parameters[5].Value.ToString();
        System.Security.Principal.  WindowsPrincipal p = System.Threading.Thread.CurrentPrincipal as System.Security.Principal.WindowsPrincipal;
        string[] namearray = p.Identity.Name.Split('\\');
        string name = namearray[1];
        string queryStringupdatecheck = "SELECT VAXCode, Reference, CostCentre, Department, ReportingCategory FROM NominalCode WHERE ID = @ID";
        string queryString = "INSERT INTO Audit (source, action, itemID, item, userid, timestamp) VALUES (@source, @action, @itemID, @item, @userid, @timestamp)";
        using (SqlConnection connection = new SqlConnection("con string = deleted for privacy"))
        {
            SqlCommand commandCheck = new SqlCommand(queryStringupdatecheck, connection);
            commandCheck.Parameters.AddWithValue("@ID", fieldID);
            connection.Open();
            SqlDataReader reader = commandCheck.ExecuteReader();
            while (reader.Read())
            {
                for (int i = 0; i < reader.FieldCount - 1; i++)
                {
                    if (reader[i].ToString() != e.Command.Parameters[i].Value.ToString())
                    {
                        fields[i] = e.Command.Parameters[i].Value.ToString() + "Old value: " + reader[i].ToString();
                    }
                    else
                    {

                    }
                }
            }
                fieldsstring = String.Join(",", fields);

                reader.Close();

            SqlCommand command = new SqlCommand(queryString, connection);
            command.Parameters.AddWithValue("@source", "Nominal");
            command.Parameters.AddWithValue("@action", "Update");
            command.Parameters.AddWithValue("@itemID", fieldID);
            command.Parameters.AddWithValue("@item", fieldsstring);
            command.Parameters.AddWithValue("@userid", name);
            command.Parameters.AddWithValue("@timestamp", DateTime.Now);
            try
            {
                command.ExecuteNonQuery();
            }
            catch (Exception x)
            {
                Response.Write(x);
            }
            finally
            {
                connection.Close();
            }
        }
    }

The issue I'm having is that the fields[] array is ALWAYS null. Even though the VS debug window shows that the e.Command.Parameter.Value[i] and the reader[i] are different, the fields variable seems like it's never input into.

Thanks

+1  A: 

You never set your fields[] to anything else than null, so it is null when you are trying to access it. You need to create the array before you can assign values to it. Try:

           SqlDataReader reader = commandCheck.ExecuteReader();
           fields = new string[reader.FieldCount]
driis
But in the IF statement in the for loop, I'm setting the [i] index of fields to be the parameter value etc.
Chris
I feel extremely stupid, forgot you have to 'create' the array after declaring it. Thanks!
Chris
@Chris, glad to help. If my answer was helpful, please remember to vote up or accept.
driis
A: 

I don't really understand what your doing here, but if your auditing, why don't you just insert every change into your audit table along with a timestamp?

Mr Shoubs
That was an idea, but talking to my supervisor, they want only updated fields auditted along with their old values.
Chris
A: 

Do fields = new string[reader.FieldCount] so that you have an array to assign to. You're trying to write to null[0].

Jon Hanna
A: 

I think the earlier answers have the answer to your problem. Btw, you shouldn't need the connection.close() as you have everything in a using statement. Also, put your reader in a using clause and you can also get rid of the reader.close()

Lareau