CodeGym /Kurse /SQL SELF /Operatoren RAISE NOTICE, RETURN QUERY

Operatoren RAISE NOTICE, RETURN QUERY

SQL SELF
Level 50 , Lektion 3
Verfügbar

Beim Programmieren sind zwei Dinge wichtig: zu verstehen, was abgeht (vor allem, wenn alles schief läuft), und nützliche Daten zurückzugeben. Das gilt besonders für PL/pgSQL, weil alles auf dem Server läuft und Debugging nicht immer easy ist. Zum Glück gibt’s eingebaute Tools:

RAISE NOTICE – das ist der Weg, Nachrichten während der Ausführung einer Funktion auszugeben. Stell’s dir wie console.log in JavaScript oder print in Python vor. Du kannst Variablenwerte zeigen, den aktuellen Status ausgeben oder einfach ein "Hallo" an dein zukünftiges Ich dalassen.

RETURN QUERY – damit gibst du einen Datensatz zurück, zum Beispiel eine ganze Tabelle oder das Ergebnis eines komplexen Queries. So werden PL/pgSQL-Funktionen fast wie echte SQL-Queries.

Befehl RAISE NOTICE

RAISE NOTICE lässt dich Nachrichten während der Funktionsausführung auf dem Bildschirm anzeigen. Das Format sieht so aus:

RAISE NOTICE 'Nachricht: %', wert;
  • % ist ein Platzhalter für eine Variable, ähnlich wie printf in C.
  • Nach dem Nachrichtentext kannst du Variablen angeben, die eingesetzt werden sollen.

Beispiel für die Nutzung

Stell dir vor, du schreibst eine Funktion, die die Anzahl der Studenten in verschiedenen Gruppen zählt. Du willst Zwischenwerte sehen, um zu checken, ob alles läuft.

CREATE OR REPLACE FUNCTION count_students_in_groups() RETURNS VOID AS $$
DECLARE
    group_name TEXT;
    student_count INT;
BEGIN
    FOR group_name IN SELECT DISTINCT group_name FROM students LOOP
        SELECT COUNT(*) INTO student_count
        FROM students WHERE group_name = group_name;

        -- Ergebnisse ausgeben
        RAISE NOTICE 'Gruppe: %, Anzahl der Studenten: %', group_name, student_count;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

Wenn du diese Funktion aufrufst:

SELECT count_students_in_groups();

Siehst du solche Nachrichten in den Logs:

NOTICE:  Gruppe: Mathematik, Anzahl der Studenten: 30
NOTICE:  Gruppe: Philosophie, Anzahl der Studenten: 25
NOTICE:  Gruppe: Biologie, Anzahl der Studenten: 18

Beachte, dass die Funktion nichts zurückgibt (sie ist mit RETURNS VOID erstellt), aber RAISE NOTICE zeigt dir, wie die Schleife läuft.

Nützliche Tricks mit RAISE

Neben NOTICE kannst du auch andere Nachrichtenlevel nutzen:

  • RAISE DEBUG – für extra Infos (wird nur angezeigt, wenn das Log-Level auf DEBUG steht).
  • RAISE INFO – für allgemeine Infos.
  • RAISE WARNING – für Warnungen.
  • RAISE EXCEPTION – um Fehler zu erzeugen, das schauen wir uns später noch an.

Zum Debuggen sind NOTICE oder DEBUG am besten, weil sie praktisch sind und die Funktion nicht stoppen.

Befehl RETURN QUERY: Daten zurückgeben wie ein Profi

RETURN QUERY wird in PL/pgSQL genutzt, um einen Satz von Zeilen zurückzugeben. Damit kannst du das Ergebnis eines SQL-Queries direkt aus der Funktion zurückgeben. Die Syntax ist so:

RETURN QUERY <SQL-Query>;

Du kannst auch mehrere Queries kombinieren:

RETURN QUERY <SQL-Query 1>;
RETURN QUERY <SQL-Query 2>;

Beispiel 1: Funktion mit RETURN QUERY

Wir schreiben eine Funktion, die eine Liste von Studenten aus einer bestimmten Gruppe zurückgibt.

CREATE OR REPLACE FUNCTION get_students_by_group(group_name TEXT)
RETURNS TABLE(id INT, name TEXT) AS $$
BEGIN
    RETURN QUERY
    SELECT id, name 
    FROM students
    WHERE group_name = group_name;
END;
$$ LANGUAGE plpgsql;

Jetzt rufen wir die Funktion auf:

SELECT * FROM get_students_by_group('Mathematik');

Um die Funktion zu testen, erstellen wir zuerst die Tabelle students und fügen Daten ein:

CREATE TABLE students (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
group_name TEXT NOT NULL
);

INSERT INTO students (name, group_name) VALUES
('Otto Song',     'Physik'),
('Alex Lin',      'Mathematik'),
('Anna Vel',      'Mathematik'),
('Maria Chi',     'Geschichte');

