我需要有关程序结构的帮助。 首先,我应该检索表名和所有者列表。 在程序的主体,我想使用此列表进行测试和比较。 我做了一些使用光标的例子,我知道这不是真的。 请告知如何实现这一点。
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;
答案 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的内容在当前会话期间不会更改。