我有一個 plpgsql 程序,我只是在嘗試處理任何可能的例外,因為我將在 pg_cron(自動化)上運行這些程序,并且我不希望任何失敗。該程序的基本框架如下所示:
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$
;
問題是 RAISE NOTICE with text_var1,它應該保存 SQL 例外訊息,永遠不會被記錄UPDATE,我的job_log表中的陳述句也應該保存該訊息。
我還想補充一點,我不得不EXCEPTION用另一個begin和包圍塊end,因為如果我不這樣做,我會得到一個語法錯誤。
我只是想從我的 SQL 腳本中捕獲例外 - 我應該使用不同的 EXCEPTION 型別嗎?我應該尋找特定的 SQL 代碼嗎?我有點困惑這里的最佳實踐是什么
uj5u.com熱心網友回復:
你真的應該開始縮進你的代碼。這不僅僅是為了美觀,而且會立即向您展示代碼的問題。
正確縮進的代碼如下所示:
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;
有兩點很明顯:
你忘記了
RETURN→ 語法錯誤前面的分號該
EXCEPTION子句是BEGIN前一行中以 the 開頭的塊的一部分。由于
EXCEPTION子句只會捕獲在它所屬的塊中拋出的例外,并且該塊是空的,因此執行永遠無法到達例外處理程式。
您顯然正在與COMMIT無法在帶有EXCEPTION子句的塊內執行的限制作斗爭。但由于不清楚你想做什么(例如,無條件RAISE EXCEPTION似乎毫無意義),很難幫助你。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/324108.html
標籤:PostgreSQL 例外 存储过程 plpgsql
下一篇:C中多層實作的錯誤處理
