2017-04-06 77 views
0

我在同一個表上有多個觸發器使用多個觸發器的原因是因爲有些字段需要從不同的表中更新,我也有backward date scheduling。有線正在發生當我第一次插入時,只有一個字段從其中一個觸發器更新或一個觸發器被觸發,當我第一次更新行時觸發三個觸發器,...我必須更新3次以獲取所有每次我做第一次,第二次,第三次更新時,更新的字段也需要大約8秒在同一個表上有多個觸發器的缺點

問題1.在單個表中有多個觸發器的缺點是什麼?

問題2.我怎樣才能加快觸發器?

問題3.我該如何調試觸發器?

後順序調度

SHIP BY = CUSTOMER PROMISED DATE-1

A-MOUNT BY =船舶-1

A-粉體= A-MOUNT BY - 1 OR A-粉體也等於船由日期-2

A-FAB BY = A-粉體 - 1 OR A-FAB BY也等於船由日期-3

AC/S BY = A-FAB BY OR AC/S BY也等於按日期發貨-4

A-CUT BY = AC/S BY -1或A-CUT BY也等於按日期發貨-5

/****** Object: Trigger [dbo].[CALC-PROMISED-DATE-AND-SHIPBY] Script Date: 4/6/2017 2:46:01 PM ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
ALTER TRIGGER [dbo].[CALC-PROMISED-DATE-AND-SHIPBY] 
    ON [dbo].[WORKORDERS] 
    AFTER INSERT, UPDATE 
    AS 
    BEGIN 
    set nocount on 
    IF TRIGGER_NESTLEVEL() > 1 
    RETURN 
    set datefirst 7; 
UPDATE T1 
    [SHIP BY] = 
       CASE datepart(WEEKDAY, t1.[CALC PROMISED DATE]) 
        WHEN 1 then DateAdd(day, -2, t1.[CALC PROMISED DATE]) 
        WHEN 7 then DateAdd(day, -1, t1.[CALC PROMISED DATE]) 
       ELSE 
        CASE 
         WHEN t1.[RE-COMMIT DATE] =Null THEN ISNULL(T1.[PROMISED DATE],Null) 
         WHEN t1.[RE-COMMIT DATE] is null THEN ISNULL(T1.[PROMISED DATE],Null) 
        ELSE ISNULL(T1.[RE-COMMIT DATE],Null) 
        END 
      END  

      FROM WORKORDERS T1 
       INNER JOIN inserted i ON T1.[WORK ORDER #] = i.[WORK ORDER #] 
       END 

A-MOUNT BY

/****** Object: Trigger [dbo].[MOUNTBY] Script Date: 4/6/2017 2:46:54 PM ******/ 
    SET ANSI_NULLS ON 
    GO 
    SET QUOTED_IDENTIFIER ON 
    GO 
    ALTER TRIGGER [dbo].[MOUNTBY] 
     ON [dbo].[WORKORDERS] 
     AFTER INSERT,UPDATE 
     AS 
     BEGIN 
     IF TRIGGER_NESTLEVEL() > 1 
     RETURN 
     set datefirst 7; 
    UPDATE T1 
     [A-MOUNT BY] = 
     case  datepart(WEEKDAY, DateAdd(day,-1,t1.[SHIP BY])) 
      when 7 then DateAdd(day, -2, t1.[SHIP BY]) 
      when 1 then DateAdd(day, -3, t1.[SHIP BY]) 
      else DateAdd(day, -1, t1.[SHIP BY])--t1.[A-C/S BY]-1 
     END 
