powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / ALTER TABLE из TRIGGER
25 сообщений из 25, страница 1 из 1
ALTER TABLE из TRIGGER
    #39209790
KraG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день, уважаемые знатоки.

Вопрос с подобным заголовком уже звучал на этом форуме, но проблемы там были другие.
Моя в следующем.
Имеется триггерная функция:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
CREATE OR REPLACE FUNCTION permission_table_update()
  RETURNS trigger AS
$BODY$
BEGIN
	--EXECUTE 'ALTER TABLE permissions ADD COLUMN "g3" text'; // Этот вариант работает также, т.е. никак
	EXECUTE 'ALTER TABLE permissions ADD COLUMN  '|| quote_ident(NEW.fio::text) ||' boolean default false';
	RETURN NEW;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION permission_table_update()
  OWNER TO postgres;



При этом:
Код: sql
1.
select * from information_schema.columns where table_name = 'permissions';


выдает, как и положено, одну строку с названием поля, которое имеется в таблице (и именуется fio).

Но, при всем при том, что поле там одно и других нет точно, выполнение следующего кода
Код: sql
1.
insert into employees (fio,userid) values ('АБВ','777');


вызывает ошибку:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
ОШИБКА:  колонка "АБВ" отношения "permissions" уже существует
КОНТЕКСТ:  SQL-оператор: "ALTER TABLE biotime.public.permissions ADD COLUMN  "АБВ" boolean default false"
функция PL/pgSQL permission_table_update(), строка 4, оператор оператор EXECUTE
********** Ошибка **********

ОШИБКА: колонка "АБВ" отношения "permissions" уже существует
SQL-состояние: 42701
Контекст: SQL-оператор: "ALTER TABLE biotime.public.permissions ADD COLUMN  "АБВ" boolean default false"
функция PL/pgSQL permission_table_update(), строка 4, оператор оператор EXECUTE
...
Рейтинг: 0 / 0
ALTER TABLE из TRIGGER
    #39209799
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KraG,

Код: sql
1.
2.
3.
4.
5.
SELECT attname,typname,attlen,attnum,attisdropped
  FROM pg_attribute a
  JOIN pg_type t ON t.oid=a.atttypid
 WHERE attrelid='permissions'::regclass
 ORDER BY attnum;


Точно нету?
...
Рейтинг: 0 / 0
ALTER TABLE из TRIGGER
    #39209808
KraG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
"tableoid";"oid";4;-7;f
"cmax";"cid";4;-6;f
"xmax";"xid";4;-5;f
"cmin";"cid";4;-4;f
"xmin";"xid";4;-3;f
"ctid";"tid";6;-1;f
"fio";"varchar";-1;1;f
...
Рейтинг: 0 / 0
ALTER TABLE из TRIGGER
    #39209814
ursido
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
KraG
Но, при всем при том, что поле там одно и других нет точно, выполнение следующего кода
Код: sql
1.
insert into employees (fio,userid) values ('АБВ','777');




Сколько раз выполняли этот код?

Для полной уверенности проверьте наличие поля в самом триггере.
...
Рейтинг: 0 / 0
ALTER TABLE из TRIGGER
    #39209819
KraG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторСколько раз выполняли этот код?

Ну, скажем, не сразу после первой неудачи стал писать на форум. Если я правильно понял вопрос.

авторДля полной уверенности проверьте наличие поля в самом триггере.

Какого поля?
...
Рейтинг: 0 / 0
ALTER TABLE из TRIGGER
    #39209825
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KraGавторДля полной уверенности проверьте наличие поля в самом триггере.
Какого поля?

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

P.S. У меня не очень хорошие чувства от системы, в которой поля в таблицы добавляются динамически. Точно нельзя сделать иначе?
...
Рейтинг: 0 / 0
ALTER TABLE из TRIGGER
    #39209826
KraG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Господа, первоначальный вопрос снимается.

Решил на всякий случай показать код создания триггера...
Код: sql
1.
2.
3.
CREATE TRIGGER permission_table_update
BEFORE INSERT [color=purple]OR UPDATE OR DELETE ON employees[/color]
FOR EACH ROW EXECUTE PROCEDURE permission_table_update();



