Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Триггер. хочу перехватить изменение поля и поставить своё значение.  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 834
Добрый день.
Хочу перехватить изменение поля одной из таблиц и подставить своё значение этого поля при некоторых условиях. делаю так :
ALTER trigger [SPK_ZAK_HEAD_PLAN_TO_WORK]
  on [dbo].[ZAK_HEAD]
  for UPDATE
as

begin
declare @nSTATE numeric (18,0)--код статуса запланирован
set @nSTATE = 53380772

if update( ID_STATE) /* Если обновляется статус ID_STATE, 
а менеджер заказа ещё не Технолог, тогда статус ID_STATE делаем запланирован */
begin


 update H
    set H.ID_STATE = @nSTATE
    from
        ZAK_HEAD H
   join inserted i     on H.UNZ = i.UNZ 
   
 where not H.M_CODE in ('4','5','6','7','36','51','8','2','20','30')  -- если менеджеры технологи.
and i.ID_STATE<>1144440
  
end   
end
а вопрос такой : произойдёт ли зацикливание или нет ?
26 окт 09, 16:39    [7839916]     Ответить | Цитировать Сообщить модератору
 Re: Триггер. хочу перехватить изменение поля и поставить своё значение.  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381

> а вопрос такой : произойдёт ли зацикливание или нет ?

http://msdn.microsoft.com/ru-ru/library/ms190739.aspx

update( ID_STATE) проверяет всего лишь наличие столбца в секции set оператора update.
т.е. для такого, например, случая
set ID_STATE = ID_STATE
update( ID_STATE) выдаст истину.

Posted via ActualForum NNTP Server 1.4

26 окт 09, 16:48    [7839994]     Ответить | Цитировать Сообщить модератору
 Re: Триггер. хочу перехватить изменение поля и поставить своё значение.  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 834
daw

update( ID_STATE) проверяет всего лишь наличие столбца в секции set оператора update.
т.е. для такого, например, случая
set ID_STATE = ID_STATE
update( ID_STATE) выдаст истину.


то есть если происходит реальная смена значения то есть меняется значение столбца ID_STATE с значения id_state1 на значение id_state2 , где id_state1<>id_state2 то срабатыавет условие
if update( ID_STATE)

верно понял ?
26 окт 09, 18:16    [7840581]     Ответить | Цитировать Сообщить модератору
 Re: Триггер. хочу перехватить изменение поля и поставить своё значение.  [new]
Glory
Member

Откуда:
Сообщений: 104760
andron81
daw

update( ID_STATE) проверяет всего лишь наличие столбца в секции set оператора update.
т.е. для такого, например, случая
set ID_STATE = ID_STATE
update( ID_STATE) выдаст истину.


то есть если происходит реальная смена значения то есть меняется значение столбца ID_STATE с значения id_state1 на значение id_state2 , где id_state1<>id_state2 то срабатыавет условие
if update( ID_STATE)

верно понял ?

Как раз наоборот.
update( ID_STATE) вернет истинно в любом случае, когда имеется set ID_STATE. Независимо от того, какое значение вы присваиваете столбцу
26 окт 09, 18:28    [7840625]     Ответить | Цитировать Сообщить модератору
 Re: Триггер. хочу перехватить изменение поля и поставить своё значение.  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 834
так, вышеуказанная ссылка у меня почему - то не работает (не хочу разбираться пока почему)

но у других работает. из ссылки я вычитал :

"Если вложенные триггеры разрешены и триггер в цепочке начинает бесконечный цикл, это превышает предел уровней вложенности и триггер завершается."

получаеться , что всё же вызываю бесконечный цикл, и он завершается , верно ?
26 окт 09, 18:35    [7840666]     Ответить | Цитировать Сообщить модератору
 Re: Триггер. хочу перехватить изменение поля и поставить своё значение.  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 834
up
27 окт 09, 09:51    [7842160]     Ответить | Цитировать Сообщить модератору
 Re: Триггер. хочу перехватить изменение поля и поставить своё значение.  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
andron81,

