转换时Postgres在函数错误/失败时返回空值 [英] Postgres return null values on function error/failure when casting

查看:452
本文介绍了转换时Postgres在函数错误/失败时返回空值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将text值转换为timestamp值. 对于名为 a 的下表:

I am attempting to convert text values to timestamp values. For the following table called a:

 id |         c1
----+--------------------
  1 | 03-03-2000
  2 | 01-01-2000
  3 | 12/4/1990
  4 | 12 Sept 2011
  5 | 12-1-1999 12:33:12
  6 | 24-04-89 2:33 am

我正尝试通过 cast 执行select,如下所示:

I am attempting to perform a select with a cast as follows:

select id, c1, c1::timestamp as c2 from a;

如果只有前5行,这是正确的,但是对于c124-04-89 2:33 am的第6行,它将引发以下错误:

This works correctly if there were only the first 5 rows, but for the 6th row where c1 is 24-04-89 2:33 am it throws the following error:

错误:日期/时间字段值超出范围:"24-04-89 2:33 am"
提示:也许您需要一个不同的日期样式"设置.

ERROR: date/time field value out of range: "24-04-89 2:33 am"
HINT: Perhaps you need a different "datestyle" setting.

我想要的是 null,用于那些无法转换为时间戳的值,而不是命令完全失败.像这样:

What I want is null for those values which cannot not be casted to timestamp instead of the command failing altogether. Like this:

 id |         c1         |         c2
----+--------------------+---------------------
  1 | 03-03-2000         | 2000-03-03 00:00:00
  2 | 01-01-2000         | 2000-01-01 00:00:00
  3 | 12/4/1990          | 1990-12-04 00:00:00
  4 | 12 Sept 2011       | 2011-09-12 00:00:00
  5 | 12-1-1999 12:33:12 | 1999-12-01 12:33:12
  6 | 24-04-89 2:33 am   | (null)
(6 rows)



另外,有没有通用的方法来实现这一点?即:(基于 klin的答案)一个plpgsql包装函数,如果包装了该函数,则将其值设置为null周围抛出一个错误. 例如:函数set_null_on_error可以像这样使用:



Also, is there a generic way to implement this? i.e.: (based on klin's answer) a plpgsql wrapper function that sets the value to null if the function it is wrapped around throws an error. For e.g.: a function set_null_on_error that can be used like this:

select id, c1, set_null_on_error(c1::timestamp) as c2 from a;

select id, c1, set_null_on_error(to_number(c1, '99')) as c2 from a;

推荐答案

这可以通过在plpgsql函数中捕获异常来完成.

This can be done by trapping an exception in a plpgsql function.

create or replace function my_to_timestamp(arg text)
returns timestamp language plpgsql
as $$
begin
    begin
        return arg::timestamp;
    exception when others then
        return null;
    end;
end $$;

select id, c1, my_to_timestamp(c1) as c2 from a;


尝试定义泛型函数.


Trying to define a generic function.

假设您定义了一个函数set_null_on_error(anyelement).呼叫

Assume that you defined a function set_null_on_error(anyelement). Calling

select set_null_on_error('foo'::timestamp);

在执行该功能之前引发错误.

raises error before the function is executed.

您可以尝试以下操作:

create or replace function set_null_on_error(kind text, args anyarray)
returns anyelement language plpgsql
as $$
begin
    begin
        if kind = 'timestamp' then
            return args[1]::timestamp;
        elseif kind = 'number' then
            return to_number(args[1], args[2]);
        end if;
    exception when others then 
        return null;
    end;
end; $$;

select set_null_on_error('timestamp', array['2014-01-01']);
select set_null_on_error('number', array['1.22444', '9999D99']);

我认为这样的解决方案太复杂了,使用起来非常不方便,并且通常可能会产生难以调试的问题.

In my opinion such a solution is too complicated, quite inconvenient to use and generally might turn out to generate problems hard to debug.

这篇关于转换时Postgres在函数错误/失败时返回空值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