2009-08-31 53 views
15

这是与Microsoft SQL Server 2008SQL Server 2008中 - 帮助编写简单的INSERT触发器

我有2个表,员工和EmployeeResult,我想写一个简单的INSERT触发器上EmployeeResult做这个 - 每一个INSERT完成到EmployeeResult如时间:

(杰克,200,销售部) (简,300,市场营销) (约翰,400工程)

应该查找的名称,部门条目对,如

(杰克,销售), (简,市场营销), (约翰工程)

Employee表内,如果这样的员工不存在,应该插入到Employee表。

我所拥有的,这是关于如何修复 “???” S未知数:

CREATE TRIGGER trig_Update_Employee 
ON [EmployeeResult] 
FOR INSERT 
AS 
IF EXISTS (SELECT COUNT(*) FROM Employee WHERE ???) 
    BEGIN 
    INSERT INTO [Employee] (Name, Department) VALUES (???, ???) 
    END 

请帮帮忙,谢谢提前

模式:

Employee 
-------- 
Name, varchar(50) 
Department, varchar (50) 

EmployeeResult 
-------------- 
Name, varchar(50) 
Salary, int 
Department, varchar (50) 

回答

58

你想要利用插入的逻辑表,该逻辑表在触发器的上下文中可用。它与要插入的表的模式匹配,并且包含将要插入的行(在更新触发器中,您可以访问插入的已删除表示新数据和原始数据的逻辑表)

因此,要插入当前不存在的员工/部门对,您可以尝试如下所示。

CREATE TRIGGER trig_Update_Employee 
ON [EmployeeResult] 
FOR INSERT 
AS 
Begin 
    Insert into Employee (Name, Department) 
    Select Distinct i.Name, i.Department 
    from Inserted i 
    Left Join Employee e 
    on i.Name = e.Name and i.Department = e.Department 
    where e.Name is null 
End 
23

cmsjr有正确的解决方案。我只是想指出一些事情为您未来的触发器开发。如果你在触发器的insert中使用values语句,那么你很可能会做错误的事情。对于插入,删除或更新的每批记录,触发器会触发一次。因此,如果在一批中插入十条记录,则触发器会触发一次。如果您正在引用已插入或已删除的变量以及values子句中的数据,那么您只能获取其中一条记录的数据。这会导致数据完整性问题。您可以通过使用基于集合的插入来解决此问题,如上面显示的cmsjr或使用游标。永远不要选择光标路径。触发器中的光标是一个等待发生的问题,因为它们很慢,可能会将桌子锁定几个小时。我从触发器中删除了一次游标,并将导入过程从40分钟改进为45秒。

您可能认为没有人会添加多个记录,但它比大多数非数据库人员意识到的更频繁。不要编写在所有可能的插入,更新,删除条件下都不起作用的触发器。当他们不得不从一个新客户导入1,000,000个销售目标记录或者将所有价格更新10%或删除一个不再销售产品的供应商的所有记录时,没有人会按时间使用该记录。

+1

+1:额外的细节是有益的。 – 2011-09-07 15:27:20

2

检查验证码:

CREATE TRIGGER trig_Update_Employee ON [EmployeeResult] FOR INSERT AS Begin 
    Insert into Employee (Name, Department) 
    Select Distinct i.Name, i.Department 
     from Inserted i 
     Left Join Employee e on i.Name = e.Name and i.Department = e.Department 
     where e.Name is null 
End