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

А зачем оно в триггере?

Вне его есть sql%rowcount.


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

НеофитSQLЕсли я правильно понял, я в строчном могу собрать, к примеру, ID вставленных строчек, а на
уровне оператора пройтись по списку?
Это чтобы обойти отсутствие "INSERTED" псевдотаблицы в Оракле. Да, так наверное можно, но
это уже превращается в тройной прыжок из-за неспособности PL/SQL передать :new как параметр.

Назовите таблицу, в которую будете вставлять вставленные строки, INSERTED и внезапно паззл
сложится.


Очень смешно. Это даст все строки, а не новые.
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009965
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
SQL> ed
Wrote file afiedt.buf

  1  declare
  2    type TRec is record(empno number(4) ,ename varchar2(10));
  3    v_r TRec;
  4    procedure p (p_rec TRec) is
  5    begin
  6      dbms_output.put_line(v_r.empno||' '||v_r.ename);
  7    end;
  8  begin
  9   v_r.empno:=7839;
 10   v_r.ename:='King';
 11   p(v_r);
 12* end;
SQL> /
7839 King

PL/SQL procedure successfully completed.



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

ORA-25002: cannot create INSTEAD OF triggers on tables

"Почему?" - "Не положено! Невозможно, несовместимо с теорией множеств и принципам СУБД!"

"А если я оберну эту таблицу в представление, тогда можно?" - "Ну, тогда да".

8-I
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009967
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
Dimitry Sibiryakov

пропущено...

Назовите таблицу, в которую будете вставлять вставленные строки, INSERTED и внезапно паззл
сложится.


Очень смешно. Это даст все строки, а не новые.


в строчном триггере вставляете строки в "INSERTED", в операторном обрабатываете

так возможно делать не надо, ето я токо для примера

.....
stax
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009968
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

Staxнасчет :new, смеритесь нет (возможно пока) в оракля new типа "record"

А параметр процедуры этого типа есть? Я честно не в курсе...

есть. через определение subtype:
Код: plsql
1.
SubType T_TYPE_FULL_ROW_NAME is RelationName%Rowtype;



PS1
а про составные (compaund) триггеры топикстартер так и не нашел времени почитать.

PS2
мало жести.
Что за скука такая - "логирование из триггера".
Давай почту отправлять, что-ли, в конце-то концов.
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009969
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL,
ты шипучки сегодня много перепил.
Клоун, ты надоел, сними колпак.
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009974
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
Похоже, я царапнул часть, где у Оракла есть недоделки.

ORA-25002: cannot create INSTEAD OF triggers on tables

"Почему?" - "Не положено! Невозможно, несовместимо с теорией множеств и принципам СУБД!"

"А если я оберну эту таблицу в представление, тогда можно?" - "Ну, тогда да".

8-I


конешно, напр навесьте обычный триггер на вью

.....
stax
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009976
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby

а про составные (compaund) триггеры топикстартер так и не нашел времени почитать.


особенно compaund и мерже

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

если ты про глобальные переменные уровня триггера - пакетных переменных вроде ещё никто не отменял.
А так да, баг.
Но это милый, обходимый баг.

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


Очень смешно. Это даст все строки, а не новые.


в строчном триггере вставляете строки в "INSERTED", в операторном обрабатываете

так возможно делать не надо, ето я токо для примера

.....
stax


Согласен, не надо таблицу заводить, где списак ID хватило бы,

Думаю что есть решение проще, чем через кампаунд триггер собирать ID, потом их обрабатывать:
- в таблице есть ID, который монотонно растет. Если знать максимальный ID до Insert, легко извлекаются все строчки из statement-level триггера.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
create or replace trigger TR_TST_AFTER_INSERT
  after insert on tst  
begin
  dbms_output.put_line( 'Statement level trigger' );
  for rnew in (select * from TST t where t.id > MaxIDbeforeInsert order by t.id)
  loop
    dbms_output.put_line( rnew.id ||','|| rnew.n );
  end loop;
end TR_TST_AFTER_INSERT;



