【问题标题】:PostgreSQL before insert trigger for blocking 0000-00-00 00:00:00PostgreSQL 在插入触发器之前阻塞 0000-00-00 00:00:00
【发布时间】:2018-01-21 07:36:38
【问题描述】:

我在我的 PostgreSQL 环境中创建了以下触发器来阻止 0000-00-00 00:00:00 在我的 timestamp 数据类型字段中的插入,因为它是不支持。

create function my_trigger_func() returns trigger as $$
begin
    if NEW.t_date = '0000-00-00 00:00:00' then
        NEW.t_date := '0001-01-01 00:00:00';
    end if;
    return new;
end
$$ language plpgsql;

CREATE TRIGGER my_trigger
BEFORE INSERT ON timezone.test
FOR EACH ROW
EXECUTE PROCEDURE my_trigger_func()

以上触发器函数创建成功。但在那之后,当我执行以下插入命令时:

Insert into timezone.test (t_id,t_date) values ('3','0001-01-01 01:10:01');

我收到以下错误:

ERROR:  date/time field value out of range: "0000-00-00 00:00:00"
LINE 1: SELECT NEW.t_date = '0000-00-00 00:00:00'
                            ^
QUERY:  SELECT NEW.t_date = '0000-00-00 00:00:00'
CONTEXT:  PL/pgSQL function my_trigger_func() line 3 at IF
********** Error **********

ERROR: date/time field value out of range: "0000-00-00 00:00:00"
SQL state: 22008
Context: PL/pgSQL function my_trigger_func() line 3 at IF

请让我知道我哪里出错了。

【问题讨论】:

    标签: postgresql triggers insert timestamp


    【解决方案1】:

    请让我知道我哪里出错了。

    简单,你试试比较:

    IF NEW.t_date          = '0000-00-00 00:00:00' THEN
       (type timestamp)      literal -> conversion to Timestamp 
    

    '0000-00-00 00:00:00' -> 时间戳无效

    由于这个触发器,您甚至无法插入正确的值。我建议在应用程序中更正它并插入正确的值。

    【讨论】:

    • 这似乎表明您首先不需要触发器(数据库无论如何都会拒绝无效数据)。您可能想要的是一个自定义函数,它可以从 varchar 转换为 date 并以您描述的方式修复无效输入(或者只是让应用程序代码处理它)。
    • @lad2025:感谢您的评论。但是没有办法修改上述触发器以忽略这些值,而是用正确的值替换它们。
    • @Thilo 你能否让我指导我更多关于如何在插入发生之前创建这个自定义函数。我这么说的原因是,我的表有很多列,并且由于这个不受支持的时间戳,在其他所需的列中没有填充任何内容。因此,我想在数据库级别创建一个触发器来更正这些值,这样整个插入就不会失败。希望你能理解
    猜你喜欢
    • 1970-01-01
    • 2013-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多