
Minderung der Unfähigkeit, Spaltennamen in Drupal-Dynamischen Abfragen zu entkommen
Durch die Arbeit in einer Drupal-Agentur machen Sie viel Drupal-Entwicklung und stoßen auf verschiedene Probleme. Kürzlich bei einer Migration zu Drupal stieß ich auf ein neues Problem mit der Drupal-Datenbankabstraktionsschicht. Es stellt sich heraus, dass dynamische Drupal-Select-Abfragen die Spaltennamen nicht escapen.
Dieses Problem betrifft nicht jeden Datenbanktyp, kann jedoch definitiv problematisch sein, wenn es um MySQL geht
$query = Database::getConnection('default', 'legacy') ->select('prod_group', 'pg') ->fields('pg', array('porductid, 'active', 'order'));
wird die folgende Abfrage erstellen:
SELECT pg.productid AS productid, pg.active AS active, pg.order AS order FROM {prod_group} pg;
Uns fehlen die `` um die Felder und in diesem Szenario hatten wir einen sehr unglücklichen Spaltennamen "order", der ein reserviertes Schlüsselwort in MySQL ist, das verwendet wird, um Ergebnisse zu sortieren (ORDER BY). So interpretiert MySQL die Abfrage, die daher falsch strukturiert ist und einen Fehler auslöst.
SQLSTATE[42000]: Syntaxfehler oder Zugriffsverletzung: 1064 Sie haben einen Fehler in Ihrer SQL-Syntax;
Wir sollten eine Abfrage mit mit Backticks escapeten Tabellennamen erstellen:
SELECT pg.productid AS `productid`, pg.active AS `active`, pg.order AS `order` FROM {prod_group} pg;
aber Drupal unterstützt dies nicht in dynamischen Abfragen, die die einzigen sind, die vom Migrationsmodul unterstützt werden.
Lösung - Feldaliase
Drupal unterstützt Aliase. Sie können dies sogar oben sehen "pg.order AS order" ist eine Abfrage, die das Order-Feld automatisch mit einem eingeschränkten Namen aliasiert.
Aber wir können diese Aliase automatisch mit SelectQueryInterface::addField setzen.
$query = Database::getConnection('default', 'legacy') ->select('prod_group', 'pg') ->fields('pg', array('groupid', 'active')) ->addField('pg', 'order', 'escaped_order');
Dies gibt uns eine Abfrage ohne ein eingeschränktes Schlüsselwort:
SELECT pg.productid AS productid, pg.active AS active, pg.order AS escaped_order FROM {prod_group} pg;.
Dies löst das Problem. Denken Sie nur daran, dass bei der Abfrage Ihrer Ergebnisse das order als escaped_order bezeichnet wird.