SQLDB und die Größe der Datenfelder (MariaDB/MySQL)

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.

SQLDB und die Größe der Datenfelder (MariaDB/MySQL)

Beitragvon Socke » 4. Nov 2017, 00:09 SQLDB und die Größe der Datenfelder (MariaDB/MySQL)

Hallo zusammen,

SQLDB erstellt mir automatisch ein Feld vom Typ ftFixedChar mit der falschen Länge? Wie kann ich SQLDB dazu überreden, die korrekte Länge automatisch von der Datenbank zu beziehen. Ich habe nicht vor, die Felddefinitionen von Hand anzulegen. Ein Wechsel auf ZEOS ist ebenfalls ausgeschlossen (kann aber gerne als Referenz für eine ggf. korrekte Ermittlung der Feldlänge angegeben werden).
Aktuell gehe ich von einem Fehler in SQLDB aus, da das Programm HeidiSQL die Abfrageergebnisse korrekt darstellt.

Eingesetzt werden:
  • MariaDB Version 10.0.31-MariaDB als Server
  • MariaDB Connector C, Version 2.1.0
  • TMySQL55Connection von FPC trunk und Lazarus trunk

Die Datenbanktabelle enthält binär gespeicherte GUIDs, die mit der Funktionen UuidToBin bzw. UuidFromBin konvertiert werden. Damit ich die GUIDS direkt in Pascal als Strings verarbeiten kann, habe ich mir eine Funktion PasUuidFromBin gebaut, die geschweifte Klammern hinzufügt.
Code: Alles auswählen
CREATE TABLE `data` (
   `ID` BINARY(16) NOT NULL COMMENT 'GUID',
   PRIMARY KEY (`ID`)
)
COLLATE='utf8_german2_ci'
ENGINE=InnoDB
;
-- Beispieldatensatz einfügen
INSERT INTO DATA VALUES(UuidToBin(UUID()));
-- Stored procedure um die GUIDs direkt als String auszulesen.
CREATE DEFINER=`user`@`%` FUNCTION `PasUuidFromBin`(
   `_bin` BINARY(16)
)
RETURNS char(38) CHARSET ascii
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT 'Retrive Pascal style UUID from binary(16)'
BEGIN
  RETURN CONCAT('{', UuidFromBin(_bin), '}');
END;

Die Datenabfrage erfolgt dann mit:
Code: Alles auswählen
SELECT PasUuidFromBin(ID) FROM DATA;

Daraus erzeugt SQLDB wie beschrieben ein Feld ftFixedChar mit der Länge 28 (TField.FSize), was dazu führt, dass nur die ersten 28 Zeichen ausgegeben werden.
Auch ein Cast die Abfrage nach CHAR(38) wird auch nicht die korrekte Länge ermittelt.
Code: Alles auswählen
SELECT CONVERT(PasUuidFromBin(ID), CHAR(38)) FROM DATA;


Weiß hier jemand weiter?

Edit: ich habe den MariaDB-Connector auf Version 3.1.0 aktualisiert und bin auf TMySQL56Connection gewechselt - keine Änderung.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Socke
 
Beiträge: 2422
Registriert: 22. Jul 2008, 18:27
Wohnort: Köln
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 8.1/Debian GNU/Linux/Raspbian/openSUSE | 
CPU-Target: 32bit x86 armhf
Nach oben

Beitragvon Soner » 4. Nov 2017, 15:33 Re: SQLDB und die Größe der Datenfelder (MariaDB/MySQL)

Villeicht das:
SELECT CONVERT(PasUuidFromBin(ID), CHAR(38)) FROM DATA;

ändern in:
SELECT CAST(PasUuidFromBin(ID) as CHAR(38) CHARSET ascii) FROM DATA;

weil oben charset ja immer noch unbekannt ist. Es könnte utf8 oder unicode sein.

Ich frage mich wie sqldb auf 28 kommt, normalerweise multipliziert es immer mit 4 wie z.B. bei utf8-Charsets.
Soner
 
Beiträge: 396
Registriert: 26. Sep 2012, 23:07
Wohnort: Hamburg
OS, Lazarus, FPC: Win7Pro-32Bit, Immer letzte Lazarus Release mit SVN-Fixes | 
CPU-Target: 32Bit
Nach oben

Beitragvon Socke » 5. Nov 2017, 17:34 Re: SQLDB und die Größe der Datenfelder (MariaDB/MySQL)

Soner hat geschrieben:SELECT CAST(PasUuidFromBin(ID) as CHAR(38) CHARSET ascii) FROM DATA;

bringt leider auch nichts, hat mich aber auf die richtige Spur geführt!

Die Eigenschaft CharSet der Verbindung war auf UTF8mb4 eingestellt, während nach Herstellen der Verbindung folgende Anweisungen ausgeführt wurden:
Code: Alles auswählen
SET CHARACTER SET `utf8`;
SET NAMES 'utf8';
SET sql_mode = ANSI_QUOTES;


Wenn das konsitent ist, d.h. sowohl per SQl als auch in den Verbindungseinstellungen die selbe Zeichenkodierung verwendet wird, wird die Länge korrekt ermittelt.
Die Länge wird übrigens in der Methode TConnectionName.MySQLDataType (generische Basisklasse für alle TMySQLNNConnection-Klassen) ausgelesen. Der Wert wird von der Datenbank vorgegeben.

Ob man UTF8 oder UTF8mb4 angibt, spielt hier keine Rolle, da alle Zeichen einer GUID in ASCII enthalten sind. Grundsätzlich sollte man aber in MySQL oder MariaDB den Zeichensatz UTF8mb4 (und zugehörige Collations) vorziehen, da dieser den gesamten Zeichenvorat abbildet. Die MySQL-Zeichenkodierung UTF8 kann maximal 3 Bytes pro Zeichen verarbeiten (während laut Unicode maximal 4 Bytes zulässig sind). Daraus können gerade aus Vergleichen sehr merkwürdige und inhaltlich fragwürdige Entscheidungen resultieren.

Der Unterschied zwischen den Einstellungen in CharSet und den SQL-Anweisungen waren übrigens genau dieser Umstellung geschuldet.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Socke
 
Beiträge: 2422
Registriert: 22. Jul 2008, 18:27
Wohnort: Köln
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 8.1/Debian GNU/Linux/Raspbian/openSUSE | 
CPU-Target: 32bit x86 armhf
Nach oben

• Themenende •

Zurück zu Datenbanken



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast

porpoises-institution
accuracy-worried