Postgresql DBIx::Class/SQL::Abstract将SQL函数应用于WHERE子句中的列

Postgresql DBIx::Class/SQL::Abstract将SQL函数应用于WHERE子句中的列,postgresql,perl,dbix-class,Postgresql,Perl,Dbix Class,我只是摆弄了一下用生成的复杂SQL查询(它在后台用于WHERE子句) 我正在使用BETWEEN运算符筛选条目: # SELECT title FROM tracks WHERE begin BETWEEN '2016-07-01' AND '2016-07-02' $searchArgs->{'begin'} = { BETWEEN => ['2016-07-01', '2016-07-02' ] }; 这将跳过2016-07-02的实际开始日期。可能是因为这些开始值超过了2016

我只是摆弄了一下用生成的复杂SQL查询(它在后台用于WHERE子句)

我正在使用BETWEEN运算符筛选条目:

# SELECT title FROM tracks WHERE begin BETWEEN '2016-07-01' AND '2016-07-02'
$searchArgs->{'begin'} = { BETWEEN => ['2016-07-01', '2016-07-02' ] };
这将跳过2016-07-02的实际开始日期。可能是因为这些开始值超过了2016-07-02的午夜(00:00),因此不在中间范围内(参见末尾的示例数据)

在SQL方面,这很容易解决:

SELECT title FROM tracks WHERE DATE(begin) BETWEEN '2016-07-01' AND '2016-07-02'
# Note the DATE()-cast of begin
有没有一种方法可以通过
SQL::Abstract
语法实现这一点?我尝试将列名作为标量引用(
$searchArgs->{\“DATE(begin)”}
)来传递它,但没有成功

仅仅使用
$searchArgs->{'DATE(begin)}
会触发一个SQL错误,因为没有这样的列“DATE(begin)”


问题似乎是像“2016-07-02”这样的日期相当于“2016-07-02T00:00:00”,“2016-07-02T12:00:00”大于此日期。调用
DATE()

我建议您放弃介于
之间的
,使用等效的
=
='2016-07-01'并开始
或者,在
DBIx::Class

$searchArgs->{begin}={
'>=' => '2016-07-01',
'=' => '2016-07-01',

“什么是”但它不起作用“是什么意思?我找不到方法,在列端获取DATE()-函数。当然,但尝试时发生了什么?我收到一个SQL引擎错误,该错误抱怨不存在列名“SCALAR…”。因为哈希中的SCALAR Ref as键不是以特殊方式计算的,就像值一样(标量引用通常以简单的SQL语句结束)。好的,那么你应该将这些信息添加到你的问题中。我下面的答案对你来说是否不足?你的解决方案意味着一些日期数学(2016-07-31+1天=>2016-08-01)。realy查询稍后会动态执行。除此之外,它还可以工作(但不包括BETWEEN)。但这可能不再是DBIx::Class/SQL::Abstract问题了。鉴于上述限制,我必须进一步研究它的外观…@ghandi:好吧,那么就用一些显式SQL来做算术。
“不用担心,只是不再在线。;
日期(…)+1
是一个很好的解决方法。谢谢:)
# Minimal example data
CREATE TABLE test ( title VARCHAR(255), begin timestamp );
INSERT INTO test (title, begin) VALUES ( 'Track 1', '2016-07-01T12:00:00'::timestamp), ( 'Track 2', '2016-07-02 12:00:00'::timestamp );
SELECT title FROM test WHERE begin BETWEEN '2016-07-01' AND '2016-07-02';
SELECT title FROM test WHERE DATE(begin) BETWEEN '2016-07-01' AND '2016-07-02';
$searchArgs->{begin} = {
    '>=' => '2016-07-01',
    '<'  => \[ 'date(?) + 1', '2016-07-02' ],
};