![]() |
Datenbank: Firebird • Version: 2.5 • Zugriff über: UIB
Firebird Character Set ändern
Hallo zusammen,
Beim Portieren eines älteren Datenbankprojektes von Delphi 2006 auf XE2, also Unicode, bin ich auf ein Problem mit meiner Datenbank gestoßen. In der DB ist soweit ich das überblicke kein Character set oder collation hinterlegt; die Daten sind aber als UTF8 hinterlegt (hier muss ich noch überprüfen, ob das wirklich für alle chars und varchars gilt) Bisher wurde mittels AnsiToUtf8() UTF-8 Codiert und direkt in das SQL-Statement eingebettet
Delphi-Quellcode:
query.sql.text := 'update mytable set name= ' + SqlQuoteAndEscape(AnsiToUtf8('Müller')) + ...
Bei der Umstellung auf Unicode wird das vermutlich so nicht mehr funktionieren, außerdem möchte ich in dem Zuge gleich auf prepared statements umstellen. Das manuell nach UTF8 zu codieren und dann als RawByteString übergeben funktioniert zwar,
Delphi-Quellcode:
query.Params.ByNameAsRawByteString['name'] := UTF8Encode('Müller');
ich frage mich aber, ob es nicht sinnvoller/richtiger wäre, die Charset-Information in der Datenbank zu hinterlegen, dann müsste es ja reichen, einfach den (Unicode)String zuzuweisen:
Delphi-Quellcode:
query.Params.ByNameAsString['name'] := 'Müller';
Hier stehe ich nur vor der Frage, ob das so einfach geht bzw. welche Nebenwirkungen das haben kann. Laut Firebird-Dokumentation müsste das Umstellen ja mit
Code:
möglich sein?
alter character set utf8 set default collation unicode_ci_ai;
[Edit: Anscheinend wird damit die default Collation für das angegebene charset geändert, und nicht wie von mir angenommen das default charset der DB] Nachdem ich die collations noch nicht so ganz verstanden habe und es doch diverse Themen zu Konvertierungsproblemen mit nicht unterstützten/vorhandenen collations gibt, frage ich lieber einmal zu häufig. Also die Fragen nochmal zusammengefasst: 1. Kann ich relativ gefahrlos den Zeichensatz meiner Datenbank ändern? 2. Muss ich dabei auf etwas aufpassen? 3. Gibt es Gründe, warum die DB nichts über den verwendeten Zeichensatz wissen soll und ich das besser so lasse wie es ist? Danke für's Lesen (und hoffentlich auch Antworten :)) |
AW: Firebird Character Set ändern
Ich habe mein Update jetzt durchgeführt. Für den Fall, dass jemand eine ähnliche Problemstellung hat (oder mir sagt, dass irgendwas von dem gemachten ganz gefährlich oder böse ist), beschreibe ich mal, was ich getan habe:
- einen offiziellen Weg, bei einer bestehenden Datenbank das default charset zu ändern habe ich nicht gefunden. Nachdem meiner Recherche zufolge bei Firebird das Client-Charset und Server-Charset zusammenpassen muss, ist das eh reine Metadata. Geändert werden kann das trotzdem in den Systemtabellen mit
Code:
- bei der UIB muss dann auf der Connection noch das (Client-)Chaset angegeben werden:
update RDB$DATABASE set RDB$CHARACTER_SET_NAME = 'UTF8';
Delphi-Quellcode:
- Natürlich gab es noch Tabellen, die noch ANSI-Daten hatten. Nachdem das nur wenige Tabellen mit wenigen Einträgen waren, lauf ich da einzeln drüber und codiere von Hand um. Hier habe ich noch kein Charset auf der Verbindung geändert. Das Projekt ist auch noch auf Delphi 2006, deswegen auch kein ByNameAsRawByteString.
// set database, user, password, client dll
DbConection.CharacterSet := csUTF8; DbConection.Connected := true;
Delphi-Quellcode:
Grüße
DBQueryRead.SQL.Text := 'select id, link_name from mytable';
DbQueryWrite.SQL.Text := 'update mytable set link_name=:Name where id=:ID'; // ignore int columns and columns with guaranteed pure ASCII data DbQueryRead.Open(); while not DbQueryRead.Eof do begin DbQueryWrite.Params.ByNameAsInteger['ID'] := DbQueryRead.Fields.ByNameAsInteger['id']; DbQueryWrite.Params.ByNameAsString['Name'] := AnsiToUtf8(DbQueryRead.Fields.ByNameAsString['link_name']); DbQueryWrite.Execute(); DbQueryRead.Next(); end; Chris |
AW: Firebird Character Set ändern
Auch wenn es schon 'ne Weilte her ist:
Hatte gerade ein ähnliches Problem mit 'ner Firebird 3-Datenbank. Die Lösung war:
SQL-Code:
Statt UTF8 nehmen man ggfls. das, was man benötigt.
alter database set default character set UTF8
Das
SQL-Code:
wird mit 'nem Fehler quittiert, ein Update auf die Tabelle ist nicht zulässig.
update RDB$DATABASE set RDB$CHARACTER_SET_NAME = 'UTF8';
|
AW: Firebird Character Set ändern
Hallo,
in FB3 ist ein Schreib-Zugriff auf die Systemtabellen nicht mehr erlaubt. |
AW: Firebird Character Set ändern
also ich würde so nicht vorgehen , da die verschiednen Zeichensätze verschiedene Byte Größen haben ändern sich die benötigten Puffergrößen und man kann sich mit der Umstellung von z.b Win1252 1-Byte auf UTF-8 4 Byte die maximalen Größen der Records in Firebird (64 KB) überschreiten,
imho richtig wäre die folgende Vorgehensweise Metatdaten Exportieren Charset(s) anpassen Datenbank neu erstellen prüfen ob alle Tabellen übernommen wurden , ggf Tabellenstruktur überarbeiten und dann die Daten von der alten DB in die Neue DB pumpen mit einem Programm das auch die Charset Transformation beherrscht z.b. ![]() fbclone Automatically exported from code.google.com/p/fbclone FBClone can clone a ![]() Latest version have flags to ignore charset definitions from source database metadata so you can "normalize" a database with multiple charsets to only one, for instance, UTF8 (see -ics and -ko flags in conjunction to -tc UTF8) hth Hannes |
AW: Firebird Character Set ändern
In rdb$database ist nur der Default Charset hinterlegt, der wird bei neuen Tabellenfeldern genommen, wenn
nicht explizit was anderes angegeben wird. Das hat aber keinerlei Einfluß auf bereits existierende Tabellen. Wir machen das immer so: 1. Datenbank mit geeignetem Tool in ein Script exportieren mit Metadaten, Daten und auch Blobs (geht z.B. in der IBExpert Vollversion). Charset Angaben nicht exportieren bzw. per suchen/ersetzen löschen. 2. Eine neue UTF8 DB anlegen 3. Das in 1. erzeugte Script mit dem alten Charset (oder bei NONE trotzdem ISO8859_1) an die UTF8 DB connecten und ausführen. Dabei übernimmt Firebird selber die Konvertierung aller benutzten Sonderzeichen in geeignete UTF8 Zeichen. 4. Evtl. Limitierungen werden zu Fehlern führen, z.B. char oder varchar deklarationen länger als 8191 Diese falls vorhanden im Script ersetzen und noch mal probieren. der Vorgang kann mit ibec_extract_metadata in ibexpert auch per script automatisiert werden, wenn man das für mehrere Kunden/DB braucht |
AW: Firebird Character Set ändern
Zitat:
madas |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:59 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz