如何在过程体上使用所选值的列表

时间:2013-11-30 17:49:47

标签: oracle plsql oracle10g

我需要有关程序结构的帮助。 首先,我应该检索表名和所有者列表。 在程序的主体,我想使用此列表进行测试和比较。 我做了一些使用光标的例子,我知道这不是真的。 请告知如何实现这一点。

CREATE OR REPLACE PROCEDURE TEST_PROCEDURE (P_CODE IN NUMBER) IS

CURSOR C01 IS
(SELECT TABLE_NAME, OWNER
FROM TABLE1
UNION
SELECT TABLE_NAME, OWNER
FROM TABLE2);

BEGIN

SELECT MAX(SCORE)
INTO V_SCORE
FROM TABLE4 Q
WHERE EXISTS (SELECT 'Y'
FROM C01 T --- ?????????
WHERE Q.TABLE_NAME = T.TAB_NAME
AND Q.OWNER = T.OWNER);

END TEST_PROCEDURE;

1 个答案:

答案 0 :(得分:1)

这个想法很好,但是经历了一些小的误解。游标不是要替换视图或完整结果集,它们只是允许您逐个解析(如游标)给出结果集。

在这种情况下,您可以使用公用表表达式(CTE):

CREATE OR REPLACE PROCEDURE TEST_PROCEDURE (P_CODE IN NUMBER) IS
BEGIN

    WITH C01 AS (
        SELECT 
            TABLE_NAME, 
            OWNER
        FROM TABLE1
        UNION
        SELECT 
            TABLE_NAME, 
            OWNER
        FROM TABLE2
    )
    SELECT MAX(SCORE) INTO V_SCORE
    FROM TABLE4 Q
    WHERE 
        EXISTS (
            SELECT 'Y'
            FROM C01 T
            WHERE Q.TABLE_NAME = T.TAB_NAME
            AND Q.OWNER = T.OWNER
    );
END TEST_PROCEDURE;

如果您多次需要此CTE,那么为什么不创建视图?

CREATE OR REPLACE VIEW C01 AS 
    SELECT 
        TABLE_NAME, 
        OWNER
    FROM TABLE1
    UNION
    SELECT 
        TABLE_NAME, 
        OWNER
    FROM TABLE2
;

CREATE OR REPLACE PROCEDURE TEST_PROCEDURE (P_CODE IN NUMBER) IS
BEGIN

    SELECT MAX(SCORE) INTO V_SCORE
    FROM TABLE4 Q
    WHERE 
        EXISTS (
            SELECT 'Y'
            FROM C01 T
            WHERE Q.TABLE_NAME = T.TAB_NAME
            AND Q.OWNER = T.OWNER
    );
END TEST_PROCEDURE;

甚至更好,因为你似乎只是检查一组值是否存在,为此创建一个确定性函数:

CREATE OR REPLACE FUNCTION EXISTS_IN_TABLES(I_OWNER IN VARCHAR2, I_TABLE IN VARCHAR2) RETURNS NUMBER DETERMINISTIC AS
BEGIN

    SELECT 1 
    FROM (
        SELECT TABLE_NAME, OWNER
        FROM TABLE1
        UNION
        SELECT TABLE_NAME, OWNER
        FROM TABLE2
    ) T
    WHERE I_TABLE = T.TAB_NAME
    AND I_OWNER = T.OWNER;

    RETURN 1;
EXCEPTION
    WHEN NO_DATA_FOUND THEN RETURN 0;
    WHEN OTHERS THEN RAISE;
END;

CREATE OR REPLACE PROCEDURE TEST_PROCEDURE (P_CODE IN NUMBER) IS
BEGIN

    SELECT MAX(SCORE) INTO V_SCORE
    FROM TABLE4 Q
    WHERE 
        EXISTS_IN_TABLES(Q.OWNER, Q.TABLE_NAME) = 1
    ;
END TEST_PROCEDURE;

deterministic选项可以优化性能,但是您必须确保TABLE1和TABLE2的内容在当前会话期间不会更改。