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 语句中不允许本地集合类型的主要内容,如果未能解决你的问题,请参考以下文章

oracle 中的 sql语句查询

oracle会记录每次执行的sql语句吗

获取oracle视图SQL语句的工具

oracle SQL查询语句

oracle 用sql语句查询 已打补丁列表。

oracle删除某个表的索引的sql语句