2009-07-15 50 views
0

我們的原始數據庫已經爲人名稱調用了第一個,中間和最後一個。現在我們創建了名爲firstname,middlename和lastname的字段。當我們正在經歷這個轉換時,我創建了一個觸發器,可以在前一個字段接收到更新或插入的任何時候,將數據從第一個名字複製到第一個名字,中間名到中間名,最後一個名字。問題是當我們將文件批量上傳到我們的數據庫時,它會減慢一切,並可能導致其他事件超時。複製觸發器會顯着減慢數據庫操作的速度

下面是我的代碼:

USE [Database] 
GO 
/****** Object: Trigger [dbo].[CopyFirstName] Script Date: 07/15/2009 08:35:37 ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

ALTER TRIGGER [dbo].[CopyFirstName] 

    ON [dbo].[Patients] 
    AFTER INSERT,UPDATE 
AS 
BEGIN 
-- SET NOCOUNT ON added to prevent extra result sets from 
-- interfering with SELECT statements. 
SET NOCOUNT ON; 

    IF UPDATE([First]) BEGIN 
     SET NOCOUNT ON; 
declare @ChangedField nvarchar(50); 

    select @ChangedField = [First] from inserted 
    update dbo.Patients set FirstName = @ChangedField where [First] = @ChangedField 


END 
end 

難道這是改善或做另一種方式?

回答

5

的幾點思考:

  • 如果你有每一個觸發第一,中間和最後的話,我想你有3個觸發器,在「插入」表3次掃描和3個更新

  • 您當前的代碼不支持多行更新或插入

  • 通過使用「...where [First] = @ChangedField」那麼,如果你很可能會被更新多行。假設你輸入了「John」或「Hans」。雖然約翰或漢斯是正確的,但你仍然用約翰或漢斯更新每一行。而忽略了其他行插入(見前面的點)

選項:

  • 合併成一個觸發
  • 更新只更改的行
  • 添加過濾器用於舊/新列的差異
  • 減少工作(例如,爲所有列結合一條語句)
你能做什麼3210

例子:

ALTER TRIGGER [dbo].[CopyNames] 
    ON [dbo].[Patients] 
    AFTER INSERT,UPDATE 
AS 
BEGIN 
SET NOCOUNT ON; 

IF NOT EXISTS (SELECT * FROM INSERTED) 
    RETURN; 

IF UPDATE(First) OR UPDATE(Middle) OR UPDATE (Last) 
    update 
     P 
    set 
     FirstName = INS.First, 
     Middlename = INS.Middle, 
     LastName = INS.Last 
    FROM 
     dbo.Patients P 
     JOIN 
     INSERTED INS ON P.KeyColumn = INS.KeyColumn 
/* optional, try it and see 
    WHERE 
     P.FirstName <> INS.First OR 
     P.Middlename <> INS.Middle OR 
     P.LastName <> INS.Last 
*/ 


END 
+0

這與事實一起工作太棒了,我們改變了批處理過程包括更新這兩個記錄,當它運行(多數民衆贊成在where子句進來非常方便) 謝謝 – Sean 2009-07-16 14:15:47

0

您可以禁用觸發器,您插入更新一個更新語句中的字段,然後重新啓用觸發器。