plpgsql function. How to compare value to set of values? - sql

I have a trigger function.
I wish to check if an status is one of (5,6,4,7)
CREATE OR REPLACE FUNCTION a()
RETURNS trigger AS
$BODY$
begin
if old.status = (5,6,4,7) then
do something.
end if;
return old;
end;
$BODY$
LANGUAGE plpgsql VOLATILE
how do I change it to proper syntax?

Use IN operator:
...
if old.status IN (5,6,4,7) then
do something.
end if;
...

This is reference of this link.
It only work with postgresql 9.x
CREATE OR REPLACE FUNCTION a()
RETURNS trigger AS
$BODY$
begin
if old.status = ANY (VALUES (5),(6),(4),(7))) then
do something.
end if;
return old;
end;
$BODY$
LANGUAGE plpgsql VOLATILE

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$

For loops in postgresql doesnt run on function, but can run outside function

Some one please help me on this problem. I'm using postgresql ver 12. Thank you. Please read the comment on the result. Running from function doesn't work. so weird.
-- NOT WORKING
CREATE OR REPLACE FUNCTION mefunc()
RETURNS TRIGGER AS $BODY$
DECLARE
a RECORD;
BEGIN
FOR a IN SELECT "aa" FROM medata LOOP
INSERT INTO othermedata ("id", "aa") VALUES ('1', a.aa);
END LOOP;
RETURN NEW;
END
$BODY$ LANGUAGE plpgsql;
when i raise notice the value of a i get ()
WORKING
DO $$
DECLARE
a RECORD;
BEGIN
FOR a IN SELECT "aa" FROM medata LOOP
INSERT INTO othermedata ("id", "aa") VALUES ('1', a.aa);
END LOOP;
END $$
When I raise notice the value of a I get output as "someoutputdata"
Try this. You should return new record when using Trigger. As you are not returning any value so it is returning null value. I have tested the below code and it is working fine.
CREATE OR REPLACE FUNCTION mefunc()
RETURNS TRIGGER AS $BODY$
DECLARE
a RECORD;
BEGIN
FOR a IN SELECT aa FROM metadata loop
INSERT INTO othermedata (id, aa) VALUES ('1', a.aa);
END LOOP;
RETURN new;
END
$BODY$ LANGUAGE plpgsql;

Conditionally drop an insert in a before insert trigger without returning error

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;

plpgsql syntx error at $$

I'm trying to write a function with plpgsql for some reason i'm getting a syntax error at $$ language plpgsql;
This is the func i'm writing:
create or replace function hello() returns trigger as $$
begin
if new.my_sc!= null and new.his_sc!= null
then update people p
set p.score=p.score+1
where p.id = new.id;
end if;
return null;
$$ language plpgsql;
my Trigger:
after insert on game
execute procedure hello();
my syntax error comes in at the last line.
any idea?
Thankx

postgres local schema qualifier

i am using postgres schemas to group views and functions and to keep multiple versions of them in a database (sometimes needed for backwards compatibility) since there are multiple versions of the same function in different schemas i cannot simply reference it by name but need to write the full qualified name "schema.funcname" to access it.
when referencing functions within schemaA from another function in schemaA i always have to write schemaA.funcname. this bugs me when i rename the schema later - is there a qualifier indicating that the function in the same schema schould be used? maybe like the "this" qualifier in java?
hope it can be understood what i am meaning
thx
You can use set schema to change search path for current session:
create schema test1;
create schema test2;
create function test1.f() returns int as $body$ begin return 1; end; $body$ language plpgsql;
create function test2.f() returns int as $body$ begin return 2; end; $body$ language plpgsql;
set schema 'test1';
select f();
set schema 'test2';
select f();
You can also add search_path to function definition:
create or replace function test1.x() returns int as $body$ begin return 1; end; $body$ language plpgsql;
create or replace function test1.f() returns int as $body$ begin return x(); end; $body$ language plpgsql set search_path = 'test1';
create or replace function test2.x() returns int as $body$ begin return 2; end; $body$ language plpgsql;
create or replace function test2.f() returns int as $body$ begin return x(); end; $body$ language plpgsql set search_path = 'test2';
select test1.f();
select test2.f();