CURRENT_DATE in postgresql triggers - sql

I have before insert trigger in postgres
CREATE OR REPLACE FUNCTION add_requestdate() RETURNS TRIGGER AS $$
DECLARE
BEGIN
new.requestdate := now();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER addrequestdate
BEFORE INSERT ON requests FOR EACH ROW EXECUTE PROCEDURE add_requestdate ();
But it doesn't work! I have solution that works...
CREATE OR REPLACE FUNCTION add_requestdate() RETURNS TRIGGER AS $$
DECLARE
BEGIN
UPDATE requests SET requestdate=now() WHERE id=NEW.id;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER addrequestdate
BEFORE INSERT ON requests FOR EACH ROW EXECUTE PROCEDURE add_requestdate ();
I have only one question. Why new.requestdate := now(); doesn't work?

it working - probably you have some other dependency - it strange, your workable solution cannot to work, because before trigger doesn't see a tuple in table, and if you use after trigger, then you start recursion..
postgres=# create table x(a int, b date, c timestamp);
CREATE TABLE
postgres=# create function fxx()
postgres-# returns trigger as $$
postgres$# begin
postgres$# new.b := now();
postgres$# new.c := now();
postgres$# return new;
postgres$# end;
postgres$# $$ language plpgsql;
CREATE FUNCTION
postgres=# create trigger xxxx before insert on x for each row execute procedure fxx();
CREATE TRIGGER
postgres=# insert into x(a) values(10);
INSERT 0 1
postgres=# insert into x(a) values(209);
INSERT 0 1
postgres=# select * from x;
a │ b │ c
─────┼────────────┼────────────────────────────
10 │ 2012-01-07 │ 2012-01-07 18:36:57.665283
209 │ 2012-01-07 │ 2012-01-07 18:37:00.853442
(2 rows)
so, you can use CURRENT_DATE instead now(), it is preferable solution.

Related

Updates/inserts not working in postgres trigger function

I have following function and trigger-
CREATE OR REPLACE FUNCTION function_copyX() RETURNS trigger AS
$BODY$
BEGIN
WITH
updates (id) AS (
UPDATE tbl_history
SET price=0
FROM tbl
WHERE tbl.id = tbl_history.id
AND tbl_history.price=1
RETURNING tbl_history.id
)
INSERT INTO tbl_history
SELECT id,1 FROM tbl;
RETURN new;
END;
$BODY$
language plpgsql;
create TRIGGER T_X
AFTER INSERT ON TBL
FOR EACH ROW
execute procedure function_copyX();
So, whenever I am inserting any record in TBL, I expect inserts/updates in the TBL_HISTORY but this does not work in trigger function.
But if I execute this 'WITH code' separately it works.
What could be the issue? please help.
Thanks
Below modification worked!
CREATE OR REPLACE FUNCTION function_copyX() RETURNS trigger AS
$BODY$
BEGIN
WITH
updates (id) AS (
UPDATE tbl_history
SET price=0 WHERE id =NEW.id AND price=1
RETURNING id
)
INSERT INTO tbl_history (id,price) values (NEW.id,1);
RETURN new;
END;
$BODY$
language plpgsql;
create TRIGGER T_X
AFTER INSERT ON TBL
FOR EACH ROW
execute procedure function_copyX();

Check attribute in trigger function (PostgreSQL)

I have a task in school which requires me to create a table and a trigger.
I don't really know how to explain it but how can I check if cID is inside the select statement within the trigger function ?
Basically my goal is to only allow cID values which are not inside of "SELECT * from Example2 natural join Example3". Can anyone help me with that? Thank you.
CREATE TABLE Example(
cID INTEGER REFERENCES Example2(attr),
level INTEGER CHECK (level BETWEEN 1 AND 10));
CREATE FUNCTION exp() RETURNS TRIGGER AS
$$
BEGIN
IF EXISTS (select * from Example2 natural join Example3) THEN
RAISE EXCEPTION '...';
END IF;
return null;
END; $$ language plpgsql;
CREATE CONSTRAINT TRIGGER trg
AFTER INSERT OR UPDATE ON Example
FOR EACH ROW
EXECUTE PROCEDURE exp();
CREATE FUNCTION exp() RETURNS TRIGGER AS
$$
BEGIN
IF EXISTS (select 1 from Example2 a where a.cID = new.cID ) THEN
RAISE EXCEPTION '...';
END IF;
return RETURN NEW;
END; $$ language plpgsql;

