2012-04-13 14 views
1

以下に記述するコードを調べてください。OracleCommandパラメータが追加されましたが、例外がスローされました

 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タイプの一覧は次のとおりです。私は2つの方法があります。ご覧のように、これらのメソッドは、それぞれInputパラメーターとOutputパラメーターを作成し、それらを_parametersリストに追加します。

 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; 

    } 

すべてのこれらのメソッドそして私は、OracleCommandを取ると、それにリスト内のすべてのパラメータが追加されます以下の方法を持っていますデータアクセス層クラスライブラリにあります。私は順番に、私は次の操作を行いExcuteReaderメソッドをコールするクラスでは:

  1. 私が最初にAddInParametersとそれから私は、ExecuteReaderメソッドを呼び出す
  2. AddOutparametersを使用してパラメータを追加します。

しかし、私はときには、誤った番号またはタイプの引数をOracle例外として取得します。これらのメソッドを使用することを拒否すれば、標準的な方法(接続の作成、コマンド、次にパラメータの追加、接続のオープン、最後にOracleCommand.ExecuteReaderメソッドの呼び出し)を実行します。奇妙なのは、私はアプリケーションの入口でこれらのメソッドを使用していますが、私はそこで例外を何度も得たことはありません。 ExecuteReaderメソッドの実行前に、すべてのパラメータが正しく設定されていることを確認するために、ブレークポイントを配置します。私がここで紛失していることを教えてください。

P.S.私はOracle Data Provider for .NET(Oracle.Data.Access.dll)を使用します。

+0

:私はあなたsuggested.Youは命の恩人であるかを試してみました後http://forums.asp.net/t/606602.aspx/1 –

答えて

2

私は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番目のパラメータが数値であり、3番目のパラメータがrefcursorであると想定しています。しかし、パラメータの受け渡しの順序が元のものと異なるため、型は互換性がなくなり、例外がスローされます。それらのタイプが異なる場合、あなたはラッキーです。
  2. 第2の悪いケースは、p2とp3の両方が同じデータ型であることです。私はあなたが何が起こるかを推測することができると確信しています:はい、あなたは間違った値を入力するでしょう、これは99%期待どおりの結果を引き起こすでしょう。

    Oracleストアドプロシージャを扱う人はこれを考慮に入れてください。そうしないと、仕事を失うことがあります。幸運ここで読む

3

OracleCommand.BindByName = trueを試しましたか?

+0

はい、それは仕事をしました。私は、あなたが与えたヒントに基づいて、私の質問に対する詳細な答えを書くつもりです。大いに感謝する。 –

+0

@Mike JM嬉しいことに、私はあなたを助けました。できるだけいつでも好きな答えを受け入れるようにしてください。 – Dummy01