TRY / CATCH в PostgreSQL

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Во встроенном процедурном языке PL/pgSQL для СУБД PostgreSQL отсутствуют привычные операторы TRY / CATCH для для перехвата исключений возникающих в коде во время выполнения. Аналогом является оператор EXCEPTION, который используется в конструкции:

BEGIN
  -- код, в котором может возникнуть исключение
EXCEPTION WHEN OTHERS -- аналог catch  
THEN
    -- код, обрабатывающий исключение
END

Если необходимо обработать только конкретную ошибку, то в условии WHEN нужно указать идентификатор или код конкретной ошибки:

BEGIN
  -- код, в котором может возникнуть исключение
EXCEPTION WHEN '<идентификатор_или_код_ошибки>'
THEN
    -- код, обрабатывающий исключение
END

Внутри секции EXCEPTION код ошибки можно получить из переменной SQLSTATE, а текст ошибки из переменной SQLERRM:

BEGIN
  -- код, в котором может возникнуть исключение
EXCEPTION WHEN OTHERS  
THEN
    RAISE NOTICE 'ERROR CODE: %. MESSAGE TEXT: %', SQLSTATE, SQLERRM;
END

Более подробную информацию по исключению можно получить командой GET STACKED DIAGNOSTICS:

BEGIN
  -- код, в котором может возникнуть исключение
EXCEPTION WHEN OTHERS  
THEN
		GET STACKED DIAGNOSTICS
    	err_code = RETURNED_SQLSTATE, -- код ошибки
		msg_text = MESSAGE_TEXT, -- текст ошибки
    	exc_context = PG_CONTEXT, -- контекст исключения
 		msg_detail = PG_EXCEPTION_DETAIL, -- подробный текст ошибки
 		exc_hint = PG_EXCEPTION_HINT; -- текст подсказки к исключению

    RAISE NOTICE 'ERROR CODE: % MESSAGE TEXT: % CONTEXT: % DETAIL: % HINT: %', 
   	err_code, msg_text, exc_context, msg_detail, exc_hint;
END

Полный список переменных, которые можно получить командой GET STACKED DIAGNOSTICS:

Имя

Тип

Описание

RETURNED_SQLSTATE

text

код исключения

COLUMN_NAME

text

имя столбца, относящегося к исключению

CONSTRAINT_NAME

text

имя ограничения целостности, относящегося к исключению

PG_DATATYPE_NAME

text

имя типа данных, относящегося к исключению

MESSAGE_TEXT

text

текст основного сообщения исключения

TABLE_NAME

text

имя таблицы, относящейся к исключению

SCHEMA_NAME

text

имя схемы, относящейся к исключению

PG_EXCEPTION_DETAIL

text

текст детального сообщения исключения (если есть)

PG_EXCEPTION_HINT

text

текст подсказки к исключению (если есть)

PG_EXCEPTION_CONTEXT

text

строки текста, описывающие стек вызовов в момент исключения

Пример обработки исключения

В качестве примера будет рассмотрена обработка ошибки деления на ноль в функции catch_exception:

CREATE OR REPLACE FUNCTION catch_exception
(
	arg_1 int,
	arg_2 int,
	OUT res int
)
LANGUAGE plpgsql
AS $$
DECLARE 
	err_code text;
	msg_text text;
	exc_context text;
BEGIN
	BEGIN
		res := arg_1 / arg_2;
	EXCEPTION 
	WHEN OTHERS 
  THEN
		res := 0;
    
		GET STACKED DIAGNOSTICS
    	err_code = RETURNED_SQLSTATE,
		msg_text = MESSAGE_TEXT,
    	exc_context = PG_CONTEXT;

   		RAISE NOTICE 'ERROR CODE: % MESSAGE TEXT: % CONTEXT: %', 
   		err_code, msg_text, exc_context;
  END;
END;
$$;

Вызов функции catch_exception со значением 0 в качестве второго параметра вызовет ошибку деления на ноль:

DO $$
DECLARE 
	res int;
BEGIN
	SELECT e.res INTO res
	FROM catch_exception(4, 0) AS e;
	
	RAISE NOTICE 'Result: %', res;
END;
$$;

Результаты обработки ошибки будут выведены на консоль:

ERROR CODE: 22012 
MESSAGE TEXT: деление на ноль 
CONTEXT: функция PL/pgSQL catch_exception(integer,integer), строка 14, оператор 
GET STACKED DIAGNOSTICS
SQL-оператор: "SELECT e.res FROM catch_exception(4, 0) AS e"
функция PL/pgSQL inline_code_block, строка 5, оператор SQL-оператор
Result: 0
Источник: https://habr.com/ru/post/657667/


Интересные статьи

Интересные статьи

Решения для больших компаний обычно должны выдерживать высокие нагрузки. Когда в штате много десятков тысяч человек, и значительная доля из них ежедневно пользуются ...
В наших предыдущих статьях о гибридных облаках (Hybrid Cloud) мы часто говорили, что один из основных вариантов их использования — это аварийное восстановление. Любые нео...
Пролог Под перечислимым типом обычно понимают тип данных, который может принимать ограниченное и, как правило, небольшое число значений. Его выделяет то, что эти значения часто хардкод...
Недавно мы пригласили в эфир "Цинкового прода" Алексея Лесовского из компании Data Egret. Разговор получился интересный и познавательный, поэтому предлагаю вашему вниманию расшифровку э...
В современных ЦП очень много ядер. Годами приложения посылали запросы в базы данных параллельно. Если это отчетный запрос ко множеству строк в таблице, он выполняется быстрее, когда задействует...