SQL Server 2008 - 帮助编写简单的INSERT触发器

Ano*_*ard 23 sql triggers insert sql-server-2008

这是Microsoft SQL Server 2008.

我有2个表,Employee和EmployeeResult,我正在尝试在EmployeeResult上编写一个简单的INSERT触发器来执行此操作 - 每次在EmployeeResult中执行INSERT,例如:

(Jack,200,Sales)(Jane,300,Marketing)(John,400,Engineering)

它应该查找Name,Department条目对,例如

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

在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
Run Code Online (Sandbox Code Playgroud)

请提前帮助,谢谢

架构:

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

EmployeeResult
--------------
Name, varchar(50)
Salary, int
Department, varchar (50)
Run Code Online (Sandbox Code Playgroud)

cms*_*sjr 67

您希望利用触发器上下文中可用的插入逻辑表.它匹配要插入的表的模式,并包括将要插入的行(在更新触发器中,您可以访问分别表示新数据和原始数据的插入已删除逻辑表.)

因此,要插入当前不存在的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
Run Code Online (Sandbox Code Playgroud)


HLG*_*GEM 27

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

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