powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Про триггеры (заранее пардон).
7 сообщений из 7, страница 1 из 1
Про триггеры (заранее пардон).
    #33410951
Paul Chabinsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что-то я почитал про триггеры в ПГ, и не понял как же мне сделать многострочный триггер... как обрадиться к рекордсету над которым произошли манипуляции?
Вот пример того что я хочу сделать, триггер должен отрабатывать набор строк вставленных таблицу "srcTable":
Код: plaintext
1.
2.
3.
4.
/* В реальности нижеприведенный запрос содержит агрегации и подзапросы */
INSERT INTO dstTable (field1, field2)
SELECT n.field1, n.field2 FROM NEW n LEFT JOIN dstTable d
WHERE d.field1 IS NULL AND d.field2 IS NULL
...
Рейтинг: 0 / 0
Про триггеры (заранее пардон).
    #33410976
Фотография XM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Paul Chabinsky wrote:
> Что-то я почитал про триггеры в ПГ, и не понял как же мне сделать
> многострочный триггер... как обрадиться к рекордсету над которым
> произошли манипуляции?

Никак. Триггеры либо ROW-LEVEL - доступ к одной измененнной записи,
либо STATEMENT-LEVEL - без доступа к измененным записям.
Т.е. рекордсета нет в любом случае.
Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
Про триггеры (заранее пардон).
    #33411007
Paul Chabinsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мда...
А правилами такое можно сделать?
...
Рейтинг: 0 / 0
Про триггеры (заранее пардон).
    #33411024
Фотография XM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Paul Chabinsky wrote:
> Мда...
> А правилами такое можно сделать?

Врядли.
Хотя, в принципе, можно извратиться и в ROW-LEVEL триггере вносить PK
измененных записей во временную таблицу, а потом в STATEMENT-LEVEL
использовать эту инфу. :)

ЗЫ не проверял, так, первое что сходу придумалось.
Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
Про триггеры (заранее пардон).
    #33411053
Paul Chabinsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Задача то как раз в том чтоб триггер/что-то-еще, давало возможность многострочной обработки...

А если построчно делать темп, то почему построчно сразу не вставить просто и все :)

Все равно спасибо за помощь...
...
Рейтинг: 0 / 0
Про триггеры (заранее пардон).
    #33412631
фффф
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
XM
... в принципе, можно извратиться и в ROW-LEVEL триггере вносить PK
измененных записей во временную таблицу, а потом в STATEMENT-LEVEL
использовать эту инфу. :)

Делал такую эмуляцию MSSQL after-триггеров с таблицами inserted/deleted. Геморрой большой - надо на каждую табличку зеркальную создавать, потом эта таблица пухнет - надо часто вакуумить её. Тестовый скрипт выкладываю:
Код: plaintext
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.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
create table teststmt (id serial primary key, d text);
create table teststmt_tr (pid int default pg_backend_pid(), inserted bool, data teststmt);
create view teststmt_inserted as
  select (data).id, (data).d
  from teststmt_tr
  where pid=pg_backend_pid() and inserted;
create view teststmt_deleted as
  select (data).id, (data).d
  from teststmt_tr a
  where pid=pg_backend_pid() and not inserted;

CREATE OR REPLACE FUNCTION tf_teststmt_stmt_process() RETURNS trigger LANGUAGE plpgsql AS $body$
DECLARE
  _rec teststmt%rowtype;
BEGIN
  if TG_LEVEL = 'ROW' then
    --collect 'inserted'/'deleted' rows
    if TG_OP = 'INSERT' or TG_OP = 'UPDATE' then
      insert into teststmt_tr(inserted, data) values (true, NEW);
    end if;
    if TG_OP = 'DELETE' or TG_OP = 'UPDATE' then
      insert into teststmt_tr(inserted, data) values (false, OLD);
    end if;
  else
    if TG_WHEN = 'AFTER' then
      --process set of rows
      for _rec in (select * from teststmt_inserted) loop
        raise INFO 'inserted : % %', _rec.id, _rec.d;
      end loop;
      for _rec in (select * from teststmt_deleted) loop
        raise INFO 'deleted : % %', _rec.id, _rec.d;
      end loop;
    end if;
    
    --cleanup before and after row processing
    delete from teststmt_tr where pid=pg_backend_pid();
    --vacuum teststmt_tr;
  end if;
  
  return NEW;
END;
$body$;

CREATE TRIGGER teststmt_before_stmt BEFORE INSERT or UPDATE or DELETE
  ON teststmt FOR EACH STATEMENT
  EXECUTE PROCEDURE tf_teststmt_stmt_process();
CREATE TRIGGER teststmt_after_stmt AFTER INSERT or UPDATE or DELETE
  ON teststmt FOR EACH STATEMENT
  EXECUTE PROCEDURE tf_teststmt_stmt_process();
CREATE TRIGGER teststmt_after_row AFTER INSERT or UPDATE or DELETE
  ON teststmt FOR EACH ROW
  EXECUTE PROCEDURE tf_teststmt_stmt_process();

insert into teststmt(d) select 'hello';
insert into teststmt(d) select 'world';
insert into teststmt(d) select d||'!' from teststmt;
select * from teststmt;
select * from teststmt_tr;

update teststmt set d=d||'-upd';
select * from teststmt;
select * from teststmt_tr;

delete from teststmt;
select * from teststmt;
select * from teststmt_tr;
...
Рейтинг: 0 / 0
Про триггеры (заранее пардон).
    #33413077
Paul Chabinsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо, попробую...
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Про триггеры (заранее пардон).
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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