0

我在 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;

这是我经过一番修改后得出的结论。

那么这是做我想做的事的惯用方式吗?有没有不那么晦涩的方法?

4

1 回答 1

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
*/
于 2013-10-22T08:46:58.023 回答