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

Откуда: Екатеринбург
Сообщений: 302
Добрый день!

MS SQL SERVER 2012
Странно отрабатывает триггер на update, запуталась совсем

Пример: есть триггер на UPDATE
IF UPDATE (koddolg)  
BEGIN

UPDATE [dbo].[СотрудникиИх] SET [prior] =  [prioritet] 
from [СотрудникиИх] s INNER JOIN inserted i ON s.КодСотрудника = s.КодСотрудника 
INNER JOIN  dolg d ON s.koddolg =  d.kod 

END

IF UPDATE (prior)
BEGIN
UPDATE [dbo].[СотрудникиИх] SET [prior] =  null
from [СотрудникиИх] s INNER JOIN inserted i ON s.КодСотрудника = s.КодСотрудника 
where s.koddolg Is Null

END



так вот выполняются оба update даже если в первом s.koddolg is null, хотя есть связь со справочником

если заменить скрипт на следующий, то всё выполняется как и когда надо, но ведь это лишние подсчёты.
Подскажите, плз, как быть в таких случаях?

IF UPDATE (koddolg)  
BEGIN

IF (select count(КодСотрудника) from inserted where koddolg > 0) > 0
begin
UPDATE [dbo].[СотрудникиИх] SET [prior] =  [prioritet] 
from [СотрудникиИх] s INNER JOIN inserted i ON s.КодСотрудника = s.КодСотрудника 
INNER JOIN  dolg d ON s.koddolg =  d.kod 
end

IF (select count(КодСотрудника) from inserted where koddolg IS NULL or koddolg = 0) > 0
BEGIN
UPDATE [dbo].[СотрудникиИх] SET [prior] =  null
from [СотрудникиИх] s INNER JOIN inserted i ON s.КодСотрудника = s.КодСотрудника 
where s.koddolg Is Null
END
10 июн 16, 13:54    [19280510]     Ответить | Цитировать Сообщить модератору
 Re: Срочно нужна ужна помощь разобраться с триггером  [new]
Konst_One
Member

Откуда:
Сообщений: 11538
ON s.КодСотрудника = s.КодСотрудника


?
10 июн 16, 14:01    [19280577]     Ответить | Цитировать Сообщить модератору
 Re: Срочно нужна ужна помощь разобраться с триггером  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37050
update(поле) возвращает true, если поле было указано в тексте запроса. Хотите, чтобы работали разные ветки, пишите правильные запросы update.
10 июн 16, 14:07    [19280630]     Ответить | Цитировать Сообщить модератору
 Re: Срочно нужна ужна помощь разобраться с триггером  [new]
ElenaLeont
Member

Откуда: Екатеринбург
Сообщений: 302
Спасибо огромное)))))))
10 июн 16, 14:07    [19280631]     Ответить | Цитировать Сообщить модератору
 Re: Срочно нужна ужна помощь разобраться с триггером  [new]
ElenaLeont
Member

Откуда: Екатеринбург
Сообщений: 302
Гавриленко Сергей Алексеевич, очень прошу привести пример как правильно нужно было
10 июн 16, 14:15    [19280668]     Ответить | Цитировать Сообщить модератору
 Re: Срочно нужна ужна помощь разобраться с триггером  [new]
Konst_One
Member

Откуда:
Сообщений: 11538
одним запросом можно

UPDATE s
SET s.[prior] =  CASE WHEN i.koddolg IS NULL THEN null ELSE d.[prioritet] END
from 
     [СотрудникиИх] s INNER JOIN inserted i ON s.КодСотрудника = i.КодСотрудника 
     LEFT OUTER JOIN  dolg d ON i.koddolg =  d.kod 

если я конечно смысл вашего кода понял правильно
10 июн 16, 14:23    [19280712]     Ответить | Цитировать Сообщить модератору
 Re: Срочно нужна ужна помощь разобраться с триггером  [new]
invm
Member

Откуда: Москва
Сообщений: 9396
UPDATE s
 SET
  [prior] = case
    when update(koddolg) and d.kod is not null then [prioritet]
    when update(prior) and s.koddolg is null then null
    else s.prior
   end
from
 [СотрудникиИх] s INNER JOIN
 inserted i ON s.КодСотрудника = i.КодСотрудника LEFT JOIN
 dolg d ON s.koddolg = d.kod
