【问题标题】:Extbase - get created sql from queryExtbase - 从查询中获取创建的 sql
【发布时间】:2012-10-16 14:20:09
【问题描述】:

我想从我的typo3 扩展中获取一些数据库表。 该扩展基于 extbase。

查询总是不返回任何内容,但数据存在

我试过了:

$query = $this->createQuery();
$query->statement('SELECT * FROM `my_table`
    WHERE field = ? ORDER BY date DESC LIMIT 1',
    array($condition));

$results = $query->execute();

还有这个:

$query = $this->createQuery();

$query->matching($query->equals('field', $condition));
$query->setOrderings(array('date' => Tx_Extbase_Persistence_QueryInterface::ORDER_DESCENDING));
$query->setLimit(1);

$results = $query->execute();

两者都返回 null 作为结果。

是否可以获取类创建的sql来查看bug在哪里?

我查看了一些 extbase 持久类,但没有找到线索

编辑: 对于那些有兴趣的人..我找到了一个“解决方案”。

如果使用 statement() 方法创建查询,则可以使用此函数打印查询

echo $query->getStatement()->getStatement();

它不会替换占位符。 但是您可以使用此方法获取变量

var_dump($query->getStatement()->getBoundVariables());

这是我找到的最佳解决方案,无需编辑 extbase 扩展

【问题讨论】:

标签: sql typo3 extbase


【解决方案1】:

在 TYPO3 6.2 中,您可以使用 Extbase DebuggerUtility 来调试查询。

在 $query->execute() 之前添加这段代码:

/** @var Typo3DbQueryParser $queryParser */
$queryParser = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Storage\\Typo3DbQueryParser');
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($queryParser->parseQuery($query));

【讨论】:

    【解决方案2】:

    查看this snippet,虽然使用起来不是很舒服,但很有帮助:

    通常,您需要在 buildQuery(array $sql) 方法 (*) 的末尾使用此代码 - 就在 return $statement; 之前

    if (in_array("your_table_name", $sql['tables'])) {
        var_dump($statement);
        print_r($statement);
    }
    

    (*) 类文件:

    • TYPO3 版本:4.x:typo3/sysext/extbase/Classes/Persistence/Storage/Typo3DbBackend.php
    • TYPO3 版本:6.x:typo3/sysext/extbase/Classes/Persistence/Generic/Storage/Typo3DbBackend.php

    在 6.2.x ...

    您可以在\TYPO3\CMS\Core\Database\DatabaseConnection::exec_SELECTquery 方法中尝试,只需在获取 $query 后添加条件,例如(trim 很重要!):

    public function exec_SELECTquery($select_fields, $from_table, $where_clause, $groupBy = '', $orderBy = '', $limit = '') {
        $query = $this->SELECTquery($select_fields, $from_table, $where_clause, $groupBy, $orderBy, $limit);
    
        if (trim($from_table) == 'fe_users') {
            DebuggerUtility::var_dump($query);
        }
    
    // rest of method
    

    【讨论】:

    • 这个问题没有简单的解决方案吗?类似 $query->getRawSql()
    • 我不知道...如果是的话,我会首先描述它。我正在按照描述使用这种方式,但没有找到更好的方法。
    • @Mateng:相信,它可以节省大量时间 :) 我用它来验证 findPrevious()... 方法之类的东西:)
    • 我在 6.2 中找不到 buildQuery 方法
    【解决方案3】:

    一种不改变任何 Typo3 核心代码且目前没有在任何论坛中提及的简单方法是使用 php "serialize()" 方法:

    $result = $query->execute();
    echo (serialize($result));
    

    在结果对象中,您可以找到 SQL 查询 ("statement;" ...)

    【讨论】:

      【解决方案4】:

      改进对biesiors的回答:

      由于 Extbase 在调用 buildQuery() 后替换了一些占位符,您可能更愿意将调试输出放在 getObjectDataByQuery() 中,就在 $this->replacePlaceholders($sql, $parameters, $tableName); 之后 em>

      if (strpos($sql, "your_table_name.")) {
          debug($sql, 'my debug output');
      };
      

      另外,最好使用 debug() 而不是 var_dump()。
      [文件:typo3\sysext\extbase\Classes\Persistence\Generic\Storage\Typo3DbBackend.php。 6.1版第339行]:

      【讨论】:

        【解决方案5】:
        $query = $this->createQuery();
        $query->getQuerySettings()->setReturnRawQueryResult(TRUE);
        $getHotelInfo = 'SELECT * FROM `my_table` WHERE field = ? ORDER BY date DESC LIMIT 1';
        return $query->statement($getHotelInfo)->execute();
        

        要执行查询,您必须在存储库中写入“setReturnQueryResult”

        【讨论】:

          【解决方案6】:

          我只是用 $_GET 条件扩展了上面的 sn-p。 对于调试,只需将“?dbg_table=tx_some_of_my_tables”附加到您的地址,您就可以开始了;-)

          if (in_array($_GET['dbg_table'], $sql['tables'])) {
                  echo('<div style="background: #ebebeb; border: 1px solid #999; margin-bottom: 20px; padding: 10px;"><pre style="white-space: normal">'.$statement.'</pre></div>');
              }
          

          【讨论】:

            【解决方案7】:

            使用 TYPO3 6.1 时调试语句的更简洁方法是使用 query parserTypo3DbBackend

            $parser = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Storage\\Typo3DbBackend');
            $params = array();
            $queryParts = $parser->parseQuery($query, $params);
            
            \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('query', 'my_extension', 1, array('query' => $queryParts, 'params' => $params));
            

            解析器返回一个数组,其中包含生成的 SQL 语句的不同部分。

            在 TYPO3 6.2 中,parseQuery 方法已移至 Typo3DbQueryParser 并丢失了第二个参数。

            【讨论】:

              【解决方案8】:

              我建议在“SYS”数组下的typo3conf/LocalConfiguration.php 文件中设置它

              'SYS' => array(
              ......
              'displayErrors' => 1,
              'sqlDebug' => 1
              .......
              )
              

              然后故意在查询中写错字段名,然后执行代码。 这将显示最后一个查询执行错误。

              【讨论】:

                猜你喜欢
                • 2013-04-13
                • 1970-01-01
                • 2017-06-05
                • 1970-01-01
                • 2014-08-22
                • 2021-09-20
                • 2014-10-26
                • 2013-09-11
                • 1970-01-01
                相关资源
                最近更新 更多