MaxIDbeforeInsert - это функция которая научилась подглядывать max(tst.id) до вставки/коммита новых строк при вызове из после-триггера.

Проверил - работает как ожидается.
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40009988
Неофит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' ); -- не дает передать :new псевдорекорд
end;



СТАЛО:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
CREATE OR REPLACE TRIGGER TR_REACTOR_EVENTS
  after insert on REACTOR_EVENTS -- в таблицу пишутся данные снаружи
begin
  for r in (select * from REACTOR_EVENTS re where re.id > PriorMaxId)
  loop
    PROCESS_REACTOR_EVENT( r, '-verbose -journal' );
  end loop;
end;
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40010000
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
Если знать максимальный ID до Insert, легко извлекаются все строчки из statement-level триггера.

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

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


В таблицу импорта событий пишет один пользователь, больше никто. Единственная операция - insert(1line)/commit, поэтому триггер будет вызываться строго сериализованно.

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

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

Тебе уже два раза сказали про Database Change Notification. И я ещё добавлю про Advanced
Queueing и её меньшего брата Publish-Subscribe.

С какого раза до тебя дойдёт, что без чтения документации ты так и будешь тыкаться слепым
кутёнком во все розетки?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40010038
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да прикольно же
Чувак думает, что он очень умный и заточил бы все намного лучше, а причина кривых решений всего лишь совместимость с legacy кодом и тупизна разработчиков (как во время разработки, так и сейчас)
Уже не раз сказали про разницу между версионником и блокировочником и многопользовательскую работу. Но, поскольку опыта нет -- делаются какие-то дикие умозаключения.

2Аффтар: Вот, кстати, тоже интересный пример многопользовательской работы, когда строчный before триггер срабатывает несколько раз вместо одного. Можешь подумать/погуглить почему так происходит (про миниоткаты/рестарты уже намекали)
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
tst> create table t_neofit as select rownum id, rownum val from dual connect by level <= 3;

Table created.

tst> create trigger t_neofit_trg before update on t_neofit for each row
  2  begin dbms_output.put_line(:new.id||': '||:old.val||' -> '||:new.val);
  3  end;
  4  /

Trigger created.

tst> set serveroutput on

-- в других сессиях производятся действия с этой таблицей

tst> update t_neofit set val=val+10;
1: 1 -> 11
2: 2 -> 12
3: 3 -> 13
1: 1 -> 11
2: 2 -> 12
3: 4 -> 14

3 rows updated.

tst> select * from t_neofit;

        ID        VAL
---------- ----------
         1         11
         2         12
         3         14

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

НеофитSQLЖаль, что я не знаю другого удобного способа пуш-передачи событий в Оракл, какие-нибудь
встроенные уведомления или сообщения были бы в самый раз..

Тебе уже два раза сказали про Database Change Notification...


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

Поллинг не предлагать :)
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40010048
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я так понимаю, "хотя бы бегло ознакомиться что такое Database Change Notification" тоже не предлагать
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40010050
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вячеслав Любомудров
Да прикольно же
2Аффтар: Вот, кстати, тоже интересный пример многопользовательской работы, когда строчный before триггер срабатывает несколько раз вместо одного. Можешь подумать/погуглить почему так происходит (про миниоткаты/рестарты уже намекали)
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
tst> create table t_neofit as select rownum id, rownum val from dual connect by level <= 3;

Table created.

tst> create trigger t_neofit_trg before update on t_neofit for each row
  2  begin dbms_output.put_line(:new.id||': '||:old.val||' -> '||:new.val);
  3  end;
  4  /

Trigger created.

tst> set serveroutput on

-- в других сессиях производятся действия с этой таблицей

tst> update t_neofit set val=val+10;
1: 1 -> 11
2: 2 -> 12
3: 3 -> 13
1: 1 -> 11
2: 2 -> 12
3: 4 -> 14

3 rows updated.

tst> select * from t_neofit;

        ID        VAL
---------- ----------
         1         11
         2         12
         3         14

tst> 



