powered by simpleCommunicator - 2.0.40     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Порядок срабатывания ограничений (очередной переход с оракла на пг)
7 сообщений из 7, страница 1 из 1
Порядок срабатывания ограничений (очередной переход с оракла на пг)
    #40123884
AndreyDmt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Дня два назад начал пробовать сдублировать оракловую БД на ПГ, вроде все проблемы решаемы пока, но вот чего я не обнаружил - это собственно сабж. Ситуация следующая:
- создаю домен dmn1 not null
- создаю таблицу, в которой есть поле fld1 тип dmn1
- создаю триггер (функцию) before insert в которой есть if (new.fld1 is null then new.fld1 := val)
Как следствие - при вставке ругается, что домен не может быть null.
Если заменить поле на стандартный тип и поставить непосредственно на поле not null, то дело до триггера доходит и всё нормально вставляется. Подозреваю, что не одна такая заковырка может встретится на начальном пути.
Как результат, пытаюсь найти какие то слова в доке (основное пока - с postgespro.ru) , книгах по сабж - не нахожу. Во решил перед НГ (не все ж праздники пить) общественность попросить подсказать, где про сие можно прочитать, чтобы не путём ошибок трудных идти.
...
Рейтинг: 0 / 0
Порядок срабатывания ограничений (очередной переход с оракла на пг)
    #40123894
Guzya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Можете привести команды, чтоб поиграться можно было.
...
Рейтинг: 0 / 0
Порядок срабатывания ограничений (очередной переход с оракла на пг)
    #40123923
AndreyDmt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Guzya,
если ничего не попутал, как то так это выглядит. Экспериментирую, меняю постоянно

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
CREATE DOMAIN dmn$_update_date AS
  TIMESTAMP WITHOUT TIME ZONE NOT NULL;
CREATE DOMAIN dmn$_metaid AS
  integer NOT NULL;
CREATE SEQUENCE seq$test_triggers
  INCREMENT 1 MINVALUE 1
  MAXVALUE 9223372036854775807 START 1
  CACHE 1 OWNED BY NONE;



Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
CREATE TABLE test_triggers (
  object_recordid dmn$_objectrecord DEFAULT nextval('seq$test_triggers'::regclass) NOT NULL,
  version_id dmn$_metaid DEFAULT 0 NOT NULL,
  profile_id dmn$_metaid DEFAULT 5 NOT NULL,
  entitygroup_id dmn$_metaid DEFAULT 2 NOT NULL,
  update_date dmn$_update_date,
-- или update_date TIMESTAMP WITHOUT TIME ZONE NOT NULL,
  CONSTRAINT test_triggers_pkey PRIMARY KEY(object_recordid)
) ;

CREATE TRIGGER test_triggers_bi01
  BEFORE INSERT 
  ON test_triggers
  
FOR EACH ROW 
  EXECUTE PROCEDURE test_new_object();



Код: 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.
CREATE OR REPLACE FUNCTION test_new_object (
)
RETURNS trigger AS
$body$
BEGIN
	new.version_id := 0;
	new.profile_id := 5;
	new.entitygroup_id := 1;
	if new.update_date is null THEN
		NEW.update_date := current_timestamp;
	end if;
-- Ещё одна проверка от оракла
--	if new.object_recordid is null then
--		new.object_recordid := nextval('seq$test_triggers');
--	end if;
	return new;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
PARALLEL UNSAFE
COST 100;



Вставка стандартно (проверяю также подмену значений в тригере для прочих полей и генерацию ключа)
Код: sql
1.
2.
3.
insert into test_triggers (version_id, profile_id, entitygroup_id)
VALUES(2,2,2);
commit;
...
Рейтинг: 0 / 0
Порядок срабатывания ограничений (очередной переход с оракла на пг)
    #40123930
AndreyDmt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Guzya,

А, и ключевые моменты (версия ПГ-12)
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
CREATE DOMAIN dmn$_update_date AS
  TIMESTAMP WITHOUT TIME ZONE NOT NULL;

-- В зависимости от определения поля, появляется ошибка или нет
  update_date dmn$_update_date,
-- или update_date TIMESTAMP WITHOUT TIME ZONE NOT NULL,

-- При определении через домен, до этого места не доходит
  if new.update_date is null THEN
		NEW.update_date := current_timestamp;
	end if;
...
Рейтинг: 0 / 0
Порядок срабатывания ограничений (очередной переход с оракла на пг)
    #40123964
