AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Firebird UUID <> GUID

Ein Thema von Morphie · begonnen am 16. Jan 2013 · letzter Beitrag vom 17. Jan 2013
Antwort Antwort
Morphie

Registriert seit: 27. Apr 2008
Ort: Rahden
630 Beiträge
 
#1

Firebird UUID <> GUID

  Alt 16. Jan 2013, 18:53
Datenbank: Firebird • Version: 2.5.2 • Zugriff über: ADO.NET
Hi,

ich habe mich aus diversen Gründen dafür entschieden, die Primärschlüssel in meiner Datenbank als UUID abzubilden.
Die UUID-Domain ist (wie hier beschrieben) in Firebird wie folgt deklariert:
Code:
CREATE DOMAIN UUID AS
  CHAR(16)
  CHARACTER SET OCTETS;
Die Felder versehe ich mit folgendem Comment:
Code:
#GUID#
Ab sofort erkennt das EntityFramework die Felder als GUIDs und mappt diese entsprechend.
Die GUIDs vergebe ich im Constructor der Entities auf der Client-Seite.

Jetzt zum Problem:
Heute habe ich mehrere Stunden damit verbracht, herauszufinden, warum das EF meine Datensätze beim Refresh nicht wiederfindet.
Zuerst hatte ich den ADO.NET Provider in Verdacht, doch dann stelle sich heraus, dass der nicht schuld war. Er überträgt schon die richtigen Werte.

Das EntityFramework setzt beim Refresh-Befehl folgenden SQL-Query ab:
Code:
SELECT
"B"."ID" AS "ID",
"B"."BEZEICHNUNG" AS "BEZEICHNUNG"
FROM "ZAHLUNGSARTEN" AS "B"
WHERE "B"."ID" = CHAR_TO_UUID('a6ddceee-dc33-46cc-9378-75fbc4d87ef2')
Folgende GUID hat mein Objekt also als Primärschlüssel:
Code:
a6ddceee-dc33-46cc-9378-75fbc4d87ef2
oder in folgende 16 Codes ausgedrückt:
Code:
238,206,221,166,51,220,204,70,147,120,117,251,196,216,126,242
Stelle ich diese Bytes aber in Firebird mittels UUID_TO_CHAR dar, so wie es die SQL-Abfrage macht, bekomme ich eine andere Zeichenfolge, nämlich diese:
Code:
EECEDDA6-33DC-CC46-9378-75FBC4D87EF2
UUID_TO_CHAR bildet also einen falschen / anderen String ab. Dann ist es auch klar, warum das EntityFramework meine Datensätze nicht wiederfindet...

Jetzt die Frage:
Ist das ein Bug in Firebird?
Laut den Release-Notes hat sich in FB 2.5.2 etwas an dem Algorithmus geändert, doch das behebt mein Problem leider nicht.

Oder gibt es wirklich einen Unterschied zwischen UUID und GUID?
Gibt es eine UDF, um die richtige GUID-Zeichenfolge abbilenden zu können?

Oder wäre es vielleicht besser, doch den ADO.NET Firebird Provider umzuschreiben, so dass er nicht mehr UUID_TO_CHAR aufruft, sondern die GUID als Byte-Array per Paramater übergibt? Und wenn ja, wie geht das?!

Ich hoffe mir kann hier jemand helfen, falls jemand diese doch recht spezielle Frage überhaupt versteht
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#2

AW: Firebird UUID <> GUID

  Alt 16. Jan 2013, 21:07
Die ersten 3 Blöcke scheinen "invertiert" die restlichen 2 nicht "invertiert".

http://stackoverflow.com/questions/2...uid-and-a-uuid
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Morphie

Registriert seit: 27. Apr 2008
Ort: Rahden
630 Beiträge
 
#3

AW: Firebird UUID <> GUID

  Alt 17. Jan 2013, 07:11
Ja, das ist mir auch aufgefallen... Die ersten 3 Blöcke sind in je 2-Char-Blöcke invertiert...
Diese erkenntnis hilft mir aber leider bis jetzt noch nicht
  Mit Zitat antworten Zitat
Lemmy

Registriert seit: 8. Jun 2002
Ort: Berglen
2.380 Beiträge
 
Delphi 10.3 Rio
 
