Globally Unique Identifiers... ou GUIDs (prononcer comme Geoduck avec le "uck" ou
"Gou-ide" pour ceux qui ne peuvent attraper le premier son) sont
intrinsèquement uniques dans l'espace-temps. Il sont fréquemment utilisés par
COM ainsi que par la réplication de JET pour créer un repère, ID, des
enregistrements qui demeureront constant peu importe ce qu'il arrive aux autres
valeurs (tel un changement de la clé primaire).Plusieurs utilisateurs
considèrent l'utilisation de GUID comme clé primaire ou de référence,
puisque ce sont des valeurs uniques. Cependant, il y a quelques raisons pour y
songer à deux fois avant de s'engager sur cette voie:
1) Dans une
application, un champ "ReplicationID Autonumber" (i.e. un autonumber
GUID) est utilisé par JET, lorsque vous convertissez votre application à une
réplication, au lieu de créer un champ s_Guid dans les autres case.
Malheureusement, le Conflict Resolver Wizard d'Access 95 et 97, de même
que le Conflict Viewer d'Access 2000, présupposent un champ s_Guid pour
la résolution des conflits et ainsi, la résolution des conflits risque de ne
pas fonctionner proprement, et vous êtes seuls avec ce désagrément.
2) Un GUID
est emmagasiné comme une valeur 16-octets. Il possède également une
représentation canonique (texte) et un format spécifique à DAO/Jet également, constitué
de {guid {xxx}} où xxx est la valeur canonique. C'est ce dernier
format que Jet affiche dans un champ de par un énoncé SELECT de par DAO... la
forme canonique est utilisée si vous utilisez Jet directement pour voir une
table (vue sous Access en mode "datasheet") ou ADO via Jet OLE DB
provider. De plus les règles des filtres et des méthodes "find"
de DAO vs. ADO, de filtrage par formulaire sous Access, liens entre
parents et sous-formulaires, propriété Text vs Value pour les contrôles
reliés à des champs GUID sont difficiles à suivrent, tout en changeant entre
chaque version. Access possède des fonctions qui permettent la conversion du
mode binaire au mode canonique, StringFromGUID et GUIDFromString, mais
elles utilisent la syntaxe DAO, même si la plupart des autres produits
utilisant COM préfèrent la forme canonique. Ce bourbier signifie qu'avec
l'utilisation d'un champ GUID signifie que vous visez une cible mouvante.
3)
Lès règles au point #2 changent à chaque version et brisent presque universellement
tout ce qui fonctionnait bien auparavant. Essentiellement, une tâche de révision
additionnelle lors d'une migration vers une nouvelle version.
4) Les autonumbers
sont quelques fois visibles pour l'utilisateur, pour un bien ou pour un mal, et
c'est évidemment peu pratique avec des GUID, et même si la myriade de points
soulevés précédemment ne sont pas des problèmes, les GUID confondent les
utilisateurs et personne ne veut être identifié à un GUID. :-)
Il
est vrai que les mentions au points #2 peuvent être manipulés par quelques
techniques, incluant:
1) Expérimenter avec l'utilisation de la forme
canonique réelle vs. la forme {guid {xxx}}
2) Conversion utilisant les
deux fonctions d'Access
3) Utiliser CStr() dans les énoncés SELECT pour
convertir les champs GUIDS en leur forme canonique réelle
4) Bien prendre
note des endroits où on en fait usage de sorte qu'on puisse facilement
revisiter ces points lors d'une prochaine migration (changement de version).
5)
Réaliser que le type de champ est dbGuid sous DAO et adGuid sous ADO, même si
tous deux retournent du "texte" lorsque vous regardez la valeur,
camouflant de grands efforts destinés à montrer une flexibilité, mais rendant
le comportement des points du #2 difficile à prédire.
Incidemment, voici des
fonctions permettant la conversion, en dehors d'Access, utiles dans le cas où
vous travaillez en VB, par exemple. Simplement copier dans un module, etc.
Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(7) As Byte
End Type
Private Declare Function _
StringFromGUID2 Lib "ole32.dll" _
(rclsid As GUID, ByVal lpsz As Long, _
ByVal cbMax As Long) As Long
Private Declare Function _
CLSIDFromString Lib "ole32.dll" _
(pstCLS As Long, clsid As GUID) As Long
Function GuidFromStGuid(stGuid As String) As GUID
Call CLSIDFromString(ByVal StrPtr(stGuid), _
GuidFromStGuid)
End Function
Function StGuidFromGuid(rclsid As GUID) As String
Dim stGuid As String
Dim cch As Long
' 39 chars for the GUID plus room for the Null char
stGuid = String$(40, vbNullChar)
cch = StringFromGUID2(rclsid, StrPtr(stGuid), 39)
StGuidFromGuid = Left$(stGuid, cch)
End Function
RECOMMANDATION FINALE:
Même s'il est possible de surmonter les points
mentionnés
en #2 et #3, #2 est essentiellement problématique et très difficile à
maintenir, en particulier en considérant le #3. Les risques
d'erreurs n'en valent généralement pas la peine et mieux vaut choisir une clé
primaire présentant moins de potentiel problématique. Il est toujours bien avisé
d'écrire du code pour votre base de données qui soit facile à maintenir et à
répliquer.
MichKa