DML – Data Manipulation Language: INSERT, UPDATE, DELETE, MERGE

Fach: Informationstechnologie – Datenbanksysteme
Schulstufe: 11. Schulstufe – HTL Informatik
Voraussetzungen: DQL – SELECT, Joins, Subqueries, SCOTT-Schema
Autor: HTL Pinkafeld – IF/IT



1. Überblick DML und Transaktionen

1.1 Was ist DML?

DML (Data Manipulation Language) umfasst alle SQL-Anweisungen, die Daten in Tabellen verändern:

DML-Anweisungen:
├── INSERT  → neue Zeilen hinzufügen
├── UPDATE  → bestehende Zeilen ändern
├── DELETE  → Zeilen entfernen
└── MERGE   → einfügen ODER aktualisieren (Upsert)

Im Gegensatz zu DDL (CREATE, ALTER, DROP) arbeitet DML auf den Daten – nicht auf der Struktur.

1.2 DML und Transaktionen

Jede DML-Anweisung startet automatisch eine Transaktion (falls noch keine aktiv ist). Änderungen sind zunächst nur für die eigene Session sichtbar und werden erst durch COMMIT dauerhaft gespeichert oder durch ROLLBACK rückgängig gemacht:

DML-Anweisung
      │
      ▼
Änderung im Puffer (nur für eigene Session sichtbar)
      │
      ├── COMMIT   → dauerhaft gespeichert, für alle sichtbar
      └── ROLLBACK → alle Änderungen seit letztem COMMIT zurückgenommen

Wichtig in Oracle: DDL-Anweisungen (CREATE, ALTER, DROP) führen immer ein implizites COMMIT aus – alle offenen DML-Änderungen werden dabei dauerhaft gespeichert!


2. INSERT – Zeilen einfügen

2.1 INSERT mit Spaltenliste (empfohlen)

-- Vollständige Syntax mit Spaltenliste
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES         (8000, 'MUSTER', 'CLERK', 7782,
                TO_DATE('15.09.2024', 'DD.MM.YYYY'),
                1500, NULL, 10);

-- Nur bestimmte Spalten befüllen (restliche erhalten NULL oder DEFAULT)
INSERT INTO EMP (EMPNO, ENAME, JOB, SAL, DEPTNO)
VALUES         (8001, 'HUBER', 'ANALYST', 3200, 20);
-- MGR, HIREDATE, COMM erhalten NULL

2.2 INSERT ohne Spaltenliste

-- Ohne Spaltenliste: Reihenfolge muss exakt der Tabellendefinition entsprechen
-- Alle Spalten müssen angegeben werden!
INSERT INTO DEPT
VALUES (50, 'IT', 'WIEN');

Empfehlung: Immer die Spaltenliste angeben. Ohne Spaltenliste bricht die Anweisung, sobald jemand die Tabelle um eine Spalte erweitert.

2.3 Verschiedene Werttypen

-- Zahlen: direkt angeben
INSERT INTO EMP (EMPNO, SAL) VALUES (8002, 2500);

-- Zeichenketten: einfache Anführungszeichen
INSERT INTO EMP (EMPNO, ENAME) VALUES (8003, 'SCHULZ');

-- Datum: TO_DATE oder Datumsliteral
INSERT INTO EMP (EMPNO, HIREDATE)
VALUES (8004, TO_DATE('01.01.2025', 'DD.MM.YYYY'));

-- NULL explizit einfügen
INSERT INTO EMP (EMPNO, ENAME, COMM)
VALUES (8005, 'NOVAK', NULL);

-- SYSDATE für aktuelles Datum
INSERT INTO EMP (EMPNO, ENAME, HIREDATE)
VALUES (8006, 'WAGNER', SYSDATE);

2.4 INSERT mit DEFAULT

-- Wenn eine Spalte einen DEFAULT-Wert hat, kann DEFAULT verwendet werden
CREATE TABLE PROTOKOLL (
    ID        NUMBER         PRIMARY KEY,
    AKTION    VARCHAR2(100),
    ZEITSTEMPEL DATE          DEFAULT SYSDATE,
    BENUTZER  VARCHAR2(30)   DEFAULT USER
);

