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

Откуда: Москва
Сообщений: 47144
Glory
iap
Придётся тогда в своей документации запретить использовать таблицу в команде MERGE.

Почему ?
Это проблема, если в вашем примере MERGE триггер на удаление сработает с пустыми таблицами inserted/deleted ?
Нет, не проблема.
Но @@ROWCOUNT-то равен 3, а не 0
Зачем его тогда вообще использовать?
Разве меня волнует общее количество строк MERGE внутри триггера AFTER DELETE?
19 июн 12, 15:21    [12739247]     Ответить | Цитировать Сообщить модератору
 Re: Триггер  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31983
RubinDm
alexeyvg
2 RubinDm
if (not(exists(select * from [inserted]))

не нужно, обновление и так не будет потреблять ресурсов, если в inserted ничего нет.
Это самый простой и быстрый способ понять, есть ли записи, которые реально были подвергнуты изменениям.
Это всего лишь в 2 раза увеличивает время выполнения триггера, если записи обновляются, и не влияет на скорость, если записей нет.

RubinDm
Это нужно, чтобы как можно быстрее завершить исполнение тригера, если фактически никаких изменений вообще не было.
Если бы там далее делалось много действий, то согласен, но на самом то деле там только инструкция update. Завершиться триггер сразу после update, если if (not(exists нет, или сразу после if (not(exists, если есть - совершенно неважно.
RubinDm
Да, возможно никакие записи в результате update'а не изменятся, но само исполнение команды update состоится, равно как и исполнение соответствующих тригеров, включая наш, который фактически окажется рекурсивным, хоть и не зацикленным.
Ну, разумеется, нужно защититься от рекурсии или запретить енё в триггерах.

В данном случае защита уже есть, её делать не нужно - защитой будет проверка IF UPDATE().
19 июн 12, 15:22    [12739254]     Ответить | Цитировать Сообщить модератору
 Re: Триггер  [new]
Shakill
Member

Откуда: мск
Сообщений: 1887
Glory
iap
@@ROWCOUNT в результате MERGE - это общее количество добавленных, изменённых и удалённых строк.
Например, 5 строк вставлено, 4 изменено и ни одной не удалено.
Однако, сработают все триггеры, и в каждом @@ROWCOUNT=5+4=9

Все равно, на мой взгляд обращение к @@ROWCOUNT выгоднее запросов к inserted/deleted.


iap вроде бы хотел сказать, что при таком раскладе триггер на удаление тоже сработает и там @@ROWCOUNT не будет равен нулю, а вы будете опираться на это значение вместо количества строк в deleted.

ну и плюс может быть несколько триггеров, тогда предыдущие триггеры могут вообще этот @@ROWCOUNT поменять, что убивает смысл проверки вообще
19 июн 12, 15:23    [12739266]     Ответить | Цитировать Сообщить модератору
 Re: Триггер  [new]
RubinDm
Member

Откуда:
Сообщений: 461
iap
...Приведёт к удивительным результатам в MERGE!
RubinDm
... мне непонято Ваше негодование ...
iap
При чём тут негодование?
ок. негодования не было. было удивление. так или иначе, оно мне все-равно непонятно.
iap
И как же порекомендуете интерпретировать MERGE?
Интерпретировать значение @@rowcount после merge следует ровно так, как описано в документации.
19 июн 12, 15:26    [12739308]     Ответить | Цитировать Сообщить модератору
 Re: Триггер  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
Shakill
ну и плюс может быть несколько триггеров, тогда предыдущие триггеры могут вообще этот @@ROWCOUNT поменять, что убивает смысл проверки вообще
Нет. Никакие триггеры @@ROWCOUNT не меняют.
Давно и неоднократно проверено.
19 июн 12, 15:27    [12739315]     Ответить | Цитировать Сообщить модератору
 Re: Триггер  [new]
RubinDm
Member

Откуда:
Сообщений: 461
alexeyvg
... В данном случае защита уже есть, её делать не нужно - защитой будет проверка IF UPDATE().
и её рекомендовали убрать :)
19 июн 12, 15:28    [12739339]     Ответить | Цитировать Сообщить модератору
 Re: Триггер  [new]
Glory
Member

Откуда:
Сообщений: 104751
iap
Но @@ROWCOUNT-то равен 3, а не 0
Зачем его тогда вообще использовать?
Разве меня волнует общее количество строк MERGE внутри триггера AFTER DELETE?

Не понял.
Вопрос был, как быстрее определить, что какие то записи затронуты.Чтобы продолжать или не продолжать выполнение триггера.
А не сколько записей затронуто.
19 июн 12, 15:29    [12739343]     Ответить | Цитировать Сообщить модератору
 Re: Триггер  [new]
RubinDm
Member

Откуда:
Сообщений: 461
iap
Shakill
ну и плюс может быть несколько триггеров, тогда предыдущие триггеры могут вообще этот @@ROWCOUNT поменять, что убивает смысл проверки вообще
Нет. Никакие триггеры @@ROWCOUNT не меняют.
Давно и неоднократно проверено.
+1, тож проверял. и хорошо, что оно работает именно так и никак иначе.
19 июн 12, 15:29    [12739355]     Ответить | Цитировать Сообщить модератору
 Re: Триггер  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
RubinDm
alexeyvg
... В данном случае защита уже есть, её делать не нужно - защитой будет проверка IF UPDATE().
и её рекомендовали убрать :)
Разумеется.
А роль этой защиты может играть проверка различий значений полей в inserted и deleted в кляузе WHERE, например.
19 июн 12, 15:30    [12739361]     Ответить | Цитировать Сообщить модератору
 Re: Триггер  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
Glory
iap
Но @@ROWCOUNT-то равен 3, а не 0
Зачем его тогда вообще использовать?
Разве меня волнует общее количество строк MERGE внутри триггера AFTER DELETE?

Не понял.
Вопрос был, как быстрее определить, что какие то записи затронуты.Чтобы продолжать или не продолжать выполнение триггера.
А не сколько записей затронуто.
Получив значение @@ROWCOUNT=3 в триггере AFTER DELETE, Вы решите, что удаление затронуло 3 записи?
Но на самом деле deleted пуста!
Я имею в виду свой же пример MERGE.
Разве не корректнее писать IF EXISTS(SELECT * FROM deleted)?
И практически без снижения производительности, кстати сказать.
19 июн 12, 15:34    [12739402]     Ответить | Цитировать Сообщить модератору
 Re: Триггер  [new]
RubinDm
Member

Откуда:
Сообщений: 461
Glory
RubinDm
Некоторые и на заправках курить не стесняются. Но даже они в подавляющем большинстве своем творят такое по невнимательности, а не изходя из антисоциальных настроений. И на замечания с указанем пальчиком на знак "курить запрещено" реагируют, как правило, адекватно, и даже оперативно. Вывод: меры предосторожности лишинми не бывают.

Ну так о том и речь.
Ваше способ получения число затронутых командой записей ничуть не стабильнее @@rowcount.
Потому что никак не предотвращает "курение на бензоколонке", т.е. исправление текста триггера
Имхо.
Возможно, Вы правы.
19 июн 12, 15:36    [12739433]     Ответить | Цитировать Сообщить модератору
 Re: Триггер  [new]
Shakill
Member

Откуда: мск
Сообщений: 1887
iap
Shakill
ну и плюс может быть несколько триггеров, тогда предыдущие триггеры могут вообще этот @@ROWCOUNT поменять, что убивает смысл проверки вообще
Нет. Никакие триггеры @@ROWCOUNT не меняют.
Давно и неоднократно проверено.

да, был не прав
19 июн 12, 15:38    [12739456]     Ответить | Цитировать Сообщить модератору
 Re: Триггер  [new]
Glory
Member

Откуда:
Сообщений: 104751
iap
Получив значение @@ROWCOUNT=3 в триггере AFTER DELETE, Вы решите, что удаление затронуло 3 записи?
Но на самом деле deleted пуста!

Да. Это будет проблемой, если триггер не должен или не может корректно обрабатывать пустую таблицу deleted.

iap
Разве не корректнее писать IF EXISTS(SELECT * FROM deleted)?
И практически без снижения производительности, кстати сказать.

Да неужели.
19 июн 12, 15:38    [12739465]     Ответить | Цитировать Сообщить модератору
 Re: Триггер  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
Glory
iap
Получив значение @@ROWCOUNT=3 в триггере AFTER DELETE, Вы решите, что удаление затронуло 3 записи?
Но на самом деле deleted пуста!

Да. Это будет проблемой, если триггер не должен или не может корректно обрабатывать пустую таблицу deleted.

iap
Разве не корректнее писать IF EXISTS(SELECT * FROM deleted)?
И практически без снижения производительности, кстати сказать.

Да неужели.
А что, много времени займёт проверка наличия одной записи в deleted?
19 июн 12, 15:41    [12739497]     Ответить | Цитировать Сообщить модератору
 Re: Триггер  [new]
Xordal
Member

Откуда: Таганрог
Сообщений: 536
iap
Получив значение @@ROWCOUNT=3 в триггере AFTER DELETE, Вы решите, что удаление затронуло 3 записи?
Но на самом деле deleted пуста!
Я имею в виду свой же пример MERGE.
Разве не корректнее писать IF EXISTS(SELECT * FROM deleted)?
И практически без снижения производительности, кстати сказать.

Извините, а разве будет отрабатывать триггер AFTER DELETE если deleted пуста?
19 июн 12, 15:41    [12739508]     Ответить | Цитировать Сообщить модератору
 Re: Триггер  [new]
RubinDm
Member

Откуда:
Сообщений: 461
alexeyvg
RubinDm
пропущено...Это самый простой и быстрый способ понять, есть ли записи, которые реально были подвергнуты изменениям.
Это всего лишь в 2 раза увеличивает время выполнения триггера, если записи обновляются, и не влияет на скорость, если записей нет.
Растолкуйте, каким именно образом данный способ увеличивает время выполнения тригера в 2 раза?
19 июн 12, 15:42    [12739515]     Ответить | Цитировать Сообщить модератору
 Re: Триггер  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Xordal
Извините, а разве будет отрабатывать триггер AFTER DELETE если deleted пуста?
А с какого перепугу он не должен отрабатывать?
19 июн 12, 15:42    [12739520]     Ответить | Цитировать Сообщить модератору
 Re: Триггер  [new]
Glory
Member

Откуда:
Сообщений: 104751
iap
А что, много времени займёт проверка наличия одной записи в deleted?

А что виртуальные таблицы уже готовые лежат в памяти как только триггер сработал ?
По сравнению с доступом к системной функции @@ROWCOUNT.
19 июн 12, 15:43    [12739528]     Ответить | Цитировать Сообщить модератору
 Re: Триггер  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
Xordal
iap
Получив значение @@ROWCOUNT=3 в триггере AFTER DELETE, Вы решите, что удаление затронуло 3 записи?
Но на самом деле deleted пуста!
Я имею в виду свой же пример MERGE.
Разве не корректнее писать IF EXISTS(SELECT * FROM deleted)?
И практически без снижения производительности, кстати сказать.

Извините, а разве будет отрабатывать триггер AFTER DELETE если deleted пуста?
Ещё как!
Запустите мой пример и убедитесь.
Или соорудите свой для DELETE MyTable WHERE 2*2=5;
19 июн 12, 15:43    [12739538]     Ответить | Цитировать Сообщить модератору
 Re: Триггер  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
Glory
iap
А что, много времени займёт проверка наличия одной записи в deleted?

А что виртуальные таблицы уже готовые лежат в памяти как только триггер сработал ?
По сравнению с доступом к системной функции @@ROWCOUNT.
Дык я ж и не спорю по поводу доступа к @@ROWCOUNT.
Быстрый доступ. Да только в @@ROWCOUNT лежит враньё
(по сравнению с обычными DELETE/UPDATE/INSERT, для которых раньше триггеры и разрабатывались).
19 июн 12, 15:46    [12739566]     Ответить | Цитировать Сообщить модератору
 Re: Триггер  [new]
Glory
Member

Откуда:
Сообщений: 104751
iap
Быстрый доступ. Да только в @@ROWCOUNT лежит враньё

в @@ROWCOUNT лежит то, что написано в хелпе.
А именно - результат головной команды. А не всех команд, которые она породит.
19 июн 12, 15:50    [12739609]     Ответить | Цитировать Сообщить модератору
 Re: Триггер  [new]
RubinDm
Member

Откуда:
Сообщений: 461
Glory
iap
Получив значение @@ROWCOUNT=3 в триггере AFTER DELETE, Вы решите, что удаление затронуло 3 записи?
Но на самом деле deleted пуста!

Да. Это будет проблемой, если триггер не должен или не может корректно обрабатывать пустую таблицу deleted.

iap
Разве не корректнее писать IF EXISTS(SELECT * FROM deleted)?
И практически без снижения производительности, кстати сказать.

Да неужели.

упс. что значит "триггер не должен ... обрабатывать пустую таблицу deleted"? Вы о чем? Каким образом Вы ему (серверу) запретите исполнять тригер с пустой deleted таблицей? Имхо тригер должен уметь обрабатывать таблицу deleted в любом ее состоянии, в том числе в пустом. То, как он (тригер) должен реагировать на пустую deleted - это уже отдельный вопрос бизнес-логики, но пережить такое пустое состояние таблицы deleted тригер так или иначе обязан. в противном случае запросы вида delete с условием, которому не удовлетворяет ни одна запись, окажется обреченным на жесткий провал.
19 июн 12, 15:53    [12739645]     Ответить | Цитировать Сообщить модератору
 Re: Триггер  [new]
Glory
Member

Откуда:
Сообщений: 104751
RubinDm
упс. что значит "триггер не должен ... обрабатывать пустую таблицу deleted"? Вы о чем? Каким образом Вы ему (серверу) запретите исполнять тригер с пустой deleted таблицей?

Глаголы "срабатывать" и "обрабатывать" имеют разный смысл.
Например, я не желаю в триггере на какой нибудь аудит заносить куда-нибудь еще запись вроде "Триггер обработал 0 записей"
19 июн 12, 15:56    [12739679]     Ответить | Цитировать Сообщить модератору
 Re: Триггер  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
Glory
iap
Быстрый доступ. Да только в @@ROWCOUNT лежит враньё

в @@ROWCOUNT лежит то, что написано в хелпе.
А именно - результат головной команды. А не всех команд, которые она породит.
Я с этого тут и начал.
Поэтому @@ROWCOUNT правильно использовать сразу после MERGE,
а не внутри триггеров таблицы, для которой этот MERGE вызван.
От того, что это всё прописано в BOL, легче не становится.
Лёгким движением руки Microsoft изменил логический смысл @@ROWCOUNT внутри триггеров!
А таких триггеров понаписано такое количество - просто жуть!
19 июн 12, 15:58    [12739697]     Ответить | Цитировать Сообщить модератору
 Re: Триггер  [new]
RubinDm
Member

Откуда:
Сообщений: 461
invm
RubinDm
Таблицы модифицировать надо. Но делать это надо только в тех случаях, когда это реально необходимо.
Даже тогда, когда проверка этой самой реальности дороже самих изменений?
А Вы можете без реальных данных, статистик и тп на пальцах доказать, что проверка этой самой реальности дороже самих изменений? Вот и я не могу доказать обратное. Смысл продолжать? :)
19 июн 12, 16:05    [12739766]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 2 [3] 4   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить