【问题标题】:OLEDB Command not generating a valid queryOLEDB 命令未生成有效查询
【发布时间】:2019-08-15 06:00:50
【问题描述】:

在我的 ASP.NET MVC 应用程序中,我有一个表单,用户可以在其中输入多个文本。 我想将这些输入保存为 OleDbCommand 参数以生成 SQL 脚本。不幸的是,它不起作用,我不知道为什么,因为我不知道生成了什么确切的脚本。

我之前使用过 OleDbCommand,它对于一个简单的脚本(只是一个带有 where 子句的更新)工作得很好。但现在我想在我的数据库中插入一个新行。

//Create OleDbCommand and add parameters
System.Data.OleDb.OleDbCommand myCommand = new System.Data.OleDb.OleDbCommand();
myCommand.Parameters.AddWithValue("", myNewMassnahme.Name); //This is a string
myCommand.Parameters.AddWithValue("", myUser.myLoginUser._MySpAppS.Encrypt_AES(myNewMassnahme.Projektleiter.A_ID)); //this is a string
myCommand.Parameters.AddWithValue("", myNewMassnahme.MassnahmenartID); //this is an int
myCommand.Parameters.AddWithValue("", myNewMassnahme.Umsetzungsweg); //this is a string
myCommand.Parameters.AddWithValue("", myNewMassnahme.Status_ID); //this is an int
myCommand.Parameters.AddWithValue("", myNewMassnahme.Massnahmenstart); //this is a DateTime
myCommand.Parameters.AddWithValue("", myNewMassnahme.Painpoint); //This is a string
myCommand.Parameters.AddWithValue("", myNewMassnahme.Loesung); //This is a string
myCommand.Parameters.AddWithValue("", myNewMassnahme.Beteiligte_User); //This is a string

//This is just to check what command is generated (but it only shows the query with the '?'
myCommand.CommandText = String.Format("INSERT INTO MASSNAHMEN (NAME, PROJEKTLEITER_AID, MASSNAHMENART_ID, UMSETZUNGSWEG, STATUS_ID, MASSNAHMENSTART, PAINPOINT, LOESUNG, BETEILIGTE_USER) VALUES (?, ?, ?, ?, ?, TO_DATE(?, 'dd/mm/yyyy hh24:mi:ss'), ?, ?, ?);", myCommand.Parameters);


DataSet myDS = new DataSet();

//Make query on DB
//myUser.myLoginUser._MySpAppS.RunSQL simply runs a query on my DB. It expects a string and optional OleDbCommand.Parameters. It return a DataSet
myDS = myUser.myLoginUser._MySpAppS.RunSQL("INSERT INTO MASSNAHMEN (NAME, PROJEKTLEITER_AID, MASSNAHMENART_ID, UMSETZUNGSWEG, STATUS_ID, MASSNAHMENSTART, PAINPOINT, LOESUNG, BETEILIGTE_USER) VALUES (?, ?, ?, ?, ?, TO_DATE(?, 'dd/mm/yyyy hh24:mi:ss'), ?, ?, ?);", myCommand.Parameters);

我没有收到任何错误消息,但我可以看到我的数据库中没有输入任何记录。我期待这样的查询:

INSERT INTO MASSNAHMEN
  (NAME, PROJEKTLEITER_AID, MASSNAHMENART_ID, UMSETZUNGSWEG, STATUS_ID, MASSNAHMENSTART, PAINPOINT, LOESUNG, BETEILIGTE_USER)
  VALUES( 'Test', 'Test_AID', 1, 'TEST_UMSETZUNGSWEG', 1, TO_DATE('15.08.2019 00:00:00', 'dd/mm/yyyy hh24:mi:ss'), 'Nothing works', 'Hopefully its getting better', 'Help!');

这是一个运行良好的示例:

System.Data.OleDb.OleDbCommand myCommand = new System.Data.OleDb.OleDbCommand();
myCommand.Parameters.AddWithValue("", role.Description);
myCommand.Parameters.AddWithValue("", role.ID);

DataSet myDS = new DataSet();
myDS = myUser.myLoginUser._MySpAppS.RunSQL("UPDATE Rollen SET DESCRIPTION=? WHERE ID=?;", myCommand.Parameters);

在 myDS 包含一个表之后,我可以看到我的数据库中的更改

