如何在Yii2中使用QueryBuilder构建SQL查询?解决参数绑定报错
Yii2中使用QueryBuilder构建SQL查询的正确方式
原代码的问题
- 参数绑定错误:
author_id ::text LIKE '%:term%'里的占位符:term被包裹在%中,Yii无法识别这是参数,会直接把:term当成字符串的一部分,导致参数绑定失效。 - 别名的获取问题:虽然
author_id AS label语法没问题,但如果直接用->all()返回ActiveRecord实例,模型中没有label属性的话,无法直接获取这个字段值,需要用asArray()返回数组才能拿到别名字段。
修复后的原生SQL写法
如果坚持用原生SQL,调整参数绑定方式即可:
$author_id = 25; // 方式1:在参数值中拼接百分号 $sql = "SELECT DISTINCT author_id AS label FROM users WHERE author_id::text LIKE :term AND role = 'Editor'"; $query = Users::findBySql($sql, [ ':term' => "%{$author_id}%" ])->asArray()->all(); // 方式2:用PostgreSQL的CONCAT函数(更安全,避免特殊字符转义问题) $sql = "SELECT DISTINCT author_id AS label FROM users WHERE author_id::text LIKE CONCAT('%', :term, '%') AND role = 'Editor'"; $query = Users::findBySql($sql, [ ':term' => $author_id ])->asArray()->all();
推荐:使用Yii2 QueryBuilder(ActiveQuery)写法
QueryBuilder是Yii2推荐的查询方式,更安全、易维护,自动处理参数绑定和SQL语法:
$author_id = 25; $result = Users::find() ->select(['author_id AS label']) // 指定字段及别名 ->distinct() // 对应DISTINCT关键字 ->where(['role' => 'Editor']) // 等值条件,自动绑定参数 ->andWhere(['like', 'author_id::text', "%{$author_id}%"]) // 模糊查询 ->asArray() // 返回数组,方便获取label别名字段 ->all();
如果要兼容更多数据库(比如MySQL),可以把author_id::text换成CAST(author_id AS TEXT):
$result = Users::find() ->select(['author_id AS label']) ->distinct() ->where(['role' => 'Editor']) ->andWhere(['like', 'CAST(author_id AS TEXT)', $author_id, false]) // 第四个参数false表示不自动加%,如果需要自动添加,去掉该参数或设为true ->asArray() ->all();
内容的提问来源于stack exchange,提问作者Honorum
相关产品推荐
相关产品推荐

