如何在Yii2的updateAll()方法中正确使用REPLACE函数执行更新操作?
问题原因
Yii2的updateAll方法默认会将数组中的值作为普通字符串参数做转义处理,你传入的REPLACE(my_column1,'removed_','')没有被识别为SQL函数,而是被当作普通字符串拼接进SQL,最终生成的语句是将整个函数字符串赋值给字段,既达不到预期执行函数的效果,也会因为字符串长度超出my_column字段的varchar(50)限制触发截断报错。
解决方案
使用Yii2内置的\yii\db\Expression类包裹原生SQL表达式,告知框架这部分内容为可直接执行的SQL片段,不需要做字符串转义处理。
正确代码
ModelName::updateAll([ 'my_column' => new \yii\db\Expression("REPLACE(my_column1,'removed_','')") ]);
执行上述代码后,生成的SQL就会和你预期的一致:
update my_table set my_column = REPLACE(my_column1,'removed_','');
安全提示
如果替换规则中包含用户传入的可变参数,不要直接拼接字符串到Expression中,需要使用参数绑定的方式避免SQL注入风险,示例如下:
// 示例:要替换的关键词来自用户输入 $searchKeyword = 'removed_'; ModelName::updateAll([ 'my_column' => new \yii\db\Expression("REPLACE(my_column1,:search_key,'')", [ ':search_key' => $searchKeyword ]) ]);
内容的提问来源于stack exchange,提问作者Shamnad
相关产品推荐
相关产品推荐

