I'm trying to create a trigger and a function to update some columns (roles and is_verified) for the first user created. Here is my function :
CREATE OR REPLACE FUNCTION public.first_user()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
DECLARE
begin
if(select count(*) from public.user = 1) then
update new set new.is_verified = true and new.roles = ["ROLE_USER", "ROLE_ADMIN"]
end if;
return new;
end;
$function$
;
and my trigger :
create trigger first_user
before insert
on
public.user for each row execute function first_user()
I'm working on Dbeaver and Dbeaver won't persist my function because of a syntax error near the "=". Any idea ?
Quite a few things are wrong in your trigger function. Here it is revised w/o changing your business logic.
However this will affect the second user, not the first. Probably you shall compare the count to 0. Then the condition shall be if not exists (select from public.user) then
CREATE OR REPLACE FUNCTION public.first_user()
RETURNS trigger LANGUAGE plpgsql AS
$function$
begin
if ((select count(*) from public.user) = 1) then
-- probably if not exists (select from public.user) then
new.is_verified := true;
new.roles := array['ROLE_USER', 'ROLE_ADMIN'];
end if;
return new;
end;
$function$;
object: public.fn_set_now_as_updated_at | type: FUNCTION --
-- DROP FUNCTION IF EXISTS public.fn_set_now_as_updated_at() CASCADE;
CREATE FUNCTION public.fn_set_now_as_updated_at ()
RETURNS trigger
LANGUAGE plpgsql
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
PARALLEL UNSAFE
COST 1
AS $$
NEW.updated_at = NOW();
RETURN NEW;
$$;
looks like you forgot to add begin an end clause documentation
CREATE FUNCTION public.fn_set_now_as_updated_at ()
RETURNS trigger
LANGUAGE plpgsql
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
PARALLEL UNSAFE
COST 1
AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$;
I have the following function in a before insert trigger:
CREATE OR REPLACE FUNCTION schema.table_somefun()
RETURNS trigger AS
LANGUAGE 'plpgsql';
$BODY$
BEGIN
IF NEW.col2 NOT NULL THEN
NEW.col1 := CASE NEW.col1
WHEN '121432' THEN '321123'
ELSE <command> END CASE; --there should be a command aborting insertion without error or exception
END IF;
RETURN NEW;
END;
$BODY$
The ELSE statement should abort insertion. Is there a command which drops the query without telling it to the client and leaving the table untouched?
Just use
RETURN NULL;
instead of
RETURN NEW;
to cancel the INSERT for the row and do nothing instead.
But you cannot execute a PL/pgSQL statement inside an SQL CASE expression. (Don't confuse SQL CASE with the similar control structure CASE of PL/pgSQL!)
Could look like this:
CREATE OR REPLACE FUNCTION schema.table_somefun()
RETURNS trigger AS
$func$
BEGIN
IF NEW.col2 NOT NULL THEN
IF NEW.col1 = '121432' THEN -- could also be plpgsql CASE ...
NEW.col1 := '321123';
ELSE
RETURN NULL;
END IF;
END IF;
RETURN NEW;
END
$func$ LANGUAGE plpgsql;
I'm getting the event(delete or create) from pg_notify with python using pg_channels but I need to put an if to check if the trigged event is a delete or create, than I can apply a rule but I don't know how to get the event name.
Thanks for your help guys.
pcg = pg_channels.connect(host='', database='', user='', password='', port='5432')
# listening an event
pcg.listen('xgracco')
#loop to watch events from posgres pg_notify
for event in pcg.events():
info = json.loads(event.payload)
my function and trigger
create or replace function public.notify() returns
trigger as $BODY$
begin
if new.tp_status = 'ERRO' then
perform pg_notify('xgracco', row_to_json(NEW)::text);
end if;
return new;
end
$BODY$
language 'plpgsql';
create trigger after_insert
after insert or update
on "tb_fila"
for each row
execute procedure public.notify()
create or replace function public.notify_delete() returns
trigger as $BODY$
begin
if old.tp_status = 'ERRO' then
perform pg_notify('xgracco', row_to_json(OLD)::text);
end if;
return old;
end
$BODY$
language 'plpgsql';
create trigger before_delete_xgracco
before delete
on "tb_fila"
for each row
execute procedure public.notify_delete()
I was created a trigger on my table.When insert/update/delete its adds a key i,u,d like that.
And i'm trying to insert this keys on another table but gives me error like that:
ERROR: column "i" does not exist
LINE 1: ...(operation,stamp,userid,empname,salary) VALUES('||i||', now(...
^
QUERY: SELECT dblink_exec('INSERT INTO emp_audit(operation,stamp,userid,empname,salary) VALUES('||i||', now(), user,NEW.*)')
CONTEXT: PL/pgSQL function process_emp_audit() line 14 at PERFORM
********** Error **********
ERROR: column "i" does not exist
SQL state: 42703
Context: PL/pgSQL function process_emp_audit() line 14 at PERFORM
i don't know why it's give me this error.And this is my trigger function
-- Function: process_emp_audit()
-- DROP FUNCTION process_emp_audit();
CREATE OR REPLACE FUNCTION process_emp_audit()
RETURNS trigger AS
$BODY$
BEGIN
PERFORM dblink_connect('dbname=ekders port=5432 user=****** password=*****');
IF (TG_OP = 'DELETE') THEN
PERFORM dblink_exec('INSERT INTO emp_audit "D", now(), user, OLD.*;');
PERFORM dblink_disconnect();
RETURN OLD;
ELSIF (TG_OP = 'UPDATE') THEN
PERFORM dblink_exec('INSERT INTO emp_audit "U", now(), user, NEW.*;');
PERFORM dblink_disconnect();
RETURN NEW;
ELSIF (TG_OP = 'INSERT') THEN
PERFORM dblink_exec('INSERT INTO emp_audit(operation,stamp,userid,empname,salary) VALUES('||i||', now(), user,NEW.*)');
PERFORM dblink_disconnect();
RETURN NEW;
END IF;
RETURN NULL; -- result is ignored since this is an AFTER trigger
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION process_emp_audit()
OWNER TO postgres;
Your code is attempting to concatenate a value i, which doesn't exist, to the string. I suspect what you really wanted to do was escape the single quotes. The below should work:
PERFORM dblink_exec('INSERT INTO emp_audit(operation,stamp,userid,empname,salary) VALUES(''i'', now(), user,NEW.*)');