Я делаю это:
$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
, можно извлечь исходный SQL-запрос непосредственно в код, например, с помощью var_dump()
.
Например, если у нас есть отношение 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()
, но я думаю, что это не удобно.
Обратите внимание, что этот метод можно использовать для сброса сгенерированного 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
.
Это дает вам функциональную панель внизу страницы. Найдите слово DB
и щелкните либо счет, либо время. На этой странице вы можете просмотреть все выполненные запросы и отфильтровать их. Обычно я не фильтрую их в Grid и использую стандартный поиск в браузере, чтобы быстро перемещаться и находить нужный запрос (например, используя имя таблицы как ключевое слово).
Способ 3
Просто сделайте ошибку в запросе, например, в столбце name – cityy
а не в city
. Это приведет к ошибке базы данных, а затем вы сможете мгновенно увидеть сгенерированный запрос в сообщении об ошибке.
В дополнение к ответу 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 >-- 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()
Если вы хотите регистрировать все реляционные запросы 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 ''; } ]] ]
ОБНОВИТЬ
Чтобы записывать запросы вставки / обновления / удаления, нужно также добавить yii\db\Command::execute
category:
'categories' => ['yii\db\Command::query', 'yii\db\Command::execute']
когда у вас есть объект запроса, вы также можете использовать
$query->createCommand()->getRawSql()
для возврата Raw SQL с включенными параметрами или
$query->createCommand()->sql
который будет выводить Sql с параметрами отдельно.
Чтобы регистрировать / отслеживать все / все запросы:
createCommand
\yii\db\Connection
и переопределить метод createCommand
, как 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 в конфигурации 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)