2015-02-09 81 views
4

由于其他(旧)的问题没有得到适当的答案,我会再次尝试:结合IS NULL和:在学说2 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,实际情况是,在这种情况下结果确实令人讨厌。

另外,在旧的问题中给出的示例在DQL中不起作用,因为NULL!= NULL。

->setParameter('parent', (is_null($parent) ? "NULL" : $parent)); 

我也试过这种方式,什么好心的人提供的,但是这会给出一个NonUniqueResult例外,因为当父母为1为例,它会给双重结果。

SELECT e 
FROM Entity e 
WHERE (e.parent = :parent OR e.parent IS NULL) 

有没有执行此查询一个更清洁的方式,当参数可以为空?

回答

5

如果你不知道关于你的参数值,那么你可以重写你的where子句作为

SELECT e 
FROM Entity e 
WHERE (e.parent = :parent OR e.parent IS NULL) 

如果您对您的查询的其他过滤器,那么要确保使用()在你OR标准像

SELECT e 
FROM Entity e 
WHERE (e.parent = :parent OR e.parent IS NULL) 
AND e.some = :some... 
+0

其实我想这也是一个,因为它是有道理的。 Unfornately它给了我一个NonUniqueResult异常,因为当我的参数不为null时它会给我2个结果。或者我错过了什么? – Matheno 2015-02-09 09:13:37

0

如果你的场景真的很简单,你只想得到实体(而且不关心查询),那么你可以使用仓库函数代替DQL:

$entities = $em->getRepository('Entity')->findBy(array('parent' => $parent)); 

,可以自动地特殊情况下,SQL条件为“parent IS NULL”如果$parentnull(其他的基本条件“parent = ?” +参数)。

否则,:parent添加一个条件,以避免在您的组合查询的NonUniqueResult例外:

SELECT e 
FROM Entity e 
WHERE (e.parent = :parent OR (e.parent IS NULL AND :parent IS NULL)) 

,甚至(从你的 “黑客” 直接翻译):

WHERE ((:parent IS NULL AND e.parent IS NULL) OR (:parent IS NOT NULL AND e.parent = :parent)) 

备注关于“NULL!= SQL/DQL中的NULL”:

严格来说,“NULL = NULL”和“NULL!= NULL”都不为真或不为:都返回NULL。
现在,NULL不是 “truthy”,所以两个询问
SELECT e FROM Entity e WHERE e.parent = NULL” 和
SELECT e FROM Entity e WHERE e.parent != NULL
永远不会返回任何行(不管是什么数据),
但NULL不“falsy “(这是第三种,说”未定义“),否定它不会改变:”NOT(NULL)“仍然是NULL(而不是TRUE),所以
SELECT e FROM Entity e WHERE NOT (e.parent = NULL)“和
SELECT e FROM Entity e WHERE NOT (e.parent != NULL)
也不会返回任何行!
因此,有必要使用的运算符“x IS NULL”和“x IS NOT NULL”(或“NOT (x IS NULL)‘)或COALESCE(),或供应商特定的功能,如ISNULL()IFNULL()NVL()
(注:可以存在的情况下’ undefinedness “被自动解决了,例如,在条件
(表达式生成NULL) OR (表达式,其值TRUE)“ 或
(表达式生成NULL) AND (表达式,其值为假)
因为” 什么或真”永远是真实的‘什么和FALSE’始终是FALSE)。

+0

感谢您的回答。这个问题相当“古老”,但也许它会帮助其他人一次。 – Matheno 2017-01-17 15:37:01