INSERT INTO PROTOKOLL (ID, AKTION)
VALUES (1, 'Login');
-- ZEITSTEMPEL und BENUTZER erhalten ihre DEFAULT-Werte

2.5 Mehrere Zeilen gleichzeitig (INSERT ALL)

-- INSERT ALL: mehrere Zeilen in einer Anweisung
INSERT ALL
    INTO DEPT VALUES (50, 'IT',        'WIEN')
    INTO DEPT VALUES (60, 'MARKETING', 'GRAZ')
    INTO DEPT VALUES (70, 'SUPPORT',   'LINZ')
SELECT * FROM DUAL;   -- Pflicht: SELECT-Klausel am Ende

3. INSERT mit Subquery

3.1 Daten aus einer anderen Tabelle kopieren

-- Backup-Tabelle anlegen
CREATE TABLE EMP_BACKUP AS SELECT * FROM EMP WHERE 1=2;
-- (leere Tabelle mit gleicher Struktur – 1=2 ist immer falsch)

-- Daten hineinkopieren
INSERT INTO EMP_BACKUP
SELECT * FROM EMP;

-- Nur bestimmte Mitarbeiter kopieren
INSERT INTO EMP_BACKUP (EMPNO, ENAME, JOB, SAL, DEPTNO)
SELECT EMPNO, ENAME, JOB, SAL, DEPTNO
FROM   EMP
WHERE  DEPTNO = 20;

3.2 INSERT mit berechneten Werten

-- Neue Tabelle für Jahresgehälter befüllen
CREATE TABLE JAHRESGEHALT (
    EMPNO       NUMBER(4),
    ENAME       VARCHAR2(10),
    JAHRESBETRAG NUMBER(10,2)
);

INSERT INTO JAHRESGEHALT (EMPNO, ENAME, JAHRESBETRAG)
SELECT EMPNO,
       ENAME,
       SAL * 12 + NVL(COMM, 0) * 12
FROM   EMP;

COMMIT;

3.3 INSERT ALL mit Bedingungen

-- Mitarbeiter je nach Gehalt in verschiedene Tabellen einfügen
INSERT ALL
    WHEN SAL < 1500 THEN
        INTO EMP_NIEDRIG VALUES (EMPNO, ENAME, SAL)
    WHEN SAL BETWEEN 1500 AND 3000 THEN
        INTO EMP_MITTEL VALUES (EMPNO, ENAME, SAL)
    WHEN SAL > 3000 THEN
        INTO EMP_HOCH VALUES (EMPNO, ENAME, SAL)
SELECT EMPNO, ENAME, SAL FROM EMP;

4. UPDATE – Zeilen aktualisieren

4.1 Grundlegende Syntax

UPDATE tabellenname
SET    spalte1 = wert1,
       spalte2 = wert2,
       ...
WHERE  bedingung;

⚠️ Warnung: Ein UPDATE ohne WHERE aktualisiert alle Zeilen der Tabelle!

4.2 Einfache UPDATE-Beispiele

-- Gehalt eines bestimmten Mitarbeiters erhöhen
UPDATE EMP
SET    SAL = 3500
WHERE  EMPNO = 7369;

-- Mehrere Spalten gleichzeitig ändern
UPDATE EMP
SET    SAL     = 2000,
       JOB     = 'ANALYST',
       DEPTNO  = 20
WHERE  EMPNO = 7900;

-- Relativ zum aktuellen Wert ändern (10% Gehaltserhöhung für Abt. 20)
UPDATE EMP
SET    SAL = SAL * 1.1
WHERE  DEPTNO = 20;

-- Alle Salesman bekommen Provision von 10% des Gehalts (wenn noch keine)
UPDATE EMP
SET    COMM = SAL * 0.1
WHERE  JOB = 'SALESMAN'
  AND  COMM IS NULL;

4.3 UPDATE mehrerer Spalten mit Ausdrücken

-- Datum und Beruf gleichzeitig aktualisieren
UPDATE EMP
SET    HIREDATE = SYSDATE,
       JOB      = 'MANAGER',
       MGR      = 7839
