Theo: Datei verarbeiten

Hallo,

ich würde gerne per php-script einige mysql-inserts der Reihe nach ausführen.

Die zu verabeitenenden Zeilen sehen so aus

--
-- Daten für Tabelle tabelle1
--

INSERT INTO tabelle1 VALUES
(1, 4272, 1422, 'Ba', '1.00', 'Text', 100, '2009', 1254434400, 0, '0.00', '', '0.01'),
(2, 4342, 1874, 'Fa', '4.50', 'Text2', 125, '2010', 1283119200, 0, '0.00', '', '0.01');

--
-- Daten für Tabelle tabelle2
--

INSERT INTO tabelle2 VALUES...       usw.

und ich möchte gerne alle INSERTs der Reihe nach verarbeiten.

Dazu gibt es noch einige Gäsenfüßchen, die in den Spalten mit Typ string maskiert werden müssten.

Nicht falsch verstehen, ich will hier keine fertige Lösung haben. Aber ein paar Hilfestellungen, wie ich das am besten mache.

Ciao, Theo

  1. Hi!

    ich würde gerne per php-script einige mysql-inserts der Reihe nach ausführen.

    Mach das.

    Die zu verabeitenenden Zeilen sehen so aus
    INSERT INTO tabelle1 VALUES
    (1, 4272, 1422, 'Ba', '1.00', 'Text', 100, '2009', 1254434400, 0, '0.00', '', '0.01'),
    (2, 4342, 1874, 'Fa', '4.50', 'Text2', 125, '2010', 1283119200, 0, '0.00', '', '0.01');

    Willst du Einzel-Statements davon haben? Warum lässt du den Dump dann nicht gleich so erzeugen?

    Ansonsten müsstest du parsen. Einfach so an bestimmte Zeichen(folgen) auseinanderschneiden kann schief gehen, wenn diese auch als Datenbestandteil auftauchen.

    Dazu gibt es noch einige Gäsenfüßchen, die in den Spalten mit Typ string maskiert werden müssten.

    Wenn das Statement bereits fertig ist, müssen die Maskierungen schon enthalten sein. Anderenfalls kannst du nicht zweifelsfrei erkennen, wo Strings aufhören.

    Nicht falsch verstehen, ich will hier keine fertige Lösung haben. Aber ein paar Hilfestellungen, wie ich das am besten mache.

    Für welches konkrete Problem eigentlich?

    Lo!

    1. Willst du Einzel-Statements davon haben? Warum lässt du den Dump dann nicht gleich so erzeugen?

      Hallo.

      Was meinst Du mit Einzelstatements? Dass die Überschriften weg sind oder alles einzelne Insertbefehle?
      Die Überschriften hätte ich gerne weg. Aber weiß nicht wie.
      Lo?
      Ok. Auch Lo :-) Theo

      1. Hi!

        Willst du Einzel-Statements davon haben? Warum lässt du den Dump dann nicht gleich so erzeugen?
        Was meinst Du mit Einzelstatements? Dass die Überschriften weg sind oder alles einzelne Insertbefehle?

        Letzeres.

        Die Überschriften hätte ich gerne weg. Aber weiß nicht wie.

        Die Überschriften stören nicht, das sind Kommentare, die beim Ausführen ignoriert werden.

        Solange du aber nicht sagst, was dein eigentliches Ziel ist, wird man dir nur wenig zielführende Vorschläge machen können.

        Lo!

        1. Solange du aber nicht sagst, was dein eigentliches Ziel ist, wird man dir nur wenig zielführende Vorschläge machen können.

          T'schuldijung :-)
          Ich will Insertbefehle, die ich so erzeugt habe, nun abarbeiten. Aber nicht in phpmyadmin einsetzen sondern über eine php datei.
          Aber da fängts schon an. Wie man eine Datei verarbeitet, weiß ich. Aber ich würde gerne das Script und die erzeugten Inserts in einer einzigen Datei haben. Und ich weiß nicht, wie ich die Inserts nacheinander ausführe.

          Theo *etwasratlos*

          1. Ich will Insertbefehle, die ich so erzeugt habe, nun abarbeiten. Aber nicht in phpmyadmin einsetzen sondern über eine php datei.
            Aber da fängts schon an. Wie man eine Datei verarbeitet, weiß ich. Aber ich würde gerne das Script und die erzeugten Inserts in einer einzigen Datei haben. Und ich weiß nicht, wie ich die Inserts nacheinander ausführe.

            Du kannst MySQL auch alle Statements gleichzeitig übergeben.

            Quasi:

              
            mysql_query(file_get_contents("statment.sql"));  
            
            
            1. Hi!

              Du kannst MySQL auch alle Statements gleichzeitig übergeben.
              mysql_query(file_get_contents("statment.sql"));

              Nein, das geht nicht - nicht mit mysql_query().

              Lo!

          2. Hi!

            Ich will Insertbefehle, die ich so erzeugt habe, nun abarbeiten. Aber nicht in phpmyadmin einsetzen sondern über eine php datei.
            Aber da fängts schon an. Wie man eine Datei verarbeitet, weiß ich. Aber ich würde gerne das Script und die erzeugten Inserts in einer einzigen Datei haben. Und ich weiß nicht, wie ich die Inserts nacheinander ausführe.

            Das beste wäre, die Datei direkt mit dem Kommandozeilen-Client von MySQL ausführen zu lassen. Das geht in der Regel sehr schnell und problemlos, setzt aber voraus, dass du ihn starten darfst.

            Die mysqli-Extension kennt dann auch mysqli_multi_query(), das mehrere Statements in einem Rutsch abarbeiten kann. Problematisch kann dabei nur die Datengröße werden. Und ein Laufzeit-Timeout seitens PHP.

            Selbst zerteilen ist aufwendig, weil du dir einen Parser schreiben musst, der genau weiß, ob ein ; innerhalb von Daten oder zwischen zwei SQL-Statements steht. Nur wenn du das innerhalb von Daten ausschließen kannst, dann kannst du am ; explodieren lassen.

            Lo!

            1. Selbst zerteilen ist aufwendig, weil du dir einen Parser schreiben musst, der genau weiß, ob ein ; innerhalb von Daten oder zwischen zwei SQL-Statements steht. Nur wenn du das innerhalb von Daten ausschließen kannst, dann kannst du am ; explodieren lassen.

              Naja, darum gehts halt.

              Ich könnte auch das ; gegen |*#| austauschen oder so.

              Das könnte ich nämlich ziemlich sicher ausschließen, dass das nochmal in Strings vorkommt.

              Bleiben aber dennoch die restlichen Fragen.

              Du meinst, ich soll dann die knapp 3000 Abfragen alle in eine Variable einlesen und anhand des Delimiters trennen und das Array abarbeiten?

              Oder habe ich Dich da falsch verstanden?

              Theo

              1. Hi!

                Selbst zerteilen ist aufwendig, weil du dir einen Parser schreiben musst, der genau weiß, ob ein ; innerhalb von Daten oder zwischen zwei SQL-Statements steht. Nur wenn du das innerhalb von Daten ausschließen kannst, dann kannst du am ; explodieren lassen.
                Naja, darum gehts halt.
                Ich könnte auch das ; gegen |*#| austauschen oder so.
                Das könnte ich nämlich ziemlich sicher ausschließen, dass das nochmal in Strings vorkommt.

                In den Daten? Das wäre Unfug, nur wegen diesem einen Problem sich für die anderweitige Verarbeitung weitere aufzuhalsen.

                Bleiben aber dennoch die restlichen Fragen.
                Du meinst, ich soll dann die knapp 3000 Abfragen alle in eine Variable einlesen und anhand des Delimiters trennen und das Array abarbeiten?

                Ich meinte nichts konkretes, weil mir die Größenordnung nicht bekannt war, um die es geht. Und ich sortierte meine Vorschläge in der vorigen Antwort auch von der besten zur aufwendigsten Lösung. Wenn du wirklich den dritten Weg gehen willst, so war ich auch hier nicht konkret bei der Aufzeigung eines möglichen Lösungswegs. Beim kompletten Einlesen könntest du ein Speicherproblem bekommen. Und wenn du nicht exploden lassen willst (weil es nicht sinnvoll geht), brauchst du kein komplettes Einlesen. Zum Parsen reicht schrittweises Lesen in Form von kleinen Blöcken. Wann immer du dann ein ; als Statementtrenner erkannt hast, kannst du selbiges abschicken.

                Lo!

                1. Zum Parsen reicht schrittweises Lesen in Form von kleinen Blöcken. Wann immer du dann ein ; als Statementtrenner erkannt hast, kannst du selbiges abschicken.

                  Kannst Du mir erklären, wie man das macht?

                  Theo

                  1. Hi!

                    Zum Parsen reicht schrittweises Lesen in Form von kleinen Blöcken. Wann immer du dann ein ; als Statementtrenner erkannt hast, kannst du selbiges abschicken.
                    Kannst Du mir erklären, wie man das macht?

                    Fang an zu lesen. Wenn du auf ein Stringbegrenzerzeichen triffst, merkst du dir das. Sowohl dass eins war als auch welches es war. Wenn du dann gemäß der String-Notationsregeln auf ein weiteres und keine Escape-Sequenz gestoßen bist, dann bist du aus dem String raus. Nur im Nicht-String-Zustand darfst du ein Semikolon als Statement-Ende betrachten.

                    Lo!

                2. Hello Dedlfix,
                  hello Theo,

                  die spannendste Frage wurde noch gar nicht gestellt:

                  Sind die Daten in der externen Datei integer?

                  Wenn es sich dabei um einen Dump handelt, und an der Tabellen- und Referenzdefinition nichts geändert wurde seit dem Dump, dann sollte der Reimport auch sauber durchlaufen, egal, ob man ein Multi-Insert (für das man übrigens keine improved Functions benötigt) durchführt oder in einer Schleife immer diskrete Inserts pro Datensatz.

                  Wenn aber die Daten und die Definitionen nicht konsisttent gehalten wurden, oder aus zwei (mehreren) unterschiedlichen Quellen stammen (das kommt ja häufig vor), dann muss man die Schleifenlösung wählen, indem ein Datensatz nach dem nächsten eingefügt wird und der Status dokumentiert wird.

                  Wie will man sonst feststellen, welche Datensätze ordnungsgemäß eingefügt werden konnten?

                  Liebe Grüße aus dem schönen Oberharz

                  Tom vom Berg

                  --
                   ☻_
                  /▌
                  / \ Nur selber lernen macht schlau
                  http://bergpost.annerschbarrich.de
                  1. Hi!

                    Wenn es sich dabei um einen Dump handelt, und an der Tabellen- und Referenzdefinition nichts geändert wurde seit dem Dump, dann sollte der Reimport auch sauber durchlaufen, egal, ob man ein Multi-Insert (für das man übrigens keine improved Functions benötigt) durchführt oder in einer Schleife immer diskrete Inserts pro Datensatz.

                    Er hat doch mehrere Statements pro Datei, schon weil er zwei Tabellen drin hat. Soweit ich mich erinnere, erzeugt ein Dump auch keine Monster-Multi-Insert-Statements sondern erzeugt nach einer bestimmten Größe ein neues. Er hat als nicht nur ein einzelnes Multi-Insert-Statement sondern derer viele. Und dafür braucht es dann die mysqli-Extension.

                    Lo!

                    1. Hello,

                      Wenn es sich dabei um einen Dump handelt, und an der Tabellen- und Referenzdefinition nichts geändert wurde seit dem Dump, dann sollte der Reimport auch sauber durchlaufen, egal, ob man ein Multi-Insert (für das man übrigens keine improved Functions benötigt) durchführt oder in einer Schleife immer diskrete Inserts pro Datensatz.

                      Er hat doch mehrere Statements pro Datei, schon weil er zwei Tabellen drin hat. Soweit ich mich erinnere, erzeugt ein Dump auch keine Monster-Multi-Insert-Statements sondern erzeugt nach einer bestimmten Größe ein neues. Er hat als nicht nur ein einzelnes Multi-Insert-Statement sondern derer viele. Und dafür braucht es dann die mysqli-Extension.

                      Das kann ich jetzt nicht nachvollziehen, dass er die improved Functions benötigen würde. Es ging ja früher auch ohne...

                      Aber Du hast meine Aussage sowieso fehlinterpretiert.

                      Es geht mir um die Datenkonsistenz, Integrität und Kontrolle. Wenn es nicht sichergestellt ist, dass der zu importierende Datenbestand integer ist, dann muss zwangsweise eine Schleife mit Einzelstatements verwendet werden, wenn man die Kontrolle behalten will.

                      Anders bekommt man nicht heraus, welcher Datensatz Schwierigkeiten gemacht hat.

                      Liebe Grüße aus dem schönen Oberharz

                      Tom vom Berg

                      --
                       ☻_
                      /▌
                      / \ Nur selber lernen macht schlau
                      http://bergpost.annerschbarrich.de
                      1. Hi!

                        Wenn es sich dabei um einen Dump handelt, und an der Tabellen- und Referenzdefinition nichts geändert wurde seit dem Dump, dann sollte der Reimport auch sauber durchlaufen, egal, ob man ein Multi-Insert (für das man übrigens keine improved Functions benötigt) durchführt oder in einer Schleife immer diskrete Inserts pro Datensatz.
                        Er hat doch mehrere Statements pro Datei, schon weil er zwei Tabellen drin hat. Soweit ich mich erinnere, erzeugt ein Dump auch keine Monster-Multi-Insert-Statements sondern erzeugt nach einer bestimmten Größe ein neues. Er hat als nicht nur ein einzelnes Multi-Insert-Statement sondern derer viele. Und dafür braucht es dann die mysqli-Extension.
                        Das kann ich jetzt nicht nachvollziehen, dass er die improved Functions benötigen würde. Es ging ja früher auch ohne...

                        Ein Semikolon (außerhalb eines Strings) und mysql_query() bricht mit einem Fehler ab. Und das schon seit ewig. Das ist in der MySQL-Client-API so festgelegt und nicht von PHP beeinflusst. Jeder Client-API-Nutzer, der mehrfache Statements in einer Query senden will, hat das zu beachten. Er muss entweder beim Verbinden das Flag CLIENT_MULTI_STATEMENTS (ggf. mit CLIENT_MULTI_RESULTS) setzen oder bei laufender Verbindung die Option MYSQL_OPTION_MULTI_STATEMENTS_ON setzen. PHP lässt weder noch zu, sondern setzt es von selbst und nur bei mysqli_multi_query().

                        Aber Du hast meine Aussage sowieso fehlinterpretiert. Es geht mir um die Datenkonsistenz, Integrität und Kontrolle.

                        Nö, den Teil hab ich einfach nur übergangen. Ich wollte nur deine Klammerbemerkung richtig-/klarstellen.

                        Lo!

                        1. Hello,

                          Ein Semikolon (außerhalb eines Strings) und mysql_query() bricht mit einem Fehler ab.

                          Du sollst doch gar nicht mehrere Statements absetzen, sondern nur ein multiple Isert benutzten, also dem Insertbefehl mehrere Datensätze übergeben. Das geht innerhalb eines Statements.

                          Liebe Grüße aus dem schönen Oberharz

                          Tom vom Berg

                          --
                           ☻_
                          /▌
                          / \ Nur selber lernen macht schlau
                          http://bergpost.annerschbarrich.de
                          1. Moin!

                            Ein Semikolon (außerhalb eines Strings) und mysql_query() bricht mit einem Fehler ab.

                            Du sollst doch gar nicht mehrere Statements absetzen, sondern nur ein multiple Isert benutzten, also dem Insertbefehl mehrere Datensätze übergeben. Das geht innerhalb eines Statements.

                            Wenn er aber so viele Datensätze übergeben muss, dass er damit die maximale Länge eines SQL-Statements überschreitet, benötigt er wieder mehr als einen Query.

                            Außerdem gehe ich davon aus, dass die Datei mit dem SQL-Statements bereits existiert und eben MEHRERE Statements enthält.

                            - Sven Rautenberg

                            1. Hello,

                              Ein Semikolon (außerhalb eines Strings) und mysql_query() bricht mit einem Fehler ab.

                              Du sollst doch gar nicht mehrere Statements absetzen, sondern nur ein multiple Isert benutzten, also dem Insertbefehl mehrere Datensätze übergeben. Das geht innerhalb eines Statements.

                              Wenn er aber so viele Datensätze übergeben muss, dass er damit die maximale Länge eines SQL-Statements überschreitet, benötigt er wieder mehr als einen Query.

                              Das saga ich doch gerade. Man muss prüfen, ob er nicht sowieso mehr al ein Query benötigt, wenn er die Kontrolle behalten will.

                              Außerdem gehe ich davon aus, dass die Datei mit dem SQL-Statements bereits existiert und eben MEHRERE Statements enthält.

                              Und trotzdem muss man sich auch dann noch fragen, ob man die Datei nicht umschreiben muss, sodass auch diese Statements noch auseinandergenommen werden, und schlussendlich jeder Datensatz sein eigenes Insert bekommt.

                              Ist es nun angekommen, worum es mir geht?

                              Liebe Grüße aus dem schönen Oberharz

                              Tom vom Berg

                              --
                               ☻_
                              /▌
                              / \ Nur selber lernen macht schlau
                              http://bergpost.annerschbarrich.de
                              1. Hi!

                                Du sollst doch gar nicht mehrere Statements absetzen, sondern nur ein multiple Isert benutzten, also dem Insertbefehl mehrere Datensätze übergeben. Das geht innerhalb eines Statements.

                                Ach - was denn nun? Empfiehltst du nun das Aufteilen oder nicht?

                                Wenn er aber so viele Datensätze übergeben muss, dass er damit die maximale Länge eines SQL-Statements überschreitet, benötigt er wieder mehr als einen Query.
                                Das saga ich doch gerade. Man muss prüfen, ob er nicht sowieso mehr al ein Query benötigt, wenn er die Kontrolle behalten will.

                                Nein, dir geht es in deiner Argumentation nicht um technische Notwendigkeit aufgrund von Beschränkungen der maximalen Datenmenge sondern um die Kontrollmöglichkeit jedes einzelnen Datensatzes. Selbst wenn er nicht kontrollieren will - er hat aber bereits mehrere Statements in der Datei. Dein Anliegen vereinzeln nur einige und macht aus sowieso schon mehreren noch viel mehr.

                                Außerdem gehe ich davon aus, dass die Datei mit dem SQL-Statements bereits existiert und eben MEHRERE Statements enthält.
                                Und trotzdem muss man sich auch dann noch fragen, ob man die Datei nicht umschreiben muss, sodass auch diese Statements noch auseinandergenommen werden, und schlussendlich jeder Datensatz sein eigenes Insert bekommt.
                                Ist es nun angekommen, worum es mir geht?

                                Dir geht es darum, dass man die Multi-Insert-Statements zum Überprüfen auf Fehler trennen muss. Man muss sie aber nicht nur in einzelne Insert-Statements aufteilen, wenn man speziell dieses Kontrollmöglichkeit haben will, man muss sowohl sie als auch mehrere Multi-Insert-Statements einzeln per mysql_query() absetzen. Und dieses Statement-Einzeln-Abschicken-Müssen hattest du in deiner Klammerbemerkung angezweifelt. Nur dies wollte ich klarstellen, und nicht die Sinnhaftigkeit der Multi-Insert-Statement-Vereinzelung im Allgemeinen oder deren möglicher Notwendigkeit in Fall des OP diskutieren.

                                Lo!