FROM WORKORDERS T1 
    INNER JOIN inserted i ON T1.[WORK ORDER #] = i.[WORK ORDER #] 
    END 

A-粉體

/****** Object: Trigger [dbo].[POWDERBY] Script Date: 4/6/2017 2:49:53 PM ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
ALTER TRIGGER [dbo].[POWDERBY] 
    ON [dbo].[WORKORDERS] 
    AFTER INSERT,UPDATE 
    AS 
    BEGIN 
    IF TRIGGER_NESTLEVEL() > 1 
    RETURN 
    set datefirst 7; 
UPDATE T1 
--SET 
SET [A-POWDER BY] = 
case datepart(WEEKDAY, t1.[A-MOUNT BY]-1) 
     when 7 then DateAdd(day, -2, t1.[A-MOUNT BY]) 
    when 1 then DateAdd(day, -3, t1.[A-MOUNT BY]) 
    else t1.[A-MOUNT BY]-1 
END 

FROM WORKORDERS T1 
    INNER JOIN inserted i ON T1.[WORK ORDER #] = i.[WORK ORDER #] 
    END 

A-FAB BY

/****** Object: Trigger [dbo].[FABBY] Script Date: 4/6/2017 2:50:23 PM ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
ALTER TRIGGER [dbo].[FABBY] 
    ON [dbo].[WORKORDERS] 
    AFTER insert, UPDATE 
    AS 
    BEGIN 
    IF TRIGGER_NESTLEVEL() > 1 
    RETURN 
    set datefirst 7; 
UPDATE T1 
SET [A-FAB BY] = case datepart(WEEKDAY, t1.[A-POWDER BY]-1) 
     when 7 then DateAdd(day, -2, t1.[A-POWDER BY]) 
    when 1 then DateAdd(day, -3, t1.[A-POWDER BY]) 
    else t1.[A-POWDER BY]-1 
END 
FROM WORKORDERS T1 
    INNER JOIN inserted i ON T1.[WORK ORDER #] = i.[WORK ORDER #] 
    END 

A-PRINT BY

/****** Object: Trigger [dbo].[PRINTBY] Script Date: 4/6/2017 2:50:50 PM ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
ALTER TRIGGER [dbo].[PRINTBY] 
    ON [dbo].[WORKORDERS] 
    AFTER INSERT, UPDATE 
    AS 
    BEGIN 
    IF TRIGGER_NESTLEVEL() > 1 
    RETURN 
    set datefirst 7; 
UPDATE T1 
SET [A-PRINT BY] = case datepart(WEEKDAY, t1.[A-FAB BY]) 
     when 7 then DateAdd(day, -2, t1.[A-FAB BY]) 
    when 1 then DateAdd(day, -3, t1.[A-FAB BY]) 
    else t1.[A-FAB BY]-1 
END 
FROM WORKORDERS T1 
    INNER JOIN inserted i ON T1.[WORK ORDER #] = i.[WORK ORDER #] 
    END 

A-C/S BY

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
ALTER TRIGGER [dbo].[C/SBY] 
    ON [dbo].[WORKORDERS] 
    AFTER INSERT,UPDATE 
    AS 
    BEGIN 
    IF TRIGGER_NESTLEVEL() > 1 
    RETURN 
    set datefirst 7; 
UPDATE T1 
--SET 
SET [A-C/S BY] = case datepart(WEEKDAY, t1.[A-PRINT BY]-1) 
     when 7 then DateAdd(day, -2, t1.[A-PRINT BY]) 
    when 1 then DateAdd(day, -3, t1.[A-PRINT BY]) 
    else t1.[A-PRINT BY]-1 
END 
FROM WORKORDERS T1 
    INNER JOIN inserted i ON T1.[WORK ORDER #] = i.[WORK ORDER #] 
    END 

A-削減

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
ALTER TRIGGER [dbo].[CUTBY] 
    ON [dbo].[WORKORDERS] 
    AFTER INSERT, UPDATE 
    AS 
    BEGIN 
    IF TRIGGER_NESTLEVEL() > 1 
    RETURN 
    set datefirst 7; 
UPDATE T1 
--SET 
SET [A-CUT BY] = 
case  datepart(WEEKDAY, DateAdd(day,-1,t1.[A-C/S BY])) 
    when 7 then DateAdd(day, -2, t1.[A-C/S BY]) 
    when 1 then DateAdd(day, -3, t1.[A-C/S BY]) 
    else t1.[A-C/S BY]-1--t1.[A-C/S BY]-1 
END 
FROM WORKORDERS T1 
    INNER JOIN inserted i ON T1.[WORK ORDER #] = i.[WORK ORDER #] 
    END 
+0

你能發佈足夠的觸發器嗎?那些更新?你是否加入插入,只更新受影響的行?您是否知道您可以在單個更新聲明中更新多個列?你真的需要提供你的問題的所有信息。這整個事情尖叫着一個非常糟糕的建築。 –

+0

確定是的,但我只想更新只有一行或受影響的行 – Joe

+0

我明白了,但你沒有提供任何代碼......只有一個片段。當您想要更新加入到插入和/或刪除虛擬表的受影​​響行時。介紹整個過程,而不只是你認爲的問題。我可以放心地說,在這一點上,整個過程是複雜的。這種事情不應該只是一個更新聲明。 –

回答

2

這確實是3個問題集於一身職位。

問題1.在單個表中有多個觸發器的缺點是什麼?

只要每個觸發器都用於一個獨特事件,這裏沒有缺點。通常最好避免在單個表上使用三個更新觸發器,因爲它很難維護,並且有時消防命令很重要,因此您必須對其進行管理。

問題2.我怎樣才能加快觸發器?

沒有萬能的按鈕來使觸發器更快。每個觸發器的查詢和邏輯需要獨立評估。

問題3.我該如何調試觸發器?

用打印語句。觸發器絕對不容易調試。


然而,這個問題有助於觸發器的更大討論。大多數時間觸發器不是解決問題的最佳方法。通常有更好的方法。在這一點上,我一直在使用數據庫超過20年,並且只有少數幾次纔有合理的觸發需求。它們對於審計非常有用,但大多數情況下它們是手頭任務的錯誤工具。


鑑於新的信息和代碼,我創建了一個新的觸發器,應該適合你。您不需要每列的觸發器,您需要觸發插入和更新事件。您可以在單個更新語句中執行所有這些編輯。這裏似乎還存在一些主要的邏輯問題,但我並不真正知道你在做什麼。我建議放棄所有這些觸發器,因爲它們命名非常差,並且給出了它們被固定在一個動作中的名稱。

我也強烈建議你養成更好名字的習慣。這些列名稱只是可怕的。他們不應該有空格,破折號等

所有這些觸發器可以簡化爲這樣的事情。

create TRIGGER [dbo].[WORKORDERS_Insert_Update] ON [dbo].[WORKORDERS] 
    AFTER INSERT, UPDATE AS 
BEGIN 
    set nocount on 

    IF TRIGGER_NESTLEVEL() > 1 
     RETURN 

    set datefirst 7; 
    UPDATE T1 
     set [SHIP BY] = 
      CASE datepart(WEEKDAY, t1.[CALC PROMISED DATE]) 
       WHEN 1 then DateAdd(day, -2, t1.[CALC PROMISED DATE]) 
       WHEN 7 then DateAdd(day, -1, t1.[CALC PROMISED DATE]) 
      ELSE T1.[RE-COMMIT DATE] 
        --CASE This entire case expression is pointless. Just put in the column, all the NULL checks in here are going to do the exact same thing. 
        -- --WHEN t1.[RE-COMMIT DATE] = Null THEN ISNULL(T1.[PROMISED DATE],Null) Nothing EVER equals NULL. This will never happen 
        --  --WHEN t1.[RE-COMMIT DATE] is null THEN ISNULL(T1.[PROMISED DATE],Null) ??? Why check for NULL and if it is NULL use an explicit NULL. This makes no sense 
        --ELSE ISNULL(T1.[RE-COMMIT DATE],Null)??? Why check for NULL and if it is NULL use an explicit NULL. This makes no sense 
        --END 
      END  
     , [A-MOUNT BY] = 
      case datepart(WEEKDAY, DateAdd(day,-1,t1.[SHIP BY])) 
       when 7 then DateAdd(day, -2, t1.[SHIP BY]) 
       when 1 then DateAdd(day, -3, t1.[SHIP BY]) 
       else DateAdd(day, -1, t1.[SHIP BY])--t1.[A-C/S BY]-1 
      END 
     , [A-POWDER BY] = 
      case datepart(WEEKDAY, t1.[A-MOUNT BY]-1) 
       when 7 then DateAdd(day, -2, t1.[A-MOUNT BY]) 
       when 1 then DateAdd(day, -3, t1.[A-MOUNT BY]) 
       else t1.[A-MOUNT BY]-1 
      END 
     , [A-FAB BY] = 
      case datepart(WEEKDAY, t1.[A-POWDER BY]-1) 
       when 7 then DateAdd(day, -2, t1.[A-POWDER BY]) 
       when 1 then DateAdd(day, -3, t1.[A-POWDER BY]) 
       else t1.[A-POWDER BY]-1 
      END 
     ,[A-PRINT BY] = 
      case datepart(WEEKDAY, t1.[A-FAB BY]) 
       when 7 then DateAdd(day, -2, t1.[A-FAB BY]) 
       when 1 then DateAdd(day, -3, t1.[A-FAB BY]) 
       else t1.[A-FAB BY]-1 
      END 
     , [A-C/S BY] = 
      case datepart(WEEKDAY, t1.[A-PRINT BY]-1) 
       when 7 then DateAdd(day, -2, t1.[A-PRINT BY]) 
       when 1 then DateAdd(day, -3, t1.[A-PRINT BY]) 
       else t1.[A-PRINT BY]-1 
      END 
     , [A-CUT BY] = 
      case datepart(WEEKDAY, DateAdd(day,-1,t1.[A-C/S BY])) 
       when 7 then DateAdd(day, -2, t1.[A-C/S BY]) 
       when 1 then DateAdd(day, -3, t1.[A-C/S BY]) 
       else t1.[A-C/S BY]-1--t1.[A-C/S BY]-1 
      END 
    FROM WORKORDERS T1 
    INNER JOIN inserted i ON T1.[WORK ORDER #] = i.[WORK ORDER #] 
END 
+0

謝謝@Sean如何管理消防指令?在我的情況下,我必須更新行三次以獲得我期待的結果,這種情況會如何發生? – Joe

+0

爲什麼你必須更新同一行三次?爲什麼它需要單獨的觸發器? –

+0

我不必我實際上只是測試試圖找出爲什麼有些字段更新和一些不,我看到,當我更新行觸發器發射/字段更新 – Joe

相關問題