powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Чтение таблицы из триггера (after-insert)
25 сообщений из 178, страница 1 из 8
Чтение таблицы из триггера (after-insert)
    #40009535
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вопрос: как передать значение строки в функцию для обработки?

Код: plsql
1.
2.
3.
4.
5.
6.
CREATE OR REPLACE TRIGGER TR_REACTOR_EVENTS
  after insert on REACTOR_EVENTS -- в таблицу пишутся данные снаружи
  for each row
begin
  PROCESS_REACTOR_EVENT( :new, '-verbose -journal' );
end;



Передача :new как параметр не разрешается компилятором, присваивание тоже запрещено,
только доступ к индивидуальным полям через :new.XYZ.

Поскольку на момент вызова триггера строка уже в таблице, я знаю ее ключ и даже rowid,
которые могу передать в функцию. Но прочитать строку по PK или rowid не могу,
select * into rec_new from REACTOR_EVENTS re where re.id = .. / re.rownum=..
дает ошибку что таблица все еще мутирует после вставки, читать ее нельзя из триггера.

Колонок в таблице не так уж и много, поэтому я сделал
Код: plsql
1.
2.
3.
4.
5.
6.
rnew   REACTOR_EVENTS%ROWTYPE;
..
  rnew.xyz1 := :new.xyz1; -- потому что rnew := :new нельзя
  rnew.xyz2 := :new.xyz2;
...
  PROCESS_REACTOR_EVENT( rnew, '-verbose -journal' );


Все работает, но теперь этот код нужно помнить подправить каждый раз таблица меняется.

Отсюда вопрос: как передать из триггера "после-вставки" значение вставленной строки в функцию обработки?

Функцию обработки я вынес из триггера для юнит-теста, т.к мне нужно прогнать наборы данных через триггер, не внося изменений в промышленную таблицу, в которую у меня даже не должно быть права писать. Функцию я могу вызвать на любом наборе данных, а также передать ей отладочные параметры. Как делать отладку на коде триггеров, я даже не представляю.

Более широкий вопрос: как юнит-тестить и дебагить код внутри триггера? добавление строк в таблицу нежелательно, т.к. приводит к нежелательному изменению состояния системы.
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009538
Правильный Вася
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
дает ошибку что таблица все еще мутирует после вставки, читать ее нельзя из триггера.Всё правильно, т.к. этот триггер может быть не единственным на такое событие у таблицы, а порядок срабатывания триггеров на одно событие не определен, поэтому может после него сработать и другой триггер. Т.е. данные в таблице ещё не устаканились и уж тем более не закоммитились.

Передавать попольно, afaik.
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009539
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL,
0) никогда, ни при каких обстоятельствах, и ни по чьему велению не ставьте натурных экспериментов на боевой системе.

1) нежелательные для вас изменения происходят не после команды insert, а после команды commit, у которой есть парно-обратная - rollback, используйте rollback в экспериментах там, где это необходимо.

2) почитайте и посмотрите любые примеры на составные триггеры, их делали специально и персонально для вас, и они долго ждали своего часа.

3) имеющийся в вашей среде отладчик вполне отладит ваши триггера, если они будут скомпилированы в режиме интерпретации и с включением отладочной информации.

4) если у вас есть возможность избегать использования триггеров - старайтесь избегать. Это определенная дисциплина проектирования, прежде всего.
---------------------
Имхо,
по тому что вы пишете, (мне) ясно, что вы делаете игрушечную систему, рассчитанную на малую нагрузку и общий небольшой объем данных.

Попробуйте далее, когда возникнет желание написать триггер, обязательно представлять себе, что вы подносите голую руку с
горящей в ней спичкой к горке магниевых стружек в смысле эффекта, оказываемого на производительность вставки
(она горит при этом ярким фонтаном огня, жестко обжигая вокруг себя все, включая поджигателя).
Ну, или что вы стеклянную колбу с царской водкой в руках несете, и ваша задача - не споткнуться.

Когда дело дойдет до "настоящих" требований по производительности, примерно также придется относиться и к каждому
создаваемому индексу.
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009553
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
booby,

авторКогда дело дойдет до... чтения документации...
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009585
graycode
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
НеофитSQL,

Для начала было бы неплохо прочитать документацию про триггеры, какие виды есть, для чего нужны и когда какие срабатывают.

Почему не используете before триггер?

Если вы хотите свои тесты залить на боевую систему, еще раз перечитайте то что вам написал booby.

