I have a trigger, but I need to associate with all tables of the my postgres. Is there a command like this below?
CREATE TRIGGER delete_data_alldb
BEFORE DELETE
ON ALL DATABASE
FOR EACH ROW
EXECUTE PROCEDURE delete_data();
I have a trigger, but I need to associate with all tables of the my postgres. Is there a command like this below?
CREATE TRIGGER delete_data_alldb
BEFORE DELETE
ON ALL DATABASE
FOR EACH ROW
EXECUTE PROCEDURE delete_data();
Well there is no database-wide trigger creation but for all such bulk-admin-operations you could use PostgreSQL system tables to generate queries for you instead of writing them by hand. In this case you could run:
SELECT
'CREATE TRIGGER '
|| quote_ident(table_name || '_rowtgr')
|| ' BEFORE DELETE ON '
|| quote_ident(table_schema) || '.' || quote_ident(table_name)
|| ' FOR EACH ROW EXECUTE PROCEDURE delete_data();' AS trigger_creation_query
FROM information_schema.tables
WHERE
table_schema NOT IN ('pg_catalog', 'information_schema')
AND table_schema NOT LIKE 'pg_toast%';
This will get you set of strings which are SQL commands like:
CREATE TRIGGER table1_rowtgr BEFORE DELETE ON schema1.table1 FOR EACH ROW EXECUTE PROCEDURE delete_data();
CREATE TRIGGER table2_rowtgr BEFORE DELETE ON schema1.table2 FOR EACH ROW EXECUTE PROCEDURE delete_data();
CREATE TRIGGER table3_rowtgr BEFORE DELETE ON schema1.table3 FOR EACH ROW EXECUTE PROCEDURE delete_data();
CREATE TRIGGER table1_rowtgr BEFORE DELETE ON schema2.table1 FOR EACH ROW EXECUTE PROCEDURE delete_data();
CREATE TRIGGER "TABLE 2_rowtgr" BEFORE DELETE ON schema2."TABLE 2" FOR EACH ROW EXECUTE FUNCTION delete_data();
...
etc
You just need to run them at once (either by psql
or pgAdmin).
Now some explanation:
information_schema.tables
system table. Because there are data of literally all tables, remember to exclude pg_catalog
and information_schema
schemas and toast tables from your select
.quote_ident(text)
function which will put string inside double quote signs (""
) if necessary (ie. names with spaces or capital letters require that).see https://www.postgresql.org/docs/current/sql-createtrigger.html for proper syntax
subquery in FROM must have an alias
, so added ) AS inner_select;
to the end and it worked. –
Florio A conveniently encapsulated version of Gabriel's answer. This time I am using the trigger to update a column named update_dt datetime
granted to be part of any table in the public schema of the current database.
--
-- function: tg_any_update_datetime_fn
-- when: before insert or update
--
create or replace function tg_any_update_datetime_fn ()
returns trigger
language plpgsql as $$
begin
new.update_dt = now();
return new;
end;
$$;
--
-- function: ddl_create_before_update_trigger_on_all_tables
-- returns: Create a before update trigger on all tables.
--
create or replace procedure ddl_create_before_update_trigger_on_all_tables ()
language plpgsql as $$
declare
_sql varchar;
begin
for _sql in select concat (
'create trigger tg_',
quote_ident(table_name),
'_before_update before update on ',
quote_ident(table_name),
' for each row execute procedure tg_any_update_datetime_fn ();'
)
from
information_schema.tables
where
table_schema not in ('pg_catalog', 'information_schema') and
table_schema not like 'pg_toast%'
loop
execute _sql;
end loop;
end;
$$;
-- create before update trigger on all tables
call ddl_create_before_update_trigger_on_all_tables();
On my DDL scripts I use a large number of such ddl_
functions that have only meaning at DDL time. To remove them from the database use
--
-- function: ddl_drop_ddl_functions
-- returns: Drop all DDL functions.
-- since: 1.1.20
--
create or replace procedure ddl_drop_ddl_functions ()
language plpgsql as $$
declare
r record;
_sql varchar;
begin
for r in
select oid, prokind, proname
from pg_proc
where pronamespace = 'public'::regnamespace
and proname ilike 'ddl_%'
loop
case r.prokind
when 'a' then _sql = 'aggregate';
when 'p' then _sql = 'procedure';
else _sql = 'function';
end case;
_sql = format('drop %s %s', _sql, r.oid::regprocedure);
execute _sql;
end loop;
end
$$;
© 2022 - 2024 — McMap. All rights reserved.