Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2008 无法创建替代触发器_Sql Server 2008_Tsql - Fatal编程技术网

Sql server 2008 无法创建替代触发器

Sql server 2008 无法创建替代触发器,sql-server-2008,tsql,Sql Server 2008,Tsql,我有两个SQLServer2008表:Schedules(父表)和ScheduleResults(子表) 及 逻辑是,在插入/更新/删除子项之后,我查看父项的所有子项。如果其中任何一个具有IsEndOfRun=1,则父计划记录状态变为“DEA”,否则变为“ACT”。如果没有找到,它仍然会转到“ACT” 这是我的触发器: CREATE TRIGGER ScheduleResultsStatus ON [ScheduleResults] AFTER INSERT, UPDATE, DELETE AS

我有两个SQLServer2008表:Schedules(父表)和ScheduleResults(子表)

逻辑是,在插入/更新/删除子项之后,我查看父项的所有子项。如果其中任何一个具有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
插入后效果完美。更新后的作品完美。删除后不起作用。触发器名称上有一条歪歪扭扭的警告信息:

无法创建而不是删除触发器。这是因为表有一个带有级联删除的外键

我最初的定义在ScheduleID列上有一个ON DELETE CASCADE子句。我移除了它,但没有成功。另外,正如您所看到的,我正在创建一个AFTER触发器,而不是一个INSTEAD-of触发器。所以现在我的问题是。。。我如何调整触发器和/或FK约束,以便处理引用完整性和删除子场景


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

感谢前面的评论。它引发了一些想法,我不仅能够让它工作,而且代码在使用集合时更简单。以下是子孙后代的代码:

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

谢谢你之前的评论。它引发了一些想法,我不仅能够让它工作,而且代码在使用集合时更简单。以下是子孙后代的代码:

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

旁注:看到这条语句
SELECT@ScheduleID=ScheduleID FROM inserted
,您似乎认为每行将调用一次触发器-事实并非如此;每个语句将调用一次触发器,如果该语句影响多行,则插入的
伪表中将包含多行。您需要以这样一种方式编写触发器代码,即它可以处理插入的
中的多行-您的代码当前无法这样做。您真的需要存储此状态吗?-在检索过程中计算它似乎是一件简单的事情(如果愿意,您可以创建一个包含逻辑的视图),而且,除了marc_的注释之外,当您只想确定存在与否时,不要
COUNT()
EXISTS()
存在是有原因的。另外:插入的表在INSERT和UPDATE语句期间存储受影响行的副本。在insert或update事务期间,新行同时添加到插入表和触发器表中。插入表中的行是触发器表中新行的副本。因此,在delete的情况下,您的select将永远不会返回任何内容。marc_s,正确,我需要调整触发器以处理集合,而不是单个记录。旁注:看到此语句
select@ScheduleID=ScheduleID FROM inserted
,您似乎认为触发器将每行调用一次-情况并非如此;每个语句将调用一次触发器,如果该语句影响多行,则插入的
伪表中将包含多行。您需要以这样一种方式编写触发器代码,即它可以处理插入的
中的多行-您的代码当前无法这样做。您真的需要存储此状态吗?-在检索过程中计算它似乎是一件简单的事情(如果愿意,您可以创建一个包含逻辑的视图),而且,除了marc_的注释之外,当您只想确定存在与否时,不要
COUNT()
EXISTS()
存在是有原因的。另外:插入的表在INSERT和UPDATE语句期间存储受影响行的副本。在insert或update事务期间,新行同时添加到插入表和触发器表中。插入表中的行是触发器表中新行的副本。因此,如果删除,您的选择将永远不会返回任何内容。marc_,正确,我需要调整触发器以处理集合,而不是单个记录。
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