MySQL "Data too long for column" obwohl Length korrekt

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Antworten
pschoett
Beiträge: 36
Registriert: Sa 7. Feb 2015, 11:48

MySQL "Data too long for column" obwohl Length korrekt

Beitrag von pschoett »

Hallo allerseits,
beim Schreiben von Daten in eine MySQL-Tabelle erhalte ich den MySQL Fehler "Data too long for column Feld_a".

Die MySQL Tabelle verwendet die Engine MyISAM und den Zeichensatz Utf-8. Feld_a ist als VarChar(30) definiert. Length(MeinString)=30. Sollte also eigentlich passen. Der DBFehler tritt später auch nochmal bei einem anderen Feld_b vom Typ VarChar(40) auf. Dort ist der zu schreibene String dann auch exakt 40 Zeichen lang.

Was in beiden Fällen gleich ist, dass in den Strings Umlaute vorkommen. Könnte es sein, dass die maximale Stringlänge eines VarChars bei Utf-8 mit Umlauten anders zu berücksichtigen ist?

Irgendeine andere Idee?

Gruß,
Peter

pschoett
Beiträge: 36
Registriert: Sa 7. Feb 2015, 11:48

Re: MySQL "Data too long for column" obwohl Length korrekt

Beitrag von pschoett »

Vielleicht, sollte ich ergänzen, dass ich das ganze natürlich über Lazarus versuche. Die Quelldaten stammen aus einer FoxPro Datenbank, die per TODBCConnection angesprochen wird. Das Ziel ist MySQL, das direkt mit TMySQL51Connection angesprochen wird.

Außerdem geht es hier nur um einige wenige Ausnahmefehler beim Schreiben nach MySQL. Der Großteil der INSERT-Befehl funktioniert ohne Probleme.

Desweiteren verwende ich Lazarus 1.2.6 mit FPC 2.6.4 unter Win7 Prof x64. MySQL 5.1.56 auf Win2k8r2 Server.

Und noch eine Ergänzung. Ich schreibe nach MySQL per SQLQuery.SQL.Text mit INSERT und Variablen. Erst wenn ich SQLQuery.ExecSQL ausführe, wird der Fehler angezeigt. D.h. es handelt sich tatsächlich um eine Meldung von MySQL.
Inzwischen habe ich einiges bzgl dieses Fehlers mit UTF-8 und Umlaute bzw Sonderzeichen gelesen und es könnte sich um einen Bug in MySQL handeln. Andererseits sind die Meldungen aus 2006 und die MySQL Version 5.1.56 aus dem Jahr 2011. Ich gehe davon aus, dass solch ein Bug in den fünf Jahren behoben wurde.

TBug
Beiträge: 177
Registriert: Mi 2. Sep 2015, 11:09
OS, Lazarus, FPC: Lazaurus 2.2.4 FPC 3.2.2
CPU-Target: Windows 32/64bit

Re: MySQL "Data too long for column" obwohl Length korrekt

Beitrag von TBug »

Wie ist die Porperty CharSet der TMySql51connection-Komponente eingestellt?

hde
Beiträge: 556
Registriert: Mi 11. Aug 2010, 02:56

Re: MySQL "Data too long for column" obwohl Length korrekt

Beitrag von hde »

TBug hat geschrieben:Wie ist die Porperty CharSet der TMySql51connection-Komponente eingestellt?

welche Datenbankkomponenten? Lazarus oder Zeos?
Welcher Character Set ist bei mySQL eingestellt?
UTF8 Umlaute belegen mehrere Bytes

pschoett
Beiträge: 36
Registriert: Sa 7. Feb 2015, 11:48

Re: MySQL "Data too long for column" obwohl Length korrekt

Beitrag von pschoett »

@TBug @hde
Wie ist die Porperty CharSet der TMySql51connection-Komponente eingestellt?

TMySQL51Connection.Charset = // ist leer und habe ich bisher nicht verwendet.
welche Datenbankkomponenten? Lazarus oder Zeos?

Die Standard Lazarus Komponenten unter SQLdb.
Welcher Character Set ist bei mySQL eingestellt?

In MySQL ist für die Tabellen als Zeichensatz utf8 eingestellt.

Im Wiki zu Lazarus/Freepascal habe ich den folgenden Artikel http://wiki.freepascal.org/mysql#Lazarus.2C_MySQL_and_UTF-8 gefunden:
Lazarus, MySQL and UTF-8

The following may be required for other codepages/character sets as well

UTF-8 Unicode is a convenient multibyte character set encoding, that allows working with multilingual texts without requiring WideStrings. It is supported both by Lazarus SQLdb components and by MySQL since version 4.1 by choosing the appropriate character set.

However, simply setting this encoding as default for

