Oracle 函数不是过程或未定义。语句被忽略

Posted

技术标签:

【中文标题】Oracle 函数不是过程或未定义。语句被忽略【英文标题】:Oracle function is not a procedure or is undefined. Statement ignored 【发布时间】:2014-05-01 15:58:07 【问题描述】:

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

【问题讨论】:

What is wrong with my Oracle function? 导致问题的不是 PL/SQL 代码本身,而是您调用该函数的方式。如果您提供定义myCommand 和参数(OracleParameter 变量)的 c# 代码,那就太好了? @NicholasKrasnov 我添加了其余代码供您查看 登录的用户是否有权访问该功能?用户名是“MyID”还是其他 oracle 用户? @OldProgrammer 是的,因为我让该用户访问我编写的其他功能 Code for calling a function in a package from C# and ODP.NET的可能重复 【参考方案1】:

你只需要再定义一个参数,一个负责返回值的参数。这是一个例子:

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。到目前为止,它们是同义词,但它们的行为将来可能会改变。

【讨论】:

【参考方案2】:

已经有一段时间了,但这应该会让你朝着正确的方向前进......

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

【讨论】:

以上是关于Oracle 函数不是过程或未定义。语句被忽略的主要内容,如果未能解决你的问题,请参考以下文章

PLS-00221:“DISPLAY_TRANS”不是过程或未定义

ORACLE:错误错误(6,3):PL/SQL:SQL 语句被忽略和错误(8,3):PL/SQL:ORA-00933:SQL 命令未在过程中正确结束

检查jQuery中的未定义和空值

Oracle 终止会话过程

是否可以使 oracle 数据库过程忽略提交语句?

SCRIPT5009:“JSON”在 IE 10 中未定义属性“$”的值为 null 或未定义,不是函数对象