Yii - Как распечатать SQL, используемый findAll
У меня есть следующий код, чтобы получить некоторые записи из db
$criteria = new CDbCriteria();
$criteria->condition = 't.date BETWEEN "'.$from_date.'" AND "'.$to_date.'"';
$criteria->with = array('order');
$orders = ProductOrder::model()->findAll($criteria);
Можно ли получить SQL, который используется findAll? Я знаю, что вы можете получить его с консоли отладки. Но я запускаю script в фоновом режиме, используя yiic.php
Ответы
Ответ 1
Вы можете регистрировать выполненные запросы в журнале приложений и просматривать их. Что-то вроде этого в файле конфигурации:
'components' => array(
'db'=>array(
'enableParamLogging' => true,
),
'log'=>array(
'class'=>'CLogRouter',
'routes'=>array(
array(
'class'=>'CFileLogRoute',
'levels'=>'trace,log',
'categories' => 'system.db.CDbCommand',
'logFile' => 'db.log',
),
),
),
);
В некоторых случаях (например, при выполнении тестов) вам также потребуется вызвать Yii::app()->log->processLogs(null);
в конце процесса, чтобы это работало.
Конечно, как только вы там ничего не мешаете вам писать свой собственный маршрут журнала, который делает что-то другое с зарегистрированными сообщениями, но помните, что журналы обрабатываются в конце запроса (или когда вы вызываете processLogs
), не каждый раз, когда вы что-то записываете.
Кстати, вы не должны создавать такие запросы, с динамическим вводом прямо в запросе. Вместо этого используйте переменные bind:
$criteria = new CDbCriteria();
$criteria->condition = 't.date BETWEEN :from_date AND :to_date';
$criteria->params = array(
':from_date' => $from_date,
':to_date' => $to_date,
);
$criteria->with = array('order');
$orders = ProductOrder::model()->findAll($criteria);
Ответ 2
-
Первый способ (официальный путь):
В конфигурационном файле main.php
добавьте эти два параметра в log section
, и вы можете видеть сообщения журнала в конце своей страницы или FireBug Console
в своем браузере. не забудьте установить необходимые параметры в разделе db
.
'components' => array(
'db'=>array(
'enableProfiling'=>true,
'enableParamLogging' => true,
),
'log'=>array(
'class'=>'CLogRouter',
'routes'=>array(
array(
'class'=>'CWebLogRoute',
'showInFireBug' => true,
),
array(
'class'=>'CProfileLogRoute',
'levels'=>'profile',
'enabled'=>true,
),
),
),
);
-
Второй способ:
В вашем коде просто измените написание одного из ваших столбцов на что-то неправильное, и вы получите сообщение об ошибке содержит полный SQL-запрос на вашей странице ошибок (вы должны находиться в режиме YII_DEBUG
true). что-то вроде этого:
(Я изменил t.date
на t.wrong_date
, когда вы обновляете свою страницу, вы увидите сгенерированный SQL, который был выполнен в вашей базе данных)
$criteria = new CDbCriteria();
$criteria->condition = 't.wrong_date BETWEEN "'.$from_date.'" AND "'.$to_date.'"';
$criteria->with = array('order');
$orders = ProductOrder::model()->findAll($criteria);
в обоих направлениях, YII_DEBUG
true в index.php
defined('YII_DEBUG') or define('YII_DEBUG',true);
Ответ 3
Вы можете получить sql, используя CDbCommandBuilder, например:
ModelClassName::model()->
getCommandBuilder()->
createFindCommand('tableName', $criteria)->text;
Ответ 4
Вы можете просмотреть журнал непосредственно на своей странице:
'log'=>array(
'class'=>'CLogRouter',
'routes'=>array(
array(
'class'=>'CWebLogRoute',
),
),
),
Ответ 5
Если вы не хотите выполнять запрос перед просмотром SQL, это не так просто, как вы могли бы надеяться.
Это так же грязно, как и ошибочно, но когда только в разработке, я в прошлом старался добавить преднамеренную преднамеренную ошибку в критерии и полагаться на полученное исключение, чтобы попытаться выполнить SQL.
например.
$criteria = new CDbCriteria();
$criteria->condition = 't.date_fgjhfgjfgj BETWEEN :from_date AND :to_date';
$criteria->params = array(
':from_date' => $from_date,
':to_date' => $to_date,
);
$criteria->with = array('order');
$orders = ProductOrder::model()->findAll($criteria);
Я нашел метод Ilya ненадежным (не знаю почему, но иногда критерии игнорируются с помощью этого метода).