Но, перед этим проверить иные варианты. И вот при таком выполнение происходит без ошибок.
Код: sql
1.
2.
3.
CREATE TRIGGER permission_table_update
BEFORE INSERT ON employees 
FOR EACH ROW EXECUTE PROCEDURE permission_table_update();



Теперь мой вопрос - почему так то? Ткните, пожалуйста, в кучку ссылок или тут объясните недалекому.
...
Рейтинг: 0 / 0
ALTER TABLE из TRIGGER
    #39209838
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KraG,

Вы действительно не понимаете — почему?
При добавлении новой записи соответствующей колонки нет и всё работает нормально.
Когда колонка изменяется (или ещё круче удаляется), вы зачем-то пытаетесь добавить это поле ещё раз.

В целом же — вместо извращений с динамическим созданием колонок, вам просто нужна подчинённая таблица (Внешний Ключ + набор пермиссий). Посмотрите на что-то готовое.
...
Рейтинг: 0 / 0
ALTER TABLE из TRIGGER
    #39209848
KraG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorovKraG,

Вы действительно не понимаете — почему?
При добавлении новой записи соответствующей колонки нет и всё работает нормально.
Когда колонка изменяется (или ещё круче удаляется), вы зачем-то пытаетесь добавить это поле ещё раз.

В целом же — вместо извращений с динамическим созданием колонок, вам просто нужна подчинённая таблица (Внешний Ключ + набор пермиссий). Посмотрите на что-то готовое.

Любезный vyegorov, я действительно не понимаю почему одна и также триггерная функция при одном и том же событии (INSERT), но, в одном случае призванная реагировать только INSERT, а в другом и на другие события (UPDATE or DELETE), функционирует по-разному.
Функционал для обработки UPDATE и DELETE я просто не дописал, ибо на этапе тестирования INSERT'а столкнулся с вышеописанной проблемой.

Имеются ли на форуме "физиологи" postgresql, способные объяснить неразумному причину сабжа
...
Рейтинг: 0 / 0
ALTER TABLE из TRIGGER
    #39209870
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KraG,

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


И да, -- при [конкурентной работе и] любви к динамическому ддл вам надо в любом случае писать блок обработки исключений . если это непонятно -- физиологи тут бессильны.
...
Рейтинг: 0 / 0
ALTER TABLE из TRIGGER
    #39209895
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KraG,

Чтобы помочь по существу, предоставьте изолированный скрипт, который в пустой схеме сделает таблицу и триггиер. А потом покажет как это падает.

Зачастую подготовка таких изолированных кейсов приводит к пониманию проблемы.
...
Рейтинг: 0 / 0
ALTER TABLE из TRIGGER
    #39210400
KraG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Прошу прощения за задержку (каждый раз, когда пишу эти слова, мне представляется девушка с положительным тестом...).
Отдельно хочется отблагодарить vyegorov за идею "изолированного теста".
Я подготовил скрипт для изолированного теста. Могу заранее сказать, что по результатам его выполнения проблема локализовалась и причина ее была выявлена (как мне кажется).

Вот так, собственно, выглядит "изолированная" БД.

Код: 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.
-- Database: test
CREATE DATABASE test
  WITH OWNER = postgres
       ENCODING = 'UTF8'
       TABLESPACE = pg_default
       LC_COLLATE = 'ru_RU.UTF-8'
       LC_CTYPE = 'ru_RU.UTF-8'
       CONNECTION LIMIT = -1;
GRANT ALL ON DATABASE test TO postgres;

-- Table: employees
CREATE TABLE employees
(
  userid character varying NOT NULL,
  fio character varying NOT NULL,
  CONSTRAINT empl_pki PRIMARY KEY (userid)
);

-- Rule: emp_update ON employees
CREATE OR REPLACE RULE emp_update AS
    ON INSERT TO employees
   WHERE (EXISTS ( SELECT 1
           FROM employees employees_1
          WHERE employees_1.userid::text = new.userid::text)) DO INSTEAD  UPDATE employees SET fio = new.fio
  WHERE employees.userid::text = new.userid::text;

