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

VB.Net调用Oracle存储过程pr_1报PLS-00306错误,求排查方法

问题描述

调用Oracle存储过程pk_1.pr_1时触发PL/SQL参数错误:

pls-00306: wrong number or types of arguments in call to procedure 'pr_1'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignore

当前VB.Net调用代码:

Try
    Dim int_key As Integer = 8 
    Dim cnnctn As New OracleConnection
    Dim cmmnd  As New OracleCommand
    With cmmnd
        .Connection = cnnctn
        .CommandType = CommandType.StoredProcedure
        .CommandText = "pk_1.pr_1"
        .Parameters.Add("@wp_subtype_1", OracleDbType.Int32, ParameterDirection.Input).Value = int_key
        Dim ret_PR As New OracleParameter("@wp_tab_result", OracleDbType.Varchar2, ParameterDirection.Output)
        .Parameters.Add(ret_PR)
        .Parameters.Add("@wp_cd_err" , OracleDbType.Int32, ParameterDirection.Output).Size = 5
        .Parameters.Add("@wp_msg_err", OracleDbType.Varchar2, ParameterDirection.Output).Size = 250
        .ExecuteNonQuery()
        If CInt(.Parameters("@wp_cd_erro").Value.ToString()) <> 0 Then
            'TODO : error handling'
        End If

存储过程包规范:

create or replace PACKAGE pk_1 AS
    TYPE rc_cursor  IS REF CURSOR;
    SUBTYPE subtype_1  IS PLS_INTEGER RANGE 1..10 NOT NULL;
    TYPE tp_tb_rslt  IS TABLE OF VARCHAR2(7);
-- ...   
   PROCEDURE pr_1 (
   wp_subtype_1    IN       subtype_1
 , wp_tab_result   OUT      tp_tb_rslt
 , wp_cd_err       OUT      NUMBER
 , wp_msg_err      OUT      VARCHAR2) ;
END pk_1;      
调试排查步骤
  • 修正集合类型参数的映射错误
    存储过程中wp_tab_result是自定义表类型tp_tb_rslt,但VB.Net代码错误使用OracleDbType.Varchar2,这是核心类型不匹配。需改用OracleDbType.Array并关联Oracle自定义类型:

    Dim arrayType As New OracleParameter("@wp_tab_result", OracleDbType.Array, ParameterDirection.Output)
    arrayType.UdtTypeName = "PK_1.TP_TB_RSLT" ' Oracle标识符默认大写,需与数据库定义一致
    .Parameters.Add(arrayType)
    
  • 验证输入参数的取值范围
    wp_subtype_1是带范围限制的PLS_INTEGER(1-10),VB.Net用OracleDbType.Int32类型兼容,但要确保传入的int_key值在1-10范围内,超出范围会触发参数校验错误。

  • 修正参数名称拼写错误
    VB.Net错误处理部分引用了@wp_cd_erro,但存储过程参数是wp_cd_err,拼写错误会导致后续取值失败,虽不是当前PLS-00306的直接原因,但必须修正。

  • 确认参数顺序与存储过程严格一致
    OracleCommand的参数顺序必须和存储过程定义完全匹配(部分ODP.NET版本依赖参数顺序而非名称),当前代码顺序符合要求,但需确保无遗漏或多余参数。

  • 调整参数Size的无效设置

    • wp_cd_err是NUMBER类型,VB.Net设置Size=5无效,可直接移除该设置;
    • wp_msg_err的Size需与存储过程实际定义的VARCHAR2长度一致,若存储过程未指定,需确认数据库端实际长度后调整。
  • 补充数据库连接打开逻辑
    当前代码未打开数据库连接,调用ExecuteNonQuery()前必须添加cnnctn.Open(),否则会触发连接错误,也可能间接导致参数解析异常。

  • 启用ODP.NET调试日志排查
    开启ODP.NET调试日志,查看实际发送到Oracle的调用语句,对比参数类型和数量是否正确:
    在项目配置文件中添加:

    <configuration>
      <oracle.dataaccess.client>
        <settings>
          <add name="TraceLevel" value="7"/>
          <add name="TraceFileName" value="odpnet_trace.log"/>
        </settings>
      </oracle.dataaccess.client>
    </configuration>
    

    查看生成的日志文件,确认参数的实际传递情况。

  • 直接在PL/SQL环境验证存储过程
    在SQL Developer等Oracle客户端手动调用存储过程,验证参数逻辑是否正常:

    DECLARE
        v_subtype pk_1.subtype_1 := 8;
        v_result pk_1.tp_tb_rslt;
        v_err_code NUMBER;
        v_err_msg VARCHAR2(250);
    BEGIN
        pk_1.pr_1(v_subtype, v_result, v_err_code, v_err_msg);
        DBMS_OUTPUT.PUT_LINE('Err Code: ' || v_err_code);
        DBMS_OUTPUT.PUT_LINE('Err Msg: ' || v_err_msg);
        IF v_result IS NOT NULL THEN
            FOR i IN v_result.FIRST..v_result.LAST LOOP
                DBMS_OUTPUT.PUT_LINE('Result ' || i || ': ' || v_result(i));
            END LOOP;
        END IF;
    END;
    

    若PL/SQL调用正常,说明问题出在VB.Net参数映射;若PL/SQL调用也报错,需排查存储过程本身的逻辑。

内容的提问来源于stack exchange,提问作者Tomás

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 09:00:38