2012-03-28 4 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

ответ

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 

EDIT

Так я узнал, что происходит. Если вы вставляете все строки за один раз, то 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

Я пробовал, чтобы это не работало. –

+0

ОК. в чем проблема? – Arion

+0

все еще получает все строки из 'mytable' в' mytable_backup' –

1

Ваш исходный код имеет два недостатка:

  1. Он предполагает, что только одна запись вставляется в то время.

  2. Ваша вставка в mytable_backup происходит за пределами условия if. Эта вставка будет выполняться каждый раз.

Смежные вопросы