使用ActiveRecord与Yii2logging实际的SQL查询?
我正在这样做:
$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
 使用返回yii\db\ActiveQuery实例的关系,可以直接在代码中使用var_dump()提取原始SQL查询。 
 例如,如果我们有user关系: 
 /** * @return \yii\db\ActiveQuery */ public function getUser() { return $this->hasOne(User::className(), ['id' => 'user_id']); } 
 然后你可以var_dump()的原始SQL: 
 var_dump($model->getUser()->prepare(Yii::$app->db->queryBuilder)->createCommand()->rawSql); exit(); 
 请注意,您应该像这样调用它,而不是$model->user->... (后者返回User实例)。 
 但在你的情况下,这是不可能的,因为count()立即返回int 。 你可以var_dump()部分查询而不用count() ,但是我觉得这样不方便。 
 请注意,您可以使用此方法来转储任何ActiveQuery实例(不仅是通过关系返回的实例)所生成的SQL,例如: 
 $query = User::find()->where(['status' => User::STATUS_ACTIVE]); var_dump($query->prepare(Yii::$app->db->queryBuilder)->createCommand()->rawSql); exit(); 
方法2
这在我看来更简单了,我个人更喜欢这个debuggingSQL查询。
Yii 2内置了debugging模块。 只需将此添加到您的configuration:
 'modules' => [ 'debug' => [ 'class' => 'yii\debug\Module', ], ], 
 确保你只有本地,而不是生产。 如果需要,还可以更改allowedIPs属性。 
 这给你function面板在页面的底部。 findDB字,然后点击数量或时间。 在此页面上,您可以查看所有执行的查询并对其进行过滤。 我通常不会在网格中对它们进行过滤,并使用标准的浏览器search快速浏览并find必要的查询(例如,使用表名作为关键字)。 
方法3
 只是在查询中出现错误,例如在列名称中,而不是city 。 这将导致数据库exception,然后您可以即时看到错误消息中生成的查询。 
 除了arogachev答案之外,当你已经使用了一个ActiveQuery对象的时候,这里是我search查看rawsql的那一行。 
 /* @var $studentQuery ActiveQuery */ $studentQuery = Student::Find(); // Construct the query as you want it $studentQuery->where("status=3")->orderBy("grade ASC"); // Get the rawsql >-- The line I usually use --< var_dump(studentQuery->prepare(Yii::$app->db->queryBuilder)->createCommand()->rawSql); // Run the query $studentQuery->all(); 
你可以试试这个,假设你有一个查询给出像:
 $query = new Books::find()->where('author=2'); echo $query->createCommand()->sql; 
或者获取包含所有参数的SQL请尝试:
 $query->createCommand()->getRawSql() 
 如果要在控制台应用程序中loggingActiveRecord所有关系查询,所有build议的方法都无济于事。 它们只显示活动logging表中的主要SQL, \yii\debug\Module仅在浏览器中工作。 
获取所有执行的SQL查询的替代方法是通过添加指定的FileTarget来configuration它们来logging它们:
 'log' => [ 'targets' => [[ ... ], [ 'class' => 'yii\log\FileTarget', 'logFile' => '@runtime/logs/profile.log', 'logVars' => [], 'levels' => ['profile'], 'categories' => ['yii\db\Command::query'], 'prefix' => function($message) { return ''; } ]] ] 
UPDATE
 为了logging插入/更新/删除查询,还应该添加yii\db\Command::execute类别: 
 'categories' => ['yii\db\Command::query', 'yii\db\Command::execute'] 
当你有一个查询对象,你也可以使用
 $query->createCommand()->getRawSql() 
返回包含参数的原始SQL
 $query->createCommand()->sql 
这将分别输出参数的Sql。
为了logging/跟踪每个/ 所有查询:
 扩展\yii\db\Connection并覆盖createCommand方法,如下所示: 
 namespace app\base; class Connection extends \yii\db\Connection { public function createCommand($sql = null, $params = array()) { $createCommand = parent::createCommand($sql, $params); $rawSql = $createCommand->getRawSql(); // ########### $rawSql -> LOG IT / OR DO ANYTHING YOU WANT WITH IT return $createCommand; } } 
然后,简单地改变你的数据库连接在你的数据库configuration如下所示:
 'db' => [ 'class' => 'app\base\Connection', // #### HERE 'dsn' => 'pgsql:host=localhost;dbname=dbname', 'username' => 'uname', 'password' => 'pwd', 'charset' => 'utf8', ], 
 现在,你可以跟踪/读取/ …由db连接执行的所有查询。 
试试像,
 $query = Yii::$app->db->createCommand() ->update('table_name', ['title' => 'MyTitle'],['id' => '1']); var_dump($query->getRawSql()); die(); $query->execute(); 
输出:
 string 'UPDATE `table_name` SET `title`='MyTitle' WHERE `id`='1' ' (length=204)