
Zitat von
akretschmer
Das Problem ist, daß das nicht performen wird.
Andreas
Hallo,
leider verstehe ich nicht was das genau heißen soll aber trotzdem danke dür die Idee mit den floating-points. Mal ganz davon abgesehen ist es mir eben doch gelungen das Problem zu lösen.
Ich habe jetzt einen zeilenbasierten Trigger (FOR EACH ROW), der nach einem UPDATE ausgeführt wird. Nehmen wir an wir haben wieder folgenden Zustand:
Code:
ID: Titel: Ranking:
1 Ein Buch 0
2 Zwei Bücher 1
3 Drei Bücher 2
Das Buch mit dem Titel "Drei Bücher" soll jetzt das Ranking '0' erhalten. Also führe ich ein Update auf der Tabelle 'Buch' aus:
Code:
UPDATE t_buch
SET ranking=0
where ID=3;
Das führt direkt vor der Ausführung meines Triggers zu folgender Tabelle:
Code:
ID: Titel: Ranking:
1 Ein Buch 0
2 Zwei Bücher 1
3 Drei Bücher 0 <--
Der AFTER Trigger muss jetzt alle Zeilen finden, die ebenfalls das Ranking '0' haben, aber nicht die ID=3 haben. Für einen solchen Datensatz ist das Ranking um '1' zu erhöhen.
Es kommt also zu folgender Tabelle:
Code:
ID: Titel: Ranking:
1 Ein Buch 1 <--
2 Zwei Bücher 1
3 Drei Bücher 0
Durch das Update-Kommando des Triggers wird ja genau dieser Trigger - jetzt nur mit anderen Parametern - erneut ausgelöst. Im nächsten Schritt werden alle Zeilen gesucht, die ebenfalls das Ranking 1 haben jedoch nicht die ID '1'.
Es kommt also zu folgender Tabelle:
Code:
ID: Titel: Ranking:
1 Ein Buch 1
2 Zwei Bücher 2 <--
3 Drei Bücher 0
Durch das Update wird der Trigger wieder ausgelöst. Er sucht nach Zeilen, die ein Ranking von 2 aber eine ID != '2' haben. Da es eine solche Zeile nicht gibt, ist der Vorgang hiermit beendet und der Trigger wird - zumindest durch diesen Statement - nicht erneut gefeuert.
Wen es interessiert hier noch der getestete Quellcode für den UPDATE-Zweig:
Code:
DECLARE
counter INTEGER;
BEGIN
IF (TG_OP = 'DELETE') THEN
...
return OLD;
ELSIF (tg_op = 'INSERT') THEN
...
RETURN NEW;
ELSIF (tg_op = 'UPDATE') THEN
SELECT count(id) into counter from t_buch
WHERE ranking = NEW.ranking
AND id <> NEW.id;
IF ( counter = 1 ) THEN
UPDATE t_buch
SET ranking = ranking+1
WHERE ranking = NEW.ranking
AND id <> NEW.id;
ELSIF ( counter > 1 ) THEN
RAISE EXCEPTION 'COUNTER cannot be greater than 1.';
END IF;
RETURN NEW;
END IF;
END
Vielen Dank für Eure Hilfe,
--Heiko
Lesezeichen