-- Function: permission_table_update()
CREATE OR REPLACE FUNCTION permission_table_update()
  RETURNS trigger AS
$BODY$
BEGIN
	EXECUTE 'ALTER TABLE permissions ADD COLUMN  ' || quote_ident(NEW.fio::text) || ' boolean default false';
	RETURN NEW;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION permission_table_update()
  OWNER TO postgres;
  
-- Trigger: permission_table_update on employees
CREATE TRIGGER permission_table_update
  BEFORE INSERT OR UPDATE OR DELETE
  ON employees
  FOR EACH ROW
  EXECUTE PROCEDURE permission_table_update();

-- Table: permissions
CREATE TABLE permissions
(
  fio character varying
);

-- Вставляем данные
INSERT INTO employees (userid, fio) VALUES ('778', 'AAC');



И по результатам INSERT'а получаем ту же самую ошибку.
Однако, стоит удалить RULE emp_update с таблицы employees, то ошибка пропадает.

Как мне думается, в рамках одной транзакции происходит:
1) INSERT в employees, по которому срабатывает триггер
2) Согласно правилу emp_update вместо INSERT'а почему то происходит UPDATE, по которому тоже срабатывает триггер
3) А в это время... вот тут я с механизмом выполнения транзакций толком не знаком. Я так представляю, что, где то в далекой далекой галактике кэше уже создано и готово воплотиться новое поле для таблицы permissions. А этот же триггер, сработавший на UPDATE уже видит в кэше это поле.

Только при всем при этом мне не понятно, причем здесь правило.
...
Рейтинг: 0 / 0
ALTER TABLE из TRIGGER
    #39210407
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KraG,

Не мешайте RULE с триггерами. Никогда. Это еще никого до добра не довело.
А лучше вообще забудьте RULE в принципе, у них крайне мало того что нельзя сделать триггерами и куча проблем (так как 99% разработчиков НЕ понимаю как они работают внутри).
...
Рейтинг: 0 / 0
ALTER TABLE из TRIGGER
    #39210409
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KraG,

Забавно... похоже на баг. А какая версия Postgres'а?
Судя по всему, триггер срабатывает и на INSERT, и на UPDATE — последний по правилу. Однако мне казалось, что триггера не должны стрелять до того, как правила выполнятся... (моё ИМХО, не уверен).

В списках не советуют мешать правила и триггера: либо одно, либо другое. Вы точно так же можете "запретить" INSERT-ы триггером, сделав UPDATE в функции и вернув NULL из BEFORE триггера.
Также можно попробовать сделать триггер AFTER, и он должен выстрелить только по UPDATE-у. Но мне думается, что отказаться от правила совсем будет лучше.

И совсем хорошо будет завести статичную таблицу с предопределённым набором полей и не мучаться с такой динамикой совсем :)
...
Рейтинг: 0 / 0
ALTER TABLE из TRIGGER
    #39210727
KraG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorovKraG,

Забавно... похоже на баг. А какая версия Postgres'а?
Судя по всему, триггер срабатывает и на INSERT, и на UPDATE — последний по правилу. Однако мне казалось, что триггера не должны стрелять до того, как правила выполнятся... (моё ИМХО, не уверен).


Если я правильно понял, то "выполнение правила" есть модификация (если условие, при наличии оного, выполнится) SQL-инструкции до ее выполнения. В моем случае правило должно сработать по условию
Код: sql
1.
2.
3.
WHERE (EXISTS ( SELECT 1
           FROM employees employees_1
          WHERE employees_1.userid::text = new.userid::text))


Однако, если это новое поле, то оно не выполняется. Теоретически.

vyegorovВ списках не советуют мешать правила и триггера: либо одно, либо другое. Вы точно так же можете "запретить" INSERT-ы триггером, сделав UPDATE в функции и вернув NULL из BEFORE триггера.
Также можно попробовать сделать триггер AFTER, и он должен выстрелить только по UPDATE-у. Но мне думается, что отказаться от правила совсем будет лучше.


