Eindeutige Schlüssel (GUID)

Wenn man in Tabellen einen Fremdschlüssel benötigt und nicht den Datentyp Integer (AutoInc) verwenden möchte oder kann (z.B. wegen einer ODBC-Verbindung mit VFP6 Treiber), oder wenn man mit mehreren Rechnern in einem gemeinsam Verzeichnis im Netzwerk temporäre Dateinamen generieren will, die mit Sicherheit eindeutig sind, stößt man mit SYS(2015) rasch an die Grenzen, weil das Ergebnis immer nur auf dem jeweiligen Rechner eindeutig ist. Als Alternative kann man einen sogenannten GUID (Globally Unique Identifier) verwenden.

Sie kennen sicherlich diese unansehnlichen "Würste" von Zahlen und Buchstaben in geschwungenen Klammern aus der Windows Registry, Ihrem temporären Verzeichnis oder aus dem OLE-Control / ActiveX Dialog von FoxPro:

{951AB756-D4FB-446f-BB29-63C896E316A0}

GUIDs sind die Microsoft-spezifische Implementierung der sogenannten UUIDs (Universally Unique Identifier), sind 128 Bit lang und garantieren die Eindeutigkeit über Ort und Zeit, das heißt, es ist sicher gestellt, dass eine einmal generierte GUID nirgends und zu keinem Zeitpunkt ein zweites Mal generiert werden kann. Diese UUIDs wurden ursprünglich von Apollo Computers eingesetzt und später in das Open Software Foundation DCE (Distributed Computing Environment) übernommen. Prinzipiell werden sie basierend auf der Systemzeit und der Adresse einer Netzwerkkarte generiert. Eine genaue Beschreibung findet sich im RFC 4122 vom Juli 2005.

Die obige Darstellungsform ist die Repräsentation einer GUID als Zeichenfolge, im Speicher belegt ein GUID genau 16 Byte (16 * 8 Byte = 128 Bit).

CoCreateGuid

Das Windows API (Application Programmer Interface) stellt in der Bibliotheksdatei ole32.dll eine Funktion zur Verfügung, mit der eine GUID generiert werden kann: CoCreateGuid(). Sie ist wie folgt deklariert:

Um sie in FoxPro nutzen zu können, müssen wir sie zunächst einmal deklarieren. Bitte beachten Sie dabei, dass die Groß-/Kleinschreibung des Funktionsnamens genau eingehalten werden muss:

DECLARE Integer CoGreateGuid ;
    IN ole32.dll ;
    String@ pguid

pguid ist dabei eine Referenz auf einen 16 Byte langen Speicherbereich, in den die Funktion den 128 Bit langen GUID schreibt. Am einfachsten erstellen wir in FoxPro einen Speicherbereich bestimmter Länge mit der Funktion SPACE(), die uns eine Folge von Leerzeichen im Speicher erstellt. Ein Zeichen entspricht in FoxPro genau einem Byte (8 Bit).

lcGuid = SPACE(16)
CoCreateGuid(@lcGuid)

Die Funktion CoCreateGuid() gibt dabei einen der folgenden Werte zurück:

Rückgabewert Bedeutung
0 (0x00000000) Die Funktion wurde erfolgreich ausgeführt. Im Speicher, den wir als Referenz übergeben haben, befinden sich nun 16 Byte, die eine GUID darstellen. Jedes dieser 16 Byte kann dabei für sich einen Wert zwischen 0 und 255 aufweisen.
2147485472 (0x80000720) Die generierte GUID ist nur auf diesem Computer eindeutig. Es kann sein, dass ein anderer Computer ebenfalls diese GUID generiert.
2147485387 (0x800006CB) Für diesen Computer kann keine Hardware Adresse (Ethernet oder Token-Ring) ermittelt werden.

Da ein jedes der 16 Byte in lcGuid nun einen Wert zwischen 0 und 255 aufweisen kann, aber nicht alle diese Werte am Bildschirm oder Drucker als Zeichen ausgegeben werden können (die Zeichen 0-31 und 127 sind reservierte Steuerzeichen), können wir diese "Zeichenfolge" nur in Tabellenfeldern verwenden, die ausdrücklick binäre Daten unterstützen, z.B. Character (binary), Memo (binary), oder Varbinary.

StringFromGUID2

Um die zuvor generierten 16 Byte in eine druckbare Zeichenfolge umzuwandeln (dieses "seltsame" Ding in den geschwungenen Klammern), kann man sich der Windows API Funktion StringFromGUID2() bedienen, die ebenfalls von ole32.dll exportiert wird. Diese wird wie folgt in FoxPro deklariert:

DECLARE Integer StringFromGUID2 ;
    IN ole32.dll ;
    String pguid, ;
    String  @lpszBuffer, ;
    Integer cbBuffer

Diese Funktion erwartet drei Parameter:

Wenn cbBuffer größer als 38 ist, gibt die Funktion 39 zurück, das ist die Anzahl der UNICODE-Zeichen einschließlich der Nullterminierung. Wenn cbBuffer kleiner als 38 ist, der Speicherbereich also nicht ausreichen würde, gibt die Funktion 0 zurück.

lcBuffer = SPACE(78)
lnResult = StringFromGUID2(lcGuid,@lcBuffer,LEN(lcBuffer)/2)

Abschließend müssen wir mit LEFT() die Nullterminierung am Ende des Strings entfernen und mit STRCONV() den resultierenden UNICODE String in eine ANSI Zeichenfolge umwanden. 

lcBuffer = LEFT(lcBuffer,(lnResult-1)*2)
lcBuffer = STRCONV(lcBuffer,6)

Sie können das folgende Beispielprogramm herunterladen, in dem alle diese grundsätzlichen Schritte demonstriert werden. Es enthält eine Funktion GuidGen, die Sie auch in eigene Anwendungen übernehmen können.

 guidgen.zip (2 kB)

Weitere Informationen

 

Informationen im dFPUG Portal

Die folgenden Dokumente stehen nur dFPUG Mitgliedern zur Verfügung. Weitere Informationen zur Mitgliedschaft finden Sie hier.

 
 

Zurück zum Archiv