2013-04-12 4 views
5

同じコードを持つSQLクエリはありますが、2つの異なるテーブル(AUDIT_TRAIL_ARCHIVEとAUDIT_TRAIL)があります。私は "UNION ALL"を使って1つの結果を得ます。自分自身を繰り返してはいけません:同じSQLクエリではあるが2つの異なるテーブル

良いプログラマーは"Don't repeat yourself"原則を使用します。良いプログラマーはWETを避ける(すべてを2回書く)。

このコードを「自分自身を繰り返さないでください」という原則に書き換えますか?例えば

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だがdiff。テーブルを作成したり、Florinの例のようにクエリを書き直したりできますか? – Art

+0

@ fyodor78最初の解決策は必ずしも最良ではありません。もちろん、選択前のテーブルに参加することはできますが、各テーブルから1行を取得する場合は、なぜ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'という2つの選択肢をフィルタリングできないと思っていますか? – Lilienthal

+1

いいえ、実際には、答えはwhere句の2つのクエリ、つまり、 'AU.TABLE_NAME = 'rss_user'をフィルタリングします。 AUは、ユニオンのすべての部分のエイリアスです。ジョインを行う前にフィルタをエンジンにプッシュしてフィルタリングすることができます。 –

0

良いプログラマは原則を "自分自身を繰り返してはいけない" を使用します。良いプログラマーはWETを避ける(すべてを2回書く)。

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を記憶しています。問合せの各半分には、依存性、異なる「バイトコード」および異なる実行計画があります。

あなたは

  • 使用表領域のパーティショニングすることができます。それからあなたはテーブルを1つしか持たないでしょう。 "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 ... 
    ... 
    

    などの使用クエリーファクタリングしかし、私はこのケースでは、Oracleは実行計画の同じ効率を保証するかどうかはわかりません。

関連する問題