Extbase - 从查询中获取创建的 sql

Posted

技术标签:

【中文标题】Extbase - 从查询中获取创建的 sql【英文标题】:Extbase - get created sql from query 【发布时间】: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 扩展

【问题讨论】:

您也可以使用 Zend Server,它的“Z-Ray”会自动收集所有数据库查询。 这能回答你的问题吗? How to debug a query in 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 parser 的 Typo3DbBackend

$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
.......
)

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

【讨论】:

以上是关于Extbase - 从查询中获取创建的 sql的主要内容,如果未能解决你的问题,请参考以下文章

php TYPO3 Extbase - 按照逗号逗号列表的顺序获取产品

如何获取将在 PHPMyAdmin 中重新创建 sql 表的查询

如何从 VB.NET 的视图中获取 SQL 查询

是否可以通过 REST API 从 Metabase MBQL / SQL 查询中获取原始数据?

如何循环在 SQL Server 中动态创建的查询

用SQL语句怎么从一个表中怎么获取最高工资的三个人