Argument not taking the value from Postgres function - postgresql

I have a simple Postgres function where I want to take table_name as a parameter and pass it into an argument and delete the data from table by condition.
CREATE OR REPLACE FUNCTION cdc.audit_refresh(tablename text)
RETURNS integer AS
$$
BEGIN
delete from tablename where id<4;
RETURN(select 1);
END;
$$ LANGUAGE plpgsql;
select cdc.audit_refresh('cdc.adf_test');
But it throws out an error that tablename
ERROR: relation "tablename" does not exist in the delete statement.(refer snapshot)

What you want to achieve is to execute Dynamic SQL statements. You can do this with EXECUTE. See more here
CREATE OR REPLACE FUNCTION audit_refresh(tablename text)
RETURNS integer AS
$$
DECLARE
stmt TEXT;
BEGIN
stmt = 'delete from '||tablename||' where id<4;';
EXECUTE stmt;
RETURN 1;
END
$$ LANGUAGE plpgsql;

Related

How to fetch all data from dynamic table using Function & Stored Procedure in the PostgreSQL database? table name passed in parameter

I am tryign to fetch data from dynamic table using Function but getting error: "SQL Error [42704]: ERROR: type "schemaName.p_dynamictablename" does not exist".
CREATE OR REPLACE FUNCTION schemaName."GetAllDataFromDynamicTable"(IN P_DynamicTableName text, IN id integer)
RETURNS SETOF schemaName."P_DynamicTableName"
AS $$
BEGIN
return query
SELECT * FROM schemaName."P_DynamicTableName" WHERE "Id" = id;
END;
$$
LANGUAGE plpgsql;
I am tryign to fetch data from dynamic table using Stored Procudure but getting error: "SQL Error [42704]: ERROR: type "ml.tableName" does not exist"
Note: able to fetch data from table. ex: select * from schemaName."TableName";
CREATE OR REPLACE FUNCTION schemaName."GetAllDataFromDynamicTable"(tableName character varying)
RETURNS SETOF schemaName."tableName"
as $$
BEGIN
return query
select * from schemaName."tableName";
END;
$$
LANGUAGE plpgsql;
As stated by #Adrian, dynamic sql could be a solution :
CREATE OR REPLACE FUNCTION GetAllDataFromDynamicTable(IN P_DynamicTableName text, IN id integer)
RETURNS SETOF record
AS $$
BEGIN
RETURN QUERY
EXECUTE FORMAT('SELECT * FROM %I WHERE id = %s', P_DynamicTableName, id) ;
END;
$$
LANGUAGE plpgsql;
But calling this function will lead to an error until you can explicitly define the output columns of the function. This is possible only in the case where all the tables to be queried dynamically have the same columns definition.
There is a workaround which consists in converting the output record into a json object :
CREATE OR REPLACE FUNCTION NewGetAllDataFromDynamicTable(IN P_DynamicTableName text, IN id integer)
RETURNS SETOF jsonb
AS $$
BEGIN
RETURN QUERY
EXECUTE FORMAT('SELECT to_jsonb(t.*) FROM %I AS t WHERE t.id = %s', P_DynamicTableName, id) ;
END;
$$
LANGUAGE plpgsql;
Then you can call the function in different ways :
SELECT t.* FROM NewGetAllDataFromDynamicTable ('test', 1) AS t will return a json object
SELECT (jsonb_populate_record(NULL :: "test", t.*)).* FROM NewGetAllDataFromDynamicTable ('test', 1) AS t will return the columns of the table test
see dbfiddle

Select Statement using Stored Procedure