Guzya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Наверное не совсем то, но вопрос решается установкой default для поля

Код: 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.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
postgres=# \d test_triggers
                                      Table "public.test_triggers"
     Column      |        Type        | Collation | Nullable |                 Default                  
-----------------+--------------------+-----------+----------+------------------------------------------
 object_recordid | integer            |           | not null | nextval('"seq$test_triggers"'::regclass)
 version_id      | "dmn$_metaid"      |           | not null | 0
 profile_id      | "dmn$_metaid"      |           | not null | 5
 entitygroup_id  | "dmn$_metaid"      |           | not null | 2
 update_date     | "dmn$_update_date" |           |          | CURRENT_TIMESTAMP
Indexes:
    "test_triggers_pkey" PRIMARY KEY, btree (object_recordid)
Triggers:
    test_triggers_bi01 BEFORE INSERT ON test_triggers FOR EACH ROW EXECUTE FUNCTION test_new_object()

postgres=# 

postgres=# insert into test_triggers (version_id, profile_id, entitygroup_id)
VALUES(2,2,2);
INSERT 0 1
postgres=# select * from test_triggers \gx
-[ RECORD 1 ]---+---------------------------
object_recordid | 2
version_id      | 0
profile_id      | 5
entitygroup_id  | 1
update_date     | 2021-12-29 11:57:11.594805

postgres=#



postgres=# alter domain "dmn$_update_date" set default current_timestamp;
ALTER DOMAIN

postgres=# alter table test_triggers alter COLUMN update_date drop default;
ALTER TABLE

postgres=# \d test_triggers
                                      Table "public.test_triggers"
     Column      |        Type        | Collation | Nullable |                 Default                  
-----------------+--------------------+-----------+----------+------------------------------------------
 object_recordid | integer            |           | not null | nextval('"seq$test_triggers"'::regclass)
 version_id      | "dmn$_metaid"      |           | not null | 0
 profile_id      | "dmn$_metaid"      |           | not null | 5
 entitygroup_id  | "dmn$_metaid"      |           | not null | 2
 update_date     | "dmn$_update_date" |           |          | 
Indexes:
    "test_triggers_pkey" PRIMARY KEY, btree (object_recordid)
Triggers:
    test_triggers_bi01 BEFORE INSERT ON test_triggers FOR EACH ROW EXECUTE FUNCTION test_new_object()

postgres=# insert into test_triggers (version_id, profile_id, entitygroup_id)
VALUES(2,2,2);
INSERT 0 1
postgres=# insert into test_triggers (version_id, profile_id, entitygroup_id)
VALUES(2,2,2);
INSERT 0 1
postgres=# insert into test_triggers (version_id, profile_id, entitygroup_id)
VALUES(2,2,2);
INSERT 0 1
postgres=# insert into test_triggers (version_id, profile_id, entitygroup_id)
VALUES(2,2,2);
INSERT 0 1

postgres=# select * from test_triggers;
 object_recordid | version_id | profile_id | entitygroup_id |        update_date         
-----------------+------------+------------+----------------+----------------------------
               2 |          0 |          5 |              1 | 2021-12-29 11:57:11.594805
               3 |          0 |          5 |              1 | 2021-12-29 12:01:22.52968
               4 |          0 |          5 |              1 | 2021-12-29 12:01:23.673485
               5 |          0 |          5 |              1 | 2021-12-29 12:01:24.201779
               6 |          0 |          5 |              1 | 2021-12-29 12:01:24.617591
(5 rows)
...
Рейтинг: 0 / 0
Порядок срабатывания ограничений (очередной переход с оракла на пг)
    #40123987
Павел Лузанов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndreyDmt
Дня два назад начал пробовать сдублировать оракловую БД на ПГ, вроде все проблемы решаемы пока, но вот чего я не обнаружил - это собственно сабж. Ситуация следующая:
- создаю домен dmn1 not null


Ограничение NOT NULL лучше накладывать на столбец таблицы, а не в самом домене.
Посмотрите раздел Замечания в документации к команде CREATE DOMAIN.
...
Рейтинг: 0 / 0
Порядок срабатывания ограничений (очередной переход с оракла на пг)
    #40124093
AndreyDmt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
GuzyaНаверное не совсем то, но вопрос решается установкой default для поля

Павел Лузанов

Ограничение NOT NULL лучше накладывать на столбец таблицы, а не в самом домене.
Посмотрите раздел Замечания в документации к команде CREATE DOMAIN.

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


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