Can't see raise messages in DBeaver or PgAdmin - postgresql

When i execute the function below (in the picture), i can't find the raise message anywhere even in execution logs: is there anyway to make it appear.
script:
SELECT helloworld('myname');
CREATE OR REPLACE FUNCTION helloWorld(name text) RETURNS void AS $helloWorld$
DECLARE
BEGIN
RAISE LOG 'Hello, %', name;
END;
$helloWorld$ LANGUAGE plpgsql;

Messages with the level LOG typicall don't get sent to the client.
Either use RAISE NOTICE or set client_min_messages to log.

also dont do a basic mistake like me that to see the raise notice messages inside function, you first have to call that function by select public.helloworld()

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.

How to do global exception handler in postgres?

I have search exception handler in postgres it says to add
DECLARE
text_var1 text;
text_var2 text;
text_var3 text;
BEGIN
-- some processing which might cause an exception
...
EXCEPTION WHEN OTHERS THEN
GET STACKED DIAGNOSTICS text_var1 = MESSAGE_TEXT,
text_var2 = PG_EXCEPTION_DETAIL,
text_var3 = PG_EXCEPTION_HINT;
-- call a function which log all this variable perform log_function (text_var1 ,text_var2 , text_var3 );
END;
If I do that for every function is this efficient?
Any performance lack by this approach?
Can't we have a global exception handler for all functions? In this approach I have added the exception handler for every function.
Then save them in variable and save log for that. Can we have any global error handler for that?
Edit
I have to log all exception coming in postgres into a table . I am following this step.
1) write GET STACKED block in all function (if i have 20 function then i write this block in all function)
2)Than log then in table.
What i want is there should be mechanism for global exception handler in postgres , So that i have to not write GET STACKED EXCEPTION block in postgres for all function
Using an EXCEPTION clause in a PL/pgSQL block has a negative performance impact; see the “tip” in the documentation of error trapping.
There is no way to automatically handle all top-level exceptions in a PL/pgSQL function.
My recommendation is that you don't log errors in database functions, but from the application. For one, when your transaction rolls back, the log will be gone.

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;

INFO output despite "SET client_min_messages TO WARNING" just before

postgresql-9.0.15 on CentOS 6.5. I have a plperlu function that outputs an INFO message. I want to suppress it during testing (using psql, which also behaves as below), but I can't even seem to do it from a pgAdminIII (1.18.1 for win2003) query window:
SET client_min_messages TO WARNING;
select my_info_outputting_function('lalala')
I run that and look in the "messages" tab, and there's my INFO message.
(This may appear similar to How to suppress INFO messages when running psql scripts , but I don't want to disable INFO messages for my whole session, just part of it and then set the minimum back to NOTICE.)
What am I doing wrong with the above code snippet? Does client_min_messages not apply to pl/perlu functions?
UPDATE: upon further investigation, it seems to happen even with plpgsql functions, not just plperlu functions:
create or replace function my_info_outputting_function() returns void as $$
begin
raise INFO 'this should not appear...';
return;
end;
$$ language plpgsql;
SET client_min_messages TO WARNING;
select my_info_outputting_function();
I run the above snippet in a pgAdminIII query window and "this should not appear" appears in the messages tab. Quoi?
Update 2: I also tried log_min_messages just in case. Same behaviour.
I asked on the postgresql-general mailing list and received an informative answer: what distinguishes INFO from NOTICE is that INFO does not have a level: it's intended to always go through, no matter what client_min_messages or anything else is set to, from functions that you would call specifically for INFO output. So in my case, the appropriate thing is to output only NOTICE from my function.

Display Comments while Running Script

I've seen the answer to this question in a couple posts. However when I the below which was an answer coming from another post, I get an error. My objective is to simply write comments to the screen as I execute DML commands in a script. However I have not found a simple way to do this.
CREATE OR REPLACE FUNCTION raise_exception(text)
RETURNS void AS $$
BEGIN
RAISE EXCEPTION '%', $1;
END;
$$ LANGUAGE plpgsql;
Called like this: select * from sp_send_msg('go for it');
I would like to be able to do something like this:
SELECT send_comment('Writing widgets to temporary table');
SELECT * INTO t_widgets FROM widgets;
SELECT send_comment('Writing temporary table into new widget table');
INSERT INTO new_widgets
SELECT * FROM t_widgets;
Thanks in advance for any helpful guidance on this. I'm running PostgreSQL 8.4.7.
You should raise notice instead of raise exception. The former will show a message and the latter is treated as an error and will abort your transaction.