添加了 OracleCommand 参数,但抛出异常
本文关键字:抛出异常 参数 OracleCommand 添加 | 更新日期: 2023-09-27 18:31:10
请您耐心等待我在下面编写的代码。我有两种方法:
public void AddInParameters(string parameterName, OracleDbType dbtype,
object value)
{
OracleParameter myparameter = new OracleParameter();
myparameter.ParameterName = parameterName;
myparameter.OracleDbType = dbtype;
myparameter.Value = value;
myparameter.Direction = ParameterDirection.Input;
this._parameters.Add(myparameter);
}
和
public void AddOutParameter(string parameterName, OracleDbType dbType)
{
OracleParameter myparameter = new OracleParameter();
myparameter.ParameterName = parameterName;
myparameter.OracleDbType = dbType;
myparameter.Direction = ParameterDirection.Output;
this._parameters.Add(myparameter);
}
私有字段_parameters的类型为列表。如您所见,这些方法分别创建输入和输出参数,并将它们添加到_parameters列表中。然后我有以下方法,它将采用 OracleCommand 并将列表中的所有参数添加到其中:
private void ProcessParameters(OracleCommand command)
{
foreach (OracleParameter myparameter in this._parameters)
{
command.Parameters.Add(myparameter);
}
}
这是我返回 OracleDataReader 的最后一个方法:
public OracleDataReader ExecuteReader(string commandText, CommandType commandType)
{
OracleDataReader returnValue = null;
OracleCommand myCommand = this.CreateCommand(commandText, commandType);
this.ProcessParameters(myCommand);
try
{
myCommand.Connection.Open();
returnValue = myCommand.ExecuteReader(CommandBehavior.CloseConnection);
}
catch (Exception ex)
{
throw new DatabaseException(ex.Message);
}
return returnValue;
}
所有这些方法都在数据访问层类库中。在我想调用ExcuteReader方法的类中,我按顺序执行以下操作:
- 我首先使用AddInParameters和AddOutparameters添加参数
- 然后我调用 ExecuteReader 方法。
但我有时会得到"错误的数量或类型的参数"甲骨文异常。如果我拒绝使用这些方法,请继续使用标准方式(创建连接,然后是命令,然后逐个添加参数,打开连接并最终计算OracleCommand.ExecuteReader方法),则不会收到该错误。奇怪的是,我在应用程序的入口处使用这些方法,但我从未在那里遇到过任何例外。在执行 ExecuteReader 方法之前,我放置了一个断点来检查参数列表,一切似乎都很好,我的意思是所有参数都设置正确。你能告诉我我在这里错过了什么吗?
附言我使用 Oracle Data Provider for .NET (Oracle.Data.Access.dll)。
你试过用OracleCommand.BindByName = true
吗?
找到一个花了我 1.5 天的时间解决问题的方法真的感觉真好。正如我已经说过的,甲骨文是一个真正令人头疼的问题。这就像一个"我不想要这个,我不想要那个,我想要这样"的女孩。如此多的细节,如此多需要考虑的事情。那些为甲骨文疯狂的人说,这就是甲骨文健壮的原因。
经过长时间的争吵和无望的搜索@Dummy01建议我设置 OracleCommand.BindByName=true。我实际上没有立即尝试。我在 ODP.NET 文档中查找了该属性,并查看了我发现的内容:
如果 OracleCommand BindByName 属性设置为 false(默认值),则ODP.NET 假定参数已根据其位置绑定,并且所有参数都以正确的顺序指定。
这意味着,如果在存储过程中参数的顺序是p1,p2,p3,则必须以相同的顺序将这些参数添加到OracleCommand.Parameters中。否则可能会发生 2 件坏事:
-
更好的情况是你得到例外。假设您按 p1,p3,p2 的顺序传递它们,并且 p2 是类型编号,p3 是引用光标。数据库中的存储过程期望第二个参数是数字,第三个参数是 refcursor。但是由于参数传递的顺序与原始顺序不同,因此类型将不兼容,因此将引发异常。如果这些类型不同,那么您很幸运。
-
第二种也是最糟糕的情况是 p2 和 p3 属于相同的数据类型。我相信你可以猜到会发生什么:是的,你会为参数输入错误的值,这将 99% 导致与预期不同的结果。
我希望任何处理 Oracle 存储过程的人都考虑到这一点,否则他们可能会失去工作。祝你好运