Postgresql Unknow field in function - postgresql

I'm trying to create a function in postgresql and i get the following error:
ERROR: column "A00" does not exist
LINE 1: SELECT * from "UpdateStatus"(91206618515,"A00")
^
********** Error **********
ERROR: column "A00" does not exist
SQL state: 42703
Character: 50
My function bellow:
CREATE OR REPLACE FUNCTION UpdateStatus(id bigint,status varchar(3))
RETURNS void AS $$
BEGIN
UPDATE tb_test
set
id_status = status
where id_test = id;
END
$$ LANGUAGE plpgsql;
if i put the parameter like this "UpdateStatus"(91206618515,'A00')
i get the following error:
ERROR: function UpdateStatus(bigint, unknown) does not exist
Runnig /df +updatestatus
public | updatestatus | void | cpf bigint, status character
public | updatestatus | void | cpf bigint, status character varying
Thanks in advance.

In SQL you mask strings with single quotes, and you must remove the double quotes around the function name, because you have created it with a case insensitive name:
SELECT * from UpdateStatus(91206618515, 'A00')

My bet is you create multiple functions with similar signature. Check your schema functions and drop duplicate function.
Try changing the name of your function for testing. Because your function should work.
SQL DEMO
CREATE OR REPLACE FUNCTION TestUpdateStatus(id bigint,status varchar(3))
RETURNS varchar AS $$
BEGIN
return status;
END
$$ LANGUAGE plpgsql;
SELECT TestUpdateStatus(1, 'A001')
OUTPUT and see how result show lowercase even when define with CamelCase?

Related

I have the following string '3,45,543,6,89'. Need output like table thorugh function. Pl help me get output through postgresql function

CREATE OR REPLACE FUNCTION public.SplitToTable(
iv_datalist varchar,iv_Separator varchar)
RETURNS TABLE(out_param varchar)
LANGUAGE 'plpgsql'
COST 100
VOLATILE
ROWS 1000
AS $BODY$
BEGIN
RETURN query select (select regexp_split_to_table(iv_datalist, iv_Separator) as out_param );
END
$BODY$;
When I run
select * from splitToTable('3,34,4,545,35,3',',');
I get this error:
ERROR: structure of query does not match function result type
DETAIL: Returned type text does not match expected type character varying in column 1.
CONTEXT: PL/pgSQL function splittotable1(character varying,character varying) line 4 at RETURN QUERY
SQL state: 42804
You'd have to declare the function as RETURNS text rather than RETURNS varchar. Use text everywhere, as that is the preferred string type in PostgreSQL. That way, you have no problems with type conversions.
The function could be written simpler as
CREATE OR REPLACE FUNCTION public.SplitToTable(
iv_datalist text,
iv_Separator text
) RETURNS TABLE(out_param text)
LANGUAGE sql
IMMUTABLE
AS
$BODY$SELECT * FROM regexp_split_to_table(iv_datalist, iv_Separator);$BODY$;
Essentially, the function is useless; you could just use regexp_split_to_table directly.

How to pass ENUM variable as input for POSTGRESQL functions

I have a function in MySQL which works fine:
CREATE PROCEDURE `Accounts_Active`(IN_DeptName VARCHAR(255), IN_Src ENUM('TRAINING','ELZA'))
BEGIN
END$$
DELIMITER ;
But when converted to PostgreSQL:
CREATE or replace FUNCTION Accounts_Active(IN_DeptName VARCHAR(255), IN_Src ENUM('TRAINING','ELZA'))
RETURNS void
AS
$$
BEGIN
RAISE INFO ' ';
END;
$$ LANGUAGE plpgsql;
The following error occurs:
ERROR: type enum does not exist
SQL state: 42704
Any guidance on how I can fix this error would be appreciated.
Create an enum data type:
CREATE TYPE atype AS ENUM ('TRAINING', 'ELZA');
Then you can use it as function parameter:
CREATE FUNCTION Accounts_Active(
IN_DeptName text,
IN_Src atype
) RETURNS void
...
When using enums, remember that you can add values to such a data type, but never again remove them. Often you will be better of using a string data type like text, but of course then you have to write code that checks the input for validity.

