1

オラクルのプロシージャ\関数から結果を返すためにC#を使用OracleCommandするのは初めてです.storedProcedureの実行のほとんどを機能させることができましたが、次のことについてアドバイスが必要です.

以下は、レコードタイプから作成したテーブルを返す関数です

create or replace
function return_table return t_nested_table AS

v_ret   t_nested_table;

begin
  v_ret  := t_nested_table();

  v_ret.extend;
  v_ret(v_ret.count) := t_col(1, 'one');

  v_ret.extend;
  v_ret(v_ret.count) := t_col(2, 'two');

  v_ret.extend;
  v_ret(v_ret.count) := t_col(3, 'three');

  return v_ret;
end return_table;

タイプは次のように作成されました

create or replace
type t_col as object (
  i number,
  n varchar2(30)
);

t_col レコードのテーブル

create or replace
type t_nested_table as table of t_col;

C# で関数を実行したいとき、次のことを試しましたが、OracleDbType には PL\SQL テーブルの列挙型がないことに気付きました。

using (OracleConnection conn = new OracleConnection(connection))
            using (OracleCommand cmd = new OracleCommand())
            {
    cmd.Connection = conn;
    cmd.BindByName = true;
    cmd.CommandText = "return_table";
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.Add("\"v_ret\"", OracleDbType.Object, DBNull.Value, ParameterDirection.ReturnValue);
    conn.Open();
    try
    {
        cmd.ExecuteNonQuery();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

しかし、これは単にエラーをスローします:

Invalid parameter binding
Parameter name: "v_ret"

私は他の方法を試しましたが、これまでのところ何もうまくいきませんでした。

編集できない既存の関数がたくさんあるという理由だけで、C# コードでこれを修正する方法があることを願っています。

私も同様の質問を見ましたが、それらからの答えを見つけることができませんでした。

4

2 に答える 2

1

ユーザー定義オブジェクトを Oracle Data Provider に返すことはできないと思います。しかし、RefCursor を返すことができます:

create or replace
function return_table return SYS_REFCURSOR AS

v_ret   t_nested_table;
res SYS_REFCURSOR;

begin
  v_ret  := t_nested_table();

  v_ret.extend;
  v_ret(v_ret.count) := t_col(1, 'one');

  v_ret.extend;
  v_ret(v_ret.count) := t_col(2, 'two');

  v_ret.extend;
  v_ret(v_ret.count) := t_col(3, 'three');

  OPEN res for SELECT * from TABLE(v_ret);
  RETURN res;
end return_table;

次に、C# では次のようになります。

cmd.Parameters.Add("v_ret", OracleDbType.RefCursor, ParameterDirection.ReturnValue);
于 2015-06-14T19:37:10.500 に答える
1

この C# コードは役に立つかもしれません。独自に定義した Oracle の型でうまくいきました。

using (OracleCommand cmd = new OracleCommand())
{
    cmd.Connection = conn;
    cmd.CommandText = "select * from table(return_table())";
    cmd.CommandType = CommandType.Text;
    conn.Open();
    OracleDataReader rdr = cmd.ExecuteReader();
    while (rdr.Read())
    {
        Console.WriteLine(rdr.GetOracleDecimal(0));
        Console.WriteLine(rdr.GetOracleString(1));
    }
    conn.Close();
}
于 2015-06-14T18:56:48.113 に答える