Содержание

Предыдущий раздел

Обработка ошибок и исключений в pl/pgsql коде

Следующий раздел

Групповая обработка данных с использованием window-функций first_value/last_value

Тип параметра не соответствует подготовленному плану

Иногда возникает ошибка, подобная этой:

ERROR:  type of parameter 6 (numeric) does not match that when preparing the plan (integer)
CONTEXT:  PL/pgSQL function inline_code_block line 15 at RAISE

и найти причины её возникновения бывает не так просто.

Причина же почти в 100% процентах случаев кроется в динамических запросах и обработке их результатов.

Вот пример кода, при выполнении которого возникает ошибка:

DO $$
DECLARE
  _rec record;
  _i integer;
  _query text;
BEGIN
  FOR _i IN 1..2
  LOOP
    IF _i = 1 THEN
      _query := 'SELECT 1::int AS value';
    ELSE
      _query := 'SELECT 1::numeric AS value';
    END IF;
    EXECUTE _query INTO _rec;
    RAISE LOG '%', _rec.value; -- ошибка возникает во время второго прохода
  END LOOP;
END
$$;

Причина подобных ошибок

Причина кроется в том, как PL/pgSQL интерпретатор выполняет код. При первом обращении в сессии к функции интерпретатор строит дерево инструкций, а при первом выполнении инструкции "кэширует план её выполнения", учитывая тип переменных. При повторном обращении к данной инструкции (выражению) интерпретатор использует уже закэшированный план её выполнения. И если тип переменных по какой-либо причине изменился, то генерируется ошибка. При использовании простых переменных такой ошибки быть не может, так как тип переменной не может быть изменен в рамках выполнения хранимой процедуру. При использовании же изменяемых типов, к которым относится record, такие ошибки вполне вероятны.

Будьте бдительны!

Дополнительные материалы

PostgreSQL Documentation: Plan Caching

comments powered by Disqus