2016-05-07 10 views
1

Betrachten Sie R (A, B, C) mit der funktionalen Abhängigkeit B -> C. Ich schrieb den folgenden Trigger, um die FD zu bewahren.Fehler in FD-Erhaltung Trigger in SQL Server

create trigger t1 on R after insert 
as 
if exists(select B from R 
group by B 
having count(distinct C)>1 
) 
print 'B->C FD does not permit!' 
rollback; 

Es funktioniert gut, aber gibt einen Fehler:

The transaction ended in the trigger. The batch has been aborted.

Wie kann ich fangen/diesen Fehler beheben?

+0

was genau möchten Sie tun, wenn Sie die Transaktion zurückrollen? –

+0

Nichts außer dem Drucken der Nachricht: "B-> C FD erlaubt nicht!" – John

Antwort

0

können Sie INSTEAD OF Trigger verwenden:

CREATE TRIGGER t1 on R 
INSTEAD OF INSERT 
AS 
BEGIN 
    IF EXISTS(
     SELECT B 
     FROM (
     SELECT B, C 
     FROM R 
     UNION ALL 
     SELECT B, C 
     FROM INSERTED) AS T 
     GROUP BY B 
     HAVING COUNT(DISTINCT C) > 1 
    ) 
    PRINT 'B->C FD does not permit!' 
    ELSE 
    INSERT INTO R SELECT * FROM inserted 
END; 
GO 

Ein anderer Weg:

CREATE TRIGGER t1 on R 
AFTER INSERT 
AS 
     IF EXISTS(
      SELECT B 
      FROM (
      SELECT B, C 
      FROM R 
      UNION ALL 
      SELECT B, C 
      FROM INSERTED) AS T 
      GROUP BY B 
      HAVING COUNT(DISTINCT C) > 1 
     ) 
BEGIN 
PRINT 'B->C FD does not permit!' 
ROLLBACK TRANSACTION; 
RETURN 
END; 
GO 
+0

Danke, aber NACH dem Einsatz kann die FD beschädigt sein, vorher nicht! – John

+1

Fügen Sie dann eingefügt in Ihrer EXISTS-Anweisung hinzu. Ich habe meinen Beitrag geändert. Bitte schau es dir an. – gofr1

+0

Danke nochmal, es funktioniert, aber ich fragte mich, was falsch in meinem Code ist (was offensichtlich lesbarer ist)? Was bedeutet dieser Fehler? und gibt es eine einfache Möglichkeit, es zu cachen? – John

0

Die Abfrage in Ihrem Trigger ist in keinem Zusammenhang zu dem, was Sie eingefügt haben, die inserted Tabelle ist.

create trigger t1 on R after insert 
as 
if exists(select B from R 
where B in (select B from inserted) --"is" was mistype 
group by B 
having count(C)>1 --distinct allows to insert same (B,C) pairs 
) 
begin 
print 'B->C FD does not permit!' 
rollback; 
end 

-- insert fresh data 
insert R (A,B,C) 
values 
(1,'ab','cd'), 
(2,'cd','ef') 
--passed 
-- insert more 
insert R (A,B,C) 
values 
(3,'abc','cd'), 
(4,'cde','ef'), 
(5,'ab','qq') 
-- failed with message: 
B->C FD does not permit! 
Msg 3609, Level 16, State 1, Line 16 
The transaction ended in the trigger. The batch has been aborted. 
-- As Expected 
+0

Danke, habe das versucht aber der Fehler existiert noch .... – John