2013-04-12 22 views
5

Aynı kodla bir SQL sorgum var, ancak iki farklı tablo (AUDIT_TRAIL_ARCHIVE ve AUDIT_TRAIL). Bir sonuca sahip olmak için "UNION ALL" kullanıyorum.Kendiniz tekrarlama: aynı SQL sorgusu, ancak iki farklı tablo

İyi programcılar "Don't repeat yourself" ilkesini kullanır. İyi programcılar WET'ten kaçınıyor (her şeyi iki kez yaz).

Bu kodu "Kendiniz tekrar etmeyin" ilkesiyle nasıl yeniden yazabilirsiniz? Örneğin

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

Hedefiniz burada: dinamik sql'yi kullanmak, ör. aynı sql ancak farklı. tabloları veya Florin örneğinde olduğu gibi sorguyu yeniden yazmak? – Art

+0

@ fyodor78 İlk çözüm her zaman en iyisi değil. Tabii ki Seçmeden ÖNCE tablolara katılabilirsiniz - fakat her birini bir sıra almak istediğinizde neden 100.000 satırlık geçici bir tablo oluşturursunuz? Dinamik SQL'de bakın, bir prosedür oluşturun, bir sorgu dizgisi oluşturun ve bu prosedürü tekrar kullanın. – dognose

cevap

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

Sorunun geri kalanından gelen değerler ile "BİRLİĞİ TÜMÜ" seçeneğini seçtiğiniz iki seçenekten birini filtreleyemeyeceğinizi düşünüyorum. – Lilienthal

+1

Hayır. Aslında, yanıt, aşağıdaki iki sorguyu filtreler: "AU.TABLE_NAME =" rss_user ". AU, sendikanın bütün kısmıdır. Filtre, birleştirmeden önce filtrelemek için motor tarafından itilebilir. –

0

İyi programcılar ilkesini "Kendini tekrar etme" kullanırlar. İyi programcılar WET'ten kaçınıyor (her şeyi iki kez yaz).

Heh. Bunu sevdim. ince.

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

düzenleme: ayrıca

, muhtemelen bu işi gibi bir şey olurdu yol çok temel varlık ama değilim ben bir trolling için düştü ilk yayınlanan cevabını görmek? aptal ben

+0

@@ Bryan Devaney: Kodunuz asla Oracle'da çalışmayacaktır. Lütfen gözden geçirin. – Art

+0

Üzgünüz, sql altında attı, mysql olduğunu düşündüm ... güncelleme –

0

Basitçe yapamazsınız. SQL derlenmiş dildir (betik gibi görünse bile) ve Oracle, sorguya bağlı OBJECT_ID'leri hatırlar. Sorgunun her yarısında farklı bağımlılıklar, farklı "bytecode" ve farklı yürütme planı vardır.

yapabilirsiniz

  • kullanın tablo bölümleme. O zaman sadece bir tablonun olurdu. Canlı verilere yönelik sorgular, "AUDIT_TRAIL bölümü ACTIVE'dan select *" kullanılarak kısıtlanabilir.

  • Kullanım sorgu

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

    gibi faktoring Ama Oracle yürütme planının aynı verimi garanti edecek bu durumda olup olmadığından emin değilim.