Postgresql function dynamic table quote_ident error - postgresql

I created a dynamic function. I get a part of table name with dynamically. The function is created successfully. But when I execute the function. I get an error. How can I solve this problem? I call the function with
select * from dwgcould.getlatlngcenter(2000653);
CREATE OR REPLACE FUNCTION dwgcould.getlatlngcenter(IN pro_id integer,
OUT lat_center double precision, OUT lng_center double precision)
AS $$
BEGIN
EXECUTE 'SELECT st_x(st_centroid( st_transform(geom,4326))) as lng_center ,st_y(st_centroid( st_transform(geom,4326))) as lat_center
FROM dwgcould.adpes_v1_' || quote_ident(pro_id) || '_line limit 1';
END;
$$ LANGUAGE plpgsql;
The error code is
ERROR: function quote_ident(integer) does not exist
LINE 2: FROM dwgcould.adpes_v1_' || quote_ident(pro_id) || '_line...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
QUERY: SELECT 'SELECT st_x(st_centroid( st_transform(geom,4326))) as lng_center ,st_y(st_centroid( st_transform(geom,4326))) as lat_center
FROM dwgcould.adpes_v1_' || quote_ident(pro_id) || '_line limit 1'
CONTEXT: PL/pgSQL function dwgcould.getlatlngcenter(integer) line 4 at EXECUTE statement
********** Error **********
ERROR: function quote_ident(integer) does not exist
SQL state: 42883
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
Context: PL/pgSQL function dwgcould.getlatlngcenter(integer) line 4 at EXECUTE statement
Also How can I check whether table exist?

better use format, eg:
CREATE OR REPLACE FUNCTION dwgcould.getlatlngcenter(IN pro_id integer,
OUT lat_center double precision, OUT lng_center double precision)
AS $$
BEGIN
if (select count(1) from pg_tables where tablename = format('adpes_v1_%s_line',pro_id)) < 1 then
raise info '%','NO SUCH TABLE!';
return;
end if;
EXECUTE format('SELECT * FROM dwgcould.adpes_v1_%s_line limit 1',pro_id) into lat_center,lng_center;
return;
END;
$$ LANGUAGE plpgsql;
docs

Related

PostgreSQL error in creating function with varying columns using RECORD

