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

Oracle调用包函数传RECORD类型参数触发PLS-00306错误咨询

Oracle PLS-00306 错误排查与修复

错误根因

这个场景下触发PLS-00306的核心原因是PL/SQL自定义记录类型的强类型校验规则:

  • 函数f1要求接收的参数类型,是包作用域下定义的pkg_test1.t_rec1,这个类型的身份是和包绑定、唯一归属的
  • 你在匿名块内独立定义的t_rec,属于匿名块局部作用域的自定义类型

哪怕两个记录类型的字段名、字段数据类型、字段顺序100%完全一致,PL/SQL也不会做结构层面的兼容校验,只会校验类型的定义来源:只要两个类型不是从同一个定义位置引用的,就会被判定为完全不兼容的独立类型,最终因为参数类型不匹配抛出PLS-00306错误。

这个错误提示的表述比较笼统,不会精准告知是两个记录类型不兼容,很容易误导开发者反复核对参数个数,忽略类型定义来源的差异。

修复方案

方案1:直接引用包内暴露的记录类型(最简便)

删掉匿名块里重复定义的t_rec类型,声明变量时直接使用包对外暴露的正式类型,保证类型路径完全匹配。
修改后的匿名块代码:

DECLARE
  -- 不再单独定义局部记录类型,直接引用包内的类型
  v_rec pkg_test1.t_rec1;  
  v_var VARCHAR2(15);
BEGIN
  v_rec.c1 := 1;
  v_var := pkg_test1.f1(v_rec);
END;

方案2:从根源上避免重复定义同类结构的自定义类型

如果这个记录结构需要在多个存储过程、函数、匿名块中复用,不要在每个使用场景下重复写相同的RECORD定义,推荐两种标准化的类型定义方式:

  • 把公共记录类型定义在独立的公共工具包中,所有业务代码统一从公共包引用类型
  • 如果记录字段和某张表的字段结构完全匹配,直接用表名%ROWTYPE的锚定方式定义类型,避免手写重复的字段结构

常见踩坑提醒

不要默认PL/SQL会像Java、Python这类高级语言一样,对同结构的自定义类型做结构化的兼容适配,所有自定义的RECORD、TABLE类型,只有引用同一个定义源头,才能在参数传递时通过类型校验。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 13:15:07