【问题标题】:Checking if a collection element exists in Oracle检查Oracle中是否存在集合元素
【发布时间】:2010-11-23 18:48:47
【问题描述】:

我创建了一个简单的类型:

create or replace TYPE SIMPLE_TYPE AS OBJECT (ID NUMBER(38), NAME VARCHAR2(20));

简单测试:

DECLARE
   TYPE ObjectList IS TABLE OF SIMPLE_TYPE;
   tmp SIMPLE_TYPE := SIMPLE_TYPE(1, 'a');
   o ObjectList := new ObjectList(SIMPLE_TYPE(2, 'a'), SIMPLE_TYPE(3, 'a'));
BEGIN
   IF tmp.EXISTS(tmp) THEN
    dbms_output.put_line('OK, exists.');
   END IF;
END;

我得到一个异常:PLS-00302:必须声明组件“EXISTS”

但是这个例子有效:

DECLARE
   TYPE NumList IS TABLE OF INTEGER;
   n NumList := NumList(1,3,5,7);
BEGIN
   n.DELETE(2);
   IF n.EXISTS(1) THEN
      dbms_output.put_line('OK, element #1 exists.');
   END IF;
   IF n.EXISTS(3) = FALSE THEN
      dbms_output.put_line('OK, element #2 has been deleted.');
   END IF;
   IF n.EXISTS(99) = FALSE THEN
      dbms_output.put_line('OK, element #99 does not exist at all.');
   END IF;
END;

是否可以在 SIMPLE_TYPE 类型中实现 EXISTS 方法?

【问题讨论】:

  • 您确定要tmp.EXISTS,而不是o.EXISTStmp 是标量,即使您更正了它的类型。这不是一个集合。

标签: oracle stored-procedures exists user-defined-types


【解决方案1】:

正如documentation statesEXISTS() 测试集合中是否存在编号条目。也就是说,array.exists(3) 断言array 的第三个元素已填充。

您在第一个示例中尝试做的是测试实例tmp 是否与ObjectList 中的元素匹配。从 10g 开始,我们可以使用 MEMBER OF 语法来做到这一点。不幸的是,为了完成这项工作,我们必须声明一个 MAP 方法,该方法相当笨拙,并且如果对象有很多属性会变得相当烦人。

SQL> create or replace type simple_type as object
  2       ( id number
  3         , name varchar2(30)
  4         , map member function compare return varchar2);
  5  /

Type created.

SQL>
SQL> create or replace type body simple_type as
  2       map member function compare return varchar2
  3       is
  4          return_value integer;
  5       begin
  6          return to_char(id, '0000000')||name;
  7       end compare;
  8  end;
  9  /

Type body created.

SQL>

运行示例...

SQL> set serveroutput on size unlimited
SQL>
SQL> declare
  2      type objectlist is table of simple_type;
  3      tmp simple_type := simple_type(1, 'a');
  4      o objectlist := new objectlist(simple_type(2, 'a'), simple_type(3, 'a'));
  5  begin
  6      if tmp MEMBER OF o then
  7          dbms_output.put_line('ok, exists.');
  8      else
  9          dbms_output.put_line('search me');
 10      end if;
 11  end;
 12  /
search me

PL/SQL procedure successfully completed.

SQL>

【讨论】:

  • MEMBER OF .. 这是一个改变我生活的提示​​!惊人的 !谢谢!
【解决方案2】:
tmp SIMPLE_TYPEE := SIMPLE_TYPE(1, 'a');

…

IF tmp.EXISTS(tmp) THEN

您将tmp 声明为SIMPLE_TYPE,而不是ObjectList

SIMPLE_TYPE 是标量类型,而不是集合。

您可能想改为检查o.EXISTS(这是ObjectList)?

更新:

EXISTS 应用于集合时,将整数索引作为参数并检查具有此索引的元素是否存在(而不是其值)。

要检查SIMPLE_TYPE(1, 'a') 是否存在于您的表中,您应该执行以下操作:

在字典中创建ObjectList

CREATE TYPE ObjectList IS TABLE OF SIMPLE_TYPE;

发出SELECT 查询:

DECLARE
        tmp SIMPLE_TYPE := SIMPLE_TYPE(1, 'a');
        o ObjectList := new ObjectList(SIMPLE_TYPE(2, 'a'), SIMPLE_TYPE(3, 'a'));
        myid INT;
BEGIN
        SELECT  1
        INTO    myid
        FROM    TABLE(o) q
        WHERE   SIMPLE_TYPE(q.id, q.name) = tmp
                AND rownum = 1;
        IF (myid = 1) THEN
                dbms_output.put_line('OK, exists.');
        END IF;
END;

【讨论】:

  • 此外,我们必须提供 NO_DATA_FOUND 异常。谢谢提示!
猜你喜欢
  • 2021-05-05
  • 2021-12-22
  • 1970-01-01
  • 1970-01-01
  • 2012-11-20
相关资源
最近更新 更多