2013-03-13 73 views
3

這是for循環,它將轉到時間並將時間列設置爲true。這是第一次,但是當時間增加0.5時,它仍然是錯誤的。 for循環正在工作,因爲我試過一個MessageBox.Show(「」+ Time1 +「」);在for循環中。SQL插入命令只能在循環中工作一次

for (double Time = time_began_5; Time < time_finished_5; Time = Time + 0.5) 
     { 
      string Time1 = Time.ToString("0.00"); 


      try 
      { 
       SqlConnection cn = new SqlConnection("Data Source=.\\SqlExpress;Initial Catalog=AllensCroft;Integrated Security=True;MultipleActiveResultSets=True;Application Name=EntityFramework;"); 

       cn.Open(); 
       SqlCommand Command = new SqlCommand("INSERT INTO Slots ([Date],[RoomID],[" + Time1 + "]) Values (@date,@room,1)", cn); 
       Command.Parameters.AddWithValue("date", date); 
       Command.Parameters.AddWithValue("room", rooms_combo.SelectedValue); 

       Command.ExecuteNonQuery(); 


       try 
       { 
        cn.Close(); 
       } 
       catch (Exception e) 
       { 
        Console.WriteLine(e.ToString()); 
       } 

      } 
      catch (Exception e) 
      { 
       Console.WriteLine(e.ToString()); 
      } 

     } 

這裏是數據庫的樣子,第一個真正的現場工作,但是當它循環到另一個時間,它仍然是假的,我認爲這可能是由於這樣的事實,如果我有一個現有的一行該日期(日期是主鍵),我無法更新該行,所以我可能需要有一個IF行存在,更新,否則創建一個新行。

slots database

+0

作爲方法的參數爲:private void SaveSlots(DateTime的日期) – Hamoudy 2013-03-13 21:32:16

回答

3

試試這個,你不必打開每個環路連接,首先創建你的SQL語句通過每個價值循環,然後使用一個語句就插入

private string CreateInsertStatement(double time_began_5, double time_finished_5) 
{ 
    string sql = "INSERT INTO Slots ([Date],[RoomID],"; 
    string valuesql = " Values (@date,@room,"; 
    for (double Time = time_began_5; Time < time_finished_5; Time = Time + 0.5) 
    { 
    string Time1 = Time.ToString("0.00"); 
    sql+ = "[" + Time1 + "],"; 
    valuesql+ = "1,"; 
    } 
    sql = sql.TrimEnd(',') + ") "; 
    valuesql = valuesql.TrimEnd(',') + ") "; 

    return sql + valuesql; 
} 

private string CreateUpdateStatement(double time_began_5, double time_finished_5) 
{ 
    string sql = "UPDATE Slots SET "; 
    string wheresql = " WHERE [Date] = @date AND [RoomID] = @room"; 
    for (double Time = time_began_5; Time < time_finished_5; Time = Time + 0.5) 
    { 
     string Time1 = Time.ToString("0.00"); 
     sql+ = "[" + Time1 + "] = 1,";   
    } 
    sql = sql.TrimEnd(','); 
    return sql + wheresql; 
} 

然後,在你實際插入代碼:

try 
{ 
    SqlConnection cn = new SqlConnection("Data Source=.\\SqlExpress;Initial Catalog=AllensCroft;Integrated Security=True;MultipleActiveResultSets=True;Application Name=EntityFramework;"); 

    cn.Open(); 
    SqlCommand Command; 
    //check if row exists 
    Command = new SqlCommand("select count(*) from Slots WHERE [Date] = @date AND [RoomID] = @room", cn); 
    Command.Parameters.AddWithValue("date", date); 
    Command.Parameters.AddWithValue("room", rooms_combo.SelectedValue); 

    var cnt = Command.ExecuteScalar(); 
    if(cnt!=null) 
    { 
     string sqlstr = "" 
     if(Int32.Parse(cnt.ToString()) > 0) 
     { 
      sqlstr = CreateUpdateStatement(time_began_5,time_finished_5); 
     } 
     else if(Int32.Parse(cnt.ToString()) == 0) 
     { 
      sqlstr = CreateInsertStatement(time_began_5,time_finished_5); 
     } 
     Command = new SqlCommand(sqlstr, cn); 
     Command.Parameters.AddWithValue("date", date); 
     Command.Parameters.AddWithValue("room", rooms_combo.SelectedValue); 
     Command.ExecuteNonQuery(); 
    } 
    try 
    { 
     cn.Close(); 
    } 
    catch (Exception e) 
    { 
     Console.WriteLine(e.ToString()); 
    } 
} 
catch (Exception e) 
{ 
    Console.WriteLine(e.ToString()); 
} 
+0

感謝讓我的代碼更高效,但它只會將一列設置爲true,它只插入一個新行但不更新 – Hamoudy 2013-03-13 21:53:31

+0

這將根據您使用的time_finished_5值執行所有列嗎?你能調試並檢查它從CreateInsertStatement函數返回的值是什麼,並在這裏發佈? – 2013-03-13 21:55:16

+0

這是第一次在循環中的所有時間,謝謝,但是當我嘗試做同樣的過程,再次相同的日期不同的時間,它不會再更新,我們應該嘗試合併? – Hamoudy 2013-03-13 22:04:09

3

您正在做一個插入。 在每一個循環中插入一個新行,並僅爲名稱等於變量Time1的當前值的列設置值true。

對於其他列沒有值,它們可能默認爲false。 (bit列我想)

如果你想有一個默認爲true,每一列也許是更好的改變數據庫架構增加了對每一次列的默認,否則你需要的參數

編輯一個長長的清單如果你的邏輯決定了你需要每個日期只有一排,如果你進入上面的情況,那麼你可以使用存儲過程移動數據庫中的這個邏輯在每個時間列設置爲true:

CREATE PROCEDURE InsertOrUpdateSlotFromCode(@dt smalldatetime, @roomID int) 
AS 
BEGIN 
    DECLARE @cnt INT 
    SELECT @cnt = COUNT(*) from Slots WHERE [Date] = @dt 
    if @cnt = 0 
     INSERT INTO Slots ([Date],[RoomID], <here all the time fields> VALUES (@dt, @roomID, 1, ....) 
    else 
     UPDATE Slots SET [09.00] = 1, ..... WHERE [Date] = @dt 
    End 
END 

那麼你的代碼致電sp

using(SqlConnection cn = new SqlConnection(.........)) 
{ 
    cn.Open(); 
    SqlCommand Command = new SqlCommand("InsertOrUpdateSlotFromCode", cn); 
    Command.CommandType = CommandType.StoredProcedure; 
    Command.Parameters.AddWithValue("date", date); 
    Command.Parameters.AddWithValue("room", rooms_combo.SelectedValue); 
    Command.ExecuteNonQuery(); 
} 

當然現在你可以徹底擺脫循環

+0

沒有,我想for循環通道將它們自己改爲true,默認值應該是false,但是當for循環運行時,只有第一次變爲true。如果行已經存在,我將如何更新行? – Hamoudy 2013-03-13 21:40:40

+1

@Hamoudy,你將不得不包含一些邏輯來查看該鍵是否已經存在,並根據你找到的內容進行插入/更新。更好的方法是構建所有要插入的值,然後插入它們。你所說的基本上是執行1次插入操作,並且爲每一行填充至少12次更新(屏幕截圖中的列數)。如果你的數據庫管理員聽到你這樣做,他/她可能會讓你活着。 – 2013-03-13 21:43:26

+0

@steve,他正在動態計算列名稱,不確定他如何使用存儲過程來完成這一操作。 – 2013-03-13 21:58:47

相關問題