Oracle函数不是过程或未定义。声明被忽略了

时间:2014-05-01 15:58:08

标签: sql oracle plsql stored-functions

我正在尝试从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功能有什么问题?

2 个答案:

答案 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));