mysqlfan: Suchabfrage funktioniert bei einem übergebenen POST-Wert nicht

Hallo!

Ich habe folgendes SQL-Problem:

Wenn ich einen Formular-Wert als POST-Variable übergebe, wird nur ein Wert ausgelesen, der andere ignoriert, obwohl eine Prüfabfrage eigentlich sagt, dass die Abfrage logisch formuliert sein müsste.

Ich stehe also auf dem Schlauch, warum die Abfrage nicht umgesetzt wird.

Zum besseren Verständnis hier der Codeauszug:

<td>  
<form action="http://localhost/db.php" class="tfsearch" method="post">  
  
<B><Font Color=white>Country:</font></b>  
<select name="country">  
<option value="%%%"></option>  
<option value="Afghanistan">Afghanistan</option>  
<option value="Albania">Albania</option>  
<option value="Algeria">Algeria</option>  
</select>  
  
  
<input type="hidden" name="action" value="book" />Exact Value  
<input type="text" name="exact" />  
  
<input type="hidden" name="action" value="book" />Partial Value  
<input type="text" name="partial" />  
  
<input type="hidden" name="action" value="book" />Other  
<input type="text" name="other" />  
<input type="submit" value="Suchen" />  
  
</form>  
</td>

Der Wert wird per POST-Variablen übergeben und lasse dann die SQL-Query machen:

case 'book':  
  
$result = $mysqli->query("SELECT * FROM model, company, number, type WHERE number.number = '{$_POST['exact']}' AND number.number LIKE '%{$_POST['partial']}%' AND number.numberid = model.numberid AND model.typeid = type.typeid AND number.companynumber = company.companynumber LIMIT 10");

So SOLLTE die Abfrage aussehen.

Entweder wird der Wert des Formularfeldes "exact" übergeben oder von "partial" - was auch so sein soll.

Das Problem ist: Bei exact wird es ausgegeben, bei partial nicht.

Gebe ich einen Wert ein, der 100%ig zu einem Treffer führt, also number.number = '{$_POST['exact']}' dann wird diese Abfrage korrekt ausgeführt.

Eine Prüfung, was überhaupt an Werten übergeben wird, mit

if ($_POST) {  
echo'<pre>', print_r($_POST),'<pre>'  
}

ergibt:

Array
(
[country] => %%%
[action] => book
[exact] => A12345
[partial] =>
[other] =>
)
1

Das ist auch so ganz in meinem Sinne.
Sprich: Wenn nach dem Begriff 'A12345' gesucht wird, soll nur dieser Treffer aufgeführt werden; partial und other bleiben frei.

Wenn ich aber jetzt im Formular-Feld partial 'A123' eingebe, dann müsste mindestens ebenfalls der Wert 'A12345' ausgegeben werden bzw. noch eine ganze Menge andere, die mit 'A123' anfangen.

Das passiert aber nicht.

Eine Prüfung hier ergibt:

Array
(
[country] => %%%
[action] => book
[exact] =>
[partial] => A123
[other] =>
)
1

Es ist doch eigentlich dasselbe in grün wie die Abfrage unter exact?!?
Statt partial und other bleiben hier eben die Felder exact und other frei.

Und es ist ja auch in der SQL-Abfrage als number.number LIKE '%{$_POST['partial']}%' formuliert, so dass es kein Problem hier geben dürfte, einen Wert, der mit 'A123' beginnt aufzufinden.

Wie gesagt, ich steh auf dem Schlauch.
Es muss irgendwie am SQL-Query liegen.
Findet wer den Fehler oder - falls hier irgendwas komplett falsch formuliert sein soll - könnte mir jemand den korrekten SQL-Query für eine = und eine LIKE-Abfrage bei Übergabe zweier Formularfeld-Variablen posten, bei der ein Feld freibleibt?

