有没有一种简单的方法可以在Doctrine 2 DQL中组合IS NULL和=:value?

时间:2013-01-02 13:27:06

标签: doctrine-orm dql

我经常遇到一个场景,我想查询具有特定值的实体:

$query = $em->createQuery('SELECT e FROM Entity e WHERE e.parent = :parent');
$query->setParameter('parent', $parent);

通常,此值可以为NULL,但WHERE e.parent = NULL不会产生任何结果,因此强迫我这样做:

if ($parent === null) {
    $query = $em->createQuery('SELECT e FROM Entity e WHERE e.parent = IS NULL');
}
else {
    $query = $em->createQuery('SELECT e FROM Entity e WHERE e.parent = :parent');
    $query->setParameter('parent', $parent);      
}

虽然我理解SQL / DQL中NULL != NULL背后的基本原理,但事实是,在这种情况下结果真的很烦人。

当参数可以为null时,是否有更简洁的方法来执行此查询?

3 个答案:

答案 0 :(得分:1)

目前不可能。 (只为我自己试过几种方法)。

带有bindValue()

null仅适用于INSERT / UPDATE值绑定。

我认为限制在PDO或SQL语法本身而不是Doctrine。

您可以使用QueryBuilder,因此您只需要“复制”WHERE部分,而不是整个查询:http://doctrine-dbal.readthedocs.org/en/latest/reference/query-builder.html#where-clause

编辑:可以在原生SQL中使用: https://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#operator_equal-to

可悲的是,学说没有那个算子:http://doctrine1-formerly-known-as-doctrine.readthedocs.org/en/latest/en/manual/dql-doctrine-query-language.html#operators-and-operator-precedence

答案 1 :(得分:0)

您可以使用查询构建器:

$em = \Zend_Registry::get('em');

$qb_1 = $em->createQueryBuilder();

$q_1 = $qb_1->select('usr')
->from( '\Entities\user', 'usr' )
->where( 'usr.deleted_at IS NULL' )
->orWhere( 'usr.status='.self::USER_STATUS_ACTIVE )
->andWhere('usr.account_closed_on is null');

$q_1->getQuery()->getResult();

答案 2 :(得分:0)

只是试图解决同样的问题,我实际上找到了PostgreSQL的解决方案。

$sql = 'SELECT * FROM company WHERE COALESCE(:company_id, NULL) ISNULL OR id = :company_id;'
$connection->executeQuery($sql, ['company_id' => $id]);

如果$id已通过,则根据给定的null返回特定公司或全部公司。问题似乎是解析器不知道你实际上要对参数做什么,所以通过将它传递给COALESCE函数,它知道它将它传递给函数,所以问题就解决了。 / p>

所以,如果它开始在"纯" SQL解决方案,在DQL中使用它应该不是问题。我没有尝试过,但Doctrine应该有COALESCE支持,因此DQL应该很容易更新。