Trigger to fire only if a condition is met in SQL Server

后端 未结 7 864
夕颜
夕颜 2020-12-03 07:14

I hope this is a simple enough question for any SQL people out there...

We have a table which hold system configuration data, and this is tied to a history table via

相关标签:
7条回答
  • 2020-12-03 07:17

    Given that a WHERE clause did not work, maybe this will:

    CREATE TRIGGER 
        [dbo].[SystemParameterInsertUpdate]
    ON 
        [dbo].[SystemParameter]
    FOR INSERT, UPDATE 
    AS
      BEGIN
        SET NOCOUNT ON
    
          If (SELECT Attribute FROM INSERTED) LIKE 'NoHist_%'
          Begin
              Return
          End
    
          INSERT INTO SystemParameterHistory 
          (
            Attribute,
            ParameterValue,
            ParameterDescription,
            ChangeDate
          )
        SELECT
          Attribute,
          ParameterValue,
          ParameterDescription,
          ChangeDate
        FROM Inserted AS I
    END
    
    0 讨论(0)
  • 2020-12-03 07:17

    How about this?

    CREATE TRIGGER 
    [dbo].[SystemParameterInsertUpdate]
    ON 
    [dbo].[SystemParameter]
    FOR INSERT, UPDATE 
    AS
    BEGIN
    SET NOCOUNT ON
      IF (LEFT((SELECT Attribute FROM INSERTED), 7) <> 'NoHist_') 
      BEGIN
          INSERT INTO SystemParameterHistory 
          (
            Attribute,
            ParameterValue,
            ParameterDescription,
            ChangeDate
          )
        SELECT
          Attribute,
          ParameterValue,
          ParameterDescription,
          ChangeDate
       FROM Inserted AS I
    END
    END
    
    0 讨论(0)
  • 2020-12-03 07:17

    The _ character is also a wildcard, BTW, but I'm not sure why this wasn't working for you:

    CREATE TRIGGER 
        [dbo].[SystemParameterInsertUpdate]
    ON 
        [dbo].[SystemParameter]
    FOR INSERT, UPDATE 
    AS
      BEGIN
        SET NOCOUNT ON
          INSERT INTO SystemParameterHistory 
          (
            Attribute,
            ParameterValue,
            ParameterDescription,
            ChangeDate
          )
        SELECT
          I.Attribute,
          I.ParameterValue,
          I.ParameterDescription,
          I.ChangeDate
        FROM Inserted AS I
        WHERE I.Attribute NOT LIKE 'NoHist[_]%'
    END
    
    0 讨论(0)
  • 2020-12-03 07:21

    Your where clause should have worked. I am at a loss as to why it didn't. Let me show you how I would have figured out the problem with the where clause as it might help you for the future.

    When I create triggers, I start at the query window by creating a temp table called #inserted (and or #deleted) with all the columns of the table. Then I popultae it with typical values (Always multiple records and I try to hit the test cases in the values)

    Then I write my triggers logic and I can test without it actually being in a trigger. In a case like your where clause not doing what was expected, I could easily test by commenting out the insert to see what the select was returning. I would then probably be easily able to see what the problem was. I assure you that where clasues do work in triggers if they are written correctly.

    Once I know that the code works properly for all the cases, I global replace #inserted with inserted and add the create trigger code around it and voila, a tested trigger.

    AS I said in a comment, I have a concern that the solution you picked will not work properly in a multiple record insert or update. Triggers should always be written to account for that as you cannot predict if and when they will happen (and they do happen eventually to pretty much every table.)

    0 讨论(0)
  • 2020-12-03 07:27

    Using LIKE will give you options for defining what the rest of the string should look like, but if the rule is just starts with 'NoHist_' it doesn't really matter.

    0 讨论(0)
  • 2020-12-03 07:38
    CREATE TRIGGER
        [dbo].[SystemParameterInsertUpdate]
    ON 
        [dbo].[SystemParameter]
    FOR INSERT, UPDATE 
    AS
      BEGIN
        SET NOCOUNT ON 
    
        DECLARE @StartRow int
        DECLARE @EndRow int
        DECLARE @CurrentRow int
    
        SET @StartRow = 1
        SET @EndRow = (SELECT count(*) FROM inserted)
        SET @CurrentRow = @StartRow
    
        WHILE @CurrentRow <= @EndRow BEGIN
    
            IF (SELECT Attribute FROM (SELECT ROW_NUMBER() OVER (ORDER BY Attribute ASC) AS 'RowNum', Attribute FROM inserted) AS INS WHERE RowNum = @CurrentRow) LIKE 'NoHist_%' BEGIN
    
                INSERT INTO SystemParameterHistory(
                    Attribute,
                    ParameterValue,
                    ParameterDescription,
                    ChangeDate)
                SELECT
                    I.Attribute,
                    I.ParameterValue,
                    I.ParameterDescription,
                    I.ChangeDate
                FROM
                    (SELECT Attribute, ParameterValue, ParameterDescription, ChangeDate FROM (
                                                                                                SELECT ROW_NUMBER() OVER (ORDER BY Attribute ASC) AS 'RowNum', * 
                                                                                                FROM inserted)
                                                                                        AS I 
                WHERE RowNum = @CurrentRow
    
            END --END IF
    
        SET @CurrentRow = @CurrentRow + 1
    
        END --END WHILE
    END --END TRIGGER
    
    0 讨论(0)
提交回复
热议问题