Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi SQLight, Unicode, UTF8 nicht korrekt (https://www.delphipraxis.net/208067-sqlight-unicode-utf8-nicht-korrekt.html)

jziersch 4. Jun 2021 09:20

Datenbank: SQLight • Version: 3 • Zugriff über: Firedac

SQLight, Unicode, UTF8 nicht korrekt
 
Hallo,



ich speichere in meiner SQLight Datenbank (StringFormat=Unicode) den Text
UnicodeΩ₤ABCÄÖÜ

bekomme aber dies zurück:
UnicodeO£ABCÄÖÜ

Das Zeichen Omega wurde also in ein O umgewandelt und das Pfundzeichen ist auch verändert.

Ich habe die Datenbank Datei (*.db) in Notepad++ im Modus UTF8 angesehen und sehe hier bereits die falsche Schreibweise. Die Umlaute wurden also korrekt in UTF8 gewandelt, nicht aber das Omega. Viele andere Zeichen sind betroffen, auch bullets.

Habt Ihr einen Tip wie ich das am besten lösen kann, also exakt das aus der DB rausbekomme was ich reingeschrieben habe? Ich verwende Delphi 10.4 mit FireDac.

Viele Grüsse,
Julian

Uwe Raabe 4. Jun 2021 09:52

AW: SQLight, Unicode, UTF8 nicht korrekt
 
Kannst du das mit einem kleinen Beispielprogramm reproduzieren?

jziersch 4. Jun 2021 10:35

AW: SQLight, Unicode, UTF8 nicht korrekt
 
Danke, ich kann den Fehler so reproduzieren:

Code:
var s, s2 : string;
    a : AnsiString;
begin
  s := 'Unicode' + #937 + #8356 + 'ABCÄÖÜ';
  a := UTF8Encode(s);
  s2 := UTF8Decode(a);
  if s=s2 then ShowMessage('UTF8 Encode OK'); // <-- OK


  WPData.DBQuery.SQL.Text := 'UPDATE "WPFILEITEMS" SET NAME=:NAME WHERE FILE_ID=1';
  WPData.DBQuery.ParamByName('NAME').AsString := s;
  WPData.DBQuery.ExecSQL;

  WPData.DBQuery.SQL.Text := 'SELECT NAME FROM "WPFILEITEMS" WHERE FILE_ID=1';
  WPData.DBQuery.OPEN;
  s2 := WPData.DBQuery.FieldByName('NAME').AsString;
  WPData.DBQuery.Close;

  if s<>s2 then
       ShowMessage( 'Fehler:' + s + '#' + s2 ) //<--- Wird aufgerufen
  else
       ShowMessage( s + '=' + s2 );
end;
NAME ist ein VARCHAR

und die Connection wird so geöffnet

Code:
with dbMain.Params do begin
               Clear;
               Add('Database=' + systemdirectory + 'wpdata.db' );
               Add('DriverID=SQLite');
               Add('SharedCache=False');
               Add('LockingMode=Normal');
               Add('StringFormat=Unicode');
end;
Auffällig ist, dass in der Datenbank (*DB) UTF8 steht, also UnicodeO£ABCÄÖÜ und offenbar hier das Omega bereits zu einem O wurde wogegen die Umlaute UTF8 sind.

jziersch 4. Jun 2021 10:41

AW: SQLight, Unicode, UTF8 nicht korrekt
 
Ich hab den Fehler gefunden. Mit AsWideString gehts:

Code:
  WPData.DBQuery.SQL.Text := 'UPDATE "WPFILEITEMS" SET NAME=:NAME WHERE FILE_ID=1';
  WPData.DBQuery.ParamByName('NAME').AsWideString := s;
  WPData.DBQuery.ExecSQL;

  WPData.DBQuery.SQL.Text := 'SELECT NAME FROM "WPFILEITEMS" WHERE FILE_ID=1';
  WPData.DBQuery.OPEN;
  s2 := WPData.DBQuery.FieldByName('NAME').AsWideString;
  WPData.DBQuery.Close;

himitsu 4. Jun 2021 15:18

AW: SQLight, Unicode, UTF8 nicht korrekt
 
String (in Delphi2009 und neuer) ist aber auch Unicode. :gruebel:
Und AsAtring sollte doch vom Typ String sein?

Das TField muß dennoch ein TWideStringField (oder Nachfahre) sein, denn TStringField ist ANSI.

Aber vielleicht macht AsWideString bei einem TStringField intern auch ein UTF8Encode/UTF8Decode. :gruebel:




Dann kommt dazu, speichert Datenbank/Tabelle/Feld das Unicode (UCS2, UTF-16, UTF-8 o.Ä.)
und arbeitet auch die Connection mit Unicode.

jziersch 4. Jun 2021 17:39

AW: SQLight, Unicode, UTF8 nicht korrekt
 
Hallo himitsu,

das mit AsString hatte ich auch so vorausgesetzt.

Wenn man aber FieldByName bzw. ParamByName verwendet macht es offenbar einen Unterschied, ob man AsString oder AsWideString verwendet. Bei AsWideString findet intern ein UTF8Encode statt - bei AsString auch, aber es wird ein ANSIfizierter String an diese Umwandlung übergeben. Dadurch werden Umlaute ÄÖÜ... korrekt in UTF8 in die Datenbank gespeichert, andere Zeichen aber gewandelt: Omega->O und andere Zeichen werden einfach nur ?.

Jetzt, nachdem ich alle AsString als AsWideString gewandelt habe gehts prima.

Viele Grüsse,
Julian

himitsu 4. Jun 2021 17:57

AW: SQLight, Unicode, UTF8 nicht korrekt
 
Wir hatten mit AsString noch nie Probleme.

Wie gesagt, welchen Typ hat das TField (TStringField oder TWideStringField)
und welches Transport-Encoding hat die Connection?

Und was zeigt z.B. ein TDBEdit an, wenn man es an dieses DataSet/DataSource hängt?


Bei dir scheint ja das TField oder eventuell die Connection ANSI (bzw. UTF-8) zu haben

jziersch 4. Jun 2021 21:56

AW: SQLight, Unicode, UTF8 nicht korrekt
 
Die paar erstellten Felder sind TWideStringField.

Das war auch der Hinweis auf die Lösung, denn als ich mal probiert habe FormatString auf UTF8 zu ändern kam promt hier ein typ-mismatch.


Ich verwende in meinen queries nur diese Felder nicht, auch kein DBGrid. Wie in meinem Code gezeigt, kommt das Problem bei der Verwendung von FieldByName und ParamByName.

himitsu 5. Jun 2021 11:19

AW: SQLight, Unicode, UTF8 nicht korrekt
 
Nja, ein DB-Control (TDBEdit) kurz dranzuhängen war nur dazu gedacht, um mal nachzusehn, was das anzeigt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:12 Uhr.

Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf