PostgreSQL INSERT INTO syntax error when creating function - postgresql

I'm getting a syntax error but having issues identifying what exactly the issue is. I'm not sure if I'm misunderstanding things here -- but it looks like the INSERT INTO is breaking, but only when it's in the function.
I'm running the below through Hasura:
CREATE OR REPLACE FUNCTION custom_q_into_selected()
RETURNS trigger AS $BODY$
BEGIN
IF NEW.is_custom = true THEN
INSERT INTO selected_question(book_id,question_id)
VALUES(NEW.custom_for_book_id,NEW.id);
END IF;
RETURN NEW;
END;
$BODY$ LANGUAGE plpgsql;
Keep getting this error when I run this:
postgres-error: syntax error at or near "\"
Database logs:
CREATE OR REPLACE FUNCTION custom_q_into_selected() \r
RETURNS trigger AS $BODY$\r
BEGIN\r
IF NEW.is_custom THEN \r
INSERT INTO selected_question(book_id,question_id) VALUES(NEW.custom_for_book_id,NEW.id);\r
END IF;\r
RETURN NEW;\r
END;\r
$BODY$ LANGUAGE plpgsql;\r
Any help is appreciated.

Related

Cannot catch Exception from Postgres plpgsql Procedure and Exception handling best practices?

I have a plpgsql Procedure where I am simply trying to handle any possible exceptions, since I will be running these Procedures on pg_cron (automated) and I do not want anything to fail. The basic skeleton of the procedure looks like this:
CREATE OR REPLACE PROCEDURE marketing_offers.stackover_overflow_ex_question(limit_size integer)
LANGUAGE plpgsql
AS
$procedure$
DECLARE
n_rec_cnt bigint;
BEGIN
LOOP
EXIT WHEN n_rec_cnt = 0;
WITH cte AS (SELECT *
FROM master_table mt
where mt.created_date <= '1999-01-01'::time
LIMIT limit_size)
INSERT INTO some_archive_table (SELECT * FROM cte)
COMMIT;
GET DIAGNOSTICS n_rec_cnt = row_count;
RAISE EXCEPTION 'Max retry count exceeded';
begin
EXCEPTION
WHEN OTHERS then
GET STACKED DIAGNOSTICS text_var1 = message_text,
text_var2 = PG_EXCEPTION_DETAIL,
text_var3 = PG_EXCEPTION_HINT;
RAISE NOTICE 'error msg is %', text_var1;
UPDATE job_log
SET error_msg = text_var1
return;
end;
END LOOP;
END;
$procedure$
;
The problem is the RAISE NOTICE with text_var1, which is supposed to hold the SQL exception message, never gets logged neither does the UPDATE statement to my job_log table that should hold the message also.
I also would like to add that , I had to surround the EXCEPTION block with another begin and end , because when I did not, I would get a syntax error.
I am simply trying to catch the exception from my SQL script - should I be using a different EXCEPTION type and should I be looking for specific SQL codes? I'm kind of confused what the best practices are here
You should really start indenting your code. This is not just about being pretty, but it would immediately show you the problem with your code.
Your code, properly indented, looks like this:
BEGIN
LOOP
EXIT WHEN n_rec_cnt = 0;
COMMIT;
RAISE EXCEPTION 'Max retry count exceeded';
begin
EXCEPTION
WHEN OTHERS then
RAISE NOTICE 'error msg is %', text_var1;
UPDATE job_log
SET error_msg = text_var1
return;
end;
END LOOP;
END;
There are two things obvious:
You forgot the semicolon in front of the RETURN → syntax error
The EXCEPTION clause is part of the block that starts with the BEGIN in the immediately preceding line.
Since an EXCEPTION clause will only catch exceptions thrown in the block to which it belongs, and that block is empty, execution can never reach the exception handler.
You are obviously fighting with the restriction that COMMIT cannot be executed inside a block with an EXCEPTION clause. But since it is not clear what you want to do (for example, the unconditional RAISE EXCEPTION seems pointless), it is difficult to help you.
I had the similar problem. when I removed commit and roll back from my code(I read postgres is auto commit) it worked fine. and also begin infront of exception is not neededI think.

Plpgsql function error at or near Create syntax

I have just started using postgres and am new to the whole thing, I am using postgres version 9.6 and am trying to create a new function however I keep getting the error
ERROR: syntax error at or near "CREATE"
LINE 6: CREATE OR REPLACE FUNCTION time_passed(created text)
my function is this
CREATE OR REPLACE FUNCTION time_passed(created text)
RETURNS text AS
BEGIN
created :='Now';
RETURN created;
END;
$$ LANGUAGE plpgsql
What could be wrong with the Create syntax?
You're missing the opening $$ to match the closing ones:
CREATE OR REPLACE FUNCTION time_passed(created text)
RETURNS text AS $$
-- Here --------^
BEGIN
created :='Now';
RETURN created;
END;
$$ LANGUAGE plpgsql

Unable to get the SQL function to run

I'm unable to get a simple SQL function that run over rows of a tables and display it column info
Here how the SQL function looks like.
CREATE OR REPLACE FUNCTION iterators() RETURNS Void AS $$
DECLARE
t2_row call_records%ROWTYPE;
BEGIN
FOR t2_row IN (SELECT timestamp,plain_crn INTO call_records limit 2)
LOOP
RAISE NOTICE t2_row.timestamp;
END LOOP
END
$$ LANGUAGE plpgsql;
But I keep getting following error
ERROR: syntax error at or near "t2_row"
LINE 7: RAISE NOTICE t2_row.timestamp;
I'm not sure what possible syntax error the code has? Is it possible to get a bit more verbose error log or know as to what is the syntax error in code that I have to fix.
Statement RAISE requires format string. It should be trivial, but should be there.
RAISE NOTICE '%', t2_row.timestamp;

ERROR: syntax error at or near "$$

I am a newbie on Postgres.
I try to convert an Oracle PL/SQL script to Postgres.
At this, it's not a succes !
Here is a simple code with errors :
$$
DECLARE
Err_Exec numeric; -- Erreur d'execution.
BEGIN
Err_Exec := 0;
END;
$$ LANGUAGE plpgsql;
which reports:
:13: ERROR: syntax error at or near "$$
Any idea to this error when executing ?
That isn't a complete statement.
You need a CREATE FUNCTION statement if you're trying to create a function, or a DO block if you're trying to run a one-off procedure.
For one-off DO blocks, it should look like
DO LANGUAGE plpgsql
$$
BEGIN
.... plpgsql code here ...
END;
$$;

Function argument not interpreted inside body

I am trying to create a PL/pgSQL function in PostgreSQL 9.3.6, but there is weird behavior when using the passed argument inside function body. Here is the 'very simple' function:
CREATE OR REPLACE FUNCTION myschema.test (myarg text) RETURNS text AS $$
DECLARE
entity text;
buffer text;
BEGIN
CREATE ROLE myarg;
RETURN myarg;
END;
$$ LANGUAGE plpgsql;
So, if for instance myarg equals 'test':
A role named 'myarg' is created (WRONG)
'test' is returned (CORRECT)
I searched for hours why this could be and no clue... security parameter? Why is myarg not interpreted for creating roles?
Testing with phpPgAdmin through sql files if this has any impact.
You should use:
EXECUTE FORMAT('CREATE ROLE %I', myarg);
Here you can find an explanation (especially read Craig's answer).
As Erwin stated (thanks), %I is safer than %s. Anyway, myarg should be verified before the function call. Try for example
SELECT myschema.test('something; stupid; here;')