Oracle 8.05. Trigger
Релиб
Форумы       Участники    Календарь    Кто он-лайн?
Добро пожаловать, гость ( Вход | Регистрация )
        



Oracle 8.05. Trigger Expand / Collapse
Автор
Сообщение
26.10.2001 13:26
Supreme Being

Supreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme Being

участник
Last Login: 21.02.2007 18:25
Сообщ.: 109, Visits: 1 201
Neobhodimo sdelat trigger, kotorij deletal bi dochernie zapisi. Dopustim, nado unichtogit klienta – doljni snachala bit unchtogeni vse child-records v svjasannich tablicah. Eto ponjatno. No kak peredat parametr v trigger (id ynichtjaemogo klienta?). Naprjamuju v trigger parametr peredavat zaprescheno. Napisal procedury, kotoraja vse vesde deletaet , no ne soobraju, kak peredat etoj procedure parametri pri visove is triggera.
Ili edinstvennij put – s primeneniem :old.id_klient? No eta chernja otkasivaetsja rabotat naprjamuju s tablicami...
Please!
Сообщ. #730088
28.10.2001 14:09
Supreme Being

Supreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme Being

участник
Last Login: 21.02.2007 18:25
Сообщ.: 109, Visits: 1 201
Нет ответа... Попробую сформулировать ещё раз, но по-человечески, по-русски - кириллицей.
Итак, нужно, удалить, к примеру, клиента из таблицы клиенты. Таблица связана ещё с шестью таблицами, где могут содержаться дочерние записи. Несложно написать процедуру, которая будет уничтожать в этих шести таблицах все записи, где клиент-ID = ID клиента, которого нужно уничтожить. Но как активировать эту процедуру при попытке уничтожить клиента из таблицы КЛИЕНТЫ? Понятно: триггер с BEFOR DELETE ON таблица КЛИЕНТЫ. Не соображу, как передать параметр процедуры(ID клиента) в триггер. Если я пытаюсь просто запустить процедуру из тела триггера BEGIN name_of_procedure(ID_клиента); END; - не компилируется, сообщает, что содержимое скобок должно быть декларировано... Напрямую передать параметр в триггер тоже нельзя...
Как быть-то?
Заранее благодарен. С уважением GOLB
Сообщ. #730294
05.11.2001 21:32
Forum Guru

Forum GuruForum GuruForum GuruForum GuruForum GuruForum GuruForum GuruForum Guru

участник
Last Login: 17.04.2003 15:55
Сообщ.: 69, Visits: 760
Триггеры бывают "for each row" и на всю таблицу, делаешь триггер "for each row" и имеешь :old - переменная уровня триггера, которая содержит текущую запись, т.е. можешь обратиться :old.CLIENT_ID (только как r-value).
Сообщ. #731568
06.11.2001 1:18
Supreme Being

Supreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme Being

участник
Last Login: 21.02.2007 18:25
Сообщ.: 109, Visits: 1 201
В любом случае спасибо за готовность помочь и за собственно помощь.Спасибо, далёкий друг. Что-то похожее надыбал я в одной книге, но эта штука - 'for each row', похоже, не признаёт прямое обращение к таблице, а желает работать только с запросами... Это действительно так?
И ещё, пардон за тупость, что имеется в виду под r-value?
А вообще за это время поступила вводная от генералитета: триггеры не использовать. Они-де замедляют базу (что, на самом деле?), и порою приводят к нежелательным последствиям (это как раз можно представить себе). Было решено управляться процедурами, кои следует запихнуть в пакиджи и кои будут все связи отслеживать, апдейтая и делетая всё на своём пути... Имеюсь нынче с ними. База-то - по две сотни табличек, и референцев - будь здоров, хватает, чего нельзя сказать об опыте - его мало совсем... Но это уже детали, прорвёмся.
В любом случае спасибо за готовность помочь и за собственно помощь.
Сообщ. #731584
06.11.2001 12:49
Forum Guru

Forum GuruForum GuruForum GuruForum GuruForum GuruForum GuruForum GuruForum Guru

участник
Last Login: 17.04.2003 15:55
Сообщ.: 69, Visits: 760
Делаешь так:
create or replace trigger TG_CLIENT_DELETE
before delete on CLIENT
for each row
call PCK_CLIENT.KILL_CLIENT_REFERENCES(:OLD.CLIENT_ID);
или так
create or replace trigger TG_CLIENT_DELETE
before delete on CLIENT
for each row
begin
PCK_CLIENT.KILL_CLIENT_REFERENCES(:OLD.CLIENT_ID);
end;
Здесь TG_CLIENT_DELETE - имя триггера, PCK_CLIENT.KILL_CLIENT_REFERENCES(CLIENT_ID in number) - процедура удаления ссылающихся записей, а PCK_CLIENT - название пакета.
Из триггера FOR EACH ROW нельзя даже селекать по таблице CLIENT, но селекать можно в триггера уровня STATEMENT (без FOR EACH ROW) - всей операции DML над таблицей, но в этом триггере нельзя использовать :OLD и :NEW.
R-VALUE - это стандартное название одного из классов переменных/констант - не допускает присвоения (т.е. :OLD.CLIENT_ID=10 даст ошибку). Есть еще L-VALUE, которое можно использовать как в правой, так и в левой части оператора присвоения.
Удачи, если есть быстрый и-нет, советую otn.oracle.com - техническая библиотека разработчика от ORACLE Corp.
Сообщ. #731650
07.11.2001 0:10
Supreme Being

Supreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme Being

участник
Last Login: 21.02.2007 18:25
Сообщ.: 109, Visits: 1 201
Ну, просто исчерпывающе!
Огромное тебе спасибо. Успехов ;)
Сообщ. #731785
08.11.2001 13:39
Forum Guru

Forum GuruForum GuruForum GuruForum GuruForum GuruForum GuruForum GuruForum Guru

участник
Last Login: 28.12.2002 11:35
Сообщ.: 69, Visits: 760
Можно использовать каскадное удаление
для записей в дочерних таблицах.
Будет быстро и без триггеров.
Сообщ. #731965
08.11.2001 14:23
Forum Guru

Forum GuruForum GuruForum GuruForum GuruForum GuruForum GuruForum GuruForum Guru

участник
Last Login: 17.04.2003 15:55
Сообщ.: 69, Visits: 760
Использование ON DELETE CASCADE, или даже ON DELETE SET NULL, это порочная практика. Проектировщик и/или разработчик БД должен сознательно!!! прописывать удаления дочерних записей, а то можно грохнуть запись о клиенте и вместе с ней все записи о заказах.
И если уж сущность без родителя не существует, то можно использовать ON DELETE CASCADE только для такой сущности, но нужно сотню раз подумать.
Сообщ. #731976
08.11.2001 17:21
Supreme Being

Supreme BeingSupreme Being