PL/SQL块报PLS-00382类型错误,包中同逻辑正常的原因咨询
问题解释:PL/SQL本地类型与包类型在TABLE()函数中的差异
问题场景
尝试在PL/SQL块中实现以下逻辑:
- 创建引用表行的表类型
- 将表中数据批量收集到表变量中
- 遍历表变量并按需打印指定列
报错的PL/SQL代码
DECLARE TYPE my_type IS TABLE OF emp%rowtype INDEX BY PLS_INTEGER; l_arr_type my_type; BEGIN SELECT * BULK COLLECT INTO l_arr_type FROM emp; FOR rec IN (SELECT * FROM TABLE (l_arr_type) ORDER BY HIREDATE) LOOP DBMS_OUTPUT.PUT_LINE('Ename is: '||rec.ENAME||' and hire date is: '||rec.HIREDATE); END LOOP; END;
错误信息
ORA-06550: line 8, column 38: PLS-00382: expression is of wrong type
可正常运行的包实现代码
CREATE OR REPLACE PACKAGE my_array IS TYPE my_type IS TABLE OF emp%rowtype INDEX BY PLS_INTEGER; END my_array; / DECLARE l_arr_type my_array.my_type; BEGIN SELECT * BULK COLLECT INTO l_arr_type FROM emp; FOR rec IN (SELECT * FROM TABLE (l_arr_type) ORDER BY HIREDATE) LOOP DBMS_OUTPUT.PUT_LINE('Ename is: '||rec.ENAME||' and hire date is: '||rec.HIREDATE); END LOOP; END;
原因解析
- SQL引擎的类型可见性限制:Oracle的
TABLE()函数用于将集合转换为关系表,它只能识别SQL层可见的命名类型。PL/SQL块DECLARE段定义的my_type是本地私有类型,仅在PL/SQL引擎内部可见,SQL引擎无法识别该类型,因此调用TABLE(l_arr_type)时会抛出类型不匹配错误。 - 包级别类型的全局可见性:当类型定义在包中时,该类型成为数据库级别的命名对象,SQL引擎可以访问到这个类型的定义。即使是关联数组(INDEX BY PLS_INTEGER的表类型),包级别的定义也会被Oracle隐式处理为可被SQL引擎识别的类型,因此
TABLE(l_arr_type)能正常执行。
内容的提问来源于stack exchange,提问作者Rito Sarkar
相关产品推荐
相关产品推荐

