Как выполнять манипуляции с датой / временем в функции 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 ответа
Там нет простого способа сделать это. У вас есть четыре основных варианта, и выбор зависит от вашей конкретной ситуации.
Используйте 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};
Оберните ваш plperl SP хранимой процедурой SQL или plpgsql, которая передает требуемые значения даты:
CREATE FUNCTION foo AS $$ SELECT foo_pl(EXTRACT(...),EXTRACT(...),...) $$ LANGUAGE SQL;
Сделайте манипуляции с датами вручную в Perl.
Это часто некрасиво (и почему модули манипулирования датами существуют в первую очередь!), Но может работать для достаточно простых операций, где високосные годы, часовые пояса и т. Д. Не имеют значения (добавление одного часа или дня к промежутку времени и т. Д.)).
Требуется более сложный модуль Perl, такой как DateTime.
Это обычно требует использования plperlu вместо стандартного plperl, что может привести к некоторым проблемам безопасности. Это также вряд ли повысит производительность при загрузке таких больших модулей в ваши хранимые процедуры. Но если у вас достаточно системной памяти, и вас устраивает вопрос безопасности plperlu (не рассматривается в этом посте), это может быть вариантом.
Практически любая инфраструктура баз данных Postgres автоматически преобразует типы данных Date и DateTime. А при вставке этих типов в Postgres, если они не конвертируются автоматически, Postgres всегда может понять формат UTC.
ОБНОВИТЬ
Что касается последующих комментариев, я могу сослаться только на список хорошо документированных функций даты / времени, поскольку в вопросе нет конкретного указания относительно типа необходимых операций: функции даты и времени Postgres и операторы