2017-07-07 32 views
0

我有這樣的一個表:如何使用條件觸發SQL Server中更新

---------------table1-------------------------------------------- 
    id | name | lname | displayStatus | delStatus 
    1   a   b    1    0 
    2   aa  bb    0    0 
    3   aaa  bbb    1    0 
    4   aaaa  bbbb   0    1 

---------------tbl_LOG-------------------------------------------- 
    id | rowData| actType 

和我有這個觸發更新:

alter trigger tgr_delete 
on table1 
after update 
as 
begin 
    declare @rowData nvarchar(max), @username nvarchar(50) 

    if update(delStatus) 
    begin 
     if((select delStatus from inserted) = 1) 
     begin 
      set @rowData = (select CAST((CAST(id as nvarchar(12)) + ' | ' + name) as nvarchar(max)) from inserted) 

      exec sp_insert_LOG 'table1', @rowData, 2 
     end 
     else if((select delStatus from inserted) = 0) 
     begin 
      set @rowData = (select CAST((CAST(id as nvarchar(12)) + ' | ' + name) as nvarchar(max)) from inserted) 

      exec sp_insert_LOG 'table1', @rowData, 3 
     end 
    end 
    else if update(displayStatus) 
    begin 
     if((delStatus = 0 or delStatus is null) and (select displayStatus from inserted) = 0) 
     begin 
      set @rowData = (select CAST((CAST(id as nvarchar(12)) + ' | ' + name) as nvarchar(max)) from inserted) 

      exec sp_insert_LOG 'table1', @rowData, 4 
     end 
     else if((delStatus = 0 or delStatus is null) and (select displayStatus from inserted) = 1) 
     begin 
      set @rowData = (select CAST((CAST(id as nvarchar(12)) + ' | ' + name) as nvarchar(max)) from inserted) 

      exec sp_insert_LOG 'table1', @rowData, 5 
     end 
    end 
end 

和我有3個存儲過程

  • 第一個用於更新delStatus
  • 第二個用於更新displaySt的ATU
  • ,三是更新所有列

現在我應該怎麼做,以避免與前兩個條件的干擾。

+0

只需檢查我是否理解問題 - 只有當delStatus或displayStatus被更改時,您才希望觸發器工作,但是如果它們一起更改或者其他列也更改了,則不會觸發。 –

+0

是的。我要這個。 –

+0

SQL語句中的觸發器不是每行都有效。如果你曾經在你的table1上運行多行更新語句,它將會失敗。通過使用主鍵上的內部連接(在這種情況下假設爲id)比較刪除和插入之間的值,可以檢查哪些列已更改。 –

回答

0

這不是一個完整的答案,因爲我不知道該怎麼做sp_insert_LOG,但它應該讓你開始朝着正確的方向:

CREATE TRIGGER trg_Table1_Update ON Table1 
FOR UPDATE 
AS 


DECLARE @LogData AS TABLE 
(
    TableName sysname, 
    RowData nvarchar(max), 
    ActionType int 
) 

INSERT INTO @LogData (TableName, RowData, ActionType) 
SELECT 'Table1', 
     CAST((CAST(id as nvarchar(12)) + ' | ' + name) as nvarchar(max)), 
     CASE WHEN i.delStatus = 1 THEN 2 
      WHEN i.delStatus = 0 THEN 3 
      WHEN ISNULL(i.delStatus, 0) = 0 AND i.displayStatus = 0 THEN 4 
      WHEN ISNULL(i.delStatus, 0) = 0 AND i.displayStatus = 1 THEN 5 
     END 
FROM INSERTED i 
INNER JOIN Deleted d ON i.Id = d.Id 
WHERE (i.name = d.name OR i.name IS NULL and d.name IS NULL) 
AND (i.lname = d.lname OR i.lname IS NULL and d.lname IS NULL) 
AND 
(
(
    ISNULL(i.delStatus, 0) <> ISNULL(d.delStatus, 0) 
    AND ISNULL(i.displayStatus, 0) = ISNULL(d.displayStatus, 0) 
) 
OR 
(
    ISNULL(i.delStatus, 0) = ISNULL(d.delStatus, 0) 
    AND ISNULL(i.displayStatus, 0) <> ISNULL(d.displayStatus, 0) 
) 
) 

在這一點上,@LogData表包含任何數據你會發送到sp_insert_LOG。我建議創建一個新的存儲過程,如sp_insert_log,它將接受一個表值參數並處理這些數據。