忽略产生错误的结果

tom*_*ahh 3 sql postgresql

我正在尝试提出以下请求

SELECT login, time FROM table 
  WHERE time::timestamp <= (CURRENT_TIMESTAMP - interval '5' month);
Run Code Online (Sandbox Code Playgroud)

其中时间是包含时间戳的文本字段。

有没有办法我可以忽略当时间格式不正确时生成强制转换错误的行?

我尝试过以下方法

SELECT login, time FROM table 
  WHERE (((CURRENT_TIMESTAMP - interval '6' month)::text || time)::timestamp
    <= (CURRENT_TIMESTAMP - interval '5' month);
Run Code Online (Sandbox Code Playgroud)

但首先,这并不美观,其次,它会导致错误ERROR: time zone displacement out of range,我不明白。

Pav*_*ule 5

您可以在 plpgsql 中编写自己的转换函数并进行错误处理。

创建或替换函数 to_timestamp_ignore_errors(text)
返回时间戳 AS $$
开始
  返回 $1::时间戳;
其他人则例外
  返回空值;
结尾;
$$ 语言 plpgsql IMMUTABLE STRICT;

postgres=# 选择 to_timestamp_ignore_errors('bbbb');
 to_timestamp_ignore_errors
----------------------------

(1 行)

postgres=# 选择 to_timestamp_ignore_errors('2013-08-16');
 to_timestamp_ignore_errors
----------------------------
 2013-08-16 00:00:00
(1 行)

其他可能性是在投射之前进行格式检查 - 一些初始版本

创建或替换函数 to_timestamp_ignore_errors(text)
返回时间戳 AS $$
--常规应该更丰富
SELECT CASE WHEN $1 ~ '^\d{4}-\d{2}-\d{2}$' THEN $1::timestamp ELSE NULL END;
$$ 语言 SQL;       
创建函数
postgres=# 选择 to_timestamp_ignore_errors('2013-08-16');
 to_timestamp_ignore_errors
----------------------------
 2013-08-16 00:00:00
(1 行)

postgres=# 选择 to_timestamp_ignore_errors('bbbb');
 to_timestamp_ignore_errors
----------------------------

(1 行)

在 9.2 上测试

当错误最少时,基于正则表达式的版本应该快一点(30%),当错误很多时,速度确实更快,所以这个解决方案更可取。因此,更好的解决方案是清理数据并使用良好的类型。