【问题标题】:SQL TriggerSQL 触发器
【发布时间】:2009-02-03 11:35:13
【问题描述】:

如果tbl_repair_visit.TENANTSATISFACTION = 'Poor' 更新,我有附加的触发器。

如果我们更改工程师名称,我遇到的问题是,如果 TENANTSATISFACTION = 'Poor' ,工程师列会更新并且触发器会再次运行

如何将其设置为仅在更新 TENANTSATISFACTION = 'Poor' 列并忽略所有其他列的更新时运行

ALTER TRIGGER [dbo].[tr_CustomerSatisfactionAlertRepair] 
    ON [dbo].[tbl_repair_visit] 
AFTER UPDATE
AS 
BEGIN
    SET NOCOUNT ON;
    INSERT alertmessagedata (TypeID, Contract, Address, ORDERID, 
                ENGINEERS, Sent, DateAdded)
    SELECT '5', tbl_property.contract, tbl_property.fulladdress, 
            tbl_repair_visit.orderid, tbl_repair_visit.engineer, 
            0, GETDATE()
    FROM TBL_REPAIR_VISIT 
    INNER JOIN
        INSERTED X ON TBL_REPAIR_VISIT.VISITID = X.VISITID 
    INNER JOIN 
        TBL_PROPERTY ON TBL_REPAIR_VISIT.PROPREF = TBL_PROPERTY.PROPREF
    WHERE tbl_repair_visit.TENANTSATISFACTION = 'Poor'
END

【问题讨论】:

  • 触发器中 BL 不良后果的好例子。
  • 既然可以改变它以达到预期的效果,这不是更多的“当实现与设计不匹配时的不良后果”的情况吗?我不明白为什么在这种情况下触发器不好,因为它可以正确编码......
  • @MartGriff:如果之前的值为“差”,则 IF UPDATE(tenantsatisfaction) 将失败,即使租户满意度没有真正改变,它仍会标记已更新。 IF UPDATE 将触发多个 INSERT INTO alertmessagedata。想想用户双击您基于网络的程序上的提交按钮。
  • 触发器在 Microsoft SQL 中的存储位置,因为我在 Programmability Database Triggers 文件夹中找不到它们。

标签: sql triggers


【解决方案1】:

在更新触发器中,您可以检查列是否正在更新:

如果更新(租户满意) 开始 …… 结束

【讨论】:

    【解决方案2】:

    我不认为你可以指定。每当对表执行 UPDATE、DELETE 或 INSERT(相应地)时,都会触发触发器 UPDATE、DELETE 和 INSERT。

    您可以按照 Mike K. 的建议进行操作,并检查您感兴趣的列是否发生了变化。

    【讨论】:

      【解决方案3】:

      你不能用嵌套触发器选项做点什么吗?
      (关闭该选项,以便触发器不会导致其他触发器被触发)

      或者,也许您可​​以创建一个 INSTEAD OF 触发器,而不是一个 AFTER 触发器。 当然,然后在您的 INSTEAD OF 触发器中,您还必须在附加逻辑旁边编写应该执行实际更新或插入表的 UPDATE(或插入)语句。

      【讨论】:

        【解决方案4】:

        从旧版本左加入新版本的记录,如果加入的表(即插入的)为空值,则表示您要检测变化的字段发生了变化。

        create table family
        (
        id int not null identity(1,1),
        name varchar(100) not null,
        age int not null
        );
        
        
        insert into family(name,age) values('Michael', 32);
        insert into family(name,age) values('Matthew', 23);
        
        
        
        create trigger TrigUpdOnFamily on family
        for update
        as
        
            if exists
                (
                select * from deleted 
                left join inserted on inserted.id = deleted.id    
        
                -- put the fields to detect here...
                and inserted.age = deleted.age
                    -- ...detections
                where inserted.age is null) begin    
        
                -- detect important fields
                print 'age change';
        
            end
            else begin
                -- ignore non-important fields
                print 'nothing change';
            end;
        
        go
        
        
        -- possible SqlCommand from .NET
        update family set name = 'Michael', age = 20 where id = 1;    
        
        update family set name = 'Mateo', age = 23 where id = 2;
        

        【讨论】:

          【解决方案5】:
          create table Programmer
          (
          id int not null identity(1,1),
          name varchar(100) not null,
          status varchar(20)
          );
          
          
          insert into Programmer(name,status) values('Pampers', 'Rich');
          
          
          
          
          create trigger TrigUpdOnProgrammer on Programmer
          for update
          as
          
              if exists
                  (
                  select * from deleted 
                  left join inserted on inserted.id = deleted.id    
          
                  -- put the fields to detect here...
                  and inserted.status = deleted.status -- detect if changed
                  -- ...detections
                  where inserted.status is null) 
          
                 -- if changes detected on status, then check if it is Poor.  
                 -- don't worry, there's no performance degradation.  SQL AND is short-circuited
                 and exists(select * from inserted where status = 'Poor')
              begin    
                 print 'status changed';
              end
              else begin
                  print 'changes ignored';
              end;
          
          go
          
          -- execute the following on succession, then check the output
          
          update Programmer set status = 'Poor' where id = 1; -- changes detected
          
          update Programmer set status = 'Poor' where id = 1; -- changes ignored
          
          update Programmer set status = 'Rich' where id = 1; -- changes ignored
          
          update Programmer set status = 'Poor' where id = 1; -- changes detected
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-07-27
            • 2011-08-06
            • 1970-01-01
            • 2010-12-11
            • 2015-09-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多