2014-04-09 31 views
1

我試圖插入一個記錄,如果請求prodName不存在數據庫中。如果存在,我想更新quantity屬性的值。我用下面它既不插入也不更新任何記錄。我得到以下異常:在asp.net和SQL SERVER 2008中插入/更新

ExecuteScalar requires an open and available Connection. The connection's current state is closed

這是代碼

public static void manageStock(CompanyStock stock) 
    { 
     ///// Check if record exists///////// 
     cmd = new SqlCommand("select count(*) from tblStock where [email protected]", con); 
     cmd.Parameters.AddWithValue("@prodName", stock.prodName); 
     con.Open(); 
     Int32 count = (Int32)cmd.ExecuteScalar(); //returns null if doesnt exist 
     con.Close(); 

     if (count > 0) 
     { 
      cmd = new SqlCommand("update tblStock set quantity = @quantity where [email protected]", con); 
      cmd.Parameters.AddWithValue("@prodName", stock.prodName); 
      cmd.Parameters.AddWithValue("@quantity", stock.quantity); 
     } 
     else 
     { 
      cmd = new SqlCommand("insert into tblStock(prodName,quantity) values (@prodName, @quantity)", con); 
      cmd.Parameters.AddWithValue("@prodName",stock.prodName); 
      cmd.Parameters.AddWithValue("@quantity",stock.quantity); 
     } 

     try 
     { 
      con.Open(); 
      cmd.ExecuteNonQuery(); 
     } 

     finally 
     { 
      con.Close(); 
     } 
    } 
} 

編輯 我編輯我的代碼。現在它工作正常。我必須在執行ExecuteScalar之前打開我的連接,但我想知道編寫這個開始和結束內容的標準方式。它看起來很隨意。我該如何改進?

+0

我相信你需要打開你的執行的第一個命令對象之前的連接:首先寫一個存儲過程。我不確定你的代碼是如何執行的。如果這確實是代碼,它將始終執行INSERT到tblStock命令。 – abhi

+0

你的代碼有什麼問題是你不處理你的異常,所以你看不到可能告訴你問題真的是什麼的錯誤信息。 – Pleun

+1

@Pleun雖然沒有「catch」,他們不會只是泡了嗎?雖然聽起來好像有可能在某處進一步吞嚥。 –

回答

0

您可以使用Convert.ToInt32()方法將結果轉換爲整數值。如果值爲null,則將其轉換爲0

試試這個:

int count = Convert.ToInt32(cmd.ExecuteScalar()); 
0

考慮使用MERGE在SQL服務器的條款。這是一個很好的Microsoft article你可以使用。

0

當您逐步完成代碼時,它會做什麼?

在某些SQL排序規則中(例如Latin1_General_BIN),變量區分大小寫。在您的第一條語句中,您的查詢中有@P rodName,您的參數集合中有@p rodName。如果你有一個區分大小寫的排序規則,你永遠不會越過這部分。在Management Studio中右鍵單擊數據庫,然後單擊「屬性」以查找排序規則。

+0

我糾正了這種情況,但仍然無法使用 – Insafian

+0

當您逐步完成代碼時,它會執行什麼操作? – InbetweenWeekends

+0

重新讀取您的編輯後,在您的SELECT行上,您提供了一個'con'連接,但是我沒有看到它被打開。 – InbetweenWeekends

0

錯誤說沒有connection.Mayü首先檢查所有問題,所以

檢查連接,如果不爲空,在這一點上存在檢查con.State =打開或任何其他值。我連接狀態是關閉打開它。但首先在哪裏是連接聲明?我沒有在你的代碼中看到它。

試試這個:

//USING THE STATEMNET USING IT WILL TAKE CARE TO DISPOSE CONNECTION AND PLACE TRY CATCH WITHIN PROCS 

{ 
using (SqlConnection cnn = new SqlConnection(ConfigurationManager.AppSettings("connectionString"))) { 
    if (cnn.State == System.Data.ConnectionState.Closed) 
     cnn.Open(); 
    using (SqlCommand cmd = new SqlCommand()) { 
     try { 
      cmd.Connection = cnn; 
      cmd.CommandText = "YOUR SQL STATEMENT"; 
      int I = Convert.ToInt32(cmd.ExecuteNonQuery); 

      if (I > 0) 
      { 
       cmd.CommandText = "YOUR SQL STATEMENT"; 
      //ADDITIONAL PARAMTERES 
      } 
      else 
      { 
       cmd.CommandText = "YOUR SQL STATEMENT"; 
       //ADDITIONAL PARAMETERS 
      } 
      cmd.ExecuteNonQuery(); 
      } 
       catch (Exception ex) 
      { 
      Response.Write(ex.Message); 
      } 
     } 
    } 
} 
+0

編輯我的QS。檢查它 – Insafian

+0

看看我的解決方案,它更簡單和安全。不要離開連接打開記住:)。它符合你的目標,將其作爲答案 – makemoney2010

0

你可以試試這個代碼。在代碼

CREATE PROCEDURE sprocquanupdateinsert 
    @prodName nvarchar(250), 
    @quantity int 
AS 
BEGIN 
    UPDATE tblStock 
    SET quantity = @quantity 
    WHERE prodName = @prodName 

    IF @@ROWCOUNT = 0 
     INSERT INTO tblStock(prodName, quantity) 
     VALUES (@prodName, @quantity) 
END 
GO 

那麼後面你可以使用這個

using (conn) 
{ 
    SqlCommand cmd = new SqlCommand("sprocquanupdateinsert", conn); 
    cmd.CommandType = CommandType.StoredProcedure; 

    cmd.Parameters.AddWithValue("@prodName", stock.prodName); 
    cmd.Parameters.AddWithValue("@quantity", stock.quantity); 

    conn.Open(); 
    cmd.ExecuteNonQuery(); 
    conn.Close(); 
}