PL/SQL向数组指定下标插入元素并移位报ORA-06550/PLS-00103错误求解
错误原因排查
1. 直接触发报错的语法问题
你编写的APPENDARR存储过程的参数定义不符合PL/SQL语法要求:
- 参数
idx、val只声明了IN模式,没有指定对应的数据类型 - 第一个参数名
arr和你自定义的VARRAY类型名arr重名,会导致解析器识别冲突
这两个问题就是触发PLS-00103报错的直接原因。
2. 代码中存在的其他逻辑错误
除了语法报错之外,你的实现逻辑还有多处不符合需求的问题:
- 条件判断逻辑错误:
arr.LIMIT是VARRAY定义时指定的最大容量,不是当前实际存储的元素个数,判断插入位置是否越界应该用arr.COUNT或者arr.LAST - 扩容逻辑错误:VARRAY的最大容量在定义时就固定为10,无法超过这个值扩容,你写的
idx > arr.LIMIT时扩容的逻辑本身不可行,超过最大容量会触发报错 - 元素后移逻辑错误:你在循环里判断
arr(i) = arr(idx)再赋值的逻辑完全错误,后移完成后直接给目标位置赋值即可,不需要这个判断 - 下标边界问题:如果插入的位置比当前数组实际长度+1还大,会出现下标断层的问题,VARRAY是连续下标集合,不允许中间有空位置
修正后的可运行代码
执行前先运行SET SERVEROUTPUT ON;开启输出即可查看运行结果:
DECLARE -- 自定义VARRAY类型,注意不要和后续参数名重名 TYPE varr_type IS VARRAY(10) OF VARCHAR(32); ar varr_type := varr_type('1', '1', '1'); idx INTEGER := 2; -- 要插入的下标位置 val VARCHAR(32) := 'new_val'; -- 要插入的值 PROCEDURE APPENDARR ( p_arr IN OUT varr_type, p_idx IN INTEGER, p_val IN VARCHAR ) IS tmp INTEGER; BEGIN -- 校验插入位置合法性 IF p_idx < 1 OR p_idx > p_arr.LIMIT THEN RAISE_APPLICATION_ERROR(-20001, '插入位置不合法,需在1到数组最大容量之间'); END IF; -- 如果插入位置超过当前实际长度,直接扩容到对应长度赋值即可,不需要后移 IF p_idx > p_arr.COUNT THEN tmp := p_idx - p_arr.COUNT; p_arr.EXTEND(tmp); p_arr(p_idx) := p_val; ELSE -- 先扩容1位,给插入的元素腾位置 p_arr.EXTEND(1); -- 从最后一位开始倒序把元素往后移一位,直到目标位置 FOR i IN REVERSE p_idx..p_arr.LAST-1 LOOP p_arr(i+1) := p_arr(i); END LOOP; -- 目标位置赋值 p_arr(p_idx) := p_val; END IF; END; BEGIN -- 调用测试 APPENDARR(ar, idx, val); -- 输出结果验证 FOR i IN 1..ar.COUNT LOOP DBMS_OUTPUT.PUT_LINE('下标'||i||':'||ar(i)); END LOOP; END; /
内容的提问来源于stack exchange,提问作者justaDN
相关产品推荐
相关产品推荐

