Doctrine - 从db中选择NULL值

时间:2016-09-09 07:35:46

标签: symfony doctrine

我有一节课,让我们说Test.php。此类具有ID,描述,代码和折扣百分比。

此代码返回一个对象:

$test = $this->getDoctrine()->getRepository('\UserBundle\Entity\Test')->findOneBy(array('code' => 12345 ));

相反,此代码不会返回对象:

$test = $this->getDoctrine()->getRepository('\UserBundle\Entity\Test')->findOneBy(array('code' => null ));

默认情况下,代码字段为NULL。

有什么建议吗?谢谢!

3 个答案:

答案 0 :(得分:2)

取自this answer

  

在SQL中,使用逻辑运算符(例如=,!=,<等等)将null值与任何其他值(包括另一个null)进行比较将导致null,这被视为false where子句的目的。原因是null表示" unknown",因此与null进行任何比较的结果也是" unknown"。

要查询null值,您需要使用is null而不是= null,而不是主张快捷方式不能执行的操作。您需要直接使用SQL / DQL或像...这样的查询构建器来执行此操作。

/** QueryBuilder */
$test = $this
    ->getDoctrine()
    ->getRepository('\UserBundle\Entity\Test')
    ->createQueryBuilder('t')
    ->where('t.code is null')
    ->getQuery()
    ->getResult();
/**
 * Alternatively, if trying to find a single record you can use ->getOneOrNullResult();
 * as ->getResult() will throw a NoResultException if no results are found
 */

/** DQL */
$test = $this
    ->getDoctrine()
    ->createQuery('
        SELECT t
        FROM \UserBundle\Entity\Test t
        WHERE t.code is null
    ')
    ->getResult()
    ->getOneOrNullResult();

答案 1 :(得分:2)

虽然qooplmao对于第一部分是正确的"要查询null值,您需要使用is null而不是= null",我不得不说第二部分"教条的捷径不做"事实并非如此(至少对于版本2.5.4,这是问题发布时的最新稳定版本)。

\Doctrine\ORM\EntityRepository::findOneBy()(带参数array('code' => null))最终调用
\Doctrine\ORM\Persisters\Entity\BasicEntityPersister::getSelectConditionStatementSQL()(带有参数'code', null, null),其中 处理空值的特殊情况(此处缩写为必要值,$columns是一个带有单个值的数组元素例如array('t0.code')$valuenull):

        foreach ($columns as $column) {
            $placeholder = '?';

            ...

            if (null === $value) {
                $selectedColumns[] = sprintf('%s IS NULL', $column);
                continue;
            }

            $selectedColumns[] = sprintf('%s = %s', $column, $placeholder);
        }

然后执行具有正确条件的SQL查询,格式为:

SELECT t0.id AS id_1, t0.description AS description_2, t0.code AS code_3, ...
FROM Test t0
WHERE t0.code IS NULL
LIMIT 1

(它甚至在数组值中处理null,例如使用参数array('code' => array(12345, null, 42)),它将生成表单的SQL条件

WHERE (t0.code IN (12345, NULL, 42) OR t0.code IS NULL)

(实际上它可以从NULL删除IN,但结果是相同的)。)

编辑:自版本2.5.0以来,简单和数组值都是如此(感谢commit 733102b4a109c0bb8ca026b1dbbadaa9bb62ae70),甚至自版本2.1.0以来简单(非数组)值(就像你的情况一样)(感谢提交a3290075260cdafdd17952ca14daa305fabccfe2)。

因此,findOneBy(array('code' => null ))没有返回对象的事实只能意味着您的表格没有列code设置为NULL的任何行,你的答案评论中你和qooplmao的讨论似乎证实了这一点,所以如果现在重新使用你的新数据,它应该返回一个与QueryBuilder或DQL相同的对象。

答案 2 :(得分:0)

您可以在 TestRepository

中使用原则表达式
$db = $this->createQueryBuilder('t');

return $db->select('t')
    ->where($db->expr()->isNull('t.field1'))
    ->orWhere($db->expr()->isNull('t.field2'))
    ->orWhere($db->expr()->isNull('t.field3'))
    ->getQuery()
    ->getResult();