Stored Procedures und Functions sind nicht nur bequeme Container für eine Gruppe von Queries. Sie erlauben dir auch, recht komplexe Logik mit Verzweigungen und Schleifen umzusetzen.
In diesem Artikel schauen wir uns die wichtigsten Kontrollstrukturen an: die Verzweigungen IF und CASE sowie die WHILE-Schleife.
Die IF-Anweisung
IF führt Code abhängig davon aus, ob eine Bedingung erfüllt ist.
Syntax von IF
IF bedingung THEN
anweisungen
[ELSEIF bedingung THEN
anweisungen] ...
[ELSE
anweisungen]
END IF;- [ ]optionaler Teil
- ...kann wiederholt werden
- bedingung
Ein logischer Ausdruck, zum Beispiel student_age < 18. Es greift der erste Zweig, dessen Bedingung wahr ist, die übrigen werden übersprungen.
- anweisungen
Eine oder mehrere SQL-Anweisungen, jede endet mit ;. Sie laufen, wenn dieser Zweig gewählt wird.
- ELSEIF
Ein weiterer Zweig mit eigener Bedingung. Er wird nur geprüft, wenn alle Bedingungen darüber falsch sind. Du kannst mehrere solcher Zweige anlegen.
SchlüsselwortOptional- ELSE
Der Zweig, der läuft, wenn keine der Bedingungen wahr war.
SchlüsselwortOptional
IF bedingung THEN
anweisungen
[ELSIF bedingung THEN
anweisungen] ...
[ELSE
anweisungen]
END IF;- [ ]optionaler Teil
- ...kann wiederholt werden
- bedingung
Ein logischer Ausdruck, zum Beispiel student_age < 18. Es greift der erste Zweig, dessen Bedingung wahr ist, die übrigen werden übersprungen.
- anweisungen
Eine oder mehrere SQL-Anweisungen, jede endet mit ;. Sie laufen, wenn dieser Zweig gewählt wird.
- ELSIF
Ein weiterer Zweig mit eigener Bedingung. Er wird nur geprüft, wenn alle Bedingungen darüber falsch sind. Du kannst mehrere solcher Zweige anlegen.
SchlüsselwortOptional- ELSE
Der Zweig, der läuft, wenn keine der Bedingungen wahr war.
SchlüsselwortOptional
Beispiel für IF
Wir bauen eine Procedure, die einen Studenten anhand seines Alters in eine Kategorie einordnet:
MySQL 8.4CREATE PROCEDURE categorize_student_by_age( IN student_id INT, OUT category VARCHAR(20) ) BEGIN DECLARE student_age INT; -- Alter des Studenten ermitteln SELECT TIMESTAMPDIFF(YEAR, birthday, CURDATE()) INTO student_age FROM Student WHERE id = student_id; -- Kategorie anhand des Alters bestimmen IF student_age < 18 THEN SET category = 'Minderjährig'; ELSEIF student_age BETWEEN 18 AND 25 THEN SET category = 'Jung'; ELSE SET category = 'Erwachsen'; END IF; END; -- Aufruf der Procedure CALL categorize_student_by_age(1, @category); SELECT @category AS age_category;
Wir bauen eine Function, die einen Studenten anhand seines Alters in eine Kategorie einordnet:
MySQL 8.4CREATE OR REPLACE FUNCTION categorize_student_by_age(student_id INT) RETURNS VARCHAR(20) LANGUAGE plpgsql AS $$ DECLARE student_age INT; category VARCHAR(20); BEGIN -- Alter des Studenten ermitteln SELECT EXTRACT(YEAR FROM AGE(CURRENT_DATE, birthday)) INTO student_age FROM Student WHERE id = student_id; -- Kategorie anhand des Alters bestimmen IF student_age < 18 THEN category := 'Minderjährig'; ELSIF student_age BETWEEN 18 AND 25 THEN category := 'Jung'; ELSE category := 'Erwachsen'; END IF; RETURN category; END; $$; -- Aufruf der Function SELECT categorize_student_by_age(1) AS age_category;
Die CASE-Anweisung
CASE bietet eine elegantere Möglichkeit, mehrere Bedingungen zu verarbeiten.
Syntax von CASE
CASE
WHEN bedingung THEN ergebnis
[WHEN ...]
[ELSE standard_ergebnis]
END- [ ]optionaler Teil
- ...kann wiederholt werden
- bedingung
Ein logischer Ausdruck, der in seinem WHEN-Zweig geprüft wird. Es kann mehrere Zweige geben: Es greift der erste, dessen Bedingung wahr ist.
- ergebnis
Der Wert, den CASE annimmt, wenn die Bedingung dieses Zweigs wahr ist.
- standard_ergebnis
Der Wert für den Fall, dass keine Bedingung zutrifft. Ohne ELSE kommt NULL zurück.
Optional
CASE
WHEN bedingung THEN ergebnis
[WHEN ...]
[ELSE standard_ergebnis]
END- [ ]optionaler Teil
- ...kann wiederholt werden
- bedingung
Ein logischer Ausdruck, der in seinem WHEN-Zweig geprüft wird. Es kann mehrere Zweige geben: Es greift der erste, dessen Bedingung wahr ist.
- ergebnis
Der Wert, den CASE annimmt, wenn die Bedingung dieses Zweigs wahr ist.
- standard_ergebnis
Der Wert für den Fall, dass keine Bedingung zutrifft. Ohne ELSE kommt NULL zurück.
Optional
Beispiel für CASE
Wir bauen dieselbe Kategorisierungs-Procedure, diesmal mit CASE:
MySQL 8.4CREATE PROCEDURE categorize_student_with_case( IN student_id INT, OUT category VARCHAR(20) ) BEGIN DECLARE student_age INT; -- Alter des Studenten ermitteln SELECT TIMESTAMPDIFF(YEAR, birthday, CURDATE()) INTO student_age FROM Student WHERE id = student_id; -- Kategorie mit CASE bestimmen SET category = CASE WHEN student_age < 18 THEN 'Minderjährig' WHEN student_age BETWEEN 18 AND 25 THEN 'Jung' ELSE 'Erwachsen' END; END; -- Aufruf der Procedure CALL categorize_student_with_case(1, @category); SELECT @category AS age_category;
Wir bauen dieselbe Kategorisierungs-Function, diesmal mit CASE:
MySQL 8.4CREATE OR REPLACE FUNCTION categorize_student_with_case(student_id INT) RETURNS VARCHAR(20) LANGUAGE plpgsql AS $$ DECLARE student_age INT; category VARCHAR(20); BEGIN -- Alter des Studenten ermitteln SELECT EXTRACT(YEAR FROM AGE(CURRENT_DATE, birthday)) INTO student_age FROM Student WHERE id = student_id; -- Kategorie mit CASE bestimmen category := CASE WHEN student_age < 18 THEN 'Minderjährig' WHEN student_age BETWEEN 18 AND 25 THEN 'Jung' ELSE 'Erwachsen' END; RETURN category; END; $$; -- Aufruf der Function SELECT categorize_student_with_case(1) AS age_category;
Die WHILE-Schleife
Mit WHILE kannst du Code wiederholt ausführen, solange eine Bedingung erfüllt ist.
Syntax von WHILE
WHILE bedingung DO
anweisungen
END WHILE;- bedingung
Ein logischer Ausdruck, der vor jedem Schleifendurchlauf geprüft wird. Solange er wahr ist, werden die Anweisungen wiederholt.
- anweisungen
Die SQL-Anweisungen im Schleifenkörper. Eine davon sollte die Bedingung irgendwann falsch machen, sonst endet die Schleife nie.
WHILE bedingung LOOP
anweisungen
END LOOP;- bedingung
Ein logischer Ausdruck, der vor jedem Schleifendurchlauf geprüft wird. Solange er wahr ist, werden die Anweisungen wiederholt.
- anweisungen
Die SQL-Anweisungen im Schleifenkörper. Eine davon sollte die Bedingung irgendwann falsch machen, sonst endet die Schleife nie.
Beispiel für WHILE
Hier ein Beispiel für eine Stored Procedure, die mehrere Testfächer anlegt:
MySQL 8.4CREATE PROCEDURE create_test_subjects(IN count_subjects INT) BEGIN DECLARE i INT DEFAULT 1; DECLARE subject_id INT DEFAULT 20; WHILE i <= count_subjects DO INSERT INTO Subject (id, name) VALUES ( subject_id + i, CONCAT('Test Subject ', i) ); SET i = i + 1; END WHILE; END; -- 3 Testfächer anlegen CALL create_test_subjects(3); -- Ergebnis prüfen SELECT * FROM Subject WHERE name LIKE 'Test Subject%';
MySQL 8.4CREATE OR REPLACE PROCEDURE create_test_subjects(count_subjects INT) LANGUAGE plpgsql AS $$ DECLARE i INT := 1; subject_id INT := 20; BEGIN WHILE i <= count_subjects LOOP INSERT INTO Subject (id, name) VALUES ( subject_id + i, 'Test Subject ' || i ); i := i + 1; END LOOP; RAISE NOTICE '% Testfächer wurden erstellt', count_subjects; END; $$; -- 3 Testfächer anlegen CALL create_test_subjects(3); -- Ergebnis prüfen SELECT * FROM Subject WHERE name LIKE 'Test Subject%';
Mit Kontrollstrukturen werden Stored Procedures und Functions zu einem mächtigen Werkzeug, um komplexe Geschäftslogik direkt in der Datenbank umzusetzen! 🚀