添加了 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方法的类中,我按顺序执行以下操作:

  1. 我首先使用AddInParameters和AddOutparameters添加参数
  2. 然后我调用 ExecuteReader 方法。

但我有时会得到"错误的数量或类型的参数"甲骨文异常。如果我拒绝使用这些方法,请继续使用标准方式(创建连接,然后是命令,然后逐个添加参数,打开连接并最终计算OracleCommand.ExecuteReader方法),则不会收到该错误。奇怪的是,我在应用程序的入口处使用这些方法,但我从未在那里遇到过任何例外。在执行 ExecuteReader 方法之前,我放置了一个断点来检查参数列表,一切似乎都很好,我的意思是所有参数都设置正确。你能告诉我我在这里错过了什么吗?

附言我使用 Oracle Data Provider for .NET (Oracle.Data.Access.dll)。

添加了 OracleCommand 参数,但抛出异常

你试过用OracleCommand.BindByName = true吗?

找到一个花了我 1.5 天的时间解决问题的方法真的感觉真好。正如我已经说过的,甲骨文是一个真正令人头疼的问题。这就像一个"我不想要这个,我不想要那个,我想要这样"的女孩。如此多的细节,如此多需要考虑的事情。那些为甲骨文疯狂的人说,这就是甲骨文健壮的原因。

经过长时间的争吵和无望的搜索@Dummy01建议我设置 OracleCommand.BindByName=true。我实际上没有立即尝试。我在 ODP.NET 文档中查找了该属性,并查看了我发现的内容:

如果 OracleCommand BindByName 属性设置为 false(默认值),则ODP.NET 假定参数已根据其位置绑定,并且所有参数都以正确的顺序指定。

这意味着,如果在存储过程中参数的顺序是p1,p2,p3,则必须以相同的顺序将这些参数添加到OracleCommand.Parameters中。否则可能会发生 2 件坏事:

  1. 更好的情况是你得到例外。假设您按 p1,p3,p2 的顺序传递它们,并且 p2 是类型编号,p3 是引用光标。数据库中的存储过程期望第二个参数是数字,第三个参数是 refcursor。但是由于参数传递的顺序与原始顺序不同,因此类型将不兼容,因此将引发异常。如果这些类型不同,那么您很幸运。

  2. 第二种也是最糟糕的情况是 p2 和 p3 属于相同的数据类型。我相信你可以猜到会发生什么:是的,你会为参数输入错误的值,这将 99% 导致与预期不同的结果。

    我希望任何处理 Oracle 存储过程的人都考虑到这一点,否则他们可能会失去工作。祝你好运