I try take all records from two columns with different tables and Divide Between each other but i have only result from first row not from all rows How i can fix that?
CREATE FUNCTION human() RETURNS integer AS $$
DECLARE person integer;
size integer;
def integer;
Begin
Select sizex into size from region;
Select defx into def from humans;
osoba = def / size;
return person;
END;
$$ LANGUAGE 'plpgsql';
select human();
Assuming your "humans" table and "region" table both have an ID field. And also assuming your humans table has a regionId field creating a relationship between your two tables, I would suggest doing the following:
CREATE FUNCTION human(arg_humanId int) RETURNS decimal AS $$
DECLARE
div_result decimal;
Begin
SELECT h.defx/r.sizex
INTO result
FROM humans h
JOIN region r on r.ID = h.RegionID
WHERE h.ID = arg_humanId;
RETURN div_result;
END;
$$ LANGUAGE 'plpgsql';
SELECT human(h.ID)
FROM humans h;
Note I've changed the data type from integer to decimal since division usually results in decimal places.
Another option is to return a setof decimals and do all of the logic inside your function:
CREATE FUNCTION human() RETURNS setof decimal AS $$
DECLARE
div_result decimal;
Begin
RETURN QUERY
SELECT h.defx/r.sizex
FROM humans h
JOIN region r on r.ID = h.RegionID;
END;
$$ LANGUAGE 'plpgsql';
SELECT *
FROM human();
Related
I'm a beginner in plpgsql and working on a project which requires me to write a function that returns two variables in the form of 2 columns (res,Result). I've done a quite a bit of searching but didn't find answer for the same. The reference to my code is below
CREATE OR REPLACE FUNCTION propID(character varying)
RETURNS SETOF RECORD AS $val$
DECLARE
t_row record;
res BOOLEAN;
result character varying;
value record;
BEGIN
FOR t_row IN SELECT property_id FROM property_table WHERE ward_id::TEXT = $1 LOOP
RAISE NOTICE 'Analyzing %', t_row;
res := false; -- here i'm going to replace this value with a function whos return type is boolean in future
result := t_row.property_id;
return next result; --here i want to return 2 variables (res,result) in the form of two columns (id,value)
END LOOP;
END;
$val$
language plpgsql;
Any help on the above query would be very much appreciated.
Assuming that property_id and ward_id are integers you can achieve your goal in a simple query like this:
select some_function_returning_boolean(property_id), property_id
from property_table
where ward_id = 1; -- input parameter
If you absolutely need a function, it can be an SQL function like
create or replace function prop_id(integer)
returns table (res boolean, id int) language sql
as $$
select some_function_returning_boolean(property_id), property_id
from property_table
where ward_id = $1
$$;
In a plpgsql function you should use return query:
create or replace function prop_id(integer)
returns table (res boolean, id int) language plpgsql
as $$
begin
return query
select some_function_returning_boolean(property_id), property_id
from property_table
where ward_id = $1;
end
$$;
Need Output from table with in clause in PostgreSQL
I tried to make loop or ids passed from my code. I did same to update the rows dynamically, but for select I m not getting values from DB
CREATE OR REPLACE FUNCTION dashboard.rspgetpendingdispatchbyaccountgroupidandbranchid(
IN accountgroupIdCol numeric(8,0),
IN branchidcol character varying
)
RETURNS void
AS
$$
DECLARE
ArrayText text[];
i int;
BEGIN
select string_to_array(branchidcol, ',') into ArrayText;
i := 1;
loop
if i > array_upper(ArrayText, 1) then
exit;
else
SELECT
pd.branchid,pd.totallr,pd.totalarticle,pd.totalweight,
pd.totalamount
FROM dashboard.pendingdispatch AS pd
WHERE
pd.accountgroupid = accountgroupIdCol AND pd.branchid IN(ArrayText[i]::numeric);
i := i + 1;
end if;
END LOOP;
END;
$$ LANGUAGE 'plpgsql' VOLATILE;
There is no need for a loop (or PL/pgSQL actually)
You can use the array directly in the query, e.g.:
where pd.branchid = any (string_to_array(branchidcol, ','));
But your function does not return anything, so obviously you won't get a result.
If you want to return the result of that SELECT query, you need to define the function as returns table (...) and then use return query - or even better make it a SQL function:
CREATE OR REPLACE FUNCTION dashboard.rspgetpendingdispatchbyaccountgroupidandbranchid(
IN accountgroupIdCol numeric(8,0),
IN branchidcol character varying )
RETURNS table(branchid integer, totallr integer, totalarticle integer, totalweight numeric, totalamount integer)
AS
$$
SELECT pd.branchid,pd.totallr,pd.totalarticle,pd.totalweight, pd.totalamount
FROM dashboard.pendingdispatch AS pd
WHERE pd.accountgroupid = accountgroupIdCol
AND pd.branchid = any (string_to_array(branchidcol, ',')::numeric[]);
$$
LANGUAGE sql
VOLATILE;
Note that I guessed the data types for the columns of the query based on their names. You have to adjust the line with returns table (...) to match the data types of the select columns.
I am trying to Create a cursor on cartesian product/join as below, it gives an error
create or replace function som1() returns integer as $$
declare
rCur cursor for (select* from t1);
er route%rowtype;
begin
for er in
select route_id, location, happy from t1, t2 where exams.pid = route.pid
loop
end loop;
return 4;
end;
$$ language plpgsql;
select som1();
I am having the following function in `
CREATE OR REPLACE FUNCTION public.get_avalable_providers(
start_day_id integer,
end_day_id integer,
number_of_days integer,
requested integer)
RETURNS SETOF provider AS
$BODY$declare
required integer;
available_product integer;
p provider;
p_id integer;
noa integer;
begin
FOR p IN SELECT * FROM provider
loop
FOR p_id, noa IN SELECT id, number_of_availables FROM product
WHERE provider_id = p.id
LOOP
required = requested/noa;
select available_product =
public.get_available_products_biggerthan(
start_day_id, end_day_id, number_of_days, required, p_id);
if available_product = number_of_days then
return next p;
exit;
end if;
END LOOP;
end loop;
return;
end;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION public.get_avalable_providers(integer, integer, integer,
integer, integer)
OWNER TO postgres;
The above functions is supposed to return some providers that have sufficient amount of the requested product in a days range
it is taking advantage anther function get_available_products_biggerthan and I am getting the following 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
get_avalable_products(integer,integer,integer,integer,integer) line 15 at
SQL statement
Question
where am I making mistake?
https://www.postgresql.org/docs/current/static/plpgsql-statements.html#PLPGSQL-STATEMENTS-SQL-ONEROW
The result of a SQL command yielding a single row (possibly of
multiple columns) can be assigned to a record variable, row-type
variable, or list of scalar variables. This is done by writing the
base SQL command and adding an INTO clause
try below (I only fixed obvious syntax):
CREATE OR REPLACE FUNCTION public.get_avalable_providers(
start_day_id integer,
end_day_id integer,
number_of_days integer,
requested integer)
RETURNS SETOF provider AS
$BODY$declare
required integer;
available_product integer;
p provider;
p_id integer;
noa integer;
begin
FOR p IN (SELECT * FROM provider)
loop
FOR p_id, noa IN (SELECT id, number_of_availables FROM product
WHERE provider_id = p.id)
LOOP
required = requested/noa;
select public.get_available_products_biggerthan(
start_day_id, end_day_id, number_of_days, required, p_id) INTO available_product ;
if available_product = number_of_days then
return next p;
exit;
end if;
END LOOP;
end loop;
return;
end;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
I'm trying to write a simple postgres function which looks more or less like that:
CREATE OR REPLACE FUNCTION USER_TOTALS(column_name varchar, in_t users) RETURNS float AS $$
DECLARE
sum float;
BEGIN
sum = (SELECT SUM($1) FROM jobs WHERE jobs.technician_id = in_t.id);
RETURN sum;
END;
$$ LANGUAGE plpgsql;
And i need to use it like that:
SELECT users.*, USER_TOTALS('jobs.price', users.*) AS total_price_value FROM users;
Hovewer, that's obviously not working cause SUM() function expects to get a column name but my code passes a varchar to it, so the error says:
Function sum(character varying) does not exist
The question is - can i somehow cast a varchar variable to column name var type? I've been googling for this thing for about 2 hours now and i have no idea how can i make that happen.
A recommended form:
CREATE OR REPLACE FUNCTION USER_TOTALS(column_name varchar, in_t users)
RETURNS float AS $$
DECLARE
sum float;
BEGIN
EXECUTE format('SELECT SUM(%I) FROM jobs WHERE jobs.technician_id=$1', column_name)
INTO sum
USING in_t;
RETURN sum;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION USER_TOTALS(column_name varchar, in_t users) RETURNS float AS $$
DECLARE
sum float;
BEGIN
EXECUTE 'SELECT SUM('||column_name||') FROM jobs WHERE jobs.technician_id='||in_t INTO sum;
RETURN sum;
END;
$$ LANGUAGE plpgsql;