【问题标题】:cakephp see the compiled SQL Query before executioncakephp 在执行前查看编译好的 SQL Query
【发布时间】:2013-05-22 17:47:46
【问题描述】:

我的查询在每次运行时都会出现超时错误。它是一个带有连接的分页。
我想调试SQL,但由于超时,我看不到它。

如何在执行前查看已编译的 SQL Query?


一些蛋糕代码:

$this -> paginate = array(
        'limit' => '16',
        'joins' => array( array(
                'table' => 'products',
                'alias' => 'Product',
                'type' => 'LEFT',
                'conditions' => array('ProductModel.id = Product.product_model_id')
            )),
        'fields' => array(
            'COUNT(Product.product_model_id) as Counter',
            'ProductModel.name'
            ),
        'conditions' => array(
            'ProductModel.category_id' => $category_id,
        ),
        'group' => array('ProductModel.id')
    );

【问题讨论】:

    标签: sql debugging logging cakephp-1.3


    【解决方案1】:

    首先,在app/config/config.php 中将debug 变量设置为2。

    然后添加:

    <?php echo $this->element('sql_dump');?>
    

    在布局的末尾。这实际上应该在您的默认蛋糕布局中注释掉。

    您现在可以看到进入数据库的所有 SQL 查询。

    现在复制查询并在数据库上使用SQL EXPLAIN 命令(链接用于 MySQL)以查看查询在DBMS 中的作用。有关 CakePHP 调试的更多信息,请查看here

    由于您的脚本甚至没有渲染,您可以尝试直接从数据源获取最新日志:

    function getLastQuery()
    {
        $dbo = $this->getDatasource();
        $logs = $dbo->getLog();
        $lastLog = end($logs['log']);
        return $lastLog['query'];
    }
    

    这需要在模型中,因为getDatasource() 函数是在模型中定义的。 检查整个 $logs 变量,看看里面有什么。

    【讨论】:

    • 谢谢。但它不起作用。问题是脚本永远不会进入渲染部分,因为超时是在控制器操作级别。
    • 而且,这个脚本会返回上次执行的最后一个查询?
    • 不完全确定,因为我不记得确切的回报是什么。就试一试吧。它肯定会返回最后一个查询的日志。只需转储 $logs 变量并检查它。
    • 从控制器调用时使用ConnectionManager::getDataSource('default')获取数据源
    【解决方案2】:

    你可以做的另一件事是......

    转到 Cake/Model/DataSource/DboSource.php 并找到函数 execute() 并打印 $sql 变量。 那应该打印 sql。

    这当然不是最干净的方法(因为您正在更改 Cake 目录).. 但如果某些东西无法使用 sql 进行调试,肯定会是最快的。

    【讨论】:

    • 当其他一切都因为恶意查询而完全崩溃时,这有时是最有用的方法!
    • 答案对于您无权访问sql_dump 元素的命令行环境也很有帮助。
    • 谢谢!这个有帮助:)
    • 受此答案的启发,从 Cakephp 3.9 开始,分页器文件的路径是 vendor/cakephp/cakephp/src/Datasource/Paginator.php 可以打印第 172 行的 $cleanQuery 以快速查看的查询。我尝试了其他几种方法,但没有奏效。查询日志有效,但我希望它打印在页面上。
    【解决方案3】:
    Try...
    function getLastQuery($model) {
        $dbo = $model->getDatasource();
        $logData = $dbo->getLog();
        $getLog = end($logData['log']);
        echo $getLog['query'];
    }
    

    【讨论】:

    • 此函数在 PHP 5.4.32 的服务器上运行良好,但在 $dbo->getLog() 为空的情况下不适用于 5.5.16 的服务器。在另一台服务器上,我得到了完整的日志。任何人都知道为什么该功能在 5.5 上不起作用。版本?
    • @user1555112 我不确定问题出在哪里,但它在 5.6.1 上运行良好
    • @user1555112 如果您使用 this->log 或 CakeLog,您可能在配置中关闭了调试模式
    【解决方案4】:

    显示给定模型的所有已执行查询的简单方法:

      $sqllog = $this->ModelName->getDataSource()->getLog(false, false);       
      debug($sqllog);
    

    【讨论】:

      【解决方案5】:
      class YourController extends AppController {
          function testfunc(){
              $this->Model->find('all', $options);
              echo 'SQL: '.$this->getLastQuery();
          }
      
          function getLastQuery()
          {
              $dbo = ConnectionManager::getDataSource('default');
              $logs = $dbo->getLog();
              $lastLog = end($logs['log']);
              return $lastLog['query'];
          }
      }
      

      或者您可以通过在 lib/Cake/Model/DataSource.php 中的函数 execute() 中添加以下行来获取所有查询

      Debugger::dump($sql);
      

      【讨论】:

        【解决方案6】:

        在 app/config/config.php 中将调试变量设置为 2。

        echo $this->Payment->save();
        

        输出类似于 =>SQL 查询:INSERT INTO photoora_photoorange.payments VALUES (*******)

        [插入查询][2]

        【讨论】:

          【解决方案7】:

          在 app/config/config.php 中将调试变量设置为 2。

          并且

          【讨论】:

            猜你喜欢
            • 2021-10-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-05-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多