#4

AW: Firebird UUID <> GUID

  Alt 17. Jan 2013, 14:27
Hallo,

Problem kann ich mit Firebird 2.5.2.26539 embedded und Flamerobin nicht nachvollziehen. Hast Du die DB mit 2.5.2 angelegt? Hier soll es ja zwischen 2.5 und 2.5.2 wirklich unterschiedliche Rückgabewerte geben.
Code:

CREATE TABLE TEST
(
  GUID char(36),
  UUID char(16) CHARACTER SET OCTETS
);

INSERT INTO TEST (GUID, UUID)
VALUES (
    '9B7C3C32-2B51-49D5-BB9A-7C044B91A061',
    CHAR_TO_UUID('9B7C3C32-2B51-49D5-BB9A-7C044B91A061')
);

select guid, UUID_TO_CHAR(UUID) from test;

ergibt:

9B7C3C32-2B51-49D5-BB9A-7C044B91A061   9B7C3C32-2B51-49D5-BB9A-7C044B91A061
  Mit Zitat antworten Zitat
Morphie

Registriert seit: 27. Apr 2008
Ort: Rahden
630 Beiträge
 
#5

AW: Firebird UUID <> GUID

  Alt 17. Jan 2013, 14:46
ja, ich habe es mit 2.5.2 ansprobiert.

Du hast das Problem in deinem Beispiel nicht, weil du die 16-Byte UUID bereits mittels CHAR_TO_UUID('9B7C3C32-2B51-49D5-BB9A-7C044B91A061') anlegst...

Das Problem tritt auf, wenn man (z.B. in .NET) eine Variable vom Typ Guid hat. Wenn man sich diesen als 36-Zeichen String ausgeben lässt, bekommt man z.B. diese Darstellung:
Code:
a6ddceee-dc33-46cc-9378-75fbc4d87ef2
Intern speichert Guid aber ein Array von 16 Bytes.
Code:
238,206,221,166,51,220,204,70,147,120,117,251,196,216,126,242
Legt man jetzt einen Datensatz an und will die 16-Byte UUID übergeben, macht man das so:
Code:
INSERT INTO TABLE (ID) VALUES (@PARAMETER1)
im Parameter1 übergibt man dann das 16-Byte-Array. Hier unterscheidet sich dein Beispiel von meinem. Du übergibst die UUID mittels der (ebenfalls fehlerhaften) Funktion CHAR_TO_UUID. Diese beiden Fehler heben sich gegenseitig auf.
Übergibt man die UUID immer über den Befehl CHAR_TO_UUID merkt man den Fehler nicht. Übergibt man ihn dann irgendwann mal als Parameter, hat man das Problem.


In der Datenbank stehen anschließend im Feld ID genau diese 16 Bytes drin. Das kann man sich auch ganz gut mit folgender Abfrage ansehen:
Code:
select
ascii_val(substring(Tabelle.id from 1 for 1)),
ascii_val(substring(Tabelle.id from 2 for 1)),
ascii_val(substring(Tabelle.id from 3 for 1)),
ascii_val(substring(Tabelle.id from 4 for 1)),
ascii_val(substring(Tabelle.id from 5 for 1)),
ascii_val(substring(Tabelle.id from 6 for 1)),
ascii_val(substring(Tabelle.id from 7 for 1)),
ascii_val(substring(Tabelle.id from 8 for 1)),
ascii_val(substring(Tabelle.id from 9 for 1)),
ascii_val(substring(Tabelle.id from 10 for 1)),
ascii_val(substring(Tabelle.id from 11 for 1)),
ascii_val(substring(Tabelle.id from 12 for 1)),
ascii_val(substring(Tabelle.id from 13 for 1)),
ascii_val(substring(Tabelle.id from 14 for 1)),
ascii_val(substring(Tabelle.id from 15 for 1)),
ascii_val(substring(Tabelle.id from 16 for 1))
from Tabelle
Konvertiert man diese Bytes anschließend wieder mittels UUID_TO_CHAR zurück, bekommt man einen vom original-.NET.GUID-String abweichenden String:
Code:
EECEDDA6-33DC-CC46-9378-75FBC4D87EF2

Geändert von Morphie (17. Jan 2013 um 15:00 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:11 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz