在学说2中的日期之间选择条目

man*_*nix 49 php date between query-builder doctrine-orm

我会因为这个我没有得到解决的最小错误而疯狂.我想在两天之间选择条目,下面的例子说明了我所有的失败:

选择1.

$qb->where('e.fecha > ' . $monday->format('Y-m-d'));
$qb->andWhere('e.fecha < ' . $sunday->format('Y-m-d'));
Run Code Online (Sandbox Code Playgroud)

结果(0个条目):

SELECT r0_.id_reservacion AS id_reservacion0, r0_.fecha AS fecha1, r0_.cliente AS cliente2 
FROM reservacion r0_ 
WHERE (r0_.fecha > 2012 - 07 - 16) AND (r0_.fecha < 2012 - 07 - 22)
Run Code Online (Sandbox Code Playgroud)

选择2

$qb->add('where', 'e.fecha between 2012-01-01 and 2012-10-10');
Run Code Online (Sandbox Code Playgroud)

结果(0个条目):

SELECT r0_.id_reservacion AS id_reservacion0, r0_.fecha AS fecha1, r0_.cliente AS cliente2 
FROM reservacion r0_ WHERE r0_.fecha 
BETWEEN 2012 - 01 - 01 AND 2012 - 10 - 10
Run Code Online (Sandbox Code Playgroud)

这是我当前条目的表格:

id      fecha            cliente
1   2012-07-16 00:00:00    2    
2   2012-07-16 13:00:00    4    
3   2012-07-22 23:00:00    4
Run Code Online (Sandbox Code Playgroud)

编辑1

为了评估sql以避免疑惑,我运行了这个查询:

$qb->where('e.fecha > ' . $sunday->format('Y-m-d'));
Run Code Online (Sandbox Code Playgroud)

结果(3个条目):

SELECT r0_.id_reservacion AS id_reservacion0, r0_.fecha AS fecha1, r0_.cliente AS cliente2 
Run Code Online (Sandbox Code Playgroud)

所以,看起来像sql不是问题.FROM reservacion r0_ WHERE r0_.fecha> 2012 - 07

Mac*_*ada 138

你可以做......

$qb->where('e.fecha BETWEEN :monday AND :sunday')
   ->setParameter('monday', $monday->format('Y-m-d'))
   ->setParameter('sunday', $sunday->format('Y-m-d'));
Run Code Online (Sandbox Code Playgroud)

要么…

$qb->where('e.fecha > :monday')
   ->andWhere('e.fecha < :sunday')
   ->setParameter('monday', $monday->format('Y-m-d'))
   ->setParameter('sunday', $sunday->format('Y-m-d'));
Run Code Online (Sandbox Code Playgroud)

  • 这可能会破坏与某些数据库平台的兼容性,例如Microsoft SQL Server,其中没有Date类型,并且所有内容都以"Ymd H:i:s.000"的形式保存.您应该让Doctrine通过将类型定义为``setParameter()``的第三个参数来处理转换,如``setParameter('monday',$ monday,\ Doctrine\DBAL\Types\Type :: DATE)``. (8认同)
  • +1参数,这是唯一真正正确的方法. (7认同)
  • 参数+2.不使用参数是非常危险的,因为Doctrine不能正确地逃避它们 (3认同)

Har*_*air 32

我相信这样做的正确方法是使用查询构建器表达式:

$now = new DateTime();
$thirtyDaysAgo = $now->sub(new \DateInterval("P30D"));
$qb->select('e')
   ->from('Entity','e')
   ->add('where', $qb->expr()->between(
            'e.datefield',
            ':from',
            ':to'
        )
    )
   ->setParameters(array('from' => $thirtyDaysAgo, 'to' => $now));
Run Code Online (Sandbox Code Playgroud)

http://docs.doctrine-project.org/en/latest/reference/query-builder.html#the-expr-class

编辑:这种方法优于其他任何答案的优点是它与数据库软件无关 - 你应该让Doctrine处理日期类型,因为它有一个抽象层来处理这类事情.

如果您执行类似于以"Ymd"形式添加字符串变量的操作,例如,当它转到MySQL以外的数据库平台时会中断.