I'm learning PosgreSQL, i'm trying to call function get_color in a SELECT statement inserting the column name of the table as parameter, but PostgreSQL version 9.6 (i've tried on 13.0 with the same result) returns me an UndefinedFunction error.
Here's the complete query code:
SELECT n
FROM pianokeys pn,
LATERAL get_color(pn.n) AS res;
CREATE OR REPLACE FUNCTION get_color(n integer) RETURNS text AS $$
BEGIN
IF((n % 88) % 2)
THEN
RETURN $b$black$b$;
ELSE
RETURN $w$white$w$;
END IF;
END;
$$
LANGUAGE plpgsql;
`
Here's the compiler error:
There was an error with the SQL query:
PG::UndefinedFunction: ERROR: function get_color(integer) does not exist
LINE 8: lateral get_color(pn.n) as res) AS "t1" LIMIT 1
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
What am i missing?
Related
I created the stored procedure in redshift. Below is the code for that.
create or replace procedure sp4(f1 IN int)
as
$$
begin
IF f1==0 then
CREATE TABLE myetl(a int, b varchar);
ELSE
insert into new_tbl(id) values(47);
END IF;
end;
$$ LANGUAGE plpgsql;
While calling the stored procedure I am getting the error like this
call sp4(0)
ERROR: operator does not exist: integer == integer Hint: No operator matches the given name and argument type(s). You may need to add explicit type casts. Where: SQL statement "SELECT $1 ==0" PL/pgSQL function "sp4" line 2 at if
Your comparison should be IF f0 = 0 THEN, with single equal signs. See the Redshift PLpgSQL documentation
I have PostgreSQL v12 and this code works fine for me in this version. I have no idea if this is a version issue or not but I want to use POSTGRESQL v9.4
----------------------- Function Start v1.0 ------------------------------
drop function if exists aa_Dev.VDN();
CREATE OR REPLACE FUNCTION aa_dev.VDN()
RETURNS VOID AS
$$
declare
tempp json;
begin
DROP TABLE IF EXISTS aa_dev.sdg_vdn;
CREATE TABLE IF NOT EXISTS aa_dev.sdg_vdn (
VDN INT,
skills INT[]
);
tempp := (select VDN_group from aa_dev.sdg_metadata);
insert into aa_dev.sdg_vdn (vdn, skills)
select (jsonb_populate_record(null::aa_dev.sdg_vdn, to_jsonb(t))).*
from jsonb_each(tempp::jsonb) as t(vdn, skills);
end
$$
LANGUAGE plpgsql;
----------------- Function Ends ----------------------
select * from aa_dev.VDN();
select * from aa_dev.sdg_vdn;
So the error is
SQL Error [42883]: ERROR: function to_jsonb(text, jsonb) does not exist
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
Where: PL/pgSQL function aa_dev.vdn() line 17 at SQL statement
How can I eliminate this error and run the function in postgresql 9.4. I have a restriction with this version.
There is some support to jsonb in version 9.4. https://www.postgresql.org/docs/9.4/functions-json.html
You can instead of to_jsonb(t) use to_json(t)::jsonb
I am using PostgreSQL 11 version.
I want to implement a function that takes the layer name (table), column name, and id as parameters.
create or replace function test(layer_name anyelement, field_name anyelement, object_id text)
returns setof anyelement
language plpgsql
as $function$
begin
return query execute format('
select
*
from
%s
where
%s = cast($1 as int4)'
, pg_typeof(layer_name), pg_typeof(field_name))
using object_id;
end;
$function$
;
This is the code I've implemented and when I call the function I get an error.
What am I doing wrong?
Error querying database. Cause: org.postgresql.util.PSQLException: ERROR: syntax error at or near "="
Where: PL/pgSQL function test(anyelement,anyelement,text) line 3 at RETURN QUERY
### The error occurred while setting parameters
### SQL: select * from test(?, ?, ?)
### Cause: org.postgresql.util.PSQLException: ERROR: syntax error at or near "="
Where: PL/pgSQL function test(anyelement,anyelement,text) line 3 at RETURN QUERY
; bad SQL grammar []; nested exception is org.postgresql.util.PSQLException: ERROR: syntax error at or near "="
Where: PL/pgSQL function test(anyelement,anyelement,text) line 3 at RETURN QUERY}
org.springframework.jdbc.BadSqlGrammarException:
### Error querying database. Cause: org.postgresql.util.PSQLException: ERROR: syntax error at or near "="
Where: PL/pgSQL function test(anyelement,anyelement,text) line 3 at RETURN QUERY
### The error occurred while setting parameters
### SQL: select * from test(?, ?, ?)
### Cause: org.postgresql.util.PSQLException: ERROR: syntax error at or near "="
Where: PL/pgSQL function test(anyelement,anyelement,text) line 3 at RETURN QUERY
; bad SQL grammar []; nested exception is org.postgresql.util.PSQLException: ERROR: syntax error at or near "="
Where: PL/pgSQL function test(anyelement,anyelement,text) line 3 at RETURN QUERY
You have to change your function slightly
Instead of field_name anyelement use field_name text in parameter.
and in place of pg_typeof(field_name) use only field_name:
So your function definition will be:
create or replace function test(layer_name anyelement, field_name text, object_id text)
returns setof anyelement
language plpgsql
as $function$
begin
return query execute format('
select
*
from
%s
where
%s = cast($1 as int4)'
, pg_typeof(layer_name), field_name)
using object_id;
end;
$function$
;
Most important part is calling of the function:
select * from test(null::table_name,'field_name','2');
Please note that your field_name always should be integer type and object_id should be number only because you are casting it to integer.
DEMO
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
I am using PostgreSQL 8.4. My goal is to insert multiple rows with the help of PL/pgSQL and return the id-s of the inserted records back in a recordset.
At first I tried to do it in a single row, using the following code for my permission_create(..) function:
CREATE FUNCTION permission_create(
IN method permission.permission_method % TYPE,
IN resource permission.permission_resource % TYPE
)
RETURNS TABLE(id permission.permission_id % TYPE)
AS
$BODY$
BEGIN
RETURN QUERY
WITH inserted_permission AS (
INSERT INTO permission (permission_id, permission_method, permission_resource) VALUES (DEFAULT, method, resource)
RETURNING permission_id
)
SELECT
inserted_permission.permission_id AS id
FROM inserted_permission;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
However, I got the following error message:
[2013-07-04 17:38:01] [00000] type reference permission.permission_method%TYPE converted to character varying
[2013-07-04 17:38:01] [00000] type reference permission.permission_resource%TYPE converted to character varying
[2013-07-04 17:38:01] [00000] type reference permission.permission_id%TYPE converted to integer
[2013-07-04 17:38:01] [00000] type reference permission.permission_id%TYPE converted to integer
[2013-07-04 17:38:01] [42601] ERROR: syntax error at or near "INSERT"
Where: SQL statement in PL/PgSQL function "permission_create" near line 9
How should I fix this? Is there a way to do this in multiple lines?
Solution:
CREATE FUNCTION permission_create(
IN method permission.permission_method % TYPE,
IN resource permission.permission_resource % TYPE
)
RETURNS TABLE (id INT)
AS
$BODY$
BEGIN
RETURN QUERY
INSERT INTO permission (permission_id, permission_method, permission_resource)
VALUES (DEFAULT, method, resource)
RETURNING permission_id;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
Updateable CTE is supported from PostgreSQL 9.1.
you don't need use CTE (in your case)
postgres=# CREATE OR REPLACE FUNCTION fx()
RETURNS SETOF int AS $$
BEGIN
RETURN QUERY INSERT INTO taba(a) VALUES(1),(2)
RETURNING *;
RETURN;
END;
$$ LANGUAGE plpgsql;
CREATE FUNCTION
postgres=# select * from fx();
fx
----
1
2
(2 rows)