在PL / SQL中比较表的惯用法

时间:2013-10-22 07:52:49

标签: oracle plsql

我在PL / SQL中创建一个函数,我需要多次一组数据,只想查询一次数据库,所以我将数据存储在一个表中:

TYPE number_tbl IS TABLE OF NUMBER;
CURRENTFOOS number_tbl;
...
SELECT B.FOO BULK COLLECT
  INTO CURRENTFOOS 
  FROM A, B
WHERE
...

现在我想检查表CURRENTFOOS是否包含某些值,因此我创建了两个(或更多)其他表:

BADFOOS      number_tbl := number_tbl (1, 2, 3); 
MONDAYFOOS   number_tbl := number_tbl (2, 3, 7, 8); 
INTERSECTION number_tbl;

并检查坏的foos和星期一foos:

INTERSECTION := CURRENTFOOS MULTISET INTERSECT BADFOOS;

IF INTERSECTION.COUNT > 0 THEN
    RETURN -1; -- bad foo
END IF;

...some more steps...

INTERSECTION := CURRENTFOOS MULTISET INTERSECT MONDAYFOOS;

IF INTERSECTION.COUNT > 0 AND ISMONDAY THEN
    RETURN 1337; -- monday foo
END IF;

这是我在经过一些修补之后想出来的。

这是做我想要的惯用方法吗?是否有一种不那么模糊的方式?

1 个答案:

答案 0 :(得分:1)

EXISTS足够快。

DECLARE
    TYPE number_tbl IS TABLE OF NUMBER;

    currentfoos  number_tbl;
    badfoos      number_tbl;

    l_exists     NUMBER := 0;
BEGIN
    DBMS_OUTPUT.PUT_LINE(SYSDATE);

    SELECT  LEVEL
    BULK    COLLECT INTO currentfoos 
    FROM    DUAL
    CONNECT BY
            LEVEL < 10000000;    -- 10 000 000

    SELECT  a_level
    BULK    COLLECT INTO badfoos 
    FROM
    (
        SELECT  LEVEL AS a_level
        FROM    DUAL
        CONNECT BY
                LEVEL < 200000    -- 200 000
    )
    WHERE   a_level > 100000;     -- 100 000

    FOR indx IN badfoos.FIRST..badfoos.LAST LOOP
        IF currentfoos.EXISTS(badfoos(indx)) THEN
            l_exists := 1;

            EXIT;
        END IF;
    END LOOP;

    DBMS_OUTPUT.PUT_LINE(SYSDATE);

    DBMS_OUTPUT.PUT_LINE(l_exists);
END;
/*
2013-10-22 10:45:23
2013-10-22 10:45:28
1
*/