0

PL/SQL で関数を作成していますが、一連のデータが複数回必要で、データベースを 1 回だけクエリしたいので、データをテーブルに保存します。

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

ここで、テーブルに値が含まれているかどうかを確認したいCURRENTFOOSので、2 つ (またはそれ以上) の他のテーブルを作成します。

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

そして、悪い foo と monday foo をチェックするには:

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 に答える