У меня есть следующий код, чтобы получить некоторые записи из 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? Я знаю, что вы можете получить его с консоли отладки. Но я запускаю сценарий в фоновом режиме, используя yiic.php
Вы можете регистрировать выполненные запросы в журнале приложений и просматривать это. Что-то вроде этого в файле конфигурации:
'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);
Первый путь (официальный путь):
В конфигурационном файле 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);
Вы можете получить sql, используя CDbCommandBuilder, например:
ModelClassName::model()-> getCommandBuilder()-> createFindCommand('tableName', $criteria)->text;
Вы можете просмотреть журнал прямо на своей странице:
'log'=>array( 'class'=>'CLogRouter', 'routes'=>array( array( 'class'=>'CWebLogRoute', ), ), ),
Если вы не хотите выполнять запрос перед просмотром 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);
Я нашел метод Илии ненадежным (не знаю почему, но иногда критерии игнорируются с помощью этого метода).