Yii - 如何打印findAll使用的SQL

时间:2012-05-17 04:13:53

标签: php yii

我有以下代码从db

获取一些记录
    $criteria = new CDbCriteria();
    $criteria->condition = 't.date BETWEEN "'.$from_date.'" AND "'.$to_date.'"';
    $criteria->with = array('order');

    $orders = ProductOrder::model()->findAll($criteria);

是否可以获取findAll使用的SQL?我知道你可以从调试控制台获取它。但我正在使用yiic.php

在后台运行脚本

5 个答案:

答案 0 :(得分:16)

您可以在应用程序日志中记录执行的查询并查看。在配置文件中有这样的东西:

'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);才能生效。

当然,一旦你在那里,没有什么能阻止你编写自己的日志路由,这些路由会对记录的消息做出不同的事情,但是请注意在请求结束时处理日志(或者当你调用{{1而不是每次你记录的东西。


顺便说一句,你不应该在查询中使用动态输入来构建这样的查询。改为使用绑定变量:

processLogs

答案 1 :(得分:6)

  • 第一种方式(官方方式):
    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

index.php为真
defined('YII_DEBUG') or define('YII_DEBUG',true);

答案 2 :(得分:5)

您可以使用CDbCommandBuilder获取sql,如下所示:

ModelClassName::model()-> getCommandBuilder()-> createFindCommand('tableName', $criteria)->text;

答案 3 :(得分:1)

您可以直接在自己的页面上看到日志:

'log'=>array(
    'class'=>'CLogRouter',
    'routes'=>array(
        array(
            'class'=>'CWebLogRoute',
        ),
    ),
),

答案 4 :(得分:1)

如果您在查看SQL之前不想执行查询,这实际上并不像您希望的那样简单。

它就像错误一样脏,但是,在开发时,我过去曾在标准中添加故意的故意错误,并依赖于生成的SQL来尝试SQL。

e.g。

$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的方法不可靠(不知道为什么,但有时使用这种方法会忽略标准)。