使用 C# 中的 OracleCommand 获取从函数返回的 'PL\SQL Table'
Get 'PL\SQL Table' returned from a function with OracleCommand in C#
我刚开始使用 C# 中的 OracleCommand
来 return 来自 Oracle procedures\functions 的结果,我已经能够让我的大部分存储过程执行工作,但我在以下方面需要建议。
下面是一个 return 函数 table 我创建了一个记录类型
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 记录的 table
create or replace
type t_nested_table as table of t_col;
现在,当我想在 C# 中执行该函数时,我尝试了以下操作,但意识到 OracleDbType 没有 PL\SQL Table.
的枚举
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# 代码可能对您有用,它适用于您自己定义的 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();
}
我认为您不能 return Oracle 数据提供程序的用户定义对象。但是你可以 return 一个 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);
我刚开始使用 C# 中的 OracleCommand
来 return 来自 Oracle procedures\functions 的结果,我已经能够让我的大部分存储过程执行工作,但我在以下方面需要建议。
下面是一个 return 函数 table 我创建了一个记录类型
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 记录的 table
create or replace
type t_nested_table as table of t_col;
现在,当我想在 C# 中执行该函数时,我尝试了以下操作,但意识到 OracleDbType 没有 PL\SQL Table.
的枚举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# 代码可能对您有用,它适用于您自己定义的 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();
}
我认为您不能 return Oracle 数据提供程序的用户定义对象。但是你可以 return 一个 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);