当前位置:  开发笔记 > 编程语言 > 正文

如何从Oracle函数返回RefCursor?

如何解决《如何从Oracle函数返回RefCursor?》经验,为你挑选了1个好方法。

我正在尝试执行用户定义的Oracle函数,该函数使用ODP.NET返回RefCursor.这是功能:

CREATE OR REPLACE FUNCTION PKG.FUNC_TEST (ID IN TABLE.ID%type)
   RETURN SYS_REFCURSOR
AS
   REF_TEST   SYS_REFCURSOR;
BEGIN
   OPEN REF_TEST FOR
      SELECT   *
        FROM   TABLE;
   RETURN REF_TEST;
END;
/

我可以在Toad中调用此函数(从dual中选择func_test(7))并返回CURSOR.但是我需要使用C#和ODP.NET来获取光标以填充DataSet,但我不断得到NullReferenceException - "对象引用未设置为对象的实例".以下是我的意见:

OracleConnection oracleCon = new OracleConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString);
OracleCommand sqlCom = new OracleCommand("select func_test(7) from dual", oracleCon);
sqlCom.Parameters.Add("REF_TEST", OracleDbType.RefCursor, ParameterDirection.ReturnValue);
OracleDataAdapter dataAdapter = new OracleDataAdapter();
dataAdapter.SelectCommand = sqlCom;

DataSet dataSet = new DataSet();
dataAdapter.Fill(dataSet);  //FAILS HERE with NullReferenceException

我能够在使用存储过程和ODP.NET时找到大量信息和示例,但对于从函数返回RefCursors并没有那么多.

编辑: 我不想显式地将输入参数添加到OracleCommand对象(即sqlCom.Parameters.Add("id", OracleDbType.Int32,ParameterDirection.Input).Value = 7;),因为这使得很难将其作为通用RESTful Web服务实现,但我将其作为我的最后手段,但将使用存储过程.

任何帮助深表感谢!



1> Harrison..:

我想你错过了sqlCom.ExecuteNonQuery();

另外,不是从dual运行select func_test(7); 让我们切换它来运行函数并传入参数

  OracleConnection oracleCon = new OracleConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString);


  // Set the command

  string anonymous_block = "begin " +
                              "  :refcursor1 := func_test(7) ;" +
                              "end;";  
 //fill in your function and variables via the above example
  OracleCommand sqlCom= con.CreateCommand();
  sqlCom.CommandText = anonymous_block;

  // Bind 
  sqlCom.Parameters.Add("refcursor1", OracleDbType.RefCursor);
  sqlCom.Parameters[0].Direction = ParameterDirection.ReturnValue;

  try 
  {
    // Execute command; Have the parameters populated
    sqlCom.ExecuteNonQuery();

    // Create the OracleDataAdapter
    OracleDataAdapter da = new OracleDataAdapter(sqlCom);

    // Populate a DataSet with refcursor1.
    DataSet ds = new DataSet();
    da.Fill(ds, "refcursor1", (OracleRefCursor)(sqlCom.Parameters["refcursor1"].Value));

    // Print out the field count the REF Cursor
    Console.WriteLine("Field count: " + ds.Tables["refcursor1"].Columns.Count);
  }
  catch (Exception e)
  {
    Console.WriteLine("Error: {0}", e.Message);
  }
  finally
  {
    // Dispose OracleCommand object
    cmd.Dispose();

    // Close and Dispose OracleConnection object
    con.Close();
    con.Dispose();}

这是基于可以找到的示例ODP @%ora_home%\ Client_1\ODP.NET\samples\RefCursor\Sample5.csproj

如果你想避免(为了更好或更差!)每个proc/function调用的自定义构建的param集合你可以通过在代码中使用匿名块来解决这个问题,我已经修改了(再次未经测试!)上面的代码来反映这种技术.这是一个很好的博客(来自马克威廉姆斯),展示了这种技术. http://oradim.blogspot.com/2007/04/odpnet-tip-anonymous-plsql-and.html

推荐阅读
有风吹过best
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有