Eric: supplied argument is not a valid MySQL result resource?

Okay, ich hab' gesucht und mir das Hirn zermartert, und vielleicht bin ich einfach zu blöd als Anfänger ... aber ich finde für das folgende Problem keine Lösung:

Ich lasse ein php-Script zwei Variablen übergeben an ein anderes Script (var1 und var2). Es handelt sich dabei um eine Monats- und eine Jahresangabe.

Die übergebenen Variablen übernehme ich in die Strings $monat und $jahr. Das funktioniert auch soweit.

Jetzt will ich aus meiner Tabelle alle Felder auswählen, bei denen Monat und Jahr übereinstimmen mit folgender Syntax:

$abfrage = "SELECT * FROM PlatteMonat WHERE Monat=$monat AND Jahr=$jahr";

Als Ergebnis erhalte ich die Fehlermeldung:

Warning: mysql_fetch_object(): supplied argument is not a valid MySQL result resource

Was mich allerdings vor ein echtes Rätsel stellt: Verkürze ich die Abfrage lediglich auf das Jahr, also:

$abfrage = "SELECT * FROM PlatteMonat WHERE Jahr=$jahr";

dann funzt die Kiste einwandfrei. Verkürze ich die Abfrage allerdings auf den Monat, also

$abfrage = "SELECT * FROM PlatteMonat WHERE Monat=$monat";

