这适用于Microsoft SQL Server 2008。
我有两个表,Employee和EmployeeResult,我正在尝试在EmployeeResult上编写一个简单的INSERT触发器来执行此操作 - 每次INSERT都在EmployeeResult中完成,例如:
(杰克,200,销售) (简,300,市场营销) (John,400,Engineering)
它应该查找Name,Department条目对,例如
(杰克,销售), (Jane,Marketing), (John,Engineering)
在Employee表中,如果这样的员工不存在,应该将其插入到Employee表中。
我所拥有的是关于如何修复“???”的未知数:
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)
答案 0 :(得分:64)
您希望利用触发器上下文中可用的插入逻辑表。它与正在插入的表格的架构相匹配,并包含将要插入的行(在更新触发器中,您可以访问插入和已删除逻辑表分别代表新数据和原始数据。)
因此,要插入当前不存在的Employee / Department对,您可以尝试以下内容。
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
答案 1 :(得分:26)
cmsjr有正确的解决方案。我只是想为你未来的触发器开发指出一些事情。如果您在触发器的插入中使用values语句,那么您可能会犯错误。对于插入,删除或更新的每批记录,触发一次触发。因此,如果在一个批次中插入十个记录,则触发器会触发一次。如果要引用插入或删除的数据并使用变量和values子句,那么您将只获取其中一条记录的数据。这会导致数据完整性问题。您可以通过使用基于集合的插入来解决此问题,如上面显示的cmsjr或使用游标。不要选择光标路径。触发器中的光标是一个等待发生的问题,因为它们很慢并且可能会将您的表锁定几个小时。我从触发器中删除了一次光标,并将导入过程从40分钟改为45秒。
您可能认为没有人会添加多条记录,但它比大多数非数据库人员意识到的更频繁。不要编写在所有可能的插入,更新,删除条件下都不起作用的触发器。当他们必须从新客户导入1,000,000个销售目标记录或将所有价格更新10%或删除其产品不再销售的供应商的所有记录时,没有人会一次使用一个记录方法。
答案 2 :(得分: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