私はこれをやっています:
$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']);
}
次に、そのような生のSQLをvar_dump()
できます:
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
私の意見ではこれははるかに簡単であり、個人的にはSQLクエリをデバッグするときにこれを好む。
Yii 2にはデバッグモジュールが組み込まれています。これを設定に追加するだけです:
'modules' => [
'debug' => [
'class' => 'yii\debug\Module',
],
],
本番環境ではなくローカルでのみ使用するようにしてください。必要に応じて、allowedIPs
プロパティも変更します。
これにより、ページの下部に機能パネルが表示されます。 DB
Wordを見つけて、カウントまたは時間をクリックします。このページでは、実行されたすべてのクエリを表示し、それらをフィルタリングできます。私は通常、グリッドでそれらをフィルタリングせず、標準のブラウザ検索を使用して、必要なクエリをすばやくナビゲートして見つけます(たとえば、テーブル名をキーワードとして使用)。
方法
たとえば、列名-cityy
の代わりにcity
などのクエリでエラーを作成します。これはデータベース例外として発生し、生成されたクエリを即座にエラーメッセージで確認できます。
コンソールアプリケーションでActiveRecord
のすべてのリレーショナルクエリをログに記録する場合、提案されたすべての方法は役に立ちません。アクティブレコードのテーブルのメインSQLのみが表示され、\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 '';
}
]]
]
UPDATE
挿入/更新/削除クエリを記録するには、yii\db\Command::execute
カテゴリも追加する必要があります。
'categories' => ['yii\db\Command::query', 'yii\db\Command::execute']
これを試すことができます。次のようなクエリがあると仮定します。
$query = new Books::find()->where('author=2');
echo $query->createCommand()->sql;
または、すべてのパラメーターを含むSQLを取得するには、次を試してください。
$query->createCommand()->getRawSql()
Arogachevの答えに加えて、すでにActiveQuery
オブジェクトを操作している場合、ここにrawsqlを表示するために検索する行があります。
/* @var $studentQuery ActiveQuery */
$studentQuery = Student::Find();
// Construct the query as you want it
$studentQuery->where("status=3")->orderBy("grade ASC");
// Get the rawsql
var_dump($studentQuery->prepare(Yii::$app->db->queryBuilder)->createCommand()->rawSql);
// Run the query
$studentQuery->all();
クエリオブジェクトがある場合は、使用することもできます
$query->createCommand()->getRawSql()
パラメータが含まれるRaw SQLを返すか、
$query->createCommand()->sql
パラメータ付きのSqlを個別に出力します。
Every/allクエリを記録/追跡するには:
以下のように\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;
}
}
次に、以下のようにdb configでdb接続を変更します。
'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)