【问题标题】:How to call an Oracle function with a Ref Cursor as Out-parameter from Visual Basic如何使用 Ref 游标作为 Visual Basic 的 Out-parameter 调用 Oracle 函数
【发布时间】:2021-01-08 05:56:24
【问题描述】:

我正在尝试调用从 VB 中返回 SYS_REFCURSOR 的 Oracle 函数。我能够使用存储过程检索数据。我尝试调用 oracle 函数的方式相同,但它给出了错误。

是否有人可以提供帮助?谢谢。如果需要,我会提供屏幕截图。

Function in DB end
====================

PKG BODY

FUNCTION GET_ALLCUST RETURN SYS_REFCURSOR AS 
  getallcursor SYS_REFCURSOR; 
BEGIN
    OPEN getallcursor FOR SELECT * FROM CUSTOMER; 
    RETURN getallcursor; 
CLOSE getallcursor;
END;

PKG Spec
==============

create or replace PACKAGE GetAllProdPckg AS
   PROCEDURE GetAllProd;
   PROCEDURE get_allprod_viasqldev;
   PROCEDURE get_allcust_viasqldev;
   FUNCTION get_allcust RETURN SYS_REFCURSOR;
   function GET_ALLPROD_FROM_DB RETURN SYS_REFCURSOR;
   
   END GetAllProdPckg;

** 错误 **

System.NullReferenceException: '对象引用未设置为对象的实例。

我的代码 ======================================= ====================================

    Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
        Dim rvConn As Oracle.DataAccess.Client.OracleConnection
        rvConn = CreateConnection()
        Dim rvCmd As New Oracle.DataAccess.Client.OracleCommand
        '  Dim OracleRefCursor As New Oracle.DataAccess.Client.OracleDbType.RefCursor
        Dim ds As DataSet

        Dim oraDataAdapter As New Oracle.DataAccess.Client.OracleDataAdapter()


        Try
            rvCmd.Connection = rvConn
            rvConn.Open()

            Dim strSQL As String
            strSQL = "getallprodpckg.get_allcust"
            rvCmd.CommandType = CommandType.StoredProcedure
            rvCmd.CommandText = strSQL
            MsgBox("")

            Dim qrySerial3 As New Oracle.DataAccess.Client.OracleParameter("getallcursor", OracleDbType.RefCursor) With {
            .Direction = ParameterDirection.Output}


            rvCmd.Parameters.Add(qrySerial3)


            Dim vStr As String
            Dim reader As OracleDataReader = rvCmd.ExecuteReader

            While reader.Read()
                Console.WriteLine("{0}", reader(0) & reader(1) & reader(2))
                MsgBox(vStr)
            End While


        Catch ex As Exception
            MessageBox.Show("ERROR OCCURRED" & ex.Message)

        Finally
            rvConn.Close()
        End Try

    End Sub

** 数据库连接类**

公开课表1 Private Sub TestOracleButton_Click(sender As Object, e As EventArgs) 处理 TestOracleButton.Click 测试OracleConnection() 结束子

Dim custID As Integer
Dim custID2 As Integer
Dim custName As String
Dim prodID As Integer
Dim prodName As String
Dim prodPrice As Integer
Dim prodAmount As Integer
Dim custAmount As Integer
Dim custStatus As String
Dim prodQuant As Integer

Public Sub TestOracleConnection()
    Dim rvConn As Oracle.DataAccess.Client.OracleConnection
    rvConn = CreateConnection()
    Try
        rvConn.Open()
        MessageBox.Show("Oracle Connection OK")
    Catch ex As Exception
        MessageBox.Show(ex.Message)
        MessageBox.Show("No Oracle Connection established")
    Finally
        rvConn.Close()
    End Try
End Sub
Public Function CreateConnection() As Oracle.DataAccess.Client.OracleConnection
    Dim rvConn As New Oracle.DataAccess.Client.OracleConnection With {
        .ConnectionString = GetConnectionString()
    }
    Return rvConn
End Function
Public Function GetConnectionString() As String
    Dim vConnStr As String
    vConnStr = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)"
    vConnStr = vConnStr & "(HOST=feenix-oracle.swin.edu.au)(PORT=1521))"
    vConnStr = vConnStr & "(CONNECT_DATA=(SERVICE_NAME=dms)));"
    vConnStr = vConnStr & "User Id=S1234564;"
    vConnStr = vConnStr & "Password=******;"
    Return vConnStr
End Function

【问题讨论】:

  • 您可以分享您的代码和您收到的确切错误消息,而不是屏幕截图吗?
  • @vc74 感谢您的快速回复。我已经用我的代码更新了这个问题。感谢您的帮助。
  • @vc74 rvCmd 和 rvConn 已经在不同的类中定义。当我们使用相同的方式调用存储过程时,它正在工作。但问题是当我们调用 oracle 函数时它不起作用。如果您愿意,我们也可以发送工作代码。谢谢。
  • 已经使用 db 类建立了数据库连接。它工作正常。我们也可以连接到数据库并检索数据。更新了原始线程。请看一看。感谢您的宝贵时间。
  • OK 2 件事,ParameterDirection 应该是 ReturnValue 对于函数,更重要的是在哪一行抛出异常?

标签: oracle sys-refcursor


【解决方案1】:

您需要从参数中获取阅读器,而不是从命令中。

所以不是

Dim reader As OracleDataReader = rvCmd.ExecuteReader()

你需要:

rvCmd.CommandType = CommandType.StoredProcedure
rvCmd.CommandText = "getallprodpckg.get_allcust"

Dim qrySerial3 As New Oracle.DataAccess.Client.OracleParameter(
    None, OracleDbType.RefCursor, ParameterDirection.ReturnValue)

rvCmd.Parameters.Add(qrySerial3)

rvCmd.ExecuteNonQuery()

Dim cursor as OracleRefCursor = DirectCast(qrySerial3.Value, OracleRefCursor)

Dim reader As OracleDataReader = cursor.GetDataReader()

【讨论】:

  • 非常感谢您的支持。您的解决方案运行良好。再次感谢。
猜你喜欢
  • 1970-01-01
  • 2021-01-09
  • 2012-08-08
  • 1970-01-01
  • 2014-10-01
  • 1970-01-01
  • 2010-10-26
  • 2018-11-01
  • 2017-03-19
相关资源
最近更新 更多