Sql create a view X_myview where X is given into a function(X text) which creates the view - sql

Trying to create a function that given the name of a table will create a function with the table name concatenated to _myView
eg if the name of the table is students the function will create a view called students_myView
Here's what I have so far.
create or replace function skyline_naive(tableName text)
as $$
declare
name text;
begin
name:= $1;
create or replace view name_myView as select * from name;
end
$$ language plpgsql;

A dynamic command in PLPgSQL must be executed as a string with EXECUTE statement.
To make it work, you should write it like this:
create or replace function skyline_naive(tableName text)
returns void as $$
begin
execute format('create or replace view %1$s_myView as select * from %1$s;', tableName)
return;
end;
$$ language
plpgsql;

Related

Return a table that already exist in postgresql function

I have a bunch of functions that return the same table schema, so I have to repeat the same table schema over and over between those functions' declarations, to make this example simple let's say we have two functions that return the same table schema:
Table: people
CREATE TABLE people(full_name TEXT, age integer);
Functions:
CREATE OR REPLACE FUNCTION get_people_by_age(_age integer)
RETURNS TABLE(full_name TEXT, age integer)
LANGUAGE PLPGSQL
AS
$$
BEGIN
RETURN QUERY SELECT * FROM people WHERE people.age = $1;
END
$$
CREATE OR REPLACE FUNCTION get_people_by_name(_full_name text)
RETURNS TABLE(full_name TEXT, age integer)
LANGUAGE PLPGSQL
AS
$$
BEGIN
RETURN QUERY SELECT * FROM people WHERE people.full_name = $1;
END
$$
Is there a way to refer to the existing table within the function declarations? I imagine something like this:
CREATE OR REPLACE FUNCTION get_people_by_age(_age integer)
RETURNS TABLE(people)
LANGUAGE PLPGSQL
AS
$$
BEGIN
RETURN QUERY SELECT * FROM people WHERE people.age = $1;
END
$$
CREATE OR REPLACE FUNCTION get_people_by_name(_full_name text)
RETURNS TABLE(people)
LANGUAGE PLPGSQL
AS
$$
BEGIN
RETURN QUERY SELECT * FROM people WHERE people.full_name = $1;
END
$$
Where instead of declaring the same schema in every function I refer to a table that already exists, is it possible?
Use returns setof
CREATE OR REPLACE FUNCTION get_people_by_name(_full_name text)
RETURNS setof people
LANGUAGE PLPGSQL
AS
$$
BEGIN
RETURN QUERY SELECT * FROM people WHERE people.full_name = _full_name;
END
$$;
Or a bit simpler as a SQL function:
CREATE OR REPLACE FUNCTION get_people_by_name(_full_name text)
RETURNS setof people
LANGUAGE sql
AS
$$
SELECT * FROM people WHERE people.full_name = _full_name;
$$;

How do I return a table from a function with a bespoke column name?

This function works:
CREATE OR REPLACE FUNCTION public.a()
RETURNS TABLE(a text)
LANGUAGE plpgsql
AS $function$
BEGIN
return query execute
'select a from ztable';
END;
$function$;
But when I try to add some text to the column name:
CREATE OR REPLACE FUNCTION public.a(prefix text)
RETURNS TABLE(a text)
LANGUAGE plpgsql
AS $function$
BEGIN
return query execute
'select a as $1_a from ztable' using prefix;
END;
$function$;
This just fails as a syntax error on $1.
Or:
CREATE OR REPLACE FUNCTION public.a(prefix text)
RETURNS TABLE(a text)
LANGUAGE plpgsql
AS $function$
BEGIN
return query execute
'select a as '||prefix||'_a from ztable';
END;
$function$;
select * from a('some prefix') doesn't work.
Is there some other syntax that does the job?
That's simply not possible. SQL does not allow dynamic column names.
You must assign a column alias with the call. Like:
SELECT a AS prefix_a FROM public.a();
Or in a column definition list directly attached to the function:
SELECT * FROM public.a() AS f(prefix_a);
Or, while dealing with a single output column, even just:
SELECT * FROM public.a() AS prefix_a;
See:
RETURNING rows using unnest()?

Relation does not exist PLPGSQL

I am trying to create a view inside the function using plpgsql which returns the x column of the "small" table which is defined as (x integer,y integer).
create or replace function skyline_naive2(dataset text) returns setof integer as
$$
declare
fullx text;
begin
fullx = dataset||'_skyline_naive2';
execute format('create view %s as select x,y from %s',fullx,dataset);
return query select x from fullx;
end
$$ language plpgsql;
select * from skyline_naive2('small');
It returns "relation fullx does not exist"
I understand that it is because there is no fullx relation, but I want to call the view using the variable name.
Any help will be
Use dynamic SQL for select (as you have used for create):
create or replace function skyline_naive2(dataset text) returns setof integer as
$$
declare
fullx text;
begin
fullx = dataset||'_skyline_naive2';
execute format('create view %I as select x,y from %I',fullx,dataset);
return query execute format('select x from %I', fullx);
end
$$ language plpgsql;
You need to EXECUTE your dynamic query:
RETURN QUERY EXECUTE 'SELECT x FROM ' || fullx;

postgres local schema qualifier

i am using postgres schemas to group views and functions and to keep multiple versions of them in a database (sometimes needed for backwards compatibility) since there are multiple versions of the same function in different schemas i cannot simply reference it by name but need to write the full qualified name "schema.funcname" to access it.
when referencing functions within schemaA from another function in schemaA i always have to write schemaA.funcname. this bugs me when i rename the schema later - is there a qualifier indicating that the function in the same schema schould be used? maybe like the "this" qualifier in java?
hope it can be understood what i am meaning
thx
You can use set schema to change search path for current session:
create schema test1;
create schema test2;
create function test1.f() returns int as $body$ begin return 1; end; $body$ language plpgsql;
create function test2.f() returns int as $body$ begin return 2; end; $body$ language plpgsql;
set schema 'test1';
select f();
set schema 'test2';
select f();
You can also add search_path to function definition:
create or replace function test1.x() returns int as $body$ begin return 1; end; $body$ language plpgsql;
create or replace function test1.f() returns int as $body$ begin return x(); end; $body$ language plpgsql set search_path = 'test1';
create or replace function test2.x() returns int as $body$ begin return 2; end; $body$ language plpgsql;
create or replace function test2.f() returns int as $body$ begin return x(); end; $body$ language plpgsql set search_path = 'test2';
select test1.f();
select test2.f();

How to create view with the name which can be pass through function as a parameter in postgresql?

I am trying to create a view in postgreSQL using function. I want a view name in such a way that, which should be pass by the function as a parameter. For example..
--Table
create table test
( rollno int,
name text);
--Function to create a view
create or replace function fun_view(roll int)
returns void as
$Body$
declare
rec record;
begin
for rec in select * from test where rollno=roll loop
create or replace view "---Name of view should be roll---" as
select rollno from test;
end loop;
$Body$
language plpgsql;
You need PL/PgSQL's dynamic SQL EXECUTE command:
EXECUTE format('create or replace view %I as ...', roll::text);
See: dynamic SQL in PL/PgSQL in the docs.