Zeichensatz Win1252 vs. UTF8

Forum zu diversen Themen rund um die Firebird-Programmierung

Moderator: martin.koeditz

Antworten
zappa2
Beiträge: 7
Registriert: Fr 5. Okt 2018, 10:59

Do 20. Jun 2019, 10:29

Meine Frage hier ist schon zig mal von anderen in diversen Foren gestellt worden, allerdings habe ich nirgendwo eine brauchbare Lösung finden können:

Ich programmiere in Lazarus und muss auf ziemlich viele 2.5-Firebird-DBs. Deren Varchars sind sämtlich mit Charset Win1252 definiert. Auf diesen DBs rödeln diverse Applikationen rum, die z.T. in Delphi5, einige in Delphi10 usw. geschrieben sind. Demzufolge ist ein Umbau der DB auf UTF8 leider keine Option - was mir das Liebste wäre.

Einzelne Datenfelder kann ich mit WinCPToUTF8 bzw. UTF8ToWinCP gerade biegen. Das funzt auch super.

Was mache ich aber mit Datenmengen-Queries? Bin zwar selbst kein Fan von DbGrid, ist aber Vorgabe.

In der IBConnection Win1252 im CharSet festzulegen bringt leider keinen Erfolg.
Benutzeravatar
martin.koeditz
Beiträge: 95
Registriert: Sa 31. Mär 2018, 14:35

Do 20. Jun 2019, 19:08

Hallo,

leider kenne ich DbGrid nicht. Arbeitet das intern mit UTF8?

Ich gehe davon aus, dass die DBs unangetastet bleiben sollen. Ist es möglich, den verwendeten Zeichensatz als Verbindungsparameter mit auf den Weg zu geben? Ich weiß allerdings nicht, ob dies was bringt.

Gruß
Martin
Martin Köditz
it & synergy GmbH
bfuerchau
Beiträge: 81
Registriert: Mo 7. Mai 2018, 18:09

Fr 21. Jun 2019, 11:08

Da heute so gut wie alle höheren Sprachen Strings grundsätzlich in Unicode verarbeiten, bist du eigentlich gezwungen die Datenbank sowie die Tabellen komplett auf UTF8 umzustellen.
Deine Konvertierungsfunktionen sollten eigentlich alle erstmal unnötig sein, da normalerweise alle verwendeten Zugriffe (ADO, .Net, ODBC) die Konvertierungen zwischen WinCP und UNICODE (das ist WideChar und nicht UTF8) vornehmen.
Deine FBConnection sollte also mit CHRSET=WIN1252 funktionieren.

Setze hier nicht auf UTF8, da du dann tatsächlich selber alles von UTF8 nach Unicode und zurück durchführen musst, was du ja auch zusätzlich mit dem Umweg über WINACP (hier also WIN1252) auch tust.

Auch beim Befüllen eines Commandobjektes wird die Konvertierung bei Verwendung von Parameter-Objekten berücksichtig, wenn diese als Type String oder WideChar definiert sind.
Solltest du den Commandstring allerdings selber zusammenbauen (nicht zu empfehlen), so wird alles in WinCP umgewandelt. Erst ab FB3 kann man auch die SQL's in Unicode (Widechar) absetzen.

UTF8 ist generell nur ein Transportwerkzeug (Variabel 1-4 Bytes).
DIe verarbeitbaren Darstellungen sind hier grundsätzlich nur
Byte (8-Bit SBCS SingleByteCharacterSet)
WChar (16-Bit UCS2 UniversalCharacterSet 2Btye)
UCS4 (32-Bit UniversalCharacterSet 4Btye, wird aber real noch nirgends unterstützt)
CString/String/BSTR (WChar[<n>])

Die Darstellung eines Frontends arbeitet ebenso in Strings und benötigt dann eine Unicodefähige Schrift (also WChars > 256).
Bei Webfrontends sieht es wieder etwas anders aus, hierführ gibt es das sog. HTML-Encoding, das dann meist 2 Varianten:
UTF8toHTML
UnicodeToHTML (Default, da wieder von WChar).
Dann wird z.B. aus unserem "Ü" ein "&Uuml;".

Deine WinCP-Routinen haben auch noch den Nachteil, dass sie mit der aktuellen Codepage von Windows umgehen. Kommst du mal auf einen Client/Server mit einer anderen Codepage (WIN1251 = Osteuropa) passen deine Konvertierungen nicht mehr!

Desweiteren:
Dein Frontend wie DBGrid ist Unicodefähig erlaubt also auch die Eingabe von anderen Sprachen. Diese gehen dir aber bei der Übersetzung nach Win1252 verloren, häufig werden sie durch "?" ersetzt.
bfuerchau
Beiträge: 81
Registriert: Mo 7. Mai 2018, 18:09

Fr 21. Jun 2019, 12:08

Nachtrag:
Wenn du Standardsteuerelemente verwendest, wie DBGrid, dann unterstützen diese auch direkte Datenbindung.
Dies klappt aber nur, wenn die Inhalte auch bindbar sind, also von typ Char oder Wchar und nicht native UTF8!
Du kannst dir das Leben da also massiv vereinfachen, wenn du den Charset der DB in der Verbindung verwendest.
Das klappt dann auch ebenso, wenn du die DB später mal auf UTF8 umgestellt hast, da der FB-Treiber dann Strings verwendet.
zappa2
Beiträge: 7
Registriert: Fr 5. Okt 2018, 10:59

Fr 5. Jul 2019, 14:57

Vielen Dank für die ausführlichen Infos.

Wenn ich der Chefentwickler wäre, würde ich die DB nach UTF8 umstellen (über den Umweg ExtractMetadata=>Edit=>Neuaufbau). Leider bin ich hier nur ein Nebendarsteller, muss mich also dem Druck von oben beugen. Unglaublich, wieviel Zeit man mit diesem Quatsch verballert, ohne irgendwie befriedigend weiter zu kommen.
bfuerchau
Beiträge: 81
Registriert: Mo 7. Mai 2018, 18:09

Sa 6. Jul 2019, 16:11

Warum kommst du nicht weiter?
Connecte einfach mit Win1252, so wie die DB definiert ist.
Und lass einfach den Quatsch mit der von/nach-UTF8-Konvertierung.
Da WIN1252 eben nur westeuropäisch kann, können eben keine osteuropäischen oder sonstigen Zeichen in der DB gespeichert werden.
Den Steuerelementen und den Programmen ist das egal, da Strings generell Unicode sind (UCS2) und der Treiber die Codewandlung von UCS2 in WIN1252 und umgekehrt erledigt.
Sollte irgendwann die DB in UTF8 umgewandelt sein, brauchst du nur die Connection auf UTF8 anzupassen, ansonsten läuft alles so weiter wie bisher.
Auch dann ist eine zusätzliche Konvertierung nicht erforderlich, das ist Aufgabe des Treibers.
Das Leben kann so einfach sein.
Antworten