если апдейтить только изменившиеся поля, то никакого зацикливания не будет,
если в начале триггера проверять @@ROWCOUNT на >0.
Ибо уже на втором уровне вложенности окажется, что @@ROWCOUNT=0.
Но беда ещё и в том, что Вы не проверяете поля на изменение, о чём Вам уже сказали.
27 окт 09, 09:58    [7842215]     Ответить | Цитировать Сообщить модератору
 Re: Триггер. хочу перехватить изменение поля и поставить своё значение.  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381

> получаеться , что всё же вызываю бесконечный цикл, и он завершается ,
> верно ?

если разрешены вложенные триггеры в бд (по умолчанию - разрешены) и
рекурсия триггеров на сервере (по умолчанию - запрещена).
еще про функцию TRIGGER_NESTLEVEL в документации посмотрите.

Posted via ActualForum NNTP Server 1.4

27 окт 09, 09:59    [7842223]     Ответить | Цитировать Сообщить модератору
 Re: Триггер. хочу перехватить изменение поля и поставить своё значение.  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 834
так , а тогда такой вопрос, а если оформить тело триггера следующим образом:
ALTER trigger [SPK_ZAK_HEAD_PLAN_TO_WORK]
  on [dbo].[ZAK_HEAD]
  for UPDATE
as

begin
declare @nSTATE numeric (18,0)--код статуса запланирован
set @nSTATE = 53380772

if update( ID_STATE) /* Если обновляется статус ID_STATE, 
а менеджер заказа ещё не Технолог, тогда статус ID_STATE делаем запланирован */
begin


 update H
    set H.ID_STATE = @nSTATE
    from
        ZAK_HEAD H
   join inserted i     on H.UNZ = i.UNZ 
   
 where not H.M_CODE in ('4','5','6','7','36','51','8','2','20','30')  -- если менеджеры технологи.
and i.ID_STATE<>1144440 and i.ID_STATE<>@nSTATE 
  
end   
end



то есть, если добавить ещё одно условие в where : i.ID_STATE<>@nSTATE поможет ?

