无法创建而不是触发器

时间:2013-04-11 07:14:25

标签: sql-server-2008 tsql

我有两个SQL Server 2008表:Schedules(父级)和ScheduleResults(子级)

CREATE TABLE Schedules(
    ID int identity primary key NOT NULL,
    Status nvarchar(3)
) [ON PRIMARY]

CREATE TABLE ScheduleResults(
    ID int identity primary key NOT NULL,
    ScheduleID int NOT NULL CONSTRAINT [FK_ScheduleResults_Schedules] REFERENCES Schedules(ID) ON DELETE CASCADE,
    IsEndOfRun bit NOT NULL CONSTRAINT DF_ScheduleResults_IsEndOfRun DEFAULT(0)
) [ON PRIMARY]

逻辑是在插入/更新/删除孩子之后,我会查看父母的所有孩子。如果其中任何一个具有IsEndOfRun = 1,那么父计划记录状态将变为'DEA',否则它将变为'ACT'。如果没有找到,它仍然会进入'ACT'。

所以这是我的触发器:

CREATE TRIGGER ScheduleResultsStatus
ON [ScheduleResults] AFTER INSERT, UPDATE, DELETE
AS
    SET NOCOUNT ON;
    DECLARE @ScheduleID int
    DECLARE @IsEORSum int
    SELECT @ScheduleID=ScheduleID FROM inserted
    SELECT @IsEORSum=COUNT(*) FROM ScheduleResults WHERE ScheduleID=@ScheduleID AND IsEndOfRun=1

    IF @IsEORSum=0
    BEGIN
            -- There are no EndOfRun results. Schedule should be active
            UPDATE Schedules SET Status='ACT' WHERE ID=@ScheduleID
    END
    ELSE
    BEGIN
            -- There is at least 1 record with IsEndOfRun=True. Schedule should be DEACTIVATED
            UPDATE Schedules SET Status='DEA' WHERE ID=@ScheduleID
    END

插入后工作完美。更新后工作完美。删除后不起作用。触发器名称上出现警告,并显示以下消息:

  

无法创建INSTEAD OF DELETE TRIGGER。这是因为table有一个带有级联删除的外键。

我的原始定义在ScheduleID列上确实有一个ON DELETE CASCADE子句。我删除了它,但没有成功。另外,正如您所看到的,我正在创建一个AFTER触发器,而不是INSTEAD触发器。那么现在我的问题是...如何调整Trigger和/或FK约束以让我处理参照完整性并处理删除子项场景?

我感谢所有SQL Server向导的任何帮助。

1 个答案:

答案 0 :(得分:1)

感谢之前的评论。它引发了一些想法,我不仅能够使它工作,而且代码使用集合更简单。这是后代的代码:

CREATE TRIGGER ScheduleResultsStatus
ON [ScheduleResults] AFTER INSERT, UPDATE, DELETE
AS
    SET NOCOUNT ON;
    UPDATE Schedules SET Status='ACT' WHERE ID IN (SELECT DISTINCT Schedules.ID FROM Schedules INNER JOIN deleted ON Schedules.ID=deleted.ScheduleID)
    UPDATE Schedules SET Status='DEA' WHERE ID IN (SELECT DISTINCT Schedules.ID FROM Schedules INNER JOIN inserted ON Schedules.ID=inserted.ScheduleID WHERE IsEndOfRun=1)
    UPDATE Schedules SET Status='ACT' WHERE ID IN (SELECT DISTINCT Schedules.ID FROM Schedules INNER JOIN inserted ON Schedules.ID=inserted.ScheduleID Group BY Schedules.ID HAVING SUM(CONVERT(int, IsEndOfRun))=0)
GO