Действительно интересно. Сам не догадался, но спасибо Гуглу, теперь понимаю почему триггер вызвался более трех раз:
В таблицу одновременно пишут более одного пользователя. ОК, многопользовательский режим, рестарты, там свои погремушки.

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

insert 1 line /commit; -- одно событие, пришла новая строка
insert 1 line /commit; -- через минуту еще событие, еще строка
insert 1 line /commit; -- и так много полезных событий, которые надо обработать
...

А в триггере события читаю. Эксепшн обрабатываю, каждый insert/commit успешный.

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

Наверное можно было и посложнее что-то замутить, чтоб было что отлаживать. Чтоб все события из разных источников в одну таблицу ломились из разных сессий, и чтоб обработчик событий тоже туда писал, и обработку ошибок через эксепшн - пусть внешний скрипт ловит. Одновременно чистить таблицу из джоба от старых данных, переставляя строки... :)

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

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


Возможно, я что-то пропустил, когда читал про это. Рассматривал использование этого механизма для уведомления клиентов (терминалы) об изменении в адресной книге на сервере, поэтому запомнил что это уведомление от сервера к клиенту.

Если он может работать в другую сторону, я об этом очевидно не знал. Посмотрев на сетап такого механизма, он в разы более трудоемкий чем stateless insert/commit который я могу исполнить хоть из шелла, хоть из аутлука.

Начинаю думать, что передача низкочастотных сообщений через insert-only таблицы был выбран удачно, возможно оптимально для моих целей. От (пока недолгих) вычислений в импорт-триггере я не в восторге; что именно меня смущает, пока не могу сказать. Может, синхронная привязка к импорту, выглядит неэффективно. Для событий частотой в 0.02 герц должно работать без проблем.
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40010063
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
чтобы все было просто и удобно, особенно для меня
... и мне вообще покласть с прибором и пробором на тех у кого другие нужды и потребности. Подчёркнуто мною.
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40010068
Фотография кит северных морей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
Для событий частотой в 0.02 герц должно работать без проблем.

не совсем.
https://docs.oracle.com/cd/E11882_01/server.112/e22490/ldr_modes.htm#SUTIL1335 Database Insert Triggers
Table insert triggers are also disabled when a direct path load begins. After the rows are loaded and indexes rebuilt, any triggers that were disabled are automatically reenabled. The log file lists all triggers that were disabled for the load. There should not be any errors reenabling triggers.

Unlike integrity constraints, insert triggers are not reapplied to the whole table when they are enabled. As a result, insert triggers do not fire for any rows loaded on the direct path. When using the direct path, the application must ensure that any behavior associated with insert triggers is carried out for the new rows.
завтра поменяется логика вставки в вашу таблицу, и привет.
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40010081
Фотография env
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL,

Искренне жаль тех, кому придётся потом это сопровождать. Они не будут знать умозаключений про 0.2 герца, гарантию однопользовательской работы и т.п. Зато будут совершенно искренне материть "умника", влепившего > priorMaxId в триггер, когда наконец докопаются до источника ошибки.
...
Рейтинг: 0 / 0
Чтение таблицы из триггера (after-insert)
    #40010106
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
env,

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

не совсем.
https://docs.oracle.com/cd/E11882_01/server.112/e22490/ldr_modes.htm#SUTIL1335 Database Insert Triggers
Table insert triggers are also disabled when a direct path load begins. After the rows are loaded and indexes rebuilt, any triggers that were disabled are automatically reenabled. The log file lists all triggers that were disabled for the load. There should not be any errors reenabling triggers.

Unlike integrity constraints, insert triggers are not reapplied to the whole table when they are enabled. As a result, insert triggers do not fire for any rows loaded on the direct path. When using the direct path, the application must ensure that any behavior associated with insert triggers is carried out for the new rows.

завтра поменяется логика вставки в вашу таблицу, и привет.

Кит, я не знал о названии direct load, это используется при backup/restore? Логично что в особых ситуациях для "старых" данных триггеры не вызовутся заново. В моем случае, попытка вогнать новые данные без insert триггеров потерпит неудачу, т.к. до-триггер проставляет PK в non-nullable колонку.

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


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