CakePHP使用updateAll更新单条数据库记录出现SQL语法错误如何解决
错误原因
从最终生成的SQL语句可以直接定位问题:日期类型值2021-08-16 15:10:55、字符串类型值tarjeta都没有被单引号包裹,不符合SQL语法要求,因此触发1064语法错误。
这是CakePHP updateAll方法的固有特性导致的:updateAll的第一个参数(更新字段数组)中的值会被直接当作SQL片段处理,框架不会自动为字符串、日期类型的值添加引号、也不会自动转义,只有第二个参数(条件数组)中的值才会被框架自动处理转义和加引号。
解决方案
有两种常用的修复方式:
方式1:手动给字符串/日期值加单引号
对需要当作字面量处理的字符串、日期值,手动包裹单引号即可,注意PHP层面的转义:
$this->Factura->updateAll( array( 'Factura.I_COBRADO' => $factura['Factura']['I_TOTAL'], 'Factura.L_COBRADA' => 1, 'Factura.FH_COBRO' => "'" . date('Y-m-d H:i:s') . "'", 'Factura.S_FORMAPAGO' => "'tarjeta'", 'Factura.FK_FORMAPAGOCOBRO' => 41 ), array( 'Factura.PK_FACTURA' => $factura['Factura']['PK_FACTURA'] ) );
方式2:使用数据源的value方法自动处理(更安全)
如果值是动态传入的,为了避免SQL注入风险,推荐用数据库数据源的value()方法自动处理转义和加引号:
$db = $this->Factura->getDataSource(); $this->Factura->updateAll( array( 'Factura.I_COBRADO' => $factura['Factura']['I_TOTAL'], 'Factura.L_COBRADA' => 1, 'Factura.FH_COBRO' => $db->value(date('Y-m-d H:i:s'), 'datetime'), 'Factura.S_FORMAPAGO' => $db->value('tarjeta', 'string'), 'Factura.FK_FORMAPAGOCOBRO' => 41 ), array( 'Factura.PK_FACTURA' => $factura['Factura']['PK_FACTURA'] ) );
额外优化建议
如果你只是更新单条主键已知的记录,完全不需要用updateAll,直接用save()方法更简单,框架会自动处理所有字段的类型匹配、转义加引号:
$this->Factura->id = $factura['Factura']['PK_FACTURA']; $this->Factura->save(array( 'I_COBRADO' => $factura['Factura']['I_TOTAL'], 'L_COBRADA' => 1, 'FH_COBRO' => date('Y-m-d H:i:s'), 'S_FORMAPAGO' => 'tarjeta', 'FK_FORMAPAGOCOBRO' => 41 ));
内容的提问来源于stack exchange,提问作者Fran Martín
相关产品推荐
相关产品推荐