I have this function that should be returning a varying columns, can I get a help on what is wrong with my code?
CREATE OR REPLACE FUNCTION functions.search(column_name VARCHAR(40))
RETURNS SETOF RECORD AS $$
DECLARE
rec RECORD;
BEGIN
RETURN QUERY EXECUTE format('SELECT %I FROM students_table);
END;
$$ LANGUAGE plpgsql;
Call:
SELECT * FROM functions.search(
('Student Id', 'Subect')
) as ("Student Id" bigint, "Subect" text)
Here's my error
ERROR: function functions.search(record) does not exist
LINE 1: SELECT * FROM functions.search(
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
SQL state: 42883
Character: 15
Thank you very much
There are several things wrong here.
First, to support a variable number of arguments, you need a VARIADIC parameters. Then, your format function call is somewhat truncated and syntactical nonsense.
You could experiment with a function like this:
CREATE FUNCTION functions.search(VARIADIC column_names text[]) RETURNS SETOF record
LANGUAGE plpgsql AS
$$BEGIN
RETURN QUERY EXECUTE
format('SELECT %s FROM students_table',
(SELECT string_agg(quote_ident(s), ', ')
FROM unnest(column_names) AS cols(s))
);
END;$$;
You can call it like this:
SELECT *
FROM functions.search('Student Id', 'Subect')
AS ("Student Id" bigint, "Subect" text);

Using a parameter as return type in plpgsql function

Say I have this query:
CREATE OR REPLACE FUNCTION select_from_table(table_name varchar(63))
RETURNS SETOF table_name AS
$$
DECLARE
query TEXT := 'SELECT * FROM ' || table_name;
BEGIN
RETURN QUERY EXECUTE query;
END;
$$ LANGUAGE plpgsql;
Now if I try to execute it, I get error: type "table_name" does not exist and that's probably because I can only use the parameters within the function (between the dollar quotes) and not in the return type definition.
The question would be: are there any ways to SELECT from a table by passing its name as a parameter instead of hard coding it to the function? How?

Table name as PostgreSQL function parameter / ERROR: column ".." does not exist

I'm new to pgsql. I just want to use a table name as a function parameter in pgsql.
CREATE OR REPLACE FUNCTION user_test_table_name_as_input (table_name text)
RETURNS VOID
LANGUAGE plpgsql
AS $$
DECLARE
i int;
BEGIN
FOR i IN EXECUTE 'SELECT DISTINCT category FROM' || quote_ident(table_name)
LOOP
RAISE NOTICE '%', i;
END LOOP;
END
$$
When I try to use this function...
SELECT user_test_table_name_as_input (table_name);
...i get this error:
ERROR: column "table_name" does not exist
SQL state: 42703
I read the related threads, like Table name as a PostgreSQL function parameter, but the other proposed solutions (Concatenation, format() ), do not work for me, neither. Any idea?
'table_name' needs quotes as the argument to the call of your stored procedure - it's text.

How to use EXECUTE FORMAT ... USING in postgres function

CREATE OR REPLACE FUNCTION dummytest_insert_trigger()
RETURNS trigger AS
$BODY$
DECLARE
v_partition_name VARCHAR(32);
BEGIN
IF NEW.datetime IS NOT NULL THEN
v_partition_name := 'dummyTest';
EXECUTE format('INSERT INTO %I VALUES ($1,$2)',v_partition_name)using NEW.id,NEW.datetime;
END IF;
RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION dummytest_insert_trigger()
OWNER TO postgres;
I'm trying to insert using
insert into dummyTest values(1,'2013-01-01 00:00:00+05:30');
But it's showing error as
ERROR: function format(unknown) does not exist
SQL state: 42883
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
Context: PL/pgSQL function "dummytest_insert_trigger" line 8 at EXECUTE statement
I'm unable get the error.
Your function could look like this in Postgres 9.0 or later:
CREATE OR REPLACE FUNCTION dummytest_insert_trigger()
RETURNS trigger AS
$func$
DECLARE
v_partition_name text := quote_ident('dummyTest'); -- assign at declaration
BEGIN
IF NEW.datetime IS NOT NULL THEN
EXECUTE
'INSERT INTO ' || v_partition_name || ' VALUES ($1,$2)'
USING NEW.id, NEW.datetime;
END IF;
RETURN NULL; -- You sure about this?
END
$func$ LANGUAGE plpgsql;
About RETURN NULL:
To ignore result in BEFORE TRIGGER of PostgreSQL?
I would advice not to use mixed case identifiers. With format( .. %I ..) or quote_ident(), you'd get a table named "dummyTest", which you'll have to double quote for the rest of its existence. Related:
Are PostgreSQL column names case-sensitive?
Use lower case instead:
quote_ident('dummytest')
There is really no point in using dynamic SQL with EXECUTE as long as you have a static table name. But that's probably just the simplified example?
You need explicit cast to text:
EXECUTE format('INSERT INTO %I VALUES ($1,$2)'::text ,v_partition_name) using NEW.id,NEW.datetime;

PostgreSQL 9.3: Get list of table names present in view using function

I want to get list of table names present in the view.
So I have created the function with one parameter(view_name) to get table names.
Function : funtion_GetTables_FromView
CREATE OR REPLACE FUNCTION funtion_GetTables_FromView
(
view_Name varchar
)
RETURNS TABLE
(
TableNames varchar
) AS
$BODY$
DECLARE
v_SQL varchar;
BEGIN
v_SQL := 'SELECT Table_Name
FROM INFORMATION_SCHEMA.VIEW_TABLE_USAGE
WHERE View_Name = ''' || view_Name || '''';
RAISE INFO '%',v_SQL;
RETURN QUERY EXECUTE v_SQL;
END;
$BODY$
LANGUAGE PLPGSQL;
Calling function:
select * from funtion_GetTables_FromView('myview');
But getting an error:
ERROR: structure of query does not match function result type
You only showed a part of the error message, the complete error message gives the actual reason:
ERROR: structure of query does not match function result type
Detail: Returned type information_schema.sql_identifier does not match expected type character varying in column 1.
Where: PL/pgSQL function funtion_gettables_fromview(character varying) line 14 at RETURN QUERY
So the column information_schema.table_name is not a varchar column. The immediate fix for this is to cast the column to the required type:
v_SQL := 'SELECT Table_Name::varchar
FROM INFORMATION_SCHEMA.VIEW_TABLE_USAGE
WHERE View_Name = ''' || view_Name || '''';
But the whole function is needlessly complex and error prone. A simply SQL function will do just fine:
CREATE OR REPLACE FUNCTION funtion_GetTables_FromView(v_viewname varchar)
RETURNS TABLE(tablenames varchar)
AS
$$
SELECT table_name
FROM information_schema.view_table_usage
WHERE view_Name = v_viewname;
$$
LANGUAGE sql;
For some reason this does not require the cast to varchar. I suspect this has something to do with running dynamic SQL inside PL/pgSQL.
Unrelated, but: I personally find it pretty useless to prefix a function with function_. It is obvious when using it, that it is a function. Are you prefixing all your classes with class_ and all your methods with method_ in your programming language?