Why am I getting syntax error at or near "#"

When trying to join two tables and update one of them, I'm receiving an unexpected error from this function right here:
CREATE OR REPLACE FUNCTION tsi.update_data(_creation_time int)
RETURNS VOID
AS $$
BEGIN
EXECUTE format($sql$
UPDATE tsi.forecasts_%s a SET
a."incidents # 01:00" = b.n_incid,
a."road # 01:00" = b.n_roads
FROM tgi_tmp b WHERE a.link_ix = b.link_id;
$sql$,_creation_time);
END $$ LANGUAGE plpgsql;
It gives me this error message:
syntax error at or near "#"
cidents # 01:00" = n_incid,
^
Do anyone know why I'm getting this error? The tables do contain the mentioned columns, so that is not the problem. Is postgres having a hard time dealing with string-columns in an Execute-format?
Postgres version: 10.5
Simplified table structure:
CREATE TABLE tsi.forecasts_%s (
link_ix int PRIMARY KEY,
"slipincidents # 00:00" SMALLINT NOT NULL,
"roadcoverage # 00:00" SMALLINT NOT NULL,
);
and tgi_tmp:
CREATE TEMPORARY TABLE tgi_tmp (
link_id TEXT,
n_road SMALLINT,
n_incid SMALLINT
CONSTRAINT tgi_tmp_pkey PRIMARY KEY (link_id)
);
Weird it complaints about the # doesn't do that for me. What however is wrong is specifying the table (alias) for the columns you are assigning to in the set. You should only specify the column names.
CREATE OR REPLACE FUNCTION tsi.update_data(_creation_time int)
RETURNS VOID
AS $$
BEGIN
EXECUTE format($sql$
UPDATE tsi.forecasts_%s a SET
"incidents # 01:00" = b.n_incid,
"road # 01:00" = b.n_roads
FROM tgi_tmp b WHERE a.link_ix = b.link_id;
$sql$,_creation_time);
END $$ LANGUAGE plpgsql;
Trying to debug your function, I get these error messages, one after the other:
ERROR: operator does not exist: integer = text
ERROR: column b.n_roads does not exist
ERROR: column "a" of relation "tsi_forecasts_1" does not exist
ERROR: column "incidents # 01:00" of relation "tsi_forecasts_1" does not exist
Each after fixing the previous error.
I arrive at this working version:
CREATE OR REPLACE FUNCTION tsi_update_data(_creation_time int)
RETURNS VOID AS
$func$
BEGIN
EXECUTE format($sql$
UPDATE tsi_forecasts_%s a
SET "slipincidents # 00:00" = b.n_incid -- don't table-qualify target cols
, "roadcoverage # 00:00" = b.n_road -- col names in q don't match
FROM tgi_tmp b
WHERE a.link_ix = b.link_id::int; -- your db design forces a cast
$sql$, _creation_time);
END
$func$ LANGUAGE plpgsql;
But I cannot reproduce your error:
syntax error at or near "#"
cidents # 01:00" = n_incid,
^
Which must be invoked by something that's not in the question, like outer double-quoting or special meaning of characters in your unnamed client program.
All that aside, it might pay to reconsider your naming convention and your db design. Use legal, lower-case, unquoted identifiers and matching data types (link_ix is int while link_ix is text).
Works for some reason when I'm not specifying the offset. Like this:
CREATE OR REPLACE FUNCTION tsi.update_data(_creation_time int)
RETURNS VOID
AS $$
BEGIN
EXECUTE format($sql$
UPDATE tsi.forecasts_%s a SET
"incidents # %s" = b.n_incid,
"road # %s" = b.n_roads
FROM tgi_tmp b WHERE a.link_ix = b.link_id;
$sql$,_creation_time, '01:00', '01:00');
END $$ LANGUAGE plpgsql;

how do I pass a user defined type variable to a function as a parameter?

