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'
类型,但很难从当前阶段更改类型。
如何纠正?
答案 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.image
为INT
,Person.photos
为VARCHAR
类型
好吧,''
(空字符串)不是整数的有效值。我假设您已在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
,因此您可能需要检查这些。