So I have a function with an argument for example:
CREATE OR REPLACE FUCNTION example(arg int)
RETURNS int4
LANGUAGE plpgsql
AS $$
BEGIN
--function body
somequery := $q1$ SELECT field*arg FROM randomtable $q1$
EXECUTE somequery;
END
$$
Right now arg is just a string, how do I pass real arg from function argument ?
For your example, you don't need dynamic SQL to begin with, but if you really do, use a parameter placeholder:
CREATE OR REPLACE FUCNTION example(arg int)
RETURNS int4
LANGUAGE plpgsql
AS $$
declare
somequery text;
result int;
BEGIN
somequery := 'SELECT field*$1 FROM randomtable';
EXECUTE somequery
into result
using arg;
return result;
END;
$$
But without more information about the real problem you are trying to solve, the above can be simplified to:
CREATE OR REPLACE FUCNTION example(arg int)
RETURNS int4
LANGUAGE plpgsql
AS $$
declare
result int;
BEGIN
SELECT field * arg
into result
FROM randomtable;
return result;
END;
$$
Related
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
I've a PostgreSQL function that returns a string. I want to use this function into another one but I obtain an error.
These are the sample functions, with get_some_string that returns text, and use_the_string where I want to call the previous one and store the result in a variable:
CREATE OR REPLACE FUNCTION public.get_some_string()
RETURNS text AS
$func$
DECLARE
BEGIN
return 'mystring';
END
$func$ LANGUAGE plpgsql VOLATILE;
CREATE OR REPLACE FUNCTION public.use_the_string()
RETURNS boolean AS
$func$
DECLARE
mytext text;
BEGIN
mytext := select public.get_some_string();
END
$func$ LANGUAGE plpgsql VOLATILE;
If I run this query I obtain the error:
ERROR: syntax error at or near "select"
LINE 24: mytext := select public.get_some_string();
What I'm doing wrong? How can I use the return value of the first function into the second one?
You don't need a select:
CREATE OR REPLACE FUNCTION public.use_the_string()
RETURNS boolean AS
$func$
DECLARE
mytext text;
BEGIN
mytext := public.get_some_string();
END
$func$ LANGUAGE plpgsql VOLATILE;
The second one must be:
RETURNS boolean AS
$func$
DECLARE
mytext text;
BEGIN
select public.get_some_string() into mytext;
END
$func$ LANGUAGE plpgsql VOLATILE;
or
mytext := (select public.get_some_string());
or
mytext := public.get_some_string();
Note to other answers: select is implicitly added in plpgsql context. Example:
do $$
declare
v text[];
begin
v := array_agg(datname) from pg_database;
raise info 'List of databases: %', v;
end $$;
So when you call mytext := select public.get_some_string(); it is transformed to select select public.get_some_string(); internally.
Thats why parenthesesis mytext := (select public.get_some_string()); could be the solution: select (select public.get_some_string()); is the acceptable statement.
How to recognize the data type of anyelement inside function?
CREATE OR REPLACE FUNCTION test1(par1 int,**par2 anyelement**)
RETURNS BOOL
AS $$
DECLARE rc bool := true;
BEGIN
-- ?
RETURN rc;
END;
$$
LANGUAGE plpgsql;
Use pg_typeof(any):
create or replace function test(par anyelement)
returns text language plpgsql as $$
begin
return pg_typeof(par)::text;
end $$;
select test(100::int), test('2012-12-12'::date);
test | test
---------+------
integer | date
(1 row)
I am trying to run the code:
CREATE OR REPLACE FUNCTION anly_work_tbls.testfncjh (tablename text) returns int
AS $$
DECLARE
counter int;
rec record;
tname text;
BEGIN
counter = 0;
tname := tablename;
FOR rec IN
select *
from tname
loop
counter = counter + 1;
end loop;
RETURN counter;
END;
$$
LANGUAGE 'plpgsql' IMMUTABLE
SECURITY DEFINER;
The goal of this code is to return the number of rows in the table you input. I know that this might not be the best way to accomplish this task, but the structure of this function would extend nicely to another question I am trying to tackle. Every time I run the code, I get the error:
ERROR: syntax error at or near "$1"
All online resources I have found tell me how to use the input variable within and EXECUTE block, but not in the above situation.
Currently running PostgreSQL 8.2.15.
CREATE OR REPLACE FUNCTION anly_work_tbls.testfncjh (tbl regclass, OUT row_ct int) AS
$func$
BEGIN
EXECUTE 'SELECT count(*) FROM '|| tbl
INTO row_ct;
END
$func$ LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER;
Call:
SELECT anly_work_tbls.testfncjh('anly_work_tbls.text_tbl');
This should work for Postgres 8.2, but you consider upgrading to a current version anyway.
I pass the table name as object identifier type regclass, which takes care of quoting automatically and works with schema-qualified names. Details:
Table name as a PostgreSQL function parameter
Using an OUT parameter simplifies the function.
Don't quote the language name. It's an identifier.
If you actually need to loop through the result of a dynamic query:
CREATE OR REPLACE FUNCTION anly_work_tbls.testfncjh (tbl regclass)
RETURNS int AS
$func$
DECLARE
counter int := 0; -- init at declaration time
rec record;
BEGIN
FOR rec IN EXECUTE
'SELECT * FROM ' || tbl
LOOP
counter := counter + 1; -- placeholder for some serious action
END LOOP;
RETURN counter;
END
$func$ LANGUAGE plpgsql IMMUTABLE SECURITY DEFINER;
Read this chapter in the manual: Looping Through Query Results
The documented assignment operator in plpgsql is :=:
The forgotten assignment operator "=" and the commonplace ":="
Yes is really not the best way, but this would work:
CREATE OR REPLACE FUNCTION testfncjh (tablename text) returns int
AS $$
DECLARE
counter int;
rec record;
BEGIN
counter = 0;
FOR rec IN
EXECUTE 'select * from '||quote_ident(tablename) loop
counter = counter + 1;
end loop;
RETURN counter;
END;
$$
LANGUAGE 'plpgsql' IMMUTABLE
SECURITY DEFINER;
This would be nicer:
CREATE OR REPLACE FUNCTION testfncjh (tablename text) returns int
AS $$
DECLARE _count INT;
BEGIN
EXECUTE 'SELECT count(*) FROM '|| quote_ident(tablename) INTO _count;
RETURN _count;
END;
$$
LANGUAGE 'plpgsql' IMMUTABLE
SECURITY DEFINER;
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;