Create trigger in Postgres

I have two tables A and B. A has the following columns :
a_name, a_num, a_addr. B also has these columns.
Whenever I insert a record in A, I want that record to be inserted in B as well by the use of a trigger.
CREATE OR REPLACE FUNCTION trigger()
RETURNS trigger AS
$BODY$
begin
if tg_op='INSERT' then
insert into b values (new.a_name ,new.a_num ,new.a_addr);
return new;
end if;
return null;
end;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
---------------------------
CREATE TRIGGER trigger_a
AFTER INSERT OR UPDATE
ON a
FOR EACH ROW
EXECUTE PROCEDURE trigger();

Correct SQL table alias syntax in trigger with if statement

So basically I'm trying to create a trigger that will update another table if an insert or update is located less than 1 meter of distance of an existing one.
It does not allow me to insert anything because the FROM clause is missing on the if statement and I'm not sure how to call it properly.
I got the following
CREATE TRIGGER access_node_aiu
AFTER INSERT OR UPDATE
ON schemab.table
FOR EACH ROW
EXECUTE PROCEDURE schemab.trigegr();
CREATE OR REPLACE FUNCTION schemab.trigger()
RETURNS trigger AS
$BODY$
BEGIN
if st_distance(new.geom, a.geom) < 1 then
INSERT INTO schemab.overlap
SELECT nextval('schemab.overlap_id_seq'::regclass), a.node_id, new.node_id, a.date, now(), st_distance(a.geom, new.geom), new.geom
FROM schemab.table a;
end if;
RETURN new;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
How to do this in postgresql?
Change IF into WHERE
CREATE OR REPLACE FUNCTION schemab.trigger()
RETURNS trigger AS
$BODY$
BEGIN
INSERT INTO schemab.overlap
SELECT nextval('schemab.overlap_id_seq'::regclass), a.node_id, new.node_id, a.date, now(), st_distance(a.geom, new.geom), new.geom
FROM schemab.table a
WHERE st_distance(new.geom, a.geom) < 1;
RETURN new;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

PostgreSQL simple trigger question

trigger:
CREATE TRIGGER "tr_update_ts" BEFORE INSERT OR UPDATE
ON "public"."test" FOR EACH ROW
EXECUTE PROCEDURE "public"."update_ts"();
and the function is:
CREATE OR REPLACE FUNCTION "public"."update_ts" () RETURNS trigger AS
$body$
DECLARE
BEGIN
NEW.ts := now();
RETURN NEW;
END;
$body$
LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;
Why is this not working? No error thrown, but the ts is still null...
I tested your code and it works:
First, let's create table:
# create table test (x int4, ts timestamptz);
CREATE TABLE
Now, Let's add function:
# CREATE OR REPLACE FUNCTION "public"."update_ts" () RETURNS trigger AS
>> $body$
>> DECLARE
>> BEGIN
>> NEW.ts := now();
>> RETURN NEW;
>> END;
>> $body$
>> LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;
CREATE FUNCTION
And finally, add a trigger:
# CREATE TRIGGER "tr_update_ts" BEFORE INSERT OR UPDATE
>> ON "public"."test" FOR EACH ROW
>> EXECUTE PROCEDURE "public"."update_ts"();
CREATE TRIGGER
So, now, let's test ON INSERT part of it:
# insert into test (x) values (1);
INSERT 0 1
# select * from test;
x | ts
---+-------------------------------
1 | 2009-09-12 19:54:50.812139+02
(1 row)
Clearly it works.
Now, the update:
# update test set x = 2;
UPDATE 1
# select * from test;
x | ts
---+-------------------------------
2 | 2009-09-12 19:54:57.463933+02
(1 row)
ts has been changed. Clearly the code you shown works, so the error must be someplace else.
Show us "\d test" output from psql, and \df+ of the trigger function.
What is the full syntax of your create function? Here is the full syntax of the function that I created, and it is working as expected.
create function update_timestamp() RETURNS trigger AS $$
BEGIN
NEW.ts := now();
RETURN NEW;
END;
$$ language plpgsql;