执行,在C#返回一个指针引用一个Oracle功能 [英] Execute an oracle Function that returns a reference cursor in C#

查看:213
本文介绍了执行,在C#返回一个指针引用一个Oracle功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Oracle包在了参考光标有一个过程。我的理解是,这是非常标准。



我不喜欢的是,我不得不写一吨的代码,只看到输出。 所以我问这个问题,它原来我可以通过创建一个包装过程的功能得到我想要的东西。



更新:看起来像我不需要的功能了,但它可能是值得反正知道对于那些好奇看到原来的问题及答案更新。



下面是VARCHAR2功能

 功能GetQuestionsForPrint(用户)
返回MYPACKAGE.refcur_question
AS

输出MYPACKAGE.refcur_question;

BEGIN

MYPACKAGE.GETQUESTIONS(p_OUTPUT =>输出,
p_USER =>用户);


返回输出;
端;

和这里就是我做什么在SQL Developer中执行它。



  VAR  -  [R REFCURSOR; 
EXEC:R:= mypackage.getquestionsForPrint('OMG小马');
打印内容R;



所以从现在开始我可能会到ForPrint功能添加到我的所有过程。



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



要测试这个我试着从.NET执行的功能,但我不能这样做。 。这真的是事情是这样的。



 使用(为OracleConnection CNN =新的OracleConnection(数据源=测试;用户ID =测试;密码=测试;))
{
cnn.Open();
的OracleCommand CMD =新的OracleCommand(mypackage.getquestionsForPrint);
cmd.CommandType = System.Data.CommandType.StoredProcedure;

cmd.Parameters.Add(p_USER,OMG小马);

cmd.Connection = CNN;
OracleDataReader RDR = cmd.ExecuteReader();

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

到Console.ReadLine();
}



所以我得到的错误。



getquestionsForPrint不是一个过程或未定义



我试过的ExecuteScalar也具有相同的结果。



修改以Slider345的意见,我也试着设置命令类型为文本,并使用下面的语句,我得到
无效的SQL语句

  mypackage.getquestionsForPrint('OMG Poinies'); 

  VAR  -  [R REFCURSOR; EXEC:R:= mypackage.getquestionsForPrint('OMG Poinies'); 

使用ABHI的变化为命令文本

 从双
选择mypackage.getquestionsForPrint('OMG Poinies')

导致




在在0x00000ce10x61c4aca5
指令引用内存。在
内存不能为read。




我只是找错了树?



更新
试图添加一个输出参数没有帮助。

  cmd.Parameters.Add(NULL,OracleDbType.RefCursor,ParameterDirection.Output); 



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




ORA-06550:第1行,第7列:
PLS-00306:错号码或在调用
'getquestionsForPrint


<类型
参数/ BLOCKQUOTE>

最终编辑(希望)



显然Guddie问的 3个月我做了后,类似的问题。他得到了这是




    答案
  • 您的命令文本设置为一个匿名块

  • 绑定参数裁判光标设置

  • 的方向输出调用execute非读者。

  • 然后用你的参数






 使用(CNN的OracleConnection =新的OracleConnection(数据源=测试;用户ID =测试;密码=测试;))
{
cnn.Open();
的OracleCommand CMD =新的OracleCommand(mypackage.getquestionsForPrint);
cmd.CommandType = CommandType.Text;

cmd.CommandText =开头的+
:refcursor1:= mypackage.getquestionsForPrint('OMG小马'); +
结尾;

cmd.Connection = CNN;
OracleDataAdapter DA =新OracleDataAdapter(CMD);
cmd.ExecuteNonQuery();

Oracle.DataAccess.Types.OracleRefCursor T =(Oracle.DataAccess.Types.OracleRefCursor)cmd.Parameters [0] .value的;
OracleDataReader RDR = t.GetDataReader();
,而(rdr.Read())
Console.WriteLine(rdr.GetOracleValue(0));

到Console.ReadLine();
}


解决方案

我还没有测试过这一个功能,但我的存储过程。我指定REFCURSOR OUT参数。

  command.Parameters.Add(新的OracleParameter(refcur_questions,OracleDbType.RefCursor, ParameterDirection.Output)); 

如果你能够获得与CommandType.Text工作的功能。我不知道你可以尝试添加上面的参数除了与方向:

  ParameterDirection.ReturnValue 

我使用Oracle.DataAccess版本2.111.6.0


I have an oracle package with a procedure that has a in out reference cursor. My understanding is that this is pretty standard.

What I didn't like is the fact that I had to write a ton of code to just see the output. So I asked this question and it turns out I can get what I want by creating a function that wraps the procedure.

Update: Looks like I don't need the function anymore but it may be worth knowing anyway for those curious see the original question and answer updates.

Here's the function

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;

and here's what I do to execute it in SQL Developer

var r refcursor;
exec :r := mypackage.getquestionsForPrint('OMG Ponies');
print r;

So from now on I'm probably going to add the ForPrint functions to all my procedures.

This got me thinking, maybe functions are what I want and I don't need procedures.

To test this I tried executing the function from .NET, except I can't do it. Is this really the way it is.

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

So I get the error.

getquestionsForPrint is not a procedure or is undefined

I tried ExecuteScalar as well with the same result.

EDIT Taking Slider345's advice I've also tried setting the command type to text and using the following statement and I get invalid SQL statement

mypackage.getquestionsForPrint('OMG Poinies');

and

var r refcursor; exec :r :=  mypackage.getquestionsForPrint('OMG Poinies'); 

Using Abhi's variation for the command text

select mypackage.getquestionsForPrint('OMG Poinies') from dual

resulted in

The instruction at "0x61c4aca5" referenced memory at "0x00000ce1". The memory could not be "read".

Am I just barking up the wrong tree?

Update Attempting to add an output parameter doesn't help.

cmd.Parameters.Add(null, OracleDbType.RefCursor, ParameterDirection.Output);

Not sure what the name should be since its the return value of a function (I've tried null, empty string, mypackage.getquestionsForPrint) but in all cases it just results in

ORA-06550: line 1, column 7: PLS-00306: wrong number or types of arguments in call to 'getquestionsForPrint'

Final Edit (hopefully)

Apparently Guddie asked a similar question 3 months after I did. He got the answer which is to

  • Set your command text to an anonymous block
  • Bind a parameter to the ref cursor setting the direction to output
  • Call Execute non reader.
  • Then use your parameter

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

解决方案

I have not tested this with a function, but for my stored procedures. I specify the out parameter for the refCursor.

command.Parameters.Add(new OracleParameter("refcur_questions", OracleDbType.RefCursor, ParameterDirection.Output));

If you are able to get the function to work with the CommandType.Text. I wonder if you can try adding the parameter above except with the direction as:

ParameterDirection.ReturnValue

I am using Oracle.DataAccess version 2.111.6.0

这篇关于执行,在C#返回一个指针引用一个Oracle功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