2013-04-12 96 views
5

我有一個SQL查詢具有完全相同的代碼,但有兩個不同的表(AUDIT_TRAIL_ARCHIVE和AUDIT_TRAIL)。我使用「UNION ALL」來獲得一個結果。不要重複自己:相同的SQL查詢,但兩個不同的表

好程序員使用"Don't repeat yourself"原理。好的程序員避免WET(把所有的東西寫兩遍)。

如何用「不要重複自己」的原則重寫這段代碼?

SELECT REPLACE (ENTITY_KEY, 'rss_user_name=CN=', '') 
FROM AUDIT_TRAIL_ARCHIVE AU 
    INNER JOIN 
     (SELECT RSS_USER_NAME 
     FROM RSS_USER 
     WHERE RSS_NAME = 'rmad' 
       AND ADD_INFO_MASTER LIKE '%__47__UPN=%@richemont.com%') FALSCH 
    ON REPLACE (AU.ENTITY_KEY, 'rss_user_name=CN=', '') = 
     FALSCH.RSS_USER_NAME 
WHERE  AU.RSS_NAME = 'rmad' 
    AND AU.TABLE_NAME = 'rss_user' 
    AND AU.ACTION = 'Insert' 
    AND AU.ENTITY_KEY LIKE 'rss_user_name=CN=%' 
    AND AU.ORIGIN != 'RSS' 
UNION ALL 
SELECT REPLACE (ENTITY_KEY, 'rss_user_name=CN=', '') 
FROM AUDIT_TRAIL AU 
    INNER JOIN 
     (SELECT RSS_USER_NAME 
     FROM RSS_USER 
     WHERE RSS_NAME = 'rmad' 
       AND ADD_INFO_MASTER LIKE '%__47__UPN=%@richemont.com%') FALSCH 
    ON REPLACE (AU.ENTITY_KEY, 'rss_user_name=CN=', '') = 
     FALSCH.RSS_USER_NAME 
WHERE  AU.RSS_NAME = 'rmad' 
    AND AU.TABLE_NAME = 'rss_user' 
    AND AU.ACTION = 'Insert' 
    AND AU.ENTITY_KEY LIKE 'rss_user_name=CN=%' 
    AND AU.ORIGIN != 'RSS' 
+0

這裏你的目標是什麼:使用動態sql,例如相同的SQL但差異。表或重寫查詢,如弗羅林的例子? – Art

+0

@ fyodor78第一種解決方案並不總是最好的。當然,您可以在選擇之前加入表格 - 但是,如果您想從每個表格檢索一行,爲什麼要構建一個100.000行的臨時表格?在動態SQL中查看,創建一個過程,建立一個查詢字符串並重用該過程。 – dognose

回答

4

例如:

SELECT REPLACE (ENTITY_KEY, 'rss_user_name=CN=', '') 
FROM (select * --or relevant columns 
      from AUDIT_TRAIL_ARCHIVE AU 
      union all 
      select * 
      from AUDIT_TRAIL AU 
      ) AU 
    INNER JOIN 
     (SELECT RSS_USER_NAME 
     FROM RSS_USER 
     WHERE RSS_NAME = 'rmad' 
       AND ADD_INFO_MASTER LIKE '%__47__UPN=%@richemont.com%') FALSCH 
    ON REPLACE (AU.ENTITY_KEY, 'rss_user_name=CN=', '') = 
     FALSCH.RSS_USER_NAME 
WHERE  AU.RSS_NAME = 'rmad' 
    AND AU.TABLE_NAME = 'rss_user' 
    AND AU.ACTION = 'Insert' 
    AND AU.ENTITY_KEY LIKE 'rss_user_name=CN=%' 
    AND AU.ORIGIN != 'RSS' 
+0

我是否認爲你無法通過查詢的其餘部分的值來過濾兩個選擇,即'UNION ALL'? – Lilienthal

+1

否。實際上,答案會過濾where子句中的兩個查詢:'AU.TABLE_NAME ='rss_user''。 AU是聯盟的所有部分的別名。在進行連接之前,過濾器可以由發動機推動進行過濾。 –

0

好的程序員會用 「不要重複自己」 的原則。好的程序員避免WET(把所有的東西寫兩遍)。

heh。我喜歡。微妙。

也,我可能是太基本的,但會是這樣的工作:

CREATE [OR REPLACE] PROCEDURE <name_of_procedure> [ (<ENTITY_KEY_variable>) ] 
IS 
    <ENTITY_KEY=ENTITY_KEY_variable> 
BEGIN 
    <your code goes here> 

    [EXCEPTION 
     exception_section] 
END [procedure_name]; 

編輯:我從第一個公佈答案,我愛上了一個曳看到了什麼?傻我。

+0

@@ Bryan Devaney:您的代碼在Oracle中將無法使用。請修改。 – Art

+0

對不起,在sql下彈出,以爲是mysql ... 現在更新回答 –

0

只是你不能。 SQL是編譯語言(即使它看起來像腳本),Oracle會記住查詢依賴的OBJECT_ID。查詢的每一半都有不同的依賴關係,不同的「字節碼」和不同的執行計劃。

您可以

  • 使用表分區。那麼你將只有一張桌子。使用「select * from AUDIT_TRAIL partition ACTIVE」可以限制針對實時數據的查詢。

  • 使用查詢保像

    WITH AU AS 
    (SELECT * from AUDIT_TRAIL union all select * from AUDIT_TRAIL_ARCHIVE) 
    SELECT REPLACE (ENTITY_KEY, 'rss_user_name=CN=', '') 
    FROM AU JOIN ... 
    ... 
    

    但我不知道是否在這種情況下,將甲骨文保證執行計劃的相同的效率。