Für jede Hilfe schon mal allerbesten Dank im voraus!

  1. Hallo,

    was sagt var_dump($result)?

    Gruß

    jobo

    1. Hallo,

      was sagt var_dump($result)?

      quatsch, ich meinte den query-string. aber den packst du ja direkt darein. ist das mit den % da richtig so? keine ' . $_POST["blub"] . ' ???

      Gruß

      jobo

  2. Hallo,

    Array
    (
    [country] => %%%
    [action] => book
    [exact] =>
    [partial] => A123
    [other] =>
    )

    SELECT * FROM ... WHERE number.number = '' AND number.number LIKE '%A123%'

    Frage: Kann number.number gleichzeitig gleich '' UND wie %A123% sein?

    Du meinst number.number soll entweder gleich '' ODER wie %A123% sein.

    viele Grüße

    Axel

    1. Frage: Kann number.number gleichzeitig gleich '' UND wie %A123% sein?

      Ja, das ist die Frage, deren Lösung ich suche ;-) .

      Du meinst number.number soll entweder gleich '' ODER wie %A123% sein.

      Ja.

      Wenn number.number im Formularfeld mit dem Bezeichner 'exact' eingegeben wird, wird dazu auch der Treffer korrekt aufgeführt. Im Feld 'secondvalue' (vormals 'partial', da geschützter Bezeichner) und Feld 'other' bleibt auch frei.

      Mache ich dasselbe allerdings mit 'secondvalue' und lasse 'exact' und 'other' frei, dann wird nichts ausgegeben.

      Dabei ändert sich an der Gleichung doch eigentlich nichts?! Wenn's bei dem einen funktioniert, müsste es doch bei dem anderen auch so gehen.

      1. Hi!

        Frage: Kann number.number gleichzeitig gleich '' UND wie %A123% sein?
        Ja, das ist die Frage, deren Lösung ich suche ;-) .

        Und warum findest du darauf keine Antwort?

        Du meinst number.number soll entweder gleich '' ODER wie %A123% sein.
        Ja.

        Sag nicht einfach nur "Ja". Dieses "Ja" ist nämlich richtig. Du solltest dir nun überlegen, warum das richtig ist (abgesehen vom "entweder" in der Aussage).

        Wenn number.number im Formularfeld mit dem Bezeichner 'exact' eingegeben wird, wird dazu auch der Treffer korrekt aufgeführt. Im Feld 'secondvalue' (vormals 'partial', da geschützter Bezeichner) und Feld 'other' bleibt auch frei.
        Mache ich dasselbe allerdings mit 'secondvalue' und lasse 'exact' und 'other' frei, dann wird nichts ausgegeben.

        Und was für SQL-Abfragen resultieren daraus? Welches Ergebnis liefern die beiden verknüpften Bedingungen?

        Wenn number.number = '' nicht zutrifft (FALSE ergibt), weil in dem Feld etwas enthalten ist, dann werden weitere AND-Bedingungen gar nicht mehr ausgewertet, weil das Ergebnis bereits feststeht.

        x | y | AND
        ---+---+-----
         F | F |  F
         F | T |  F
         T | F |  F
         T | T |  T

        Wenn einer der beiden Operanden FALSE ergibt, ist das Ergebnis immer FALSE. Du bekommst nur dann ein TRUE (und damit einen gefundenen Datensatz), wenn beide Bedingungen zutreffen. Und kann number.number gleichzeitig leer und gefüllt sein? Und nun die ganze Überlegung nochmal mit OR. Anschließend solltest du, da du weitere Verknüpfungen in der Query hast, noch die Rangfolge der Operatoren beaachten.

        Lo!

        1. @dedlfix: Ich krieg die Formulierung irgendwie nicht hin. Bei

          $result = $mysqli->query("SELECT * FROM model, company, number, type WHERE number.number = '{$_POST['exact']}' OR number.number LIKE '%{$_POST['secondvalue']}%' AND number.numberid = model.numberid AND model.typeid = type.typeid AND number.companynumber = company.companynumber LIMIT 10");

          hängt er sich auf, obwohl LIMIT 10 angegeben war und auf den Datensätzen ein Index liegt.

          Ich glaube, ich lerne in dem Fall am meisten, wenn ich sehe, wie so etwas korrekt formuliert sein muss.

          Könntest du mir bitte ein solches Beispiel posten?

          Gruß
          mysqlfan

          1. Hi!

            Ich glaube, ich lerne in dem Fall am meisten, wenn ich sehe, wie so etwas korrekt formuliert sein muss.
            Könntest du mir bitte ein solches Beispiel posten?

            Wenn du immer noch ein Problem hast und es noch nicht mit https://forum.selfhtml.org/?t=200275&m=1349324 lösen konntest, dann zeig bitte das fertige SQL-Statement, nicht den Code, der es zusammenbaut. Und dann gab ich dir ja schon den Hinweis auf die Operatorenrangfolge. Ein AND bindet stärker als ein OR, wird also zuerst ausgewertet. Schreib doch Joins in der exliziten Schreibweise (Abschnitt Syntax). Dann kann man einerseits besser unterscheiden, was Join-Bedingung ist und was Auswahlkriterium ist, und andererseits kommen erstere nicht letzteren ins Gehege.

            Lo!

            1. moin,

              Schreib doch Joins in der exliziten Schreibweise (Abschnitt Syntax). Dann kann man einerseits besser unterscheiden, was Join-Bedingung ist und was Auswahlkriterium ist, und andererseits kommen erstere nicht letzteren ins Gehege.

              der hinweis wurde ihm schon mehrfach gegeben, ist aber offenbar beratungsresistent.....

              Ilja

  3. Hallo!

    Ich habe folgendes SQL-Problem:

    Der Wert wird per POST-Variablen übergeben und lasse dann die SQL-Query machen:

    case 'book':

    $result = $mysqli->query("SELECT * FROM model, company, number, type WHERE number.number = '{$_POST['exact']}' AND number.number LIKE '%{$_POST['partial']}%' AND number.numberid = model.numberid AND model.typeid = type.typeid AND number.companynumber = company.companynumber LIMIT 10");

    
    >   
    > Das Problem ist: Bei exact wird es ausgegeben, bei partial nicht.  
    >   
    > Für jede Hilfe schon mal allerbesten Dank im voraus!  
    >   
      
    hallo,  
    MySQL :: MySQL 5.1 Referenzhandbuch :: 13.1.5 CREATE TABLE ... col\_name [( length )] [ASC | DESC] reference\_definition : REFERENCES tbl\_name [(  
    index\_col\_name ,...) MATCH FULL | MATCH PARTIAL | MATCH SIMPLE] [ON DELETE ...  
    dev.mysql.com/doc/refman/5.1/de/create-table.html  
      
    d.h. partial ist "gesperrte bezeichnung"  
    (kann es im moment nicht besser bezeichnen ,es gibt besseren bzw. üblichen namen)  
    mfg
    
    1. d.h. partial ist "gesperrte bezeichnung"
      (kann es im moment nicht besser bezeichnen ,es gibt besseren bzw. üblichen namen) »» mfg

      --> Geändert in andere Bezeichnung. Hat aber leider vom Ergebnis her nichts gebracht.

      Erster übergebener Wert wird umgesetzt, zweiter nicht.

      1. Hi!

        d.h. partial ist "gesperrte bezeichnung"
        --> Geändert in andere Bezeichnung. Hat aber leider vom Ergebnis her nichts gebracht.

        Warum nicht? Hast du dir mal überlegt, ob der Wert für MySQL überhaupt eine Bedeutung hat oder ob der da gar nicht ankommt?

        Du betrachtest - wie so viele - den PHP-Code und nicht den relevanten SQL-Code, der letztlich beim MySQL-Server ankommt.

        Und den Kontextwechsel beachtest du auch nicht.

        Lo!

        1. SELECT * FROM model, company, number, type  
          WHERE number.number = 'A12345'  
          AND number.number LIKE '%%%'  
          AND number.numberid = model.numberid  
          AND model.typeid = type.typeid  
          AND number.companynumber = company.companynumber  
          LIMIT 5
          

          ==> Funktioniert!
          'A12345' wird ausgegeben.

          SELECT * FROM model, company, number, type  
          WHERE number.number = '%%%'  
          AND number.number LIKE 'A12345'  
          AND number.numberid = model.numberid  
          AND model.typeid = type.typeid  
          AND number.companynumber = company.companynumber  
          LIMIT 5
          

          ==> Funktioniert nicht!
          MySQL lieferte ein leeres Resultat zurück.

          Liegt es an dem grundsätzlichen Dilemma, dass ein exakter Wert zwar einem LIKE-Wert entsprechen kann, aber ein LIKE-Wert nicht einem Exakten?

          Ich ging bisher davon aus, dass die Erfüllung einer Bedingung ausreicht, um die Abfrage auszugeben?

          Wie muss die Abfrage korrekt formuliert sein?

          1. Hallo,

            SELECT * FROM model, company, number, type

            WHERE number.number = 'A12345'
            AND number.number LIKE '%%%'

            
            > ==> Funktioniert!  
            > 'A12345' wird ausgegeben.  
            
            Ja, denn der Feldinhalt kann durchaus gleich "A12345" UND wie "%%%" sein, denn wie "%%%" ist alles Mögliche ;-).  
            
            >   
            > ~~~sql
            
            SELECT * FROM model, company, number, type  
            
            > WHERE number.number = '%%%'  
            > AND number.number LIKE 'A12345'  
            > 
            
            

            ==> Funktioniert nicht!
            MySQL lieferte ein leeres Resultat zurück.

            Ja, denn _kein_ Feldinhalt kann gleich "%%%" UND wie "A12345" sein, denn wenn der Feldinhalt gleich "%%%" ist, dann stehen dort drei "%"-Zeichen drin und eben _nicht_ "A12345".

            Liegt es an dem grundsätzlichen Dilemma, dass ein exakter Wert zwar einem LIKE-Wert entsprechen kann, aber ein LIKE-Wert nicht einem Exakten?

            Nein.

            Ich ging bisher davon aus, dass die Erfüllung einer Bedingung ausreicht, um die Abfrage auszugeben?

            Nein, nicht bei UND-Verknüpfungen. Wozu, denkst Du, gibt es ODER-Verknüpfungen?

            Aber wenn ohnehin nur _entweder_ exact ODER partial gefüllt per POST zurückkommen, warum baust Du dann nicht je Fall per PHP exakt je ein SQL-Statement zusammen? Also wenn exact gefüllt zurückkommt, dann ...WHERE number.number = 'A1234' und wenn partial gefüllt zurückkommt, dann ...WHERE number.number LIKE '%A12%'.

            Und bitte beachte dedlfix' Hinweis auf die kontextgerechte Behandlung.

            viele Grüße

            Axel

            1. Hi!

              Aber wenn ohnehin nur _entweder_ exact ODER partial gefüllt per POST zurückkommen,

              Diesen Fall kann man nicht verhindern. Man kann lediglich dafür sorgen, dass er per Hand ausgefiltert wird. Besteht dazu aber die fachliche Notwendigkeit? Alternativ zur Filterung könnte dann wirklich ein exklusives Oder (XOR - also ein Entweder-Oder) verwenden.

              Lo!

    2. Moin!

      case 'book':

      $result = $mysqli->query("SELECT * FROM model, company, number, type WHERE number.number = '{$_POST['exact']}' AND number.number LIKE '%{$_POST['partial']}%' AND number.numberid = model.numberid AND model.typeid = type.typeid AND number.companynumber = company.companynumber LIMIT 10");

      
      >   
      > hallo,  
      > MySQL :: MySQL 5.1 Referenzhandbuch :: 13.1.5 CREATE TABLE ... col\_name [( length )] [ASC | DESC] reference\_definition : REFERENCES tbl\_name [(  
      > index\_col\_name ,...) MATCH FULL | MATCH PARTIAL | MATCH SIMPLE] [ON DELETE ...  
      > dev.mysql.com/doc/refman/5.1/de/create-table.html  
      >   
      > d.h. partial ist "gesperrte bezeichnung"  
      > (kann es im moment nicht besser bezeichnen ,es gibt besseren bzw. üblichen namen)  
        
        
      Das ist irrelevant, denn dieser Bezeichner wird ausschließlich im PHP-Land verwendet und gelangt nicht ins MySQL-Land. Und nur dort wäre er böse.  
        
      Entsprechend hätte MySQL, wenn es denn böse wäre, eine Fehlermeldung ausgegeben - aber es hat ja augenscheinlich funktioniert. Und wie zu erwarten: Das Ändern des Bezeichners hat nix verändert am Resultat.  
        
       - Sven Rautenberg