Matthias Apsel: prepared statement mit or bei zunächst unbekannter Anzahl von Bedingungen

Hallo alle,

SELECT `row` FROM `table` WHERE `foo` = value1 OR `foo` = value2;

Obiges statement soll per prepared statement erzeugt werden. Zum Zeitpunkt der Programmierung weiß ich nicht, wieviele Bedingungen verknüpft werden müssen.

Wie stellt man das am besten an?

Bis demnächst
Matthias

--
Pantoffeltierchen haben keine Hobbys.
¯\_(ツ)_/¯

akzeptierte Antworten

  1. Hallo Matthias,

    SELECT `row` FROM `table` WHERE `foo` = value1 OR `foo` = value2;
    

    Obiges statement soll per prepared statement erzeugt werden. Zum Zeitpunkt der Programmierung weiß ich nicht, wieviele Bedingungen verknüpft werden müssen.

    Wie stellt man das am besten an?

    Keine Ahnung ob das so am Besten ist, ich behelfe mir bei so was meist indem ich einen möglichen appendix erzeuge und einbinde wenn vorhanden. Dabei entweder direkt in einer Schleife $appendx .= $wheres; oder bevorzugt das erst mal als Array speichern und dann mit implode wieder freigebe, also $appendx[]= $wheres;

    Somit also dann: $sqlx = "SELECT row FROM table WHERE foo = value1 $wheres";

    Gruss
    Henry

    --
    Meine Meinung zu DSGVO & Co:
    „Principiis obsta. Sero medicina parata, cum mala per longas convaluere moras.“
    1. Würde ich auch so machen. Jedoch nur unter der Voraussetzung daß es eine Funktion zum Quoten gibt. Was zu prüfen wäre. MFG

  2. Hi,

    SELECT `row` FROM `table` WHERE `foo` = value1 OR `foo` = value2;
    

    also:

    SELECT `row` FROM `table` WHERE `foo` IN (value1, value2);
    

    Kann pdo mit einem Array als Parameter umgehen? Dann könnte man

    SELECT `row` FROM `table` WHERE `foo` IN (?);
    

    schreiben und das ? von pdo durch das Array ersetzen lassen.

    cu,
    Andreas a/k/a MudGuard

    1. Hallo MudGuard,

      und das ? von pdo durch das Array ersetzen lassen.

      Und ich kann einfach so das Array übergeben?

      $stmt -> bindParam (1, $array);
      // bzw.
      $stmt -> bindParam(':values', $array);
      

      Bis demnächst
      Matthias

      --
      Pantoffeltierchen haben keine Hobbys.
      ¯\_(ツ)_/¯
      1. Hi,

        Und ich kann einfach so das Array übergeben?

        Ich weiß es nicht - ich benutze kein pdo. Daher ja auch meine Formulierung als Frage:

        Kann pdo mit einem Array als Parameter umgehen? Dann könnte man

        Es war eine Idee, wie es evtl. machbar sein könnte; das war kein "das geht so!"!

        cu,
        Andreas a/k/a MudGuard

        1. Hello,

          Und ich kann einfach so das Array übergeben?

          Ich weiß es nicht - ich benutze kein pdo. Daher ja auch meine Formulierung als Frage:

          Kann pdo mit einem Array als Parameter umgehen? Dann könnte man

          Es war eine Idee, wie es evtl. machbar sein könnte; das war kein "das geht so!"!

          Die Frage haben sich Andere auch schon gestellt.

          Glück Auf
          Tom vom Berg

          --
          Es gibt nichts Gutes, außer man tut es!
          Das Leben selbst ist der Sinn.
        2. Hallo MudGuard,

          Kann pdo mit einem Array als Parameter umgehen?

          Offensichtlich nicht: Notice: Array to string conversion in C:\….php on line 5

          Bis demnächst
          Matthias

          --
          Pantoffeltierchen haben keine Hobbys.
          ¯\_(ツ)_/¯
  3. Tach!

    SELECT `row` FROM `table` WHERE `foo` = value1 OR `foo` = value2;
    

    Obiges statement soll per prepared statement erzeugt werden. Zum Zeitpunkt der Programmierung weiß ich nicht, wieviele Bedingungen verknüpft werden müssen.

    Wie stellt man das am besten an?

    Mit einem Gemisch aus Stringverknüpfung und Prepared Statement. Es gibt keine Dynamik in Prepared Statements. Wenn sie unterschiedlich lang sein sollen, müssen sie in der jeweiligen Länge für das DBMS generiert werden.

    dedlfix.

    1. Hallo dedlfix,

      weiß der Geier, wer auf den blöden Gedanken gekommen ist, dass der Inhalt einer IN-Klausel nicht durch ein Array geliefert werden darf. Generationen von SQL Entwicklern fluchen darüber. Bzw. erzeugen Temp-Tables in der Temp-DB, um dagegen zu joinen.

      Dann schon lieber die OR-Klauseln dynamisch ins SQL schieben.

      Je nach DBMS und DB-Statistiken kann eine OR-Bedingung aber dazu führen, dass kein direkter Indexzugriff mehr gemacht wird (sofern foo denn im Index steht), sondern ein Table-Scan bzw. Index-Scan. Das muss man per EXPLAIN erforschen. Je nach Table-Größe und Anzahl von Werten kann ein eigener SELECT pro Wert besser sein als ein OR. Zumindest haben mir das unser DB-Admins früher mal so gepredigt.

      Rolf

      --
      sumpsi - posui - clusi
      1. Hallo Rolf B,

        Je nach Table-Größe und Anzahl von Werten kann ein eigener SELECT pro Wert besser sein als ein OR.

        Da bin ich aber froh, dass ich nur ein Datenbänklein habe.

        Bis demnächst
        Matthias

        --
        Pantoffeltierchen haben keine Hobbys.
        ¯\_(ツ)_/¯
      2. Hallo

        weiß der Geier, wer auf den blöden Gedanken gekommen ist, dass der Inhalt einer IN-Klausel nicht durch ein Array geliefert werden darf. Generationen von SQL Entwicklern fluchen darüber. Bzw. erzeugen Temp-Tables in der Temp-DB, um dagegen zu joinen.

        Da wir hier von PHP sprechen, sollte es doch eine simple Übung sein, das Array vor seiner Nutzung im Statement per join(", ", $array) zum String umzuwandeln, oder?

        Tschö, Auge

        --
        Ein echtes Alchimistenlabor musste voll mit Glasgefäßen sein, die so aussahen, als wären sie beim öffentlichen Schluckaufwettbewerb der Glasbläsergilde entstanden.
        Hohle Köpfe von Terry Pratchett
        1. Hallo Auge,

          schematisch ja, aber in der Praxis ist es so einfach nicht. Du müsstest dann schon den Kontextwechsel selbst durchführen (sprich: die Array-Einträge Stück für Stück mit real_escape behandeln, es sei denn, du hast vorher bspw. sicher gestellt dass es Zahlen sind).

          Matthias' Plan war, ein prepared statement zu verwenden, dafür muss er die benötigte Menge von ? in die Klammern setzen und dann einen eigenen parameter bind pro Array-Eintrag durchführen. Einfacher ist das sicherlich nicht.

          Rolf

          --
          sumpsi - posui - clusi
          1. Hallo

            schematisch ja, aber in der Praxis ist es so einfach nicht. Du müsstest dann schon den Kontextwechsel selbst durchführen (sprich: die Array-Einträge Stück für Stück mit real_escape behandeln …

            Ah ja.

            … es sei denn, du hast vorher bspw. sicher gestellt dass es Zahlen sind).

            Das wird sich im einen Fall einfach erledigen lassen, im anderen so überhaupt nicht.

            Matthias' Plan war, ein prepared statement zu verwenden, dafür muss er die benötigte Menge von ? in die Klammern setzen und dann einen eigenen parameter bind pro Array-Eintrag durchführen. Einfacher ist das sicherlich nicht.

            Das heißt also, das Array durchzuzählen und den String des Statements, egal ob mit IN() oder OR-„Abschnitten“, entsprechend aufzufüllen, wenn ich es richtig verstehe. Elegant ist anders.

            Tschö, Auge

            --
            Ein echtes Alchimistenlabor musste voll mit Glasgefäßen sein, die so aussahen, als wären sie beim öffentlichen Schluckaufwettbewerb der Glasbläsergilde entstanden.
            Hohle Köpfe von Terry Pratchett
          2. Tach!

            Matthias' Plan war, ein prepared statement zu verwenden, dafür muss er die benötigte Menge von ? in die Klammern setzen und dann einen eigenen parameter bind pro Array-Eintrag durchführen. Einfacher ist das sicherlich nicht.

            PDO macht es dem Verwender einfach. Da braucht man nicht einzeln zu binden, sondern kann gleich nach dem Prepare das Execute mit einem Array an Werten aufrufen.

            dedlfix.

            1. Hallo dedlfix,

              guter Hinweis, dass dieses Array nicht assoziativ sein muss. Da habe ich mal wieder was gelernt.

              Rolf

              --
              sumpsi - posui - clusi