15

我有以下代码从 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 在后台运行脚本

4

5 回答 5

18

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

'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)处理的,而不是每次你记录一些东西。


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

$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);
于 2012-05-17T04:40:49.597 回答
8

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

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

于 2014-08-13T05:43:38.740 回答
7
  • 第一种方式(官方方式):
    在您的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.datet.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);
于 2016-01-24T08:26:47.647 回答
1

您可以直接在您的页面上查看日志:

'log'=>array(
    'class'=>'CLogRouter',
    'routes'=>array(
        array(
            'class'=>'CWebLogRoute',
        ),
    ),
),
于 2013-03-07T14:42:33.353 回答
1

如果您不想在看到 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 的方法不可靠(不知道为什么,但有时使用此方法会忽略标准)。

于 2015-01-08T13:01:52.807 回答