[英]Postgres return null values on function error/failure when casting
I am attempting to convert text
values to timestamp
values. 我试图将
text
值转换为timestamp
值。 For the following table called a
: 对于下面的表中调用
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
I am attempting to perform a select
with a cast as follows: 我试图执行一个
select
如下与铸造 :
select id, c1,
c1::timestamp
as c2 from a;
as c2 from a;
select id, c1,
c1::timestamp
as c2 from a;
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: 如果只有前5行,这可以正常工作,但对于第6行,其中
c1
是24-04-89 2:33 am
它会抛出以下错误:
ERROR: date/time field value out of range: "24-04-89 2:33 am"
错误:日期/时间字段值超出范围:“24-04-89 2:33 am”
HINT: Perhaps you need a different "datestyle" setting.提示:也许你需要一个不同的“日期风格”设置。
What I want is null
for those values which cannot not be casted to timestamp instead of the command failing altogether. 对于那些无法将时间戳转换为时间戳的值而不是完全失败的命令,我想要的是
null
。 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)
EDIT: 编辑:
Also, is there a generic way to implement this? 另外,有没有通用的方法来实现这个? ie: (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. 即:(基于klin的答案 )一个plpgsql包装器函数,如果它所包含的函数抛出错误,则将该值设置为
null
。 For eg: a function set_null_on_error
that can be used like this: 例如:一个函数
set_null_on_error
,可以像这样使用:
select id, c1,
set_null_on_error(c1::timestamp)
as c2 from a;
as c2 from a;
select id, c1,
set_null_on_error(c1::timestamp)
as c2 from a;
or 要么
select id, c1,
set_null_on_error(to_number(c1, '99'))
as c2 from a;
select id, c1,
set_null_on_error(to_number(c1, '99'))
as c2 from a;
This can be done by trapping an exception in a plpgsql function. 这可以通过在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;
Trying to define a generic function. 试图定义一个通用函数。
Assume that you defined a function set_null_on_error(anyelement)
. 假设您定义了一个函数
set_null_on_error(anyelement)
。 Calling 调用
select set_null_on_error('foo'::timestamp);
raises error before the function is executed. 在执行函数之前引发错误。
You can try something like this: 你可以尝试这样的事情:
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. 在我看来,这样的解决方案太复杂,使用起来非常不方便,并且通常可能会产生难以调试的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.