plpgsql function return another function value - postgresql

I have a function func1() which returns integer.
I want to write another function func2(mode integer) which can return func1() reults or do some more stuff. The return value of func1() is of type INTEGER.
something like this:
CREATE OR REPLACE FUNCTION func2(mode integer)
RETURNS integer AS
$$
begin
if mode=1 then
return func1(); -- NOT plpgsql syntax
end if;
more stuff .....
return 2;
end
$$
LANGUAGE plpgsql VOLATILE
my question is how to do return func1(); ?
I know I can do :
select func1() into temp;
return temp;
but I was wondring if there is a more elegent way to do that.

All of these work:
Option 1:
CREATE OR REPLACE FUNCTION func2(mode integer)
RETURNS integer AS
$BODY$
DECLARE
_result integer;
BEGIN
_result = 2;
IF mode=1 THEN
_result = func1();
END IF;
--more stuff .....
RETURN _result;
END
$BODY$
LANGUAGE plpgsql VOLATILE COST 100;
Option 2:
CREATE OR REPLACE FUNCTION func2(mode integer)
RETURNS integer AS
$BODY$
BEGIN
IF mode=1 THEN
RETURN func1();
END IF;
--more stuff .....
RETURN 2;
END
$BODY$
LANGUAGE plpgsql VOLATILE COST 100;

Related

Return a not null value when it return null in postgresql function

CREATE OR REPLACE FUNCTION wlmember.fn_string_to_row(p_str character varying)
RETURNS SETOF text
LANGUAGE plpgsql
SECURITY DEFINER
AS $function$
declare
v_str TEXT[];
BEGIN
/* Check to see the number of occurences of the comma */
v_str := string_to_array($1, ',');
FOR i IN coalesce(array_lower(v_str, 1),1) .. coalesce(array_upper(v_str, 1),1) LOOP
RETURN NEXT v_str[i];
END LOOP;
RETURN;
END;
$function$;

How postgresql return a data set like the follows?

Just like the below function. I don't know how to return a set of inside parameter in postgresql?
create or replace function g_i(num int)
returns setof integer
as $$
declare
i int;
begin
while i < $1 loop
select i; -- How to write statements here?
end loop;
end;
$$ language plpgsql;
create or replace function g_i(num int)
returns setof integer
as $$
declare
i int;
begin
i := 0;
while i< $1 loop
i := i+1;
return query select i;
end loop;
end;
$$ language plpgsql;

Looping in PostgreSQL

I am new to PostgreSQL and have a simple task with a looping structure.
Trying to print 0 to 10. Here is my function:
CREATE OR REPLACE FUNCTION LOOPING()
RETURNS TABLE(asd text) AS
$BODY$declare
i integer;
Begin
i:=0;
WHILE i > 10 LOOP
select i;
i:=(i+1);
END LOOP;
end;$BODY$
LANGUAGE plpgsql IMMUTABLE
COST 100
ROWS 1000;
ALTER FUNCTION LOOPING()
OWNER TO postgres;
I have tried with while loop. If anybody can do this task with for loop it will be very helpful.
You have several hick-ups in there. One working way (of many):
CREATE OR REPLACE FUNCTION f_loop()
RETURNS TABLE(asd int) AS
$BODY$
BEGIN
asd := 0;
WHILE asd < 11 LOOP
RETURN NEXT;
asd := asd + 1;
END LOOP;
END
$BODY$ LANGUAGE plpgsql IMMUTABLE
Call:
SELECT * FROM f_loop();
FOR loop
CREATE OR REPLACE FUNCTION f_loop()
RETURNS TABLE(asd int) AS
$BODY$
BEGIN
FOR i IN 0..10 LOOP
asd := i;
RETURN NEXT;
END LOOP;
END
$BODY$ LANGUAGE plpgsql IMMUTABLE;
Or, for this simple case:
CREATE OR REPLACE FUNCTION f_loop()
RETURNS SETOF int AS
$BODY$
BEGIN
FOR i IN 0..10 LOOP
RETURN NEXT i;
END LOOP;
END
$BODY$ LANGUAGE plpgsql IMMUTABLE;
Details in the excellent manual.
Your problem as far as I can see is that you have to return the value properly and RETURN NEXT in my experiments (on Pg 9.1) did not work as I expected it to.
I tested this and it was working:
create or replace function loop() returns table (i int)
language plpgsql as
$$
declare i_array int[];
begin
for i in 0 .. 10 loop
i_array := i_array || i;
end loop;
return query select unnest(i_array);
end;
$$;

