plpgsql function with conditional statement to access column name - postgresql

I'm trying to create a conditional statement in a plpgsql function what will filter out only the records I want through an if statement. I am just testing now, but here is my table structure:
CREATE TABLE addresses
(
gid serial NOT NULL,
housenum character varying(30),
prefix character varying(10),
name character varying(100),
type character varying(16)
)
Here is my function:
CREATE OR REPLACE FUNCTION "geomCheck".getAllFoo() RETURNS SETOF
addresses AS
$BODY$
DECLARE
r addresses%rowtype;
BEGIN
FOR r IN SELECT * FROM addresses
WHERE gid > 0
LOOP
if name = 'BRIE' then
RETURN NEXT r;
end if;
END LOOP;
RETURN;
END
$BODY$
LANGUAGE 'plpgsql' ;
But when I go to call the function I get this error:
ERROR: column "name" does not exist
LINE 1: SELECT name = 'BRIE'
^
QUERY: SELECT name = 'BRIE'
CONTEXT: PL/pgSQL function "geomCheck".getallfoo() line 8 at IF
********** Error **********
ERROR: column "name" does not exist
SQL state: 42703
Context: PL/pgSQL function "geomCheck".getallfoo() line 8 at IF
How do I check if the name = 'BRIE' in the if statement?

You need to prefix name with r:
BEGIN
FOR r IN SELECT * FROM addresses
WHERE gid > 0
LOOP
if r.name = 'BRIE' then -- instead of "name" => "r.name"
RETURN NEXT r;
end if;
END LOOP;
RETURN;
END

Related

ERROR: syntax error at or near "declare" LINE 5: declare #b_result bit ^