I want to pass a user defined type parameter to a PLPGSQL function, but I am getting this error at runtime:
dev=# select process_shapes();
ERROR: invalid input syntax for integer: "(,,7)"
CONTEXT: PL/pgSQL function process_shapes() line 9 at SQL statement
dev=#
For some reason, the parameters are not passed correctly and I have no idea why it doesn't work.
My functions are:
CREATE OR REPLACE FUNCTION join_shapes(first_shape shape_t,second_shape shape_t,OUT new_shape shape_t)
AS $$
DECLARE
BEGIN -- simplified join_shape()s function
new_shape.num_lines:=first_shape.num_lines+second_shape.num_lines;
END;
$$ LANGUAGE PLPGSQL;
CREATE OR REPLACE FUNCTION process_shapes()
RETURNS void AS $$
DECLARE
rectangle shape_t;
triangle shape_t;
produced_shape shape_t;
BEGIN
rectangle.num_lines:=4;
triangle.num_lines:=3;
SELECT join_shapes(rectangle,triangle) INTO produced_shape;
RAISE NOTICE 'produced shape = %s',produced_shape;
END;
$$ LANGUAGE PLPGSQL;
Type definition:
CREATE TYPE shape_t AS (
shape_id integer,
shape_name varchar,
num_lines integer
);
Postgres version: 9.6.1
When the target of a SELECT ... INTO statement is of a composite type, it will assign each of the columns returned by the SELECT to a different field in the target.
However, SELECT join_shapes(rectangle,triangle) returns a single column of type shape_t, and it's trying to cram the whole thing into the first column of the target, i.e. produced_shape.shape_id (hence the error message about a failed integer conversion).
Instead, you need a SELECT statement which returns three columns. Just replace
SELECT join_shapes(rectangle,triangle)
with
SELECT * FROM join_shapes(rectangle,triangle)
Alternatively, you could use
produced_shape := (SELECT join_shapes(rectangle,triangle));
which performs a single assignment, rather than trying to assign the target fields individually.
For other people whom want to pass composite types to functions:
create type pref_public.create_test_row_input as (
name text
);
create or replace function pref_public.create_test_row(test_row pref_public.create_test_row_input) returns pref_public.test_rows as $$
insert into pref_public.test_rows (name)
values
(test_row.name)
returning *;
$$ language sql strict security definer;
grant execute on function pref_public.create_test_row to pref_user;
You'll need to use row()
select * from pref_public.create_test_row(row('new row'));
More info here

catching select query return value in postgresql function and use it

I want to execute this function. But it got error said
ERROR:
syntax error at or near ":="
LINE 7: select result:=MAX(path_history_id)as path INTO result from...
In this function I want to:
execute select with (MAX) and it will return maximum id from a table;
catch that value (it is an integer value);
put that value into last select query where condition.
I cant find a way in postgresql to do this.
CREATE OR REPLACE FUNCTION memcache(IN starting_point_p1 character varying, IN ending_point_p1 character varying)
RETURNS TABLE(path integer, movement_id_out integer, object_id_fk_out integer, path_history_id_fk_out integer, walking_distance_out real, angel_out real, direction_out character varying, time_stamp_out timestamp without time zone, x_coordinate_out real, y_coordinate_out real, z_coordinate_out real) AS
$BODY$
DECLARE result int;
BEGIN
select result:=MAX(path_history_id)as path INTO result from path_history_info where starting_point=starting_point_p1 and ending_point =ending_point_p1 and achieve='1';
return query
select * from movement_info where path_history_id_fk=result;
END;
$BODY$
LANGUAGE plpgsql
Syntax Error
The first query inside your function needs to be changed as follows:
select MAX(path_history_id)as path INTO result
from path_history_info
where starting_point=starting_point_p1
and ending_point =ending_point_p1 and achieve='1';
A single Query
You don't actually need a stored procedure for this. A single query can achieve the same result.
select * from movement_info where path_history_id_fk =
(SELECT MAX(path_history_id) FROM path_history_info
where starting_point=starting_point_p1
and ending_point =ending_point_p1 and achieve='1';