如何在PostgreSQL PLPerl函数中进行日期/时间操作

时间:2015-08-06 23:21:20

标签: perl postgresql datetime plperl

在plperl中编写Postgres函数(存储过程)时,我了解到无法加载perl模块,例如“use Time :: Piece;”。鉴于此,在plperl中处理日期/时间操作和比较的最佳方法是什么?使用plperlu和加载模块对我来说不是一个选择。

我不得不诉诸以下问题:

$query = "SELECT extract(day from timestamp '$eventDate') AS day,
                 extract(month from timestamp '$eventDate') AS month,
                 extract(year from timestamp '$eventDate') AS year";

我还使用SQL将时间戳转换为纪元时间,以便在perl中进行比较。我希望这是一个愚蠢的问题,并且有更直接和简单的方法来处理日期/时间功能。 感谢。

2 个答案:

答案 0 :(得分:0)

几乎任何Postgres数据库框架都会自动为您转换Date和DateTime数据类型。当将这些类型插入Postgres时,如果它们没有自动转换,那么UTC格式就是Postgres总能理解的格式。

<强>更新

根据随后的评论,我只能参考记录良好的日期/时间函数列表,因为问题中没有具体的操作类型:Postgres Date/Time Functions and Operators

答案 1 :(得分:0)

这不是一个简单的方法。您有四个基本选项,使用哪个选项取决于您的具体情况。

  1. 在存储过程中使用SQL。

    这通常比我喜欢的更冗长,但它可能是最简单,最有效的。例子:

    my $now = spi_exec_query('SELECT EXTRACT(epoch FROM NOW())')->{rows}[0]->{date_part}
        || die "Unable to determine current time";
    

    或一次获得多个值:

    my $row = spi_exec_query('SELECT EXTRACT(...) AS a,EXTRACT(...) AS b,... AS x')->{rows}
        or die "Some useful message...";
    my $a = $row->{a};
    my $b = $row->{b};
    ...
    my $x = $row->{x};
    
  2. 使用SQL或plpgsql存储过程包装plperl SP,该过程传入所需的日期值:

    CREATE FUNCTION foo AS $$
        SELECT foo_pl(EXTRACT(...),EXTRACT(...),...)
    $$ LANGUAGE SQL;
    
  3. 在perl中手动执行日期操作。

    这通常是丑陋的(为什么日期操作模块首先存在!)但可能适用于足够简单的操作,其中闰年,时区等是无关紧要的(在一个时间内添加一小时或一天)跨度等。)

  4. 需要更复杂的perl模块,例如DateTime

    这通常需要使用plperlu而不是标准plperl,这可能带来一些安全问题。将大型模块加载到存储过程中也不太可能有利于提高性能。但是如果你有足够的系统内存,而且你对plperlu的安全问题感到满意(本文未涉及),那么它可以是一个选项。