Datenbank Umlaute

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
VB_Lazarus
Beiträge: 85
Registriert: Do 23. Dez 2010, 19:10
OS, Lazarus, FPC: Windows 10 32/64bit, L 2.0.4 32bit, FPC 3.0.4 32bit
CPU-Target: 32Bit

Re: Datenbank Umlaute

Beitrag von VB_Lazarus »

Hallo,

das Problem (MSAccess) habe ich auch früh erkannt.
Für die Umlaute in Feldnamen habe ich keine Lösung.
Ich habe alle Feldnamen so gewählt, dass keine Umlaute darin enthalten sind.
Bei Leerzeichen funktioniert es mit den eckigen Klammern.
Du kannst auch mit Column(0....x) arbeiten. Dann bist du nicht an Feldnamen gebunden.

Gruß

hubblec4
Beiträge: 246
Registriert: Sa 25. Jan 2014, 17:50

Re: Datenbank Umlaute

Beitrag von hubblec4 »

Es ist schon eine Zeit vergangen seit dem letzten Eintrag, aber bei meiner suche kommt man immer wieder zu diesem Thema hier.

Es geht wieder einmal um eine String Umwandlung wegen den Umlauten.
So wie es hier im Thema beschrieben ist funktionierten UTF8toAnsi(AnsiToUTF8) bei mir bis Lazarus 1.4.4 auch.
Aber mit Lazarus 1.6 und FPC 3.0 sieht es wieder anders auch.

Im FPC 3.0 soll man ja nicht mehr alles umwandeln müssen was ich auch soweit bestätigen kann.
Nur funktioniert das in Verbindung mit MySQL 5.5 im Moment nicht bei mir.

Es soll ein einfacher Datensatz in die Datenbank eingepflegt werden

Code: Alles auswählen

INSERT INTO fragen (fr_frage) VALUES ('Störungen/Probleme bei der An-/Abreise');'


Wenn ich keinerlei Umwandlung vornähme dann steht da kein "ö" sondern Sonderzeichen.
Also dachte ich vll muss man hier doch was umwandeln aber es landet nie ein "ö" in der Datenbank.

hubble

Michl
Beiträge: 2349
Registriert: Di 19. Jun 2012, 12:54

Re: Datenbank Umlaute

Beitrag von Michl »