where
 update(koddolg) or update(prior);
10 июн 16, 14:28    [19280736]     Ответить | Цитировать Сообщить модератору
 Re: Срочно нужна ужна помощь разобраться с триггером  [new]
ElenaLeont
Member

Откуда: Екатеринбург
Сообщений: 302
спасибо сейчас попробую по шагам, будет ли в таком варианте происходить update , если count(*) запроса на Update = 0
10 июн 16, 14:31    [19280757]     Ответить | Цитировать Сообщить модератору
 Re: Срочно нужна ужна помощь разобраться с триггером  [new]
ElenaLeont
Member

Откуда: Екатеринбург
Сообщений: 302
Спасибо, поняла суть)
10 июн 16, 14:56    [19280910]     Ответить | Цитировать Сообщить модератору
 Re: Срочно нужна ужна помощь разобраться с триггером  [new]
ElenaLeont
Member

Откуда: Екатеринбург
Сообщений: 302
Остался ещё вопрос, как правильно сделать если например в триггере на инсерт тоже нужно делать

UPDATE s
 SET
  [prior] = case
    when update(koddolg) and d.kod is not null then [prioritet]
    when update(prior) and s.koddolg is null then null
    else s.prior
   end
from
 [СотрудникиИх] s INNER JOIN
 inserted i ON s.КодСотрудника = i.КодСотрудника LEFT JOIN
 dolg d ON s.koddolg = d.kod


но чтобы избежать, запуска триггер на такой-же update в триггере на апдэйт?
10 июн 16, 16:31    [19281566]     Ответить | Цитировать Сообщить модератору
 Re: Срочно нужна ужна помощь разобраться с триггером  [new]
iap
Member

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

поясните, пожалуйста, зачем здесь нужны update(koddolg) и update(prior)?
Не могли бы здесь привести текст триггеров полностью?
10 июн 16, 16:40    [19281615]     Ответить | Цитировать Сообщить модератору
 Re: Срочно нужна ужна помощь разобраться с триггером  [new]
defragmentator
Member

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

интересует работа коллекторского агентства?
10 июн 16, 16:48    [19281657]     Ответить | Цитировать Сообщить модератору
 Re: Срочно нужна ужна помощь разобраться с триггером  [new]
iap
Member

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

интересует работа коллекторского агентства?
В общем-то, нет.
Заинтриговало утверждение "поняла суть)" :))
10 июн 16, 17:03    [19281727]     Ответить | Цитировать Сообщить модератору
 Re: Срочно нужна ужна помощь разобраться с триггером  [new]
ElenaLeont
Member

Откуда: Екатеринбург
Сообщений: 302
iap, это Copy\Past

не стёрла при копировании

эти два поля нужно Update - ить и на вставку, не понимаю, как сделать, чтобы при апдейте при вставке не сработал затем триггер на апдейт?

сделать один на AFTER INSERT, AFTER UPDATE?
10 июн 16, 19:50    [19282444]     Ответить | Цитировать Сообщить модератору
 Re: Срочно нужна ужна помощь разобраться с триггером  [new]
iap
Member

Откуда: Москва
Сообщений: 46999
ElenaLeont
как сделать, чтобы при апдейте при вставке не сработал затем триггер на апдейт?
Мы про триггер ничего не знаем. Вы же игнорируете мою просьбу.
Например, UPDATE в триггере меняет значения в таблице, к которой привязан триггер, или в какой-то другой?
Если в той же, то:
1. UPDATE надо делать только в случае, если в inserted существует запись.
2. UPDATE надо делать только записи, в которых произошло какое-нибудь изменение в результате UPDATE, на который сработал триггер,
или inserted.koddolg или inserted.prior ещё не равны значениям, которые будет присваивает UPDATE.
В этом случае (если разрешён рекурсивный вызов триггера) второй вложенный вызов будет последним, причём это будет UPDATE 0 строк.

Конкретнее сказать невозможно, имея дело с "чёрным ящиком"
10 июн 16, 21:05    [19282747]     Ответить | Цитировать Сообщить модератору
 Re: Срочно нужна ужна помощь разобраться с триггером  [new]
ElenaLeont
Member