Согласен, что однообразие в какой то степени залог отсутствия неожиданного поведения. Но, в свою очередь скажу что я в какой то степени новоначальный и, что наверное естественно, не предполагал, что реализованный функционал может как то не дружить с другим функционалом. Хотя и это навряд ли, ибо, скорее всего, причина в том, что я просто не понимаю как, что и в какой последовательности работает. И дальше тут должна была быть тирада на пять страниц о том, что хочется впитать из книг или с потом фундаментальные знания и процессах, происходящих внутри postgresql во время выполнения того или иного кода. А книг таких нет... И времени тоже нет... Печаль, печаль.
vyegorovИ совсем хорошо будет завести статичную таблицу с предопределённым набором полей и не мучаться с такой динамикой совсем :)
У меня, как и у любого лентяя, есть патологическое желание сделать что то, что будет делать остальное за меня :)

Но, предупреждая посты про то, что раз "такой лентяй, то и мучайся с динамикой, отлавливай эксепшены" и т.п. сразу сообщу, что внемлю вашим предостережениям. Буду использовать динамический DDL исключительно когда не договорюсь со своей ленью.
Да и к тому же, какое это мучение? Это набивание шишек. Учебный, так сказать, процесс.

$ psql --version
psql (PostgreSQL) 9.5.2

Однако dpkg говорит, что и прежняя 9.3 все еще есть.

Утверждать про баг пока рановато, ибо не видно, заменяет ли правило исходный код INSERT'а и, если да, то на какой код. Как бы это посмотреть? А то может я что то в правиле напортачил и дебажить надо мой код.
...
Рейтинг: 0 / 0
ALTER TABLE из TRIGGER
    #39210803
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KraG,

Вы добавляете имена пользователей в виде колонок к таблице `permissions`.
Это означает, что вы не сможете написать 1 SQL запрос (параметризованный), который будет выбирать права для нужного пользователя. Вместо этого вы должны будете каждый раз формировать запрос динамически, т.к. идентификаторы (имена колонок в данном случае) не могут передаваться как параметры.

Т.е. вы умышленно создаёте себе лишнюю работу и проблемы (это к вашему утрверждению про лень).

Ещё раз:
уберите правило совсем

переделайте таблицу `permissions` к виду `(userid int4 PRIMARY KEY, can_login bool, is_admin bool)` (к примеру)

также нужно повесить внешний ключ к таблице`employees` на поле `userid`

в ON INSERT триггере добавляйте новую запись в таблицу, с нужным `userid` и умолчательными правами.
...
Рейтинг: 0 / 0
ALTER TABLE из TRIGGER
    #39210806
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KraG
Если я правильно понял, то "выполнение правила" есть модификация (если условие, при наличии оного, выполнится) SQL-инструкции до ее выполнения. В моем случае правило должно сработать по условию
Код: sql
1.
2.
3.
WHERE (EXISTS ( SELECT 1
           FROM employees employees_1
          WHERE employees_1.userid::text = new.userid::text))



во первых вы неправильно поняли про правила.

NEW [OLD] в правилах не записи, как в триггерах, а табличные наборы, типа как в мсскл inserted/deleted.

а во вторых я только что вам соврал, поскольку они не табличные наборы, как таковые [однажды и навсегда], а правила для исчисления табличных наборов, как таковых. [в руле с несколькими последовательными стейтментами содержимое new / old может, сюрпрайс, меняться от стейтмента к стейтменту]

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

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

такие дела
...
Рейтинг: 0 / 0
ALTER TABLE из TRIGGER
    #39210840
Фотография Новичок ООП.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KraG
Код: plsql
1.
EXECUTE 'ALTER TABLE permissions ADD COLUMN  '|| quote_ident(NEW.fio::text) ||' boolean default false';


Посмотрел только на эту строчку.
Судя по вашей логике, вы для каждого сотрудника добавляете столбец что-ли?
Вам не приходило в голову, что эту простую логику можно реализовать добавляя строки, а не столбцы?
...
Рейтинг: 0 / 0
ALTER TABLE из TRIGGER
    #39210852
KraG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
vyegorovKraG,

