Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] Commands out of Sync (mysqli) - wie code ich es sauber und ohne Fehler?

Einklappen

Neue Werbung 2019

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

  • [Erledigt] Commands out of Sync (mysqli) - wie code ich es sauber und ohne Fehler?

    Guten Tag nochmal.

    Steh hier vor nem Problem das mir schon häufig immer mal wieder in die Quere gekommen ist. Nun wüsste ich gerne mal was ein programmiertechnisch sauberer Ansatz ist.

    Ich habe ein Query, dass mehrere rows zurückgibt. Also schleife ich mit while durch. Jetzt würde ich mir aber während dem durchschleifen gerne gleich die Variablen schnappen und damit weitere Queries ausführen.

    Ein Beispiel:

    PHP-Code:
    <?php
        $stmt 
    $mysqli_db->prepare("SELECT name FROM benutzer WHERE variable=? LIMIT 5;");    //gibt 5 Reihen zurück
        
    $stmt->bind_param('d',$variable);
        
    $variable=5;
        
    $stmt->execute();
        
    $stmt->bind_result($name);
        while (
    $stmt->fetch()) 
        {
            
    LadeAddresse($name,$mysqli_db);
        }
    ?>

    <?php
        
        
    function LadeAddresse($name,$mysqli_db)
        {
            
    $stmt $mysqli_db->prepare("SELECT anschrift FROM addressen WHERE name=? LIMIT 1;");
            
    $stmt->bind_param('s',$benutzer_name);
            
    $benutzer_name=$name;
            
    $stmt->execute();
            
    $stmt->store_result();
            if(
    $reihen $stmt->num_rows)
            {
                
    $stmt->bind_result($addresse);
                
    $stmt->fetch();
            }
            
    $stmt->free_result();
            if(
    $reihen)
                return 
    $addresse;
            else
                return 
    "Keine Addresse";
    ?>
    Das obige Beispiel haut meine Variable "$mysqli_db" raus, der mysql error "Commands out of Sync" ensteht.

    Nun beuge ich dem eig. vor indem ich bei jedem Query ein store und free result hinhäng.

    Also quasi:

    PHP-Code:
    <?php
        $stmt 
    $mysqli_db->prepare("SELECT name FROM benutzer WHERE variable=? LIMIT 5;");    //gibt 5 Reihen zurück
        
    $stmt->bind_param('d',$variable);
        
    $variable=5;
        
    $stmt->execute();
        
    $stmt->store_result(); 
        
    $stmt->bind_result($name);
        while (
    $stmt->fetch()) 
        {
            
    LadeAddresse($name,$mysqli_db);
        }
       
    $stmt->free_result(); 
    ?>
    Jetzt bringt das aber nicht viel, da weitere mysql queries innerhalb der Schleife ausgeführt werden -> selbes Resultat, mysql stürzt zusammen.

    Von daher, wie wird ein solches Beispiel sauber umgesetzt?

    Die einzige Möglichkeit die mir einfällt, ist erst alle Rückgabewerte des ersten Queries in Variablen schreiben und dann die Funktion jeweils aufrufen - allerdings sieht das nicht wirklich schön aus, kann uU einiges an Variablen auffressen und ich kann mir nicht vorstellen, dass es da keine bessere Lösung gibt.

    Deswegen, gibt es eine bessere Lösung?

    Danke!


  • #2
    Also die Ursache kann ich dir nicht erklären, da ich die Klassen, die du verwendest nicht benutze. Aber wenn du in einer Schleife Queries abfeuerst, kann das schon ein Zeichen für ein falsches Design sein.

    Wenn du eine n:m Beziehung auflösen möchtest, musst du nicht n mal einen Query ausführen, um an den Inhalt von m zu kommen. Du kannst stattdessen alle m-Verbindungen in n auslesen (in einer Schleife) und dann ein Query absetzen, dass in der m-Tabelle danach sucht. Dann hast du, egal wieviele n:m-Verbindungen es gibt, nur 2 Queries auszuführen.
    "Mein Name ist Lohse, ich kaufe hier ein."

    Kommentar


    • #3
      Die Ursache liegt meines Wissens nach daran dass man vor dem free_result eines vorherigen Queries schon wieder ein neues verwendet, das Daten zurückgibt.

      Kurz zur Entschärfung deines Textes : Meinst du damit, die 5 Namen die das erste Query zurückgeben würde abspeichern und dann die Anschriften für alle 5 Namen mit einem Query abfragen?

      Kommentar


      • #4
        mein Tip: probier’s mal mit PDO, da haben die Prepared Statements wesentlich mehr fetch modes (nämlich alle die, die auch bei regulären Queries möglich sind)

        Kommentar


        • #5
          Ich bin schon relativ weit an dem jetzigen "Projekt" und füge nur noch das ein oder andere zu. Aber ich werde es im Hinterkopf behalten und mir beim nächsten Mal wenn ich was starte PDO ansehen

          Kommentar


          • #6
            Zitat von marcial Beitrag anzeigen
            Meinst du damit, die 5 Namen die das erste Query zurückgeben würde abspeichern und dann die Anschriften für alle 5 Namen mit einem Query abfragen?
            Nein, vermutlich meint er JOINs.

            Kommentar


            • #7
              Wozu bzw. wie soll das realisiert werden? Über JOINs würds doch auf ein Query und nicht wie von ihm vorgeschlagen 2 rauslaufen oder?

              Kommentar


              • #8
                Und dir erscheint eine Query, die gleich alles liefert, nicht irgendwie besser ...?

                Kommentar


                • #9
                  ich verwende zwar selbst mysql_query in meinem Projekt ...

                  aber irgendwie sieht dein Konstrukt

                  prepared statement
                  bind-param
                  jetzt erst der Variable einen wert zuweisen

                  für mich merkwürdig aus



                  ich hab das früher in Java benutzt und da musste die Variable zum Zeitpunkt des bind-param schon ihren Wert haben .. hat aber vermutlich wenig mit deinem Problem zu tun
                  "Irren ist männlich", sprach der Igel und stieg von der Drahtbürste

                  Kommentar


                  • #10
                    Zitat von ChrisB Beitrag anzeigen
                    Und dir erscheint eine Query, die gleich alles liefert, nicht irgendwie besser ...?
                    Das habe ich nicht gefragt, ich habe gefragt wie sein Text zu verstehen ist.

                    Dennoch, in meinem Falle scheint mir ein Query nicht irgendwie besser, da ich sowohl den Namen als auch die Anschrift anzeigen lassen möchte. Klar kann ich mir auch den Namen grabben, aber letzten Endes sehe ich ein riesiges "verschachteltes" Query doch als zu umständlich für eine eig. recht einfache Sache an.

                    Zitat von eagle275
                    ich hab das früher in Java benutzt und da musste die Variable zum Zeitpunkt des bind-param schon ihren Wert haben .. hat aber vermutlich wenig mit deinem Problem zu tun
                    Das funktioniert alles bestens soweit - ich habe zuvor noch nicht mit mysqli gearbeitet und mich an die Referenzen auf php.net gehalten. bind-param scheint wirklich so zu funktionieren (hat mich anfangs auch gewundert) - alle anderen Varianten die mir in den Kopf kamen erzeugten Fehler.


                    Edit: Möchte mich nochmal kurz zurückmelden. Zwischenzeitlich hatte ich meine Verständnisprobleme JOINs korrekt anzuwenden - jetzt habe ich mich rangesetzt und es klappt eig. wunderbar von daher dankeschön für den Hinweiß mit JOINs zu arbeiten.

                    Kommentar


                    • #11
                      Ein neues Problem besteht (ich hoffe in diesem Fall ist Doppelposting ok - falls nicht kommts nicht mehr vor, ich wollte aber keinen neuen Thread aufmachen).

                      Bitte fragt mich nicht wieso die Tabellenstruktur so unmöglich dumm gewählt worden ist, meine Frage ist aber:

                      Kann ich mir irgendwie einen Wert in einer Zelle schnappen und dann eine Abfrage nach der Spalte mit der gleichen Bezeichnung schnappen?

                      Beispiel:

                      Wert in der Spalte `Land` von `Benutzer` ist "Deutschland".

                      Ist es irgendwie möglich in einem Query diesen Wert zu nehmen und dann ein SELECT auf die Spalte `Deutschland` in der Tabelle `Laender` auszuführen?

                      Nochmals, ich kann mir gut vorstellen dass das dämlich klingt aber dennoch.

                      Ich habe bereits versucht:

                      "SELECT Laender.(SELECT benutzer.land FROM benutzer WHERE benutzer.id=1) FROM Laender"

                      Allerdings bekomme ich dann eben als Feld "Deutschland" (Inhalt von benutzer.land) anstelle den Inhalt des Feldes `Laender`.`Deutschland`.

                      Kommentar


                      • #12
                        ÄHm,,,und das ist jetzt nicht richtig? Du formulierst sehr ungünstig und mir ist nicht klar, was Du jetzt genau als Ergebnis haben willst?!?!

                        Wolf29
                        while (!asleep()) sheep++;

                        Unterschätze nie jemanden der einen Schritt zurück geht! Er könnte Anlauf nehmen.

                        Kommentar


                        • #13
                          Is auch ein dummes Beispiel aber mir ist kein besseres eingefallen - das orig. ist noch abwegiger.

                          Ich versuchs nochmal .

                          Ich habe eine Tabelle `a` mit der Spalte `SpaltenNameDerZweitenTabelle`. Das jeweilige Feld `a`.`SpaltenNameDerZweitenTabelle` stellt einen Spaltennamen der zweiten Tabelle `x` da.

                          Bsp.: `a`.`SpaltenNameDerZweitenTabelle` = 'RichtigerSpaltenName' -> Also möchte ich den Wert des Feldes `x`.`RichtigerSpaltenName` dessen Inhalt zum Beispiel "Korrekt" ist.

                          Prinzipiell möchte ich also zu `x`.`5`='Korrekt' über eine Abfrage von `a`.`SpaltenNameDerZweitenTabelle`.

                          Ich denke kaum dass es mögl. ist dennoch frage ich lieber nochmal.

                          Versucht habe ich u.a.:

                          "SELECT `x`.(SELECT `a`.`SpaltenNameDerZweitenTabelle` FROM `x` LIMIT 1) FROM `x` LIMIT 1;"

                          Dadurch erhalte ich aber anstelle von "Korrekt" (von `x`...), "RichtigerSpaltenName" (von `a`...).

                          Kommentar


                          • #14
                            öhm .. da kommst du um eine 2stufige Abfrage kaum herum,

                            1te Abfrage -> den gewünschten Spaltennamen

                            2te Abfrage -> damit in die richtige Tabelle und auslesen

                            soweit ich SQL kenne , bzw mysql kannst du nicht innerhalb einer Abfrage einen Datenwert in einen Spalten-Titel umwandeln - zumal aus mysql-sicht deine "äußere" Abfrage keinen Sinn ergibt ..

                            wenn du sicher gehen willst. probier die gesamte Abfrage in phpmyadmin aus - der wird dir vermutlich einen Fehler in deiner SQL-Syntax vorwerfen
                            "Irren ist männlich", sprach der Igel und stieg von der Drahtbürste

                            Kommentar


                            • #15
                              Hab ich bereits, ich bekomm es leider nicht hin. Leider ist es auch nicht gerade leicht über prepared statements da man z.B. meines Wissens nach nicht

                              ->prepare(SELECT ? FROM ...) anwenden kann und deinen einen String '`Spalte`' verwenden kann, sondern nur ohne die accents. Das ist dann auch kritisch wenn der Spaltenname zufällig mal ein Bezeichner für was anderes wäre wie z.B. eine Zahl. Somit erhält man dann immer die Zahl anstelle dem Feld dessen Spaltenname die Zahl ist (natürlich ein schlechter DB-Stil aber dennoch nervig). ->prepare(SELECT `?` ...) funzt auch nicht.

                              Kommentar

                              Lädt...
                              X