|
|
|
Supreme 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!
|
|
|
|
|
Supreme 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
|
|
|
|
|
Forum Guru
      
участник
Last Login: 17.04.2003 15:55
Сообщ.: 69,
Visits: 760
|
|
| Триггеры бывают "for each row" и на всю таблицу, делаешь триггер "for each row" и имеешь :old - переменная уровня триггера, которая содержит текущую запись, т.е. можешь обратиться :old.CLIENT_ID (только как r-value).
|
|
|
|
|
Supreme Being
      
участник
Last Login: 21.02.2007 18:25
Сообщ.: 109,
Visits: 1 201
|
|
В любом случае спасибо за готовность помочь и за собственно помощь.Спасибо, далёкий друг. Что-то похожее надыбал я в одной книге, но эта штука - 'for each row', похоже, не признаёт прямое обращение к таблице, а желает работать только с запросами... Это действительно так? И ещё, пардон за тупость, что имеется в виду под r-value? А вообще за это время поступила вводная от генералитета: триггеры не использовать. Они-де замедляют базу (что, на самом деле?), и порою приводят к нежелательным последствиям (это как раз можно представить себе). Было решено управляться процедурами, кои следует запихнуть в пакиджи и кои будут все связи отслеживать, апдейтая и делетая всё на своём пути... Имеюсь нынче с ними. База-то - по две сотни табличек, и референцев - будь здоров, хватает, чего нельзя сказать об опыте - его мало совсем... Но это уже детали, прорвёмся. В любом случае спасибо за готовность помочь и за собственно помощь.
|
|
|
|
|
Forum 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.
|
|
|
|
|
Supreme Being
      
участник
Last Login: 21.02.2007 18:25
Сообщ.: 109,
Visits: 1 201
|
|
Ну, просто исчерпывающе! Огромное тебе спасибо. Успехов ;)
|
|
|
|
|
Forum Guru
      
участник
Last Login: 28.12.2002 11:35
Сообщ.: 69,
Visits: 760
|
|
Можно использовать каскадное удаление для записей в дочерних таблицах. Будет быстро и без триггеров.
|
|
|
|
|
Forum Guru
      
участник
Last Login: 17.04.2003 15:55
Сообщ.: 69,
Visits: 760
|
|
Использование ON DELETE CASCADE, или даже ON DELETE SET NULL, это порочная практика. Проектировщик и/или разработчик БД должен сознательно!!! прописывать удаления дочерних записей, а то можно грохнуть запись о клиенте и вместе с ней все записи о заказах. И если уж сущность без родителя не существует, то можно использовать ON DELETE CASCADE только для такой сущности, но нужно сотню раз подумать.
|
|
|
|
|
|
| | |