getRawSql() 只能在 createCommand() 之后、execute() 或 queryAll() 之前调用,且仅适用于 yii\db\Command 实例;AR 查询需先调用 createCommand() 转换,批量操作须拆解调用,返回 SQL 含占位符,参数值存于 params 属性中。

直接用 getRawSql() 就能拿到最终执行的 SQL,但必须在 createCommand() 之后、execute() 或 queryAll() 之前调用,否则返回空字符串。
为什么 getRawSql() 返回空或报错
常见错误是调用时机不对:比如先 execute() 再 getRawSql(),或者对 AR 查询(如 User::find()->where(...))直接调用该方法——它只属于 yii\db\Command 实例,不支持 ActiveQuery。
- ✅ 正确姿势:构造完 command,立刻调用
getRawSql() - ❌ 错误姿势:
$cmd->execute(); echo $cmd->getRawSql();(执行后绑定参数已释放) - ❌ 错误姿势:
User::find()->where(['id' => 1])->getRawSql()(AR 查询对象没有这个方法)
AR 查询如何看原生 SQL
AR 查询需先转成 Command 才能打印 SQL。核心是调用 createCommand() 方法获取底层命令对象。
- 用
User::find()->where(['status' => 1])->createCommand(Yii::$app->db)->getRawSql() - 注意:必须显式传入
Yii::$app->db,否则可能因未指定 DB 组件而抛出异常 - 如果用了自定义 db 组件(如
db2),要换成Yii::$app->db2 - 批量操作如
batchInsert()无法直接链式调用getRawSql(),得拆开写:$cmd = Yii::$app->db->createCommand(); $cmd->batchInsert('user', ['name'], [['test']]); echo $cmd->getRawSql(); // ✅ 这样才有效
调试时容易忽略的参数绑定细节
打印出的 SQL 默认含占位符(如 :qp0),不是真实值。想看到带实际参数的 SQL,得手动替换或启用日志组件。
-
getRawSql()只返回带占位符的语句,例如:SELECT * FROM user WHERE id = :qp0 - 真实参数值存在
$cmd->params中,可打印:var_dump($cmd->params) - 更省事的方式是开启
yii\log\DbTarget或配置yii\log\FileTarget并设置'levels' => ['trace'],SQL 日志会自动记录带参数展开的完整语句 - 注意:生产环境禁用此日志级别,避免敏感数据泄露
真正麻烦的是嵌套查询或复杂关联场景下,createCommand() 链式调用断裂后难以捕获完整 SQL;这种时候建议把构建逻辑抽成变量,确保 command 实例生命周期可控。











