sql - Postgres 在转换时在函数错误/失败时返回空值

标签 sql postgresql casting plpgsql

我正在尝试将 text 值转换为 timestamp 值。 对于名为 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,如下所示:

选择 id, c1,c1::timestampas c2 from a;

如果只有前 5 行,这会正常工作,但对于 c124-04-89 2:33 am 的第 6 行,它会抛出以下内容错误:

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

我想要的是 null 那些不能强制转换的值 到时间戳而不是命令完全失败。像这样:

 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's answer)一个 plpgsql 包装器函数,如果它所包装的函数抛出错误,则将值设置为 null。 例如:函数 set_null_on_error 可以像这样使用:

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

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

最佳答案

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

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;

尝试定义一个通用函数。

假设您定义了一个函数set_null_on_error(anyelement)。呼唤

select set_null_on_error('foo'::timestamp);

在函数执行之前引发错误。

你可以尝试这样的事情:

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']);

在我看来,这样的解决方案过于复杂,使用起来很不方便,而且通常会产生难以调试的问题。

关于sql - Postgres 在转换时在函数错误/失败时返回空值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30800140/

相关文章:

mysql - SQL Group By 对每个日期求和并使用最大日期

sql - 如何为表的行的子集创建外键约束?

python - Django + PostgreSQL + DjangoRestFramework

sql - 在不计数的情况下获取没有行的表

java - 将内部类转换为父类(super class)

c# - 如何在 C# 中从数据读取器中转换为空 boolean 值?

sql - 列名包含下划线时的语法错误

postgresql - 如何使用 uid :gid set correctly 在 openshift 中挂载 secret

c++ - C++ 中的 cast 属性

mysql - 错误 - "Result consisted of more than one row",由于 GROUP BY