Вы добавляете имена пользователей в виде колонок к таблице `permissions`.
Это означает, что вы не сможете написать 1 SQL запрос (параметризованный), который будет выбирать права для нужного пользователя. Вместо этого вы должны будете каждый раз формировать запрос динамически, т.к. идентификаторы (имена колонок в данном случае) не могут передаваться как параметры.

Т.е. вы умышленно создаёте себе лишнюю работу и проблемы (это к вашему утрверждению про лень).

Ещё раз:
уберите правило совсем

переделайте таблицу `permissions` к виду `(userid int4 PRIMARY KEY, can_login bool, is_admin bool)` (к примеру)

также нужно повесить внешний ключ к таблице`employees` на поле `userid`

в ON INSERT триггере добавляйте новую запись в таблицу, с нужным `userid` и умолчательными правами.


Категорически согласен с Вами, что так будет верно. Но при условии, если ролей всего две. Ну или *надцать. Я же хотел реализовать схему прав доступа на полноразмерной матрице, где каждый пользователь может получить права на доступ к другому пользователю. Или нескольким заранее определенным. И где количество или параметры пользователей меняются. Пока их около 200. Потому и появился соблазн динамически формировать таблицу (добавлять столбец и запись)...

Про то, что придется формировать запрос динамически я не подумал. Каюсь и прошу у всех причастных прощения. Не тратил бы ваше время, если бы думал впрок.
Хотя можно было бы названия полей генерировать вида наподобие a_1,a_2...a_n. А в запросе получать все поля и анализировать их на предмет NOT_NULL дальше.... Но, видимо, правильнее будет прийти к неким заранее определенным наборам (группам) и просто модифицировать таблицу employees добавлением одного поля.
...
Рейтинг: 0 / 0
ALTER TABLE из TRIGGER
    #39210863
Alexius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Новичок ООП.,

тут скорее лучше какой-нибудь hstore использовать. если я правильно понял и там что-то вроде ACL храниться будет. либо нормализовать полностью, создав таблицу связей.
...
Рейтинг: 0 / 0
ALTER TABLE из TRIGGER
    #39210874
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Новичок ООП.,

ээттаа неемпартивнаа

тут интересно, насколько мы не понимаем, как работают руле.

вот сделал набростки теста:

Код: 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.
-- CREATE TABLE _new  (body text);
-- create extension dblink;
drop table if exists employees;
drop table if exists permissions;
--drop table if exists _new;
TRUNCATE  _new;
CREATE TABLE employees
(
  userid character varying NOT NULL,
  fio character varying NOT NULL,
  CONSTRAINT empl_pki PRIMARY KEY (userid)
);

-- Rule: emp_update ON employees
CREATE OR REPLACE RULE emp_update AS
    ON INSERT TO employees
   WHERE (EXISTS ( SELECT 1 
           FROM employees employees_1
          WHERE  employees_1.userid::text = new.userid::text )) DO INSTEAD 
          (
			SELECT dblink_exec('dbname='||current_database()
				||' port=5433 user=postgres password=postgres'
				,'INSERT INTO  _new (body) VALUES (' ||quote_nullable(( /*new.**/
						( SELECT (employees_1.* )::text
							FROM employees employees_1
							WHERE  employees_1.userid::text = new.userid::text )
				)::text)||');') ;
			--	INSERT INTO  _new (body) SELECT (new.*)::text ;
			UPDATE employees SET fio = new.fio
				WHERE employees.userid::text = new.userid::text;
			);
-- Function: permission_table_update()
CREATE OR REPLACE FUNCTION permission_table_update()
  RETURNS trigger AS
$BODY$
BEGIN
	EXECUTE 'ALTER TABLE permissions ADD COLUMN  ' || quote_ident(NEW.fio::text) || ' boolean default false';
	RETURN NEW;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION permission_table_update()
  OWNER TO postgres;
  
-- Trigger: permission_table_update on employees
CREATE TRIGGER permission_table_update
  BEFORE INSERT OR UPDATE OR DELETE
  ON employees
  FOR EACH ROW
  EXECUTE PROCEDURE permission_table_update();

-- Table: permissions
CREATE TABLE permissions
(
  fio character varying
);

