2012-10-09 40 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调用从未真正调用该函数,而是执行了与该调用相关联的“成功”代码。添加一个具有唯一值的虚拟参数给该调用修复了它。