Calling a function with a boolean return value inside of a trigger in postgres - postgresql

I am trying to call a function inside of a trigger in postgres. Basically I have a function,
c.check_level(bigint, integer)
which returns a boolean value.
I would like to call this function inside of a trigger as follows:
CREATE OR REPLACE FUNCTION c.check_level_tg()
RETURNS trigger AS
$BODY$
DECLARE
parent_id int8;
level int;
result bool;
begin
parent_id := NEW.fk_parent;
level := NEW.level;
select * from c.check_category_level(parent_id, level) as result;
if (result) then
return (NEW);
else
return(NULL);
end if;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION c.check_category_level_tg()
OWNER TO postgres;
When I try to put data in the table on which this trigger resides, I get an error:
"ERROR: query has no destination for result data HINT: If you want to discard the results of a SELECT, use PERFORM instead. CONTEXT: PL/pgSQL function".
The function c.check_level works properly when run in isolation.

Change
select * from c.check_category_level(parent_id, level) as result;
into:
SELECT c.check_category_level(parent_id, level) INTO result;

Related

Postges call procedure for each row of a returning delete statement

I have a delete statement and I want to call a procedure for each of the rows affected by it. Currently I only seem to be able to access a single row of the set that was deleted.
That is if the delete statement below affects multiple rows then I only see a single passed to my analytics procedure
create or replace function platform.update_foo() returns trigger language plpgsql as $$
declare
result record;
begin
with affected_rows as (
delete from private.foo
where environment_id=new.environment_id
and name=new.name
returning *
)
select private.analytics(affected_rows, 'cancelled')
from affected_rows into result;
return new;
end;
$$;
My analytics function has a signature like so
analytics(f private.foo, t varchar default null)
returns void as $$
begin
-- ...

"query has no destination for result data" error even after having return in the function

Below is my function, even after having a RETURN statement, but a
query has no destination for result data
error is thrown. Am I missing something?
CREATE OR REPLACE FUNCTION test(ulds character varying)
RETURNS boolean AS
$BODY$
DECLARE
val_result boolean;
BEGIN
select * from regexp_split_to_array('BLK&AAK&AKE', '&');
SET val_result = false;
RETURN val_result;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION test(character varying)
There are more than one issues:
Result of unbind queries is not result of function in Postgres. You need to use INTO clause.
regexp_split_to_array is scalar function, there is not any reason to call this function from SELECT statement. Use SELECT only when you take result of table function, or when you need to read data from relations.
assign statement in plpgsql is based on := symbol. The command SET is used for something different.
the type text is proffered against varchar for function's parameters.
So your code can looks like:
CREATE OR REPLACE FUNCTION test(ulds text)
RETURNS boolean AS $$
DECLARE
result boolean;
target text[];
BEGIN
-- suboptimal, don't do this!!!
SELECT regexp_split_to_array('BLK&AAK&AKE', '&') INTO target;
-- preferred
target := regexp_split_to_array('BLK&AAK&AKE', '&');
result := true;
RETURN result;
END;
$$ LANGUAGE plpgsql;

Error Message : Query has no destination for result data

I am new to postgreSQL. I am trying to convert SQL store procedure into postgreSQL store function. I tried Like below store function created successfully but when I am trying to execute I am getting following error message. I am not getting where I need to replace PERFORM.
ERROR: query has no destination for result data
HINT: If you want to discard the results of a SELECT, use PERFORM instead.
SQL Store Procedure
CREATE PROCEDURE [dbo].[roomType]
#intInstId int
AS
BEGIN
SELECT
nClientRoomTypeID,sClientRTDesc,sClientRTName,sClientRTCode
FROM
ClientRoomType
WHERE
ClientRoomType.nInstID=#intInstId
ORDER BY
ClientRoomType.sClientRTCode
END
GO
PostgreSQl Store Function
CREATE OR REPLACE FUNCTION roomType (int_inst_id int)
RETURNS VOID
AS $$
BEGIN
SELECT
nclient_room_type_id,sclient_rt_desc,sclient_rt_name,sclient_rt_code
FROM
clientroomtype
WHERE
clientroomtype.ninst_id=int_inst_id
ORDER BY
clientroomtype.sclient_rt_code;
END;
$$ LANGUAGE plpgsql;
I assume you're attempting to return the query result with your function. You actually do not need plpgsql language for this, but in case you need it for somthing else, use this syntax:
CREATE OR REPLACE FUNCTION roomType (int_inst_id int)
RETURNS TABLE (res_nclient_room_type_id INT,res_sclient_rt_desc TEXT,res_sclient_rt_name TEXT, res_sclient_rt_code TEXT)
AS $$
BEGIN
RETURN QUERY
SELECT
nclient_room_type_id,sclient_rt_desc,sclient_rt_name,sclient_rt_code
FROM
clientroomtype
WHERE
clientroomtype.ninst_id=int_inst_id
ORDER BY
clientroomtype.sclient_rt_code;
END;
$$ LANGUAGE plpgsql;
How to use it?
SELECT * FROM roomType(1);
Since I do not have your data, I cannot test it. But it follows this principle:
CREATE OR REPLACE FUNCTION f ()
RETURNS TABLE (b boolean, x int)
AS $$
BEGIN
RETURN QUERY SELECT TRUE, 1;
END;
$$ LANGUAGE plpgsql;
SELECT * FROM f();
b | x
---+---
t | 1
(1 Zeile)