Касательно функций и прочего PL/SQL, нужно четко понимать SQL - транзакционный, PL/SQL - нет.
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009607
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
graycode
... нужно четко понимать SQL - транзакционный, PL/SQL - нет.

В такой простой формулировке, это слишком сложное высказывание.

Имхо, выглядит как out of context, в нём недостаточно явных битов информации на количество букв,
и потому, оно, для первого чтения, совершенно бессмысленное. Это шифровка.

Общий контекст восприятия возникает на фоне овладения концептами "транзакция",
"согласованные изменения" и "потеря изменений при конкуренции".
Если нет понимания ничего из этого - умнее и упоминать, всё равно не будет понято, о чём идет речь.
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009657
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Правильный Вася
дает ошибку что таблица все еще мутирует после вставки, читать ее нельзя из триггера.
Всё правильно, т.к. этот триггер может быть не единственным на такое событие у таблицы, а порядок срабатывания триггеров на одно событие не определен, поэтому может после него сработать и другой триггер. Т.е. данные в таблице ещё не устаканились и уж тем более не закоммитились.

Передавать попольно, afaik.

Спасибо за объяснение; я не совсем его понял.
Почему таблица считается мутирующей на чтение в "после" триггере? Я предполагал что раз уж в после-триггере запрещено изменение таблицы, то сама таблица находится в стабильном состоянии. Даже если их несколько, все после-триггеры должны увидеть одну и ту же таблицу, с уже вставленной строкой.

Есть ли логическое обоснование, почему после-триггеру запрещено прочитать из таблицы только что вставленную строку, или это просто ограничение имплементации?
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009658
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
booby,

Много полезных комментариев.

0) согласен, боевая система не должна использоваться для разработок. В моей работе, это правило не применяется.

1) я изучу, можно ли весь код триггера сделать совместимым с откатом. Использование отката для юнит-тестов не приходила мне в голову, т.к. у триггера есть побочные эффекты которые не откатятся.

2) почитаю про составные триггеры, о которых знаю "краем глаза". Я предполагал, что мой вопрос слишком простой для таких конструкций.

(3) понял, не знал

(4) о вреде триггеров. Я понимаю, что они считаются вредными для скорости. Есть другие причины? Этот триггер вызывается раз в минуту, не чаще.
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009659
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL,

Вам сейчас нужно больше думать о допустимости и последствиях в вашей конкретной ситуации неоткатываемых действий.

"Другие причины" лежат вокруг того, что вы сознательно вплетаете отключаемые событийные интерфейсы.
Если это было сделано до вас, и вы не вполне понимаете, что это такое - это одна сторона медали.
Если вы делаете это своей рукой, хорошо, чтобы вы абсолютно точно понимали и что это такое, и как вы собираетесь с этим
долго жить в условиях неизвестных вам сегодня будущих потребностей.
И особенно , когда вы на голубом глазу собираетесь в контексте транзакции выполнять неоткатываемые действия.

Вы кого-то заведомо обмануть пытаетесь, или это способ тотальной слежки за мыслями и случайными почёсываниями?
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009660
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
graycode

Почему не используете before триггер?
.


Я выбрал после-триггер, т.к. мой код обработки событий не предполагает изменения самого события, те остаются в первоначальном виде. Также, если у таблицы когда-то появится* до-триггер, я хотел чтобы код обработки событий видел окончательное значение события, а не сырое промежуточное.

(*) Уже появился; пришлось повесить до-триггер когда дополнял таблицу событий первичным ключом. До 12.х у оракла не было автоинкремента колонки, пришлось добавить короткий до-триггер с :new.id := sequence.nextval
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009661
Правильный Вася
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
Почему таблица считается мутирующей на чтение в "после" триггере?
Потому что ещё не было коммита .
Не забывай, что другой триггер на это row-событие (или в целом на table-событие) может попытаться что-то сделать, что вызовет exception, а это автоматом отменит транзакцию. Например, в другом триггере будет неудачная попытка каскадных изменений в каких-то зависимых таблицах или сложная проверка целостности данных.

НеофитSQL
все после-триггеры должны увидеть одну и ту же таблицу, с уже вставленной строкой.
Ну так row-триггеры и видят ровно одну свою строку в :NEW.

НеофитSQL
Есть ли логическое обоснование, почему после-триггеру запрещено прочитать из таблицы только что вставленную строку, или это просто ограничение имплементации?
Она ещё НЕ вставленная, она В ПРОЦЕССЕ.
И почитай разницу между блокировочниками и версионниками среди СУБД. Это к вопросу имплементации.
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009662
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
booby,

