Текущий архив: 2006.11.26;
Скачать: CL | DM;
Вниз
ERwin триггеры на каскадную стратегию Найти похожие ветки
← →
July (2006-09-06 12:22) [0]Уважаемые мастера!
Подскажите, пожалуйста, как такое возможно - при генерации базы данных по схеме из ERwin, для каскадных стратегий на удаление из таблицы-родителя создаются триггеры на "после
удаления". И оно как-то работает! :) Т.е. получается, что запись, несмотря на наличие дочерних записей в другой таблице, все таки удаляется, а уже потом выполняется триггер и удаляются записи из дочерней таблицы. У меня это все не укладывается в голове, если бы я писала сама триггер для реализации каскадной стратегии, то он был бы на "до удаления".
Хотя я уже догадываюсь, что вероятно проверка ограничений целостности выполняется позднее срабатывания триггеров, но все никак не могу привыкнуть к этой мысли.
Посоветуйте, пожалуйста, что по этому вопросу почитать, чтобы отбросить последние сомнения :)
← →
Val © (2006-09-06 12:52) [1]покажите ddl ограничения.
← →
July (2006-09-06 13:24) [2]?.. не поняла
← →
ANB © (2006-09-06 13:27) [3]
> July (06.09.06 13:24) [2]
Вообще то огород с триггерами для каскадного удаления не особо нужен. Достаточно включить каскад в ограничениях по внешнему ключу.
← →
Desdechado © (2006-09-06 13:29) [4]FOREIGN KEY ON DELETE CASCADE
← →
Sergey13 © (2006-09-06 13:30) [5]> [3] ANB © (06.09.06 13:27)
> Вообще то огород с триггерами для каскадного удаления не
> особо нужен.
Я бы даже сказал вреден, если можно решить через констрейнт. ИМХО.
← →
July (2006-09-06 13:46) [6]Но даже если так, как же он все таки работает, этот огород?
Хочется понять, чтобы учитывать при написании собственных триггеров.
← →
Sergey13 © (2006-09-06 14:06) [7]> [6] July (06.09.06 13:46)
> Хочется понять
Мне тоже, но ты с огородом тригеров далеко и молчишь. 8-)
← →
July (2006-09-06 17:13) [8]
> Мне тоже, но ты с огородом тригеров далеко и молчишь. 8-
> )
У меня доступ в сеть только эпизодически.
А что-то еще нужно добавить?
Вроде уже целый трактат накатала в первом посте :) .. о наболевшем :)))
← →
Val © (2006-09-06 17:15) [9]>?.. не поняла
выгрузите из базы ddl-текст внешнего ключа дочерней таблицы на родительскую, работа которого вас смущает.
← →
Sergey13 © (2006-09-07 08:21) [10]> [8] July (06.09.06 17:13)
Никакой трактат от огороде тригеров не заменит листинга самих тригеров. 8-)
← →
July (2006-09-07 12:49) [11]
> Val © (06.09.06 17:15) [9]
ALTER TABLE RECEIPT ADD FOREIGN KEY (BUYCARDID) REFERENCES BUYCARD (BUYCARDID);
поле BUYCARDID not null
> Никакой трактат от огороде тригеров не заменит листинга
> самих тригеров. 8-)
CREATE TRIGGER TD_BUYCARD FOR BUYCARD
ACTIVE AFTER DELETE POSITION 0
AS
/* ERwin Builtin Mon Apr 04 12:41:20 2005 */
/* DELETE trigger on BuyCard */
DECLARE VARIABLE numrows INTEGER;
BEGIN
/* ERwin Builtin Mon Apr 04 12:41:20 2005 */
/* BuyCard R/93 Receipt ON PARENT DELETE CASCADE */
delete from Receipt
where
/* %JoinFKPK(Receipt,OLD," = "," and") */
Receipt.BuyCardID = OLD.BuyCardID;
......
END
← →
Sergey13 © (2006-09-07 13:47) [12]Действительно странно.
У тебя случайно не отложенная проверка констрейнтов?
select CONSTRAINT_NAME, DEFERRED from dba_constraints
что показывает?
← →
Desdechado © (2006-09-07 13:59) [13]Sergey13 © (07.09.06 13:47) [12]
у нее не Оракл, а IB6
автору
не мудри с триггером, используй Desdechado © (06.09.06 13:29) [4]
← →
Val © (2006-09-07 14:07) [14]>[12] Sergey13 ©
я о том же - нет ли такой фичи и в иб уже?
>[13] Desdechado ©
да, да, но описанное поведение интересно.
← →
Sergey13 © (2006-09-07 14:11) [15]> [13] Desdechado © (07.09.06 13:59)
Блин, не переключился я. 8-)))))))))))))
← →
Desdechado © (2006-09-07 15:41) [16]> нет ли такой фичи и в иб уже?
Может, и есть в современных версиях (я как-то поотстал), хотя вряд ли. Но в IB6 точно нет. Вот из справки:<col_constraint> = [CONSTRAINT constraint]
{ UNIQUE
| PRIMARY KEY
| REFERENCES other_table [(other_col [, other_col …])]
[ON DELETE {NO ACTION|CASCADE|SET DEFAULT|SET NULL}]
[ON UPDATE {NO ACTION|CASCADE|SET DEFAULT|SET NULL}]
| CHECK (<search_condition>)}
<tconstraint> = [CONSTRAINT constraint]
{{PRIMARY KEY | UNIQUE} (col [, col …])
| FOREIGN KEY (col [, col …]) REFERENCES other_table
[ON DELETE {NO ACTION|CASCADE|SET DEFAULT|SET NULL}]
[ON UPDATE {NO ACTION|CASCADE|SET DEFAULT|SET NULL}]
| CHECK (<search_condition>)}
← →
Desdechado © (2006-09-07 15:49) [17]> вероятно проверка ограничений целостности выполняется позднее
> срабатывания триггеров
AFAIR, да. Это связано с тем, что триггеры работают в контексте транзакции, а ограничения - в контексте БД.
Кстати, помнится, в одной из промежуточных версий IB (или FB?) был баг, который устранили потом: ограничения срабатывали раньше триггеров.
← →
July (2006-09-07 17:40) [18]Desdechado> Это связано с тем, что триггеры работают в контексте транзакции, а ограничения - в контексте БД.
Но ведь транзакция не завершится, пока не будут проверены ограничения, просто проверяются они после выполнения всех операций в транзации, правильно я поняла?
Но вот если бы я вручную такой триггер писала то с опцией befor delete - это было бы ошибочно или на деле работало бы также только с логической точки зрения было понятнее?
(кстати, вопрос этот всплыл в процессе объяснения человеку, что такое стратегии и как они реализуются и работают :)
← →
July (2006-09-07 17:51) [19]П.С. Наврала в теме - у нас IB7
← →
Desdechado © (2006-09-07 18:02) [20]> правильно я поняла?
вроде да
> befor delete - это было бы ошибочно
Я так и пишу (иногда, когда ON DELETE CASCADE не получается задействовать). Не понимаю, зачем AFTER в этом случае.
> у нас IB7
Доки должны быть в поставке.
← →
Val © (2006-09-08 10:46) [21]>[17] Desdechado © (07.09.06 15:49)
Правда Оракл, нет IB сейчас :(, но все же...
Processing ...
create or replace trigger tmp_tr_supplier_test
after insert
on supplier
for each row
begin
dbms_output.put_line("after insert: i fired!");
end;
TRIGGER TMP_TR_SUPPLIER_TEST compiled successfully
Processing ...
insert into supplier (id, name, sname, bankid, accountno, nointerdebtness, contactdata, insiderid,siteid)
values (999,"dfdfd",
"dfdfd",
111,
"2600???", 1, null, 99,1)
insert into supplier (id, name, sname, bankid, accountno, nointerdebtness, contactdata, insiderid,siteid)
*
ORA-02291: integrity constraint (CREATOR_FORUM2.FK_SUPPLIER_BANKID) violated - parent key not found
after insert: i fired!
*** Script stopped due to error ***
← →
Desdechado © (2006-09-08 11:31) [22]Val © (08.09.06 10:46) [21]
> Правда Оракл, нет IB сейчас :(, но все же...
Только что на FB 1.5.3 проверил триггеры BEFORE INSERT, UPDATE, DELETE - все 3 выполняются до проверки ограничений.
← →
Val © (2006-09-08 11:38) [23]>[22] Desdechado © (08.09.06 11:31)
конечно, потому как проверять еще нечего.
обратите внимание - автор говорил об AFTER триггерах
← →
Desdechado © (2006-09-08 11:42) [24]> выполняются до проверки ограничений
И это логично, ибо в триггере проблемные значения полей могут быть заменены и стать приемлемыми.
← →
Desdechado © (2006-09-08 11:46) [25]> автор говорил об AFTER триггерах
Да, это я говорил о BEFORE. AFTER использую редко, потому и ступил с тестом.
AFTER срабатывают после проверки ограничений. И это тоже логично.
← →
Val © (2006-09-08 12:23) [26]я вроде не спорю о логичности - но - автор утверждает, что при наличии внешних ключей и каскадного удаления в AFTER триггерах(зачем, вопрос другой) у нее возникает ситуация:
> Т.е. получается, что запись, несмотря на наличие дочерних
> записей в другой таблице, все таки удаляется, а уже потом
> выполняется триггер и удаляются записи из дочерней таблицы.
>
если она верно получила текст-ddl ограничения (там нет ни отложенности, ни всяких on delete set null)- то, по-моему - такого быть не может..или я чего-то не понимаю.
← →
July (2006-09-08 17:12) [27]В общем, если принять, что ограничения (ну может не все их разновидности, но по крайней мере ограничение внешнего ключа) проверяются перед завершением транзакции, после того как пройдут
- действия триггеров befor,
- собственно запрашиваемые действия с таблицей,
- действия триггеров after,
тогда как оно все работает вроде понятно.
Остается вопрос - почему разработчики ERwin заложили в него для автоматически создаваемых триггеров, реализующих стратегии, опцию after, хотя по смыслу больше подходит befor?
Хотя работает в итоге одинаково.
Попробую предположить - может быть чтобы оставить возможность для специфических случаев написания разработчиком собственных триггеров, выполняющихся befor и создающих условия для корректного срабатывания стратегии...
Во как :)
← →
ANB © (2006-09-08 17:32) [28]
> Остается вопрос - почему разработчики ERwin заложили
Ты уверена, что это именно они заложили ?
В МВ у нас не было ограничений, все проверки стояли на триггерах. И почему то они были before . . .
← →
July (2006-09-12 17:32) [29]
> > Остается вопрос - почему разработчики ERwin заложили
> В МВ у нас не было ограничений, все проверки стояли на триггерах.
> И почему то они были before . . .
Вы их генерировали из схемы ERwin или все таки вручную писали?
> Ты уверена, что это именно они заложили ?
Конечно, я не могу быть в этом уверена.
Но ведь в схеме мы только указываем Interbase как целевую СУБД, в опциях для связей я нашла только где устанавливаются стратегии, предлагаемые по умолчанию при создании связи. И все.
Неужели СУБД диктует, как именно реализовывать триггеры для стратегий?
← →
ANB © (2006-09-12 17:57) [30]
> Вы их генерировали из схемы ERwin или все таки вручную писали?
Есно, генерировали.
Правда перед этим запихали их в шаблоны :)
Чего и вам советую.
← →
Val (from Kiev) (2006-09-12 19:55) [31]>Неужели СУБД диктует...
Думаю, что это ErWin вам надиктовал...
← →
July (2006-09-18 12:41) [32]
> Правда перед этим запихали их в шаблоны :)
> Чего и вам советую.
Заглянула только что в шаблоны - не нашла ничего касательно опций befor\after. Может быть плохо ищу
Там в template для определенной стратегии - только тело триггера, без заголовка. Можно ли там же и заголовок определять?
Честно говоря, сама никогда не пробовала эти шаблоны менять..
Есть еще отдельно CUSTOM TRIGGER HEADER в таком виде:
CREATE TRIGGER %TriggerName FOR %TableName
%Fire %Action AS
Но нигде не нашла, чтобы этот %Fire непременно устанавливался after.
Возникло еще одно предположение - мне тут напомнили, что, например, в SQL-server у триггеров вообще нет такой опции и выполняются они всегда после определенного действия, а установка нюансов - befor-after это особенность IB. Может ERwin и фигачит всем одинаково для стратегий after? :) (раз уж они все равно сработают раньше проверки ограничений целостности) А при создании триггера вручную остается возможность устанавливать эту опцию как хочется разработчику...
← →
July (2006-09-22 12:49) [33]Тем, кто еще заглянет в этот топик, сообщаю - нашла все таки этот шаблон:
trigger delete header:
CREATE TRIGGER t%1Action_%27TableName FOR %TableName AFTER %Action AS
Надо быть внимательнее :)
Кстати, как выяснилось, то что проверка целостности при операции удаления выполняется после срабатывания after триггера - это особенность именно операции удаления. Потому что для действия insert все работает по другому (как в общем-то и думалось о всех действиях) - триггер before, действие-проверка целостности, если действие прошло - триггер after.
← →
Johnmen © (2006-09-22 13:56) [34]Ветку не читал, но по последнему посту скажу.
Последовательность каскадного удаления системными триггерами можно изменить. Т.е. если стандартно сначала удаляется Мастер, потом Деталь, то эту последовательность можно изменить на обратную. И тогда пользовательские триггеры на М. и Д. будут выполняться в др.последовательности.
Страницы: 1 вся ветка
Текущий архив: 2006.11.26;
Скачать: CL | DM;
Память: 0.56 MB
Время: 0.041 c