1

我有两个 SQL Server 2008 表:Schedule(父)和 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。这是因为表有一个带有级联删除的外键。

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

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

4

1 回答 1

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
于 2013-04-11T18:52:40.997 回答