О неоткатываемых действиях и прочих "обманах".

Одно известное мне сегодня неоткатываемое действие - запись ошибок исполнения в лог/таблицу ошибок.
Логгинг, по своей природе, не следует отката, и сохраняет сообщения об ошибках кода даже при откатах.
Я не знаю, есть ли код с побочными эффектами кроме лога ошибок, но посмотрю.

Я следую установленной в продукте архитектуре, которая использует триггеры довольно обширно, включая каскадную их разновидность, когда изменение строки в одном представлении выстреливает триггеры в нескольких других. Это выглядело способным вызвать кольцевую зависимость, поэтому я для себя набросал иерархию представлений и таблиц - какие триггеры могут писать в какие таблицы. Все пока легло в дерево, т.е. каждое одиночное изменение должно закончиться в конечное время.

Возможно, уже кто-то написал best practices: как в оракле принято обрабатывать внешние события, и я просто ещё не нашел этот труд. Он мог бы начинаться "избегайте таблиц с триггерами в качестве механизма передачи внешних событий, вместо этого оформите внешние события в виде...."? Сообщений? Запросов? Поллинга внешних таблиц?

Как это принято делать?
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009665
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я благодарен вашему терпению. Я наверное задаю новичковые вопросы. С триггерами познакомился буквально два дня назад.

Правильный Вася
НеофитSQL
Почему таблица считается мутирующей на чтение в "после" триггере?
Потому что ещё не было коммита .
Не забывай, что другой триггер на это row-событие (или в целом на table-событие) может попытаться что-то сделать, что вызовет exception, а это автоматом отменит транзакцию. Например, в другом триггере будет неудачная попытка каскадных изменений в каких-то зависимых таблицах или сложная проверка целостности данных.


Я понимаю что до коммита строка в таблице только для сессии, а не глобально. И коммита ещё может не произойти.
Однако, в других ситуациях оракл вполне позволяет мне читать строку для которой ещё не произошел коммит. С точки зрения сессии новая строка уже в таблице, и я могу на ней исполнить селект. Только не даёт это сделать в триггере. Поэтому я спросил. Разве триггер исполняется не в контексте сессии?

