Yii - 如何打印findAll使用的SQL

Adr*_*wan 14 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);
Run Code Online (Sandbox Code Playgroud)

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

DCo*_*der 17

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

'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',
      ), 
    ),
  ),
);
Run Code Online (Sandbox Code Playgroud)

在某些情况下(例如,在运行测试时),您还需要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);
Run Code Online (Sandbox Code Playgroud)

  • 我想,取决于你想对结果做些什么.如果您想使用模型功能(例如验证),使用AR是一个显而易见的选择.就个人而言,我更喜欢AR并且只为更复杂的情况(例如涉及连接的更新)留下DAO.这样,我可以将模型范围用于常见条件,而不必在架构或业务逻辑更改时手动查看/更新所有直接命令.(另外,在任何地方使用AR意味着访问结果中包含的数据的一致方式,而不必担心结果行是对象还是数组......) (3认同)

Moh*_*ima 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);
Run Code Online (Sandbox Code Playgroud)

  • 我总是用第二个 (2认同)

Ily*_*tin 6

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

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

  • 对于简单的查询,这是一个很好的解决方案,但是[不考虑“ with”](https://github.com/yiisoft/yii/blob/1.1.16/framework/db/schema/CDbCommandBuilder.php#L74)在OP的示例中已说明 (2认同)