|
Чтение таблицы из триггера (after-insert)
|
|||
---|---|---|---|
#18+
Вопрос: как передать значение строки в функцию для обработки? Код: plsql 1. 2. 3. 4. 5. 6.
Передача :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.
Все работает, но теперь этот код нужно помнить подправить каждый раз таблица меняется. Отсюда вопрос: как передать из триггера "после-вставки" значение вставленной строки в функцию обработки? Функцию обработки я вынес из триггера для юнит-теста, т.к мне нужно прогнать наборы данных через триггер, не внося изменений в промышленную таблицу, в которую у меня даже не должно быть права писать. Функцию я могу вызвать на любом наборе данных, а также передать ей отладочные параметры. Как делать отладку на коде триггеров, я даже не представляю. Более широкий вопрос: как юнит-тестить и дебагить код внутри триггера? добавление строк в таблицу нежелательно, т.к. приводит к нежелательному изменению состояния системы. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.10.2020, 01:23 |
|
Чтение таблицы из триггера (after-insert)
|
|||
---|---|---|---|
#18+
дает ошибку что таблица все еще мутирует после вставки, читать ее нельзя из триггера.Всё правильно, т.к. этот триггер может быть не единственным на такое событие у таблицы, а порядок срабатывания триггеров на одно событие не определен, поэтому может после него сработать и другой триггер. Т.е. данные в таблице ещё не устаканились и уж тем более не закоммитились. Передавать попольно, afaik. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.10.2020, 03:57 |
|
Чтение таблицы из триггера (after-insert)
|
|||
---|---|---|---|
#18+
НеофитSQL, 0) никогда, ни при каких обстоятельствах, и ни по чьему велению не ставьте натурных экспериментов на боевой системе. 1) нежелательные для вас изменения происходят не после команды insert, а после команды commit, у которой есть парно-обратная - rollback, используйте rollback в экспериментах там, где это необходимо. 2) почитайте и посмотрите любые примеры на составные триггеры, их делали специально и персонально для вас, и они долго ждали своего часа. 3) имеющийся в вашей среде отладчик вполне отладит ваши триггера, если они будут скомпилированы в режиме интерпретации и с включением отладочной информации. 4) если у вас есть возможность избегать использования триггеров - старайтесь избегать. Это определенная дисциплина проектирования, прежде всего. --------------------- Имхо, по тому что вы пишете, (мне) ясно, что вы делаете игрушечную систему, рассчитанную на малую нагрузку и общий небольшой объем данных. Попробуйте далее, когда возникнет желание написать триггер, обязательно представлять себе, что вы подносите голую руку с горящей в ней спичкой к горке магниевых стружек в смысле эффекта, оказываемого на производительность вставки (она горит при этом ярким фонтаном огня, жестко обжигая вокруг себя все, включая поджигателя). Ну, или что вы стеклянную колбу с царской водкой в руках несете, и ваша задача - не споткнуться. Когда дело дойдет до "настоящих" требований по производительности, примерно также придется относиться и к каждому создаваемому индексу. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.10.2020, 04:46 |
|
Чтение таблицы из триггера (after-insert)
|
|||
---|---|---|---|
#18+
booby, авторКогда дело дойдет до... чтения документации... ... |
|||
:
Нравится:
Не нравится:
|
|||
18.10.2020, 09:10 |
|
Чтение таблицы из триггера (after-insert)
|
|||
---|---|---|---|
#18+
НеофитSQL, Для начала было бы неплохо прочитать документацию про триггеры, какие виды есть, для чего нужны и когда какие срабатывают. Почему не используете before триггер? Если вы хотите свои тесты залить на боевую систему, еще раз перечитайте то что вам написал booby. Касательно функций и прочего PL/SQL, нужно четко понимать SQL - транзакционный, PL/SQL - нет. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.10.2020, 14:25 |
|
Чтение таблицы из триггера (after-insert)
|
|||
---|---|---|---|
#18+
graycode ... нужно четко понимать SQL - транзакционный, PL/SQL - нет. В такой простой формулировке, это слишком сложное высказывание. Имхо, выглядит как out of context, в нём недостаточно явных битов информации на количество букв, и потому, оно, для первого чтения, совершенно бессмысленное. Это шифровка. Общий контекст восприятия возникает на фоне овладения концептами "транзакция", "согласованные изменения" и "потеря изменений при конкуренции". Если нет понимания ничего из этого - умнее и упоминать, всё равно не будет понято, о чём идет речь. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.10.2020, 17:54 |
|
Чтение таблицы из триггера (after-insert)
|
|||
---|---|---|---|
#18+
Правильный Вася дает ошибку что таблица все еще мутирует после вставки, читать ее нельзя из триггера. Передавать попольно, afaik. Спасибо за объяснение; я не совсем его понял. Почему таблица считается мутирующей на чтение в "после" триггере? Я предполагал что раз уж в после-триггере запрещено изменение таблицы, то сама таблица находится в стабильном состоянии. Даже если их несколько, все после-триггеры должны увидеть одну и ту же таблицу, с уже вставленной строкой. Есть ли логическое обоснование, почему после-триггеру запрещено прочитать из таблицы только что вставленную строку, или это просто ограничение имплементации? ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2020, 01:40 |
|
Чтение таблицы из триггера (after-insert)
|
|||
---|---|---|---|
#18+
booby, Много полезных комментариев. 0) согласен, боевая система не должна использоваться для разработок. В моей работе, это правило не применяется. 1) я изучу, можно ли весь код триггера сделать совместимым с откатом. Использование отката для юнит-тестов не приходила мне в голову, т.к. у триггера есть побочные эффекты которые не откатятся. 2) почитаю про составные триггеры, о которых знаю "краем глаза". Я предполагал, что мой вопрос слишком простой для таких конструкций. (3) понял, не знал (4) о вреде триггеров. Я понимаю, что они считаются вредными для скорости. Есть другие причины? Этот триггер вызывается раз в минуту, не чаще. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2020, 01:57 |
|
Чтение таблицы из триггера (after-insert)
|
|||
---|---|---|---|
#18+
НеофитSQL, Вам сейчас нужно больше думать о допустимости и последствиях в вашей конкретной ситуации неоткатываемых действий. "Другие причины" лежат вокруг того, что вы сознательно вплетаете отключаемые событийные интерфейсы. Если это было сделано до вас, и вы не вполне понимаете, что это такое - это одна сторона медали. Если вы делаете это своей рукой, хорошо, чтобы вы абсолютно точно понимали и что это такое, и как вы собираетесь с этим долго жить в условиях неизвестных вам сегодня будущих потребностей. И особенно , когда вы на голубом глазу собираетесь в контексте транзакции выполнять неоткатываемые действия. Вы кого-то заведомо обмануть пытаетесь, или это способ тотальной слежки за мыслями и случайными почёсываниями? ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2020, 02:15 |
|
Чтение таблицы из триггера (after-insert)
|
|||
---|---|---|---|
#18+
graycode Почему не используете before триггер? . Я выбрал после-триггер, т.к. мой код обработки событий не предполагает изменения самого события, те остаются в первоначальном виде. Также, если у таблицы когда-то появится* до-триггер, я хотел чтобы код обработки событий видел окончательное значение события, а не сырое промежуточное. (*) Уже появился; пришлось повесить до-триггер когда дополнял таблицу событий первичным ключом. До 12.х у оракла не было автоинкремента колонки, пришлось добавить короткий до-триггер с :new.id := sequence.nextval ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2020, 02:31 |
|
Чтение таблицы из триггера (after-insert)
|
|||
---|---|---|---|
#18+
НеофитSQL Почему таблица считается мутирующей на чтение в "после" триггере? Не забывай, что другой триггер на это row-событие (или в целом на table-событие) может попытаться что-то сделать, что вызовет exception, а это автоматом отменит транзакцию. Например, в другом триггере будет неудачная попытка каскадных изменений в каких-то зависимых таблицах или сложная проверка целостности данных. НеофитSQL все после-триггеры должны увидеть одну и ту же таблицу, с уже вставленной строкой. НеофитSQL Есть ли логическое обоснование, почему после-триггеру запрещено прочитать из таблицы только что вставленную строку, или это просто ограничение имплементации? И почитай разницу между блокировочниками и версионниками среди СУБД. Это к вопросу имплементации. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2020, 02:51 |
|
Чтение таблицы из триггера (after-insert)
|
|||
---|---|---|---|
#18+
booby, О неоткатываемых действиях и прочих "обманах". Одно известное мне сегодня неоткатываемое действие - запись ошибок исполнения в лог/таблицу ошибок. Логгинг, по своей природе, не следует отката, и сохраняет сообщения об ошибках кода даже при откатах. Я не знаю, есть ли код с побочными эффектами кроме лога ошибок, но посмотрю. Я следую установленной в продукте архитектуре, которая использует триггеры довольно обширно, включая каскадную их разновидность, когда изменение строки в одном представлении выстреливает триггеры в нескольких других. Это выглядело способным вызвать кольцевую зависимость, поэтому я для себя набросал иерархию представлений и таблиц - какие триггеры могут писать в какие таблицы. Все пока легло в дерево, т.е. каждое одиночное изменение должно закончиться в конечное время. Возможно, уже кто-то написал best practices: как в оракле принято обрабатывать внешние события, и я просто ещё не нашел этот труд. Он мог бы начинаться "избегайте таблиц с триггерами в качестве механизма передачи внешних событий, вместо этого оформите внешние события в виде...."? Сообщений? Запросов? Поллинга внешних таблиц? Как это принято делать? ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2020, 02:53 |
|
Чтение таблицы из триггера (after-insert)
|
|||
---|---|---|---|
#18+
Я благодарен вашему терпению. Я наверное задаю новичковые вопросы. С триггерами познакомился буквально два дня назад. Правильный Вася НеофитSQL Почему таблица считается мутирующей на чтение в "после" триггере? Не забывай, что другой триггер на это row-событие (или в целом на table-событие) может попытаться что-то сделать, что вызовет exception, а это автоматом отменит транзакцию. Например, в другом триггере будет неудачная попытка каскадных изменений в каких-то зависимых таблицах или сложная проверка целостности данных. Я понимаю что до коммита строка в таблице только для сессии, а не глобально. И коммита ещё может не произойти. Однако, в других ситуациях оракл вполне позволяет мне читать строку для которой ещё не произошел коммит. С точки зрения сессии новая строка уже в таблице, и я могу на ней исполнить селект. Только не даёт это сделать в триггере. Поэтому я спросил. Разве триггер исполняется не в контексте сессии? [quot Ну так row-триггеры и видят ровно одну свою строку в :NEW. [/quot] Я бы этим и пользовался, но у этой псевдопеременной есть ограничения, она не типа rowtype, и ее нельзя передать как параметр. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2020, 03:15 |
|
Чтение таблицы из триггера (after-insert)
|
|||
---|---|---|---|
#18+
НеофитSQL ... Одно известное мне сегодня неоткатываемое действие - запись ошибок исполнения в лог/таблицу ошибок. Логгинг, по своей природе, не следует отката, и сохраняет сообщения об ошибках кода даже при откатах. о, боже... "логгинг" - это что, синоним "элегантности"? Есть "логгинг" и "логгинг". Если происходит плановый отказ от завершения транзакции - зачем вообще логировать планово несостоявшиеся действия? Если же фиксируются действия, отвергнутые по наличию ошибок заполнения данных, то это называется не "логгинг", а "валидация". Необходимость сохранения её результатов определяется либо потребностями программиста в трассировке на период отладки, либо конкретными особенностями устройства процедур проверки качества данных. В обоих случаях это не побочный, а явный результат специально организованного процесса, в общем случае, состоящего из произвольного числа транзакций. Вы в своих триггерах ифы писать замучаетесь, чтобы понять, какой именно красоты логирование именно сейчас требуется. У вас вставка в таблицу в таком варианте намертво привязывается к имени процесса, его производящего. Ну, или будете логировать всё подряд в общую мусорку, и результатом нельзя будет воспользоваться содержательно. Конечно, много изумительной мути, в триггерах можно наваять. НеофитSQL ... Как это принято делать? А вот как очередной свежепришедший неофит наляпяет, так и приято. Статистически неотличимая от 100% доля "ынтырпрайза" не является непроходимым гуаном чуть менее, чем целиком. В том числе и в области "логирования". Обычно это является печальным результатом блестящего образования, большого опыта работы, высокой степени самооценки и безграничного доверия руководства. ... И только очумевшие администраторы изредка постанывают - "Ау! Есть читатели на эти великолепные логи? Когда и какой мусор сносить-то можно, к чёртовой матери, или его надо ленту писать?..." ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2020, 04:00 |
|
Чтение таблицы из триггера (after-insert)
|
|||
---|---|---|---|
#18+
Сессия и транзакция - суть 2 больших разницы. Читай уже доку , что ль. Изучать монстров типа Оракл по сообщениям форума - это как по учебнику ботаники пытаться понять работу космического корабля во всех нюансах. Сначала базовые вещи, потом детали. НЕ наоборот. У Оракла достаточно документации для РАЗНЫХ уровней подготовки, даже нулячих. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2020, 04:00 |
|
Чтение таблицы из триггера (after-insert)
|
|||
---|---|---|---|
#18+
В первую очередь это сделано именно из-за многострочных операторов Согласованность любого запроса поддерживается на уровне SCN, и строки все будут вставлены/обновлены/удалены тоже на один момент SCN. А внутри одного оператора (многострочного) получится что на один и тот же SCN, триггер, стрельнувший для каждой строки, будет видеть разный набор данных, что противоречит основным принципам ACID ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2020, 04:00 |
|
Чтение таблицы из триггера (after-insert)
|
|||
---|---|---|---|
#18+
Вячеслав Любомудров, нет смысла ему абракадаброй говорить. Читать у него времени нет. Триггера писать надо. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2020, 04:21 |
|
Чтение таблицы из триггера (after-insert)
|
|||
---|---|---|---|
#18+
Нашел правильный ответ: Таблица мутирует потому что триггер построчный. Доступ к таблице работает нормально из непострочного после-триггера. Проблема решена, всем спасибо. Booby, ваши рассуждения о логгинге слишком упрощены и в данном случае неверны. Я могу посоветовать профильные книги, если вам интересно. Одно из требований доверия к логгингу - запретить любые изменения прошлых событий, в том числе откат. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2020, 04:37 |
|
Чтение таблицы из триггера (after-insert)
|
|||
---|---|---|---|
#18+
Вячеслав Любомудров В первую очередь это сделано именно из-за многострочных операторов Согласованность любого запроса поддерживается на уровне SCN, и строки все будут вставлены/обновлены/удалены тоже на один момент SCN. А внутри одного оператора (многострочного) получится что на один и тот же SCN, триггер, стрельнувший для каждой строки, будет видеть разный набор данных, что противоречит основным принципам ACID Не без труда, но расшифровал. Спасибо. Строки вставляются группой, а триггер однострочный. Мои трудности оказались связаны с однострочностью триггера, для которого в общем случае не существует стабильного промежуточного состояния таблицы. Для одиночного insert существует, но запрещен инженерами оракла. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2020, 04:45 |
|
Чтение таблицы из триггера (after-insert)
|
|||
---|---|---|---|
#18+
НеофитSQL ... Booby, ваши рассуждения о логгинге слишком упрощены и в данном случае неверны.... Спасибо, успокоили. А то я уже волноваться начал даже... ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2020, 04:46 |
|
Чтение таблицы из триггера (after-insert)
|
|||
---|---|---|---|
#18+
booby Если происходит плановый отказ от завершения транзакции - зачем вообще логировать планово несостоявшиеся действия? Но, да - это скорее аудит, чем протоколирование. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2020, 07:00 |
|
Чтение таблицы из триггера (after-insert)
|
|||
---|---|---|---|
#18+
Правильный Вася Потому что ещё не было коммита . [рукалицо] ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2020, 07:04 |
|
Чтение таблицы из триггера (after-insert)
|
|||
---|---|---|---|
#18+
НеофитSQL Одно из требований доверия к логгингу - запретить любые изменения прошлых событий, в том числе откат. P.S. И, да - вы всё равно идёте к звёздам не per astra. Запрет изменения реализуется ограничением доступа к таблице аудита. В концептах это всё тоже изложено. Хотя и не "прямо в лоб для вашего случая". ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2020, 07:05 |
|
Чтение таблицы из триггера (after-insert)
|
|||
---|---|---|---|
#18+
Правильный Вася НеофитSQL Почему таблица считается мутирующей на чтение в "после" триггере? Оказалось, дело было вовсе не в коммите. Блочный после-триггер читает таблицу без проблем. Построчный - не может, т.к. вызывается (иногда) между стабильными состояниями таблицы. Из-за этого "иногда" построчному после-триггеру всегда запрещено обращение к возможно мутирующей таблице. Я сейчас оценил, что ответ на мой вопрос "почему" требует глубоких знаний, и для всех есть возможность узнать что-то новое. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2020, 07:13 |
|
Чтение таблицы из триггера (after-insert)
|
|||
---|---|---|---|
#18+
Basil A. Sidorov НеофитSQL Одно из требований доверия к логгингу - запретить любые изменения прошлых событий, в том числе откат. P.S. И, да - вы всё равно идёте к звёздам не per astra. Запрет изменения реализуется ограничением доступа к таблице аудита. В концептах это всё тоже изложено. Хотя и не "прямо в лоб для вашего случая". Для протоколирования действий у меня отдельная таблица, где действительно работает откат. Логично, т.к. не случилось действие - нет протокола о нем. В логе ошибок у меня "безоткатные" данные, в том числе самодиагностика (asserts в лог) для ловли ошибок в моем коде, или недопустимые состояния, которых не должно быть. Поскольку мой код автоматизации работает без участия человека, мне очень помогает когда он сам рассказывает что у него болит. И не стирает свои жалобы, если где-то exception. А как этот вопрос решают колеры с опытом - просто пишут без ошибок? :) ... |
|||
:
Нравится:
Не нравится:
|
|||
19.10.2020, 07:28 |
|
|
start [/forum/topic.php?fid=52&msg=40009665&tid=1880777]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
77ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
66ms |
get tp. blocked users: |
1ms |
others: | 307ms |
total: | 491ms |
0 / 0 |