Handling EXCEPTION and return result from function

This is my code
CREATE OR REPLACE FUNCTION test_excep (arg INTEGER) RETURNS INTEGER
AS $$
DECLARE res INTEGER;
BEGIN
res := 100 / arg;
BEGIN
EXCEPTION
WHEN division_by_zero
THEN RETURN 999;
END;
RETURN res;
END;
$$
LANGUAGE plpgsql;
That is, I need returned "999", if happened division by zero, but this: SELECT test_excep(0)
returns error: division by zero
CONTEXT: PL/pgSQL function test_excep(integer) line 4 at assignment
What is wrong in my code?
The EXCEPTION clause needs to be in the same block as the exception.
For instance:
CREATE OR REPLACE FUNCTION test_excep (arg integer)
RETURNS integer
AS
$func$
DECLARE
res INTEGER;
BEGIN
res := 100 / arg;
RETURN res;
EXCEPTION
WHEN division_by_zero
THEN RETURN 999;
END
$func$
LANGUAGE plpgsql;
Here is a correct function:
CREATE OR REPLACE FUNCTION test_excep (arg INTEGER) RETURNS INTEGER
AS $$
DECLARE res INTEGER;
BEGIN
res := 100 / arg;
RETURN res;
EXCEPTION
WHEN division_by_zero
THEN RETURN 999;
END;
$$
LANGUAGE plpgsql;
EXCEPTION part must be inside the block where the exception is, and also must be the last part of the block.

how do I return a bit in postgres

I am new to postgres and trying to setup a function that returns a bit.
I keep getting the error
Function's final statement must be SELECT or INSERT/UPDATE/DELETE
RETURNING.
I understand that
Unless the function is declared to return void, the last statement must be a SELECT, or an INSERT, UPDATE, or DELETE that has a RETURNING clause.
here is the code
CREATE OR REPLACE FUNCTION "f"(...)
RETURNS bit AS
DO $$
Begin
IF someStuff
THEN
0; //also tried select 0 //also tried return 0
ELSE
1; //also tried select 1 //also tried return 0
END IF;
0; //also tried select 0 //also tried return 0
END $$
Where am I going wrong with the syntax?
There are several errors:
the DO is wrong in a function definition
you are missing the specification of the language
in PL/pgSQL you use return to return the function's result
So your function becomes:
CREATE OR REPLACE FUNCTION f(some_value integer)
RETURNS bit AS
$$
Begin
IF (some_value = 1)
THEN
return 0;
ELSE
return 1;
END IF;
END $$
language plpgsql
But you should use boolean instead of bit to return true/false flags:
CREATE OR REPLACE FUNCTION f(some_value integer)
RETURNS boolean AS
$$
Begin
IF (some_value = 1)
THEN
return false;
ELSE
return true;
END IF;
END $$
language plpgsql
If you want to use plpgsql then do as in the a_horse's answer but if you don't need plpgsql do in sql:
create or replace function f(some_value integer)
returns boolean as $$
select some_value = 1;
$$
language sql;
If the function is the one from this question then this will do it:
create or replace function isPersonQualifiedForJob(pid integer, jid)
returns boolean as $$
select exists (
select 1
from
getskillsforjob(jid) j
inner join
getskillsforperson(pid) p on j.skillid = p.skillid
)
$$
language sql;
Checking for exists is much faster then counting since it is enough to find the first match.