删除后,SQL Server触发器与引用表冲突

时间:2012-07-16 06:40:55

标签: sql sql-server triggers

我创建了一个触发器,在更改后创建一个带有新ID的新行。当我使用一个表的触发器时它可以工作,但是当我在一个引用另一个表的表上使用它时,我收到一个错误:

  

DELETE语句与REFERENCE约束冲突。

表格如下:

表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;

1 个答案:

答案 0 :(得分: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