在同一张桌子上拥有多个触发器的缺点

时间:2017-04-06 20:41:51

标签: sql-server tsql

我在同一个表上有多个触发器使用多个触发器的原因是因为有些字段需要从不同的表更新,我也有backward date scheduling。有线的东西正在进行当我第一次插入时,只有一个触发器中的一个触发器更新或其中一个触发器被触发,当我第一次更新行时触发三个触发器,...我必须更新3次才能获得所有每当我进行第一次,第二次,第三次更新时,更新的字段大约需要8秒

问题1.在单个表中有多个触发器有什么缺点?

问题2.如何加速触发?

问题3.如何调试触发器?

后退计划

  

SHIP BY = CUSTOMER PROMISED DATE-1

     

A-MOUNT BY = SHIP BY -1

     

A-POWDER BY = A-MOUNT BY-1或A-POWDER BY也相等于日期-2

     

A-FAB BY = A-POWDER BY - 1或A-FAB BY也相等于日期-3

     

A-C / S BY = A-FAB BY或A-C / S BY也按日期等于-4

     

A-CUT BY = A-C / 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-POWDER BY

   /****** 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-CUT BY

  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

1 个答案:

答案 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