views:

36

answers:

2

In my code neither of these queries appear to be running. The debug label is printing as "end" so it is executing something inside that code block, just appears it doesn't like the queries?

// Check input is all valid
if (Page.IsValid)
{
    debug.Text = "begin";

    using (SqlConnection cn = new SqlConnection(
       ConfigurationManager.ConnectionStrings["LocalSqlServer"].ToString()))
    {

        // Verify that username is unique
        using (SqlCommand cmd = new SqlCommand(
           "UPDATE tblSiteSettings SET isActive = 0", cn))
        {
            cn.Open();
            cn.Close();
        }

        using (SqlCommand cmd = new SqlCommand(
           "INSERT INTO tblSiteSettings (allowProductRatings, allowComments, " + 
           "siteName, settingDate, isActive) VALUES (@allowRatings, " +
           "@allowcomments, @siteName, getDate(), 1)", cn))
        {
            cmd.Parameters.Add("@allowRatings", SqlDbType.Bit).Value = 1;
            cmd.Parameters.Add("@allowcomments", SqlDbType.Bit).Value = 1;
            cmd.Parameters.Add("@siteName", SqlDbType.VarChar, 128).Value = "lol";
            cn.Open();
            cn.Close();
        }
        debug.Text = "end";
    }   
}

A few questions:

  1. Why are they not executing?
  2. In classic ASP for inserts, updates and deletes I would use con.Execute(query) as supposed to using a recordset, am I running my update statement correctly here?
  3. Is my design of the queries good, or should I be executing them in a different manner?
+2  A: 

Your are missing

cmd.ExecuteScalar();

You may also reuse you SqlConnection, you can open the connection right after the using (SqlConnection cn = new Sql... statement. You don't have to close the connection when the SqlConnection is in a using block, accordning to the documentation the connection is closed when you are leaving the using block.

Albin Sunnanbo
Or one of the others
leppie
@Albin, neither query appears to be intended to return a value, so ExecuteNonQuery would be the better bet in this instance, if nothing else to make the intent of the code clearer to anyone who has to review or alter the code in future =)
Rob
+1 thanks for your answer, I realise I don't need to open connection for each query now, also is it better practise to close the connection even though garbage collection will take care of it? I always prefer having the assurance I do it myself and not rely on garbage.
Tom Gullen
@Tom - the `using(){}` construct is functionally identical to having a try/catch/finally that ensures that `Dispose()` is called on the object that you place within the `using` block, it's much more reliable than me, or you ;=)
Rob
+3  A: 

The reasn it's not doing anything is because you're not actually executing the queries. What you need to do is:

// Verify that username is unique
using (SqlCommand cmd = new SqlCommand("UPDATE tblSiteSettings SET isActive = 0", cn))
{
    cn.Open();
    cmd.ExecuteNonQuery();
    cn.Close();
}

using (SqlCommand cmd = new SqlCommand("INSERT INTO tblSiteSettings (allowProductRatings, allowComments, siteName, settingDate, isActive) VALUES (@allowRatings, @allowcomments, @siteName, getDate(), 1)", cn))
{
    cmd.Parameters.Add("@allowRatings", SqlDbType.Bit).Value = 1;
    cmd.Parameters.Add("@allowcomments", SqlDbType.Bit).Value = 1;
    cmd.Parameters.Add("@siteName", SqlDbType.VarChar, 128).Value = "lol";
    cn.Open();
    cmd.ExecuteNonQuery();
    cn.Close();
}

It's the line cmd.ExecuteNoneQuery(); that you're missing. There are various different Execute methods exposed by the SqlCommand class, the most commonly used are:

  • ExecuteNonQuery: Executes a query and returns no result from the query (it does return the rows affected as its return value however)
  • ExecuteScalar: Executes a query and returns the value in the first column of the first row
  • ExecuteReader: Executes a query and returns the data to a SqlDataReader
Rob
Thank you, what is the difference between ExecuteNonQuery and ExecureScalar as suggested in the other answer?
Tom Gullen
@Tom - I've just expanded on that about 10 seconds ago for you =) along with the relevant MSDN links to save making the answer a copy and paste of MSDN, so you can get the full detail there =)
Rob
ExecuteScalar is used to return single values from a SELECT as an object. ExecuteNonQuery returns an int to denote the rows Affected. All explained in the links...
MikeB
super thank you!
Tom Gullen