Oracle - PLS-00642:SQL 语句中不允许本地集合类型
Posted
技术标签:
【中文标题】Oracle - PLS-00642:SQL 语句中不允许本地集合类型【英文标题】:Oracle - PLS-00642: local collection types not allowed in SQL statements 【发布时间】:2016-03-02 13:50:38 【问题描述】:我是在 ORACLE 中编程的新手,我正在尝试将表列值与传入的数组进行比较,但这样做的过程相当令人沮丧。
这是来自包头的类型声明。
TYPE T_STRING_ARRAY IS TABLE OF VARCHAR2(5);
这里是使用它的函数。
create or replace PACKAGE BODY TEST_PACK IS
FUNCTION TEST_LOG_FN
(
PI_START_DATE IN VARCHAR2,
PI_END_DATE IN VARCHAR2,
PI_LOG_TYPE IN T_STRING_ARRAY
)
RETURN T_REF_CURSOR
AS
PO_RESULT T_REF_CURSOR;
BEGIN
OPEN PO_RESULT FOR
SELECT
EL.ENTRY_BASE_LOG_ID,
EL.APP_NAME,
EL.APP_MODULE,
EL.CREATION_DATE,
EL.APP_STATUS,
EL.LOG_TYPE
FROM
LG_ENTRY_BASE_LOG EL
WHERE
CREATION_DATE > PI_START_DATE AND
CREATION_DATE < PI_END_DATE AND
(EL.LOG_TYPE IN PI_LOG_TYPE OR PI_LOG_TYPE = NULL);
RETURN
PO_RESULT;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN NULL;
END TEST_LOG_FN;
END;
我得到的错误是 PLS-00642: local collection types not allowed in SQL statements。我在网上看过
“为避免 PLS-00642,需要在模式级别定义集合;因此,您需要使用 Oracle DDL 和 CREATE TYPE 语法将 varray 表定义为真实表。”
http://www.dba-oracle.com/t_pls_00642_local_collection_types_not_allowed_in_sql_statement.htm
我不知道该怎么做,也没有在网上找到任何可以使用的参考资料。有人可以帮我吗?如果有人知道一种更简单的方法来查看数组中是否存在字符串,那也是一个完全可以接受的答案。
【问题讨论】:
【参考方案1】:您可以在 Oracle 12C 或更高版本中使用包规范中定义的类型。
这一行:
(EL.LOG_TYPE IN PI_LOG_TYPE OR PI_LOG_TYPE = NULL)
需要:
(EL.LOG_TYPE IN (select column_value from table(PI_LOG_TYPE))
OR (select count(*) from table(PI_LOG_TYPE)) = 0)
在 12C 之前,您需要使用 CREATE TYPE 在数据库中定义类型。无论哪种方式,选择的语法都是相同的。
【讨论】:
感谢您的快速回复。我现在收到新错误消息:PL/SQL: ORA-22905: cannot access rows from a non-nested table item。从单词“table”开始 您使用的是哪个 Oracle 版本? 好的,你不能写PI_LOG_TYPE = NULL
。无论如何它应该是P1_LOG_TYPE IS NULL
,但要测试SQL 中的集合是否为空,您需要从中获取select count(*)
。答案已更新。【参考方案2】:
您可以使用专为集合使用而设计的MEMBER OF
运算符,而不是使用IN
:
(PI_LOG_TYPE = NULL OR EL.LOG_TYPE MEMBER OF PI_LOG_TYPE);
正如@TonyAndrews 所说,如果您使用的是 Oracle 12c,那么您可以使用 PL/SQL 中包中定义的集合,但在早期版本中,您需要使用CREATE TYPE
语句在 SQL 中定义它们。
【讨论】:
以上是关于Oracle - PLS-00642:SQL 语句中不允许本地集合类型的主要内容,如果未能解决你的问题,请参考以下文章