vb.net - 如何使用 Ref 游标调用 Oracle 函数并在 Visual Basic 上返回值
问题描述
我正在尝试调用从 VB 返回 SYS_REFCURSOR 的 Oracle 函数。我能够使用存储过程检索数据。与我尝试调用 oracle 函数的方式相同,但它给出了错误。
是否有人可以提供帮助?谢谢。如果需要,我会提供屏幕截图。
DB端功能
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;
我的代码================================================= ==========================
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("getallpcursor", OracleDbType.RefCursor) With {
.Direction = ParameterDirection.ReturnValue}
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
当我使用游标对象调用存储过程时,上面的代码确实返回了一个值。游标基本上返回表中的所有数据。但是当我在函数上尝试它时会引发异常,我尝试的代码如下。** 错误 ** 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 = "select getallprodpckg.get_allcust() from dual"
rvCmd.CommandType = CommandType.Text
rvCmd.CommandText = strSQL
MsgBox("")
Dim qrySerial2 As New Oracle.DataAccess.Client.OracleParameter("getallpcursor", OracleDbType.RefCursor) With {
.Direction = ParameterDirection.ReturnValue}
rvCmd.Parameters.Add(qrySerial2)
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
End Class
** 数据库连接类 **
Public Class Form1 Private Sub TestOracleButton_Click(sender As Object, e As EventArgs) Handles TestOracleButton.Click TestOracleConnection() End Sub
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
解决方案
您需要从参数中获取阅读器,而不是从命令中获取。
所以而不是
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()
推荐阅读
- xcode - xcode / flutter 命令 /usr/bin/codesign 失败,退出代码为 1
- node.js - 节点和标准全局模式
- ios - 从 Push Extension 到 App 触发 KVO
- javascript - 组件间 JS/TS,在 Angular 项目中动态加载
- javascript - momentjs 没有正确计算周数
- python - 如何读取十六进制编辑器文件
- angular - Firebase Google 身份验证被禁止(权限被拒绝)
- rust - 如何表达闭包的生命周期限制以匹配特征有界生命周期?
- phpmyadmin - Xampp - mysql - 无法创建文件 xampp-control.ini,访问被拒绝
- javascript - 在控制台中获取'无法读取未定义的属性'classList'