代码之家  ›  专栏  ›  技术社区  ›  sloth

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

  •  0
  • sloth  · 技术社区  · 12 年前

    我正在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 回复  |  直到 12 年前
        1
  •  1
  •   the_slk    12 年前

    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
    */