Get Table Name in Event Trigger - postgresql

I have an event trigger that executes on create, alter and drop table.
create event trigger CustomizeTable
on ddl_command_end
when tag in ( 'create table', 'alter table', 'drop table' )
execute procedure CustomizeTable();
Within the procedure I want to create a trigger on the newly created table.
create or replace function CustomizeTable() returns event_trigger as
$$
begin
EXECUTE 'create trigger DoAudit after update on XXXXXX...
end;
$$
language plpgsql;
How can I get the table name within the event trigger?
I tried using TG_TABLE_NAME as explained here but it seems that this only works on non-event-triggers.

You'll have to use the event trigger information functions described in the documentation.
For example, to get the name a newly created table, use
SELECT objid::regclass
FROM pg_event_trigger_ddl_commands();

Related

How to create postgres table in talend using create query

i am trying to create table in talend using below code i see no error but in database this table is not getting created
do $$ declare begin execute 'DROP TABLE IF EXISTS tname'; execute 'CREATE TABLE IF NOT EXISTS tname (ACTIVITY VARCHAR(32))'; end $$ ;
Please help me i am new in Talend
Should be something like this
DO
$$
DECLARE BEGIN
EXECUTE 'DROP TABLE IF EXISTS tname';
EXECUTE 'CREATE TABLE IF NOT EXISTS tname (ACTIVITY VARCHAR(32))';
END;
$$
You will have to just use this component tDBRow
And a very important thing is to to use tDBCommit after the tDBRow if not the table would not be created in your Postgres Database
or just tick the commit (in advanced settings if you are using tDBConnection component)

Syntax error while creating a trigger in PostgreSQL

I created a table name Student in PostgreSQL and then I tried defining a trigger on that table but it's showing an error message in doing so.
Trigger Syntax:
CREATE TRIGGER bi_Student BEFORE INSERT ON Student as $$
FOR EACH ROW
BEGIN
raise notice 'Successfully inserted into table(%)', user;
end $$;
Table Creation Command:
create table Student(Stu_id int, Stu_Name text, Stu_Age int, Stu_address char(30));
Actually I tried to declare the execution statements directly inside the trigger only rather than calling any procedure/ function from the trigger which is working fine but I want to do in this way in PostgreSQL.
PostgreSQL doesn't support it. You need trigger function always.
As documented in the manual you need a trigger function
create function my_trigger_function()
returns trigger
as
$$
begin
raise notice 'Successfully inserted into table(%)', user;
return new; --<< important (see the manual for details)
end
$$
language plpgsql;
Not sure what you intend with the user parameter there, as that is not the table name, but the current database user. If you want to display the actual table name, you need to use TG_RELNAME instead - which is an implicit variable available in the trigger function.
And a trigger definition
CREATE TRIGGER bi_Student
BEFORE INSERT ON Student
FOR EACH ROW
execute function my_trigger_function();

Generic function to be called from multiple triggers

I have created a function and trigger to make use that the userId is uCased. The code is as followsL
CREATE OR REPLACE FUNCTION stdUserId ()
RETURNS trigger AS $stdUserId$
BEGIN
NEW.login_id = UPPER (TRIM (NEW.login_id));
RETURN NEW;
END;
$stdUserId$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS usersStdUserId ON users;
CREATE TRIGGER usersStdUserId BEFORE INSERT OR UPDATE ON users
FOR EACH ROW EXECUTE PROCEDURE stdUserId (login_id);
Now I would like to alter the function to be usable with other triggers as in:
DROP TRIGGER IF EXISTS user_rolesStdUserId ON user_roles;
CREATE TRIGGER user_rolesStdUserId BEFORE INSERT OR UPDATE ON users
FOR EACH ROW EXECUTE PROCEDURE stdUserId (user_id);
I would like a generic approach as I have a number of tables to apply this function to. I would prefer to stay away from "IF table01 .. . ELSEIF table02 .. ."
Your assistance is appreciated.

PostgreSql Trigger does not work when called 'insert'

The code below is my code to create trigger function to change column "pass".
create or replace function change_pass()
returns trigger as
$$
begin
NEW.pass := 'XXXXXXXXX';
return NEW;
end
$$
language plpgsql;
create trigger change_pass
AFTER insert or update on "D_ACCOUNT"
for each row execute procedure change_pass();
When i called insert, i did not see any changes in my data.
Can anyone explain to me where i was wrong?
You need a BEFORE trigger to change values in the NEW record:
create trigger change_pass
BEFORE insert or update on "D_ACCOUNT"
for each row execute procedure change_pass();

Event trigger to change owner on CREATE

I'm trying to create a PostgreSQL event trigger, that fires whenever a user creates anything (table, view, function, sequence...) and sets the owner of this newly created thing to a certain role.
So far I have the even trigger itself, that fires on any CREATE command:
CREATE EVENT TRIGGER setOwnerToMyRole ON ddl_command_end
WHEN tg_tag LIKE 'CREATE%'
EXECUTE PROCEDURE setOwnerToMyRole();
But I am having problems with the function itself:
CREATE FUNCTION setOwnerToMyRole() RETURNS event_trigger LANGUAGE plpgsql
AS $$ BEGIN
ALTER <type> <name> OWNER TO myRole
END; $$;
How do I get the type (as in table, view, etc.) and how do i get the name of the newly created thing?
edit:
Looking at this question and this question and of course CREATE EVENT TRIGGER and Trigger Procedures, this is currently not really possible :(
This works pretty well for me, although it's a little broader net than needed. It is based on code at https://blog.hagander.net/setting-owner-at-create-table-237/
CREATE OR REPLACE FUNCTION trg_create_set_owner()
RETURNS event_trigger
LANGUAGE plpgsql
AS $$
DECLARE
obj record;
BEGIN
-- postgresql 9.5 or later:
-- FOR obj in SELECT table_name FROM pg_event_trigger_ddl_commands() WHERE command_tag='CREATE TABLE'
FOR obj IN SELECT tablename FROM pg_tables WHERE tableowner = current_user LOOP
EXECUTE format('ALTER TABLE %s OWNER TO my_group', obj.tablename);
END LOOP;
END;
$$;
CREATE EVENT TRIGGER trg_create_set_owner
ON ddl_command_end
WHEN tag IN ('CREATE TABLE', 'CREATE TABLE AS')
EXECUTE PROCEDURE trg_create_set_owner();
Guess, I should answer this question properly and not just in an edit:
What I want is currently not possible. Perhaps a future update to Postgres will add more functionality to eventtriggers.
Sources:
http://www.postgresql.org/docs/current/static/sql-createeventtrigger.html
http://www.postgresql.org/docs/current/static/plpgsql-trigger.html
How to get the name of the altered table in a Postgres event trigger?
How to get SQL text from Postgres event trigger