This is a working function in SQL Server 2014 Express
CREATE FUNCTION [dbo].[Func_Account_FollowingCustomer]
(#AccountNumber NVARCHAR(20))
RETURNS BIT
AS
BEGIN
DECLARE #bResult BIT
IF (SELECT COUNT(AccountNumber) FROM dbo.Account AS A
WHERE DetailByAccountObject = 1
AND AccountObjectType = 1
AND AccountNumber = #AccountNumber) > 0
SET #bResult = 1
ELSE
SET #bResult = 0
RETURN #bResult
END
I try to convert to PostgreSQL 14, I have
CREATE FUNCTION public.func_account_following_customer(IN account_number character varying)
RETURNS bit
LANGUAGE 'sql'
declare #b_result bit
begin
if(select count(account_number) from account as a where detail_by_account_object = 1 and account_object_type = 1 and account_number = #account_number) > 0
set #b_result = 1
else
set #b_result = 0
return #b_result;
end;
ALTER FUNCTION public.func_account_following_customer(character varying)
OWNER TO postgres;
Error
ERROR: syntax error at or near "declare" LINE 5: declare #b_result bit ^
How to fix it?
language sql can't use variables or procedural elements (like IF), you need language plpgsql - but the syntax for variable names is different and the assignment is not done using set
The function body is a string constant, typically specified using dollar quoting.
If you want to return true/false flags, use boolean instead of bits.
Parameters or variables are referenced using # but simply with their name.
But you don't need procedural code for such a simple SQL query that just returns true/false.
CREATE FUNCTION public.func_account_following_customer(IN p_account_number character varying)
RETURNS boolean
LANGUAGE sql
as
$$
select count(*) > 0
from account as a
where detail_by_account_object = 1
and account_object_type = 1
and account_number = p_account_number;
$$
;
As a PL/pgSQL function this would be:
CREATE FUNCTION public.func_account_following_customer(IN p_account_number character varying)
RETURNS boolean
LANGUAGE plpgsql
as
$$
declare
l_result boolean;
begin
if (select count(*)
from account as a
where detail_by_account_object = 1
and account_object_type = 1
and account_number = p_account_number) > 0
then
l_result := true;
else
l_result := false;
end if;
return l_result;
end;
$$
;

Assign select value to variable into Execute in PostgreSQL 9.3 function

Consider a function like that:
CREATE OR REPLACE FUNCTION public.foo(
string1 character varying
)
RETURNS integer AS
$BODY$
DECLARE
id1 INTEGER;
BEGIN
id1 := (SELECT id FROM mytable WHERE mycolumn = string1);
END;
......
It works fine and I get the id1 value for using in other part of the function.
Now, I want to rewrite the function and pass a name who act like identifier of the table.
CREATE OR REPLACE FUNCTION public.foo(
string1 character varying,
tablecode character varying --new argument
)
RETURNS integer AS
$BODY$
DECLARE
id1 INTEGER;
BEGIN
.....
And now, there are my attepms for get id1 value and the errors:
EXECUTE FORMAT('id1 := (SELECT id FROM %I WHERE mycolumn = %s)', tablecode||'_Conceptos', quote_literal(string1));
Error:
ERROR: syntax error at or near "id1"
LINE 1: id1 := (SELECT id FROM "CENZANO_Conceptos" WHERE codigo ...
^
QUERY: id1 := (SELECT id FROM "CENZANO_Conceptos" WHERE codigo = 'CENZANO')
--second attepm
EXECUTE FORMAT ('SELECT %I.id INTO id1 FROM %I WHERE mycolumn = %s', tablecode||'_Conceptos',tablecode||'_Conceptos',quote_literal(string1));
END;
......
Error:
ERROR: EXECUTE of SELECT ... INTO is not implemented
HINT: You might want to use EXECUTE ... INTO or EXECUTE CREATE TABLE ... AS instead.
Thanks in advance
You could use INTO:
EXECUTE FORMAT('(SELECT id FROM %I WHERE mycolumn = %s)'
, tablecode||'_Conceptos', quote_literal(string1)) INTO id1;

Return table in function postgres

When trying to return table in postgres, this my query:
CREATE OR REPLACE FUNCTION list_log_approval(IN p_create_code INTEGER,IN p_update_code INTEGER) RETURNS
TABLE(processcode integer, processname VARCHAR,id BIGINT, pleader CHARACTER VARYING,activity VARCHAR,date_plead timestamp)
LANGUAGE plpgsql AS $$
BEGIN
IF NOT EXISTS( SELECT * FROM log_approval WHERE processcode = $1 and status = 'A' or status = 'D')AND NOT EXISTS(SELECT * FROM log_approval WHERE processcode = $2 and status = 'A' or status = 'D') THEN
RETURN QUERY SELECT * from vw_list_appv;
END IF;
RETURN;
END $$;
-- i call like this
select * from list_log_approval(1070,1072)
I get the following error:
[Err] ERROR: column reference "processcode" is ambiguous
LINE 3: processcode**
why is it ambiguous?
processcode is used both as function parameter and as table column.
The best thing is to use function parameters with a different name, like p_processcode.
But you can also disambiguate by qualifying the name: log_approval.processcode for the column and list_log_approval.processcode for the function parameter.

plpgsql function creates sequences for row based tenancy?

Trying to create a function that looks for sequence with particular name if does not exist should create it. Then returns function value of sequence. Part of function that does not seem to be working is where it tests if sequence already exists. Below is code for function
CREATE OR REPLACE FUNCTION public."tenantSequence"(
vtenantid integer,
vtablename character)
RETURNS bigint AS
$BODY$DECLARE
vSeqName character varying;
vSQL character varying;
BEGIN
select ('t' || trim(to_char(vtenantid,'0000')) || vtablename) INTO vSeqName;
if not exists(SELECT 0 FROM pg_class where relkind = 'S' and relname = vSeqName )
then
vSQL := 'create sequence '||vSeqName||';';
execute vSQL;
ELSE
return 0;
end if;
return nextval(vSeqName) * 10000 + vtenantid;
END$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION public."tenantSequence"(integer, character)
OWNER TO postgres;
Problem was case as mentioned by a_horse_with_no_name
changed line assign vSeqName to the following
vSeqName := lower('t' || trim(to_char(vtenantid,'0000')) || vtablename);
Now function works as expected.

Postgresql syntax error for if statement in a function

I am trying to write a function in postgresql and i am getting a syntax error for the if statement:
CREATE OR REPLACE FUNCTION getallcampuses(IN a character varying, IN b character varying)
RETURNS TABLE(campusid charactervarying, campusname character varying) AS
$BODY$
BEGIN
if $1 = 'PREK' then
SELECT * from "SIS_campus";
ELSE
BEGIN
IF $2 = 'DAll' then
SELECT distinct(district_id) || 'ALL' AS CampusID, ' District' AS CampusName
UNION
SELECT campus_id, name
FROM "SIS_campus"
WHERE district_name IS NOT NULL
order by name;
Elsif $2 = 'All' then
SELECT campus_id, name
FROM "SIS_campus"
WHERE district_name IS NOT NULL
and isnumeric(name) = 0
order by name;
end if;
END
end if;
END
$BODY$
LANGUAGE sql;
Here is the error:
ERROR: syntax error at or near "if"
LINE 5: if $1 = 'PREK' then
^
The function body is PL/PgSQL, but you declared it LANGUAGE sql.
Use LANGUAGE plpgsql if you're writing PL/PgSQL.
(related prior answer)