2009-07-15 53 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

您可以禁用触发器,您插入更新一个更新语句中的字段,然后重新启用触发器。