от чего вышеподсказанная майкрософтская ссылка может не работать ? не работает только у меня ((((((((((((((((
27 окт 09, 20:59    [7846681]     Ответить | Цитировать Сообщить модератору
 Re: Триггер. хочу перехватить изменение поля и поставить своё значение.  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 834
iap
andron81,

если апдейтить только изменившиеся поля, то никакого зацикливания не будет,
если в начале триггера проверять @@ROWCOUNT на >0.
Ибо уже на втором уровне вложенности окажется, что @@ROWCOUNT=0.
Но беда ещё и в том, что Вы не проверяете поля на изменение, о чём Вам уже сказали.


да, не врубился в возможности Update(field_name). Я полагал , что возвращает данная функция истину если изменяется поле field_name в противном случае ложь
ссылки на MSDN работают. (((((((
27 окт 09, 21:07    [7846691]     Ответить | Цитировать Сообщить модератору
 Re: Триггер. хочу перехватить изменение поля и поставить своё значение.  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 834
ссылки на MSDN не работают - хотел написать. опечатка
27 окт 09, 21:09    [7846695]     Ответить | Цитировать Сообщить модератору
 Re: Триггер. хочу перехватить изменение поля и поставить своё значение.  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
andron81,

если инет-ссылка не работает, то мало ли что еще не так

ЗЫ. Так говорите модель тригеров от MS - самая правильная? ;)
27 окт 09, 21:10    [7846697]     Ответить | Цитировать Сообщить модератору
 Re: Триггер. хочу перехватить изменение поля и поставить своё значение.  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 834
Senya_L
andron81,

если инет-ссылка не работает, то мало ли что еще не так

ЗЫ. Так говорите модель тригеров от MS - самая правильная? ;)


слушайте не начинайте плиз, я тут не развлекаюсь. для обхаивания всевозможных моделей от MS создавайте другую тему !
27 окт 09, 21:13    [7846706]     Ответить | Цитировать Сообщить модератору
 Re: Триггер. хочу перехватить изменение поля и поставить своё значение.  [new]
Senya_L
Member

Откуда: Москва
Сообщений: 5381
andron81
Senya_L
andron81,

если инет-ссылка не работает, то мало ли что еще не так

ЗЫ. Так говорите модель тригеров от MS - самая правильная? ;)


слушайте не начинайте плиз, я тут не развлекаюсь. для обхаивания всевозможных моделей от MS создавайте другую тему !
Да я и не начинаю. Но в том то и фокус, что код одного триггера ничего не скажет о его работоспособности. Имеет значение какие еще триггеры есть на таблице
27 окт 09, 21:49    [7846796]     Ответить | Цитировать Сообщить модератору
 Re: Триггер. хочу перехватить изменение поля и поставить своё значение.  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
andron81,

свяжите в триггере таблицы deleted и inserted по PRIMARY KEY
с дополнительным условием deleted.ID_STATE<>inserted.ID_STATE.
ПроUPDATEтите ZAK_HEAD из этой связки.

Если ID_STATE может принимать значение NULL, то сравнение придётся усложнить.
27 окт 09, 22:00    [7846820]     Ответить | Цитировать Сообщить модератору
 Re: Триггер. хочу перехватить изменение поля и поставить своё значение.  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 834
Senya_L

Да я и не начинаю.


ок.

Senya_L


Но в том то и фокус, что код одного триггера ничего не скажет о его работоспособности. Имеет значение какие еще триггеры есть на таблице


да триггеры ещё есть.

но вот что интересно, ошибки при выполнении триггера не возникает. и ещё решил поэкспериментировать. создал табличку SPK_TMP с полем VALUE и в неё записывал значение 'ку-ку' при срабатывании всё того же условия if update( ID_STATE)
, то есть код получился такой :
ALTER trigger [SPK_ZAK_HEAD_PLAN_TO_WORK]
  on [dbo].[ZAK_HEAD]
  for UPDATE
as

begin
declare @nSTATE numeric (18,0)--код статуса запланирован
set @nSTATE = 53380772

if update( ID_STATE) /* Если обновляется статус ID_STATE, 
а менеджер заказа ещё не Технолог, тогда статус ID_STATE делаем запланирован */
begin

Insert into SPK_TMP (DETAIL ) VALUES ('ку-ку')
 update H
    set H.ID_STATE = @nSTATE
    from
        ZAK_HEAD H
   join inserted i     on H.UNZ = i.UNZ 
   
 where not H.M_CODE in ('4','5','6','7','36','51','8','2','20','30')  -- если менеджеры технологи.
and i.ID_STATE<>1144440
  
end   
end
после выполнения триггера в таблице SPK_TMP одна запись. значит всё-таки срабатыавет один раз, а по идее должно быть всё же зацикливание, ведь все условия для этого выполняются
28 окт 09, 15:11    [7850632]     Ответить | Цитировать Сообщить модератору
 Re: Триггер. хочу перехватить изменение поля и поставить своё значение.  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
andron81,

значит, у Вас запрещены либо вложенные, либо рекурсивные триггеры. Или и то, и другое.
28 окт 09, 15:15    [7850673]     Ответить | Цитировать Сообщить модератору
 Re: Триггер. хочу перехватить изменение поля и поставить своё значение.  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 834
iap
andron81,

значит, у Вас запрещены либо вложенные, либо рекурсивные триггеры. Или и то, и другое.


как мне проверить эти параметры ?
28 окт 09, 15:33    [7850851]     Ответить | Цитировать Сообщить модератору
 Re: Триггер. хочу перехватить изменение поля и поставить своё значение.  [new]
Glory
Member

Откуда:
Сообщений: 104760
andron81
iap
andron81,

значит, у Вас запрещены либо вложенные, либо рекурсивные триггеры. Или и то, и другое.


как мне проверить эти параметры ?

Читать в статье CREATE TRIGGER параграфы
Recursive Triggers
Nested Triggers
28 окт 09, 15:37    [7850884]     Ответить | Цитировать Сообщить модератору
 Re: Триггер. хочу перехватить изменение поля и поставить своё значение.  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
andron81
iap
andron81,

значит, у Вас запрещены либо вложенные, либо рекурсивные триггеры. Или и то, и другое.


как мне проверить эти параметры ?
SELECT DATABASEPROPERTYEX(N'ИмяБД','IsRecursiveTriggersEnabled ');
EXECUTE sp_configure @configname='nested triggers';
28 окт 09, 16:04    [7851148]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить