PostgreSQL: LISTEN with insert - sql

I have one notify function and trigger as below
Here I am inserting records before notification listerner_to_insert_code(resVal)
CREATE OR REPLACE FUNCTION public.codes_notify_trigger()
RETURNS trigger AS
$BODY$
DECLARE
resVal text;
BEGIN
resVal := row_to_json(NEW);
select listerner_to_insert_code(resVal);
PERFORM pg_notify('code_channel', resVal::text);
RETURN new;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
CREATE TRIGGER codeInsertTrigger
AFTER INSERT OR UPDATE
ON public.codings
FOR EACH ROW
EXECUTE PROCEDURE public.codes_notify_trigger();
Then I can't see the payloads on
When I tried
LISTEN code_channel
But I can see the payloads if I remove select listerner_to_insert_code(resVal)
Here in below it will show the payloads
CREATE OR REPLACE FUNCTION public.codes_notify_trigger()
RETURNS trigger AS
$BODY$
DECLARE
resVal text;
BEGIN
resVal := row_to_json(NEW);
PERFORM pg_notify('code_channel', resVal::text);
RETURN new;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
But I want to insert record after LISTEN.
How can I achieve this?

You are getting error query has no destination for result data. Check your logs to make sure.
When using SELECT in PL/pgSQL code, you need to do something with returned data, like for example INSERT it into table or variable(s).
If you don't want to do anything with returned data, then use PERFORM instead.
PERFORM listerner_to_insert_code(resVal);

Related

Using the parameters given in stored procedure in a trigger function

I would like to know if it is possible to use the parameter "delivery_date_ which is given to the stored procedure "delivery" inside trigger function "insert_error".
CREATE OR REPLACE PROCEDURE delivery (delivery_date date)
LANGUAGE 'plpgsql'
AS
$BODY$
DECLARE
BEGIN
END;
$BODY$
CREATE OR REPLACE FUNCTION insert_error() RETURNS TRIGGER
LANGUAGE 'plpgsql'
AS
$BODY$
BEGIN
--being able to use the parameter "delivery_date" here--
END;
$BODY$
DROP TRIGGER check_insert ON transactions;
CREATE TRIGGER check_insert
BEFORE INSERT ON transactions
FOR EACH ROW
EXECUTE PROCEDURE insert_error();
CREATE OR REPLACE FUNCTION insert_error() RETURNS TRIGGER
LANGUAGE 'plpgsql'
AS
$BODY$
begin
------ you can use any of these code:
CALL delivery(now()::date); -- call with current datetime
CALL delivery(new."date"); -- call with from inserted date field
CALL delivery(current_timestamp::date); -- and etc.
return new;
END;
$BODY$

Trigger error in postgreSQL

I am attempting to create a trigger which will delete rows when a certain where clause criteria is met but it throws out an error. What am I doing wrong?
CREATE TRIGGER unknowns
AFTER INSERT
ON "Amazon".salesdatapcr
FOR EACH ROW
EXECUTE PROCEDURE delete_my_rows();
CREATE OR REPLACE FUNCTION delete_my_rows()
RETURNS trigger AS
$BODY$
BEGIN
DELETE FROM "Amazon".salesdatapcr WHERE "Builder" = 'unknown';
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
You must encapsulate your DELETE statement in a function, so the trigger will become:
CREATE TRIGGER unknowns
AFTER INSERT
ON "Amazon".salesdatapcr
FOR EACH ROW
EXECUTE PROCEDURE delete_my_rows();
So you must create a function as follow:
CREATE OR REPLACE FUNCTION delete_my_rows()
RETURNS trigger AS
$BODY$
BEGIN
DELETE FROM "Amazon".salesdatapcr WHERE "Builder" = 'unknown';
RETURN NEW;
END;
HERE you can find a brief guide on trigger creation

How to send current schema and affected table with notification function/trigger?

When a row is inserted or updated in a specific table (in this example it's the table called 'fpl'). How can I include the affected table and schema in the notification?
SQL as follows:
CREATE TRIGGER fpl_event
AFTER INSERT OR UPDATE ON fpl
FOR EACH ROW
EXECUTE PROCEDURE fpl_notify();
CREATE OR REPLACE FUNCTION fpl_notify()
RETURNS trigger AS $$
BEGIN
NOTIFY dbNotification, 'something got insereted in fpl!';
RETURN NULL;
END;
$$ LANGUAGE PLPGSQL;
Update:
CREATE OR REPLACE FUNCTION fpl_notify() RETURNS trigger
AS
$$
BEGIN
EXECUTE format('notify dbNotification, ''%s''', TG_TABLE_SCHEMA);
RETURN NULL;
END;
$$ LANGUAGE PLPGSQL;
read trigger special variables

PL/PgSQL creating a conditional trigger on insert

I'm working on my first ever Trigger. When I'm doing an INSERT on table I want to conditionaly remove rows from other table.
Here is a trigger:
CREATE OR REPLACE FUNCTION clear_seen_by()
RETURNS trigger AS
$BODY$
BEGIN
IF (OLD.popup = '1') THEN
DELETE FROM news_seen_by;
END IF;
RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
Invoked by:
CREATE TRIGGER clear_seen_by
AFTER INSERT
ON news
FOR EACH STATEMENT
EXECUTE PROCEDURE clear_seen_by();
As an error I see that NEW or OLD (if I motify the trigger) is not declared/unknown. Where is the problem?
In an INSERT statement you do not have an OLD record defined.
You should use NEW.popup instead, and also declare the trigger to be FOR EACH ROW.
CREATE OR REPLACE FUNCTION clear_seen_by() RETURNS trigger AS
$BODY$
BEGIN
IF (NEW.popup = '1') THEN
DELETE FROM news_seen_by;
END IF;
RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql VOLATILE COST 100;
CREATE TRIGGER
clear_seen_by
AFTER INSERT ON
news
FOR EACH ROW EXECUTE PROCEDURE
clear_seen_by();
You declare a trigger FOR EACH STATEMENT. Maybe you need FOR EACH ROW?
FOR EACH STATEMENT triggers do not have NEW and OLD.

Trigger Not Executing Yet It's Created

I have a trigger function I'm trying to have execute in Postgres.
It compiles and adds the trigger, however it does not insert the value into the table as I had hoped.
The function it uses looks like this:
CREATE OR REPLACE FUNCTION
calc_gnpDifference(n integer, o integer)
RETURNS NUMERIC AS $$
SELECT $1 ::numeric - $2::numeric AS gnpDifference;
$$ LANGUAGE SQL;
And the Trigger part:
CREATE OR REPLACE FUNCTION autoCalculate() RETURNS TRIGGER AS $$
BEGIN
IF NEW.gnp_old > NEW.gnp_old THEN
NEW.gnpDifference := calc_gnpDifference(NEW.gnp_old, NEW.gnp);
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER insertDifference ON country;
CREATE TRIGGER insertDifference BEFORE INSERT ON country
FOR EACH ROW EXECUTE PROCEDURE autoCalculate();
However, when I insert data, the trigger does not update the gnpDifference field as I had hoped. Thoughts on why this might be happening?
Obviously this condition: IF NEW.gnp_old > NEW.gnp_old will never be true so the trigger will never have any effect.