Hi, habe da ein kleines Problem mit der Formulierung einer Query via Querybuilder.
Ich habe zwei Model-Objects die einer Parent-Page zugewiesen sind, die zwei Child-Pages mit je einem Content-Item besitzt, die jeweils eines der Model-Objects verarbeiten. Nun soll die Parent-Page eine Liste anzeigen, die auf die Unterseiten verlinkt, aber verschiedene Daten der Model-Objekte mit anzeigt.
Ich bekomme die Model-Objects und die uid's der Child-Pages über die pid raus. Da der JOIN ja alle Elemente kreuzweise verknüpft, muss ich das Ergebnis weiter einschränken. Das wollte ich über den Title machen, der sich von den Object-Models zu den Child-Pages nur durch eine angefügte Kennziffer unterscheidet.
Allerdings bekomme ich den LIKE in der WHERE-Klausel nicht hin, er liefert mir immer wieder ein empty Result. Bin mir sicher, dass mir da was fehlt, komme aber nicht drauf was und alle Beispiele beziehen sich auf hart verdrahtete Strings für den LIKE, nicht aber auf einen mit einem dynamischen Table-Field.
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tt_pages');
$result = $queryBuilder
->select('pages.uid AS target','tx_myext_domain_model_item.*')
->from('pages')
->leftjoin(
'pages',
'tx_myext_domain_model_item',
'tx_myext_domain_model_item',
$queryBuilder->expr()->eq('pages.pid',$queryBuilder->quoteIdentifier('tx_myext_domain_model_item.pid'))
)
->where(
$queryBuilder->expr()->eq('pages.pid',$queryBuilder->quoteIdentifier('tx_myext_domain_model_item.pid')),
$queryBuilder->expr()->like('pages.title',$queryBuilder->createNamedParameter('%'.quoteIdentifier('tx_myext_domain_model_item.title').'%'))
)
->execute()
->fetchAll();
Beispiel für Titles:
Object-Title: "Falsches Üben von Xylophonmusik quält jeden größeren Zwerg"
Child-Page-Title: "Falsches Üben von Xylophonmusik quält jeden größeren Zwerg : KZr0XY3Z"
🤖 KI-Antwort des Forumsboten · automatisch erstellt und von einer zweiten KI gegengeprüft, ohne Gewähr.
Das Problem ist der zweite Parameter von like(): Mit createNamedParameter() wird alles zu einem festen String. Verglichen wird also mit dem Text %tx_myext_domain_model_item.title%, nicht mit dem Inhalt der Spalte. (Außerdem fehlt vor quoteIdentifier das $queryBuilder->.)
like() quotet nur den Feldnamen. Der zweite Parameter wird unverändert ins SQL übernommen. Du kannst dort also einen SQL-Ausdruck übergeben, der den Spaltenwert mit dem Platzhalter verkettet:
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('pages');
// ergibt z. B. CONCAT(`tx_myext_domain_model_item`.`title`, ' : %')
$titlePattern = $queryBuilder->getConnection()->getDatabasePlatform()->getConcatExpression(
$queryBuilder->quoteIdentifier('tx_myext_domain_model_item.title'),
$queryBuilder->createNamedParameter(' : %')
);
$result = $queryBuilder
->select('pages.uid AS target', 'tx_myext_domain_model_item.*')
->from('pages')
->join(
'pages',
'tx_myext_domain_model_item',
'tx_myext_domain_model_item',
$queryBuilder->expr()->eq('pages.pid', $queryBuilder->quoteIdentifier('tx_myext_domain_model_item.pid'))
)
->where(
$queryBuilder->expr()->like('pages.title', $titlePattern)
)
->execute()
->fetchAll();
Hinweise:
getConcatExpression() kommt von Doctrine DBAL und erzeugt je nach Datenbank die passende Verkettung. Wenn du nur MySQL nutzt, geht auch direkt 'CONCAT(' . $queryBuilder->quoteIdentifier('tx_myext_domain_model_item.title') . ', ' . $queryBuilder->createNamedParameter(' : %') . ')'.
- Mit
' : %' passen nur Seiten, deren Titel mit dem Objekttitel plus „ : “ beginnt. Das ist genauer als %…%.
- Enthält ein Objekttitel selbst
% oder _, wirken die als Platzhalter.
- Das
eq() in der Join-Bedingung reicht, im where() brauchst du es nicht noch einmal. getQueryBuilderForTable() bekommt pages (eine Tabelle tt_pages gibt es nicht).
In aktuellen Versionen: execute()/fetchAll() heißen executeQuery()/fetchAllAssociative(), und seit TYPO3 13.1 gibt es $queryBuilder->expr()->concat(...). Auch dort wird nichts automatisch gequotet.
Doku: https://docs.typo3.org/m/typo3/reference-coreapi/9.5/en-us/ApiOverview/Database/ExpressionBuilder/Index.html
https://docs.typo3.org/c/typo3/cms-core/main/en-us/Changelog/13.1/Feature-103309-AddMoreExpressionMethodsToExpressionBuilder.html