使用ActiveRecord与Yii2logging实际的SQL查询?

我正在这样做:

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

然后在这个视图中:

 foreach($students as $student) { echo $student->name . ', &nbsp;'; 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) 
Interesting Posts