WHERE  ENAME = 'MUSTER';

-- Berechneter Wert: Gehalt auf nächste 100 aufrunden
UPDATE EMP
SET    SAL = CEIL(SAL / 100) * 100
WHERE  DEPTNO = 30;

4.4 UPDATE ohne WHERE – Alle Zeilen

-- Alle Mitarbeiter: Gehalt um Inflationsausgleich anpassen
UPDATE EMP
SET    SAL = ROUND(SAL * 1.03, 2);

-- Kontrolle vor COMMIT:
SELECT EMPNO, ENAME, SAL FROM EMP ORDER BY EMPNO;

COMMIT;

5. UPDATE mit Subquery

5.1 Wert aus anderer Tabelle übernehmen

-- Abteilung von SCOTT auf den Standort von DALLAS setzen
UPDATE EMP
SET    DEPTNO = (SELECT DEPTNO
                 FROM   DEPT
                 WHERE  LOC = 'DALLAS')
WHERE  ENAME = 'SCOTT';

-- Gehalt auf den Durchschnitt der eigenen Abteilung setzen
-- (korrelierte Subquery im SET!)
UPDATE EMP e
SET    SAL = (SELECT ROUND(AVG(SAL), 0)
              FROM   EMP i
              WHERE  i.DEPTNO = e.DEPTNO)
WHERE  JOB = 'CLERK';

5.2 Mehrere Spalten mit Subquery

-- Mehrere Spalten aus einer Subquery gleichzeitig setzen
UPDATE EMP
SET    (SAL, COMM) = (SELECT SAL * 1.1, COMM * 1.2
                      FROM   EMP
                      WHERE  ENAME = 'ALLEN')
WHERE  ENAME = 'WARD';

-- Alternativ mit einzelnen Subqueries
UPDATE EMP
SET    SAL  = (SELECT SAL  * 1.1 FROM EMP WHERE ENAME = 'ALLEN'),
       COMM = (SELECT COMM * 1.2 FROM EMP WHERE ENAME = 'ALLEN')
WHERE  ENAME = 'WARD';

5.3 UPDATE mit EXISTS

-- Nur Mitarbeiter aktualisieren, deren Abteilung in CHICAGO liegt
UPDATE EMP e
SET    SAL = SAL * 1.05
WHERE  EXISTS (SELECT 1
               FROM   DEPT d
               WHERE  d.DEPTNO = e.DEPTNO
                 AND  d.LOC = 'CHICAGO');

6. DELETE – Zeilen löschen

6.1 Grundlegende Syntax

DELETE FROM tabellenname
WHERE  bedingung;

⚠️ Warnung: Ein DELETE ohne WHERE löscht alle Zeilen der Tabelle! Die Struktur bleibt erhalten.

6.2 Einfache DELETE-Beispiele

-- Einen bestimmten Mitarbeiter löschen
DELETE FROM EMP
WHERE  EMPNO = 8000;

-- Alle Mitarbeiter einer Abteilung löschen
DELETE FROM EMP
WHERE  DEPTNO = 40;

-- Mitarbeiter löschen die vor 1982 eingestellt wurden
DELETE FROM EMP
WHERE  HIREDATE < TO_DATE('01.01.1982', 'DD.MM.YYYY');

-- Alle Mitarbeiter ohne Provision löschen (COMM ist NULL)
DELETE FROM EMP
WHERE  COMM IS NULL;

6.3 DELETE mit Subquery

-- Alle Mitarbeiter in Abteilungen löschen, die in NEW YORK sind
DELETE FROM EMP
WHERE  DEPTNO IN (SELECT DEPTNO
                  FROM   DEPT
                  WHERE  LOC = 'NEW YORK');

-- Mitarbeiter löschen, deren Gehalt unter dem Durchschnitt liegt
DELETE FROM EMP
WHERE  SAL < (SELECT AVG(SAL) FROM EMP);

-- Mit EXISTS: Mitarbeiter löschen die keiner Abteilung zugeordnet sind
DELETE FROM EMP e
WHERE  NOT EXISTS (SELECT 1
                   FROM   DEPT d
                   WHERE  d.DEPTNO = e.DEPTNO);

