CakePHP3:CASE语句结果被强制转为字符串,需转为整数
解决CASE语句结果被转为字符串的问题
你已经用QueryBuilder生成了正确的CASE表达式,但关闭hydration后返回的结果被转成了字符串——这是参数化查询里很常见的小问题,我给你几个可行的解决办法:
方法1:在SQL层面强制转换为整数
直接用CAST函数把整个CASE表达式的结果转为整数类型,这样数据库返回的就是数值类型,后续转数组时就不会变成字符串了:
// 先创建CASE表达式 $caseExpr = $q->newExpr()->addCase( [$q->newExpr()->add(["description IS" => NULL])], [0, 1], ["integer", "integer"] ); // 用CAST包裹CASE表达式,指定为SIGNED整数 $desc_case = $q->func()->cast($caseExpr, 'SIGNED'); // 加入查询 $q = $q->select(["has_desc" => $desc_case]);
生成的SQL会变成:
SELECT [为清晰起见移除部分字段], CAST(CASE WHEN (description) IS NULL THEN :c0 ELSE :c1 END AS SIGNED) AS
has_descFROM skills Skills
方法2:手动指定参数绑定类型
有时候问题出在参数绑定的默认类型上,QueryBuilder可能默认把0和1当作字符串绑定。你可以手动指定参数为整数类型:
$desc_case = $q->newExpr()->addCase( [$q->newExpr()->add(["description IS" => NULL])], [ // 明确指定参数为整数类型 $q->createNamedParameter(0, \PDO::PARAM_INT), $q->createNamedParameter(1, \PDO::PARAM_INT) ], ["integer","integer"] ); $q = $q->select(["has_desc" => $desc_case]);
这样PDO会正确识别参数类型,返回的结果也会是整数。
方法3:在PHP结果集中转换类型
如果不想修改查询语句,也可以在获取数组结果后,遍历转换字段类型:
// 获取结果数组 $result = $q->hydrate(false)->toArr(); // 遍历转换has_desc为整数 foreach ($result as &$row) { $row['has_desc'] = (int)$row['has_desc']; } unset($row); // 释放引用,避免后续意外修改
这个方法简单直接,适合结果集不大的场景。
为什么会出现这个问题?
当使用参数化查询时,如果没有明确指定参数的整数类型,PDO可能会将数值型的参数结果以字符串形式返回。关闭hydration后,框架不会自动帮你做类型映射,所以就需要我们手动处理啦。
内容的提问来源于stack exchange,提问作者Roger Kaplan
相关产品推荐
相关产品推荐

