2015-02-09 66 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