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

时间:2012-04-13 04:58:14

标签: c# oracle parameters

请您耐心看看我将在下面写的代码。我有两种方法:

     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的类型为List。如您所见,这些方法分别创建输入和输出参数,并将它们添加到_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. 添加参数
  3. 然后我调用ExecuteReader方法。
  4. 但我有时会得到“错误的数字或类型的参数”Oracle异常。如果我拒绝使用这些方法,继续使用标准方式(创建连接,然后命令,然后逐个添加参数,打开连接,最后调用OracleCommand.ExecuteReader方法)我没有得到该错误。奇怪的是我在申请入口处使用这些方法,但我从来没有遇到过任何例外。我在ExecuteReader方法的执行之前设置了一个断点来检查参数列表,一切都很好看,我的意思是所有参数都设置正确。你能否告诉我这里缺少什么。

    P.S。我使用Oracle数据提供程序for .NET(Oracle.Data.Access.dll)。

2 个答案:

答案 0 :(得分:4)

您是否尝试使用OracleCommand.BindByName = true

答案 1 :(得分:2)

找到解决我1.5天的问题的解决方案真的很棒。正如我已经说过的,甲骨文真的很头疼。这就像是“我不想要这个,我不想要那个,我想要这样”女孩。这么多细节,需要考虑很多事情。那些对甲骨文疯狂的人说,这就是让Oracle健壮的原因。

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

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

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

  1. 更好的情况是你得到例外。假设您按p1,p3,p2的顺序传递它们,p2的类型为数字,p3是refcursor。数据库中的存储过程需要第二个参数为数字,第三个参数为refcursor。但由于参数传递的顺序与原始顺序不同,因此类型将不兼容,因此将引发异常。如果这些类型不同,你很幸运。
  2. 第二个和更糟的情况是p2和p3都具有相同的数据类型。我相信你可以猜到会发生什么:是的,你会为参数输入错误的值,这将导致99%的结果与预期不同。

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