|
|
|
check раньше триггера
|
|||
|---|---|---|---|
|
#18+
У меня есть триггер, который при изменении одного поля в главной таблице переписывает строку из одной подчиненной таблицы в другую - то есть в одной стирает, в другой вставляет. В обоих подчиненных таблицах есть check на значение одного из полей. Чтоб было понятнее - пример: Таблица " лица ", " юрлица " и " физлица " В "лица" поля " код ", " тип ", общие для всех типов поля В "юрлица" поля " код ", " тип " (check: "тип"='ю'), "краткое наименование", другие характерные для юрлиц поля В "физлица" поля " код ", " тип " (check: "тип"='ф'), "краткое наименование", другие характерные для физлиц поля Соответствующие внешние ключи в таблицах "юрлица" и "физлица" с каскадным обновлением. Пытаюсь сделать триггер, чтобы перед обновлением поля "тип" в главной таблице "код" и "краткое наименование" переписывались в соответствующую таблицу. Однако при изменении типа триггер на обновление срабатывает позже, чем check, который не дает сделать каскадное обновление. Каков best practice для подобных задач? Может, сделать checkи своими триггерами, у которых я смогу как мне нужно расставить последовательность? Пардон за таблицы, лица, юрлица и физлица ;) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.06.2003, 21:41 |
|
||
|
check раньше триггера
|
|||
|---|---|---|---|
|
#18+
по крайней мере можно решить влоб.... 1. Снять check'и с полей таблиц 2. Озаботить этой проверкой триггер ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.06.2003, 03:23 |
|
||
|
check раньше триггера
|
|||
|---|---|---|---|
|
#18+
Ты наверное IB6 пользуеш. Там была известная бага с тем, что проверки выполнялись до триггеров. Это было давно исправлено в ФБ. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.06.2003, 10:40 |
|
||
|
check раньше триггера
|
|||
|---|---|---|---|
|
#18+
Я использую FB 1.0. У меня check срабатывает раньше триггера. А вот тут Алексей Ковязин назвал срабатывание триггера раньше checkа глюком! \r \r У меня тогда такой вопрос. Как имеющимися средствами сделать триггер INSTEAD OF?\r \r 2StarWind: я вот думаю check оставить, но сделать ХП, чтобы менять тип лица. Там сначала будет удаление из одной подчиненной таблицы, потом изменение в главной, потом вставка в другую подчиненную таблицу. \r \r И вот, чтобы не беспокоить клиента такими мелочами, я бы попытался вызов этой ХП сделать из триггера INSTEAD OF. Ну если нельзя, то кноечно он будет получать отлуп от checkа, если попытается изменить простым updatом, ничего страшного.\r \r Ф. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.06.2003, 13:10 |
|
||
|
check раньше триггера
|
|||
|---|---|---|---|
|
#18+
Привет! Чеки ДОЛЖНЫ срабатывать РАНЬШЕ триггеров. Чеки - ограничения более низкого и приоритетного уровня, чем триггеры. Что касается каскадных обновлений - может, помжет внешний ключ с опцией ON CASCADE ? WBR, Alexey ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.06.2003, 13:37 |
|
||
|
check раньше триггера
|
|||
|---|---|---|---|
|
#18+
И с чего бы это чекам срабатывать раньше триггеров? Тогда можно будет в таблицу вставлять значения, которые не удовлетворяют проверке. Смотрите исправленную ошибку 444463. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.06.2003, 17:24 |
|
||
|
check раньше триггера
|
|||
|---|---|---|---|
|
#18+
2Алексей: Так у меня уже есть ON UPDATE CASCADE. И вот это каскадное обновление-то и не получается - срабатывает чек. У меня и чек, и каскадное обновление, и триггер after update, который должен был выхватить неудовлетворяющую чеку запись и переписать ее в другую таблицу, до срабатывания чека. 2Gold: не пойму это сарказм или вопрос... ;) Так исправлено или нет? И что написано в 444463? (На последний вопрос можно не отвечать, я и сам посмотрю) 2All: есть ли хитрость, чтобы сделать триггер INSTEAD OF? Ф ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.06.2003, 19:16 |
|
||
|
check раньше триггера
|
|||
|---|---|---|---|
|
#18+
У меня почему-то триггер BEFORE срабатывает раньше всех проверок... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.06.2003, 10:41 |
|
||
|
check раньше триггера
|
|||
|---|---|---|---|
|
#18+
Так и должно быть. Если бы триггер BEFORE срабатывал после проверки, в базу можно было бы вставить записи, не удовлетворяющие проверке (т.е. подменить их в триггере). Потом, при попытке восстановления такой базы, случилось бы несчастье. Раньше так и было в IB. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.06.2003, 10:59 |
|
||
|
check раньше триггера
|
|||
|---|---|---|---|
|
#18+
Вот теперь я понял, что это действительно ошибка! Бегу искать обновление... зы. видимо, на самом деле, чеки должны срабатывать и до, и после триггера (и во время выполнения триггера, чтобы никому не было обидно ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.06.2003, 12:02 |
|
||
|
check раньше триггера
|
|||
|---|---|---|---|
|
#18+
Совсем вы меня запутали :) Все так, как говорит Gold. WBR, Alexey ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.06.2003, 12:24 |
|
||
|
check раньше триггера
|
|||
|---|---|---|---|
|
#18+
Описание ошибки нашел по адресу http://sourceforge.net/tracker/?func=detail&atid=109028&aid=444463&group_id=9028 , написано, что исправлено в Firebird v.1.0. У меня, значит, правильная версия стоит. Видимо, я неправильно делаю, у меня последовательность получается такая. 1. Я меняю в главной таблице "ф" на "ю". 2. Срабатывает каскадное обновление подчиненной таблицы. 3. Проверяется чек подчиненной таблицы, обновление не подходит под чек, выходит исключение 4. До моего триггера "до обновления главной таблицы" выполнение не доходит. 2 выхода, который я попробую, когда доберусь до дома (если не вспомню, что уже пробовал) 1. Уберу каскадное обновление (no action). Скорее всего, тогда при изменении "ф" на "ю" она скажет, что не удовлетворяется внешний ключ, и опять до моего триггера не дойдет. 2. Сделаю вместо триггера в главной таблице триггер "до обновления" в подчиненной таблице, который сотрет запись в своей таблице и запишет ее в другую подчиненную таблицу. Тогда чек, может быть, не успеет ругнуться. Ф. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2003, 10:50 |
|
||
|
check раньше триггера
|
|||
|---|---|---|---|
|
#18+
Что-то ты там перемудрил. Вот специально сделал пример: CREATE TABLE T1 (F INTEGER CHECK F<0); CREATE TABLE T2 (F INTEGER CHECK F>0); SET TERM ^ ; CREATE TRIGGER T2_BI0 FOR T2 ACTIVE BEFORE INSERT POSITION 0 AS BEGIN IF (NEW.F<0) THEN NEW.F=NEW.F*-1; END^ SET TERM ; ^ INSERT INTO T1 VALUES(-1); INSERT INTO T2 SELECT * FROM T1; Всё отлично работает... К стати, советую заюзать функцию типа такой (если под виндой разрабатываешь): function var i:integer:integer; cdecl; begin ShowMessage(IntToStr(i)); Result:=i end; Попробуй с помощью неё отладить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2003, 11:10 |
|
||
|
check раньше триггера
|
|||
|---|---|---|---|
|
#18+
Спасибо, Gold, удивляюсь, как не лень делать проверку специально, чтоб кому-то обяснить! Но благодаря ответу мне у тебя перестало быть количество сообщений 666 :) Но у меня-то немножко по-другому. Конечно я мудрю :) У меня три таблицы, одна главная и 2 подчиненных. Изменение в главной вызывает каскадное обновление одной из подчиненных. Чтобы абстрагироваться еще больше, можно убрать "главную" таблицу и поставить вопрос так: нужно, чтобы при попытке (до) обновления в таблице 1 брать строку, стирать из таблицы 1 (потому что она не будет удовлетворять чеку) и вставлять в таблицу 2. например, CREATE TABLE T1 ( key integer, F INTEGER CHECK F<0); CREATE TABLE T2 ( key integer, F INTEGER CHECK F>0); SET TERM ^ ; CREATE TRIGGER T2_B U 0 FOR T2 ACTIVE BEFORE UPDATE POSITION 0 AS BEGIN IF (NEW.F<0) THEN insert into T1 (key, F) values (new.key, new.F); delete T1 where F=old.key; /* и видимо, update после этого просто ничего не сделает, т.е. не попытается изменить F на отрицательное, потому что не найдет ключа */ END^ SET TERM ; ^ и теперь когда мы попробуем сделать update T2 set F=F*-1 where key=123 то запись с key=123 перескочит в T1 (вот этого мне и надо добиться) Будет ли так работать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2003, 12:01 |
|
||
|
check раньше триггера
|
|||
|---|---|---|---|
|
#18+
Да уж - химия чистой воды :-))) Тут решений я вижу 2: 1. делать через обновление через процедуру и всё котролировать в ней 2. убрать чеки и всё выполнять в последних триггерах ПОСЛЕ обновления ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2003, 12:34 |
|
||
|
check раньше триггера
|
|||
|---|---|---|---|
|
#18+
А че, так как я написал, не будет работать? Уже видно? Конечно, сделаю проце дуру, если не будет, но чеки оставлю все-таки.. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2003, 12:53 |
|
||
|
check раньше триггера
|
|||
|---|---|---|---|
|
#18+
Ну, предположим, вот так оно работать будет: BEGIN IF (NEW.F<0) THEN BEGIN INSERT INTO T1 VALUES (NEW.F); NEW.F=NEW.F*-1; DELETE FROM T2 WHERE F=OLD.F; END END Только стрёмно это. Мало ли чего. Я бы так не рискнул делать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.06.2003, 13:17 |
|
||
|
|

start [/forum/topic.php?fid=40&msg=32179188&tid=1580390]: |
0ms |
get settings: |
4ms |
get forum list: |
8ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
157ms |
get topic data: |
6ms |
get forum data: |
2ms |
get page messages: |
30ms |
get tp. blocked users: |
1ms |
| others: | 227ms |
| total: | 439ms |

| 0 / 0 |