6.4 Reihenfolge beim Löschen mit Fremdschlüsseln

-- FEHLER: Kann Abteilung nicht löschen, solange Mitarbeiter darauf verweisen
DELETE FROM DEPT WHERE DEPTNO = 20;
-- ORA-02292: integrity constraint violated - child record found

-- RICHTIG: Zuerst Mitarbeiter löschen, dann Abteilung
DELETE FROM EMP  WHERE DEPTNO = 20;
DELETE FROM DEPT WHERE DEPTNO = 20;
COMMIT;

7. TRUNCATE – Tabelle leeren

7.1 TRUNCATE vs. DELETE

-- Alle Zeilen aus einer Tabelle entfernen
TRUNCATE TABLE EMP_BACKUP;
Eigenschaft DELETE (ohne WHERE) TRUNCATE
Löscht alle Zeilen
ROLLBACK möglich ❌ (DDL!)
Trigger werden ausgelöst
Geschwindigkeit Langsamer Sehr schnell
Speicher freigeben Nein Ja
WHERE möglich
Gehört zu DML DDL

7.2 Wann TRUNCATE verwenden?

-- Gute Anwendungsfälle für TRUNCATE:
-- 1. Staging-Tabellen vor dem Neuladen leeren
TRUNCATE TABLE STAGE_IMPORT;

-- 2. Testdaten vor Neubefüllung entfernen
TRUNCATE TABLE TEST_DATEN;

-- ACHTUNG: TRUNCATE kann nicht rückgängig gemacht werden!
-- Vorher prüfen: SELECT COUNT(*) FROM tabelle;

8. Transaktionskontrolle – COMMIT und ROLLBACK

8.1 COMMIT – Änderungen dauerhaft speichern

-- Ablauf einer typischen Transaktion:

-- 1. Änderungen vornehmen
INSERT INTO EMP (EMPNO, ENAME, JOB, SAL, DEPTNO)
VALUES         (8010, 'BAUER', 'CLERK', 1400, 30);

UPDATE EMP SET SAL = 5500 WHERE EMPNO = 7839;

-- 2. Ergebnis prüfen
SELECT EMPNO, ENAME, SAL FROM EMP WHERE EMPNO IN (8010, 7839);

-- 3. Dauerhaft speichern
COMMIT;
-- Jetzt für alle anderen Benutzer sichtbar und nicht mehr rückgängig machbar

8.2 ROLLBACK – Änderungen rückgängig machen

-- Änderungen vornehmen
DELETE FROM EMP WHERE DEPTNO = 20;

-- Ups! Falscher Befehl
-- Kontrolle:
SELECT COUNT(*) FROM EMP;   -- 9 statt 14

-- Rückgängig machen (solange kein COMMIT!)
ROLLBACK;

-- Kontrolle:
SELECT COUNT(*) FROM EMP;   -- wieder 14

8.3 Automatisches COMMIT und ROLLBACK

-- Implizites COMMIT tritt auf bei:
-- 1. DDL-Anweisung (CREATE, ALTER, DROP, TRUNCATE)
-- 2. Normales Beenden der Session (EXIT in SQL*Plus)

-- Implizites ROLLBACK tritt auf bei:
-- 1. Absturz / Verbindungsabbruch
-- 2. Session-Beendigung ohne COMMIT (in manchen Tools)

8.4 Lesesicherheit (Read Consistency)

-- Oracle Multiversion Concurrency Control (MVCC):
-- Andere Benutzer sehen IMMER den letzten COMMIT-Stand
-- Deine eigene Session sieht deine uncommitteten Änderungen

-- Session A:                    Session B:
UPDATE EMP SET SAL=999            SELECT SAL FROM EMP
WHERE EMPNO=7839;                 WHERE EMPNO=7839;
                                  -- Sieht noch 5000 (vor Update)
COMMIT;
                                  SELECT SAL FROM EMP
                                  WHERE EMPNO=7839;
                                  -- Sieht jetzt 999

9. SAVEPOINT – Teilrücknahme

9.1 Savepoints setzen