your tables and
the MySQL connection component (e.g. TMySQL51Connection.CharSet:='UTF8';)

will result in incorrect storage and retrieval of UTF-8 strings: any accented/international character will show up as question mark (?). Apparently, the reason for this is that MySQL client library is compiled to expect Latin1 character set by default.

In order to enable proper communication between Lazarus, MySQL client library and MySQL server, additional two queries need to be executed each time a connection to the database is established:

SET CHARACTER SET `utf8`

and

SET NAMES 'utf8'

The first query will ensure your application receives strings in correct encoding, and the second tells MySQL not to convert strings it receives from your application.

Wenn ich das richtig verstehe, brauche ich die Ansi-Strings aus FoxPro gar nicht mit Ansi2utf8 zu konvertieren, sondern es sollte automatisch richtig eingetragen werden - vorausgesetzt ich setze brav das SET CHARACTER SET und SET NAMES wie oben angegeben. Richtig?

pschoett
Beiträge: 36
Registriert: Sa 7. Feb 2015, 11:48

Re: MySQL "Data too long for column" obwohl Length korrekt

Beitrag von pschoett »

In order to enable proper communication between Lazarus, MySQL client library and MySQL server, additional two queries need to be executed each time a connection to the database is established:
SET CHARACTER SET `utf8`
and
SET NAMES 'utf8'
The first query will ensure your application receives strings in correct encoding, and the second tells MySQL not to convert strings it receives from your application.

Mir ist nicht klar, was genau gemeint ist mit "each time a connection to the database is established".
Was bedeutet genau eine Verbindung zwischen dem Lazarus Programm und MySQL aufbauen?
Muss ich jedesmal, wenn ich ein SQLQuery.close und danach SQLQuery.open ausführe, dazwischen die oben zitierten Query-Statements mit 'utf8' ausführen?

Peter

TBug
Beiträge: 177
Registriert: Mi 2. Sep 2015, 11:09
OS, Lazarus, FPC: Lazaurus 2.2.4 FPC 3.2.2
CPU-Target: Windows 32/64bit

Re: MySQL "Data too long for column" obwohl Length korrekt

Beitrag von TBug »

pschoett hat geschrieben:Mir ist nicht klar, was genau gemeint ist mit "each time a connection to the database is established".
Was bedeutet genau eine Verbindung zwischen dem Lazarus Programm und MySQL aufbauen?
Muss ich jedesmal, wenn ich ein SQLQuery.close und danach SQLQuery.open ausführe, dazwischen die oben zitierten Query-Statements mit 'utf8' ausführen?


Nicht dann, wenn Du eine Query öffnest, sondern wenn Du eine Connection mit der Datenbank verbindest. Also bei:

Code: Alles auswählen

TMySQL51Connection.Connect
.

Du öffnest also die Verbindung und schickst dann sofort diese zwei Statements. Am einfachsten setzt Du diese in das AfterConnect-Event.

pschoett
Beiträge: 36
Registriert: Sa 7. Feb 2015, 11:48

Re: MySQL "Data too long for column" obwohl Length korrekt

Beitrag von pschoett »

Ich habe es jetzt anhand eines Delphi Beispiels im Internet gefunden https://sites.google.com/site/programmingwithdelphi/Home/review-of-dac-for-mysql/dac-tutorials/connect-to-a-mysql-database und übergebe die beiden Werte als Parameter an das TMySQLConnection Objekt bevor eine Verbindung aufgebaut wird.

Code: Alles auswählen

procedure TDM.MySQL51Connection1BeforeConnect(Sender: TObject);
begin
  with MySQL51Connection1 do
    begin
      CharSet := 'utf8';
      Params.Clear;
      Params.Add('CHARSET=utf8');
      Params.Add('NAMES=utf8');
    end;
end;

Ob dadurch jetzt alles richtig anzeigt wird, kann ich noch nicht sagen.
---Edit --- (hatte den falschen Thread zitiert) ---
Laut diesem Beitrag Lazarus charset - Umlaute scheint mir doch noch eine Umwandlung auszuführen zu sein.

pschoett
Beiträge: 36
Registriert: Sa 7. Feb 2015, 11:48

Re: MySQL "Data too long for column" obwohl Length korrekt

Beitrag von pschoett »

:oops: Wäre mein letzter Beitrag eine Klassenarbeit in der Schule, dann hätte ich den Kommentar "Thema verfehlt! Sechs! Setzen" dort stehen.
Die beiden SQL_Statements als Parameter der MySQLConnection zu verpacken hört sich zwar charmant an, ist aber völliger Unsinn. Richtiger ist es, im AfterConnect-Ereignis von MySQLConnection die beiden SQL-Statements abzusetzen.

Antworten