2013-04-11 91 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 
相關問題