Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Можно ли в триггере(for U,I,D) определить какое действие над табл. вызвало его?  [new]
Алексей
Guest
Можно ли в триггере определить какое действие над таблицей вызвало этот триггер? Я понимаю, что можно написать три триггера(на добавление, редактирование и удаление) , но хочется сделать все в одном триггере.
22 мар 01, 11:37    [4633]     Ответить | Цитировать Сообщить модератору
 Можно  [new]
SergSuper
Guest
create trigger TR on TBL for insert, delete, update
as
declare @i int, @d int
select @i=count(*) from inserted
select @d=count(*) from deleted

select case
when @i<>0 and @d<>0 then 'это триггер на апдейт'
when @i=0 and @d<>0 then 'это триггер на делит'
when @i<>0 and @d=0 then 'это триггер на инсерт'
when @i=0 and @d=0 then 'а не всё ли равно что это за триггер?'
end
22 мар 01, 12:37    [4634]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Можно ли в триггере(for U,I,D) определить какое действие над табл. вызвало его?  [new]
кефаль
Guest
просто из любопытства - ничего с тех пор не изменилось?
только через анализ таблиц?
14 июл 09, 20:13    [7415937]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли в триггере(for U,I,D) определить какое действие над табл. вызвало его?  [new]
Crimean
Member

Откуда:
Сообщений: 13148
а кто-то мешает делать 3 триггера?
14 июл 09, 20:19    [7415959]     Ответить | Цитировать Сообщить модератору
 Re: Можно  [new]
Зайцев Фёдор
Member

Откуда: Лужки
Сообщений: 5308
SergSuper
create trigger TR on TBL for insert, delete, updateasdeclare @i int, @d intselect @i=count(*) from insertedselect @d=count(*) from deletedselect case when @i<>0 and @d<>0 then 'это триггер на апдейт' when @i=0 and @d<>0 then 'это триггер на делит' when @i<>0 and @d=0 then 'это триггер на инсерт' when @i=0 and @d=0 then 'а не всё ли равно что это за триггер?' end

м.б. всё-таки exists ?
14 июл 09, 21:52    [7416206]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли в триггере(for U,I,D) определить какое действие над табл. вызвало его?  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
А можно 4 - три отдельно на DELETE, INSERT, UPDATE для специфической обработки каждого действия,
а ещё один - для общего алгоритма обработки.
SET NOCOUNT ON;
USE tempdb;
IF OBJECT_ID(N'T','U') IS NOT NULL DROP TABLE T;
CREATE TABLE T(ID INT NOT NULL IDENTITY, X INT);
GO
CREATE TRIGGER tdT ON T FOR DELETE AS SET CONTEXT_INFO 0x01;
GO
CREATE TRIGGER tiT ON T FOR INSERT AS SET CONTEXT_INFO 0x02;
GO
CREATE TRIGGER tuT ON T FOR UPDATE AS SET CONTEXT_INFO 0x03;
GO
CREATE TRIGGER tdiuT ON T FOR DELETE, INSERT, UPDATE AS
SELECT CASE CONTEXT_INFO() WHEN 0x01 THEN 'DELETE' WHEN 0x02 THEN 'INSERT' WHEN 0x03 THEN 'UPDATE' END;
GO
EXEC sp_settriggerorder @triggername='tdT', @order='First', @stmttype='DELETE';
EXEC sp_settriggerorder @triggername='tiT', @order='First', @stmttype='INSERT';
EXEC sp_settriggerorder @triggername='tuT', @order='First', @stmttype='UPDATE';
GO
INSERT T(X) SELECT NULL WHERE NULL IS NOT NULL;
INSERT T(X) VALUES(100);
UPDATE T SET X=X WHERE ID IS NULL;
UPDATE T SET X=-1;
DELETE T WHERE ID IS NULL;
DELETE T;
GO
IF OBJECT_ID(N'T','U') IS NOT NULL DROP TABLE T;
GO
14 июл 09, 21:53    [7416213]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли в триггере(for U,I,D) определить какое действие над табл. вызвало его?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Если:
1. Ключи по технологии не могут меняться
2. Нет хитрых Update-ов (не трогающих ни одной колонки) :)
То:
Удаление: Columns_Updated() = 0x при удалении.
Вставка: Update(ID) (где ID - ключ).

Если ничего не путаю. А так ничего не поменялось. Проблем не вижу [LEFT] JOIN всё решает нормально.
15 июл 09, 14:08    [7418852]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли в триггере(for U,I,D) определить какое действие над табл. вызвало его?  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Mnior
Если:
1. Ключи по технологии не могут меняться
2. Нет хитрых Update-ов (не трогающих ни одной колонки) :)
То:
Удаление: Columns_Updated() = 0x при удалении.
Вставка: Update(ID) (где ID - ключ).

Если ничего не путаю. А так ничего не поменялось. Проблем не вижу [LEFT] JOIN всё решает нормально.
Можно посмотреть на пример "хитрого" UPDATE из п.2?

Если же имелись в виду строки, а не колонки, то чем не устраивает
IF EXISTS(SELECT * FROM inserted)
 IF EXISTS(SELECT * FROM deleted)
  PRINT 'UPDATE'
 ELSE
  PRINT 'INSERT'
ELSE
 IF EXISTS(SELECT * FROM deleted)
  PRINT 'DELETE'
 ELSE
  PRINT 'UNKNOWN';
?
15 июл 09, 16:32    [7419952]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли в триггере(for U,I,D) определить какое действие над табл. вызвало его?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
iap
Можно посмотреть на пример "хитрого" UPDATE из п.2?
Как я понимаю, что-то типа:
UPDATE	<Table>
SET	@Variable = <Expression>
WHERE	<Condition>

iap
Если же имелись в виду строки, а не колонки, то чем не устраивает Exist?
Да я не против, просто можно по разному реализовывать, от задачи зависит. Например, Deleted JOIN Inserted пройдёт только для UPDATE и никаких дополнительных IF ставить не надо (везде свои нюансы).
15 июл 09, 19:42    [7421084]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли в триггере(for U,I,D) определить какое действие над табл. вызвало его?  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Mnior
UPDATE	<Table>
SET	@Variable = <Expression>
WHERE	<Condition>
Действительно! Спасибо!
15 июл 09, 19:53    [7421114]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить