C# 数据库命令对象的参数顺序真的很重要吗?
我正在调试一个数据库操作代码,我发现虽然代码从未失败,但从未进行过正确的更新。代码如下:C# 数据库命令对象的参数顺序真的很重要吗?,c#,database,ms-access,oledbcommand,dbcommand,C#,Database,Ms Access,Oledbcommand,Dbcommand,我正在调试一个数据库操作代码,我发现虽然代码从未失败,但从未进行过正确的更新。代码如下: condb.Open(); OleDbCommand dbcom = new OleDbCommand("UPDATE Word SET word=?,sentence=?,mp3=? WHERE id=? AND exercise_id=?", condb); dbcom.Parameters.AddWithValue("id", wd.ID);
condb.Open();
OleDbCommand dbcom = new OleDbCommand("UPDATE Word SET word=?,sentence=?,mp3=? WHERE id=? AND exercise_id=?", condb);
dbcom.Parameters.AddWithValue("id", wd.ID);
dbcom.Parameters.AddWithValue("exercise_id", wd.ExID);
dbcom.Parameters.AddWithValue("word", wd.Name);
dbcom.Parameters.AddWithValue("sentence", wd.Sentence);
dbcom.Parameters.AddWithValue("mp3", wd.Mp3);
但经过一些调整后,这起到了作用:
condb.Open();
OleDbCommand dbcom = new OleDbCommand("UPDATE Word SET word=?,sentence=?,mp3=? WHERE id=? AND exercise_id=?", condb);
dbcom.Parameters.AddWithValue("word", wd.Name);
dbcom.Parameters.AddWithValue("sentence", wd.Sentence);
dbcom.Parameters.AddWithValue("mp3", wd.Mp3);
dbcom.Parameters.AddWithValue("id", wd.ID);
dbcom.Parameters.AddWithValue("exercise_id", wd.ExID);
更新:我去掉了
?
,包括了带和不带@
的专有名称。订单真的很重要。在这两种情况下,只有在最后提到WHERE子句参数时,才发生实际更新。更糟糕的是,在复杂的查询中,我们很难知道访问所需的顺序,而且在顺序发生更改的所有情况下,查询都不会在没有警告/错误的情况下完成预期的任务 顺序很重要,因为使用了?命令字符串中的占位符
如果要按任意顺序列出参数,最好使用命名参数,如@word、@句子等
condb.Open();
OleDbCommand dbcom = new OleDbCommand("UPDATE Word SET word=@word,sentence=@sentence,mp3=@mp3 WHERE id=@id AND exercise_id=@exercise_id", condb);
dbcom.Parameters.AddWithValue("@id", wd.ID);
dbcom.Parameters.AddWithValue("@exercise_id", wd.ExID);
dbcom.Parameters.AddWithValue("@word", wd.Name);
dbcom.Parameters.AddWithValue("@sentence", wd.Sentence);
dbcom.Parameters.AddWithValue("@mp3", wd.Mp3);
在Access中,
ADODB.Command
对象忽略参数名。事实上,我可以使用假名称引用参数(SQL语句中甚至不存在该名称),ADO对此并不在意。它所关心的似乎只是以与SQL语句中的参数完全相同的顺序提供参数值。顺便说一句,如果我用?
占位符而不是命名参数构建SQL语句,也会发生这种情况
虽然我知道你的问题是关于c#和
OleDbCommand
,但在我看来,Dot.Net的OleDbCommand
可能与Access'ADODB.Command
的操作相同。不幸的是,我不知道Dot.Net。。。但这是我的直觉。:-) 我一直在对Access DB使用OleDbCommand及其参数集合进行一些测试。参数的排序当然是必要的,因为这是必要的。但在使用问号作为占位符时,可能会遇到一个问题
假设在Access DB中有一个查询(“存储过程”),如下所示,这里非常简化:
parameters
prmFirstNumber Long,
prmSecondNumber Long;
select
fullName
from
tblPersons
where
numberOfCars < prmFirstNumber And
numberOfPets < prmSecondNumber And
numberOfBooks beteween prmFirstNumber And prmSecondNumber
所以,正如您所看到的,我可以像命名参数一样处理它,并且不必为它们的排序而烦恼
RetrievedClareDJetParametersOrder当然会增加额外的执行时间,因为它涉及到对DB的额外调用,在DB中检索SQL文本,然后解析出参数名称和类型。您的查询模板是否缺少一些为参数槽命名的语法?在没有名称的情况下,库可能会假定您希望按照名称出现的顺序填充它们。您是否希望数据库引擎随机选择模板中出现在
?
附近的单词,并假设这是您要使用的名称?@Henning Makholm,哦,可能就是这样。让我看看是不是…@Henning Makholm,不,不是这样的。我去掉了?
,包括了带和不带@
的专有名称。订单真的很重要。在这两种情况下,只有在最后提到WHERE子句参数时,才发生实际更新。可能与OleDbCommand类有关。“可能与OleDbCommand类有关。”-它与OLEDB本身有关。参数是严格位置的。在大多数(如果不是全部的话)情况下,我们可以为参数指定名称(而不是将它们全部称为“?”
),但是这些名称会被忽略。不,这不起作用。我的意思是,这段代码只按照您提到的顺序工作,而不是按照我第一篇文章中有趣的顺序(即使没有占位符)——可能是MS Access/OleDbCommand组合特有的(我用SQL Server尝试了我以前的解决方案,效果很好)。也许试试最新的答案?我都试过了。只有在最后给出WHERE参数时,它才起作用。我的意思是必须维持秩序。是的,是MS Access。MySQL也没有这个问题。汉斯,如果是这样的话,我觉得很沮丧。有了一些复杂的问题,我究竟该如何知道访问的顺序呢。使用sqlite或mysql非常简单。如果你不懂.NET,你应该学习它。这太棒了:)嗯。如果你能从.NET找到一种使用DAO
的方法(可能是互操作程序集?),你可能会更高兴,因为通过DAO.QueryDef
执行的查询似乎像我想的那样尊重参数名(IIRC)。至于使用ADO的参数顺序要求,这对我来说并不是很大的负担。。。也许是因为我已经做了这么多年了。这听起来很诱人,我最终会到达那里。。。但不要屏住呼吸。:-)我不明白阿多刀的事。我已经将sqlite和mysql与ADO.NET连接器一起使用。他们不要求保留订单。只有oledb需要。那么这是否意味着它与ADO无关,也与MS Access有关?参数顺序不是DAO plus Access的问题,而是ADO/OleDb plus Access的问题。所以我认为这是ADO/OleDb plus访问组合特有的东西,而不是访问本身特有的东西。我一直在寻找正确的答案。再次感谢第一句提供的信息+1。谢谢答案的其余部分是否回答了这里的具体问题?谢谢nawfal,是的,我认为它回答了,另外还提到了一些关于您可能遇到的奇怪和意外情况的相关警告,以及如何避免这些问题。嗯,我喜欢Jet/Ace引擎,它的工作做得不错,但是伙计,Office套件下MS提供的GUI太可怕了!20世纪的桂
Dim cmd As New OleDbCommand("qryInAccessDB", Conn)
cmd.CommandType = CommandType.StoredProcedure
Conn.Open()
retrieveDeclaredJetParametersInOrder(cmd)
cmd.Parameters("prmOneOfTheParametersPerhapsTheLastOneDeclared").Value = 1
cmd.Parameters("prmAnotherone").Value = 20
cmd.Parameters("prmYetAnotherPerhapsTheFirstOneDeclared").Value = 300
cmd.ExecuteNonQuery()
Conn.Close()