代码之家  ›  专栏  ›  技术社区  ›  Gady

如何从Oracle函数返回RefCursor?

  •  9
  • Gady  · 技术社区  · 15 年前

    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))并返回一个光标。但是我需要使用C#和ODP.NET来获取游标来填充数据集,但是我一直得到一个空引用异常-“对象引用未设置为对象的实例”。这就是我所拥有的:

    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的信息和示例并不多。

    编辑: sqlCom.Parameters.Add("id", OracleDbType.Int32,ParameterDirection.Input).Value = 7; )因为这使得它很难实现为一个通用的RESTful web服务,但我保留它作为我的最后手段,但会使用存储过程代替。

    非常感谢您的帮助!

    1 回复  |  直到 15 年前
        1
  •  15
  •   Dan    10 年前

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

    另外,不要运行 从dual中选择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();}
    

    这是基于可以在%ora\u home%\Client\ODP.NET\samples\RefCursor\Sample5.csproj中找到的示例ODP

    这是一个很好的博客(除了马克·威廉姆斯之外没有其他人)展示了这项技术。 http://oradim.blogspot.com/2007/04/odpnet-tip-anonymous-plsql-and.html

    推荐文章