В postgresql можно ли создать триггеры для таблицы с триггерами на CREATE TABLE?
Возможно ли в Postgres иметь триггер на CREATE TABLE, который будет создавать триггеры для вновь созданной таблицы?
например,
CREATE TABLE base_abc(
...
) inherits( base );
Я хотел бы автоматически добавлять триггеры в новую таблицу base_abc
это, например, будет вычислять значение столбца на основе имен столбцов.
аналогично, возможно ли запустить ALTER TABLE, чтобы триггеры можно было отбрасывать и создавать заново?
для контекста посмотрите, как лучше всего расширить postgresql для индексации объектов json?
1 ответ
Не думайте, что есть способ реализовать такие "триггеры", используя встроенные функции PostgreSQL, но вы определенно можете написать хранимую функцию, которая будет делать то, что вы хотите - т.е. создать производную таблицу и затем триггер для этой таблицы.
Вы также можете написать один для изменения таблиц.
Нашел этот вопрос при поиске в Google, и, поскольку все изменилось, решил добавить современный ответ. Начиная с 9.3 у нас есть триггеры событий. Прочтите онлайн-документацию для получения дополнительной информации.
То, что вы просите, можно сделать примерно так:
event_tg_example=# CREATE OR REPLACE FUNCTION add_tg_fn()
RETURNS event_trigger LANGUAGE plpgsql AS $f$
DECLARE
obj record;
BEGIN
FOR obj IN SELECT * FROM pg_event_trigger_ddl_commands()
LOOP
execute format('create function %I() returns trigger as $tgf$ begin raise info %L, $i$here$i$; return old; end $tgf$ language $l$plpgsql$l$', 'blah_'||obj.objid::regclass,'%');
execute format ('CREATE TRIGGER tg_blah BEFORE DELETE ON %I FOR EACH ROW EXECUTE PROCEDURE %I();', obj.objid::regclass, 'blah_'||obj.objid::regclass);
END LOOP;
END
$f$
;
CREATE FUNCTION
event_tg_example=# CREATE EVENT TRIGGER add_tg_tg
ON ddl_command_end
WHEN TAG IN ('CREATE TABLE')
EXECUTE PROCEDURE add_tg_fn()
;
CREATE EVENT TRIGGER
event_tg_example=# create table t(i int);
CREATE TABLE
event_tg_example=# insert into t values (1);
INSERT 0 1
event_tg_example=# delete from t where i = 1;
INFO: here
DELETE 1
event_tg_example=#
Имейте в виду, что это всего лишь рабочий пример, не копируйте / вставляйте его вслепую