I have a database that is named Dvdrental and in that database there is a function that is named public.film_not_in_stock, but I don't understand what it does.
-- Function: public.film_not_in_stock(integer, integer)
-- DROP FUNCTION public.film_not_in_stock(integer, integer);
CREATE OR REPLACE FUNCTION public.film_not_in_stock(
IN p_film_id integer,
IN p_store_id integer,
OUT p_film_count integer)
RETURNS SETOF integer AS
$BODY$
SELECT inventory_id
FROM inventory
WHERE film_id = $1
AND store_id = $2
AND NOT inventory_in_stock(inventory_id);
$BODY$
LANGUAGE sql VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION public.film_not_in_stock(integer, integer)
OWNER TO postgres;
It's a LANGUAGE SQL function. Not plpgsql.
SQL-language functions implicitly return the results of the last query they run.
Your function, if it was rewritten in plpgsql, would do
$BODY$
BEGIN
RETURN QUERY
SELECT inventory_id
FROM inventory
WHERE film_id = $1
AND store_id = $2
AND NOT inventory_in_stock(inventory_id);
$BODY$
LANGUAGE plpgsql VOLATILE
but in a LANGUAGE SQL function the RETURN is implicit.
Related
My project used MS SQL, and postgresql so I can't change my parameter to another name, something like below
CREATE OR REPLACE FUNCTION myfunction( ReservationNo integer)
RETURNS TABLE("reservationno" integer) AS
$BODY$
begin
RETURN QUERY
select
rr.ReservationNo
FROM Mytable rr
WHERE rr.ReservationNo = myfunction.ReservationNo;
end
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION myfunction(integer)
OWNER TO postgres;
But it give me an error
parameter name "reservationno" used more than once
How can I fix it?
You can change it to a SQL function, which doesn't have this problem:
CREATE OR REPLACE FUNCTION myfunction( ReservationNo integer)
RETURNS TABLE("reservationno" integer) AS
$BODY$
select rr.ReservationNo
FROM Mytable rr
WHERE rr.ReservationNo = myfunction.ReservationNo;
$BODY$
LANGUAGE sql stable
;
Suppose I have the following table, function and execution:
create table mytable (a INTEGER, b INTEGER);
create function test(q INTEGER)
returns table(a INTEGER, b INTEGER)
as
$body$
begin
return query select a,b from mytable;
end;
$body$
language plpgsql STABLE;
select * from test(1);
I get an 'ambiguous column name' error. I can get rid of it by changing the selection to "select t.a, t.b from mytable t" (per some similar-ish posts). But it seems very odd to have to qualify the column names when there is only 1 table in my query. I'm porting code that has quite a lot of stored procedures selecting from single tables (in various ways) and returning a table with columns that have the same name. Is there a better way than this of avoiding the error, and still having an output table with the same column names?
Thanks for any leads.
you can (you should) to use aliases.
create table mytable (a INTEGER, b INTEGER);
create function test(q INTEGER)
returns table(a INTEGER, b INTEGER)
as
$body$
begin
return query select mt.a, mt.b from mytable mt;
end;
$body$
language plpgsql STABLE;
select * from test(1);
maybe thats an option, using format and query execute:
( as the error says, it doesnt know which a to take, the pl/pgSQL variable or a columname )
create function test(q INTEGER)
returns table(a INTEGER, b INTEGER)
as
$body$
declare
lsQueryExecute text;
begin
lsQueryExecute = format('select a,b from mytable');
return query execute lsQueryExecute;
end;
$body$
language plpgsql STABLE;
How can create an function (Stored Procedure / Stored Function) that select all column in the table in PgAdmin? That same same like this.
CREATE OR REPLACE FUNCTION GetAllUsers(IN userno integer)
RETURNS TABLE(all column) AS
$BODY$
BEGIN
RETURN QUERY
SELECT *
FROM Users W
WHERE w.UserNo = GetAllUsers.userno;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION GetAllUsers(integer)
OWNER TO postgres;
You can use returns setof users instead of returns table (...)
You also don't need an expensive PL/pgSQL function for that. A plain SQL function is enough:
CREATE OR REPLACE FUNCTION getallusers(p_userno integer)
RETURNS setof users
$BODY$
SELECT *
FROM users
WHERE userno = p_userno;
$BODY$
LANGUAGE sql VOLATILE
COST 100
ROWS 1000;
I have a function like this
CREATE OR REPLACE FUNCTION factors_apart_sa()
RETURNS TABLE(surf_area integer, sa_factor numeric) AS
$BODY$
BEGIN
RETURN QUERY SELECT factors_apart_sa.surf_area, factors_apart_sa.sa_factor FROM factors_apart_sa;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
After calling this function I get an error:
column reference "factors_apart_sa.surf_area" is ambiguous
How come is it still ambiguous if I have specified the table name.
Here is the table factors_apart_sa:
CREATE TABLE factors_apart_sa
(
factors_apar_sa_id bigserial NOT NULL,
surf_area integer,
sa_factor numeric(19,4) NOT NULL
)
Use a table alias:
CREATE OR REPLACE FUNCTION factors_apart_sa()
RETURNS TABLE(surf_area integer, sa_factor numeric) AS
$BODY$
BEGIN
RETURN QUERY SELECT f.surf_area, f.sa_factor FROM factors_apart_sa f;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
It is not a good idea to have the same names for a table and a function;
To call a function returnig set of rows place it in a FROM clause:
select f.*
from factors_apart_sa() f;
I have this postgresql function
CREATE OR REPLACE FUNCTION sp_select_test(_id bigint)
RETURNS void AS
$BODY$
BEGIN
copy (select sub.id
from (
SELECT id FROM sim s where id = _id) sub) TO '/tmp/results.tsv';
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION sp_select_test(bigint)
OWNER TO postgres;
When I run
select * from sp_select_test(264);
I get error - column "_id" does not exist
If I replace the variable _id in the function with a value say 264, the function works. That is if instead of id = _id I use id = 264
Any reason why the function is failing?
CREATE OR REPLACE FUNCTION sp_select_test(_id bigint)
RETURNS void AS
$BODY$
BEGIN
execute $$copy (select sub.id
from (
SELECT id FROM sim s where id = $$||_id||$$) sub) TO '/tmp/results.tsv'$$;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION sp_select_test(bigint)
OWNER TO postgres;