【问题标题】:Parametric 'UPDATE' string running with no errors but not doing anything参数“更新”字符串运行没有错误但没有做任何事情
【发布时间】:2015-03-15 15:50:32
【问题描述】:

我最近将更新 SQL 字符串从 动态 SQL 字符串 更改为 参数 SQL 字符串。这是我以前的:

OleDbConnection conn = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + this.DBstring);
OleDbCommand comm = new OleDbCommand();
comm.CommandText = "UPDATE myTable SET MY_FIELD='" + myString + "' WHERE F_SERIAL = '"+mySerial+"'";
comm.CommandType = CommandType.Text;
comm.Connection = conn;
conn.Open();
comm.ExecuteNonQuery();
conn.Close();

这是我现在拥有的:

OleDbConnection conn = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + this.DBstring);
OleDbCommand comm = new OleDbCommand();
comm.CommandText = "UPDATE myTable SET MY_FIELD = @myString WHERE F_SERIAL = @mySerial";
comm.Parameters.Add("@mySerial",OleDbType.VarWChar).Value = mySerial;
comm.Parameters.Add("@myString",OleDbType.VarWChar).Value = myString;
comm.CommandType = CommandType.Text;
comm.Connection = conn;
conn.Open();
comm.ExecuteNonQuery();
conn.Close();

参数设置正确,从即时窗口开始(我只显示第一个,但第二个具有相同的结构):

>>> comm.Parameters[0];
{@myString}
    base {System.Data.Common.DbParameter}: {@myString}
    DbType: String
    Direction: Input
    IsNullable: false
    OleDbType: VarWChar
    ParameterName: "@myString"
    Precision: 0
    Scale: 0
    Size: 15
    SourceColumn: ""
    SourceColumnNullMapping: false
    SourceVersion: Current
    Value: "test ++ ìì''' "

然而,虽然第一个代码 sn-p 以前可以正常工作,但新代码却不行。没有引发错误,执行正常,但数据库中的值没有更新。有谁知道可能出了什么问题?我可能忘记做某事了吗? 抱歉这个愚蠢的问题,但我真的只有这个,无法弄清楚出了什么问题。

【问题讨论】:

  • 对于初学者来说,之前和之后的 SQL 是不一样的。在第二个中,您在 SQL 中为一个传递 2 个参数(没有 WHERE)
  • 这可能与此有关,也可能无关,但我注意到您的参数化命令,正如您所展示的,没有where 子句?
  • 对不起,我正在更新代码,我在复制代码时打错了。
  • 您确定要为@mySerial 设置值吗?
  • 尝试捕捉ExecuteNonQuery的返回值。它是一个整数,用于计算查询更改了多少行。如果它为零,则没有记录与 @mySerial 参数匹配,如果它是 1 或更多,那么您没有查看正确的数据库。 (你在连接字符串中使用 |DataDirectory| 吗?)

标签: c# sql ms-access oledb


【解决方案1】:

我终于解决了我的问题,这很奇怪。我会在这里添加一个答案,以防将来有人会发现它有帮助。

基本上,问题在于将参​​数添加到OleDbCommand 对象的Parameters 集合中的顺序。

在我的代码中,我是这样做的:

comm.CommandText = "UPDATE myTable SET MY_FIELD = @myString WHERE F_SERIAL = @mySerial"; //<-- defining the command text
comm.Parameters.Add("@mySerial",OleDbType.VarWChar).Value = mySerial; //<-- parameter "mySerial" before "myString"
comm.Parameters.Add("@myString",OleDbType.VarWChar).Value = myString; //<-- parameter "myString" after "mySerial"

但是,我使用的是myString 之前 mySerial,所以基本上得到的查询是:

UPDATE myTable SET MY_FIELD = mySerial WHERE F_SERIAL = myString

我想说,这有点奇怪,因为如果代码仅取决于它们在 Parameters 集合中的位置,那么使用参数名称(例如 @myString@mySerial)的原因是什么?

但是,现在问题已经解决了,显然其他人已经面临同样的问题here。正如问题的提问者所说的那样,OleDb 可以识别 您正在使用参数,但不能识别 您正在使用的参数 (???),因此一切都依赖于仅按它们在列表中的存储顺序。

我为这个“无用”的问题道歉,但我希望至少这个答案可能对像我这样的人有用参数在其列表中的顺序。

【讨论】:

  • 好吧,我早该被发现了。可能我现在有点累了。在 OleDB 中命名占位符的官方认可的方法是 ? 符号。碰巧 OleDb 在使用 Access 数据库(可能还有其他一些数据库)时允许参数占位符具有 @xxxx 形式的名称(可能是为了更好地向它的大表亲 Sql Server 移植),但这并不意味着您可以将它们按任何顺序放入参数集合中。
  • 对@Steve,这对我来说听起来有点奇怪。我会说调用参数意味着返回该参数,你不这么认为吗?无论如何,非常感谢您的帮助,除了这个问题仅由我自己和我的低注意力引起之外,您通过参数化为我的整体代码提供了一个很大的 +!
  • 别忘了 using 语句。在 SO 上再见。晚安
  • “如果代码只取决于它们在 Parameters 集合中的位置,那么使用参数名称(例如 @myString 或 @mySerial)的原因是什么?” - 就是这样System.Data.OleDb 有效。它不会阻止您使用@named 参数,但它也不注意名称;它只关心参数占位符在 CommandText 中出现的顺序(必须与创建参数的顺序相同)。
  • @GordThompson 是的,你是对的,我只是觉得这种行为具有误导性(在我看来,我们不应该使用这些名称)。基本上我们应该做的唯一用途是“?”,因为使用参数名称甚至可能使代码更具可读性,但会导致很大的混乱,因为(在我的情况下)myString 变为 mySerial,反之亦然,只是因为我定义它们的顺序.经验教训:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-24
  • 2012-09-07
  • 2016-10-02
  • 2013-09-28
  • 1970-01-01
相关资源
最近更新 更多