facing syntax error at or near if postgres - postgresql

I am new to POSTGRES and currently exploring how to create and execute stored procedures. I was trying a simple example with conditional constructs and got stuck with an error :(
create procedure learnpostgre(x integer, y integer)
language plpgsql
as $$
if x > y
then
raise 'X is greater'
end if
$$;
The error I am getting is 'syntax error at or near if'. I saw similar issues on SO and tried wrapping my code block under do block but faced the same error message for 'Do'. I am running my code in pgadmin4 and postgres version is 14.X

You're missing begin and end and a few semicolons. This should work:
create procedure learnpostgre(x integer, y integer)
language plpgsql
as $$
begin
if x > y
then
raise 'X is greater';
end if;
end
$$

Related

IF-THEN statement inside a procedure

Why I get the following error:
psql:q.sql:22: ERROR: syntax error at or near "IF"
LINE 4: IF id IS NOT NULL THEN
^
psql:q.sql:23: WARNING: there is no transaction in progress
COMMIT
from:
CREATE PROCEDURE my_procedure(id integer)
LANGUAGE SQL
BEGIN ATOMIC
IF id IS NOT NULL THEN
END IF;
END;
But if I remove the IF-THEN statement everything is fine.
My attempt:
I found the correct syntax by creating a new procedure using DBeaver which actually mentioned here:
CREATE OR REPLACE PROCEDURE my_procedure()
LANGUAGE plpgsql
AS $procedure$
BEGIN
END;
$procedure$
Now the problem is there is no syntax highlighting for plpgsql :(

Continue a PL/pgSQL block even if it finds an error

I've gotten the essence of the function below from: How to re-check an SQL function created with check_function_bodies=false?
The context is: I'm migrating some functions from Oracle to PostgreSQL. While migrating them, I used the option which establishes a non-verification of their bodies, so that all function could be created without being compiled/verified, what would "speed" the process. Therefore, now - using the function bellow as a mean - I am trying to make an analysis of each function created in this X schema.
My problem is that the function doesn't continue when it finds an error. My central thought is to run the recompile_function() once and get all the messages fired when an error is found for each function. I have tried to enclosure the statement that verifies the function within a sub-block (BEGIN, EXCEPTION, END). It didn't work though.
What am I missing here?
CREATE OR REPLACE FUNCTION public.recompile_functions()
RETURNS void
LANGUAGE plpgsql
AS
$function$
DECLARE
l_func regprocedure;
BEGIN
--test plpgsql functions
FOR l_func IN (
SELECT oid
FROM pg_proc
WHERE pronamespace='<<schema>>'::regnamespace
AND prolang=(SELECT oid FROM pg_language WHERE lanname='plpgsql')
AND pg_proc.oid NOT IN (select tg.tgfoid FROM pg_trigger tg)
AND pg_proc.prokind = 'f'
)
LOOP
BEGIN
PERFORM plpgsql_validator(l_func);
EXCEPTION
WHEN OTHERS THEN
RAISE EXCEPTION 'Function % failed validation checks: %', l_func::text, SQLERRM;
END;
END LOOP;
END;
$function$

Postgres: syntax error when trying to create multiple stored procedures from a single file

I am using Postgres version 13.1. I want to have a single file where I could store all stored procedures and create them in one shot. But when I put multiple stored procedures in a single file, I get the following error. What am I missing?
In my test.sql file I have the following content:
create or replace procedure tmp1(
)
language plpgsql as
$$
declare
l_count integer;
begin
select 1 into l_count;
raise info 'count: %', l_count;
end;
$$
create or replace procedure tmp2(
)
language plpgsql as
$$
declare
l_count integer;
begin
select 1 into l_count;
raise info 'count: %', l_count;
end;
$$
If I only have the first procedure it gets created and I can call it successfully. But the moment I have the second identical procedure with a different name, it gives me an error as follows (when run from psql):
psql=> \i test.sql
psql:test.sql:23: ERROR: syntax error at or near "create"
LINE 12: create or replace procedure tmp2(
OK - right after posting I tried putting a ";" after the end of first procedure and it works

How to run a PostgreSQL function

I am struggling to execute a PostgreSQL function. I am trying to read the documentation on the side but still no use. I am using Toad Extension for eclipse to develop/run the function
So far, this is what I have written
CREATE OR REPLACE FUNCTION dbName.function_name()
RETURNS VOID AS
$BODY$
DECLARE
x_cur CURSOR FOR select * from dbName.x;
x_row RECORD;
BEGIN
OPEN x_cur;
RAISE NOTICE 'Cursor opened';
LOOP
FETCH x_cur INTO x_row;
EXIT WHEN NOT FOUND;
END LOOP;
CLOSE x_cur;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
I executed the script and then ran select dbName.function_name(); in the sql worksheet and I don't see any output.
I remember writing functions on plsqldeveloper was so easy and interactive and i am struggling with PostgreSQL, could you guys help me getting a headstart.
I dont see any problem using pgAdmin.
The function return VOID, but the RAISE NOTICE show the message.
I simplify the function
CREATE OR REPLACE FUNCTION function_name()
RETURNS VOID AS
$BODY$
DECLARE
BEGIN
RAISE NOTICE 'Cursor opened';
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
And execute the function
SELECT function_name();

Error in postgresql function

Explain me please, why I'm getting error here:
djabase=# CREATE or REPLACE FUNCTION upset(domain_name varchar)
RETURNS TABLE (id int, domain varchar(50)) AS $$
BEGIN
SELECT domain from separser_domains where domain=$1;
EXCEPTION
when sqlstate 'no_data' then
INSERT into separser_domains(domain) VALUES (domain_name);
END; $$
LANGUAGE 'sql' STABLE;
ERROR: syntax error at or near "SELECT"
LINE 4: SELECT domain from separser_domains where domain=$1;
You are using PLPGSQL syntax but declaring the function as SQL. This the reason, why the function fails with a SYNTAX ERROR. The language of the function is declared with the statement LANGUAGE and you declared it in the last line:
LANGUAGE 'sql' STABLE;
SQL functions do not support the BEGIN - END statement and exceptions trapping.
To fix it, simple change LANGUAGE 'sql' in LANGUAGE 'plpgsql'.
Some other considerations:
Catching a exception in this place is probably not necessary. Use the FOUND variable instead.
With the STABLE keyword, the function can not perform INSERT. Change STABLEto VOLATILE.
You declared RETURNS TABLE but the function does not return anything. Use RETURNS VOID instead.
Using SELECT and discarding the result is not allowed. Use PERFORM instead.
A valid version of your version could be this:
DROP FUNCTION IF EXISTS upset(varchar);
CREATE or REPLACE FUNCTION upset(domain_name varchar)
RETURNS VOID AS $$
BEGIN
PERFORM domain from separser_domains where domain=domain_name;
IF NOT FOUND THEN
INSERT into separser_domains(domain) VALUES (domain_name);
END IF;
RETURN;
END;
$$
LANGUAGE 'plpgsql' VOLATILE;