alpman: SELECT schlägt fehl

Hallo,

Ich habe in meiner MySQL-Tabelle (5.0.2) folgender Einträge:

+----+-------------------------+
| id | name                    |
+----+-------------------------+
| 35 | SSSJPII - Omaha Special |
| 52 | \n\r"'              |
+----+-------------------------+

(id 52 habe ich mit mysqli_real_escape_string for dem Einfügen bearbeitet.)

Die Anweisung

SELECT name FROM game WHERE name = '\n\r"'';

liefert mir jedoch kein Ergebnis. Was läuft denn falsch?

Viele Grüße,

Stefan

  1. Die Anweisung

    SELECT name FROM game WHERE name = '\n\r"'';

    Du hast ja auch zwei Hochkommatas am Ende. Das erste davon schliesst ja schon den String ab.

  2. hi,

    | 52 | \n\r"'              |

    Die Anweisung
    SELECT name FROM game WHERE name = '\n\r"'';
    liefert mir jedoch kein Ergebnis. Was läuft denn falsch?

    Du hast den Wert nicht korrekt maskiert.

    Der Slash vor dem Hochkommata maskiert dieses - du willst den Slash aber gar nicht zum maskieren nutzen, sondern er soll Teil der Daten sein.

    \n\r"\'

    Wenn du die Daten aus einem PHP-Script heraus einfügst, verwendest du doch hoffentlich mysql_real_escape_string()?

    gruß,
    wahsaga

    --
    /voodoo.css:
    #GeorgeWBush { position:absolute; bottom:-6ft; }
    1. Hallöchen,

      Der Slash vor dem Hochkommata maskiert dieses - du willst den Slash aber gar nicht zum maskieren nutzen, sondern er soll Teil der Daten sein.

      \n\r"\'

      Wenn du die Daten aus einem PHP-Script heraus einfügst, verwendest du doch hoffentlich mysql_real_escape_string()?

      Ich habe ein Eingabefeld, in das ich \n\r"' eingetragen habe. Ich verwende keinen Slash, der Teil der Daten sein soll. Vor dem Einfügen in die Datenbank habe ich mysqli_real_escape_string() verwendet.

      Nachvollzogen werden kann das testweise auf der Seite http://www.kendo-dortmund.de/test.php.

      Einfach mal \n\r"' eingeben und den Knopf drücken. Es erscheint dann \n\r"' .

      Viele Grüße,

      Stefan

      1. echo $begrüßung;

        Einfach mal \n\r"' eingeben und den Knopf drücken. Es erscheint dann \n\r"' .

        Sind auf dem System vielleicht die Magic Quotes eingeschaltet? Siehe dazu in der phpinfo-Ausgabe den Wert magic_quotes_gpc an. Da du selbst deine SQL-Befehlswerte maskierst kannst du die Magic Quotes ausschalten oder ihre Wirkung mit dem dort angegebenen Code-Stück generell rückgängig machen.

        Noch ein Tipp: Du verwendest mysqli. Diese Funktionen bieten ein Feature namens Prepared Statements. Damit kann man seine SQL-Statements mit Platzhaltern erstellen und übergibt die einzusetzenden Werte getrennt. Um die ordnungsgemäße Übertragung kümmert sich dann mysqli selbst und die händische Maskierung kann man sich schenken.

        echo "$verabschiedung $name";

        1. Hallo zusammen,

          Nochmal zum Mitschreiben:

          Magic Quotes sind aus. Was soll eurer Meinung in der Datenbank stehen, wenn man \n\r"' oder meinetwegen auch "Texas Hold'em" der Funktion mysqli_real_escape_string() übergibt und das Ergebnis wiederum an eine INSERT-Anweisung? Vielleicht habe ich ja auch etwas Grundsätzliches nicht oder falsch verstanden.

          Wenn ich Prepared Statements verwende, muss ich Werte nicht escapen?

          Viele Grüße,

          Stefan

          1. Moin!

            Was soll eurer Meinung in der Datenbank stehen, wenn man \n\r"' oder meinetwegen auch "Texas Hold'em" der Funktion mysqli_real_escape_string() übergibt

            In einfachen oder doppelten Hochkommas? Oder ist \n bzw. \r gar als deine hier gebrauchte Umschreibung für die nicht sichtbar darstellbaren Zeichen ASCII-Code 10 und ASCII-Code 13 zu verstehen

            mysqli_real_escape_string() wird aus dem Anführungszeichen ' die Kombination ' machen, das " bleibt unverändert, genauso die ASCII-Zeichen 10 und 13. Ein Backslash hingegen würde verdoppelt: \.

            und das Ergebnis wiederum an eine INSERT-Anweisung? Vielleicht habe ich ja auch etwas Grundsätzliches nicht oder falsch verstanden.

            Wenn ich Prepared Statements verwende, muss ich Werte nicht escapen?

            Nein, das erledigt das Prepared Statement für dich, weil es intern den SQL-Query zusammensetzt. Du hast zwei getrennte Strings, einmal das SQL, und dann einen (oder mehrere) String mit den Daten. Alle Zeichen darin sind pure Daten, es gibt keine Doppelbedeutung von gewissen Zeichen, also mußt du dich bei diesem String um keine Sonderbehandlung (Escaping) kümmern.

            - Sven Rautenberg

            --
            "Love your nation - respect the others."
      2. hi,

        Ich habe ein Eingabefeld, in das ich \n\r"' eingetragen habe. Ich verwende keinen Slash, der Teil der Daten sein soll.

        Wenn du \n\r"' manuell in ein Eingabefeld eingibst, dann enthält dies _zwei_ Backslashes, die Teil der Daten sein sollen.

        gruß,
        wahsaga

        --
        /voodoo.css:
        #GeorgeWBush { position:absolute; bottom:-6ft; }
  3. Moin!

    Ich habe in meiner MySQL-Tabelle (5.0.2) folgender Einträge:

    +----+-------------------------+
    | id | name                    |
    +----+-------------------------+
    | 35 | SSSJPII - Omaha Special |
    | 52 | \n\r"'              |
    +----+-------------------------+

    (id 52 habe ich mit mysqli_real_escape_string for dem Einfügen bearbeitet.)

    Was bedeutet das effektiv? Steht der obige String so, wie hier ausgegeben, in der Datenbank drin, oder wurde er durch mysqli_real_escape_string() so generiert, bevor er ins SQL-Statement kam?

    Die Anweisung

    SELECT name FROM game WHERE name = '\n\r"'';

    liefert mir jedoch kein Ergebnis. Was läuft denn falsch?

    Du kannst die obige Anweisung ja gar nicht so direkt in PHP eingeben - du mußt sie immer irgendwie als String in PHP integrieren. Da ich deinen PHP-Code aber nicht kenne, kann ich dir die Fallstricke nicht zeigen, in denen du dich verständnismäßig gerade verfangen hast.

    Da du innerhalb von SQL einfache Hochkommas verwendest, ist es schlau, als Stringbegrenzer für den Gesamtstring doppelte Hochkommas zu benutzen. Das wiederum führt dazu, dass gewisse Zeichen innerhalb des Strings Sonderbedeutung erhalten!

    Und diese Sonderbedeutung pfuscht dir hier ins Handwerk. Der doppelte Backslash im Quelltext wird vom PHP-Parser zum einfachen Backslash, und ein Backslash vor doppelten und einfachen Hochkommas verschwindet ganz. Dein obiges SQL-Statement sucht also nach Datenbankeinträgen, die folgendem String entsprechen:
    \n\r"' - zumindest auf den ersten Blick.

    Auf den zweiten Blick erzeugst du möglicherweise eine ungültige SQL-Anweisung.

    - Sven Rautenberg

    --
    "Love your nation - respect the others."
    1. Hallo Sven,

      Ich habe auf meiner Spielwiese probiert, dass Problem mit sowenig Code wie möglich nachzustellen und habe dabei das Problem behoben. In der Datenbank steht der Name ohne Escape-Zeichen und die Abfrage liefert auch das gewünschte Ergebnis.

        
      <html>  
      <head>  
      </head>  
      <body>  
      <form action="test.php" method="post">  
      <input type="text" name="test"/>  
      <input type="submit">  
      </form>  
        
      <?php  
      $mysqli = new mysqli('localhost', 'root', '', 'pii');  
        
      if(isset($_POST['test'])){  
       $t = $mysqli->real_escape_string($_POST['test']) ;  
       echo "<br>".$t;  
        
       $SQL = "INSERT INTO game(name) VALUES ('".$t."');";  
       echo "<br>".$SQL;  
       $mysqli->real_query($SQL);  
        
       $SQL = "SELECT * FROM game WHERE name='".$t."';";  
       echo "<br>".$SQL;  
       $res = $mysqli->query($SQL);  
       foreach($res as $r) {  
        print_r($r);  
        echo "<br>";  
       }  
      }  
      ?>  
      </body>  
      </html>  
      
      

      Die echo-Anweisungen ergeben folgende Ausgaben:

      \n\r'"
      INSERT INTO game(name) VALUES ('\n\r'"');
      SELECT * FROM game WHERE name='\n\r'"';
      stdClass Object ( [id] => 89 [date] => 0000-00-00 [comment] => [name] => \n\r'" [special] => 0 )

      In der Datenbank steht nun

      +----+------------+---------+--------+---------+
      | id | date       | comment | name   | special |
      +----+------------+---------+--------+---------+
      | 86 | 0000-00-00 |         | \n\r'" | 0       |
      +----+------------+---------+--------+---------+

      Tataaaaa!

      Bis zum nächsten Fallstrick,

      Stefan