2016-07-28 5 views
0

最初にまず、OracleよりもSQLの方が多いので、構文/クエリエンジンに関する基本的な事実が不足しているように思えます。Oracle - 一度に複数の列を更新する(バリエーション)

Oracleの複数の列を更新しようとしていますが、以下のコードでいくつかのシナリオを解決しました。

私の問題は、より合理的なコードでは、より複雑なものは必要なものを更新しないということです。私は数十万回以上のアップデートを見ているので最小限の処理能力でこれを達成しようとしています。

だから、最初のコード:今すぐ

UPDATE [email protected] i2 
SET (i2.access, i2.permission) = 
(select 
i2m.access, i2m.permission 
from temporarytable ss 
    JOIN table2 pgm 
    ON ss.secgroup = pgm.string 
    JOIN table i2m 
    ON pgm.hmy = i2m.hgroup 
     AND ss.pername = i2m.sobjname 
    JOIN [email protected] pg 
    ON ss.secgroup = pg.string 

    WHERE 
    pg.string = 'string' -- this limits the updates to a specific subset of data 
    and i2m.hmy > 0 -- this for some freak records in both tables that are missing a primary key 
    and pg.hmy = i2.hgroup -- this matches the key of the 'string' from above to the records i need to update 
    and ss.pername = i2.sobjname -- further condition on which records to update. so only the ones that match from the temp table to the target table 
    and ss.orig_hmy = i2.hmy) -- further condition to make sure i am updating only records matching between temp table and target table 

、私はこれを実行するのではなく、上記のサブクエリに一致するだけで約700の記録を更新した場合、それはテーブルからすべてのレコードを更新「テーブルの@のDATABASE1」と私に」なぜか(おそらく私がOracleについて得られないもののうちの1つ):

しかし、私が以下を実行した場合 - 唯一の違いは、 'where exists'これは私が必要とするものだけを更新します。私の問題は、私がそれを理解する方法です。サブクエリは2回実行されます.1回は更新で、もう1回はwhere句では、処理能力の無駄です。

UPDATE [email protected] i2 
SET (i2.access, i2.permission) = 
(select 
i2m.access, i2m.permission 
from temporarytable ss 
    JOIN table2 pgm 
    ON ss.secgroup = pgm.string 
    JOIN table i2m 
    ON pgm.hmy = i2m.hgroup 
     AND ss.pername = i2m.sobjname 
    JOIN [email protected] pg 
    ON ss.secgroup = pg.string 

    WHERE 
    pg.string = 'string' 
    and i2m.hmy > 0 
    and pg.hmy = i2.hgroup 
    and ss.pername = i2.sobjname 
    and ss.orig_hmy = i2.hmy) 

where exists (select 
i2m.access, i2m.permission 
from temporarytable ss 
    JOIN table2 pgm 
    ON ss.secgroup = pgm.string 
    JOIN table i2m 
    ON pgm.hmy = i2m.hgroup 
     AND ss.pername = i2m.sobjname 
    JOIN [email protected] pg 
    ON ss.secgroup = pg.string 

    WHERE 
    pg.string = 'string' 
    and i2m.hmy > 0 
    and pg.hmy = i2.hgroup 
    and ss.pername = i2.sobjname 
    and ss.orig_hmy = i2.hmy) 

任意のすべての提案が歓迎されます。ありがとうございました!

注:表示されない場合は、同じスキーマを持つ複数のDBがあります。私はマスタースキーマからの情報でDB間のテーブルを更新しようとしています。 Tempテーブルは異なるレコードのリポジトリとして機能し、更新する必要があります。マスタースキーマとの差異が15%にすぎない場合は、何百万ものレコードを更新する必要はありません。

+4

テーブルを更新するこの方法が気に入らない場合は、「merge」を使用できます。 –

+1

私はGordonに同意します。MERGEアプローチをよく読んで理解してください。将来的に大きな配当を支払うことになります。 – mathguy

+3

"それはテーブル 'table @ database1'からすべてのレコードを更新するため、私は理由を見ることができません。 'update'ステートメントに' where'節がないからです。オラクルはそれに特化したものではありません。すべてのプラットフォームで、すべての行を更新する場所がなくても更新に精通しています。 –

答えて

1

ここで役立つすべての人からの提案を受けた後、私はMERGEを使用して調べました。上記のクエリは以下に適合しました。これは成功したと証明されました!

MERGE INTO [email protected] i2 
    USING (
    select i2m.access, i2m.permission, ss.orig_hmy 
    from table i2m 
     JOIN table2 pgm 
     ON i2m.hgroup = pgm.hmy 
     JOIN temporarytable ss 
     ON pgm.string = ss.string 
      AND ss.pername = i2m.sobjname 
     JOIN [email protected] pg 
     ON ss.string = pg.string 
    WHERE 1 = 1 
     and i2m.hmy > 0 
     and pg.string = 'string' 
     and ss.database = 'database1' 
    ) u on (i2.hmy = u.orig_hmy) 
    WHEN MATCHED THEN 
     UPDATE SET i2.access = u.access, i2.permission = u.permission; 

ありがとうございます!

+0

ありがとうございました - あなたはすべての仕事をしました! – mathguy

関連する問題