2010-06-23 45 views
2

我有以下觸發:SQL服務器刪除觸發器在同一個表更新多列

CREATE TRIGGER Users_Delete 
    ON Users 
    AFTER DELETE 
AS 
BEGIN 

    SET NOCOUNT ON; 

    -- Patients 
    UPDATE Patients SET ModifiedByID=NULL WHERE ModifiedByID=ID; 
    UPDATE Patients SET CreatedByID=NULL WHERE CreatedByID=ID; 
    UPDATE Patients SET DeletedByID=NULL WHERE DeletedByID=ID; 

END 

我想知道如果有一種方法來「相結合」這三個UPDATE語句到的東西,會像下面:

UPDATE Patients SET 
(ModifiedByID=NULL WHERE ModifiedByID=ID) OR 
(CreatedByID=NULL WHERE CreatedByID=ID) OR 
(DeletedByID=NULL WHERE DeletedByID=ID); 

我真的很想只有一個聲明來提高性能。

我使用的觸發而不是在ON DELETEFOREIGN KEY的原因是因爲我得到的是有一個以上的ON DELETE導致以下錯誤的錯誤:

Introducing FOREIGN KEY constraint 'FK_Patients_Users_Deleted' on table 'Patients' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

編輯:那會是不錯的在所有ModifiedByID,CreatedByID,DeletedByID列上都有索引?刪除用戶當然很少見,那麼值得向3列添加索引值得嗎?

+2

令我困擾的是,你正在改變這些數據。最好使用戶失效,而不是刪除與其相關聯的子記錄的用戶。現在,您將無法分辨是誰創建了這個記錄,這可能是非常重要的,特別是當用戶因性能原因而被解僱時。 – HLGEM 2010-06-23 17:21:47

+0

這實際上是一個非常有效的點。我將考慮這一點。 – TheCloudlessSky 2010-06-28 00:04:06

回答

1

是這樣的嗎?

UPDATE Patients SET 
ModifiedByID = CASE WHEN ModifiedByID=ID THEN Null ELSE ModifiedById END, 
CreatedByID = CASE WHEN CreatedByID=ID THEN Null ELSE CreatedById END, 
DeletedByID = CASE WHEN DeletedByID=ID THEN Null ELSE DeletedById END 
WHERE (ModifiedByID = ID OR CreatedByID = ID OR DeletedByID = ID) 
+0

我想你會看到性能增加的唯一情況是如果患者表非常大,並且您沒有對ModifiedByID,CreatedByID或DeletedByID的正確索引。在這種情況下,解決方案是添加索引 – Yellowfog 2010-06-23 16:07:56

+0

因此,您認爲最好像使用ModifiedByID/CreatedByID/DeletedByID上的索引那樣使用3條語句? – TheCloudlessSky 2010-06-23 16:10:13

+0

我強烈懷疑它會產生很小的差異,所以我會選擇一個更容易理解的(即三條語句) – Yellowfog 2010-06-23 16:23:11

1

您可以在一個聲明中執行此操作,但這不一定對性能更好。

UPDATE 
    Patients 
SET 
    ModifiedByID = CASE WHEN ModifiedID = ID THEN NULL ELSE ModifiedID, 
    CreatedByID = CASE WHEN CreatedByID = ID THEN NULL ELSE CreatedByID, 
    DeletedByID = CASE WHEN DeletedByID = ID THEN NULL ELSE DeletedByID 

我真的懷疑這會表現更好,但。

2

關於你原來的問題。

不是。我不能拿出任何比

UPDATE Patients 
SET ModifiedByID= CASE WHEN ModifiedByID=ID THEN NULL ELSE ModifiedByID END, 
CreatedByID= CASE WHEN CreatedByID=ID THEN NULL ELSE CreatedByID END, 
DeletedByID= CASE WHEN DeletedByID=ID THEN NULL ELSE DeletedByID END 
WHERE 
ModifiedByID IN (SELECT ID FROM DELETED) 
OR 
CreatedByID IN (SELECT ID FROM DELETED) 
OR 
DeletedByID IN (SELECT ID FROM DELETED) 

請注意,這處理多行刪除正確。目前還不清楚你發佈的內容是否是你目前的觸發器。

+0

重要的一點是,許多人在單行記錄中編碼並因多行動作而失敗。 – 2010-06-23 17:16:26