【问题讨论】:

  • 如果你能分享minimal reproducible example,那就太棒了。这里的关键是它必须是这样的代码,这样我们就可以按原样复制和粘贴它,无需修改,然后在控制台应用程序中运行它。
  • @mjwills 它的值是:“INSERT INTO MARS$T_MASSNAHMEN (NAME, PROJEKTLEITER_AID, MASSNAHMENART_ID, UMSETZUNGSWEG, STATUS_ID, MASSNAHMENSTART, PAINPOINT, LOESUNG, BETEILIGTE_USER) VALUES ('?', '?' , ?, '?', ?, TO_DATE('?', 'dd/mm/yyyy hh24:mi:ss'), '?', '?', '?');"所以和以前一样。我使用 String.Format 是因为我试图读取命令,但是当我得到这个结果时,它对我没有用。您是否有其他建议我如何在填写值后读取查询?
  • @CaiusJard - 供将来参考,设置命令文本不会重置参数。添加参数的顺序,设置命令类型,文本,超时,所有这些东西都没有关系,只要它发生在执行之前。
  • 我不是说参数顺序。我只是指参数与其他属性。
  • 99% 的时间,开发人员声称“我的 insert..values 查询没有错误,也没有插入任何值”,他们在错误的数据库中查找。另外 1% 的时间,他们会在尝试使用 catch{} 来运行它并吞下异常

标签: c# oledb oledbcommand


【解决方案1】:

我解决了我的问题:DateTime 出了问题。 我变了:

myCommand.Parameters.AddWithValue("", myNewMassnahme.Massnahmenstart);

收件人:

myCommand.Parameters.AddWithValue("", myNewMassnahme.Massnahmenstart.ToShortDateString()); 

现在它按预期工作了

P.S.:我还删除了

中的小时部分
TO_DATE(?, 'dd/mm/yyyy')

【讨论】:

  • 那么你吞下了异常吗?顺便说一句,您不需要将日期格式化为字符串,将字符串传递给数据库,然后让数据库将其解析回日期。使用参数的整个想法是您可以将日期添加为日期,它作为日期发送到数据库并作为日期插入。如果有人在美国运行您的应用程序,它很可能会开始插入错误的日期,因为 toshortdatestring 是文化敏感的! docs.microsoft.com/en-us/dotnet/api/… 使用类型化参数可以避免这一切
【解决方案2】:

如果我这样做,我会这样做:

System.Data.OleDb.OleDbCommand myCommand = new System.Data.OleDb.OleDbCommand( SET A OLEDBCONNECTION HERE );
myCommand.CommandText = "INSERT INTO MASSNAHMEN (NAME, PROJEKTLEITER_AID, MASSNAHMENART_ID, UMSETZUNGSWEG, STATUS_ID, MASSNAHMENSTART, PAINPOINT, LOESUNG, BETEILIGTE_USER) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
myCommand.Parameters.AddWithValue("", myNewMassnahme.Name); //This is a string
myCommand.Parameters.AddWithValue("", myUser.myLoginUser._MySpAppS.Encrypt_AES(myNewMassnahme.Projektleiter.A_ID)); //this is a string
myCommand.Parameters.AddWithValue("", myNewMassnahme.MassnahmenartID); //this is an int
myCommand.Parameters.AddWithValue("", myNewMassnahme.Umsetzungsweg); //this is a string
myCommand.Parameters.AddWithValue("", myNewMassnahme.Status_ID); //this is an int
myCommand.Parameters.AddWithValue("", myNewMassnahme.Massnahmenstart); //this is a DateTime
myCommand.Parameters.AddWithValue("", myNewMassnahme.Painpoint); //This is a string
myCommand.Parameters.AddWithValue("", myNewMassnahme.Loesung); //This is a string
myCommand.Parameters.AddWithValue("", myNewMassnahme.Beteiligte_User); //This is a string

int numRecordsInserted = myCommand.ExecuteNonQuery();

你需要解决的问题,我不知道:

  • 您的 oledb 连接的名称,应传递给命令构造函数
  • 你的 db 表的名称:你在浏览代码时改变了主意

实际上,说“我会这样做”有点说谎。我要么使用强类型数据集,要么使用像 dapper、实体框架或 nhibernate 这样的 ORM。但曾几何时,在我知道这些数据访问助手的神奇之处之前,我会走这条费力的路线:)

【讨论】:

  • 不幸的是,这不起作用。我创建 OleDbCommand 只是为了填充参数并将它们传输到我们的库,剩下的就交给我们了。我已经用一个运行示例修改了我的帖子。
  • 你应该始终避免告诉试图帮助你的人一个简单的“它不起作用”——它不包含帮助解决问题的细节。总是说出为什么它不起作用,包括确切的错误 mrssages
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-03
相关资源
最近更新 更多