[quot Ну так row-триггеры и видят ровно одну свою строку в :NEW.
[/quot]

Я бы этим и пользовался, но у этой псевдопеременной есть ограничения, она не типа rowtype, и ее нельзя передать как параметр.
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009667
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
...
Одно известное мне сегодня неоткатываемое действие - запись ошибок исполнения в лог/таблицу ошибок.
Логгинг, по своей природе, не следует отката, и сохраняет сообщения об ошибках кода даже при откатах.

о, боже... "логгинг" - это что, синоним "элегантности"?

Есть "логгинг" и "логгинг".

Если происходит плановый отказ от завершения транзакции - зачем вообще логировать планово несостоявшиеся действия?

Если же фиксируются действия, отвергнутые по наличию ошибок заполнения данных, то это называется не "логгинг",
а "валидация".

Необходимость сохранения её результатов определяется либо потребностями программиста в трассировке на период отладки,
либо конкретными особенностями устройства процедур проверки качества данных.

В обоих случаях это не побочный, а явный результат специально организованного процесса, в общем случае, состоящего из произвольного числа транзакций.

Вы в своих триггерах ифы писать замучаетесь, чтобы понять, какой именно красоты логирование именно сейчас требуется.
У вас вставка в таблицу в таком варианте намертво привязывается к имени процесса, его производящего.
Ну, или будете логировать всё подряд в общую мусорку, и результатом нельзя будет воспользоваться содержательно.
Конечно, много изумительной мути, в триггерах можно наваять.

НеофитSQL
...
Как это принято делать?

А вот как очередной свежепришедший неофит наляпяет, так и приято.
Статистически неотличимая от 100% доля "ынтырпрайза" не является непроходимым гуаном чуть менее, чем целиком.
В том числе и в области "логирования".

Обычно это является печальным результатом блестящего образования, большого опыта работы,
высокой степени самооценки и безграничного доверия руководства.

...
И только очумевшие администраторы изредка постанывают -
"Ау! Есть читатели на эти великолепные логи?
Когда и какой мусор сносить-то можно, к чёртовой матери, или его надо ленту писать?..."
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009668
Правильный Вася
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сессия и транзакция - суть 2 больших разницы.

Читай уже доку , что ль. Изучать монстров типа Оракл по сообщениям форума - это как по учебнику ботаники пытаться понять работу космического корабля во всех нюансах.

Сначала базовые вещи, потом детали. НЕ наоборот.

У Оракла достаточно документации для РАЗНЫХ уровней подготовки, даже нулячих.
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009669
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В первую очередь это сделано именно из-за многострочных операторов
Согласованность любого запроса поддерживается на уровне SCN, и строки все будут вставлены/обновлены/удалены тоже на один момент SCN.
А внутри одного оператора (многострочного) получится что на один и тот же SCN, триггер, стрельнувший для каждой строки, будет видеть разный набор данных, что противоречит основным принципам ACID
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009671
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вячеслав Любомудров,

нет смысла ему абракадаброй говорить.
Читать у него времени нет. Триггера писать надо.
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009674
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нашел правильный ответ:

Таблица мутирует потому что триггер построчный.

Доступ к таблице работает нормально из непострочного после-триггера.

Проблема решена, всем спасибо.

Booby, ваши рассуждения о логгинге слишком упрощены и в данном случае неверны. Я могу посоветовать профильные книги, если вам интересно.
Одно из требований доверия к логгингу - запретить любые изменения прошлых событий, в том числе откат.
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009675
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вячеслав Любомудров
В первую очередь это сделано именно из-за многострочных операторов
Согласованность любого запроса поддерживается на уровне SCN, и строки все будут вставлены/обновлены/удалены тоже на один момент SCN.
А внутри одного оператора (многострочного) получится что на один и тот же SCN, триггер, стрельнувший для каждой строки, будет видеть разный набор данных, что противоречит основным принципам ACID


Не без труда, но расшифровал. Спасибо.

Строки вставляются группой, а триггер однострочный.

Мои трудности оказались связаны с однострочностью триггера, для которого в общем случае не существует стабильного промежуточного состояния таблицы.
Для одиночного insert существует, но запрещен инженерами оракла.
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009676
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
...
Booby, ваши рассуждения о логгинге слишком упрощены и в данном случае неверны....

Спасибо, успокоили. А то я уже волноваться начал даже...
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009682
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby
Если происходит плановый отказ от завершения транзакции - зачем вообще логировать планово несостоявшиеся действия?
"в автономной транзакции: начато - "Действие"; фиксация", ..., "в автономной транзакции: завершено - "Результат"; фиксация".
Но, да - это скорее аудит, чем протоколирование.
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009683
проходил мимо...
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Правильный Вася
Потому что ещё не было коммита .

[рукалицо]
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009684
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
Одно из требований доверия к логгингу - запретить любые изменения прошлых событий, в том числе откат.
К аудиту. Который сильно отличается от протоколирования.

P.S.
И, да - вы всё равно идёте к звёздам не per astra.
Запрет изменения реализуется ограничением доступа к таблице аудита. В концептах это всё тоже изложено. Хотя и не "прямо в лоб для вашего случая".
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009688
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Правильный Вася
НеофитSQL
Почему таблица считается мутирующей на чтение в "после" триггере?
Потому что ещё не было коммита .


Оказалось, дело было вовсе не в коммите. Блочный после-триггер читает таблицу без проблем. Построчный - не может, т.к. вызывается (иногда) между стабильными состояниями таблицы. Из-за этого "иногда" построчному после-триггеру всегда запрещено обращение к возможно мутирующей таблице.

Я сейчас оценил, что ответ на мой вопрос "почему" требует глубоких знаний, и для всех есть возможность узнать что-то новое.
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009689
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Basil A. Sidorov
НеофитSQL
Одно из требований доверия к логгингу - запретить любые изменения прошлых событий, в том числе откат.
К аудиту. Который сильно отличается от протоколирования.

P.S.
И, да - вы всё равно идёте к звёздам не per astra.
Запрет изменения реализуется ограничением доступа к таблице аудита. В концептах это всё тоже изложено. Хотя и не "прямо в лоб для вашего случая".


Для протоколирования действий у меня отдельная таблица, где действительно работает откат. Логично, т.к. не случилось действие - нет протокола о нем.

В логе ошибок у меня "безоткатные" данные, в том числе самодиагностика (asserts в лог) для ловли ошибок в моем коде, или недопустимые состояния, которых не должно быть.
Поскольку мой код автоматизации работает без участия человека, мне очень помогает когда он сам рассказывает что у него болит.

И не стирает свои жалобы, если где-то exception.

А как этот вопрос решают колеры с опытом - просто пишут без ошибок? :)
...
Рейтинг: 0 / 0
25 сообщений из 178, страница 1 из 8
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Чтение таблицы из триггера (after-insert)
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]