===== 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: 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) / Alternativ traditionell: 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') / Es lassen sich auch mehrere Spalten auf einmal updaten: 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') / Wenn das zu langsam wird hift dann nur noch PL/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; / ---- ==== Merge Lösung ==== An einfachsten und am besten lesbar ist die Verwendung des Merge Befehles: 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) / Alternativ mit SQL Abfrage in den Using Clause: 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) / **Einschränkung! => ORA-38104: Columns referenced in the ON Clause cannot be updated:** ---- ==== 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