Es gab eine große Veränderung von FPC 2.6.4 zu 3.0.0. Erstmals hat man Einfluss darauf, welche Kodierung Strings bei der internen Verwendung haben. Daher stellt sich ab FPC 3.0.0 immer die Frage, welche Kodierung man intern nutzen will und extern benötigt wird. Entwickelt man reine FreePascal Programme, sind per Default interne Strings gleich des Systems kodiert. Erstellt man ein Programm, in dem die Unit LazUtils eingebunden wird (z.B. wenn man die LCL nutzt, also bei einer GUI-Anwendung), wird per Default eine interne String Kodierung von UTF8 genutzt (diese ist somit abwärtskompatibel). Will man trotzdem intern lieber Strings nutzen, die die gleiche Kodierung, wie das System haben, kann man -dDisableUTF8RTL nutzen (http://wiki.freepascal.org/Lazarus_with_FPC3.0_without_UTF-8_mode). Würde ich ohne driftigen Grund allerdings nicht empfehlen, da sonst alle Strings, die auf LCL-Controls zugreifen explizit umgewandelt werden müssen.

Sind diese Fragen geklärt, kann man mit SetCodePage einem String eine beliebige Kodierung zuweisen oder, wenn man LazUtils nutzt, eine Umwandlung à la UTF8ToCP1252 (Unit LConvEncoding) durchführen. Ausführliche Infos gibt es hier:
http://wiki.freepascal.org/FPC_Unicode_support
http://wiki.freepascal.org/Better_Unicode_Support_in_Lazarus

PS: Es gibt noch einige externe Komponenten, die noch nicht auf die neuen Anforderungen angepasst sind.
Zuletzt geändert von Michl am So 17. Jul 2016, 10:14, insgesamt 1-mal geändert.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

wp_xyz
Beiträge: 3440
Registriert: Fr 8. Apr 2011, 09:01

Re: Datenbank Umlaute

Beitrag von wp_xyz »

Du findest weiter oben in diesem Thread ein kleines Demo-Programm, in dem die Stringumwandlung gezeigt wird. Grundidee ist, nach dem Öffnen der Query für jedes Feld einen OnGetText und OnSetText Handler zu installieren, der die Stringumwandlung vornimmt. Allerdings hat dies auch bei meiner Tabelle mit einem 'ü' in einem Feld ein falsches Zeichen erzeugt. Schließlich habe ich mich mit dem Debugger in den Eventhandler gehängt und gesehen, dass der aus der Access-DB kommende String kein UTF16-String ist, wie in dem Beispiel angenommen, sondern ein Standard Ansi-String mit Codepage 1252. So hat's dann funktioniert:

Code: Alles auswählen

uses
  lconvencoding;
 
procedure TForm1.SQLQuery1AfterOpen(DataSet: TDataSet);
var
  i: Integer;   //diese Funktion wandelt die Umlaute um
begin
  for i:=0 to DataSet.Fields.Count-1 do
  begin
    if DataSet.Fields[i].DataType=ftString then
    begin
      DataSet.Fields[i].OnGetText:=@Text_von_DB_umwandeln;
      DataSet.Fields[i].OnSetText:=@Text_nach_DB_umwandeln;
    end;
  end;
end;
 
procedure TForm1.Text_von_DB_umwandeln(Sender: TField; var aText: string; DisplayText: BOOLEAN);
begin
  if not Sender.IsNull then begin
    aText := cp1252ToUTF8(Sender.AsString);
  end;
end;
 
procedure TForm1.Text_nach_DB_umwandeln(Sender: TField; const aText: string);
begin
  if aText <> '' then Sender.Value := UTF8ToCp1252(aText);
end;

Michl
Beiträge: 2349
Registriert: Di 19. Jun 2012, 12:54

Re: Datenbank Umlaute

Beitrag von Michl »

Vielleicht noch eine Ergänzung zum Code von wp_xyz.

Es wird von FreePascal-Seite empfohlen, Stringkonvertierungen mittels SetCodePage durchzuführen. Es betrifft in erster Linie Windows, doch falls man ein Programm schreiben will, welches international Verwendung finden soll, würde ich das auch empfehlen, da man somit unabhängig von den lokalen Codepages ist. Der Code könnte dann so aussehen:

Code: Alles auswählen

uses ..., Windows;
...
procedure TForm1.Text_von_DB_umwandeln(Sender: TField; var aText: string; DisplayText: BOOLEAN);
var
  rs: RawByteString;   
begin
  if Sender.IsNull then Exit;
  rs := Sender.AsString;
  SetCodePage(rs, GetACP, False)// Setzt System-Codepage (z.B. 1252), ohne die Codepoints zu konvertieren
  SetCodePage(rs, CP_UTF8, True)// Setzt Codepage UTF8, die intern von Lazarus bei Strings genutzt wird und konvertiert den String zu UTF8
  aText := rs;
end;
 
procedure TForm1.Text_nach_DB_umwandeln(Sender: TField; const aText: string);
var
  rs: RawByteString;   
begin
  if aText = '' then Exit;
  rs := aText;
  SetCodePage(rs, GetACP);   
  Sender.Value := rs;
end;

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

wp_xyz
Beiträge: 3440
Registriert: Fr 8. Apr 2011, 09:01

Re: Datenbank Umlaute

Beitrag von wp_xyz »

Für mich sind die direkten String-Konvertierungen klarer, zumal es diese auch schon vor FPC 3 gab, und viele Leute noch FPC 2.6.4 oder älter auf der Maschine haben.

Die Version des Beispiels, die die System-Codepage erkennt, wäre dann:

Code: Alles auswählen

procedure TForm1.Text_von_DB_umwandeln(Sender: TField; var aText: string; DisplayText: BOOLEAN);
begin
  if Sender.IsNull then Exit;
  aText := WinCPToUTF8(Sender.AsString);
end;

hubblec4
Beiträge: 246
Registriert: Sa 25. Jan 2014, 17:50

Re: Datenbank Umlaute

Beitrag von hubblec4 »

So bin wieder da.
Danke euch beiden für die Antworten.
Ich konnte bereits selber mittels...

Code: Alles auswählen

Unit LConvEncoding
 
UTF8ToCP1250()

... alles erledigen.

Mein SQL-Beispiel wird mittels der Komponente

Code: Alles auswählen

TSQLScript

in die Datenbank gefeuert. Daher habe ich dort keine "Query".
Meine Spalten Köpfe enthalten allerdings keine Umlaute, so dass ich dazu keine Aussagen machen kann.

hubble

Antworten