2013-04-12 14 views
5

Mam zapytanie SQL z dokładnie tym samym kodem, ale dwiema różnymi tabelami (AUDIT_TRAIL_ARCHIVE i AUDIT_TRAIL). Używam "UNION ALL", aby uzyskać jeden wynik.Nie powtarzaj się: to samo zapytanie SQL, ale dwie różne tabele

Zasada dobrego programisty polega na użyciu zasady "Don't repeat yourself". Dobrzy programiści unikają WET (zapisuj wszystko dwa razy).

Howto przepisać ten kod za pomocą zasady "Nie powtarzaj się"?

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

Jaki jest Twój cel: użyć dynamicznego sql, np. ten sam sql ale diff. tabele lub przepisać zapytanie tak jak w przykładzie Florina? – Art

+0

@ fyodor78 Pierwsze rozwiązanie nie zawsze jest najlepsze. Oczywiście możesz dołączyć do tabel PRZED WYBOREM - ale dlaczego chcesz utworzyć tabelę tymczasową o wartości 100 000 wierszy, jeśli chcesz pobrać jeden wiersz z każdego z nich? Zobacz w dynamicznym SQL, utwórz procedurę, zbuduj ciąg zapytania i ponownie użyj tej procedury. – dognose

Odpowiedz

4

Na przykład:

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

Czy mam rację, sądząc, że nie będzie można filtrować dwóch wyborów, które "UNION WSZYSTKO" od wartości z reszty kwerendy? – Lilienthal

+1

Nie. W rzeczywistości odpowiedź filtruje dwa zapytania w klauzuli where: 'AU.TABLE_NAME = 'rss_user''. AU jest pseudonimem dla związku wszystkich części. Filtr może być wciśnięty przez silnik, aby filtrować przed wykonaniem połączenia. –

0

Dobrzy programiści użyć "dry" zasadę. Dobrzy programiści unikają WET (zapisuj wszystko dwa razy).

Heh. Lubię to. subtelny.

też, ja prawdopodobnie jest zbyt proste, ale byłoby coś podobnego do tego dzieła:

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]; 

edit: widzę od pierwszej wysłana odpowiedź upadłem na trolling? głupi ja.

+0

@@ Bryan Devaney: Twój kod nigdy nie zadziała w Oracle. Proszę zrewidować. – Art

+0

Przepraszam, pojawił się w sql, że to było mysql ... aktualizacja odpowiedzi teraz –

0

Po prostu nie możesz. SQL jest językiem skompilowanym (nawet jeśli wygląda na skrypt), a Oracle zapamiętuje identyfikatory obiektów OBJECT_ID, od których zależy zapytanie. Każda połowa zapytania ma różne zależności, inny "kod bajtowy" i inny plan wykonania.

Można

  • Wykorzystanie partycjonowania tabel. Wtedy miałbyś tylko jeden stół. Zapytania dotyczące danych na żywo mogą być ograniczone za pomocą "wybierz * z AKTYWUJ partycję AUDIT_TRAIL".

  • Wykorzystanie zapytań faktoring jak

    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 ... 
    ... 
    

    Ale nie jestem pewien, czy w tym przypadku Oracle gwarantuje taką samą skuteczność planu wykonania.

Powiązane problemy