2013-04-12 19 views
5

Ho una query SQL con lo stesso codice esatto, ma due tabelle diverse (AUDIT_TRAIL_ARCHIVE e AUDIT_TRAIL). Io uso "UNION ALL" per avere un risultato.Non ripetersi: stessa query SQL, ma due tabelle diverse

I buoni programmatori usano il principio "Don't repeat yourself". I bravi programmatori evitano WET (scrivono tutto due volte).

Come riscrivere questo codice con il principio "Non ripetere te stesso"?

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

Qual è il tuo obiettivo qui: utilizzare SQL dinamico, ad es. stesso sql ma diff. tabelle o riscrivi la query come nell'esempio di Florin? – Art

+0

@ fyodor78 La prima soluzione non è sempre la migliore. Naturalmente puoi unirti alle tabelle PRIMA di selezionare - ma perché dovresti costruire una tabella temporanea di 100.000 righe, quando vuoi recuperare una riga da ciascuna? Vedere in SQL dinamico, creare una procedura, creare una stringa di query e riutilizzare tale procedura. – dognose

risposta

4

Ad esempio:

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

Ho ragione nel ritenere che non sareste in grado di filtrare i due selezioni che si "UNION ALL" con i valori del resto della query? – Lilienthal

+1

No. In realtà, la risposta filtra le due query nella clausola where: 'AU.TABLE_NAME = 'rss_user''. AU è lo pseudonimo dell'unione a parte. Il filtro può essere spinto dal motore per filtrare prima di eseguire il join. –

0

bravi programmatori usano "Non ripetere te stesso" principio. I bravi programmatori evitano WET (scrivono tutto due volte).

Heh. Mi piace. sottile.

anche, sto probabilmente essere troppo semplice, ma sarebbe qualcosa di simile a questo lavoro:

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: vedo dalla prima risposta postato mi sono innamorata di una pesca a traina? sciocco me.

+0

@@ Bryan Devaney: il tuo codice non funzionerà mai in Oracle. Per favore rivedi. – Art

+0

scusa, sono spuntato sotto sql, ho pensato che fosse mysql ... aggiornamento risposta ora –

0

Semplicemente non puoi. SQL è linguaggio compilato (anche se sembra uno script) e Oracle ricorda OBJECT_IDs dipende dalla query. Ogni metà della query ha diverse dipendenze, diversi "bytecode" e diversi piani di esecuzione.

Puoi

  • Usa tabelle di partizionamento. Quindi avresti solo un tavolo. Le query su dati live potrebbero essere limitate utilizzando "select * from AUDIT_TRAIL partition ACTIVE".

  • Utilizzo di query di factoring come

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

    ma non sono sicuro se in questo caso sarà di Oracle garantire la stessa efficienza del piano di esecuzione.

Problemi correlati