2012-07-27 15 views
6

Ich schreibe gerade Update-Anweisungen, um eine abfragbare Tabelle ständig auf dem neuesten Stand zu halten. Das Schema ist identisch zwischen den beiden Tabellen und die Inhalte sind nicht wichtig:Oracle SQL-Update basiert auf Unterabfrage zwischen zwei Tabellen

STAGING 

ID 
NAME 
COUNT  

PRODUCTION 

ID 
NAME 
COUNT 

Meine Update-Anweisung sieht wie folgt aus:

update PRODUCTION 
set name = (select stage.name from staging stage where stage.name=name and rownum <2), 
    count = (select stage.countfrom staging stage where stage.count=count and rownum <2); 

Die zwei Dinge bemerkenswert ist, dass 1) Es gibt keine where-Klausel bei das Ende meiner Aktualisierung (dies kann das Problem sein) und 2) alle Datensätze nach der Aktualisierung haben die gleichen Werte. Was ich damit meine, ist folgende:

BEFORE UPDATE: 

1,"JOHN", 12; 
2,"STEVE",15; 
3,"BETTY",2; 

AFTER UPDATE 

    1,"JOHN", 12; 
    2,"JOHN",12; 
    3,"JOHN",12; 

Meine Frage ist, wie kann ich dieses Problem beheben, so dass die Tabelle spiegelt richtig „neue“ Daten als korrektes SQL-Update Staging?

UPDATE

meine Inszenierung Daten könnten zufällig So spiegeln, was in PRODUCTION und zum Zwecke der Diskussion ist, es wird:

STAGING DATA TO MERGE: 

    1,"JOHN", 12; 
    2,"STEVE",15; 
    3,"BETTY",2; 

UPDATE die zweite

Die Abfrage, die Ich würde gerne folgendes tun:

Dies ist jedoch in einem ungültigen Kennung Probleme Treffer zu „staging.name“

+0

Möchten Sie ** Name ** und ** zählen ** in ** PRODUKTION ** Tabelle aktuell und ** STAGING ** Tabelle ändert sich? – hmmftg

+0

Warum verwenden Sie keine Trigger, um neue Werte anstelle dieses Updates einzufügen? Was genau macht dieses Update? – hmmftg

+0

Vereinbart, wenn Sie Tabellen synchronisieren, können Trigger wirklich nützlich sein, um sie in Echtzeit auf dem neuesten Stand zu halten. Achten Sie nur auf mutierende Tabellenfehler, und stellen Sie sicher, dass Sie dies NACH dem Einfügen oder Aktualisieren tun. – Hermit

Antwort

26

Es gibt zwei Möglichkeiten zu tun, was Sie

One versuchen, ist ein Multi-column Correlated Update

UPDATE PRODUCTION a 
SET (name, count) = (
    SELECT name, count 
    FROM STAGING b 
    WHERE a.ID = b.ID); 

DEMO

Sie merge verwenden können

MERGE INTO PRODUCTION a 
USING (select id, name, count 
      from STAGING) b 
ON (a.id = b.id) 
WHEN MATCHED THEN 
UPDATE SET a.name = b.name, 
      a.count = b.count 

DEMO

+0

Lassen Sie mich versuchen, die Multi-Spalte korreliert. Ich musste aus dem Merge wegziehen, weil es langsam ist (über 10 Millionen Datensätze) – Woot4Moo

0

Wie Sie bemerkt haben, haben Sie keine Selektivität für Ihre Update-Anweisung, so dass es Ihre gesamte Tabelle aktualisiert. Wenn Sie bestimmte Zeilen aktualisieren möchten (dh wo die IDs übereinstimmen), möchten Sie wahrscheinlich eine koordinierte Unterabfrage durchführen.

Da Sie jedoch Oracle verwenden, ist es möglicherweise einfacher, eine materialisierte Ansicht für Ihre Abfragetabelle zu erstellen, und der Transaktionsmechanismus von Oracle verarbeitet die Details. MVs funktionieren genau wie eine Tabelle zum Abfragen von Semantiken, sind recht einfach einzurichten und ermöglichen Ihnen, das Aktualisierungsintervall anzugeben.

1

Ohne Beispiele für den Dataset der Inszenierung ist dies eine Aufnahme im Dunkeln, aber haben Sie so etwas versucht?

update PRODUCTION p, 
     staging s 
set p.name = s.name 
    p.count = s.count 
where p.id = s.id 

Dies würde unter der Annahme funktionieren, dass die ID-Spalte in beiden Tabellen übereinstimmt.

+0

Also, wenn die einzigen Dinge, die ich angleichen möchte, sind die where-Klauseln in meinen Unterabfragen? IE set blah wo p.name = s.name und p.count = s.count? – Woot4Moo

+0

Wenn Sie das tun würden, würden Sie a = zu b setzen, wobei a = = b ist (d. H. Es würde nichts tun). – Hermit

+0

Oops fehlgeschlagen Logik meinerseits :) – Woot4Moo

0

Versuchen Sie es ..
UPDATE PRODUCTION a
SET (Name, count) = (
SELECT name, zählen
FROM STAGING b
WHERE a.ID = b.ID)
WHERE EXISTIERT (1
FROM STAGING b Wählen
WHERE a.ID = b.ID
);

Verwandte Themen