powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / rule не заменяет а дополняет insert - видно если есть триггер
9 сообщений из 9, страница 1 из 1
rule не заменяет а дополняет insert - видно если есть триггер
    #38427279
Адель
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте, уважаемые!

Столкнулся вот с какой странностью.

Код: 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.
create table tst(a integer primary key, b varchar);

CREATE OR REPLACE RULE tst_rule AS
   ON INSERT TO tst
   where exists (select 1 from tst  WHERE a = new.a)
      DO instead
UPDATE tst SET b = new.b  WHERE a = new.a;


CREATE FUNCTION tst_update() RETURNS trigger AS $$
    BEGIN
        RAISE notice 'TG_OP =  %, id = %', TG_OP, new.a;
        if TG_OP = 'UPDATE' then
          RAISE notice 'old b % => bew.b %', old.b, new.b;
       END if;
        return new;
    END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER tst_update after INSERT OR UPDATE ON tst
    FOR EACH ROW EXECUTE PROCEDURE tst_update();

insert into tst values (1, '11');
insert into tst values (1, '22');

-- видно, что на первый insert триггер запускается два раза - для вставки и для замены c '11' на '11'. 
-- Второй insert вызывает только один update. 


drop FUNCTION tst_update() cascade;

drop table tst;



Вроде ничего страшного, проверяешь что old = new и выходишь, но может можно как-то второй раз триггер вообще не запускать?
...
Рейтинг: 0 / 0
rule не заменяет а дополняет insert - видно если есть триггер
    #38427361
ССЗБ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Адель,

а чего вы тут видите странного ?
сначала руле не исполняется, посколь не выполнено
where exists (select 1 from tst WHERE a = new.a)
потом руле в принципе не атомарно, т.е. сказать где у него сначала, и что будет потом, и в каком месте оно будет считать NEW (rcnfnb yjdjt d rf;ljv vtnct tuj egjvbyfybz) - ,tp cnfrfyf yt elf`ncz

- короче, переведёте, я замахался что-то


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


т.ч. любой удод, без надобности юзающий руле - сам себе злобный буратино, одеревеневший по пояс, причём - с обоих концов
...
Рейтинг: 0 / 0
rule не заменяет а дополняет insert - видно если есть триггер
    #38428969
Адель
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ССЗБАдель,

в общем в какой-то момент мы после инсерта попадаем опять в руле внутри той же транзы (думаю - аккурат на вашем return new;


Вот это и странно.

Хорошо, руле убиваем,пишем все в триггере

Код: 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.
create table tst(a integer primary key, b varchar);

CREATE FUNCTION tst_update() RETURNS trigger AS $$
    BEGIN
        RAISE notice 'TG_OP =  %, id = %', TG_OP, new.a;
        if TG_OP = 'INSERT' then
           perform 1 from tst where a = new.a;
           if found then
              RAISE notice 'update instead of insert will be performed';
              update tst set b = new.b where a = new.a;
              return null; -- не выполняем insert и защищаемя от duplicate rows, 
                           -- но клиентское приложение обманываем, говоря что 0 строчек изменено
           end if;
        end if;
        if TG_OP = 'UPDATE' then
          RAISE notice 'old b % => new.b %', old.b, new.b;
        END if;
        -- some logic
        RAISE notice '% operation performed', TG_OP;
        return new;
    END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER tst_update before insert or UPDATE ON tst
FOR EACH ROW
    EXECUTE PROCEDURE tst_update();

insert into tst values (2, '21');
insert into tst values (2, '22');

select * from tst;

drop FUNCTION tst_update() cascade;
drop table tst;



Все работает, но insert возвращает приложению 0, если заменяется на апдейт. А чтобы всем было хорошо - никак?
...
Рейтинг: 0 / 0
rule не заменяет а дополняет insert - видно если есть триггер
    #38429124
ССЗБ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Адель,

ах, ви в этом смыысле

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

и таки да "returning" -- это проблема, что для партицирования , что для апсерта. Поищите по форуму или в гугле - кажется я видел сносные (и, вроде, более приличные, чем делетить псевдовставку) решения и там.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
rule не заменяет а дополняет insert - видно если есть триггер
    #39325789
Фотография Legushka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
АдельВсе работает, но insert возвращает приложению 0
в гугле есть такое решение для инсерта на rule:
1. делаем вьюху на нашу таблицу
2. делаем instead of тригер на вьюху на insert где запустите ваш tst_update
3. делаем rule и прописываем правило что при инсерте надо делать вставку во вьюху

минус решения: rule и CTE в одном запросе не работают

без rule, вы вместо вставки в таблицу делаете вставку во вьюху, можно даже вью и таблицу поменять местами
но надо так же будет создать instead of на апйдейт и на делет
...
Рейтинг: 0 / 0
rule не заменяет а дополняет insert - видно если есть триггер
    #39325790
Фотография Legushka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
АдельВсе работает, но insert возвращает приложению 0
в гугле есть такое решение для инсерта на rule:
1. делаем вьюху на нашу таблицу
2. делаем instead of тригер на вьюху на insert где запустите ваш tst_update
3. делаем rule и прописываем правило что при инсерте надо делать вставку во вьюху

минус решения: rule и CTE в одном запросе не работают

без rule, вы вместо вставки в таблицу делаете вставку во вьюху, можно даже вью и таблицу поменять местами
но надо так же будет создать instead of на апйдейт и на делет
...
Рейтинг: 0 / 0
rule не заменяет а дополняет insert - видно если есть триггер
    #39326411
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Legushka,

"а ты азартен , парамоша" (сс)

вы там , в казане совсем все сварились
одного 3 года тому отучали от руля
так теперь другой варвар все руки пообрезал, а всё туда же
"лавровы, ля"

----

напоминаю, ссылка на интернеты тут 19738578
реализация в т.ч с апдейтом -- тут 19763729
...
Рейтинг: 0 / 0
rule не заменяет а дополняет insert - видно если есть триггер
    #39326807
Фотография Legushka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwq, ваша взяла, реализация на rule заваливает нагрузочные тесты в ERROR: out of shared memory
буду отучаться-)
хочу реализовать вашу схему: заменить вместо таблицы вьюху, навесить тригеры instead of -)
...
Рейтинг: 0 / 0
rule не заменяет а дополняет insert - видно если есть триггер
    #39327295
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Legushkaqwwq, ваша взяла, реализация на rule заваливает нагрузочные тесты в ERROR: out of shared memory
буду отучаться-)
хочу реализовать вашу схему: заменить вместо таблицы вьюху, навесить тригеры instead of -)

я вот тут думал послабление сделать -- ещё одного предка завести, опубликовать, а вью спрятать и через рули от публичного корня задействовать, чтобы его системные видеть как родные. так блин оно с рулями ещё и ретёнить не умеет. пишет -- "не могу с инстеад рулями returning делать". т.ч все эти рули -- зыбкое нечто. с перепоя оно там, не иначе.
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / rule не заменяет а дополняет insert - видно если есть триггер
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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