Cake PHP复杂查找'OR'与null和空字符串无法正常工作

时间:2012-06-07 12:49:39

标签: cakephp cakephp-1.3

Cake PHP复杂查找'OR'opertor与null无法正常工作...

$conditions = array(
    'Person.id' => array(2, 4, 1, 23, 45, 11),
    'OR' => array(
    array(
        array('NOT' => array('Person.image' => null)),
        array('NOT' => array('Person.image' => '')),
    ),
    array(
        array('NOT' => array('Person.photos' => null)),
        array('NOT' => array('Person.photos' => '')),
    )
    )
);

相应的cake sql dump输出查询如下

SELECT `Person`.`id`, `Person`.`created`, `Person`.`modified` 
FROM `people` AS `Person` WHERE `Person`.`id` IN (2, 4, 1, 23, 45, 11)  AND 
((((NOT (`Person`.`image` IS NULL)) AND (NOT (`Person`.`image` = NULL))))   OR 
(((NOT (`Person`.`photos` IS NULL)) AND (NOT (`Person`.`photos` = ''))))) 
ORDER BY FIELD(`Person`.`id`, 2, 4, 1, 23, 45, 11) ASC LIMIT 3

在蛋糕条件数组中,我给出了Person.image不是null'',但相应的蛋糕sql输出为(NOT (Person.image IS NULL)) AND (NOT (Person.image = NULL)),它应该像(NOT (Person.image IS NULL)) AND (NOT (Person.image = '')) }。

此处 Person.image 两者都与NULL本身( IS NULL = NULL )进行比较,其中 Person。 image = NULL 想要与 Person.image =''之类的空字符串进行比较。

此处'Person.image''INT''Person.photos''VARCHAR'类型,但很难从当前阶段更改类型。

如何纠正?

4 个答案:

答案 0 :(得分:3)

您不必使用关联数组来定义条件。您可以这样定义:

$conditions = array(
    'Person.id' => array(2, 4, 1, 23, 45, 11),
    'OR' => array(
    array(
        array('NOT' => array('Person.image' => null)),
        array('NOT' => array('Person.image = "" ')),
    ),
    array(
        array('NOT' => array('Person.photos' => null)),
        array('NOT' => array('Person.photos = "" ')),
    )
    )
);

答案 1 :(得分:1)

解释'Person.image <>' => null时可能存在问题,因为它不是严格有效的SQL(至少在MySQL中没有)。

来自MySQL manual

  

您不能使用算术比较运算符,例如=,&lt;或&lt;&gt;测试NULL。

您可以尝试使用否定的空比较替换它:

array('NOT' => array('Person.image' => null))

除此之外,你的最后两个OR运算符什么都不做,因为每个运算符只有一个语句。你的阵列是否嵌套了你的装备?如果添加换行符和缩进,则代码将变为

$conditions = array(
    'Person.id' => array(2, 4, 1, 23, 45, 11),
    'OR' => array(
        array(
            'OR' => array(
                'Person.image <>' => null
            ),
            array(
                'Person.image <>' => ''
            )
        ),
        array(
            'OR' => array(
                'Person.photos <>' => ''
            ),
            array(
                'Person.photos <>' => null
            )
        )
    )
);

......看起来很奇怪。

完整的改变是:

$conditions = array(
    'Person.id' => array(2, 4, 1, 23, 45, 11),
    'OR' => array(
        array(
            array('NOT' => array('Person.image' => null)),
            array('NOT' => array('Person.image' => '')),
        ),
        array(
            array('NOT' => array('Person.photos' => null)),
            array('NOT' => array('Person.photos' => '')),
        )
    )
);

答案 2 :(得分:1)

似乎Cake的null比较取决于数据库字段类型。如果你的字段是整数类型,那么Cake会将''重新定义为Null。变量不会被重新定义。

您是否可以转到MySQL并将Person.image类型更改为varchar?

如果是这样,请记得在app / tmp / cache / models中清除缓存,以便Cake注册更改。

更新:手动更改架构类型将强制cake处理已定义的字段类型。因此,查询之前的类似内容将起作用:

$this->Person->_schema['image']['type']='string';

答案 3 :(得分:0)

很抱歉,这些答案在我看来并非100%正确,它们提供了解决方法,但没有解决方案。

问题是数据库列类型:

  

Person.imageINTPerson.photosVARCHAR类型

好吧,''(空字符串)不是整数的有效值。我假设您已在NULL列上允许Person.image值,因此蛋糕能做正确的工作!

询问整数字段是否具有空字符串的值是没有任何意义的,它只能是NULL,0,1,-1,2,-2等。(如果签了)。

这里发生的事情是蛋糕了解您的数据结构(请注意当DESCRIBE标记为&gt; 0时debug个查询),因此它会尝试将您的语句更正为下一个有用的语句 - 测试NULL值。此外,即使您要求MySQL(或强制蛋糕这样做)查询您的数据库,永远也不会因为这种情况而产生任何影响(可能是因为其他因素):

SELECT * FROM table WHERE my_int_column = ''是完全合法的SQL,但总会返回0结果,而SELECT * FROM table WHERE NOT(my_int_column = '')将始终返回所有结果。

结论:如果你的应用程序现在使用=''条件,那么它将在没有条件的情况下完全相同。

最后注意事项:但是,您可以将INSERT空字符串转换为整数列,并且它将由MySQL转换为0,因此您可能需要检查这些。