ukulele
Datenbank-Guru
- Beiträge
- 5.284
Folgendes Szenario:
Ich habe eine Testtabelle, die eine Hierachie abbildet.
Außerdem gibt es eine Testsicht, die mir einen Pfad zu jedem Eintrag generiert. Der Code der Testsicht sollte hierbei eigentlich keine Rolle spielen, der Vollständigkeit halber:
Ein Trigger soll verhindern, das der Pfad rekursiv wird. Hier der Testtrigger:
Wenn ich den Code manuell ausführe, funktioniert das:
Ergebnis:
Führe ich aber ein Update Statement aus (mit aktivem Trigger) reagiert dieser nur, wenn fk = pk ist, nicht aber wenn der neue fk im Pfad der Sicht steht:
Ergebnis: Fehler (wie gewünscht)
Ergebnis: Kein Fehler
Ich habe eine Testtabelle, die eine Hierachie abbildet.
Code:
pk PRIMARY KEY
fk FOREIGN KEY
bla VARCHAR
9EC68708-E3A2-4CFB-854E-09B0DCF2449B 03D86DE3-1052-4B51-ACAB-C9C75E143928 Unterorder
03D86DE3-1052-4B51-ACAB-C9C75E143928 NULL Überordner
Außerdem gibt es eine Testsicht, die mir einen Pfad zu jedem Eintrag generiert. Der Code der Testsicht sollte hierbei eigentlich keine Rolle spielen, der Vollständigkeit halber:
Code:
with c as (
SELECT pk,
'/'+cast(pk as varchar(1000)) as pathid
FROM testtabelle b
WHERE b.fk IS NULL
UNION ALL
SELECT b.pk,
cast(c.pathid+'/'+cast(b.pk as varchar(36)) as varchar(1001))
FROM testtabelle b join c on b.fk = c.pk )
SELECT b.pk,
c.pathid+'/' as pfadid
FROM c join testtabelle b on c.pk = b.pk
ORDER BY pfadid
03D86DE3-1052-4B51-ACAB-C9C75E143928 /03D86DE3-1052-4B51-ACAB-C9C75E143928/
9EC68708-E3A2-4CFB-854E-09B0DCF2449B /03D86DE3-1052-4B51-ACAB-C9C75E143928/9EC68708-E3A2-4CFB-854E-09B0DCF2449B/
Ein Trigger soll verhindern, das der Pfad rekursiv wird. Hier der Testtrigger:
Code:
-- ================================================================
-- ================================================================
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- ================================================================
-- ================================================================
CREATE TRIGGER [dbo].[testtrigger]
ON [dbo].[testtabelle]
FOR INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE @pk UNIQUEIDENTIFIER
DECLARE @fk UNIQUEIDENTIFIER
DECLARE @error VARCHAR(255)
SELECT @pk = pk,
@fk = fk
FROM INSERTED
-- 0: Prüfen, ob sich eine Endlosschleife ergibt
IF @fk = @pk
OR ( SELECT pfadid
FROM testsicht
WHERE pk = @fk ) LIKE '%' + cast(@pk AS CHAR(36)) + '%'
BEGIN
SET @error = 'Erstellen einer rekursive Hierachie nicht möglich.' + CHAR(10)
+ 'Wählen Sie eine andere Überaufgabe.' + CHAR(10) + CHAR(13)
RAISERROR(@error,16,1)
ROLLBACK
END
-- 0: Ende
END
GO
Wenn ich den Code manuell ausführe, funktioniert das:
Code:
DECLARE @pk UNIQUEIDENTIFIER
DECLARE @fk UNIQUEIDENTIFIER
DECLARE @error VARCHAR(255)
SELECT @pk = pk,
@fk = fk
FROM testtabelle
WHERE bla = 'Überordner'
SET @fk = ( SELECT pk
FROM testtabelle
WHERE bla = 'Unterord' )
-- 0: Prüfen, ob sich eine Endlosschleife ergibt
IF @fk = @pk
OR ( SELECT pfadid
FROM testsicht
WHERE pk = @fk ) LIKE '%' + cast(@pk AS CHAR(36)) + '%'
BEGIN
SET @error = 'Erstellen einer rekursive Hierachie nicht möglich.' + CHAR(10)
+ 'Wählen Sie eine andere Überaufgabe.' + CHAR(10) + CHAR(13)
RAISERROR(@error,16,1)
ROLLBACK
END
-- 0: Ende
Ergebnis:
Meldung 50000, Ebene 16, Status 1, Zeile 22
Erstellen einer rekursive Hierachie nicht möglich.
Wählen Sie eine andere Überaufgabe.
Meldung 3903, Ebene 16, Status 1, Zeile 23
Die ROLLBACK TRANSACTION-Anforderung hat keine entsprechende BEGIN TRANSACTION-Anweisung.
Führe ich aber ein Update Statement aus (mit aktivem Trigger) reagiert dieser nur, wenn fk = pk ist, nicht aber wenn der neue fk im Pfad der Sicht steht:
Code:
update testtabelle
set fk = pk
where pk = '03D86DE3-1052-4B51-ACAB-C9C75E143928'
Code:
update testtabelle
set fk = '9EC68708-E3A2-4CFB-854E-09B0DCF2449B'
where pk = '03D86DE3-1052-4B51-ACAB-C9C75E143928'