Oracle проверяет существование перед удалением в триггере - PullRequest
0 голосов
/ 17 декабря 2008

Я проанализировал сгенерированную базу данных оракула в спящем режиме и обнаружил, что удаление строки из одной таблицы вызовет запуск более 1200 триггеров для удаления связанных строк в дочерних таблицах. Все триггеры автоматически генерируются одинаково - автоматическое удаление дочерней строки без предварительной проверки на существование. Поскольку невозможно предсказать, какие дочерние таблицы действительно будут иметь связанные строки, я думаю, что жизнеспособным решением для предотвращения запуска каскадного удаления по глубоко разветвленной полностью пустой конечности будет проверка на наличие связанной строки перед попыткой удалять. В других dbms 'я мог бы просто заявить "если существует ....." перед удалением. Есть ли сопоставимый способ сделать это в оракуле?

Ответы [ 4 ]

4 голосов
/ 17 декабря 2008

«удаление строки из одной таблицы вызовет запуск более 1200 триггеров» Эти операторы или триггеры уровня строки? Если последнее, они будут срабатывать только при удалении строки. Скажем, у вас есть триггер BEFORE DELETE для клиентов, чтобы удалить заказы клиентов, и триггер BEFORE DELETE для заказов, чтобы удалить позиции заказа. Если у клиента нет заказов, а триггер таблицы заказов является триггером уровня строки, он не будет запускать удаление из позиций заказа.

"проверить наличие связанной строки перед попыткой удаления" Наверное, нет пользы. На самом деле это сделало бы больше работы, имея SELECT, а затем DELETE.

Конечно, логика гибернации нарушена. Сеанс удаления будет видеть только (и пытаться удалить) зафиксированные транзакции. Если FRED вставил заказ для клиента, но он не зафиксирован, удаление JOHN (через триггер) не увидит его и не попытается удалить. Однако он все равно будет «успешным» и попытается удалить родительского клиента. Если вы действительно включили ограничения внешнего ключа в базе данных, Oracle сработает. Он будет ожидать фиксации FRED, а затем отклонит удаление, поскольку у него есть дочерний элемент. Если ограничения внешнего ключа отсутствуют, у вас есть заказ для несуществующего клиента. Вот почему вы должны применять подобную бизнес-логику в базе данных.

2 голосов
/ 17 декабря 2008

Если возможно, измените и настройте таблицы БД соответствующим образом. - Привлекайте DBA, если он у вас есть.

Вам необходимо использовать Ограничения внешнего ключа и каскадное удаление . Это исключает необходимость в триггерах и т.д ...

0 голосов
/ 14 июня 2010
select * from Tab where Tname = "TABLENAME"

Если этот запрос возвращает какую-либо строку, то таблица существует, в противном случае ее нет.

0 голосов
/ 17 декабря 2008

Вы можете запросить специальную таблицу dba_objects:

DECLARE 
X    NUMBER;
BEGIN
    SELECT COUNT(*) INTO X FROM DBA_OBJECTS WHERE OBJECT_TYPE = 'TRIGGER' AND OBJECT_NAME = 'YOUR_TRIGGER_NAME_HERE';
    IF X = 0 THEN
        --Trigger doesn't exist, OK to delete...
    END IF;
END;
...