执行一个在C#中返回引用游标的oracle函数

Con*_*rix 11 c# oracle odp.net

我有一个oracle包,其中包含一个带有输入引用游标的过程.我的理解是,这是非常标准的.

我不喜欢的是我必须编写大量代码才能看到输出.所以我问了这个问题,事实证明我可以通过创建一个包装程序的函数来得到我想要的东西.

更新:看起来我不再需要这个功能但是对于那些好奇的人来说可能值得知道,看看原来的问题和答案更新.

这是功能

FUNCTION GetQuestionsForPrint (user in varchar2)
  RETURN MYPACKAGE.refcur_question
AS  

    OUTPUT MYPACKAGE.refcur_question;

BEGIN 

      MYPACKAGE.GETQUESTIONS(p_OUTPUT => OUTPUT, 
      p_USER=> USER ) ;


  RETURN OUTPUT;
END;
Run Code Online (Sandbox Code Playgroud)

这就是我在SQL Developer中执行它的方法

var r refcursor;
exec :r := mypackage.getquestionsForPrint('OMG Ponies');
print r;
Run Code Online (Sandbox Code Playgroud)

所以从现在开始,我可能会将ForPrint函数添加到我的所有程序中.

这让我思考,也许功能是我想要的,我不需要程序.

为了测试这个我尝试从.NET执行该函数,除了我不能这样做.这真的是这样吗?

using (OracleConnection cnn = new OracleConnection("Data Source=Test;User Id=Test;Password=Test;"))
{
    cnn.Open();
    OracleCommand cmd = new OracleCommand("mypackage.getquestionsForPrint");
    cmd.CommandType = System.Data.CommandType.StoredProcedure;

    cmd.Parameters.Add ( "p_USER", "OMG Ponies");

    cmd.Connection = cnn;
    OracleDataReader rdr = cmd.ExecuteReader();

    while (rdr.Read())
    {
        Console.WriteLine(rdr.GetOracleValue(0));
    }

    Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)

所以我得到了错误.

getquestionsForPrint is not a procedure or is undefined

我也尝试了ExecuteScalar,结果相同.

编辑采取Slider345的建议我也尝试将命令类型设置为文本并使用以下语句,我得到无效的SQL语句

mypackage.getquestionsForPrint('OMG Poinies');
Run Code Online (Sandbox Code Playgroud)

var r refcursor; exec :r :=  mypackage.getquestionsForPrint('OMG Poinies'); 
Run Code Online (Sandbox Code Playgroud)

使用Abhi的变体命令文本

select mypackage.getquestionsForPrint('OMG Poinies') from dual
Run Code Online (Sandbox Code Playgroud)

结果

"0x61c4aca5"处的指令引用"0x00000ce1"处的内存.内存无法"读取".

我只是在错误的树上吠叫?

更新 尝试添加输出参数没有帮助.

cmd.Parameters.Add(null, OracleDbType.RefCursor, ParameterDirection.Output);
Run Code Online (Sandbox Code Playgroud)

不知道名称应该是什么,因为它的函数的返回值(我尝试过null,空字符串,mypackage.getquestionsForPrint),但在所有情况下它只会导致

ORA-06550:第1行第7列:PLS-00306:调用'getquestionsForPrint'时参数的数量或类型错误

最终编辑(希望如此)

显然,Guddie 在我做了3个月后问了一个类似的问题.他得到了答案

  • 将命令文本设置为匿名块
  • 将参数绑定到ref光标,设置要输出的方向
  • 呼叫执行非读者.
  • 然后使用您的参数

using (OracleConnection cnn = new OracleConnection("Data Source=Test;User Id=Test;Password=Test;"))
{
    cnn.Open();
    OracleCommand cmd = new OracleCommand("mypackage.getquestionsForPrint");
    cmd.CommandType = CommandType.Text;

    cmd.CommandText = "begin " +
              "    :refcursor1 := mypackage.getquestionsForPrint('OMG Ponies') ;"  +
              "end;";

    cmd.Connection = cnn;
    OracleDataAdapter da = new OracleDataAdapter(cmd);
    cmd.ExecuteNonQuery();

    Oracle.DataAccess.Types.OracleRefCursor t = (Oracle.DataAccess.Types.OracleRefCursor)cmd.Parameters[0].Value;
    OracleDataReader rdr = t.GetDataReader();
    while(rdr.Read())
        Console.WriteLine(rdr.GetOracleValue(0));

    Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)

小智 5

我没有用函数测试它,但是我的存储过程.我为refCursor指定了out参数.

command.Parameters.Add(new OracleParameter("refcur_questions", OracleDbType.RefCursor, ParameterDirection.Output));
Run Code Online (Sandbox Code Playgroud)

如果您能够使用CommandType.Text的函数.我想知道你是否可以尝试添加上面的参数,除了方向为:

ParameterDirection.ReturnValue
Run Code Online (Sandbox Code Playgroud)

我使用的是Oracle.DataAccess版本2.111.6.0