2011-04-12 120 views
0

我已經寫了一個觸發器來記錄表中的變化,我當然沒有意識到,直到這之後,它才一次只能處理一條記錄。現在我試圖更新它,以允許批量更新,我無法弄清楚如何做到這一點。多行觸發器

CREATE TRIGGER [DT].[trg_LogChanges] 
ON [DT].[NewDetails] 
FOR UPDATE 
AS 

DECLARE 
    @TableName VARCHAR(100) , 
    @UpdatedDate smalldatetime , 
    @UpdatedBy uniqueidentifier 

SELECT @TableName = 'DT.NewDetails' 

IF EXISTS (SELECT 1 FROM INSERTED i INNER JOIN DELETED d on i.Guid = d.Guid) 

    IF(SELECT ModifiedDate FROM INSERTED) Is Null 
     SET @UpdatedDate = getdate() 
    ELSE 
     SET @UpdatedDate = (SELECT ModifiedDate FROM INSERTED) 

    IF(SELECT ModifiedBy FROM INSERTED) Is Null 
     SET @UpdatedBy = '11111111-1111-1111-1111-111111111111' 
    ELSE 
     SET @UpdatedBy = (SELECT ModifiedBy FROM INSERTED) 


IF UPDATE (StatusID) 
    BEGIN 
     INSERT INTO DT.LogChanges 
     (
      ChangeType, TableName, RecordGuid, FieldName 
      , OldValue, NewValue, UpdatedBy, UpdatedDate 
     ) 
     SELECT 
      'U', @TableName, d.Guid, 'StatusID' 
      , d.StatusID, i.StatusID, @UpdatedBy, @UpdatedDate 
     FROM INSERTED i INNER JOIN DELETED d on i.Guid = d.Guid 
     WHERE 
      (d.StatusID IS NULL AND i.StatusID IS NOT NULL) 
      OR (d.StatusID IS NOT NULL AND i.StatusID IS NULL) 
      OR (d.StatusID <> i.StatusID) 
    END 

任何人都可以提供任何幫助如何解決這與多行工作?我試圖通過添加SELECT 1 FROM INSERTED來解決以下問題,但我仍然收到子查詢錯誤消息。

CREATE TRIGGER [DT].[trg_LogChanges] 
    ON [DT].[NewDetails] 
    FOR UPDATE 
AS 

DECLARE 
    @TableName VARCHAR(100) , 
    @UpdatedDate smalldatetime , 
    @UpdatedBy uniqueidentifier 

SELECT @TableName = 'DT.NewDetails' 

IF EXISTS (SELECT 1 FROM INSERTED i INNER JOIN DELETED d on i.Guid = d.Guid) 

    IF(SELECT ModifiedDate FROM INSERTED) Is Null 
     SET @UpdatedDate = getdate() 
    ELSE 
     SET @UpdatedDate = (SELECT ModifiedDate FROM INSERTED) 

    IF(SELECT ModifiedBy FROM INSERTED) Is Null 
     SET @UpdatedBy = '11111111-1111-1111-1111-111111111111' 
    ELSE 
     SET @UpdatedBy = (SELECT ModifiedBy FROM INSERTED) 


IF UPDATE (StatusID) 
    BEGIN 
     IF EXISTS (SELECT 1 FROM INSERTED i 
        INNER JOIN DELETED d 
         on i.Guid = d.Guid 
        WHERE 
         (d.StatusID IS NULL AND i.StatusID IS NOT NULL) 
         OR (d.StatusID IS NOT NULL AND i.StatusID IS NULL) 
         OR (d.StatusID <> i.StatusID)) 
     BEGIN 
      INSERT INTO DT.LogChanges 
      (
       ChangeType, TableName, RecordGuid, FieldName 
       , OldValue, NewValue, UpdatedBy, UpdatedDate 
      ) 
      SELECT 
       'U', @TableName, d.Guid, 'StatusID' 
       , d.StatusID, i.StatusID, @UpdatedBy, @UpdatedDate 
      FROM INSERTED i INNER JOIN DELETED d on i.Guid = d.Guid 
      WHERE 
       (d.StatusID IS NULL AND i.StatusID IS NOT NULL) 
       OR (d.StatusID IS NOT NULL AND i.StatusID IS NULL) 
       OR (d.StatusID <> i.StatusID) 
     END 
    END 

我已經在網上搜索,但顯然我仍然錯過了正確的方法來做到這一點。任何幫助將不勝感激。

編輯 我與此流程的業務所有者交談過,他們希望忽略多行更新。如果記錄大於0,是否有辦法在整個觸發器中添加IF來忽略它?

謝謝

回答

2

我相信你的條件檢查可以最小化爲CASE語句。好像你可以儘量減少對整個觸發

INSERT INTO DT.LogChanges (ChangeType, TableName, RecordGuid, FieldName, OldValue, NewValue, UpdatedBy, UpdatedDate) 
    SELECT 'U', 'DT.NewDetails', d.Guid, 'StatusID', d.StatusID, i.StatusID, 
CASE WHEN i.ModifiedBy IS NULL THEN GETDATE() ELSE i.ModifiedBy AS ModifiedBy, 
CASE WHEN i.ModifiedDate IS NULL THEN '11111111-1111-1111-1111-111111111111' ELSE i.ModifiedDate AS ModifiedDate 
FROM INSERTED i INNER JOIN DELETED d on i.Guid = d.Guid 
WHERE  (d.StatusID IS NULL AND i.StatusID IS NOT NULL) 
    OR (d.StatusID IS NOT NULL AND i.StatusID IS NULL) 
    OR (d.StatusID <> i.StatusID) 

我沒有時間,以確保語法是完美的,但如果你有一些問題,但我可以協助。

在回答您的編輯,這與做事情很容易地像

IF (SELECT COUNT(*) FROM INSERTED i INNER JOIN DELETED d on i.Guid = d.Guid) = 1 
BEGIN 
PRINT 'Only one update record' 
END