Mit SAVEPOINT können Zwischenpunkte innerhalb einer Transaktion gesetzt werden. Ein ROLLBACK TO savepoint macht nur die Änderungen seit dem Savepoint rückgängig:

-- Transaktion mit mehreren Schritten

-- Schritt 1: Neue Abteilung
INSERT INTO DEPT VALUES (50, 'ENTWICKLUNG', 'WIEN');
SAVEPOINT nach_dept;

-- Schritt 2: Mitarbeiter einfügen
INSERT INTO EMP (EMPNO, ENAME, JOB, SAL, DEPTNO)
VALUES (8020, 'KLEIN', 'ANALYST', 3000, 50);
SAVEPOINT nach_emp1;

INSERT INTO EMP (EMPNO, ENAME, JOB, SAL, DEPTNO)
VALUES (8021, 'GROSS', 'CLERK', 1200, 50);
SAVEPOINT nach_emp2;

-- Kontrollabfrage
SELECT * FROM EMP WHERE DEPTNO = 50;

-- Nur letzten INSERT rückgängig
ROLLBACK TO nach_emp1;
-- emp2 (GROSS) wurde gelöscht, emp1 (KLEIN) und DEPT 50 bleiben

-- Prüfen
SELECT * FROM EMP WHERE DEPTNO = 50;   -- nur KLEIN

-- Alles bestätigen
COMMIT;

9.2 Savepoint-Hierarchie

COMMIT / Start
    │
    ├── DML 1
    ├── SAVEPOINT A
    ├── DML 2
    ├── SAVEPOINT B
    ├── DML 3
    └── SAVEPOINT C

ROLLBACK TO B  → DML 3 und SAVEPOINT C werden rückgängig
ROLLBACK TO A  → DML 2, DML 3, SAVEPOINT B und C rückgängig
ROLLBACK       → Alles seit letztem COMMIT rückgängig
COMMIT         → Alles dauerhaft speichern (Savepoints gelöscht)

10. MERGE – Upsert

10.1 Was ist MERGE?

MERGE kombiniert INSERT und UPDATE in einer einzigen Anweisung: Wenn eine Zeile in der Zieltabelle existiert, wird sie aktualisiert – wenn nicht, wird sie eingefügt. Dieses Muster nennt man auch Upsert (Update + Insert).

10.2 Grundsyntax

MERGE INTO zieltabelle z
USING quelltabelle   q ON (z.schluessel = q.schluessel)
WHEN MATCHED THEN
    UPDATE SET z.spalte1 = q.spalte1,
               z.spalte2 = q.spalte2
WHEN NOT MATCHED THEN
    INSERT (spalte1, spalte2, ...)
    VALUES (q.spalte1, q.spalte2, ...);

10.3 Praktisches Beispiel

-- Staging-Tabelle mit neuen/aktualisierten Mitarbeiterdaten
CREATE TABLE EMP_UPDATES (
    EMPNO   NUMBER(4),
    ENAME   VARCHAR2(10),
    SAL     NUMBER(7,2),
    DEPTNO  NUMBER(2)
);

-- Neue Daten simulieren:
-- 7369 = bestehend (SAL geändert), 9001 = neu
INSERT INTO EMP_UPDATES VALUES (7369, 'SMITH',  999, 20);
INSERT INTO EMP_UPDATES VALUES (9001, 'NEUMANN', 2500, 30);

-- MERGE: aktualisieren oder einfügen
MERGE INTO EMP z
USING EMP_UPDATES q ON (z.EMPNO = q.EMPNO)
WHEN MATCHED THEN
    UPDATE SET z.SAL    = q.SAL,
               z.DEPTNO = q.DEPTNO
WHEN NOT MATCHED THEN
    INSERT (EMPNO, ENAME, SAL, DEPTNO)
    VALUES (q.EMPNO, q.ENAME, q.SAL, q.DEPTNO);

-- Ergebnis prüfen:
SELECT * FROM EMP WHERE EMPNO IN (7369, 9001);
-- 7369/SMITH hat jetzt SAL=999
-- 9001/NEUMANN wurde neu eingefügt

COMMIT;

10.4 MERGE mit DELETE

