我正在尝试从C#调用Oracle函数,该函数返回多行,但它不起作用。这是我正在使用的功能:
create or replace function return_columns(
tableName IN varchar
)
return types.ref_c
as
c_result types.ref_c;
begin
open c_result for
select column_name
from all_tab_columns
where table_name = tableName;
return c_result;
end return_columns;
这是类型:
create or replace package types
as
type ref_c is ref cursor;
end;
我在C#代码中调用这样的函数:
OracleConnection oraConn = new OracleConnection("DATA SOURCE=MySource;PASSWORD=MyPassword;USER ID=MyID");
OracleCommand objCmd = new OracleCommand("MyID.RETURN_COLUMNS", oraConn);
objCmd.CommandType = CommandType.StoredProcedure;
OracleParameter oraParam = new OracleParameter("tableName", OracleType.VarChar);
oraParam.Value = "MY_TABLE";
oraCmd.Parameters.Add(oraParam);
oraConn .Open();
DataTable dt = new DataTable();
OracleDataAdapter ad = new OracleDataAdapter(objCmd);
ad.Fill(dt);
oraConn.Close();
它不断返回此错误:
'RETURN_COLUMNS' is not a procedure or is undefined ORA-06550: line 1, column 7: PL/SQL: Statement ignored
我的Oracle功能有什么问题?
答案 0 :(得分:4)
您只需要再定义一个参数,一个负责返回值的参数。这是一个例子:
OracleParameter retVal = new OracleParameter("retVal", OracleDbType.RefCursor);
retVal.Direction = ParameterDirection.ReturnValue;
注意#1: retVal
参数应首先添加到参数列表中,否则可能会收到ORA-00306: wrong number or type of arguments..
错误。
cmd.Parameters.Add(retVal); -- ReturnValue parameter is being added first
cmd.Parameters.Add(tabName); -- then goes everything else
注意#2:最好使用ODP for .NET而不是过时和弃用的Microsoft Oracle客户端(System.Data.OracleClient
)
注意#3:在PL / SQL代码中使用varchar2
数据类型而不是varchar
。截至目前,他们是同义词,但他们的行为可能在未来发生变化。
答案 1 :(得分:0)
已经有一段时间了,但这应该让你朝着正确的方向前进......
OracleParameter prm = cmd.CreateParameter();
prm.OracleDbType = OracleDbType.RefCursor;
prm.ParameterName = "retcurse";
prm.Direction = ParameterDirection.ReturnValue;
oraCmd.Parameters.Add(prm);
OracleRefCursor rc = (OracleRefCursor)prm.Value;
// Not sure about this next part off the top of my head...
OracleDataAdapter ad = new OracleDataAdapter(objCmd);
DataSet ds = new DataSet();
ad.Fill(ds, "retcurse", rc);
// May also be this
// ad.Fill(ds, "retcurse", (OracleRefCursor)(oraCmd.Parameters["retcurse"].Value));