MySQL-Datenbanksuche mit Arrays: Suchen nach exakter Übereinstimmung

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • MySQL-Datenbanksuche mit Arrays: Suchen nach exakter Übereinstimmung

    Hi!
    Ich habe eine Suchfunktion für eine MySQL-Datenbank geschrieben (bin Anfänger, habe mir das alles aus Foren, Tutorials und Büchern zusammengesucht), die soweit auch zufriedenstellend funktioniert.

    Allerdings gibt es ein unschönes Verhalten, welches ich abstellen möchte. Es gibt in der Tabelle der Datenbank eine Spalte mit dem Namen "ZG". Diese enthält Bezeichnungen wie z.B. RE und E. Wenn nun nach "E" gesucht wird dann werden auch alle Datensätze, die "RE" enthalten angezeigt. Ich möchte dies zukünftig verhindern. Allerdings sehe ich basierend auf dem derzeitigen code keine Möglichkeit dies möglichst elegant zu lösen. Zum Verständnis: Ich möchte nicht das komplette Skript neu schreiben (dazu fehlt mir die Zeit im Moment) sondern nur eine Bedingung einfügen dass wenn nach "ZG" gesucht wird, nicht die "LIKE" Bedingung zum Einsatz kommt sondern eben nach dem exakten Ausdruck (d.h. E und nicht RE) gesucht wird.
    Hier der bisherige Code:

    PHP-Code:
    <?php 
    //Verbindungsdaten für Datenbank
    $db_host "*";
    $db_user =  "*";
    $db_pass =  "*";
    $db_name =  "*";
     
    //Herstellen der Verbindung
    $verbindung mysqli_connect($db_host$db_user$db_pass$db_name);
     
    //Zeichensatz anpassen
    mysqli_query($verbindung,"SET NAMES 'utf8'");
    mysqli_query($verbindung,"SET CHARACTER SET 'utf8'");
    if(!
    $verbindung) {exit("Es konnte keine Verbindung zur Datenbank hergestellt werden. Bitte versuchen Sie es zu einem späteren Zeitpunkt erneut.");}
     
    //Einlesen der Suchparameter (wird nur benötigt für Ausgabe der Suchkriterien auf Ergebnisseite; bei Inaktivität werden die Suchbegriffe nicht auf Ergebnisseite angezeigt.)
    $suche1 mysqli_real_escape_string($verbindung,$_POST['datum']);    //Datum      
    $suche2 mysqli_real_escape_string($verbindung,$_POST['tfznr']);    //Triebfahrzeugnummer
    $suche3 mysqli_real_escape_string($verbindung,$_POST['tfzevu']);    //EVU des Triebfahrzeugs
    $suche4 mysqli_real_escape_string($verbindung,$_POST['tfzfarbe']);   //Farbe des Triebfahrzeugs
    $suche5 mysqli_real_escape_string($verbindung,$_POST['tfzname']);    //Name des Triebfahrzeugs
    $suche6 mysqli_real_escape_string($verbindung,$_POST['tfzmerkmal']);   //Werbung oder Tfz-Merkmal
    $suche7 mysqli_real_escape_string($verbindung,$_POST['tfztraktion']);   //Traktion Tfz
    $suche8 mysqli_real_escape_string($verbindung,$_POST['zugg']);    //Zuggattung
    $suche9 mysqli_real_escape_string($verbindung,$_POST['zugnr']);    //Zugnummer
    $suche10 mysqli_real_escape_string($verbindung,$_POST['zugn']);    //Zugname
    $suche11 mysqli_real_escape_string($verbindung,$_POST['zugstart']);   //Start
    $suche12 mysqli_real_escape_string($verbindung,$_POST['zugziel']);   //Ziel
    $suche13 mysqli_real_escape_string($verbindung,$_POST['anmerkungen']);  //Anmerkungen/Bemerkungen
     //Zusammenstellen der Suchanfrage 
    $mapPOST2DB = array( 
        
    //keys (Formular) => values (Datenbank)
     
    'datum' => 'Datum'
        
    'tfznr' => 'Triebfahrzeug'
        
    'tfzevu' => 'EVU'
        
    'tfzfarbe' => 'Farbe'
        
    'tfzname' => 'Taufname'
        
    'tfzmerkmal' => 'Werbung'
        
    'tfztraktion' => 'Traktion'
        
    'zugg' => 'ZG'
        
    'zugnr' => 'ZN'
        
    'zugn' => 'Zugname'
        
    'zugstart' => 'Start'
        
    'zugziel' => 'Ziel'
        
    'anmerkungen' => 'Anmerkungen'
    );
      if(
    strlen($_POST['datum']) == 4) {
        
    $datum $suche1
       
    // echo "Neues Datum ist ".$datum;
     
    } else {
        
    $datum2 $_POST['datum']; 
           
    $umbau strtotime($datum2); 
           
    //echo $umbau;
           
    $datum date('Y-m-d'$umbau);
        
    //echo "Datum ist ".$datum;
       
    }
     
    /*$datum2 = $_POST['datum']; 
    $umbau = date_create_from_format('j-M-Y',$datum2); 
    echo $umbau;
    $datum = date($umbau,'Y-m-d');
    echo "Datum ist ".$datum;*/
     /*$datum2 = $_POST['datum'];
    $umbau = DateTime::createFromFormat('Y-M-j', $datum2); 
    $datum = $date->format('d.m.Y'); */ 
     
    // Jede Teilabfrage lautet LIKE '% ... %', aber vielleicht will man das ja mal ändern...  
    // Wird sprintf() benutzt, müssen Prozentzeichen doppelt geschrieben werden, um sie in den resultierenden String zu bekommen 
    $sqlPattern "%s LIKE '%%%s%%'"
    // Teilabfragen in Array ablegen, hier: array initialisieren 
    $conditions = array(); 
    // Sicherstellen, dass alle Felder berücksichtigt werden (jedes Feld könnte vorkommen)
    foreach ($mapPOST2DB as $keyPOST => $keyDB) {
        
    $_POST['datum'] = $datum
     if(
    $_POST['datum'] === "1970-01-01") {
        
    $_POST['datum'] = "";
        }
      
    // Gibt es den Schlüssel im POST? 
        
    if (isset($_POST$keyPOST ]) && ($_POST$keyPOST ]) != "") { 
            
    // Wert ist vorhanden, baue eine Teilabfrage und lege sie ins Array. 
      
    $conditions[] = sprintf($sqlPattern$keyDBmysqli_real_escape_string($verbindung$_POST$keyPOST ])); 
        } else {}  
    }
     
    //Prüfen, ob mindestens ein Feld ausgefüllt wurde. Falls nein -> $conditions leer, $test = 0 < 1 => Abbruch
    $test count($conditions);
    if(
    $test 1) {exit ("Bitte mindestens einen Suchbegriff eingeben!");}
     
    //Kombinieren der Arrayelemente zum String, der an Datenbank übergeben wird
    $where implode(' AND '$conditions); 
     
    //Zusammenstellen des Endstrings für Übergabe an Datenbank
    $ergebnis "SELECT DATE_FORMAT(Datum,'%d.%m.%Y') AS Datum, Triebfahrzeug, EVU, Farbe, Taufname, Werbung, Traktion, ZG, ZN, Zugname, Start, Ziel, Anmerkungen FROM zugdatenbank WHERE $where LIMIT 500";
     
    //Query zusammenstellen und abschicken
    $i 1;                                              //Zähler für dynamischen Tabellenaufbau initiieren 
    $res mysqli_query($verbindung,$ergebnis);
    //-------------------------------------------------------------------------------------------------------------------
    //Ab hier Beginn der Ausgabe der Ergebnisse
    //-------------------------------------------------------------------------------------------------------------------   
       
    if(mysqli_num_rows($res) < 1) {                            //Prüfen, ob Datensätze gefunden wurden
      
    echo "Es wurden keine Datensätze gefunden!";
      
    /*print '<pre>'; 
         print $res; 
         print '</pre>';*/
      //trigger_error('Datenbankanfrage schlug fehl: '.mysqli_error(), E_USER_ERROR); 
       
    }
       if(
    mysqli_num_rows($res) === 500) {
       echo 
    "<strong>Es wird nur eine Auswahl an Datensätzen angezeigt, da mehr als 500 zutreffende Einträge vorhanden sind. Bitte verfeinern Sie ggf. Ihre Suche durch Eingabe zusätzlicher oder anderer Kriterien.</strong><br>";
       }    
       if(
    mysqli_num_rows($res) > 0) {                           //Datensätze wurden gefunden; Ausgabe
         
    $zeilen mysqli_num_rows($res);
      
    $spalten mysqli_fetch_fields($res);
      echo 
    "Es wurden $zeilen Datensätze zu Ihrer Suchanfrage gefunden.<br><br>"
      echo 
    "<table class=ausgabe width=1000>";
      echo 
    "<tr>\n";
      echo 
    "<th align=left width=5>Datum</th>";
      echo 
    "<th align=left width=8>Triebfahrzeug</th>";
      echo 
    "<th align=left width=4>EVU</th>";
      echo 
    "<th align=left width=2>Farbe</th>";
      echo 
    "<th align=left width=5>Taufname</th>";
      echo 
    "<th align=left width=14>Werbung</th>";
      echo 
    "<th align=left width=3>Traktion</th>";
      echo 
    "<th align=left width=1>ZG</th>";
      echo 
    "<th align=left width=2>ZN</th>";
      echo 
    "<th align=left width=7>Zugname</th>";
      echo 
    "<th align=left width=16>Start</th>";
      echo 
    "<th align=left width=16>Ziel</th>";
      echo 
    "<th align=left width=14>Anmerkungen</th>";
      while(
    $row mysqli_fetch_assoc($res)):
      echo 
    '<tr',($i%2==0?' style="background-color:#CCCCCC;"':''),'>'."\r\n";
         echo 
    '<td width=7>'.$row['Datum'].'</td>'."\r\n"
      echo 
    '<td width=8>'.$row['Triebfahrzeug'].'</td>'."\r\n"
      echo 
    '<td width=4>'.$row['EVU'].'</td>'."\r\n"
      echo 
    '<td width=4>'.$row['Farbe'].'</td>'."\r\n"
      echo 
    '<td width=10>'.$row['Taufname'].'</td>'."\r\n"
      echo 
    '<td width=14>'.$row['Werbung'].'</td>'."\r\n"
      echo 
    '<td width=6>'.$row['Traktion'].'</td>'."\r\n"
      echo 
    '<td width=3>'.$row['ZG'].'</td>'."\r\n"
      echo 
    '<td width=5>'.$row['ZN'].'</td>'."\r\n"
      echo 
    '<td width=8>'.$row['Zugname'].'</td>'."\r\n"
      echo 
    '<td width=9>'.$row['Start'].'</td>'."\r\n"
      echo 
    '<td width=8>'.$row['Ziel'].'</td>'."\r\n"
      echo 
    '<td width=14>'.$row['Anmerkungen'].'</td>'."\r\n"
      echo 
    '</tr>'."\r\n";
      
    $i++;                                          //Zähler für dynamischen Tabellenaufbau fortsetzen
        /*echo $row['Datum'];
           echo $row['Triebfahrzeug'];
        echo $row['EVU'];
        echo $row['Farbe'];
           echo $row['Taufname'];
           echo $row['Werbung'];
           echo $row['Traktion'];
           echo $row['ZG'];
           echo $row['ZN'];
           echo $row['Zugname'];
           echo $row['Start'];
        echo $row['Ziel'];
        echo $row['Anmerkungen'];*/
      
    endwhile;
      echo 
    "</table>\n";
       }  
    ?>
    Ich müsste je eigentlich nur festlegen, dass bei einer Suche in ZG nicht mit "LIKE" gesucht werden soll sondern eben nach einer eindeutigen Übereinstimmung. D.h. die Wildcards müssten weg. allerdings ist mir nicht ganz klar wie ich das mit meinem bisherigen Skript umsetzen kann und hoffe hier auf ein wenig Unterstützung.

    Veilen Danke schon mal !

  • #2
    Hallo,

    damit für das DB Feld ZG keine Like Abfrage benutzt wird, erstelle zunächst das neue Pattern:
    Code:
    $sqlPattern = "%s LIKE '%%%s%%'";
    $sqlPatternZG = "%s = '%s'";
    Dann prüfe einfach bevor Du das conditions Array füllst, welches Pattern benutzt werden soll:
    Code:
    [COLOR=#000000][COLOR=#FF9900]// Gibt es den Schlüssel im POST? 
        [/COLOR][COLOR=#006600]if (isset([/COLOR][COLOR=#0000CC]$_POST[/COLOR][COLOR=#006600][ [/COLOR][COLOR=#0000CC]$keyPOST [/COLOR][COLOR=#006600]]) && ([/COLOR][COLOR=#0000CC]$_POST[/COLOR][COLOR=#006600][ [/COLOR][COLOR=#0000CC]$keyPOST [/COLOR][COLOR=#006600]]) != [/COLOR][COLOR=#CC0000]""[/COLOR][COLOR=#006600]) { 
          if($keyPOST !='zugg')[/COLOR][COLOR=#0000CC]$conditions[/COLOR][COLOR=#006600][] = [/COLOR][COLOR=#0000CC]sprintf[/COLOR][COLOR=#006600]([/COLOR][COLOR=#0000CC]$sqlPattern[/COLOR][COLOR=#006600], [/COLOR][COLOR=#0000CC]$keyDB[/COLOR][COLOR=#006600], [/COLOR][COLOR=#0000CC]mysqli_real_escape_string[/COLOR][COLOR=#006600]([/COLOR][COLOR=#0000CC]$verbindung[/COLOR][COLOR=#006600], [/COLOR][COLOR=#0000CC]$_POST[/COLOR][COLOR=#006600][ [/COLOR][COLOR=#0000CC]$keyPOST [/COLOR][COLOR=#006600]])); 
          else [/COLOR][/COLOR][COLOR=#000000][COLOR=#006600][COLOR=#000000][COLOR=#0000CC]$conditions[/COLOR][COLOR=#006600][] = [/COLOR][COLOR=#0000CC]sprintf[/COLOR][COLOR=#006600]([/COLOR][COLOR=#0000CC]$sqlPatternZG[/COLOR][COLOR=#006600], [/COLOR][COLOR=#0000CC]$keyDB[/COLOR][COLOR=#006600], [/COLOR][COLOR=#0000CC]mysqli_real_escape_string[/COLOR][COLOR=#006600]([/COLOR][COLOR=#0000CC]$verbindung[/COLOR][COLOR=#006600], [/COLOR][COLOR=#0000CC]$_POST[/COLOR][COLOR=#006600][ [/COLOR][COLOR=#0000CC]$keyPOST [/COLOR][COLOR=#006600]]));[/COLOR][/COLOR][/COLOR][/COLOR][B][COLOR=#000000][COLOR=#006600][COLOR=#000000][COLOR=#006600]
     [/COLOR][/COLOR]   [/COLOR][/COLOR][/B][COLOR=#000000][COLOR=#006600]} else {}  [/COLOR][/COLOR]
    LG
    Markus

    Kommentar


    • #3
      Hi!
      Ich habe den abfrage-Teil jetzt umgeschrieben:

      PHP-Code:
       // Gibt es den Schlüssel im POST? 
      if ($suche[$keyPOST] != "") {
      if (
      $keyPOST == 'zugg') {
      $sqlPattern "%s = '%%%s%%'";
      $conditions[] = sprintf($sqlPattern$keyDB$suche[$keyPOST]);
      } else {
      $conditions[] = sprintf($sqlPattern$keyDB$suche[$keyPOST]);
      }
      }
      //...
      //Kombinieren der Arrayelemente zum String, der an Datenbank übergeben wird
      $where implode(' AND '$conditions); 
      //...
      $ergebnis "SELECT DATE_FORMAT(Datum,'%d.%m.%Y') AS ".implode(",",$mapPOST2DB)." FROM zugdatenbank WHERE $where LIMIT 500"
      Wenn ich jetzt nach "E" im Feld "ZG" suche erhalte ich die Meldung daß keine Datensätze gefunden wurden . Bei der Suche in jedem anderen Feld funktioniert alles so wies soll . Sobald ich aber ein beliebiges Feld mit "ZG " kombiniere kommt immer die Meldung daß keine Datensätze existieren.

      EDIT: Hat sich erledigt, ich habe den Fehler gefunden . Ich hatte das Pattern für die Suche mit "=" nicht angepasst sodass er nach einer exakten Übereinstimmung mit Platzhaltern gesucht hat.

      PHP-Code:
      $sqlPatternZG "%s = '%%%s%%'"
      nach
      PHP-Code:
      $sqlPatternZG "%s = '%s'"
      Zuletzt geändert von tgb14; 26.01.2014, 19:58.

      Kommentar

      Lädt...
      X