Benutzer-Werkzeuge

Webseiten-Werkzeuge


prog:sql_update_syntax

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
prog:sql_update_syntax [2016/10/06 17:27] – [Merge Lösung] gpipperrprog:sql_update_syntax [2016/10/06 17:40] (aktuell) – [Inline View für die SQL 92 Syntax] gpipperr
Zeile 1: Zeile 1:
 +===== Oracle SQL - Update und Merge mit Daten in einer Tabelle mit Werten aus einer zweiten Tabelle =====
  
 +
 +
 +
 +
 +**Aufgabe:** Daten in einer Tabelle mit Daten aus einer zweiten Tabelle aktualisieren.
 +
 +{{:images:highland_kuh_dolomiten_2016.png?300 |Highland Kuh in Oberegen in den Dolomiten - hat wohl andere Sorgen}}
 +
 +
 +==== Update Lösung ====
 +
 +=== Inline View für die SQL 92 Syntax ===
 +
 +Die einfache INNER JOIN Syntax wird auch mit Oracle 12 nicht unterstützt, daher diese Lösung über eine "Inline View" gewählt:
 +<code SQL>
 +UPDATE(
 +  select emp.PHONE_NUMBER
 +       , DEPARTMENT_ID 
 +   from EMPLOYEES emp inner join departments dept using (DEPARTMENT_ID) 
 +  where dept.DEPARTMENT_NAME='IT'
 +)
 +SET PHONE_NUMBER = '0890000'||to_char(DEPARTMENT_ID)
 +/
 +</code>
 +
 +Alternativ traditionell:
 +<code SQL>
 +UPDATE EMPLOYEES emp
 +   set PHONE_NUMBER = '0890000'|| (  select to_char(dept.DEPARTMENT_ID) 
 +                                       from departments dept 
 +        where dept.DEPARTMENT_NAME= 'IT'   
 +         and dept.DEPARTMENT_ID  = emp.DEPARTMENT_ID )
 +where emp.DEPARTMENT_ID in ( select DEPARTMENT_ID from departments dept where dept.DEPARTMENT_NAME='IT'    
 +/
 +</code>
 +
 +Es lassen sich auch mehrere Spalten auf einmal updaten:
 +
 +<code SQL>
 +UPDATE EMPLOYEES emp
 +   set (PHONE_NUMBER , EMAIL)  =  (  select '0890000'||to_char(dept.DEPARTMENT_ID),dept.DEPARTMENT_NAME||'@info.de' 
 +                                       from departments dept 
 +        where dept.DEPARTMENT_NAME= 'IT'   
 +         and dept.DEPARTMENT_ID  = emp.DEPARTMENT_ID )
 +where emp.DEPARTMENT_ID in ( select DEPARTMENT_ID from departments dept where dept.DEPARTMENT_NAME='IT'    
 +/
 +</code>
 +
 +
 +Wenn das zu langsam wird hift dann nur noch PL/SQL
 +<code sql>
 +declare
 +    cursor c_old_id  is 
 +        select ed.LOCALID,per.per_id_1  
 +          from event_detail ed  
 +            inner join ods.person per on (per.per_id_3= ed.LOCALID);
 +    v_count pls_integer:=0;
 +begin
 +     for rec in c_old_id
 +     loop
 +        update event_detail set LOCALID=rec.per_id_1 where LOCALID=rec.LOCALID;
 +        dbms_output.put_line('Set '||rec.LOCALID||' to '||rec.per_id_1);
 +        v_count:=v_count+1;
 +     end loop;
 +    dbms_output.put_line('Update '||v_count||' Records');
 +end;
 +/
 +</code>
 +----
 +
 +==== Merge Lösung ====
 +
 +An einfachsten und am besten lesbar ist die Verwendung des Merge Befehles:
 +<code sql>
 +MERGE INTO EMPLOYEES emp 
 +USING departments dept 
 +   ON (dept.DEPARTMENT_ID  = emp.DEPARTMENT_ID and dept.DEPARTMENT_NAME= 'IT' )
 + WHEN MATCHED THEN
 +      UPDATE SET emp.PHONE_NUMBER = '0890000'||to_char(dept.DEPARTMENT_ID)
 +/
 +</code>
 +
 +
 +Alternativ mit SQL Abfrage in den Using Clause:
 +<code sql>
 +MERGE INTO EMPLOYEES emp
 +USING ( select * from departments where DEPARTMENT_NAME= 'IT') dept
 +   ON (dept.DEPARTMENT_ID  = emp.DEPARTMENT_ID  )
 + WHEN MATCHED THEN
 +      UPDATE SET emp.PHONE_NUMBER = '0890000'||to_char(dept.DEPARTMENT_ID)
 +/
 +</code>
 +
 +<fc #800000>**Einschränkung! => ORA-38104: Columns referenced in the ON Clause cannot be updated:**</fc> 
 +
 +----
 +
 +==== Quellen ====
 +
 +Update:
 + * https://docs.oracle.com/database/121/SQLRF/statements_10008.htm#SQLRF01708
 +
 +Merge:
 + * https://docs.oracle.com/database/121/SQLRF/statements_9016.htm#SQLRF01606
prog/sql_update_syntax.txt · Zuletzt geändert: 2016/10/06 17:40 von gpipperr