Pull to refresh

Comments 5

Способ с составным триггером действительно интересный и похож на кунг-фу. Но для решения повседневных задач, где нужно избежать мутирующих таблиц, лучше использовать хранимые процедуры (если есть такая возможность). Иначе будет не так просто понять почему художники стали ниньзя.
Вы имеете в виду хранимки вообще вместо триггеров? Возможно да, так будет наглядней. Но на скольо я помню, процедуру, например, для апдэйта можно вызывать при одиночном апдэйте, если же это массовый апдэйт большого количества строк, то вызов процедуры одиночного апдейта в курсорном цикле будет работать медленнее, чем один массовый апдэйт с триггером.
И второй момент — получается надо выбрать что-то одно, или использование хранимок для всех DML с таблицей или использование триггеров. На большом проекте не видел, чтоб выбор останавливали на первом. Возможно из-за аргумента приведенного в пред. посте (сегодня таблица маленькая, завтра разрослась и апдэйты стали массовыми), возможно из-за того, что он менее интуитивно понятен для вновь подключившихся к проекту, если надо сделать UPD таблицы чел может сразу не допереть, что все, оказывается, идет через хранимки (а использовать, повторюсь, надо что-то одно — хранимка или триггер, иначе могут быть траблы). Верно?
Исходя из моего опыта, неверно. Никто не мешает использовать и то и другое. Обычно (речь идёт про Oracle и, опять же, из моего опыта), стараются отказаться от триггеров и весь DML выполнять через хранимки (естественно, оформленные пакетами). Также, встречается подход, когда хранимками оборачиваются и все select-ы, но это, на мой взгляд, уже перебор. Триггеры остаются на случаи какой-то уж совсем невменяемой интеграции, когда хранимками обойтись не удаётся. Главные аргументы такого подхода — производительность и мутации (именно в таком порядке). Разумеется, это надо мерять, но я не думаю, что DML со строчными триггерами будет сильно быстрее аналогичных действий, оформленных через API хранимок. Конечно массовые операции, через такое API будут работать медленно (не медленнее чем триггеры), но для массовых операций, обычно, делается другое API.
Хочу предупредить аудиторию, что использование составных триггеров связано с документированным багом СУБД.
Представим, что в составном триггере объявлена коллекция, которая заполняется в частях each row и обрабатывается в afer statement. Если вызвать dml-операцию удаления, по таблице, триггер отработает корректно. Если же удалить строку из ДРУГОЙ таблицы, на которую наша таблица с триггером ссылается каскадным внешним ключем, то в after statement часть коллекция придет ПУСТОЙ, хотя и будет заполняться в each row частях.
Данный баг присутствует в 11.2.0.4, почитать про него и способы его обхода можно здесь:
community.oracle.com/thread/3823651?start=0&tstart=0
asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:9523633800346769343
support.oracle.com/rs?type=doc&id=1638849.1
Sign up to leave a comment.

Articles