You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET/VB使用Oracle OCI 12c/19c驱动时DeriveParameters返回0参数

问题分析与解决方案

问题现象

使用.NET Framework 4.6.1搭配Oracle 12c+/19c OCI驱动连接Oracle 11g后端时,调用OracleCommandBuilder.DeriveParameters无法获取包内存储过程TESTPARAMS_PKG.test1param的参数,返回参数数量为0;但使用Oracle 11g OCI驱动连接同一数据库时可正常返回1个参数。

原因

Oracle 12c及后续版本的OCI驱动默认采用新的基于XML的元数据获取机制,该机制在连接11g数据库时存在兼容性问题,导致无法正确解析包内存储过程的参数信息。

解决方案

方案1:显式定义参数(推荐生产环境使用)

OracleCommandBuilder.DeriveParameters需要额外数据库往返获取元数据,性能较差且兼容性不稳定,建议直接显式声明参数:

Imports System.Data.OracleClient

Private Sub btnFakeStoredProcedure(sender As Object, e As EventArgs) Handles btnStoredProcedure.Click
    Dim OConn = New OracleConnection()
    OConn.ConnectionString = "Password=...; User ID=...; Data Source=...;"
    OConn.Open()

    Dim Command = New OracleCommand("TESTPARAMS_PKG.test1param", OConn)
    Command.CommandType = CommandType.StoredProcedure

    ' 显式添加参数,替代DeriveParameters
    Command.Parameters.Add(New OracleParameter("param1", OracleType.VarChar))

    Dim txtParameters = "The parameters: " & vbCrLf & Command.Parameters.Count & vbCrLf
    OConn.Close()

    For Each parameter As OracleParameter In Command.Parameters
        txtParameters += "Parameter Name: " & parameter.ParameterName & vbCrLf
        txtParameters += "Parameter Direction: " & parameter.Direction & vbCrLf
        txtParameters += "Parameter Value: " & If(parameter.Value Is DBNull.Value, "DBNull", parameter.Value.ToString()) & vbCrLf & vbCrLf
    Next

    txtStoredProcedure.Text = txtParameters
End Sub

方案2:修改连接字符串兼容旧元数据机制

在连接字符串中添加MetaDataXml=False,强制驱动使用11g兼容的元数据获取方式:

OConn.ConnectionString = "Password=...; User ID=...; Data Source=...; MetaDataXml=False;"

添加该参数后,原代码中的OracleCommandBuilder.DeriveParameters即可正常获取参数。


重现代码与环境

VB.NET 代码

Imports System.Data.OracleClient

Private Sub btnFakeStoredProcedure(sender As Object, e As EventArgs) Handles btnStoredProcedure.Click
        Dim OConn = New OracleConnection()

        OConn.ConnectionString = "Password=...; User ID=...; Data Source=...;"
        OConn.Open()

        Dim Command = New OracleCommand("TESTPARAMS_PKG.test1param", OConn)
        Command.CommandType = CommandType.StoredProcedure

        OracleCommandBuilder.DeriveParameters(Command)

        Dim txtParameters = "The parameters: " & vbCrLf & Command.Parameters.Count & vbCrLf
        OConn.Close()

        For Each parameter As OracleParameter In Command.Parameters
            txtParameters += "Parameter Name: " & parameter.ParameterName & vbCrLf
            txtParameters += "Parameter Direction: " & parameter.Direction & vbCrLf
            txtParameters += "Parameter Value: " & parameter.Value.ToString() & vbCrLf & vbCrLf
        Next

        txtStoredProcedure.Text = txtParameters

    End Sub

Oracle 存储过程定义

CREATE OR REPLACE PACKAGE TESTPARAMS_PKG AS 

  -- just 1 varchar param with and without default, implicit IN
  PROCEDURE test1param (param1 VARCHAR2);

END TESTPARAMS_PKG;
/

CREATE OR REPLACE PACKAGE BODY TESTPARAMS_PKG AS

  PROCEDURE test1param (param1 VARCHAR2) AS
  BEGIN
    -- TODO: Implementierung for PROCEDURE TESTPARAMS_PKG.test1param erforderlich
    NULL;
  END test1param;

END TESTPARAMS_PKG;
/

版本对比

  • "Oracle in instantclient_11.2.0_x86":正常返回参数数量
  • "Oracle in OraClient12cR2_x86":参数数量为0

内容的提问来源于stack exchange,提问作者clemens utschig

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 01:45:05