获取从 C# 中使用 OracleCommand 的函数返回的“PLSQL 表”

本文关键字:返回 函数 PLSQL OracleCommand 获取 | 更新日期: 2023-09-27 17:56:13

我是 C# 中使用 OracleCommand 从 Oracles 过程''函数返回结果的新手,我已经能够让我的大部分 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# 代码中解决此问题,只是因为有我无法编辑的现有函数。

我也看过与我类似的问题,但无法从中得到答案。

获取从 C# 中使用 OracleCommand 的函数返回的“PLSQL 表”

这个 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();
}

我认为您不能将用户定义的对象返回给Oracle数据提供程序。但是你可以返回一个 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);