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 的类型。
在我的生产环境中,我想测试一种优化请求的新技术,但我无法创建任何东西,例如包或类型。所以我希望能够在不创建任何东西的情况下测试这项技术。
在对此 post 的回答中(
文档 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 的类型。