How to get a output of a variable from function in postgresql

I am new to PostgreSQL. I have the query:
---------
DO
$$
DECLARE
l_pin INT;
l_pin1 int;
BEGIN
l_pin := 3;
l_pin1 := 4;
select l_pin,l_pin1;
END;
$$
LANGUAGE PLPGSQL;
--------------------------
from above query am getting an error as
ERROR: query has no destination for result data
HINT: If you want to discard the results of a SELECT, use PERFORM instead.
CONTEXT: PL/pgSQL function inline_code_block line 9 at SQL statement
SQL state: 42601
I need to get the values of l_pin and l_pin1 as output.
What you have there is a DO statement, not a "query" nor a "function". DO statements cannot return anything at all.
How to perform a select query in a DO block?
The displayed error is because you cannot call SELECT in a plpgsql code block without assigning the result. To actually return values from a plpgsql function, use some form of RETURN (explicitly or implicitly).
As minimal example:
CREATE OR REPLACE FUNCTION foo(OUT l_pin int, OUT l_pin1 int)
RETURNS record AS -- RETURNS record is optional because of OUT parameters
$func$
BEGIN
l_pin := 3;
l_pin1 := 4;
RETURN; -- RETURN is optional here because of OUT parameters
END
$func$ LANGUAGE plpgsql;
SELECT * FROM foo();
Related:
Can I make a plpgsql function return an integer without using a variable?
SELECT or PERFORM in a PL/pgSQL function
Returning from a function with OUT parameter
First you can create a new type that can hold multiple values:
CREATE TYPE type_name AS (l_pin INTEGER, l_pin1 INTEGER);
Then you can do something like:
CREATE OR REPLACE FUNCTION function_name()
RETURNS type_name AS $$
DECLARE
result type_name;
BEGIN
/* Code that puts those values into type_name object
i.e.
result.l_pin := 3;
result.l_pin1 := 4;
*/
return result ;
END
$$ language plpgsql

function which returns as hstore datatype in postgresql

"hstoredata" is a variable of type hstore which contains key value pairs.
i.e. for ex: "hstoredata" variable contains the key value pairs '"ed"=>"1", "id"=>"1", "age"=>"27"'.
If "hstoredata" variable is passed to the function i.e select sampletest(hstoredata), function is returning as null.
-- Function: sampletest(hstore)
-- DROP FUNCTION sampletest(hstore)
CREATE OR REPLACE FUNCTION sampletest(hstoredata hstore)
RETURNS SETOF void AS
$BODY$
DECLARE
newhstoredata hstore;
BEGIN
newhstoredata := samplehstore(hstoredata);
RAISE NOTICE 'newhstoredata: %', newhstoredata;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION sampletest(hstore)
OWNER TO postgres;
Below is the program for function samplehstore(hstore)
-- Function: samplehstore(hstore)
-- DROP FUNCTION samplehstore(hstore)
CREATE OR REPLACE FUNCTION samplehstore(hstoredata hstore)
RETURNS SETOF void AS
$BODY$
BEGIN
RAISE NOTICE 'hstoredata: %', hstoredata;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION samplehstore(hstore)
OWNER TO postgres;
It's unclear what you're asking precisely, but based on the title, I assume you'd like your function to return something.
If so, the issue here is that you're declaring your function as returning setof void.
Declare it as returning whatever it should, and use return ... or return query ..., depending on what you actually need.