SQL-Queries Debuggen in Typo3

TYPO3 Tutorials by undkonsorten BerlinOft kommt es vor das das frisch gebaute Repository keine Ergebnisse zurück liefert. Meistens fehlt dann nur eine gesetzte Storage PID. Doch was wenn sich das Repository weiterhin hartnäckig weigert Ergebnisse zurück zu liefern? Dann wird es Zeit etwas tiefer in die Materie einzusteigen und ordentlich zu debuggen. Zunächst macht es Sinn, sich seine gebauten Constraints anzuschauen und genau zu überlegen ob dort ein Logikfehler vorliegt. Ich baue meine Queries meist so:

PHP (Repository)


$constraints = array();

if($demand->getListMode()=="archive"){
  $archivConstraints[] = $query->lessThan('start', time());
  $archivConstraints[] = $query->logicalOr(
    array(
    0=>$query->equals('end', 0),
    1=>$query->lessThan('end', time())
    )
  );
  $constraints[] = $query->logicalAnd($archivConstraints);
}

if (is_array($searchWords) && count($searchWords)) {
  foreach($searchWords as $searchWord){
    $searchWordConstraint = array();
    foreach ($searchFields as $field) {
      //Search for each word seperatly
      $searchWordConstraint[] = $query->like($field, '%' . $searchWord . '%');
    }
    $searchConstraints[] = $query->logicalOr($searchWordConstraint);
  }
  $constraints[] = $query->logicalAnd($searchConstraints);
}

Constraints ausgaben (var_dump)

Jetzt kann man die gebauten Constraints debuggen, indem man folgende Zeile in seinen php-Code einfügt:

PHP


\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($constraints);
Dies bringt uns zu folgendem Ergebnis: Bildschirmfoto - 26.09.2014 - 11:36:14 Liegt hier kein Logikfehler vor, hilft nur noch ein Blick in die SQL-Query die von Extbase tatsächlich gebaut wird.

SQL-Query debuggen

Früher konnte man in sysext/extbase/Classes/Persistence/Generic/Storage/Typo3DbBackend.php in der buildQuery() Funktion das Statement debuggen, das geht aber seit Typo3 6.2 nicht mehr. Daher habe ich eine Funktion geschrieben die ein QueryResult erfordert und dessen SQL-Query zurückgeliefert.

PHP


/**
* Debugs a SQL query from a QueryResult
*
* @param \TYPO3\CMS\Extbase\Persistence\Generic\QueryResult $queryResult
* @param boolean $explainOutput
* @return void
*/
public function debugQuery(\TYPO3\CMS\Extbase\Persistence\Generic\QueryResult $queryResult, $explainOutput = FALSE){
  $GLOBALS['TYPO3_DB']->debugOutput = 2;
  if($explainOutput){
    $GLOBALS['TYPO3_DB']->explainOutput = true;
  }
  $GLOBALS['TYPO3_DB']->store_lastBuiltQuery = true;
  $queryResult->toArray();
  DebuggerUtility::var_dump($GLOBALS['TYPO3_DB']->debug_lastBuiltQuery);

  $GLOBALS['TYPO3_DB']->store_lastBuiltQuery = false;
  $GLOBALS['TYPO3_DB']->explainOutput = false;
  $GLOBALS['TYPO3_DB']->debugOutput = false;
}
Aufgerufen wird sie im Controller:

PHP


$events = $this->eventRepository->findDemanded($demand, $limit);
$this->debugQuery($events);
Ergebnis: Bildschirmfoto - 26.09.2014 - 11:28:22 Der Trick dabei ist, das wenn $queryResult->toArray(); aufgerufen wird das SQL-Statement neu ausgeführt wird. Fröhliches debuggen.

Kommentare

Siehe auch https://www.typo3.net/forum/thematik/zeige/thema/125747/

Funktioniert in TYPO3 CMS 8.7 nicht mehr.

Danke für den Hinweis, ist gemacht.

[…] SQL-Queries Debuggen in Typo3 (blog.undkonsorten.com) […]

Hi,

könnt Ihr das ggf. korrigieren:

$GLOBALS['TYPO3_DB']->debugOuput = 2;

=>

$GLOBALS['TYPO3_DB']->debugOutput = 2;

es fehlt das "t". Zweimal siehe oben.

Noch eine Methode: einfach einen einfach Fehler produzieren mit beispielsweise $query->lessThan('start', time()) geändert zu $query->lessThan('start1', time());

Dazu das sqlDebug im Installtool auf 1 stellen. Dann wird der nicht funktionierende Query als debug ausgegeben.

Super - das hab ich gebraucht

für Extensions mit Namespaces muß in der Funktion debug Query \TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump... gesetzt werden

Das mit dem ersetzen kann eigentlich nicht sein.

Das evtl. andere Queries ausgegeben werden liegt daran, das Typo3 nur den letzten Query speichert. Hat der Mitarbeiter zum Beispiel einen MM-Beziehung zu Mitarbeitergruppen, dann wird der letzte Query sein eben diese Datensätze zu hohlen. Dies kann man durch eine @lazy Anotation im Model unterdrücken, dann werden Beziehungen nur aufgelöst wenn auch auf sie zugegriffen wird. Empfiehlt sich eigentlich meistens.

Sollte ein Query wie Thomas in hat erscheinen (INSERT INTO cf_extbase_object ) liegt das daran, das der letzte Query ein Eintrag in die Object Cache Tabelle von Extbase ist. Das kann umgangen werden in dem der Cache abgeschaltet wird, oder ein anderer benutzt wird Memcache, APC usw.

Super, danke schön!

Ich erhalte auch nur was anderes: 'SELECT sys_category.* FROM sys_category_record_mm LEFT JOIN sys_category ON...'

Aber erst nachdem diese Zeile ersetzt wurde:

DebuggerUtility::var_dump(...)

durch

\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump(...)

Top! Genau das, was ich gesucht habe, vielen Dank!

Also ich erhalte hier leider nur "INSERT INTO cf_extbase_object ..."


Kommentar schreiben

* Diese Felder sind erforderlich