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 ненадежным (не знаю почему, но иногда критерии игнорируются с помощью этого метода).