Zeichensatz-Probleme beim Schreiben in MariaDB

  • Hallo zusammen!


    Ich habe eine Datenbank erstellt, in die ich Textblöcke in unterschiedlichen Sprachen hineinschreiben möchte. Diese "Kopierarbeiten" (Insert) funktionieren wunderbar, so lange keine chinesischen oder russischen Texte geschrieben werden sollen. Diese werden dann als Fragezeichen übertragen.

    Nach nun etlichen Stunden des Recherchierens und Probierens gehen mir langsam die Ansätze aus. Außer, dass das Problem etwas mit den Eingestellten/ übertragenen Zeichensätzen zu tun hat (mutmaßlich) hab ich keine Ahnung was ich noch ausprobieren könnte (oder wo das Problem liegt).


    Anbei ein Code-Schnipsel, dass die Problematik umschreibt. (Bei Nachhaken gehe ich gerne tiefer)

    Ich habe zum Test ein kleines Array angelegt, in dem irgendwelche unterschiedlichen Contents drin sind.

    Dann lasse ich mir diese mit _ArrayDisplay anzeigen. -> das Ergebnis ist korrekt

    Ich schreibe einen der problematischen Texte in eine Textdatei. -> das Ergebnis ist korrekt

    Bis dahin scheint mir klar, dass mit dem Inhalt des Arrays soweit passen dürfte.


    Nun kommt es:

    in der Datenbank steht dann folgendes:


    Content

    ----------------------------------

    ???????? ??????? ??? ????? ???????

    ??????????

    Loret ipsum äöüß


    An der kleinen Schreib-Funktion von mir sollte es nicht liegen: Diese schreibt ansonsten alle meine Arrays zu meiner Zufriedenheit in meine Datenbanken ;)

    Also gibt es irgendwo ein Problem mit den verwendeten oder angenommenen Zeichensätzen.


    UTF8 als Basis scheint mir geeignet um alle meine Anforderungen abzudecken. Deshalb hab ich schon an den Einstellungen der Datenbank herumgeschraubt. Ein Blick in die Einstellungen der Datenbank:

    SHOW VARIABLES LIKE 'character_set\_%'

    character_set_clientutf8
    character_set_connectionutf8
    character_set_databaseutf8
    character_set_filesystembinary
    character_set_resultsutf8
    character_set_serverutf8
    character_set_systemutf8


    Wenn ich die Daten mit anderen Programmen (z.B. DBeaver oder aus PhpMyAdmin) in die Datenbank schreibe, dann klappt das alles.

    Ergo:

    Die Datenbank kann es.

    Das Array/Autoit kann es auch (eigentlich)

    ->irgendwo ist ein Problem beim Übertragen als "UTF8"


    Für alle Hinweise dankbar,


    Gruß Robbytobi

  • Vielleicht doch noch ein bisschen tiefer:

    Hier die Funktion zum Schreiben des Arrays. Diese Funktion baut aus den in der ersten Zeile enthaltenen Spaltennamen ein "Basisstatement" auf und schreibt dann Zeilenweise die Daten an die richtigen Stellen

    Ich übergebe hierbei die Verbindungsdaten des Servers als Array an eine entsprechend leicht modifizierte Funktion "_SQLConnect"


    Das alles nur mal erwähnt, damit a) ihr wisst wie ich mich mit dem Server verbinde und (ansonsten erfolgreich) kommuniziere. Vielleicht hilft das ja jemand.

  • UTF8 als Basis scheint mir geeignet um alle meine Anforderungen abzudecken.

    Ja, denke ich auch, nur in SciTE hast du es wohl nicht eingestellt, denn das arbeitet per Default ja mit der ANSI-Codepage.


    SciTE kannst du auf UTF-8 umstellen, indem du diese Zeilen in der SciTEUser.properties hinzufügst bzw. änderst:

    Code: SciTEUser.properties
    # Internationalisation
    # Unicode
    code.page=65001
    #~ output.code.page=850
    output.code.page=65001
    #~ output.code.page=0

    So sieht das bei mir aus...



    Alternativ sollte es funktionieren, wenn du den String vor dem Absenden an die DB nach UTF-8 konvertierst. Dafür hat die Windows-API ein paar Funktionen:

    _WinAPI_WideCharToMultiByte und _WinAPI_MultiByteToWideChar bzw. _WinAPI_MultiByteToWideCharEx


    Du brauchst dann wohl _WinAPI_WideCharToMultiByte... $iCodePage musst du dann auf 65001 setzen.



    Gun-Food

    Habe soeben einen Fehler entdeckt... bei aufgeklappten Code-Tags wandert das "Code" beim Scrollen der Seite mit, was aber eigentlich nicht sein sollte.


    Hier ein Bild, um es verständlich zu machen:

  • Nachdem ich zuerst die SciTEUser.properties angepasst hatte ist noch gar nichts passiert. Die Zeichen wurden durch die berühmten Fragezeichen ersetzt.


    Eine erste Veränderung hat nun der Einsatz von _WinAPI_WideCharToMultiByte ergeben: Folgendes Array wird wie unten stehend an der Console ausgegeben und kommt dann auch so in der Datenbank an....

    Code
    Local $sUTFcontent[4][1]
    $sUTFcontent[0][0] ="Content"
    $sUTFcontent[1][0] ="облачные решения для любой отрасли"
    $sUTFcontent[2][0] ="業界に特化したモダン"
    $sUTFcontent[3][0] ="Loret ipsum äöüß"
    
    ;Consolen-Outout:
    ;INSERT INTO testcont (Content) VALUES ('облачные Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð»ÑŽÐ±Ð¾Ð¹ отраÑли')
    ;INSERT INTO testcont (Content) VALUES ('業界ã«ç‰¹åŒ–ã—ãŸãƒ¢ãƒ€ãƒ³')
    ;INSERT INTO testcont (Content) VALUES ('Loret ipsum äöüß')

    Ergo: Ich hab zwar noch nicht die richtige Quell/Ziel -Codepage, aber ich mutmaße, dass das, was ich an die Datenbank schicke mir richtig übertragen und auch von der Console entsprechend angezeigt wird. Also dafür schon mal einen kleinen Dank an dich! (nach zwei Wochen an diesem Thema ist das ein echter, erster Fortschritt!! :party: )

    Die Frage ist nun nur noch, wo das Problem liegen könnte? Wenn ich das Array in eine Datei schreibe und es mit Notepad öffne, dann zeigt er mir UTF8 an. Auch ohne, dass ich erst was konvertiere.

    Was mich irritiert: in der Beschreibung von _WinAPI_WideCharToMultiByte steht "...Converts a UTF-16 (wide character) string to a multibyte string...". Ist das Problem vielleicht, dass ich das falsche "Quellformat" habe?

  • Wenn du SciTE auf UTF-8 umgestellt hast und der Text in deinem Post #4 in der Scite Editor-Pane korrekt angezeigt wird, darfst du die Zeichen nicht mehr konvertieren. Die sollten dann - so wie sie sind - korrekt in der DB ankommen, da die Quell- und Ziel-Codepage ja gleich sind.


    In der Scite Output-Pane (Consolen-Output wäre in einer CMD) werden die Zeichen ja via ConsoleWrite ausgegeben... und ConsoleWrite konvertiert die Zeichen vor der Ausgabe immer nach ANSI. Deswegen musst du sie hier dann doch konvertieren... s. Bild.


    Wenn diverse Zeichen nicht korrekt, sondern als Fragezeichen angezeigt werden, bedeutet dies, dass diese mit der verwendeten Schriftart nicht darstellbar sind.


    So sollte das auch bei dir aussehen...

  • Ich habe nun folgenden Status:

    Soweit stimmt das. Ich konvertiere den Text vor der Konsolenausgabe und er erscheint richtig in der Konsole. Allerdings kommen in der DB nun wieder nur Fragezeichen an:


    Zwei Fragen: Wo kann man die Statusleiste unten denn so einstellen? Ich hab dort nur einen Eintrag. Den kann ich per Klick toggeln. Aber das Encoding ist nicht dabei? (Ich denke zwar, dass das stimmt, aber kann es leider nicht final bestätigen)

  • Allerdings kommen in der DB nun wieder nur Fragezeichen an:

    Wie genau hast du das denn überprüft? - Das Bild unter deinem Text (Content)... wie bist du an den Text aus der DB gekommen und womit hast du ihn wo ausgegeben? Und nein, da kommen keine Fragezeichen an!!!


    Evtl. muss der Text vor dem Senden doch mit einer *MultiByte*-Funktion konvertiert werden... also entweder nach MultiByte oder nach WideChar. Das musst du aber selbst austesten, weil habe kein MariaDB.


    Die Werte für die Statusleiste kannst du in der SciTEUser.properties setzen. Ich habe dir mal meine als Anhang dazugelegt... da findest du sie fast am Ende.

  • Erstmal Dank für die User-Properties. Das entsprechende Fragment ist erfolgreich eingebaut und stimmt mit dem Screenshot überein.


    Die Daten in der Datenbank hab ich sowohl mit PhpMyAdmin als auch mit DBeaver angeschaut. Wenn ich die Daten dort damit (mit beiden) versuchsweise mit den korrekten Zeichen überschreibe, dann erscheinen diese auch dort korrekt. Ich werd mal versuchen die Daten vor dem Absenden "doch" zu konvertieren...

  • #Topic Solved#

    Code
    ;$sSQLstring enthält ein gültiges SQL-Statement, das wie folgt konvertiert werden muß:
            $sSQLstringUTF8 = _WinAPI_WideCharToMultiByte($sSQLstring,65001)                ;Konvertierung
            ConsoleWrite($sSQLstringUTF8&@CRLF)                                              ;Ausgabe an Konsole
            $oQueryResult = _SQLQuery($oConn, $sSQLstringUTF8)                                ;Ausgabe an DB

    Das Problem war, dass MariaDB eine "ganz spezielle" Beziehung zu UTF8 hat! Auch wenn das nichts mehr mit AutoIt zu tun hat, will ich noch folgende Lösungsansätze hier posten, damit der nächste, der hier verzweifelt, auch fündig wird:

    Grob gesagt ist UTF8 die falsche Wahl. Um zum Ziel zu kommen ist "UTF8MB4" notwendig gewesen. Hierzu musste ich in der Konfigurationsdatei des Servers my.cnf folgende Anpassungen vornehmen:

    Code
    [client]
    default-character-set = utf8mb4
    
    [mysql]
    default-character-set = utf8mb4
    
    [mysqld]
    character-set-client-handshake = FALSE
    character-set-server = utf8mb4
    collation-server = utf8mb4_unicode_ci

    Natürlich müssen dann noch die Datenbank, Tabelle(n) und Spalte(n) entsprechend angepasst werden. Dann sieht das Ergebnis so aus:

    Sowohl das Array, als auch die Konsole zeigen die identischen Daten und diese kommen auch korrekt in der Datenbank an.


    Soweit ich das beurteilen kann: Case closed!

    Vielen Dank für deine Hilfe Bitnugger !

  • Grob gesagt ist UTF8 die falsche Wahl. Um zum Ziel zu kommen ist "UTF8MB4" notwendig gewesen.

    Hier findet du auch eine Erklärung dazu, warum dem so ist:

    What is the difference between utf8mb4 and utf8 charsets in MySQL?
    What is the difference between utf8mb4 and utf8 charsets in MySQL? I already know about ASCII, UTF-8, UTF-16 and UTF-32 encodings; but I'm curious to know…
    stackoverflow.com

    UTF-8 is a variable-length encoding. In the case of UTF-8, this means that storing one code point requires one to four bytes. However, MySQL's encoding called "utf8" (alias of "utf8mb3") only stores a maximum of three bytes per code point.

    So the character set "utf8"/"utf8mb3" cannot store all Unicode code points: it only supports the range 0x000 to 0xFFFF, which is called the "Basic Multilingual Plane". See also Comparison of Unicode encodings.