2013-04-11 101 views
1
的创建

我有两个SQL Server 2008张的表格:调度(父)和ScheduleResults(孩子)不能INSTEAD OF触发器

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 [email protected] AND IsEndOfRun=1 

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

插入可以完美运行之后。更新完美后。删除后不起作用。在此消息的触发器名称上有一个警告波形曲线:

无法创建INSTEAD OF DELETE TRIGGER。这是因为表具有级联删除的外键。

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

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

+3

旁注:看到这个声明'SELECT @ ScheduleID = ScheduleID FROM inserted',看来,你认为触发器将每行一次被称为 - 这是** **不能在案件;触发器将在每个语句**中调用一次**,如果该语句影响多行,则“插入”伪表将在其中包含多行**。您需要编写触发器代码,以便可以在“插入”中处理多行 - 您的代码目前无法执行此操作。 – 2013-04-11 07:48:14

+0

你真的需要**存储**这个状态吗? - 在检索期间计算它似乎是一件简单的事情(如果你想创建一个包含逻辑的视图) – 2013-04-11 07:52:04

+1

而且,除了marc_s的注释之外 - 当所有的时候都不要使用COUNT()你想要做的是建立存在与否。 'EXISTS()'存在是有原因的。 – 2013-04-11 07:53:02

回答

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 
相关问题