Oracle 12c 上的 PLS-00642 和 ORA-22905 在访问 return 在 pl/sql 块的 DECLARE 部分中声明的自定义类型的函数时

PLS-00642 and ORA-22905 on Oracle 12c when accessing to a function that return a custom type declared in the DECLARE section of a pl/sql block

在我的生产环境中,我想测试一种优化请求的新技术,但我无法创建任何东西,例如包或类型。所以我希望能够在不创建任何东西的情况下测试这项技术。

在对此 post 的回答中(), wernfried-domscheit Oracle 12c 在 SQL 中支持本地集合类型。

文档 Database New Features Guide 说:

PL/SQL-Specific Data Types Allowed Across the PL/SQL-to-SQL Interface

The table operator can now be used in a PL/SQL program on a collection whose data type is declared in PL/SQL. This also allows the data type to be a PL/SQL associative array. (In prior releases, the collection's data type had to be declared at the schema level.)

所以我尝试实现它,但编译失败,错误为 PLS-00642 和 ORA-22905。

我做了一个我的问题的小例子:

DECLARE
    TYPE simple_type IS RECORD
    (
        no             NUMBER (6),
        description    VARCHAR2 (50)
    );

    line                     SYS_REFCURSOR;
    line_no                  NUMBER (6);
    line_description         VARCHAR2 (50);

    TYPE table_simple_type IS TABLE OF simple_type;

    ret_table_simple_type    table_simple_type;

    FUNCTION calc_table_simple_type
        RETURN table_simple_type
    IS
        ret                 table_simple_type;
        data_simple_type    simple_type;
    BEGIN
        ret := table_simple_type ();

        FOR i IN 1 .. 5
        LOOP
            data_simple_type.no := i;
            data_simple_type.description := 'Test';
            ret.EXTEND ();
            ret (ret.COUNT) := data_simple_type;
        END LOOP;

        RETURN ret;
    END;
BEGIN
    ret_table_simple_type := calc_table_simple_type ();

    OPEN line FOR SELECT no, description FROM TABLE (ret_table_simple_type);

    LOOP
        FETCH line INTO line_no, line_description;

        EXIT WHEN line%NOTFOUND;
        DBMS_OUTPUT.Put_Line (line_no || ' ' || line_description);
    END LOOP;
END;

它在编译时抛出:

Error at line 2
ORA-06550: Line 37, column 54 :
PLS-00642: local collection types not allowed in SQL statements
ORA-06550: Line 37, column 47 :
PL/SQL: ORA-22905: cannot access rows from a non-nested table item
ORA-06550: Line 37, column 19 :
PL/SQL: SQL Statement ignored

如果 Oracle 12c 现在支持,为什么我会收到此错误?以及如何避免在不创建任何东西的情况下测试我的两个函数的问题?

我不能在 SELECT 中调用函数 calc_table_simple_type () 否则我会得到错误:

PLS-00231: function 'CALC_TABLE_SIMPLE_TYPE' may not be used in SQL

我无法将 simple_type 声明为对象,因为我得到:

PLS-00540: object not supported in this context.

在代码的最终版本中,simple_type 将是一个对象,select 将直接调用该函数,因为它们将在一个包中,但现在我不能这样做没有先在生产环境中测试它,因为我的其他环境并不真正具有代表性(我知道这不理想,但这就是我的情况)

这是 SELECT * FROM V$VERSION

的完整输出
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production    0
PL/SQL Release 12.1.0.2.0 - Production  0
CORE    12.1.0.2.0  Production  0
TNS for Solaris: Version 12.1.0.2.0 - Production    0
NLSRTL Version 12.1.0.2.0 - Production  0

如果您真的必须使用类型,是否可以重用数据库中具有 2 列的任何现有类型?

SELECT TYPE_NAME
FROM   USER_TYPES
WHERE  TYPECODE  = 'OBJECT' and attributes='2';

据推测,您需要找到具有 NUMBER 和 VARCHAR 的类型。