powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Триггер на дочернюю таблицу
6 сообщений из 6, страница 1 из 1
Триггер на дочернюю таблицу
    #39493008
Sheriffua
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Собственно вопрос, КАК это сделать, если при INSERT триггер срабатывает корректно, а на UPDATE триггер не срабатывает. Кто-то решал такую проблему?
Опишу суть.
1. Есть таблица документов - documents
2. В ней есть поле dt_registration
3. Также нарезаны патиции по годам, от 2006 до 2017
Теперь, есть триггер такого вида (на родителе):

Код: sql
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.
CREATE OR REPLACE FUNCTION public.documents_insert_trigger (
)
RETURNS trigger AS
$body$
BEGIN
 -- raise exception 'XAXAXAXA';
  
    IF ( NEW.dt_registration >= DATE '2006-01-01' AND
         NEW.dt_registration < DATE '2007-01-01' ) THEN
        INSERT INTO documents_2006 VALUES (NEW.*);
    ELSIF ( NEW.dt_registration >= DATE '2007-01-01' AND
            NEW.dt_registration < DATE '2008-01-01' ) THEN
        INSERT INTO documents_2007 VALUES (NEW.*);
    ELSIF ( NEW.dt_registration >= DATE '2008-01-01' AND
            NEW.dt_registration < DATE '2009-01-01' ) THEN
        INSERT INTO documents_2008 VALUES (NEW.*);
    ELSIF ( NEW.dt_registration >= DATE '2009-01-01' AND
            NEW.dt_registration < DATE '2010-01-01' ) THEN
        INSERT INTO documents_2009 VALUES (NEW.*);
    ELSIF ( NEW.dt_registration >= DATE '2010-01-01' AND
            NEW.dt_registration < DATE '2011-01-01' ) THEN
        INSERT INTO documents_2010 VALUES (NEW.*);
    ELSIF ( NEW.dt_registration >= DATE '2011-01-01' AND
            NEW.dt_registration < DATE '2012-01-01' ) THEN
        INSERT INTO documents_2011 VALUES (NEW.*);
    ELSIF ( NEW.dt_registration >= DATE '2012-01-01' AND
            NEW.dt_registration < DATE '2013-01-01' ) THEN
        INSERT INTO documents_2012 VALUES (NEW.*);
    ELSIF ( NEW.dt_registration >= DATE '2013-01-01' AND
            NEW.dt_registration < DATE '2014-01-01' ) THEN
        INSERT INTO documents_2013 VALUES (NEW.*);
    ELSIF ( NEW.dt_registration >= DATE '2014-01-01' AND
            NEW.dt_registration < DATE '2015-01-01' ) THEN
        INSERT INTO documents_2014 VALUES (NEW.*);
    ELSIF ( NEW.dt_registration >= DATE '2015-01-01' AND
            NEW.dt_registration < DATE '2016-01-01' ) THEN
        INSERT INTO documents_2015 VALUES (NEW.*);
    ELSIF ( NEW.dt_registration >= DATE '2016-01-01' AND
            NEW.dt_registration < DATE '2017-01-01' ) THEN
        INSERT INTO documents_2016 VALUES (NEW.*);
    ELSIF ( NEW.dt_registration >= DATE '2017-01-01' AND
            NEW.dt_registration < DATE '2018-01-01' ) THEN
        INSERT INTO documents_2017 VALUES (NEW.*);
    ELSIF ( NEW.dt_registration >= DATE '2018-01-01' OR
            NEW.dt_registration < DATE '2006-01-01' ) THEN
        INSERT INTO documents_musor VALUES (NEW.*);
    ELSE
        RAISE EXCEPTION 'Date out of range.  Fix the documents_insert_trigger() function!';
    END IF;
    RETURN NULL;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;



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

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
CREATE OR REPLACE FUNCTION public.test_update (
)
RETURNS trigger AS
$body$
BEGIN
raise exception '44444444444444444444';
  
  IF (NEW.dt_registration is distinct from OLD.dt_registration)	THEN 
    INSERT INTO documents VALUES (NEW.*);
    RETURN NULL;    
  ELSE
    --INSERT INTO documents VALUES (OLD.*);
    RETURN new;
  END IF;
  
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;



и точ я вижу, когда запускаю команду :
Код: plsql
1.
update documents set dt_registration='01.01.2000' where doc_id=67451371;


Код: sql
1.
Запрос выполнен успешно, затронуто записей: 1 (выполнено: 16 мс; всего: 47 мс)


Хотя по логике должен быть вызван:
Код: sql
1.
exception '44444444444444444444'


Пока я в тупике, может есть варианты как это обойти?
...
Рейтинг: 0 / 0
Триггер на дочернюю таблицу
    #39493023
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sheriffua,

2 варианта.

1. "неправильный" (на мой вкус)
-- вью вместо головной с "инстеад-офами". (где-то тут было в примерах у легушки расписано 19757774 )

удобства -- в RETURNING-ах (их "поддержке" на уровне "головных")


2. более, на мой вкус, верный
-- триггера на апдейт на партициях. (например проверять только констрайнт, и , удалив при необходимости , невлезающее -- перевставлять запись в "головную", не копируя* логику разброса по партициям из триггера вставки)

неудобства -- в RETURNING-ах , вернее их отсутствии (при BEFORE тр--ах).
удобство -- например в доступности tableoid --ов.

* спорно, если бороться за произв-сть. "зато" меньше дублирующего кода
...
Рейтинг: 0 / 0
Триггер на дочернюю таблицу
    #39493899
Sheriffua
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwq,

спасибо за предоставленные варианты.
...
Рейтинг: 0 / 0
Триггер на дочернюю таблицу
    #39493972
Sheriffua
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwq,

может еще подскажите как привязаться к динамической дате?
делаю так:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
BEGIN
	BEGIN
                EXECUTE 'INSERT INTO documents_'||to_char(NEW.DT_REGISTRATION, 'YYYY')||' SELECT $1.*' USING NEW;
            EXCEPTION
            WHEN undefined_table THEN
                RETURN NEW;
            END;
            RETURN NULL;
END;



это срабатывает только для дочерних таблиц, если они созданы для атрибута DT_REGISTRATION, НО есть такой вариант, что может быть запись с несуществующей дочерней таблицей, т.е. дата будет 01-05-1899 (как следствие нет таблицы documents_1899) и такую запись хотелось бы помещать в таблицу, например - documents_musor.
...
Рейтинг: 0 / 0
Триггер на дочернюю таблицу
    #39494066
Sheriffua
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сделал так:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
DECLARE
year_extr bigint;
BEGIN
	SELECT date_part('year', NEW.DT_REGISTRATION) INTO year_extr;
	IF year_extr<2006 and year_extr>2017 THEN
    INSERT INTO documents_musor VALUES (NEW.*);
    ELSE
    EXECUTE 'INSERT INTO documents_'||to_char(NEW.DT_REGISTRATION, 'YYYY')||' SELECT $1.*' USING NEW;
    END IF;
    RETURN NEW;
END;



может как-то криво, но ничего другого в голову пока не пришло.
...
Рейтинг: 0 / 0
Триггер на дочернюю таблицу
    #39494197
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sheriffua,

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


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