执行,在C#返回引用光标一个oracle功能

问题描述 投票:10回答:4

我有一个Oracle包与在出的参照光标具有一个过程。我的理解是,这是非常标准。

我不喜欢的是,我不得不写一吨的代码,只看到输出的事实。 So I asked this question它原来我可以通过创建一个包装程序的功能得到我想要的东西。

更新:看起来像我不需要的功能了,但它可能是值得知道,无论如何,那些好奇的看原来的问题和回答的更新。

这里的功能

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;

这里就是我做SQL Developer来执行它

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

所以从现在开始我可能会到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();
}

所以我得到的错误。

getquestionsForPrint is not a procedure or is undefined

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

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

mypackage.getquestionsForPrint('OMG Poinies');

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

使用ABHI的变化为命令文本

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

导致

在“0x61c4aca5”指令在“0x00000ce1”引用的内存。该内存不能为“read”。

我只是找错了树?

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

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

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

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

最后编辑(希望)

显然Guddie问similar question我做了3个月后。他得到了这对答案

  • 命令文本设置为匿名块
  • 结合一个参数到REF光标设定的方向输出
  • 调用execute非读者。
  • 然后使用你的参数

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();
}
c# oracle odp.net
4个回答
5
投票

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

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

如果你能得到与CommandType.Text工作的功能。我不知道你是否可以尝试添加上述除与方向参数:

ParameterDirection.ReturnValue

我使用Oracle.DataAccess版本2.111.6.0


1
投票

我不得不去了,问题和答案之间上下找出完整的代码工作。所以我给的全部代码在这里,为我工作的人 -

var sql = @"BEGIN :refcursor1 := mypackage.myfunction(:param1) ; end;";
using(OracleConnection con = new OracleConnection("<connection string>"))
using(OracleCommand com = new OracleCommand())
{
     com.Connection = con;
     con.Open();
     com.Parameters.Add(":refcursor1", OracleDbType.RefCursor, ParameterDirection.Output);
     com.Parameters.Add(":param1", "param");
     com.CommandText = sql;
     com.CommandType = CommandType.Text;
     com.ExecuteNonQuery();
     OracleRefCursor curr = (OracleRefCursor)com.Parameters[0].Value;
     using(OracleDataReader dr = curr.GetDataReader())
     {
         if(dr.Read())
         {
             var value1 = dr.GetString(0);
             var value2 = dr.GetString(1);
         }
     }
 }

希望能帮助到你。


0
投票

我的猜测是,你不能调用一个函数类型的Command对象“的StoredProcedure”。你可以尝试类型的“文本”命令对象和命令文本中执行的是功能?


0
投票

我知道这是一个很老的文章,但因为它花了这么久找出所有参与让.NET“战斗好”与甲骨文的细节,我想我应该把这个意见在那里为容纳任何人这个棘手的问题。

我经常打电话,在我们的环境中(.NET 3.5反对的Oracle 11g)返回REF_CURSOR Oracle存储过程。对于一个功能,你的确可以将参数命名为任何你想,但你需要设置其System.Data.ParameterDirection = ParameterDirection.ReturnValue然后ExecuteNonQueryOracleCommand对象。在这一点上该参数的值将是甲骨文函数返回的ref_cursor。只投中值通过OracleDataReaderOracleDataReader和循环。

我会发布完整的代码,但我几年前写在VB.NET数据访问层,代码使用了该数据访问层(我们的企业内部网)的大部分是在C#。我想在一个单一的响应混合语言将是更大的失礼。

© www.soinside.com 2019 - 2024. All rights reserved.