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? Я знаю, что вы можете получить его с консоли отладки. Но я запускаю сценарий в фоновом режиме, используя 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); 

Я нашел метод Илии ненадежным (не знаю почему, но иногда критерии игнорируются с помощью этого метода).