Ergebnis:

id name
2 Alex Lin
3 Anna Vel

Wie du siehst, funktioniert die Funktion wie ein normaler SQL-Query.

Beispiel 2: Mehrere Queries kombinieren

Was, wenn wir kombinierte Daten aus mehreren Tabellen zurückgeben wollen? Lass uns eine Liste von Studenten und Kursen zurückgeben, für die sie eingeschrieben sind.

CREATE OR REPLACE FUNCTION get_students_and_courses()
RETURNS TABLE(student_name TEXT, course_name TEXT) AS $$
BEGIN
    RETURN QUERY
    SELECT s.name, c.name
    FROM students s
    JOIN enrollments e ON s.id = e.student_id
    JOIN courses c ON e.course_id = c.id;
END;
$$ LANGUAGE plpgsql;

Erstmal erstellen wir drei Tabellen: students, courses und enrollments, und fügen ein paar Daten ein:

-- Tabelle Studenten
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL
);

-- Tabelle Kurse
CREATE TABLE courses (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL
);

-- Tabelle Einschreibungen (Verknüpfungstabelle)
CREATE TABLE enrollments (
student_id INT REFERENCES students(id),
course_id INT REFERENCES courses(id)
);

-- Studenten hinzufügen
INSERT INTO students (name) VALUES
('Otto Song'),
('Alex Lin'),
('Anna Vel'),
('Maria Chi');

-- Kurse hinzufügen
INSERT INTO courses (name) VALUES
('Mathematik'),
('Physik'),
('Geschichte');

-- Einschreibungen hinzufügen
INSERT INTO enrollments (student_id, course_id) VALUES
(1, 2), -- Otto -> Physik
(2, 1), -- Alex -> Mathematik
(3, 1), -- Anna -> Mathematik
(4, 3); -- Maria -> Geschichte

In diesem Fall gibt der Funktionsaufruf:

SELECT * FROM get_students_and_courses();

folgendes Ergebnis zurück:

student_name course_name
Otto Song Physik
Alex Lin Mathematik
Anna Vel Mathematik
Maria Chi Geschichte

Die Funktion kombiniert sauber die Daten aus drei Tabellen und zeigt, welcher Student in welchem Kurs eingeschrieben ist.

Kombinieren von RAISE NOTICE und RETURN QUERY

Manchmal willst du RETURN QUERY und RAISE NOTICE in einer Funktion nutzen, damit du die Ausführung kontrollieren und Zwischenstände sehen kannst.

Hier ein Beispiel für eine Funktion, die Studentendaten zurückgibt und gleichzeitig Nachrichten ausgibt, um den Ablauf zu zeigen:

CREATE OR REPLACE FUNCTION debug_students()
RETURNS TABLE(student_id INT, student_name TEXT) AS $$
DECLARE
    count_students INT;
BEGIN
    -- Anzahl der Studenten zählen
    SELECT COUNT(*) INTO count_students FROM students;
    RAISE NOTICE 'Insgesamt Studenten: %', count_students;

    -- Studentendaten zurückgeben
    RETURN QUERY
    SELECT id, name FROM students;

    RAISE NOTICE 'Funktion wurde beendet.';
END;
$$ LANGUAGE plpgsql;

Falls die Tabelle students noch nicht existiert, erstelle sie und füge Daten ein:

CREATE TABLE students (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL
);

INSERT INTO students (name) VALUES
('Otto Song'),
('Alex Lin'),
('Anna Vel'),
('Maria Chi');

Jetzt, wenn du die Funktion aufrufst:

SELECT * FROM debug_students();

bekommst du sowohl Daten als auch Nachrichten:

student_id student_name
1 Otto Song
2 Alex Lin
3 Anna Vel
4 Maria Chi

Nachrichtenausgabe in der Konsole:

NOTICE:  Insgesamt Studenten: 4
NOTICE:  Funktion wurde beendet.

Typische Fehler bei der Nutzung

Fehler mit Variablen in RAISE NOTICE: Wenn du vergisst, eine Variable zu deklarieren oder dich im Namen vertippst, bekommst du den Fehler variable does not exist. Check immer, dass die Variablen korrekt deklariert sind.

Fehler beim Rückgabetyp: Wenn du RETURN QUERY nutzt, aber beim Erstellen der Funktion kein RETURNS TABLE angibst, gibt PostgreSQL einen Fehler aus. Achte darauf, dass die Rückgabetypen zu den zurückgegebenen Daten passen.

Fehler mit Platzhaltern in RAISE: Wenn die Anzahl der Platzhalter % nicht zu den Variablen passt, gibt’s einen Fehler. Zum Beispiel:

RAISE NOTICE 'Wert: %, %', value1;

Das führt zu einem Fehler, weil die zweite Variable fehlt.

Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION