How could I return a varchar message in Postgres as part of function return table that isn't in any table? - postgresql

I need to return a message (a different message according some evaluations inside de function), but when I call the function it returns this error message: "Returned type unknown does not match expected type character varying in column 2".
CREATE OR REPLACE FUNCTION myfunction()RETURNS TABLE(
cod INTEGER,
answ CHARACTER VARYING
) AS $BODY$
BEGIN
RETURN QUERY
select 0, 'here goes the message';
END;
$BODY$
LANGUAGE plpgsql;

try:
CREATE OR REPLACE FUNCTION myfunction()RETURNS TABLE(
cod INTEGER,
answ CHARACTER VARYING
) AS $BODY$
BEGIN
RETURN QUERY
select 0, 'here goes the message'::CHARACTER VARYING;
END;
$BODY$
LANGUAGE plpgsql;

Related

Unable to call procedure inside another procedure with loop using PLPGSQL

Trying to save data into table using procedures and loop, but unable to solve this error.
CREATE OR REPLACE PROCEDURE quality_save(p_1 character varying, p_2 character varying, p_3 character varying DEFAULT NULL::character varying, INOUT response character varying DEFAULT '1'::character varying)
LANGUAGE plpgsql
AS $procedure$
declare
begin
if 1=1 then
raise notice '_Insert start';
insert into table_A
(
brand,
model,
year
)
values(
p_1,
p_2,
p_3
);
raise notice 'insert-end';
else
select 'p_1,p_2 cannot be null' into response;
end if;
exception
when sqlstate '23505' then
select 'Duplicate Record' into response;
--when others then
-- select '-1' into response;
end
$procedure$
********************************************************************************************
CREATE OR REPLACE PROCEDURE auto_save(INOUT response character varying DEFAULT '1'::character varying)
LANGUAGE plpgsql
AS $procedure$
declare
response varchar(100);
f record;
l record;
m record;
begin
for f in select p_1,p_2,p_3 from table_dump
loop
call public.quality_save(
p_1 =>f.p_1,
p_2 =>f.p_2,
p_3 =>f.p_3
)
;
select 1 into response;
end loop;
select 1 into response;
end;$procedure$
;
SQL Error [42601]: ERROR: procedure parameter "response" is an output parameter but corresponding argument is not writable
Where: PL/pgSQL function auto_save(character varying) line 182 at CALL
I tried rewriting second procedure as function but still giving the same error.
You didn't pass an argument for response. Call the procedure like this:
DECLARE
f record;
p_response character varying;
BEGIN
[...]
CALL public.quality_save(
p_1 =>f.p_1,
p_2 =>f.p_2,
p_3 =>f.p_3,
response => p_response
);
[...]

PSQLException: ERROR: syntax error at or near "test"

I'm getting the same error as in the title:
CREATE OR REPLACE FUNCTION func(param varchar) RETURNS varchar AS
'BEGIN
LOCK public.routes;
return (SELECT * FROM public.routes WHERE guid = 'test');
END;' LANGUAGE plpgsql
What might be the problem? I can execute the same in console and it's gonna work.
You need to escape single quotes embedded in string literals by doubling them:
CREATE OR REPLACE FUNCTION func(param varchar) RETURNS varchar AS
'BEGIN
LOCK public.routes;
return (SELECT * FROM public.routes WHERE guid = ''test'');
END;' LANGUAGE plpgsql
That's the reason why people usually use dollar quoting for the body of functions:
CREATE OR REPLACE FUNCTION func(param varchar) RETURNS varchar AS
$body$
BEGIN
LOCK public.routes;
return (SELECT * FROM public.routes WHERE guid = 'test');
END;
$body$
LANGUAGE plpgsql
However, even if you get the syntax right: the function will not work. It is defined to return a single (scalar) value of type varchar but it returns the all rows from the table routes. If you want to return multiple rows, you need to define the function as returns setof or returns table. In your case returns setof routes would be applicable:
CREATE OR REPLACE FUNCTION func(param varchar)
RETURNS setof public.routes
AS
$body$
BEGIN
LOCK public.routes;
return (SELECT * FROM public.routes WHERE guid = 'test');
END;
$body$
LANGUAGE plpgsql
If you intend to return the value of a single column of a single row (assuming that guid is defined as PK or unique), then indeed returns varchar would work. But then you should change the select statement to select some_column from .. or something similar

write a function in pl/pgsql

This is my query.
select origindept, `count(am_course_name)` as total_course
from am_courseoffered
group by origindept;
I am trying to create a function who will return this query.
CREATE OR REPLACE FUNCTION getcourse ()
RETURNS TABLE (
course_origindept character varying,
course_ count(am_course_name) character varying
)
AS $$
BEGIN
RETURN QUERY select origindept, count(am_course_name) as number_total_course
from am_courseoffered
group by origindept;
END; $$
LANGUAGE 'plpgsql';
There are some error in my function.
ERROR: syntax error at or near "character"
LINE 4: course_ count(am_course_name) character varying
How i create function who will return this query.
Off the top of my head, the count function should return a datatype of bigint, so I would think declaring the count as a varchar would cause a datatype mismatch. Something like this should fix that:
CREATE OR REPLACE FUNCTION getcourse ()
RETURNS TABLE (
course_origindept character varying,
course_count bigint -- change here
) AS $$
BEGIN
RETURN QUERY
select origindept, count(am_course_name) as number_total_course
from am_courseoffered
group by origindept;
END;
$$
LANGUAGE plpgsql;
I do have to ask, though... is this an academic exercise to understand functions? The use case is questionable enough, as a view would be more appropriate.

PostgreSQL function does not return a value

-- I can not understand where the error
CREATE OR REPLACE FUNCTION get_person_membership (IN person_urn CHARACTER VARYING)
RETURNS TEXT AS
$BODY$
DECLARE
result text;
urn ALIAS FOR $1;
BEGIN
SELECT INTO result pers.mx_groupmember FROM mt_person AS pers, mxt_recordheader AS rech
WHERE rech.primaryurn = 'urn'
AND rech.entitytype = 'person'
AND rech.logicalserverprefix = 'EA'
AND rech.id = pers.id;
RETURN result;
END;
$BODY$
LANGUAGE plpgsql
VOLATILE
COST 100
i simplified your query:
For input you can use $1, this goes to direct your condition.
You can return direct your result if you dont need anywhere else.
select * from get_person_membership('something');
CREATE OR REPLACE FUNCTION get_person_membership (IN person_urn CHARACTER VARYING)
RETURNS TEXT AS
$BODY$
BEGIN
RETURN (select pers.mx_groupmember --returns single value
FROM mt_person AS pers, mxt_recordheader AS rech
WHERE rech.primaryurn = $1 --input value from person_urn
AND rech.entitytype = 'person'
AND rech.logicalserverprefix = 'EA'
AND rech.id = pers.id);
END;
$BODY$
LANGUAGE plpgsql
VOLATILE
COST 100
No need for PL/pgSQL, a simple SQL function will do:
CREATE OR REPLACE FUNCTION get_person_membership (IN person_urn CHARACTER VARYING)
RETURNS TEXT AS
$BODY$
SELECT pers.mx_groupmember
FROM mt_person AS pers
JOIN mxt_recordheader AS rech ON rech.id = pers.id
WHERE rech.primaryurn = person_urn --<< input parameter
AND rech.entitytype = 'person'
AND rech.logicalserverprefix = 'EA';
$BODY$
LANGUAGE sql;

PostgreSQL 9.3: isnumeric() in a condition

I need to check whether the given text is numeric or not from the
function.
Creating function for isnumeric():
CREATE OR REPLACE FUNCTION isnumeric(text) RETURNS BOOLEAN AS $$
DECLARE x NUMERIC;
BEGIN
x = $1::NUMERIC;
RETURN TRUE;
EXCEPTION WHEN others THEN
RETURN FALSE;
END;
$$ LANGUAGE plpgsql IMMUTABLE;
Function from which I am calling the isnumeric() function:
create or replace function tm(var text)
returns varchar as
$$
begin
if (select isnumeric(var))=t::BOOLEAN then
raise info 'Is numeric value';
else
raise info 'Not numeric';
end if;
end;
$$
language plpgsql;
Calling functon:
select tm('1');
Getting an error:
Here is the error details:
ERROR: column "t" does not exist
LINE 1: SELECT (select isnumeric(var))=t::BOOLEAN
You don't need a select (and it's actually wrong, as the error indicates) - just call isnumeric directly.
Also, by the way, your function is missing a return statement.
To sum it all up:
create or replace function tm(var text)
returns varchar as
$$
begin
if (isnumeric(var)) then -- call isnumeric directly
raise info 'Is numeric value';
else
raise info 'Not numeric';
end if;
return '0'; -- missing return value in the OP
end;
$$
language plpgsql;
this will help you to identify your field is numeric or not:
select * from Table where field_name ~ '^[0-9]*$'
for decimal values you can use^[0-9.]*$ instead ^[0-9]*$
select getDataType('2021'); == Number
select getDataType('2021-05-12 23:12:10'); == Date
select getDataType('2021-05-12'); == Date
select getDataType('2X'); == String
CREATE
OR REPLACE FUNCTION getDataType ( TEXT ) RETURNS TEXT AS $$ DECLARE
x VARCHAR;
BEGIN
x = $1 :: NUMERIC;
RETURN 'Number';
EXCEPTION
WHEN OTHERS THEN
BEGIN
x = $1 :: DATE;
RETURN 'Date';
EXCEPTION
WHEN OTHERS THEN
RETURN 'String';
END;
END;
$$ STRICT LANGUAGE plpgsql IMMUTABLE;