Как выполнять манипуляции с датой / временем в функции PostgreSQL PLPerl

При написании функций Postgres (хранимых процедур) в plperl я узнал, что невозможно загрузить модули 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 ответа

Решение

Там нет простого способа сделать это. У вас есть четыре основных варианта, и выбор зависит от вашей конкретной ситуации.

  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. Оберните ваш plperl SP хранимой процедурой SQL или plpgsql, которая передает требуемые значения даты:

    CREATE FUNCTION foo AS $$
        SELECT foo_pl(EXTRACT(...),EXTRACT(...),...)
    $$ LANGUAGE SQL;
    
  3. Сделайте манипуляции с датами вручную в Perl.

    Это часто некрасиво (и почему модули манипулирования датами существуют в первую очередь!), Но может работать для достаточно простых операций, где високосные годы, часовые пояса и т. Д. Не имеют значения (добавление одного часа или дня к промежутку времени и т. Д.)).

  4. Требуется более сложный модуль Perl, такой как DateTime.

    Это обычно требует использования plperlu вместо стандартного plperl, что может привести к некоторым проблемам безопасности. Это также вряд ли повысит производительность при загрузке таких больших модулей в ваши хранимые процедуры. Но если у вас достаточно системной памяти, и вас устраивает вопрос безопасности plperlu (не рассматривается в этом посте), это может быть вариантом.

Практически любая инфраструктура баз данных Postgres автоматически преобразует типы данных Date и DateTime. А при вставке этих типов в Postgres, если они не конвертируются автоматически, Postgres всегда может понять формат UTC.

ОБНОВИТЬ

Что касается последующих комментариев, я могу сослаться только на список хорошо документированных функций даты / времени, поскольку в вопросе нет конкретного указания относительно типа необходимых операций: функции даты и времени Postgres и операторы

Другие вопросы по тегам