2012-07-16 42 views
0

我創建了一個觸發器,它在更改後創建了一個新行,並且新創建了一個新的行ID。當我使用觸發器與一個表它的工作原理,但是當我用它在具有引用其它表的表,我得到一個錯誤:刪除後SQL Server觸發器與參考表衝突

DELETE statement conflicted with the REFERENCE constraint.

的表是這樣的:

表1

ID  BEZEICHNUNG  MENGENEINHEIT  PREIS ..... 
1  Harry Potter  Book     20 
2  iPod    Music    150 

表2

DIENSTLEISTUNG_ID  RAUM_ID 
1      2 
2      1 

表3

ID  Raumname .... 
1  Elbe 
2  Main 

我的觸發看起來是這樣的:

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

ALTER TRIGGER [dbo].[DIENSTLEISTUNG_Update] 
    ON [dbo].[DIENSTLEISTUNG] 
    AFTER UPDATE 
AS 
BEGIN 
SET NOCOUNT ON; 

    DECLARE @MAX_ID INT; 
    SELECT @MAX_ID=MAX(ID) FROM [DIENSTLEISTUNG]; 

    declare @tmp Table(ID numeric, BEZEICHNUNG nvarchar(64), MENGENEINHEIT nvarchar(64), 
    PREIS numeric(19,5), BESCHREIBUNG nvarchar(64), VORLAUFZEIT numeric(10), 
    AZ_MO nvarchar(22), AZ_DI nvarchar(22),AZ_MI nvarchar(22),AZ_DO nvarchar(22),AZ_FR nvarchar(22), 
    AZ_SA nvarchar(22),AZ_SO nvarchar(22),DIENSTLEISTUNGSART_ID numeric(38), 
    UPDATE_USER numeric(38), UPDATE_DATE datetime, RUESTZEIT numeric(38), 
    PERMISSIONS numeric (38), KONTRAKTPOSITION numeric(38),ARTIKELNUMMER nvarchar(64), 
    ANZAHL numeric(10), BUCHUNGSHINWEIS nvarchar(255), SONDERWUNSCH char(1), 
    FLAG bit) 

    insert into @tmp 
    select 
    ID, BEZEICHNUNG, MENGENEINHEIT, 
    PREIS, BESCHREIBUNG, VORLAUFZEIT, 
    AZ_MO, AZ_DI,AZ_MI,AZ_DO,AZ_FR, 
    AZ_SA,AZ_SO,DIENSTLEISTUNGSART_ID, 
    UPDATE_USER, UPDATE_DATE, RUESTZEIT, 
    PERMISSIONS, KONTRAKTPOSITION,ARTIKELNUMMER, 
    ANZAHL, BUCHUNGSHINWEIS, SONDERWUNSCH, 
    1 [flag] from deleted; 


    delete T from DIENSTLEISTUNG T JOIN @tmp I 
    ON T.ID=I.ID 

SET IDENTITY_INSERT [DIENSTLEISTUNG] ON 
INSERT INTO [DIENSTLEISTUNG] (ID, BEZEICHNUNG, MENGENEINHEIT, 
    PREIS, BESCHREIBUNG, VORLAUFZEIT, 
    AZ_MO, AZ_DI,AZ_MI,AZ_DO,AZ_FR, 
    AZ_SA,AZ_SO,DIENSTLEISTUNGSART_ID, 
    UPDATE_USER, UPDATE_DATE, RUESTZEIT, 
    PERMISSIONS, KONTRAKTPOSITION,ARTIKELNUMMER, 
    ANZAHL, BUCHUNGSHINWEIS, SONDERWUNSCH, 
    FLAG) 
SELECT @MAX_ID+ROW_NUMBER() OVER(ORDER BY ID) [ID],BEZEICHNUNG, MENGENEINHEIT, 
    PREIS, BESCHREIBUNG, VORLAUFZEIT, 
    AZ_MO, AZ_DI,AZ_MI,AZ_DO,AZ_FR, 
    AZ_SA,AZ_SO,DIENSTLEISTUNGSART_ID, 
    UPDATE_USER,GETDATE(),RUESTZEIT, 
    PERMISSIONS, KONTRAKTPOSITION,ARTIKELNUMMER, 
    ANZAHL, BUCHUNGSHINWEIS, SONDERWUNSCH, 
    0 
FROM INSERTED 
union all 
select * from @tmp 

SET IDENTITY_INSERT dbo.DIENSTLEISTUNG OFF 
SET NOCOUNT OFF; 
END; 
+0

足夠簡單:您試圖刪除仍在被行引用的內容。這是具有參照完整性(外鍵)的完整點 - 你不應該這樣做!找出你想要刪除的內容,還有哪些其他行仍然指向它。 – 2012-07-16 07:58:11

回答

3

這是發生的原因是因爲雖然你重新插入使用相同的ID一排,在當您刪除行時,SQL無法知道您將重新插入它以保持參照完整性。

看起來這個觸發器的目的是不允許更新,並且在發生改變時插入一個新行,所以我認爲INSTEAD OF觸發器更適合您的需求。然後您可以忽略對現有行進行的任何更改,並插入新行,從而避免任何刪除操作,從而避免參考完整性問題。

ALTER TRIGGER [dbo].[DIENSTLEISTUNG_Update] 
    ON [dbo].[DIENSTLEISTUNG] 
    INSTEAD OF UPDATE 
AS 
BEGIN 
    INSERT INTO [DIENSTLEISTUNG] (BEZEICHNUNG, MENGENEINHEIT, 
     PREIS, BESCHREIBUNG, VORLAUFZEIT, 
     AZ_MO, AZ_DI,AZ_MI,AZ_DO,AZ_FR, 
     AZ_SA,AZ_SO,DIENSTLEISTUNGSART_ID, 
     UPDATE_USER, UPDATE_DATE, RUESTZEIT, 
     PERMISSIONS, KONTRAKTPOSITION,ARTIKELNUMMER, 
     ANZAHL, BUCHUNGSHINWEIS, SONDERWUNSCH, 
     FLAG) 
    SELECT BEZEICHNUNG, MENGENEINHEIT, 
     PREIS, BESCHREIBUNG, VORLAUFZEIT, 
     AZ_MO, AZ_DI,AZ_MI,AZ_DO,AZ_FR, 
     AZ_SA,AZ_SO,DIENSTLEISTUNGSART_ID, 
     UPDATE_USER,GETDATE(),RUESTZEIT, 
     PERMISSIONS, KONTRAKTPOSITION,ARTIKELNUMMER, 
     ANZAHL, BUCHUNGSHINWEIS, SONDERWUNSCH, 
     0 
    FROM INSERTED 

    UPDATE DIENSTLEISTUNG 
    SET  Flag = 1 
    FROM DIENSTLEISTUNG 
      INNER JOIN INSERTED 
       ON INSERTED.ID = DIENSTLEISTUNG.ID 

END 
+0

謝謝,但我怎樣才能將編輯後的行設置爲更改後的值爲1的標誌 – 2012-07-16 08:21:24

+0

我已經添加了更新語句來執行此操作。 – GarethD 2012-07-16 08:34:28

+0

非常感謝你的工作! – 2012-07-16 08:39:43