Postgres: определить значение по умолчанию для сбоев CAST? - программирование
Подтвердить что ты не робот

Postgres: определить значение по умолчанию для сбоев CAST?

Можно ли определить значение по умолчанию, которое будет возвращено в случае сбоя операции CAST?

Например, чтобы:

SELECT CAST('foo' AS INTEGER)

Вернет значение по умолчанию вместо того, чтобы выбросить ошибку?

4b9b3361

Ответ 1

Значение CAST отсутствует по умолчанию:

Приведение типа задает преобразование из одного типа данных в другое. PostgreSQL допускает два эквивалентных синтаксиса для типов:

CAST ( expression AS type )
expression::type

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

Однако вы можете сделать это вручную с помощью простой функции:

create or replace function cast_to_int(text, integer) returns integer as $$
begin
    return cast($1 as integer);
exception
    when invalid_text_representation then
        return $2;
end;
$$ language plpgsql immutable;

Затем вы можете сказать такие вещи, как cast_to_int('pancakes', 0) и получить 0.

PostgreSQL также позволяет создавать свои собственные ролики, чтобы вы могли делать такие вещи:

create or replace function cast_to_int(text) returns integer as $$
begin
    -- Note the double casting to avoid infinite recursion.
    return cast($1::varchar as integer);
exception
    when invalid_text_representation then
        return 0;
end;
$$ language plpgsql immutable;

create cast (text as integer) with function cast_to_int(text);

Тогда вы могли бы сказать

select cast('pancakes'::text as integer)

и получите 0, или вы могли бы сказать

select cast(some_text_column as integer) from t

и получите 0 для значений some_text_column, которые не являются допустимыми целыми числами. Если вы хотите использовать varchar, используя этот авто-дефолтный бросок, вам нужно будет сделать двойной бросок:

select cast(some_varchar::text as integer) from t

Просто потому, что вы можете это сделать, это не значит, что это хорошая идея. Я не думаю, что замена стандартного текста на цельный бросок - лучшая идея. Вышеупомянутый подход также требует, чтобы вы оставили стандартный varchar до integer прилив в одиночку, вы могли бы обойти это, если бы вы хотели сделать все преобразование самостоятельно, а не лениво накладывать на встроенное кастинг.

Обработка NULL остается как (легкое) упражнение для читателя.

Ответ 2

Ловушка ошибки, как описано в документации, и затем укажите действие, которое нужно сделать.

Документация по захвату ошибок для PostgreSQL. Ниже приведен фрагмент.

35.7.5. Ошибки ловушки

По умолчанию любая ошибка, возникающая в функции PL/pgSQL, прерывает выполнение функции и, в сущности, и транзакции. Вы можете ловить ошибки и восстанавливать их, используя блок BEGIN с предложением EXCEPTION. Синтаксис - это расширение стандартного синтаксиса для блока BEGIN:

[ <<label>> ]
[ DECLARE
    declarations ]
BEGIN
    statements
EXCEPTION
    WHEN condition [ OR condition ... ] THEN
        handler_statements
    [ WHEN condition [ OR condition ... ] THEN
          handler_statements
      ... ]
END;

Если ошибка не возникает, эта форма блока просто выполняет все инструкции, а затем управление переходит к следующему утверждению после END. Но если в операторах возникает ошибка, дальнейшая обработка операторов отменяется, а управление переходит в список ИСКЛЮЧЕНИЕ. В списке выполняется поиск первого условия, соответствующего ошибке, которая произошла. Если совпадение найдено, выполняются соответствующие handler_statements, а затем управление переходит к следующему утверждению после END. Если совпадение не найдено, ошибка распространяется так, как будто предложение EXCEPTION не было вообще: ошибка может быть захвачена закрывающим блоком с EXCEPTION или если он не прерывает обработку функции.