MH: CSV import mit Umlauten

Moin,
Ich hab eine CSV-Datei in der ganz viele Namen und noch weiter Daten stehen. Diese Datei soll in eine Tabelle in einer Datenbank mit PHP importiert werden. Das importieren an sich funktioniert auch, jedoch werden die Umlaute nicht richtig eingetragen. Ich hab jetzt schon mehrere Sachen ausprobiert, aber immer sind die Umlaute nicht richtig.
Was ich bis jetzt gemacht habe:

  • "SET NAMES 'utf8'" als 1. Query
  • den kompletten String durch "utf8_encode" "geschleift"
  • nur die Teile wo auch Umlaute stehen durch "utf8_encode" "geschleift"

Die Tabelle und die Spalten sind UTF-8 codiert.

Hat jmd. eine Idee wie ich das Problem lösen kann?
Gruß und schönen Sonntag noch.
MH

  1. Moin,

    und in welcher Codierung liegen die Daten in deiner Datei vor?

    Viele Grüße
    Robert

    1. Moin,

      auch in UTF-8

      Gruß
      MH

      1. Moin,

        das heißt, du enkodierst deine UTF-8-codierten Daten ein zweites Mal. Welchen Sinn soll das haben?

        Viele Grüße
        Robert

        1. Moin,

          das heißt, du enkodierst deine UTF-8-codierten Daten ein zweites Mal.

          Wie genau meinst du das? Ich enkodiere die Datei doch nicht?!

          Gruß
          MH

          1. Tach!

            das heißt, du enkodierst deine UTF-8-codierten Daten ein zweites Mal.
            Wie genau meinst du das? Ich enkodiere die Datei doch nicht?!

            Wenn deine Daten bereits UTF-8-kodiert sind (und das korrekt geschehen ist), dann muss es reichen, dem DBMS mitzuteilen, dass du UTF-8-Daten sendest.

            Für MySQL muss man das nach dem Verbindungsaufbau aushandeln, sonst verwendet der MySQL-Server einen Wert aus seiner Konfiguration, der nicht mit deinen Gegebenheiten übereinstimmen muss. SET NAMES, oder besser der Aufruf der Funktion mysqli_set_charset() beziehungsweise bei Verwendung von PDO die charset-Angabe im DSN-String, muss dann eigentlich reichen. Wenn das dann trotzdem zu Fehlern kommt, machst du irgendwas nicht richtig, oder die Daten sind doch nicht korrekt kodiert.

            dedlfix.

            1. Hello,

              SET NAMES, oder besser der Aufruf der Funktion mysqli_set_charset() beziehungsweise bei Verwendung von PDO die charset-Angabe im DSN-String, muss dann eigentlich reichen. Wenn das dann trotzdem zu Fehlern kommt, machst du irgendwas nicht richtig, oder die Daten sind doch nicht korrekt kodiert.

              Laut MySQL-Doku (wie unten schon zitiert und verlinkt) soll gena das bei Dateiimport nicht wirken, sondern man soll die Character Set-Klausel im Import Statement nutzen.

              Liebe Grüße
              Tom S.

              --
              Es gibt nichts Gutes, außer man tut es!
              Das Leben selbst ist der Sinn.
              1. Tach!

                SET NAMES, oder besser der Aufruf der Funktion mysqli_set_charset() beziehungsweise bei Verwendung von PDO die charset-Angabe im DSN-String, muss dann eigentlich reichen. Wenn das dann trotzdem zu Fehlern kommt, machst du irgendwas nicht richtig, oder die Daten sind doch nicht korrekt kodiert.

                Laut MySQL-Doku (wie unten schon zitiert und verlinkt) soll gena das bei Dateiimport nicht wirken, sondern man soll die Character Set-Klausel im Import Statement nutzen.

                Da wäre erstmal zu klären, welche Methode beim Import zur Anwendung kommt. Ist es tatsächlich LOAD INFILE mit einer auf dem MySQL-Server liegenden Datei oder irgendwas mit PHP geschriebenes?

                dedlfix.

                1. Hello Dedlfix,

                  SET NAMES, oder besser der Aufruf der Funktion mysqli_set_charset() beziehungsweise bei Verwendung von PDO die charset-Angabe im DSN-String, muss dann eigentlich reichen. Wenn das dann trotzdem zu Fehlern kommt, machst du irgendwas nicht richtig, oder die Daten sind doch nicht korrekt kodiert.

                  Laut MySQL-Doku (wie unten schon zitiert und verlinkt) soll gena das bei Dateiimport nicht wirken, sondern man soll die Character Set-Klausel im Import Statement nutzen.

                  Da wäre erstmal zu klären, welche Methode beim Import zur Anwendung kommt. Ist es tatsächlich LOAD INFILE mit einer auf dem MySQL-Server liegenden Datei oder irgendwas mit PHP geschriebenes?

                  Das sollte der OP dann mal machen, wenn es immer noch nicht läuft ;-)
                  Aber seine Aussage

                  "Ich hab jetzt schon mehrere Sachen ausprobiert, aber immer sind die Umlaute nicht richtig."
                  

                  lässt doch vermuten, dass er genau diese "Definitionslücke" von MySQL getroffen hat, also eine der Stellen, an der es eben anders funktioniert, als man denkt :-)

                  Liebe Grüße
                  Tom S.

                  --
                  Es gibt nichts Gutes, außer man tut es!
                  Das Leben selbst ist der Sinn.
          2. Moin,

            Ich enkodiere die Datei doch nicht?!

            Zitat von oben:

            den kompletten String durch "utf8_encode" "geschleift"

            Du kannst ja mal Codeschnipsel posten und was sie aus gegebener Eingabe für eine Ausgabe erzeugen.

            Viele Grüße
            Robert

  2. Tach!

    Das importieren an sich funktioniert auch, jedoch werden die Umlaute nicht richtig eingetragen. Ich hab jetzt schon mehrere Sachen ausprobiert, aber immer sind die Umlaute nicht richtig.

    Damit kommt man auch nur zufällig an eine Lösung, die sich auch als "sieht nur so aus, als ob sie funktioniert" herausstellen kann. Zielgerichtetes Arbeiten sieht anders aus und setzt Grundlagenwissen voraus, in dem Fall zur Zeichenkodierung.

    Was ich bis jetzt gemacht habe:

    • "SET NAMES 'utf8'" als 1. Query

    Das teilt lediglich dem DBMS mit, dass man gedenkt, UTF-8-kodierte Daten zu schicken. Man muss dies natürlich auch tun, denn von allein wandelt sich weder mit dieser Deklaration noch sonstwie etwas nach UTF-8 um.

    • den kompletten String durch "utf8_encode" "geschleift"
    • nur die Teile wo auch Umlaute stehen durch "utf8_encode" "geschleift"

    utf8_encode() ist auch keine Zauberfunktion, der man alles mögliche Undefinierte übergeben kann und die am Ende UTF-8 erzeugt. Stattdessen kann sie lediglich gemäß ISO-8859-1 kodierte Daten nach UTF-8 konvertieren.

    Die Tabelle und die Spalten sind UTF-8 codiert.

    Das ist zumindest eine Voraussetzung, damit UTF-8-Daten abgelegt werden können, nachdem sie den Transport zum DBMS hin korrekt absolviert haben. Die einzige "Magie", die dabei auftritt ist eine Umkodierung, falls du auf der Verbindung eine andere Kodierung ausgehandelt und diese dann auch tatsächlich verwendet hast, dann werden die Daten in das Format der Tabellenfelder umkodiert. Auch rückwärts beim Auslesen geschieht dies, wenn die Verbindungskodierung eine andere ist.

    Hat jmd. eine Idee wie ich das Problem lösen kann?

    Erstmal die Ursache ermitteln. Die Lösung hängt von dieser ab.

    Wenn dir die Kodierung des CSV-Dokuments nicht bekannt ist, kannst du nur raten. Indizien können dabei helfen, den Kreis der möglichen Kodierungen einzuschränken. Ob es letztlich möglich ist, die wirkliche Kodierung herauszufinden, liegt daran, wie mehrdeutig sich deine Testdaten interpretieren lassen. Es gibt Kodierungen, die sind größtenteils ähnlich und unterscheiden sich nur in einzelnen Zeichen. Wenn du diese Unterschiede nicht herausfinden kannst, hast du eine potentielle Lücke im System, die sich erst später bemerkbar machen kann, wenn du dann diese Zeichen zum Verarbeiten übergeben bekommst.

    Lass dir einen Teil der Daten ausgeben, der Nicht-ASCII-Zeichen enthält, zum Beispiel Umlaute. Das Euro-Zeichen kann als weiteres Indiz genommen werden, um die hierzulande üblichen Kodierung ISO 8859-15 und Windows-1252 zu unterscheiden. Auch andere "exotische" Zeichen liefern oftmals brauchbare Indizien.

    Zur Testausgabe kann man sehr schön die Funktion urlencode() missbrauchen. Die lässt die Buchstaben und Ziffern unbeachtet, die im ASCII-Bereich liegen und alle gleich kodiert werden, und zeigt dir von den übrigen Zeichen die Bytewerte als Hex mit vorangestelltem % an.

    Aus diesen Indizien kann man nun Rückschlüsse ziehen, welche Kodierung vorliegen könnte. Der Rest ist einfach - wenn man sich letztlich sicher ist - die passende Umkodierfunktion zu suchen und anzuwenden.

    dedlfix.

  3. Hello,

    es gibt auch von MySQL einen Wizzard für Import und Export.

    Und weitern Input im Abschnitt

    The server uses the character set indicated by the character_set_database system variable to interpret the information in the file. SET NAMES and the setting of character_set_client do not affect interpretation of input. If the contents of the input file use a character set that differs from the default, it is usually preferable to specify the character set of the file by using the CHARACTER SETclause. A character set of binary specifies “no conversion.”
    

    Liebe Grüße
    Tom S.

    --
    Es gibt nichts Gutes, außer man tut es!
    Das Leben selbst ist der Sinn.
  4. Moin alle zusammen,
    erstmal danke für die ganzen antworten. Es war am Ende jedoch ein Fehler meinerseits.

    Robert B. hatte am Anfang gefragt, mit welcher Codierung die Daten in der CSV-Datei vorliegen würde. Weil ich angenommen habe, dass die Daten auch UTF-8 codiert vorliegen würden hab ich das natürlich geschrieben. Leider war dem nicht so.
    Wodurch kam es zu dem Irrtum?
    Ich hatte die Datei mit Excel erstellt und als CSV-Datei gespeichert. Nun hatte ich die Möglichkeit, zwischen CSV und CSV UTF-8 zu wählen. Ich hab natürlich CSV UTF-8 genommen und dachte damit sei der Käse gegessen. War aber nicht so.
    Weil keine eurer Antworten so richtig geholfen haben das Problem zu lösen (nicht böse gemeint) hab ich mir heute nochmal die CSV-Datei im Editor anzeigen lassen und die Codierung nachgeschaut. Und natürlich war das nicht UTF-8 sondern ANSI. Also hab ich die Datei nochmal als UTF-8 codiert gespeichert, meine anfänglichen Quellcode genommen und schwups schon hat es funktioniert. Jetzt werden alle üs, ös, äs, ß richtig angezeigt.

    Trotzdem nochmal danke für die ganzen Antworten
    Gruß
    MH

    1. Hallo MH,

      Robert B. hatte am Anfang gefragt, mit welcher Codierung die Daten in der CSV-Datei vorliegen würde.

      Weil keine eurer Antworten so richtig geholfen haben das Problem zu lösen

      Naja, zumindest hat dich Roberts Antwort auf den richtigen Weg geführt. Und die anderen Antworten waren auch nah dran, z.B. "Erstmal die Ursache ermitteln." 😜

      Bis demnächst
      Matthias

      --
      Rosen sind rot.
    2. Hallo MH,

      und du hast deinen Fehler "gebeichtet" und beschrieben, was Du falsch gemacht hast. Das tut nicht jeder. Respekt!

      Rolf

      --
      Dosen sind silbern