Prepared Statement schluckt Parameter als Variable aus Array nicht

Hallo Leute,

ich habe ein Problem und bin mit meinem Latein am Ende. Vielleicht übersehe ich einfach was, ich komme einfach nicht drauf.

Ich habe ein Array mit Artikel-IDs, die ich per POST an einen Plugin-Controller übergebe. Ich durchlaufe dieses Array und mache für jede Artikelnummer eine Datenbankabfrage. Hier setze ich die Artikel-ID in ein Prepared-Statement ein. Und es passiert gar nichts, es wird auch keine Fehlermeldung generiert. Ersetze ich die Value aus dem foreach händisch durch eine beliebige Artikelnummer, läuft die Abfrage durch.

Ich hatte das ganze Konstrukt vorher auch mit dem QueryBuilder umgesetzt und bin dann auf PDO umgeschwenkt, weil es nicht funktioniert hat - mit dem gleichen Ergebnis.

Hier der Code:

foreach($articleArray AS $article){
            
        //$article_id=14; SO FUNKTIONIERT ES
          $article_id=$article['listing_id']; //Es ist auch hier der Wert 14 vorhanden - habe auch schon mit intval() umgewandelt, bringt alles nichts
          
          //DAS FUNKTIONIERT IMMER, EGAL OB VALUE MANUELL ODER AUS ARRAY
          $article_data=Shopware()->Modules()->Articles()->sGetPromotionById('fix', 0, (int) $article['listing_id']);
  
          $sql = 'SELECT COUNT(id) AS set_number FROM s_articles_viison_setarticles WHERE setid=:articleId';

          $statement = $connection->prepare($sql);
          $statement->execute(['articleId' => $article_id]);
          $result = $statement->fetch();
                
          $set_article_count=$result['set_number'];
                               
}

 

Ich hoffe Jemand hat eine Idee, ich stehe echt auf dem Schlauch…

Wie holst du articleArray und was steht da drin?

1 „Gefällt mir“

Moin @mit3233‍,

ich sehe da so spontan erstmal keinen Fehler, habe aber auch nie derartige Probleme gehabt.
Ich kann mir höchstens vorstellen, dass unterhalb von $article[‚listing_id‘]; noch ein Array liegt, das du übersiehst.
Also sowas:

[
   ...
   'listing_id' => [
      0 => 14
   ]
]

Was mir aber durchaus auffällt, ist, dass du über ein Array iterierst und  jedes Mal eine einzelne Datenbankabfrage  losschickst, das ist extrem inperformant.
Stattdessen kannst du das auch mit einem einzigen Query lösen.
Ich habe da mal  blind  etwas runterprogrammiert, vielleicht hilft das bei dem falschen Verhalten und ist gleichzeitig deutlich performanter.
Da ich es blind runterprogrammiert habe, können sich da kleinere Fehler eingeschlichen haben. :wink:

// Hier müsstest du mal eben schauen, wie du in deinem Code an den DI Container kommst
// In einem Controller müsste das schon so out of the box funktionieren
$queryBuilder = $this->get('dbal_connection')->createQueryBuilder();
$productIds = array_column($articleArray, 'listing_id');

$counts = $queryBuilder->select('COUNT(setArticles.id)')
    ->from('s_articles_viison_setarticles', 'setArticles')
    ->where('setArticles.setid IN (:productIds)')
    ->groupBy('setArticles.setid')
    ->setParameter(':productIds', $productIds, \Doctrine\DBAL\Connection::PARAM_INT_ARRAY)
    ->execute()
    ->fetchColumn();

Magst du das einfach mal versuchen?

Gruß,
Patrick  Shopware

1 „Gefällt mir“

@Patrick Stahl schrieb:

Moin @mit3233‍,

ich sehe da so spontan erstmal keinen Fehler, habe aber auch nie derartige Probleme gehabt.

Was mir aber durchaus auffällt, ist, dass du über ein Array iterierst und  jedes Mal eine einzelne Datenbankabfrage  losschickst, das ist extrem inperformant.
Stattdessen kannst du das auch mit einem einzigen Query lösen.
Ich habe da mal  blind  etwas runterprogrammiert, vielleicht hilft das bei dem falschen Verhalten und ist gleichzeitig deutlich performanter.
Da ich es blind runterprogrammiert habe, können sich da kleinere Fehler eingeschlichen haben. :wink:
 

// Hier müsstest du mal eben schauen, wie du in deinem Code an den DI Container kommst
// In einem Controller müsste das schon so out of the box funktionieren
$queryBuilder = $this->get(‚dbal_connection‘)->createQueryBuilder();
$productIds = array_column($articleArray, ‚listing_id‘);

$counts = $queryBuilder->select(‚COUNT(setArticles.id)‘)
->from(‚s_articles_viison_setarticles‘, ‚setArticles‘)
->where(‚setArticles.setid IN (:productIds)‘)
->groupBy(‚setArticles.setid‘)
->setParameter(‚:productIds‘, $productIds, \Doctrine\DBAL\Connection::PARAM_INT_ARRAY)
->execute()
->fetchColumn();

Magst du das einfach mal versuchen?

Gruß,
Patrick  Shopware

Das Funktioniert, ich brauche es aber in dem foreach, weil dort noch mehr passiert. Bzw. brauche ich für jede Artikel-ID die Anzahl der verknüpften Sets.

"\Doctrine\DBAL\Connection::PARAM_INT_ARRAY"

Brauche ich so etwas vielleicht auch für meinen einzelnen Parameter?

In article[‘listing_id’] steht nur eine Zahl, z.B. 14. Die nutze ich ja z.B. auch bei dem

"$article_data=Shopware()->Modules()->Articles()->sGetPromotionById('fix', 0, (int) $article['listing_id']);"

@BestShopPossible schrieb:

Wie holst du articleArray und was steht da drin?

Das kommt via AJAX POST und enthält nur die Artikelnummern, kein mehrdimensionales Array…

Es funktioniert doch nicht. Er gibt mir für die Artikelnummer, die auch in den Sets ist, nichts aus.

Es muss an der Datenbanktabelle liegen! Ich habe zum Test mal die s_articles_details abgefragt und auch meine article_id genommen und das funktioniert:
 

$sql = 'SELECT id AS set_number FROM s_articles_details WHERE articleID=:articleId';

 $statement = $connection->prepare($sql);
 $statement->bindParam(':articleId', $article_id);
 $statement->execute();
 $result = $statement->fetch();
                
 $article_in_stock=$result['set_number'];

Die Tabelle von dem Pickware Plugin hat Verknüpfungen in andere Tabellen. Aber ich verstehe nicht warum es denn mit einem manuellen Wert geht und mit einem Wert aus dem Array nicht?

Ich habe noch weiter getestet. Ich kann zum Beispiel die s_articles_details abfragen, die s_articles_vote aber nicht. Da liefert SQL auch kein Ergebnis. Das ist doch eigenartig. Sobald ich bei der s_articles_vote wieder meine ID manuell eintrage, geht es. Jetzt habe ich eine ganz eigene Tabelle angelegt und da geht es auch nicht.

Woran könnte das liegen?

Ich habe es gelöst, kann geschlossen werden.

Das Problem war, dass die anderen IDs nicht in der DB waren und ich das result an eine Funktion übergeben habe. Diese hat einen Error rausgehauen und somit kam er nie bis zu der ID 14, die ich getestet habe.

Sorry für die Verwirrung, es lag nicht an der Tabelle.