dann erhalte ich dieselbe Fehlermeldung wie oben beschrieben. Ich bin Anfänger, ratlos und frustriert ... kann mir jemand helfen?

  1. Hi,

    $abfrage = "SELECT * FROM PlatteMonat WHERE Monat=$monat AND Jahr=$jahr";
    Als Ergebnis erhalte ich die Fehlermeldung:
    Warning: mysql_fetch_object(): supplied argument is not a valid MySQL result resource

    diese Fehlermeldung ist nicht das Resultat obiger String-Zuweisung. Du scheinst anschließend noch etwas zu machen, was garantiert für das Problem interessant ist. Ebenfalls interessant ist die Frage:

    Wie lautet das SQL-Statement?

    Die daraus folgenden Fragen stellen wir später, falls Du nicht selbst darauf kommst.

    $abfrage = "SELECT * FROM PlatteMonat WHERE Jahr=$jahr";

    Fast ebenso interessant: Warum selektierst Du "*"?

    Cheatah

    --
    X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
  2. echo $begrüßung;

    Ich lasse ein php-Script zwei Variablen übergeben an ein anderes Script (var1 und var2). Es handelt sich dabei um eine Monats- und eine Jahresangabe.

    Diese Behauptung ist ja schön und gut, aber hast du auch den Beweis erbracht, dass das stimmt? Haben Kontrollausgaben die gewünschten Werte angezeigt?

    Die übergebenen Variablen übernehme ich in die Strings $monat und $jahr. Das funktioniert auch soweit.

    "Funktioniert" heißt in deinem Fall konkret was? Wie hast du kontrolliert, dass das "funktioniert"?

    Jetzt will ich aus meiner Tabelle alle Felder auswählen, bei denen Monat und Jahr übereinstimmen mit folgender Syntax:
    $abfrage = "SELECT * FROM PlatteMonat WHERE Monat=$monat AND Jahr=$jahr";

    Das ist in erster Linie eine Syntax, um einen PHP-String zu erstellen. Wenn du ein Problem mit der Datenbank vermutest, schau dir konkret an, was du der Datenbank übergibst.

    Nebenbei: Wie stellst du sicher, dass nur gewünschte Werte in die Abfrage eingebaut werden können und keine SQL-Injection möglich ist?

    Als Ergebnis erhalte ich die Fehlermeldung:
    Warning: mysql_fetch_object(): supplied argument is not a valid MySQL result resource

    Was hast du bei deiner Recherche herausgefunden, was diese Fehlermeldung verursacht? Welche Tipps standen dabei, um die Ursache für diesen Folgefehler zu finden?

    Was mich allerdings vor ein echtes Rätsel stellt: Verkürze ich die Abfrage lediglich auf das Jahr, also:
    $abfrage = "SELECT * FROM PlatteMonat WHERE Jahr=$jahr";
    dann funzt die Kiste einwandfrei. Verkürze ich die Abfrage allerdings auf den Monat, also
    $abfrage = "SELECT * FROM PlatteMonat WHERE Monat=$monat";

    Das ist immer noch nur PHP-Syntax.

    dann erhalte ich dieselbe Fehlermeldung wie oben beschrieben. Ich bin Anfänger, ratlos und frustriert ... kann mir jemand helfen?

    Nicht direkt, weil niemand ohne Glaskugel sagen kann, was in deinen Variablen drinsteht und was du dem MySQL-Server letzlich übergibst. Ich nehme man an, dass das was zwischen der Erstellung dieses String und der Fehlermeldung liegt soweit richtig ist, außer dass dabei überhaupt keine Auswertung und Reaktion auf die von den mysql_*-Funktionen zurückgemeldeten Fehlerzustände erfolgt.

    echo "$verabschiedung $name";

  3. Vielen Dank für eure Antworten, auch wenn ich nicht wirklich alles verstanden hab, Anfänger halt. Ich werd' versuchen, mein Problem besser zu schildern. Ich  hab' eine Tabelle, in der u.a. die Felder Jahr (als "year") und Monat (als "varchar") enthalten sind.

    Nun habe ich ein Script, mit dem ich über href das Problemscript aufrufe mit folgendem Befehl:

    echo "<a href='archiv.php?var1=" .$row->Monat. " &var2=" .$row->Jahr. "'>$row->Monat $row->Jahr</a>";

    Das übergebene Script sieht folgendermaßen aus:

    $check=0;
    $monat=$_GET["var1"];
    $jahr=$_GET["var2"];
    echo $monat;
    echo $jahr;

    mysql_connect("localhost", "...","...") or die
     ("Keine Verbindung moeglich");
    mysql_select_db("...");
    $abfrage = "SELECT * FROM PlatteMonat WHERE $monat = $row->Monat AND $jahr = $row->Jahr";
    $ergebnis = mysql_query($abfrage);

    while($row = mysql_fetch_object($ergebnis))
    {

    Danach folgen die weiteren Befehle. Wie ihr oben seht, hab' ich mir die Variablen $monat und $jahr mal anzeigen lassen, die haben den korrekten Inhalt. Die Übergabe der Variablen funktioniert also offensichtlich. Und, wie gesagt: Verkürze ich die Abfrage nur auf das Jahr, stimmt das Ergebnis. Verkürze ich die Nachfrage aber auf den Monat, erhalte ich die gleiche Fehlermeldung.

    Folgenden Fehler konnte ich mir anzeigen lassen (der mir allerdings auch nicht wirklich weiterhilft):

    Access denied for user '...'@'localhost' to database '..., Resource id #5' 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AND 2008 =' at line 1

    Danke vorab für eure Antworten!

    1. Hi!

      $monat=$_GET["var1"];
      $jahr=$_GET["var2"];

      Das ist unnötig, du kopierst hier nur zwei Variablen und erschwerst eine Fehleranalyse, außerdem verschleierst Du weiter unten die Herkunft der Daten aus dem Superglobal $_GET.

      echo "<a href='archiv.php?var1=" .$row->Monat. " &var2=" .$row->Jahr. "'>$row->Monat $row->Jahr</a>";

      Wir kennen die hier ausgegebenen Properties Deines $row-Objektes nicht!

      mysql_connect("localhost", "...","...") or die
      ("Keine Verbindung moeglich");

      Das ist keine gute Idee.

      Ermittle bitte einmal den genauen Inhalt von:

        
      
      > $abfrage = "SELECT * FROM PlatteMonat WHERE $monat = $row->Monat AND $jahr = $row->Jahr";  
      
      

      Gerade als Anfänger soltest Du immer den abzusetzenden Query-String vorher ansehen und auf Fehler prüfen, erst dann übergibst Du diesen an den DB-Server. Sollten dir bereits Fehler auffallen, kann der Schritt, die Query an diesen zu senden entfallen ;)

      Wie Cheatah bereits andeutete ist es fast nie gut,  '*' zu selektieren - benötigst du wirklich alle Felder?

      Access denied for user '...'@'localhost' to database '..., Resource id #5' 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AND 2008 =' at line 1

      Das scheinen IMHO zwei Fehlermeldungen zu sein:
      1. Die von Dir benutzte Kombination aus User/Password ist nicht zulässig:

      Ermittle diese bitte und schaue, ob der MyQL-User mit dem benutzten Kennwort so  korrekt ist.

      2: Ein SQL-Syntax-Fehler siehe oben.

      --
      "You know that place between sleep and awake, the place where you can still remember dreaming?" (Tinkerbell)
    2. echo $begrüßung;

      Vielen Dank für eure Antworten, auch wenn ich nicht wirklich alles verstanden hab, Anfänger halt.

      Dann frag doch bitte konkret nach. Es wird dir sicherlich jemand erklären, wie die Stelle gemeint war.

      Nun habe ich ein Script, mit dem ich über href das Problemscript aufrufe mit folgendem Befehl:

      echo "<a href='archiv.php?var1=" .$row->Monat. " &var2=" .$row->Jahr. "'>$row->Monat $row->Jahr</a>";

      Das übergebene Script sieht folgendermaßen aus:

      Übergebend? Nicht etwa übernehmend? Oder besser formuliert: das aufgerufene. Denn woher eine Anfrage kommt ist prinzipiell egal. Jede Requestabarbeitung steht für sich allein und hat keinen Bezug zu irgendwelchen anderen Requests.

      $monat=$_GET["var1"];
      $jahr=$_GET["var2"];

      Oft gesehen, immer wieder unnötig. In $_GET['var1'] (übrigens: var1 ist ein nicht sehr aussagekräftiger Bezeichner) steht bereits der Wert, den du haben möchtest drin. Du kannst ihn gleich weiterverwenden, ohne ihn erst in eine andere Variable umzukopieren.

      mysql_connect("localhost", "...","...") or die
      ("Keine Verbindung moeglich");

      Ein Script zu töten ist meist eine unangemessene Methode, auf Fehler zu reagieren. Reagiere besser mit Fallunterscheidung darauf, und zeig dem Anwender eine für ihn nützliche Information an, wie er nun trotz des Fehlers weitermachen kann. Für die nicht zustandegekommene Datenbankverbindung kann er nichts, er braucht auch keine Detailinformationen für solche Fehler angezeigt zu bekommen. Du als Administrator solltest aber sehr wohl davon Kenntnis nehmen.

      $abfrage = "SELECT * FROM PlatteMonat WHERE $monat = $row->Monat AND $jahr = $row->Jahr";

      Diese Variablenerstellung unterschiedet sich doch deutlich von der aus dem OP:

      $abfrage = "SELECT * FROM PlatteMonat WHERE Monat=$monat AND Jahr=$jahr";

      Es bleibt die Frage bestehen: Wie lautet das Ergebnis dieser Anweisung? Konkret: Was steht nun in $abfrage?

      Stell bitte außerdem beim Entwickeln von PHP-Anwendungen das error_reporting auf E_ALL, damit du Zugriffsversuche auf nicht vorhandene Variablen angezeigt bekommst.

      $ergebnis = mysql_query($abfrage);
      while($row = mysql_fetch_object($ergebnis))

      Die hier fehlende Auswertung des Ergebnisses von mysql_query() führt bei Fehlern im SQL-Statement zu deiner ursprünglichen Fehlermeldung, denn das false des Fehlerfalls ist kein gültiges Argument für die Fetch-Funktion.

      Folgenden Fehler konnte ich mir anzeigen lassen (der mir allerdings auch nicht wirklich weiterhilft):

      Access denied for user '...'@'localhost' to database '..., Resource id #5' 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AND 2008 =' at line 1

      Das sind zwei Fehler mit einer Kontrollausgabe einer Variablen dazwischen. Ein Fehler stammt von einem misslungenen Connect-Versuch, der andere von einem Fehler im SQL-Statement beim Ausführen. Syntax-Fehler sind immer vor der angeführten Stelle zu suchen.

      echo "$verabschiedung $name";

    3. Nochmal Danke für eure Antworten, zumindest hab' ich gelernt, dass ich völlig Ahnunglos bin, wenn in die Materie tiefer eingestiegen wird.

      Die Lösung des Problems war dann aber im Grunde recht simpel: Bei der Abfrage von zwei Variablen musste ich diese in Anführungszeichen setzen, also:

      $abfrage = "SELECT * FROM Archiv WHERE Monat = '$monat' AND Jahr = '$jahr'";

      Das war alles, jetzt tut es. ;)

      1. echo $begrüßung;

        Die Lösung des Problems war dann aber im Grunde recht simpel: Bei der Abfrage von zwei Variablen musste ich diese in Anführungszeichen setzen, also:

        $abfrage = "SELECT * FROM Archiv WHERE Monat = '$monat' AND Jahr = '$jahr'";
        Das war alles, jetzt tut es. ;)

        Ja, aber nur solange in den Variablen kein ' enthalten ist. Das ergibt dann die SQL-Injection-Lücke. Wann immer du Werte in einen bestimmten Kontext bringst, musst du sie dem Kontext gemäß behandeln. Für MySQL-Statements gibt es mysql_real_escape_string(). Und mit sprintf() lässt sich das auch lesbar gestalten:

        $abfrage = sprintf("SELECT * FROM Archiv WHERE Monat = '%s' AND Jahr = '%s'",
            mysql_real_escape_string($monat), mysql_real_escape_string($jahr));

        Außerdem gibt es noch ein PHP-Feature names Magic Quotes, dass genau diese Aufgabe erfüllen soll, aber auch unerwünschte Nebenwirkungen hat. Falls sie aktiviert sind, solltest du nun die Magic Quotes deaktivieren.

        echo "$verabschiedung $name";

        1. Puh ... das werde ich mir mal in Ruhe anschauen müssen, möglichst mit Kaffee auf'm Tisch und nicht mit Bier. ;) Danke Dir, werd' ich mir zu Gemüte führen!