Откуда: Екатеринбург
Сообщений: 302
iap, привожу полный текст триггеров

ALTER TRIGGER [dbo].[Prior_insert]
   ON  [dbo].[СотрудникиИх]
   AFTER INSERT
NOT FOR REPLICATION 
AS 
BEGIN
	SET NOCOUNT ON;
	
	

if (select count(КодСотрудника) from inserted where koddolg > 0) > 0
begin
UPDATE [dbo].[СотрудникиИх] SET [prior] =  [prioritet] 
from [СотрудникиИх] s INNER JOIN inserted i ON s.КодСотрудника = i.КодСотрудника 
INNER JOIN  dolg d ON s.koddolg =  d.kod 
end

END


ALTER TRIGGER [dbo].[SotrUpdate]
   ON  [dbo].[СотрудникиИх]
   AFTER UPDATE
AS 
BEGIN
	
	SET NOCOUNT ON;

UPDATE s
 SET
  [prior] = case 
            when d.kod is not null then d.[prioritet] 
            when s.koddolg is null then null
			else s.prior
            end
from
 [СотрудникиИх] s INNER JOIN
 inserted i ON s.КодСотрудника = i.КодСотрудника LEFT JOIN
 dolg d ON s.koddolg = d.kod
where
 update(koddolg);

 end
11 июн 16, 07:39    [19283330]     Ответить | Цитировать Сообщить модератору
 Re: Срочно нужна ужна помощь разобраться с триггером  [new]
ElenaLeont
Member

Откуда: Екатеринбург
Сообщений: 302
я правильно понимаю, что в моём случае мне нужно запретить в триггере на INSERT рекурсивный вызов или дописать так:

ALTER TRIGGER [dbo].[SotrUpdate]
   ON  [dbo].[СотрудникиИх]
   AFTER UPDATE
AS 
BEGIN
	
	SET NOCOUNT ON;

if (select count(КодСотрудника) from inserted i inner join 
                                     deleted d on i.КодСотрудника = d.КодСотрудника
                                     where i.koddolg <> d.koddolg) > 0
begin
UPDATE s
 SET
  [prior] = case 
            when d.kod is not null then d.[prioritet] 
            when s.koddolg is null then null
			else s.prior
            end
from
 [СотрудникиИх] s INNER JOIN
 inserted i ON s.КодСотрудника = i.КодСотрудника LEFT JOIN
 dolg d ON s.koddolg = d.kod
where
 update(koddolg);

 end

 end
11 июн 16, 07:47    [19283339]     Ответить | Цитировать Сообщить модератору
 Re: Срочно нужна ужна помощь разобраться с триггером  [new]
aleks2
Guest
ALTER TRIGGER [dbo].[Prior_insert]
   ON  [dbo].[СотрудникиИх]
   AFTER INSERT
NOT FOR REPLICATION 
AS 
BEGIN
	SET NOCOUNT ON;
	
	

if exists (select * from inserted where koddolg > 0) begin 
  UPDATE s SET [prior] =  ?.[prioritet] -- надо быть последовательней
     from [СотрудникиИх] s INNER JOIN inserted i ON s.КодСотрудника = i.КодСотрудника 
            INNER JOIN  dolg d ON s.koddolg =  d.kod
     where exists( select [prior] except select  ?.[prioritet] )
end

END


ALTER TRIGGER [dbo].[SotrUpdate]
   ON  [dbo].[СотрудникиИх]
   AFTER UPDATE
AS 
BEGIN
	
SET NOCOUNT ON;

UPDATE s
 SET
  [prior] = case 
                 when d.kod is not null then d.[prioritet] 
                 when s.koddolg is null then null
                 else s.prior
            end
from [СотрудникиИх] s 
       INNER JOIN inserted i ON s.КодСотрудника = i.КодСотрудника 
       LEFT JOIN dolg d ON s.koddolg = d.kod
where  update(koddolg)
   and exists ( select s.[prior] except select case 
                                                              when d.kod is not null then d.[prioritet] 
                                                              when s.koddolg is null then null
                                                              else s.prior
                                                            end
                  )
;

 end
11 июн 16, 07:53    [19283347]     Ответить | Цитировать Сообщить модератору
 Re: Срочно нужна ужна помощь разобраться с триггером  [new]
ElenaLeont
Member

