在SQL Server中为视图创建触发器的区别

时间:2015-04-29 08:35:40

标签: sql-server triggers sql-server-2012

我正在使用SQL Server 2012。

视图定义是:

create view dbo.emp
as
   select 
       e.eid, e.enm, p.fnm, p.lnm 
   from 
       employee e 
   inner join 
       person p on e.eid = p.id
go

第一个触发器定义是:

CREATE trigger emptrgg on emp
instead of insert 
as
begin 
    insert into person(id, fnm, lnm)
       select 
           id, fnm, lnm 
       from inserted

    insert into employee(eid, enm)
       select 
           eid, enm 
       from inserted
end

触发器#2(与触发器#1相同,但值通过参数插入)

CREATE TRIGGER emptrgg
ON emp
INSTEAD OF INSERT
AS
BEGIN
     DECLARE @ID INT, @FName NVARCHAR(25), @LName NVARCHAR(25), @PID INT,
@EmNum NVARCHAR(15)

     SELECT @ID = eid, @FName =fnm, @LName = lnm
     FROM inserted

     INSERT INTO Person(Id, fnm, lnm)
     VALUES(@ID, @FName, @LName)

     INSERT INTO Employee(eid, enm)
     VALUES(@PID, @ENum)
 end

以上哪项有效或性能良好?

我无法找到,你能帮我解决这个问题吗?

的问候, 奇奥。

1 个答案:

答案 0 :(得分:4)

您的触发器#2有一个 MAJOR 缺陷,因为您认为它将被称为每行一次 - 这是的情况。

触发器会在每个语句时触发,因此,如果您的INSERT语句影响25行,您将触发一次触发,但随后Inserted伪表将包含25行。

您的代码会在这里选择25行中的哪一行?

SELECT @ID = eid, @FName = fnm, @LName = lnm 
FROM inserted

这是非确定性的 - 你将获得一个任意行而忽略所有其他24行。

仅使用触发器#1 它使用正确的基于集合的方法一次处理多个插入的行。而且由于它是基于集合的,因此它也非常适合性能。