Oracle SQL: een tabel bijwerken met gegevens uit een andere tabel

Tabel 1:

id    name    desc
-----------------------
1     a       abc
2     b       def
3     c       adf

Tabel 2:

id    name    desc
-----------------------
1     x       123
2     y       345

Hoe voer ik in Oracle SQL een sql update-query uit die Tabel 1 kan bijwerken met Tabel 2’s nameen descmet dezelfde id? Dus het eindresultaat dat ik zou krijgen is

Tabel 1:

id    name    desc
-----------------------
1     x       123
2     y       345
3     c       adf

Vraag is overgenomen uit de ene tabel bijwerken met gegevens van een andere, maar specifiek voor Oracle SQL.


Antwoord 1, autoriteit 100%

Dit wordt een gecorreleerde update genoemd

UPDATE table1 t1
   SET (name, desc) = (SELECT t2.name, t2.desc
                         FROM table2 t2
                        WHERE t1.id = t2.id)
 WHERE EXISTS (
    SELECT 1
      FROM table2 t2
     WHERE t1.id = t2.id )

Ervan uitgaande dat de samenvoeging resulteert in een weergave met bewaarde sleutel, kunt u ook

UPDATE (SELECT t1.id, 
               t1.name name1,
               t1.desc desc1,
               t2.name name2,
               t2.desc desc2
          FROM table1 t1,
               table2 t2
         WHERE t1.id = t2.id)
   SET name1 = name2,
       desc1 = desc2

Antwoord 2, Autoriteit 31%

Probeer dit:

MERGE INTO table1 t1
USING
(
-- For more complicated queries you can use WITH clause here
SELECT * FROM table2
)t2
ON(t1.id = t2.id)
WHEN MATCHED THEN UPDATE SET
t1.name = t2.name,
t1.desc = t2.desc;

Antwoord 3, Autoriteit 4%

Probeer

UPDATE Table1 T1 SET
T1.name = (SELECT T2.name FROM Table2 T2 WHERE T2.id = T1.id),
T1.desc = (SELECT T2.desc FROM Table2 T2 WHERE T2.id = T1.id)
WHERE T1.id IN (SELECT T2.id FROM Table2 T2 WHERE T2.id = T1.id);

Antwoord 4, Autoriteit 2%

Update table set column = (select...)

Nooit voor mij gewerkt sinds set alleen verwacht 1 waarde – SQL-fout: ORA-01427: Subquery met enkele rij geeft meer dan één rij terug.

Hier is de oplossing:

BEGIN
For i in (select id, name, desc from table1) 
LOOP
Update table2 set name = i.name, desc = i.desc where id = i.id;
END LOOP;
END;

Dat is hoe je het precies op Sqldeveloper Worksheet uitvoert. Ze zeggen dat het langzaam is, maar dat is de enige oplossing die voor mij in deze zaak heeft gewerkt.


Antwoord 5

Hier lijkt een nog beter antwoord te zijn met ‘in’-clausule die meerdere sleutels voor de join mogelijk maakt:

update fp_active set STATE='E', 
   LAST_DATE_MAJ = sysdate where (client,code) in (select (client,code) from fp_detail
  where valid = 1) ...

Het volledige voorbeeld is hier:
http://forums.devshed.com/oracle-development-96/how-to-update-from-two-tables-195893.html– uit webarchief sinds link was dood.

Het probleem zit hem in het hebben van de kolommen die u wilt gebruiken als de sleutel tussen haakjes in de where-clausule vóór ‘in’ en de select-instructie met dezelfde kolomnamen tussen haakjes.
waar (kolom1,kolom2) in ( selecteer (kolom1,kolom2) uit tabel waar “de set die ik wil”);


Antwoord 6

Als uw tabel t1 en de back-up t2 veel kolommen hebben, kunt u dit op een compacte manier doen.

Bovendien was mijn gerelateerde probleem dat slechts enkele van de kolommen werden gewijzigd en dat veel rijen geen bewerkingen in deze kolommen hadden, dus ik wilde die met rust laten – in feite een subset van kolommen herstellen vanaf een back-up van de hele tabel. Als je gewoon alle rijen wilt herstellen, sla dan de where-clausule over.

Natuurlijk zou de eenvoudigere manier zijn om te verwijderen en in te voegen als select, maar in mijn geval had ik een oplossing nodig met alleen updates.

De truc is dat als je * selecteert uit een paar tabellen met dubbele kolomnamen, de 2e de naam _1 krijgt. Dus hier is wat ik bedacht:

 update (
    select * from t1 join t2 on t2.id = t1.id
    where id in (
      select id from (
        select id, col1, col2, ... from t2
        minus select id, col1, col2, ... from t1
      )
    )
  ) set col1=col1_1, col2=col2_1, ...

Antwoord 7

BEGIN
For i in (select id, name, desc from table2) 
LOOP
Update table1 set name = i.name, desc = i.desc where id = i.id and (name is null or desc is null);
END LOOP;
END;

Other episodes