6

Oracle関数に基づくデータベースAPIを提供する製品を使用しており、一般にODP.NETを介して関数を呼び出すことができます。ただし、アウトパラメータとして参照カーソルを含む関数を呼び出す方法がわかりません。これまでに見つけたすべてのサンプルは、Outパラメーターを使用してプロシージャを呼び出すか、戻り値としてRefCursorを使用して関数を呼び出します。同様にパラメータを定義しようとしましたが、間違った数またはタイプのパラメータが指定されているというエラーが発生し続けます。

関数ヘッダーは次のとおりです(明らかにわかりにくい):

FUNCTION GetXYZ(
   uniqueId       IN   somepackage.Number_Type,
   resultItems    OUT  somepackage.Ref_Type)
   RETURN somepackage.Error_Type;

これらは「somepackage」の型定義です。

SUBTYPE Number_Type IS NUMBER(13);
TYPE Ref_Type IS REF CURSOR;
SUBTYPE Error_Type IS NUMBER;

そして、これは私が試したコードです:

string sql = "otherpackage.GetXYZ";
var getXYZCmd = OracleCommand oracleConnection.CreateCommand(sql);
getXYZCmd.CommandType = CommandType.StoredProcedure;

getXYZCmd.Parameters.Add("uniqueId", OracleDbType.Int32).Value = uniqueExplosionId;
getXYZCmd.Parameters.Add("resultItems", OracleDbType.RefCursor).Direction = ParameterDirection.Output;
getXYZCmd.Parameters.Add("return_value", OracleDbType.Int32).Direction = ParameterDirection.ReturnValue;

関数を呼び出すために、次のさまざまな方法を試しました(もちろん、一度に1つだけ)。

var result = getXYZCmd.ExecuteNonQuery();
var reader = getXYZCmd.ExecuteReader();
var scalarResult = getXYZCmd.ExecuteScalar();

しかし、それぞれがエラーメッセージで失敗します。

Oracle.DataAccess.Client.OracleException: ORA-06550: line 1, column 15:
PLS-00306: wrong number or types of arguments in call to 'GETXYZ'
ORA-06550: line 1, column 15:
PLS-00306: wrong number or types of arguments in call to 'GETXYZ'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored.

では、ODP.NETを使用してC#から出力パラメーターとして参照カーソルを使用して関数を呼び出すことは一般的に可能ですか?RefCursorの代わりにVarchar2-Out-parameterを使用して同じ構造の関数を問題なく呼び出すことができます...

ところで、私はVisual Studio 2008のC#.NET3.5のODP.NETバージョン2.112.2.0を使用しています。

よろしくお願いします!

4

1 に答える 1

10

きっとできます。注意すべき落とし穴がいくつかありますが、ここにテストケースがあります

create or replace function testodpRefCursor(
                  uniqueId    IN NUMBER 
                 ,resultItems OUT NOCOPY SYS_REFCURSOR) RETURN NUMBER
                 IS

 BEGIN
      OPEN resultItems for select level from dual  connect by level < uniqueId ;
      return 1;
 END testodpRefCursor;
  1. 関数は、コレクション内の最初のパラメーターとして ReturnValue を持つのが好きであることがわかりました
  2. BindByName はデフォルトで FALSE であるため、デフォルトで BIND BY POSITION になります。

それ以外の場合は、非常に簡単です。

  OracleCommand cmd = new OracleCommand("TESTODPREFCURSOR", con);
  cmd.CommandType   = CommandType.StoredProcedure;
  cmd.BindByName = true;
  // Bind 


  OracleParameter oparam = cmd.Parameters.Add("ReturnValue", OracleDbType.Int64);
  oparam.Direction = ParameterDirection.ReturnValue ;       

  OracleParameter oparam0 = cmd.Parameters.Add("uniqueId", OracleDbType.Int64);
  oparam0.Value = 5 ;
  oparam0.Direction = ParameterDirection.Input;

  OracleParameter oparam1 = cmd.Parameters.Add("resultItems", OracleDbType.RefCursor);
  oparam1.Direction = ParameterDirection.Output;




  // Execute command
  OracleDataReader reader;
  try
  {
    reader = cmd.ExecuteReader();

    while(reader.Read() ){
        Console.WriteLine("level: {0}", reader.GetDecimal(0));  
    }

  } ...

その他のサンプルについては、Oracle ホーム ディレクトリに移動し、ODP.NET の Ref カーソル サンプルを参照してください。

例: %oracle client home%\odp.net\samples\4\RefCursor

h番目

于 2011-06-15T16:48:49.037 に答える