2012-03-28 43 views
1
IF EXISTS (SELECT name FROM sysobjects WHERE name = 'myTrigger' AND type = 'TR') 
BEGIN 
    DROP TRIGGER myTrigger 
END 
GO 
go 
create trigger myTrigger 
on mytable_backup 
instead of insert 
as 
begin 
    declare @seq int 
    select @seq = seq from inserted 
    if exists (select * from mytable_backup where seq= @seq) begin 
     delete from mytable_backup where [email protected] 
    end 
    insert into mytable_backup 
    select * from inserted 
end 
go 

我写这个触发器来检查,同时插入如果重复seq柱,然后用同样的seq如果seq不退出新seq插入更新上一行。ms sql server中触发问题?

在ssis包中,我使用OLEDB表(Mytable)作为源包含。

Name,Age,Seq 
Gauraw,30,1 
Gauraw,31,1 
Kiran,28,3 
Kiran,29,3 
kiran,28,3 
Venkatesh,,4 
Venkatesh,28,4 

现在我加载此表OLEDB目的地(Mytable_backup)作为目标。 我想输出为。

Gauraw,31,1 
kiran,28,3 
Venkatesh,28,4 

但我发现了从Mytable所有记录到Mytable_backup

我的触发器有什么问题吗?

+7

与大多数SQL操作一样,触发器在集上操作。你们假设一次只插入一行。这并不是一个好兆头。 – HABO 2012-03-28 12:19:23

回答

1

我认为这个触发器会把第一行和现有的比较。如果我理解你想做的事,你可以退出什么容易做到这一点:

IF EXISTS (SELECT name FROM sysobjects WHERE name = 'myTrigger' AND type = 'TR') 
BEGIN 
    DROP TRIGGER myTrigger 
END 
GO 
go 
create trigger myTrigger 
on mytable_backup 
instead of insert 
as 
begin 
insert into mytable_backup 
select 
    * 
from 
    inserted 
WHERE NOT EXISTS 
    (
     SELECT 
      NULL 
     FROM 
      mytable_backup AS mytable 
     WHERE 
      inserted.seq=mytable.seq 
    ) 
end 
go 

编辑

于是我发现了事情的原委。如果您一次插入所有行,则inserted包含所有行。对不起,我的错误。如果数据中有重复,则示例不会显示要选择的内容。我选择了年龄最大者(不知道你的要求是什么)。下面是测试数据的完整的例子

表结构

CREATE TABLE mytable_backup 
(
    Name VARCHAR(100), 
    Age INT, 
    Seq INT 
) 
GO 

触发

create trigger myTrigger 
on mytable_backup 
instead of insert 
as 
begin 
;WITH CTE 
AS 
(
    SELECT 
     ROW_NUMBER() OVER(PARTITION BY inserted.Seq ORDER BY Age) AS RowNbr, 
     inserted.* 
    FROM 
     inserted 
    WHERE NOT EXISTS 
    (
     SELECT 
      NULL 
     FROM 
      mytable_backup 
     WHERE 
      mytable_backup.Seq=inserted.Seq 
    ) 
) 
insert into mytable_backup(Age,Name,Seq) 
SELECT 
    CTE.Age, 
    CTE.Name, 
    cte.Seq 
FROM 
    CTE 
WHERE 
    CTE.RowNbr=1 
end 
GO 

插入一个更新

INSERT INTO mytable_backup 
VALUES 
    ('Gauraw',30,1), 
    ('Gauraw',31,1), 
    ('Kiran',28,3), 
    ('Kiran',29,3), 
    ('kiran',28,3), 
    ('Venkatesh',20,4), 
    ('Venkatesh',28,4) 

SELECT * FROM mytable_backup 

删除的数据库对象

DROP TRIGGER myTrigger 
DROP TABLE mytable_backup 
+0

我试过这个不行。 – 2012-03-28 12:09:28

+0

好的。问题是什么? – Arion 2012-03-28 12:10:34

+0

仍将所有行从'mytable'变为'mytable_backup' – 2012-03-28 12:12:42

1

你原来的代码有两个缺陷:

  1. 它假定只有一条记录被插入的时间。

  2. 您插入mytable_backup发生在if条件之外。该插入将每次执行。