PHP Kurs CD 3 PHP und MySql

  • Hallo Forum,


    auf der 3. CD des PHP Kurses wird sehr schön erklärt wie man eine Datenbank plant, atomisiert, normalisiert und wie verschiedene Tabellen angelegt werden die in einer Beziehung zu einander stehen ( Primär und Sekundärschlüssel ).

    Was ich aber nicht gefunden habe, wie man mit MySql und PHP solche Tabellen füllt oder ausliest (mehrere Tabellen in der Datenbank), sprich INSERT INTO oder SELECT FROM . Mit einer Tabelle in der Datenbank alles kein Problem ! Ich habe im Netz geforscht und verschiedenste Kommentare gelesen, bin mir aber nicht wirklich sicher was korrekt ist ?

    Meine Frage, wie wird das korrekt gemacht ?


    Um eure Hilfe bedanke ich mich im voraus :thumbup:


    A.Meier

  • Vielen Dank für eure Antworten,

    also an Stef, mit einer geschickten Googleanfrage findest auch du manigfaltige Antworten betreffend INSERT INTO in mehrere Tabellen.


    Nur meine Frege ist wie wird es korrekt gemacht ?


    Ein kleines Beispiel:


    1 Datenbank mit 2 Tabellen, Datenbankname sagen wir Adressenverwaltung


    Name adressen,

    Felder:

    ID, vorname, nachname,id_ stadt



    2. Tabelle

    Name stadt,

    Felder:

    id_stadt, stadt


    id_stadt der Tabelle stadt ist der Primärschlüssel

    id_stadt der Tabelle adressen ist der Sekundärschlüssel


    Die eingaben kommen von einem Formular via POST und sollen nun mit PHP und MySql in die Datenbank.


    Wie sieht nun die Anweisung aus ?


    INSERT INTO adressen...........und wie geht es dann weiter, so dass beide Tabellen befüllt werden ?


    Geht das mit einem INSERT INTO aufruf ? Braucht es 2 hintereinander ? Wie geht das korrekt ?

  • Wenn Du zwei Tabellen befüllen willst, benötigst Du zwei INSERT Queries.

    Als erstes würde ich definieren, dass stadt.id_stadt und adressen.ID PRIMARY KEY und AUTO_INCREMENT sind.


    Die Tabelle stadt würde ich als erstes füllen, damit Du die InsertId bekommst und in der zweiten Query auf die Tabelle adressen zur Verfügung hast.


    Drauf achten solltest Du, dass beim Einfügen in die Tabelle stadt keine doppelten Einträge möglich sind bzw. einen bereits vorhanden Eintrag einem INSERT vorzuziehen ist.

  • Hey,


    wie bereits erwähnt kannst du nicht gleichzeitig mehrere Tabellen füllen. Auser du benutzt Mysqli. Dort gibt es folgende Funktion: multi_query().

    Mit dieser kannst du multiple SQL-Codes ausführen.


    PDO unterstützt dies nicht.


    Eine Möglichkeit wäre eine Funktion zu erstellen welche dies unterstützt.


    Beispiel:

    Da ist hinter der jeweiligen Query die Insert Value.


    Zitat


    Das würde bedeuten, wenn ich 20 Tabellen hätte, dass ich 20 INSERTS machen muss ?

    Normalerweise ja.


    Zitat


    Was mir auch nicht klar ist, wird die ID im Sekundärschlüssel automatisch von Sql eingefügt oder muss man das über PHP programmieren, einerseits das der Primärschlüssel nicht doppelt vorkommt ? Hat das Feld in der Datenbank mit dem Sekundärschlüssel eine bestimmte Eigenschaft, Bezeichnung wo man mitgeben muss ? Wie müsste der Code aussehen ?

    In der normalen Tabelle wird das erste Feld mittels Auto_Increment immer hochgezählt. Dieses Feld besitzt dann die eindeutige Id. Nun musst du diese noch in die andere Tabelle bekommen. Um dies zu schaffen brauchst du nochmals ein Insert welches die Id mit einer Value in die 2 Tabelle einträgt.

    Davor musst du dann noch die eindeutige Id aus der anderen Tabelle fetchen. Denn es kann immer vorkommen, dass die Ids nicht übereinstimmen.

    Grüße,

    Stef

  • Update:

    ich verwende MySqli


    Was momentan funktioniert mit MySqli ist natürlich die Datenbankverbindung und dann z.B. für zwei Tabellen die Statements mit den Values hintereinander ( Stmt1,Stmt2 usw.). In der Tabelle mit dem Primärschlüssel ( das Feld Stadt ) ist als Unique Feld definiert, so dass keine doppelten Einträge vorkommen können.


    Was nicht funktioniert ist, sobald ich die Verknüpfung erstelle ( mit Designer Primär und Sekundärschlüssel ), werden nicht mehr beide Tabellen befüllt , egal welche zuerst angesprochen wird ! Warum ?


    Damit ich Anfänger es richtig Verstehe, das heisst wenn jetzt alles funktionieren würde, dass die ID oder Wert vom Primärschlüssel im Sekundärschlüssel nicht automatisch durch Sql eingefügt wird ?


  • Hey,


    dein Code ist überhaupt nicht leserlich. Und durch diese Entertaste nach der Function führst du diese auch garnicht aus. Desweiteren ist ein Fehler in der Insert-Query enthalten.


    Das A und O im Programmieren ist leserlicher Code. Dein Code wäre so für mich leserlich:

    PHP
    1. $dbv = new mysqli("localhost","root","","test");
    2. $stmt2 = $dbv->prepare("INSERT INTO test VALUE ( ?, ? ) ") ;
    3. $stmt2->bind_param("is", $_POST['idstadt'], $_POST['stadt']);
    4. $stmt2->execute();
    5. $stmt = $dbv->prepare("INSERT INTO anmeldung VALUES (?, ?, ?, ?, ?)");
    6. $stmt->bind_param("issss", $_POST['ID'], $_POST['vorname'], $_POST['nachname'], $_POST['idstadt'], date("d.m.Y H:i:s"));
    7. $stmt->execute();

    So wird auch die Funktion ausgeführt. Somit sind 2 Fehler behoben. Der letzte Fehler ist in der Insert-Query.


    Wenn du so den Code ausführst bekommst du doch eine Fehlermeldung ? Wenn nein schalte das Error Reporting an.

    Der Fehler lautet: Fatal error: Uncaught Error: Call to a member function bind_param() on boolean in Zeile ....


    Was sagt der Fehler aus?


    Die prepare Function gibt den boolean False zurück, weil die Query falsch ist. VALUE gibts nicht.


    Die richtige Insert-Query sieht so aus: INSERT INTO deineTabelle (feld1, feld2, feld3) VALUES (? , ? , ?);

    Grüße,

    Stef

  • Ich würde das MySQL erledigen lassen, dann braucht es auch nur eine Query.

    SQL besteht ja nicht nur aus SELECT, INSERT und UPDATE.


    Und dass PDO keine Multi-Queries kann ist auch falsch!

    Bei MySQLi wird auch nichts anderes gemacht, als die Queries in einem String zu übergeben.

    Das einzige, was MySQLi noch in der Hinterhand hat ist, dass Du die einzelnen Resultate per next_result() zur Verfügung stellt.

  • Sorry Schreibfehler, mein Error-Reporting ist an, meldete kein Fehler, Schreibfehler korrigiert, funzt trotzdem nicht, befüllt nur eine Tabelle wenn die Relation aktiv ist ( Primär und Sekundärschlüssel )

  • Okay. Ich habe gelesen, dass das neue PDO dies nicht mehr unterstützt.

    Finde ich auch nicht schlimm, was ist der große Vorteil der MySQLi-Variante gegenüber so etwas:

    PHP
    1. $sQuery = "INSERT INTO table ( column1, column2 ) VALUES ( 1, 2 );";
    2. $sQuery .= "UPDATE table SET column2 = 3";
    3. $oPDO->exec( $sQuery );

    Anders macht MySQLi das auch nicht, nur dass es dort eine mit multi benannte Methode ist.

    Bis hierhin gibt es keinen Vorteil einer Multi-Methode.

  • Genau, auf der Basis würde ich die hier gefragte Problematik wie bereits angesprochen auch komplett MySQL überlassen:

    SQL
    1. INSERT INTO stadt ( stadt ) values ( 'meine Stadt' );
    2. INSERT INTO adressen ( vorname, nachname, id_stadt ) VALUES ( 'Hans', 'Wurst', LAST_INSERT_ID() )

    Das würde mit PDO bspw. so aussehen:

    PHP
    1. $sQuery = "INSERT INTO stadt ( stadt ) values ( :stadt );";
    2. $sQuery .= "INSERT INTO adressen ( vorname, nachname, id_stadt ) VALUES ( :vname, :nname, LAST_INSERT_ID() )";
    3. $oStmnt = $oPDO->prepare( sQuery );
    4. $oStmnt->execute([
    5. 'stadt' => $stadt,
    6. 'vname' => $vorname,
    7. 'nname' => $nachname
    8. ]);

    WICHTIG: Das funktioniert auf die Weise nur, wenn der erste INSERT nur einen Datensatz schreibt! Wird an der Stelle ein Mulit-INSERT verwendet, liefert LAST_INSERT_ID() die ID des ersten Datensatzes! Da müsste man dann halt umdenken.

  • Hier meine komplette Versuchsanordnung, in dieser Konfiguration wird nur immer die Tabelle staedte gefüllt, anmeldung bleibt leer, Fehlermeldung erfolgt keine !


  • Wo hast Du denn $_POST['idstadt'] her? Die kann doch im Formular gar nicht bekannt sein...

    Stimmt, korrigiert, jetzt werden beide Tabellen befüllt aber in der Tabelle anmeldung Spalte idstadt habe ich jetzt den Stadtnamen z.B. Genf und in der Tabelle staedte Spalte stadt auch. Bin ich zu blöd ??

  • Update:

    Das funktioniert aber nur solange bis 2x der gleiche Städename über das Formular reinkommt, dann hängt sich das ganze auf ?!