使用 ActiveRecord 和 Yii2 记录实际的 SQL 查询?

2022-08-30 10:14:34

我正在做这个:

$students = Student::find()->all();
    return $this->render('process', array('students' => $students));

然后在视图中显示:

foreach($students as $student)
    {
        echo $student->name . ',  ';
        echo $student->getQuizActivitiesCount(); ?> <br /> <?php
    }

我希望看到正在执行的sql查询。一个学生“有很多”测验活动,查询执行完美,但我需要看到原始SQL。这可能吗?


答案 1

方法 1

使用返回实例的关系,可以直接在代码中提取原始 SQL 查询,例如使用 。yii\db\ActiveQueryvar_dump()

例如,如果我们有关系:user

/**
 * @return \yii\db\ActiveQuery
 */
public function getUser()
{
    return $this->hasOne(User::className(), ['id' => 'user_id']);
}

然后,您可以像这样使用原始 SQL:var_dump()

var_dump($model->getUser()->prepare(Yii::$app->db->queryBuilder)->createCommand()->rawSql);
exit();

请注意,您应该这样称呼它,而不是(后者返回实例)。$model->user->...User

但是对于您来说,这是不可能的,因为会立即返回。您可以在没有的情况下进行部分查询,但我认为这不方便。count()intvar_dump()count()

请注意,您可以使用此方法转储任何实例(不仅仅是由关系返回的实例)生成的 SQL,例如:ActiveQuery

$query = User::find()->where(['status' => User::STATUS_ACTIVE]);
var_dump($query->prepare(Yii::$app->db->queryBuilder)->createCommand()->rawSql);
exit();

方法 2

在我看来,这要简单得多,我个人在调试SQL查询时更喜欢这个。

Yii 2 有内置的调试模块。只需将其添加到您的配置中:

'modules' => [
    'debug' => [
        'class' => 'yii\debug\Module',
    ],
],

确保仅在本地拥有它,而不是在生产环境中使用。如果需要,还要更改属性。allowedIPs

这将在页面底部为您提供功能面板。找到单词,然后单击计数或时间。在此页上,您可以查看所有已执行的查询并对其进行筛选。我通常不会在Grid中过滤它们,而是使用标准的浏览器搜索来快速浏览并找到必要的查询(例如,使用表名作为关键字)。DB

方法 3

只需在查询中出错,例如在列名中 - 而不是 .这将导致数据库异常,然后您可以立即在错误消息中看到生成的查询。cityycity


答案 2

如果要在控制台应用程序中记录所有建议的方法的所有关系查询,则无济于事。它们在活动记录的表上仅显示主SQL,仅在浏览器中工作。ActiveRecord\yii\debug\Module

获取所有已执行的 SQL 查询的替代方法是通过将特定的 FileTarget 添加到配置来记录它们:

'log' => [
    'targets' => [[
        ...
    ], [
        'class' => 'yii\log\FileTarget',
        'logFile' => '@runtime/logs/profile.log',
        'logVars' => [],
        'levels' => ['profile'],
        'categories' => ['yii\db\Command::query'],
        'prefix' => function($message) {
            return '';
        }
    ]]
]

更新

为了记录插入/更新/删除查询,还应该添加类别:yii\db\Command::execute

'categories' => ['yii\db\Command::query', 'yii\db\Command::execute']

推荐