May I ask on how to call a method when the content of the stored procedure is about select statement? (Using postgreSQL)
CREATE OR REPLACE PROCEDURE select_table(table_name VARCHAR(255))
language plpgsql
as $$
BEGIN
EXECUTE('SELECT * FROM' || ' ' || quote_ident(table_name));
END $$;
CALL select_table('employee_table');
EDITED(USING FUNCTION)
CREATE OR REPLACE FUNCTION select_table(table_name VARCHAR(255))
language plpgsql
as $$
BEGIN
SELECT * FROM table_name
RETURN table_name;
END $$;
In PostgreSQL procedures doesn't execute any select statements and doesn't have return.
For returning data you can use functions. But functions also cannot return different structural data, examples:
CREATE OR REPLACE FUNCTION fr_test()
RETURNS TABLE(id integer, bookname character varying)
LANGUAGE plpgsql
AS $function$
begin
return QUERY
SELECT tb.id, tb.bookname from rbac.books tb;
end;
$function$
;
or
CREATE OR REPLACE FUNCTION fr_test()
RETURNS setof public.books
LANGUAGE plpgsql
AS $function$
begin
return QUERY
SELECT * from public.books;
end;
$function$
;
But for returning difference tables you can do it using procedures and using out refcursor, like as in Oracle. For example:
create or replace procedure pr_test(OUT r1 refcursor)
as $$
begin
open r1 for
select * from public.books;
end;
$$ language plpgsql;

Save execute results into a table

Below is a simplified postgres stored procedure I am trying to run:
create or replace procedure my_schema.tst(suffix varchar)
as $$
begin
execute(' select *
into my_schema.MyTable_'||suffix||'
From my_schema.MyTable
');
end;
$$
language plpgsql;
When I attempt to run using something like:
call my_schema.tst('test');
I get this error Invalid operation: EXECUTE of SELECT ... INTO is not supported;
Is it possible to execute a dynamic query that creates a new table? I have seen examples that look like:
Execute('... some query ...') into Table;
but for my use case I need the resulting tablename to be passed as a variable.
In PostgreSQL you can use INSERT INTO tname SELECT...
create or replace procedure my_schema.tst(suffix varchar)
as $$
begin
execute ' INSERT INTO my_schema.MyTable_'||suffix||' SELECT *
FROM my_schema.MyTable
';
end;
$$
language plpgsql;
or Use CREATE TABLE tname AS SELECT..., :
create or replace procedure my_schema.tst(suffix varchar)
as $$
begin
execute ' CREATE TABLE my_schema.MyTable_'||suffix||' as SELECT *
FROM my_schema.MyTable
';
end;
$$
language plpgsql;

Table name as variable parameter

I made a function in pgadmin
create or replace function get_source2(a text)
returns integer as
$$
declare
a text;
geom geometry;
begin
select get_source(geom)
from a;
end;
$$
language plpgsql;
I want input a by table name How can I do? I try to like this
select get_source2('postgis.center')
but I get:
ERROR: relation "a" does not exist LINE 2: from a help me
try this:
create or replace function get_source2(a text)
returns integer as
$$
declare
geom geometry;
begin
execute 'select get_source(geom) from '||quote_ident(a) into geom;
return geom;
end;
$$
language plpgsql;

PostgreSQL: How to assign "SELECT" query to variable using dblink?

Here I am trying to assign a "SELECT" query to a specific variable. The select query is retrieving rows from other database table using dblink. For example as shown below:
Example: My try
create or replace function fun(names varchar(60), id bigint) returns void as
$$
Declare
sql varchar;
Begin
sql := 'Select * from dblink'('conn','select * from tablex') /* Error occurred here */
'where name = ''' || names ||'''';
raise info '%',sql;
execute sql,'names varchar(60)',names=names;
end;
$$
Language plpgsql;
ERROR: syntax error at or near "("
You've messed up your quotimg.
You can use dollar-quoting inside the fumction too.
sql := $SQL$...$SQL$
Solution: Here is the solution
create or replace function fun(names varchar(60), id bigint) returns void as
$$
Declare
sql varchar;
Begin
sql := 'Select * from dblink(''conn','select * from tablex'')
where name = ''' || names ||'''';
raise info '%',sql;
execute sql,'names varchar(60)',names=names;
end;
$$
Language plpgsql;