Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > MS SQL Server > Триггер...


Автор: Vit 28.2.2006, 23:42
Стыдно спрашивать, но не могу сообразить простую казалось бы вещь: Нужен триггер который бы проверял любые Insert или Update запросы к таблице на наличие определённого условия (например создания должна быть меньше даты окончания) и если условие не выполнено то, вместо указываемой даты окончания должна подставляться дата создания. Логичнее всего было бы сделать что-то типа такого в триггере:

Код

Update Inserted
Set Ended=Created
Where Ended<Created 


Но прямое редактирование таблицы Inserted запрещено. Возможно ли такое реализовать и если возможно то как?

Автор: Akina 1.3.2006, 10:46
Ты делаешь rollback текущей транзакции и либо возвращаешь raiseerror, либо вместо нее вызываешь выполнение запроса на Insert или Update с откорректированными данными.

Автор: SergeBS 1.3.2006, 12:30
Что-то не понял. Из BOL MS SQL 7:
First, rows are inserted into the table and the inserted table, and then the trigger fires.
Т.е. вроде можно просто в таблицу записать нужную величину и все.
Попробуй влепить в триггер просто что-то типа:
if a=1 and b=2
set c = 3 where id = inserted.id

Автор: Vit 1.3.2006, 16:22
Цитата(Akina @ 1.3.2006, 01:46 Найти цитируемый пост)
Ты делаешь rollback текущей транзакции и либо возвращаешь raiseerror, либо вместо нее вызываешь выполнение запроса на Insert или Update с откорректированными данными.


Не годится, запроса реально я на уровне MS SQL Server не знаю, а отменять транзакцию... тогда мне менять хренову кучу программ, смысл в том чтоб не менять много кода, а корректно обрабатывать ситуацию на уровне сервера.


Цитата(SergeBS @ 1.3.2006, 03:30 Найти цитируемый пост)
.е. вроде можно просто в таблицу записать нужную величину и все.
Попробуй влепить в триггер просто что-то типа:
if a=1 and b=2
set c = 3 where id = inserted.id


Угу, если меняется/вставляется одна строка, а если много?

Автор: SergeBS 1.3.2006, 17:42
Vit,
Цитата

Угу, если меняется/вставляется одна строка, а если много?

а в inserted тогда сколько будет? (не прикалываюсь, просто не пробовал - не знаю) Но подозреваю что именно то что надо и будет, т.е. пока транзакция не завершена, inserted пополняется. Затем срабатывает триггер, а уже затем commit/rollback. И после этого уже inserted очищается. Она именно для commit и нужна.

Автор: Dian 1.3.2006, 18:19
Вполне типичная ситуация. Нужно делать триггер типа IsteadOf (нерекурсивный) - только и всего ;)

Автор: SergeBS 1.3.2006, 19:57
Dian,
Цитата

Вполне типичная ситуация. Нужно делать триггер типа IsteadOf (нерекурсивный) - только и всего ;)

Ну-ка поподробней: где такое в MS SQL? И причем здесь вообще рекурсия?

Автор: Vit 2.3.2006, 04:51
Цитата(SergeBS @ 1.3.2006, 08:42 Найти цитируемый пост)
в inserted тогда сколько будет? (не прикалываюсь, просто не пробовал - не знаю) Но подозреваю что именно то что надо и будет, т.е. пока транзакция не завершена, inserted пополняется. Затем срабатывает триггер, а уже затем commit/rollback. И после этого уже inserted очищается. Она именно для commit и нужна.


Если несколько строк вовлечено то Inserted будет содержать несколько строк тоже, и commit/rallback будет относится ко всем строкам сразу.

Цитата(Dian @ 1.3.2006, 09:19 Найти цитируемый пост)
Вполне типичная ситуация. Нужно делать триггер типа IsteadOf (нерекурсивный) - только и всего ;)


Думал уже об IsteadOf , но что-то не совсем понятно как его применить, я ж заранее запрос не знаю какой прийдёт, хотя можно попробовать... А рекурсия... Рекурсия тут точно что не нужна, хотя не совсем понятно как её избежать для instead of триггеров, если честно то с ними не работал.
Добавлено @ 04:52
Цитата(SergeBS @ 1.3.2006, 10:57 Найти цитируемый пост)
Ну-ка поподробней: где такое в MS SQL?



Есть такой класс триггеров, впервые появились только в 2000 сервере, в отличие от обычных триггеров вызываются не после транзакции а вместо транзакции

Автор: Dian 2.3.2006, 05:20
Цитата(Vit @ 2.3.2006, 12:51 Найти цитируемый пост)
я ж заранее запрос не знаю какой прийдёт, хотя можно попробовать...

Наборы inserted / deleted никуда не деются - можно спокойно объявлять курсор по ним.
У нас такие штуки почти на каждой таблице, в том числе и для проверки прав.

Цитата(Vit @ 2.3.2006, 12:51 Найти цитируемый пост)
хотя не совсем понятно как её избежать для instead of триггеров

Сами себя они в любом случае не вызовут, а вот насчет других триггеров - не знаю. Вообще это настраивается в общих свойствах базы

Автор: SergeBS 2.3.2006, 08:40
Vit,
Цитата

Если несколько строк вовлечено то Inserted будет содержать несколько строк тоже, и commit/rallback будет относится ко всем строкам сразу.

Так это же вроде то, что нужно. И эта лабуда отработает как надо:
Цитата

if a=1 and b=2
set c = 3 where id = inserted.id

Автор: mo3art 14.3.2006, 15:47
Цитата(Dian @ 2.3.2006, 05:20 Найти цитируемый пост)
Наборы inserted / deleted никуда не деются - можно спокойно объявлять курсор по ним.

-курсор в триггере это круто! smile а чего вы ими там делаете? если не секрет?

Автор: Dian 16.3.2006, 10:49
Цитата(mo3art @ 14.3.2006, 23:47 Найти цитируемый пост)
а чего вы ими там делаете? если не секрет?

Угадай с трех раз!
Вообще - то, для чего он и предназначен smile

Автор: malor 8.9.2008, 17:38
В триггерах можно создавать временные таблицы?

Вычитал что нет - на http://www.piter.com/lib/978527200003/sql7.phtml?fil=Ch12
В триггерах запрещены следующие команды SQL: 
Любые команды CREATE;
............

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)