2012-07-17 42 views
0

SQL表我有以下触发:预过滤器与触发器

ALTER TRIGGER [dbo].[DIENSTLEISTUNG_Update] 
    ON [dbo].[DIENSTLEISTUNG] 
    INSTEAD OF UPDATE 
AS 
BEGIN 
    SET NOCOUNT ON; 

    INSERT INTO [DIENSTLEISTUNG] (BEZEICHNUNG, MENGENEINHEIT, 
     PREIS, BESCHREIBUNG, VORLAUFZEIT, 
     AZ_MO, AZ_DI,AZ_MI,AZ_DO,AZ_FR, 
     AZ_SA,AZ_SO,DIENSTLEISTUNGSART_ID, 
     UPDATE_USER, UPDATE_DATE, RUESTZEIT, 
     PERMISSIONS, KONTRAKTPOSITION,ARTIKELNUMMER, 
     ANZAHL, BUCHUNGSHINWEIS, SONDERWUNSCH,FLAG) 

    SELECT BEZEICHNUNG, MENGENEINHEIT, 
     PREIS, BESCHREIBUNG, VORLAUFZEIT, 
     AZ_MO, AZ_DI,AZ_MI,AZ_DO,AZ_FR, 
     AZ_SA,AZ_SO,DIENSTLEISTUNGSART_ID, 
     UPDATE_USER,GETDATE(),RUESTZEIT, 
     PERMISSIONS, KONTRAKTPOSITION,ARTIKELNUMMER, 
     ANZAHL, BUCHUNGSHINWEIS, SONDERWUNSCH, 
     0 
    FROM INSERTED 

    UPDATE DIENSTLEISTUNG 
    SET  DIENSTLEISTUNG.FLAG = 1 
    FROM DIENSTLEISTUNG 
      INNER JOIN INSERTED 
      ON INSERTED.ID = DIENSTLEISTUNG.ID    
SET NOCOUNT OFF;  
END 

的触发拷贝整行,如果用原来的行中的变化发生在一个新的ID。它还在新旧行中设置了一个标志(旧行获得FLAG = 1,新行FLAG = 0)。

是否可以从触发器内过滤这些行,以便它只返回FLAG = 0的新行?

如果是,我该怎么做?

在此先感谢!

+1

你的触发器不是“他”,它不会“返回行”。我也不明白插入标志= 0的目的,然后在插入后将其更新为1。你的意思是先执行插入,并将标志设置为0? – 2012-07-17 13:25:13

回答

1

如果您要求的是Select触发器,那么,否,MS SQL Server不支持选择触发器。

但是,你可以使用一个观点,即从在FLAG列为1表只返回行,像

create view dbo.DIENSTLEISTUNG_Flagged 
as 
    select * from DIENSTLEISTUNG 
    where FLAG=1 

不过,我会建议具有对历史记录额外的表,而只是让他们就地。这样,你可以添加额外的领域,如时间戳,或者更改行的用户,或者改变了它的应用,等等...
沿

Insert into ServicesHistory (..., ChangeDate) 
Select ... , getdate() from inserted 
(用于触发伪代码)东西线

注意,这也将改变“而不是”你的触发器(纯粹的邪恶)成定期触发(稍差恶)

+1

为什么'INSTEAD OF'触发纯粹的邪恶? – 2012-07-17 15:18:34

+0

@ypercube触发器通常被称为邪恶,因为它们往往会做隐形的副作用,背后的东西,因此往往很难调试。 'INSTEAD OF'触发器增加了混合的副作用是唯一剩下的,实际上,计算机没有做我明确指示它做的事情。 – SWeko 2012-07-17 15:55:44

+1

尽管我不喜欢触发器(出于你提到的原因),但我认为INSTEAD OF触发器经常用于SQL-Server,因为没有BEFORE触发器。 – 2012-07-17 15:59:17

1

我想也许你的意思是先更新现有的行,然后插入新行与国旗0.

ALTER TRIGGER [dbo].[DIENSTLEISTUNG_Update] 
ON [dbo].[DIENSTLEISTUNG] 
INSTEAD OF UPDATE 
AS 
BEGIN 
    SET NOCOUNT ON; 

    UPDATE d 
    SET  FLAG = 1 
    FROM dbo.DIENSTLEISTUNG AS d 
      INNER JOIN inserted AS i 
      ON i.ID = d.ID; 

    INSERT INTO dbo.[DIENSTLEISTUNG] 
    (
     BEZEICHNUNG, MENGENEINHEIT, 
     PREIS, BESCHREIBUNG, VORLAUFZEIT, 
     AZ_MO, AZ_DI,AZ_MI,AZ_DO,AZ_FR, 
     AZ_SA,AZ_SO,DIENSTLEISTUNGSART_ID, 
     UPDATE_USER, UPDATE_DATE, RUESTZEIT, 
     PERMISSIONS, KONTRAKTPOSITION,ARTIKELNUMMER, 
     ANZAHL, BUCHUNGSHINWEIS, SONDERWUNSCH,FLAG 
) 
    SELECT BEZEICHNUNG, MENGENEINHEIT, 
     PREIS, BESCHREIBUNG, VORLAUFZEIT, 
     AZ_MO, AZ_DI,AZ_MI,AZ_DO,AZ_FR, 
     AZ_SA,AZ_SO,DIENSTLEISTUNGSART_ID, 
     UPDATE_USER,GETDATE(),RUESTZEIT, 
     PERMISSIONS, KONTRAKTPOSITION,ARTIKELNUMMER, 
     ANZAHL, BUCHUNGSHINWEIS, SONDERWUNSCH, 0 
    FROM inserted; 
END