为什么 SELECT 语句中的 TABLE 子句在 PLSQL 块中不起作用?

问题描述 投票:0回答:1

我是 PL/SQL 新手,我正在尝试创建一种带有 %rowtype 的表类型,然后声明一个变量并执行某种操作示例;下面是我正在尝试的逻辑的代码片段:

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:第 8 行,第 38 列:PLS-00382:表达式类型错误

但是当我在包内声明变量并使用相同的变量时,同样的事情正在起作用;我在这里错过了什么吗?这不是一个奇怪的行为吗? 以下是工作代码片段:

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;

如果我能得到这种行为背后的澄清,将会很有帮助;

------------------------更新-----------------

类型为RECORD时类似操作;下面是我的代码片段

DECLARE

TYPE my_type IS RECORD (ename_t emp.ENAME%TYPE, sal_t emp.SAL%TYPE, eno_t emp.empno%TYPE);
l_arr_type  my_type;

BEGIN
    SELECT ENAME, sal, empno  INTO l_arr_type FROM emp  where ename='KING';
           DBMS_OUTPUT.PUT_LINE('Ename is: '||l_arr_type.ename_t);
END; 
plsql plsqldeveloper oracle19c
1个回答
1
投票

SQL 与 PL/SQL 不同。它们由不同的引擎处理,并具有一组不同的可识别类型。当您在 PL/SQL 中调用 SQL 语句时,您会切换到 SQL 引擎,并且它会在您的代码不可见的情况下运行。因此,历史上 SQL 只能导航作为 SQL 类型键入的集合 (

create type ...
)。它无法访问 PL/SQL 类型。

但从 12.1 开始,Oracle 开始允许

TABLE
SQL 运算符访问 PL/SQL 集合,但要求它们在 包头 中定义。包头有点像公开的对象规范,外部代码(现在是 SQL 引擎本身)可以询问以了解如何访问 PL/SQL 对象(包括集合)。

© www.soinside.com 2019 - 2024. All rights reserved.