2012-10-09 36 views
0

我有一個使用ExecuteNonQuery()的顯式SQL更新命令更新SQL Server數據庫。但是,如果更新值與先前的更新相匹配(例如,我將列從1更改爲2,然後回到1,然後回到2,對於同一行),即使ExecuteNonQuery返回1,更新也不會發生。.NET中的SQL Server更新不起作用,但返回1行更新

當兩個連續的select語句完全相同時,我注意到類似的問題ExecuteQuery;我通過設置一個等於一個唯一值的變量來解決此問題,然後添加

AND the_unique_value = the_unique_value 

來選擇。但是,將此添加到更新不起作用。

下面是更新的.NET代碼:

(注TheValueTheKey都是字符串)

SqlConnection conn = new SqlConnection(SomeConnectionString); 
conn.Open(); 
try 
{ 
    SqlCommand cmd = new SqlCommand 
    ("update my_table " 
    + "set the_value = '" + TheValue + "' " 
    + "where the_key = '" + TheKey + "'" 
    , conn); 
    ReturnValue = cmd.ExecuteNonQuery(); 
} 
catch (Exception e) 
{ 
    ReturnValue = -2; 
} 
conn.Close(); 

這就是所謂的三倍。每次,TheKey是「1」。

第一次,TheValue是「1」; ReturnValue設置爲1,更新成功。

第二次,TheValue是「2」; ReturnValue設置爲1,更新成功。

第三次,TheValue再次爲「1」; SQL命令現在與第一次使用的 相同。 ReturnValue設置爲1,但不發生更新。

我可以在表中添加一個列,該列將包含一個虛擬值,僅用於確保每個更新都具有不同的SQL命令,但我不想用「不必要的」數據修改表。是否有另一種方式來獲得更新,因爲缺乏更好的工作,每次都會「提交」?

+0

所以在第三次執行後值是「2」? –

+0

是的,第三次執行後數據庫中的值是「2」。 –

+0

對於其中一個 - 你應該**從不**連接你的SQL語句並執行它們。這會將您的代碼打開爲SQL注入攻擊。相反:使用**參數化查詢**爲您的SQL語句提供參數;這不僅可以保護您免受SQL注入攻擊,而且通常也可以快得多 - 尤其是在重複執行時。 –

回答

0

如果您想在傳輸過程中將信息保存到數據庫中,您必須確實使用commit命令。如果你沒有提交,信息將不會在數據庫中更新。 你不需要額外的信息。

+1

只有在您使用交易時纔有效。 –

1

我會改變的SQL代碼看起來像......

using (SqlConnection conn = new SqlConnection("My Connection")) //just do a using block here 
{ 
    SqlCommand cmd = new SqlCommand(); 

    //you should never use string concatination here... ever.. 
    cmd.CommandText = "update myTable set foo = @foo where bar = @bar"; 
    cmd.Parameters.Add("@foo", "foo"); 
    cmd.Parameters.Add("@bar", "bar"); 


    conn.Open(); 
    cmd.Connection = conn; 
    cmd.ExecuteNonQuery(); 

} 

恢復將是一個,如果事情相匹配的數量。當然,如果命令中的數據是相同的,它將是相同的數據。

+0

有沒有辦法使用參數來設置多個值,還是我必須爲每個值定義一個單獨的參數? 例如例如: cmd.CommandText =「update myTable set @updateList where id = @Id」; cmd.Parameters.AddWithValue(「@ updateList」,「foo ='Foo',bar ='Bar'」); cmd.Parameters.AddWithValue(「@ Id」,Id); 對於這個問題,如果有一種方法可以一次設置多個值,是安全的還是與字符串連接一樣糟糕? –

+0

一個參數只能設置一個值。所以你將需要一個參數爲你打算設置的每個值。當你使用參數時,你正在防範SQL注入。當你使用字符串連接時,你需要知道 – iamkrillin

+0

理解 - 但這意味着我必須對代碼中要更新的列名進行硬編碼,因爲除字符串常量以外的任何東西都需要字符串連接。 –

0

事實證明,SQL Server與它無關 - 問題是,執行更新的.NET函數的AJAX調用從未真正調用該函數,而是執行了與該調用相關聯的「成功」代碼。添加一個具有唯一值的虛擬參數給該調用修復了它。