-- Вставляем данные
INSERT INTO employees (userid, fio) VALUES ('778', 'AAC');



--- после зависания лезть в spg_dtat_activity -- станет немного яснее.

т.е. сначала модифицируется дерево исполнения запроса -- рулем.
потом вставляется первая запись, в триггере, посколь в этот момент записис нет -- создаётся поле.
потом, посколь дерево запроса отмодифачено, условию EXISTS для new.* начинает удовлетоврять первая запись (ещё не закомиченное) и руле срабатывает. срабатывает триггер на апдейт -- ...

интересно, что в моем случае до апдейта не доходим -- висим на блокировке -- автономия ждёт коммита запустившей её транзакции. Т.е. руле. забавное поведение.

а вот если логировать new.* а не (employees_1.* )::text -- то очереди не возникает. очень интересное поведение локов. не знал.

т.е. ээто не баг - это настолько мы не понимаем механику руле. она супротив интуиций скл девелопера. она про интуиции разработчика движка . а они не совпадают.
...
Рейтинг: 0 / 0
ALTER TABLE из TRIGGER
    #39210892
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KraG

Я же хотел реализовать схему прав доступа на полноразмерной матрице, где каждый пользователь может получить права на доступ к другому пользователю. Или нескольким заранее определенным. И где количество или параметры пользователей меняются. Пока их около 200. Потому и появился соблазн динамически формировать таблицу (добавлять столбец и запись)...

уберите эквивалентность роли (бизнес--роли) -- усеру. и можете возвращаться к вашей матрице.

ролей не больше , чем захардкожено в бизнес приложении, т.е. конечное число, никакого динамического ддл

усеров-- сколько хотите.

для переменного по обоим измерениям представления матрицы есть связи "многие ко многим". (id1,id2,{properties}). немного медленнее плоского, но нет ограничений по спецификациям на кол--во столбцов. и нет динамического скл.
...
Рейтинг: 0 / 0
ALTER TABLE из TRIGGER
    #39210901
KraG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
qwwqKraG
Если я правильно понял, то "выполнение правила" есть модификация (если условие, при наличии оного, выполнится) SQL-инструкции до ее выполнения. В моем случае правило должно сработать по условию
Код: sql
1.
2.
3.
WHERE (EXISTS ( SELECT 1
           FROM employees employees_1
          WHERE employees_1.userid::text = new.userid::text))



во первых вы неправильно поняли про правила.

NEW [OLD] в правилах не записи, как в триггерах, а табличные наборы, типа как в мсскл inserted/deleted.

а во вторых я только что вам соврал, поскольку они не табличные наборы, как таковые [однажды и навсегда], а правила для исчисления табличных наборов, как таковых. [в руле с несколькими последовательными стейтментами содержимое new / old может, сюрпрайс, меняться от стейтмента к стейтменту]

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

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

такие дела

Я прошу прощения за свою "темноту", но если Вас не затруднит, что есть "табличные наборы"?
...
Рейтинг: 0 / 0
ALTER TABLE из TRIGGER
    #39210926
p2.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Новичок ООП.добавляя строки, а не столбцы?да и строки добавлять незачем, если не требуется различать false и null/отсутствие строки.
...
Рейтинг: 0 / 0
ALTER TABLE из TRIGGER
    #39211869
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KraG Я прошу прощения за свою "темноту", но если Вас не затруднит, что есть "табличные наборы"?правильно -- я опять собирался вас обмануть, ага.

но это не про табличные наборы
а табличные наборы -- это наборы записей, типа возвратов SELECT -ов
они могут существовать как материальные наборы (напр CTE в пж), так и как правила их исчисления (subselect)


а врать я собрался ,потому как плохо помню, чем вот всё это кончилось: 1113147 давно это было

да и в своём тутошнем тесте я транкейта видимо жду, а не rule -- добавил его , не подумав. (там эсклюзив на табличку транкейтом вешается). ну да не суть. порядок обработки он и так проясняет.


важнее резюме -- никогда не пользуйте руле. даже если приспичит.
...
Рейтинг: 0 / 0
25 сообщений из 25, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / ALTER TABLE из TRIGGER
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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