C# 参数化';更新';字符串运行时没有错误,但不执行任何操作

C# 参数化';更新';字符串运行时没有错误,但不执行任何操作,c#,sql,ms-access,oledb,C#,Sql,Ms Access,Oledb,我最近将更新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='" + m

我最近将更新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();
从即时窗口中正确设置了参数(我只显示第一个,但第二个具有相同的结构):

然而,虽然第一个代码段以前可以使用,但新的代码段不能使用。不会引发错误,执行正常,但数据库中的值不会更新。有人知道会出什么问题吗?我是不是忘了做点什么?
对不起,这个愚蠢的问题,但我真的没有什么比这个,不能找出什么是错的

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

基本上,问题在于将参数添加到
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
)的原因是什么

但是,问题现在已经解决了,显然其他人已经面临同样的问题。提问者正确地说,
OleDb
可以识别您使用的是一个参数,而不是您使用的参数(??),因此所有内容都只取决于它们在列表中的存储顺序


对于这个“无用”的问题,我深表歉意,但我希望至少这个答案可能会对某些人有用,像我一样,将来可能会因为参数列表中的顺序而在数小时内调试一个显然正确的代码而无法正常执行

对于初学者来说,前后的SQL不一样。在第二个示例中,您正在为SQL中的一个传递2个参数(no-WHERE),这可能与此有关,也可能与此无关,但我注意到您的参数化命令(如您所示)没有
WHERE
子句?抱歉,我正在更新代码,我在复制代码时输入了一个错误。您确定要为
@mySerial
设置一个值吗?请尝试捕获ExecuteOnQuery的返回值。它是一个整数,用于计算查询更改了多少行。如果为零,则没有与@mySerial参数匹配的记录;如果为1或更多,则说明您没有查看正确的数据库。(在连接字符串中使用| DataDirectory |吗?)。可能我现在有点累了。官方认可的在OleDB中命名占位符的方式是
符号。恰好OleDb在使用Access数据库(可能还有其他数据库)时,允许参数占位符以@xxxx的形式命名(可能是为了更好地移植到它的大表兄Sql Server),但这并不意味着可以在参数集合中按任何顺序排列。对@Steve,我只是觉得有点奇怪。我会说调用一个参数意味着返回那个参数,你不这么认为吗?无论如何,非常感谢你们的帮助,除了这个问题是我自己造成的和我的低关注度,你们给了我的整个代码一个大+和参数化!不要忘记using语句。再见。晚安“如果代码仅取决于它们在参数集合中的位置,那么使用@myString或@mySerial等参数名称的原因是什么?”-这就是
System.Data.OleDb
的工作方式。它不会阻止您使用@named参数,但它也不会注意名称;它只关心参数占位符在CommandText中的显示顺序(必须与创建参数的顺序相同)。@GordThompson是的,你是对的,我只是觉得这种行为有误导性(我认为我们不应该使用这些名称)。基本上,我们应该做的唯一用途是“?”,因为使用参数名甚至可能使代码更可读,但会导致很大的混乱,因为(在我的例子中)myString变成mySerial,反之亦然,这仅仅是因为我定义了它们的顺序。经验教训:)
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"
UPDATE myTable SET MY_FIELD = mySerial WHERE F_SERIAL = myString