-- MERGE kann auch Zeilen löschen (Oracle-Erweiterung)
MERGE INTO EMP z
USING EMP_UPDATES q ON (z.EMPNO = q.EMPNO)
WHEN MATCHED THEN
    UPDATE SET z.SAL = q.SAL
    DELETE WHERE z.SAL < 1000   -- Zeile nach Update löschen wenn SAL < 1000
WHEN NOT MATCHED THEN
    INSERT (EMPNO, ENAME, SAL, DEPTNO)
    VALUES (q.EMPNO, q.ENAME, q.SAL, q.DEPTNO);

11. Constraints und DML-Fehler

11.1 Häufige Constraint-Fehler

-- ORA-00001: UNIQUE / PRIMARY KEY verletzt
INSERT INTO DEPT VALUES (10, 'TEST', 'WIEN');
-- DEPTNO 10 existiert bereits!

-- ORA-02291: Fremdschlüssel – Parent-Key nicht gefunden
INSERT INTO EMP (EMPNO, ENAME, DEPTNO) VALUES (9999, 'TEST', 99);
-- Abteilung 99 existiert nicht!

-- ORA-02292: Fremdschlüssel – Child-Record vorhanden
DELETE FROM DEPT WHERE DEPTNO = 20;
-- Noch Mitarbeiter in Abt. 20!

-- ORA-01400: NOT NULL verletzt
INSERT INTO EMP (EMPNO, ENAME) VALUES (NULL, 'TEST');
-- EMPNO ist NOT NULL!

-- ORA-02290: CHECK Constraint verletzt
-- (wenn z.B. CHECK (SAL > 0) definiert)
UPDATE EMP SET SAL = -100 WHERE EMPNO = 7369;

11.2 Fehler abfangen und analysieren

-- Fehlernummer und Fehlermeldung in SQL*Plus anzeigen
-- Wird automatisch nach einem Fehler ausgegeben

-- Wichtige ORA-Fehlercodes für DML:
-- ORA-00001  Unique constraint violated
-- ORA-01400  Cannot insert NULL
-- ORA-02290  Check constraint violated
-- ORA-02291  Parent key not found (FK-Insert)
-- ORA-02292  Child record found (FK-Delete)
-- ORA-01427  Single-row subquery returns more than one row
-- ORA-01722  Invalid number (falsche Typkonvertierung)
-- ORA-01843  Not a valid month (Datumsformat falsch)

11.3 DML-Sicherheitsnetz: Vor COMMIT prüfen

-- Gute Praxis: Vor jedem COMMIT die Änderungen prüfen

-- 1. Änderungen vornehmen
UPDATE EMP SET SAL = SAL * 1.15 WHERE DEPTNO = 30;

-- 2. Anzahl betroffener Zeilen prüfen (SQL%ROWCOUNT in PL/SQL)
-- In SQL Developer: Statuszeile zeigt "6 rows updated"

-- 3. Daten prüfen
SELECT EMPNO, ENAME, SAL FROM EMP WHERE DEPTNO = 30;

-- 4. Erst dann committen oder zurücknehmen
COMMIT;    -- oder ROLLBACK;

12. Zusammenfassung und Ausblick

Überblick DML-Anweisungen

-- INSERT: neue Zeile einfügen
INSERT INTO tabelle (col1, col2) VALUES (val1, val2);
INSERT INTO tabelle (col1, col2) SELECT col1, col2 FROM quelle;

-- UPDATE: bestehende Zeilen ändern
UPDATE tabelle SET col1 = val1, col2 = val2 WHERE bedingung;
UPDATE tabelle SET col1 = (SELECT ... FROM ...) WHERE bedingung;

-- DELETE: Zeilen entfernen
DELETE FROM tabelle WHERE bedingung;
DELETE FROM tabelle WHERE col IN (SELECT ... FROM ...);

-- TRUNCATE: alle Zeilen entfernen (DDL, kein ROLLBACK!)
TRUNCATE TABLE tabelle;

-- MERGE: einfügen oder aktualisieren
MERGE INTO ziel z
USING quelle q ON (z.id = q.id)
WHEN MATCHED     THEN UPDATE SET z.col = q.col
WHEN NOT MATCHED THEN INSERT (id, col) VALUES (q.id, q.col);

