#perl #dbix-class
#perl #dbix-class
Вопрос:
У меня есть таблица в базе данных SQLite, где в столбце хранится время файла в эпохальных секундах.
Теперь я хотел бы выполнить поиск в этой таблице файлов, которые были изменены в определенном месяце?
В необработанном SQL я бы сделал:
select * from my_table where strftime('%Y-%m', mtime, "unixepoch") = "2009-08"
Есть ли способ сделать это эффективно с помощью DBIx:: Class? Возможно ли сделать
$m->search({ 'strftime('%Y-%m', mtime, "unixepoch")' => "2009-08" })
Я попытался понять, есть ли способ с DBIx:: Class ::InflateColumn::DateTime, но я его не нашел.
Спасибо
Simone
Комментарии:
1. В качестве обходного пути вы могли бы выбрать временные метки
>= Y-m-1 0:00
и< Y-(m 1)-1 00:00
.Time::Local
может использоваться для перевода дат в секунды.
Ответ №1:
Синтаксис, который вы ищете, является:
$m->search(
[ q{strftime('%Y-%m', mtime, "unixepoch") = ?}, "2009-08" ]
);
Да, это ссылкана массив-ref. Первый элемент — это буквальный SQL, которому разрешено использовать ?
заполнители, а остальные элементы — это значения для привязки к этим заполнителям, и DBIC обязательно изменит порядок всего внутри, чтобы эти значения были помещены в нужное место в списке привязки при выполнении запроса.
Если вам нужно объединить один из этих критериев с другими, поскольку arrayrefref не является допустимым хэш-ключом, вам нужно использовать -and
синтаксис:
$m->search({
-and => [
foo => 'bar',
[ q{ SQL }, $bind ],
],
});
Вот раздел SQL::Abstract docs для этой конструкции.
Ответ №2:
Я бы посоветовал вам использовать search_literal
вместо:
# assuming $m isa DBIx::Class::ResultSet
$m->search_literal('strftime("%Y%m", mtime, "unixepoch") = ?', '200908');
РЕДАКТИРОВАТЬ: я поддерживаю исправление. Пожалуйста, обратитесь к комментарию и ответу @hobbs.
Комментарии:
1. Пожалуйста, не делайте этого, это неработающий интерфейс, как говорится в документе, на который вы ссылались, и есть другой способ сделать это, который действительно работает должным образом.