2016-07-28 13 views
0

Erste Dinge zuerst, ich bin mehr ein SQL-Typ als Oracle so nackt mit mir, wenn ich grundlegende Fakten über Syntax/Abfrage-Engine zu fehlen scheinen.Oracle - Aktualisieren mehrerer Spalten auf einmal (Variation)

Ich versuche, mehrere Spalten in Oracle zu aktualisieren und nach ein paar Szenarien auf den folgenden Code festgelegt.

Mein Problem ist, dass der stromlinienförmigere Code nicht aktualisiert, was ich brauche, während der kompliziertere tut - ich versuche, dies mit minimaler Verarbeitungsleistung zu erreichen, da ich Hunderttausende von Updates oder sogar mehr betrachte.

So ist der erste Code:

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 

Nun, wenn ich dies ausführen, sondern nur noch etwa 700 Datensätze zu aktualisieren, die die oben Unterabfrage entsprechen aktualisiert es alle Datensätze aus der Tabelle ‚Tabelle @ database1‘ und ich kann‘ Ich sehe, warum (wahrscheinlich eines der Dinge, die ich über Oracle nicht verstehe :))

Aber wenn ich das unten - was der einzige Unterschied ist, dass ich die ganze Unterabfrage in einem "wo existiert" einfügen - dann Dies aktualisiert nur das, was ich brauche. Mein Problem ist, dass die Unterabfrage, so wie ich es verstehe, zweimal ausgeführt wird - einmal im Update und einmal in der Where-Klausel - was ich für eine Verschwendung von Verarbeitungsleistung halte.

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) 

Alle und alle Vorschläge sind willkommen. Danke!

hinweis: falls es nicht angezeigt wird, habe ich mehrere DBs mit dem gleichen schema. Ich versuche, eine Tabelle über DBs mit den Informationen aus einem Masterschema zu aktualisieren. Die Temp-Tabelle dient als Repository für die Datensätze, die unterschiedlich sind und aktualisiert werden müssen - kein Grund, Millionen von Datensätzen zu aktualisieren, wenn nur 15% vom Master-Schema abweichen.

+4

Sie können 'merge' verwenden, wenn Sie diese Methode zum Aktualisieren von Tabellen nicht mögen. –

+1

Ich stimme Gordon zu, bitte lesen Sie und machen Sie sich mit dem MERGE-Ansatz vertraut. Es wird in der Zukunft große Dividenden zahlen. – mathguy

+3

"Es aktualisiert alle Datensätze aus der Tabelle 'Tabelle @ Datenbank1' und ich kann nicht sehen, warum." Weil Sie keine 'where'-Klausel in der 'update'-Anweisung haben. Nichts Oracle-spezifisches darüber, in allen mir bekannten Plattformen ist das mit update ohne wo jede Zeile aktualisiert wird. –

Antwort

1

Nachdem ich Vorschläge von all den hilfsbereiten Leuten hier angenommen hatte, habe ich MERGE untersucht und die obige Abfrage wurde in das untenstehende Format übernommen - was sich als erfolgreich erwies!

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; 

Vielen Dank an alle!

+0

Vielen Dank - DU hast die ganze Arbeit gemacht! – mathguy