【问题标题】:issue with trigger in ms sql server?ms sql server 中的触发器有问题吗?
【发布时间】:2012-03-28 11:53:16
【问题描述】:
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 seq=@seq
  end
  insert into mytable_backup
  select * from inserted
end
go

我编写了这个触发器来检查插入时是否重复seq 列,然后使用相同的seq 更新前一行,如果seq 不退出,则使用新的seq 插入它。

在 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

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

【问题讨论】:

  • 触发器,像大多数 SQL 操作一样,对集合进行操作。您的假设一次只插入一行。这不是好兆头。

标签: sql sql-server sql-server-2008 triggers ssis


【解决方案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

【讨论】:

  • 仍然将所有行从mytable 获取到mytable_backup
  • 更新了答案。看看
【解决方案2】:

您的原始代码有两个缺陷:

  1. 假设一次只插入一条记录。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-24
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    • 1970-01-01
    • 1970-01-01
    • 2022-09-22
    • 2011-09-06
    相关资源
    最近更新 更多