-- Transaktionskontrolle
COMMIT;                   -- dauerhaft speichern
ROLLBACK;                 -- alles seit letztem COMMIT rückgängig
SAVEPOINT name;           -- Zwischenpunkt setzen
ROLLBACK TO name;         -- bis zum Savepoint zurück

Goldene Regeln für DML

Immer WHERE bei UPDATE und DELETE prüfen
  → SELECT mit gleicher WHERE-Bedingung vorher ausführen!

Vor COMMIT Ergebnis kontrollieren
  → Anzahl betroffener Zeilen und Inhalt prüfen

ROLLBACK ist nur vor dem nächsten COMMIT möglich
  → Kein ROLLBACK nach DDL-Anweisung!

Reihenfolge bei FK-Abhängigkeiten beachten
  → Erst Kind-Tabellen, dann Eltern-Tabellen löschen

TRUNCATE ist unwiderruflich
  → Immer COUNT(*) davor, Backup vorher prüfen

Bei NOT IN mit Subquery NULL ausschließen
  → WHERE spalte NOT IN (SELECT ... WHERE ... IS NOT NULL)

Checkliste

INSERT mit und ohne Spaltenliste
INSERT mit Subquery (Daten kopieren)
UPDATE mit WHERE und Subquery
DELETE mit WHERE und Fremdschlüssel-Reihenfolge
TRUNCATE vs. DELETE kennen
COMMIT und ROLLBACK anwenden
SAVEPOINT setzen und ROLLBACK TO verwenden
MERGE: Syntax und Anwendungsfall erklären
Constraint-Fehlermeldungen lesen und beheben
DML-Sicherheitsnetz: prüfen vor COMMIT

Typische Prüfungsaufgaben

-- 1. Neue Abteilung und Mitarbeiter einfügen
INSERT INTO DEPT VALUES (50, 'ENTWICKLUNG', 'WIEN');
INSERT INTO EMP (EMPNO, ENAME, JOB, SAL, DEPTNO, HIREDATE)
VALUES (9000, 'TESTER', 'ANALYST', 3500, 50, SYSDATE);
COMMIT;

-- 2. Alle Clerks in Abt. 20 bekommen 15% mehr Gehalt
UPDATE EMP SET SAL = ROUND(SAL * 1.15, 0)
WHERE  JOB = 'CLERK' AND DEPTNO = 20;
SELECT ENAME, SAL FROM EMP WHERE JOB = 'CLERK' AND DEPTNO = 20;
COMMIT;

-- 3. Alle Mitarbeiter löschen deren Gehalt unter dem Durchschnitt liegt
DELETE FROM EMP
WHERE SAL < (SELECT AVG(SAL) FROM EMP);
ROLLBACK;   -- Rückgängig für weitere Übungen

-- 4. Gehalt auf Abteilungsdurchschnitt setzen (korrelierte Subquery)
UPDATE EMP e
SET    SAL = (SELECT ROUND(AVG(SAL), 0) FROM EMP i WHERE i.DEPTNO = e.DEPTNO)
WHERE  JOB = 'CLERK';
SELECT ENAME, SAL, DEPTNO FROM EMP WHERE JOB = 'CLERK';
ROLLBACK;

-- 5. MERGE: Gehaltstabelle mit aktuellen Werten synchronisieren
MERGE INTO JAHRESGEHALT j
USING (SELECT EMPNO, ENAME, SAL*12 + NVL(COMM,0)*12 AS jahresbetrag
       FROM EMP) q
ON (j.EMPNO = q.EMPNO)
WHEN MATCHED THEN
    UPDATE SET j.JAHRESBETRAG = q.jahresbetrag
WHEN NOT MATCHED THEN
    INSERT (EMPNO, ENAME, JAHRESBETRAG)
    VALUES (q.EMPNO, q.ENAME, q.jahresbetrag);
COMMIT;

Ausblick: Nächste Themen


HTL Pinkafeld – IF/IT | Oracle SQL | 11. Schulstufe

Vorheriges ThemaSubqueries Nächstes ThemaDDL & Data Dictionary