Откуда: Екатеринбург
Сообщений: 302
aleks2,
объясните, плз, зачем
where exists( select [prior] except select  d.[prioritet]  
???
11 июн 16, 08:26    [19283378]     Ответить | Цитировать Сообщить модератору
 Re: Срочно нужна ужна помощь разобраться с триггером  [new]
iap
Member

Откуда: Москва
Сообщений: 46999
ElenaLeont
мне нужно запретить в триггере на INSERT рекурсивный вызов
Рекурсивный вызов можно запретить только для всей базы.
Кстати, по-умолчанию, он запрещён, если я не ошибаюсь.
11 июн 16, 09:45    [19283440]     Ответить | Цитировать Сообщить модератору
 Re: Срочно нужна ужна помощь разобраться с триггером  [new]
iap
Member

Откуда: Москва
Сообщений: 46999
ElenaLeont
aleks2,
объясните, плз, зачем
where exists( select [prior] except select  d.[prioritet]  

???
Чтобы апдейтить только записи, для которых [prior] ещё не равно d.[prioritet].
Вы читаете, что вам пишут? 19282747
11 июн 16, 09:47    [19283442]     Ответить | Цитировать Сообщить модератору
 Re: Срочно нужна ужна помощь разобраться с триггером  [new]
ElenaLeont
Member

Откуда: Екатеринбург
Сообщений: 302
iap, это я уже поняла, что чушт написала, запуталась совсем, на базе стоит false
11 июн 16, 10:37    [19283511]     Ответить | Цитировать Сообщить модератору
 Re: Срочно нужна ужна помощь разобраться с триггером  [new]
ElenaLeont
Member

Откуда: Екатеринбург
Сообщений: 302
iap, спасибо большое, поняла)
11 июн 16, 10:40    [19283516]     Ответить | Цитировать Сообщить модератору
 Re: Срочно нужна ужна помощь разобраться с триггером  [new]
ElenaLeont
Member

Откуда: Екатеринбург
Сообщений: 302
iap
ElenaLeont
aleks2,
объясните, плз, зачем
where exists( select [prior] except select  d.[prioritet]  

???
Чтобы апдейтить только записи, для которых [prior] ещё не равно d.[prioritet].
Вы читаете, что вам пишут? 19282747



iap, я ещё раз хочу уточнить, что правильно поняла синтаксис:

поняла так, что приведенный ниже скрипт1 = скрипту2 в результате

скрипт1

	

  UPDATE s
 SET
  [prior] = case 
                 when d.kod is not null then d.[prioritet] 
                 when s.koddolg is null then null
                 else s.[prior]
            end
from [СотрудникиИх] s 
       INNER JOIN inserted i ON s.КодСотрудника = i.КодСотрудника 
       LEFT JOIN dolg d ON s.koddolg = d.kod
where  update(koddolg)
   and exists ( select s.[prior] except select case 
                                                              when d.kod is not null then d.[prioritet] 
                                                              when s.koddolg is null then null
                                                              else s.[prior]
                                                            end
                  )
end



скрипт2

UPDATE s
 SET
  [prior] = case 
                 when d.kod is not null then d.[prioritet] 
                 when s.koddolg is null then null
                 else s.prior
            end
from [СотрудникиИх] s 
       INNER JOIN inserted i ON s.КодСотрудника = i.КодСотрудника 
       INNER JOIN deleted d ON i.КодСотрудника = d.КодСотрудника 
       LEFT JOIN dolg d ON s.koddolg = d.kod
where  update(koddolg)
   and isnull(i.[prior], 0) <> isnull(d.[prior], 0)
                  )
end
11 июн 16, 10:53    [19283541]     Ответить | Цитировать Сообщить модератору
 Re: Срочно нужна ужна помощь разобраться с триггером  [new]
aleks2
Guest
ElenaLeont
iap
пропущено...
Чтобы апдейтить только записи, для которых [prior] ещё не равно d.[prioritet].
Вы читаете, что вам пишут? 19282747



iap, я ещё раз хочу уточнить, что правильно поняла синтаксис:

поняла так, что приведенный ниже скрипт1 = скрипту2


Нет, не эквивалентен.
У тя, глупенькая, 0 = null.
11 июн 16, 14:57    [19283826]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить