选错参数模式是Oracle存储过程报PLS-00363、ORA-06502或输出为NULL的主因;核心依据是参数是否需“带值进来”及“把新值带出去”:IN只读输入、OUT纯输出须变量接收、IN OUT双向传递且异常时状态不同。

选错参数模式是 Oracle 存储过程最常引发 PLS-00363、ORA-06502 或输出值始终为 NULL 的根本原因。核心判断标准只有一条:这个参数在调用时是否需要“带值进来”,以及执行后是否需要“把新值带出去”。
IN 参数:只读输入,禁止赋值
当参数仅用于传入数据供过程内部读取(比如查询条件、计算因子),且你明确不希望它被修改,就用 IN。它是默认模式,可省略关键字。
-
IN参数在过程体内不可赋值——哪怕只是临时变量用途,写p_id := 100就会报PLS-00363: expression 'P_ID' cannot be used as an assignment target - 允许指定
DEFAULT值,例如p_status IN VARCHAR2 DEFAULT 'ACTIVE';OUT和IN OUT不支持默认值 - 调用时可直接传字面量:
EXEC update_salary(7839, 1.1),无需提前声明变量 - 性能上无额外开销,因为只是引用传入值(Oracle 实际按引用传递
IN,但语义上视为只读)
OUT 参数:纯输出,必须用变量接收
当参数唯一作用是返回结果(比如查出的姓名、计算后的余额、是否成功的标志),就用 OUT。它不关心调用时传了什么,过程内必须赋值。
- 调用时不能传字面量,必须用已声明的变量,例如:
VARIABLE v_name VARCHAR2(50)→EXEC get_employee(7839, :v_name) - 过程开始时,
OUT参数值恒为NULL,无论你调用时“试图传”什么——EXEC get_employee(7839, 'xxx')中的'xxx'被完全忽略 - 若过程中途异常退出,
OUT变量不会被更新,仍保持调用前的值(或NULL) - 大数据集(如嵌套表)作
OUT参数时,复制开销大;可加NOCOPY提示(p_result OUT NOCOPY my_table_type),但需确保过程不会异常退出
IN OUT 参数:双向传递,变量是硬性要求
当参数既要参与初始计算(如传入原始金额),又要被过程修改后返回(如返回扣税后的净额),就用 IN OUT。它本质是“先入后出”的单变量通道。
- 调用时必须用变量,且该变量在调用前已有值——
IN部分靠它传入,OUT部分靠它接收 - 过程内可读可写,例如:
IF p_balance > 1000 THEN p_balance := p_balance * 0.95; END IF; - 过程异常退出时,
IN OUT变量的值不会回滚到原始值,而是保持最后一次成功赋值的状态(这点和OUT不同) - 注意类型一致性:变量声明类型必须严格匹配参数类型,
VARCHAR2(10)接收IN OUT VARCHAR2参数没问题,但接IN OUT CHAR(10)可能隐式转换失败
真正容易被忽略的是 NOCOPY 的适用边界和异常行为差异——OUT 和 IN OUT 在异常时的变量状态完全不同,而多数人只测了正常路径。写之前先想清楚:这个参数在出错时,我期望它保持原值,还是接受中间态?这决定了你该用纯 OUT 还是 IN OUT,以及是否加 NOCOPY。


















