« OIDs numériques (framework) » : différence entre les versions
Aucun résumé des modifications |
|||
| (10 versions intermédiaires par un autre utilisateur non affichées) | |||
| Ligne 1 : | Ligne 1 : | ||
{{ | {{version900}} | ||
Une base en OIDs numériques stocke les OID en entier 64 bits au lieu de les stocker en chaîne de caractères. | Une base en OIDs numériques stocke les OID en entier 64 bits au lieu de les stocker en chaîne de caractères. | ||
| Ligne 9 : | Ligne 9 : | ||
* Gain réseau, le volume de données échangé est réduit. | * Gain réseau, le volume de données échangé est réduit. | ||
{{tip|Seul le stockage est différent, le framework et le code métier utilisent toujours des OIDs au format caractère en interne}} | {{tip|Seul le stockage est différent, le framework et le code métier utilisent toujours des OIDs au format caractère en interne}} | ||
===Struture interne=== | |||
{|class="wikitable" | |||
|- | |||
!nom | |||
!taille | |||
!Remarque | |||
|- | |||
|LID | |||
|16 bits | |||
|Local OID, incrément propre à chaque client | |||
|- | |||
|GID | |||
|32 bits | |||
|Root OID, stocké dans la séquence RootOID, incrémenté par chaque client à la connexion | |||
|- | |||
|OTP | |||
|16 bits | |||
|identifie la classe, grâce à la table sysOTPs | |||
|} | |||
===Revue de code métier=== | ===Revue de code métier=== | ||
| Ligne 27 : | Ligne 48 : | ||
!Fonction | !Fonction | ||
!Supporte l'encodage d'OID | !Supporte l'encodage d'OID | ||
!Remarque | |||
|- | |- | ||
|dboutOID() | |dboutOID() | ||
|Oui | |Oui | ||
| | |||
|- | |- | ||
|dbOutStr() | |dbOutStr() | ||
|Non | |Non | ||
| | |||
|- | |- | ||
|dbOutVariant() | |dbOutVariant() | ||
|Non | |Non | ||
| | |||
|- | |||
|dbOutWhereString('oidXXX','=',' ') | |||
|Oui | |||
| oidXXX is NULL | |||
|- | |||
|dbOutWhereString('oidXXX','<>',' ') | |||
|Oui | |||
| oidXXX is NOT NULL | |||
|- | |||
|dbOutWhereString('oidXXX','=',aOID) | |||
|Oui | |||
| | |||
|- | |||
|dbOutWhereString('oidXXX','=',dbOutStr(aOID)) | |||
|non | |||
| | |||
|- | |||
|dbOutWhereVariant('oidXXX','=',aOID) | |||
|oui | |||
| | |||
|} | |} | ||
| Ligne 68 : | Ligne 114 : | ||
then showMessage('success') | then showMessage('success') | ||
else showMessage(Format('failed :%d, %s / %s',[ctn,aoid,xoid])); | else showMessage(Format('failed :%d, %s / %s',[ctn,aoid,xoid])); | ||
end; | |||
</source> | |||
<source lang="delphi"> | |||
begin | |||
// OK | |||
// Equality test | |||
aOID := inst.OID; | |||
vQuery.SQL.Add(Format('WHERE oid=%s',[vQuery.translator.dbOutOID(aOID)])); | |||
// Null test | |||
vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereString('oid','=','NULL')])); | |||
vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereString('oid','<>','NULL')])); | |||
vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereString('oid','=','')])); | |||
vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereString('oid','<>','')])); | |||
vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereString('oid','=',aOID)])); | |||
vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereNull('oid')])); | |||
vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereNotNull('oid')])); | |||
// In test | |||
aWhereIn := '('''+aOID+'')'; | |||
vQuery.SQL.Add(Format('WHERE oid in %s',[vQuery.translator.dbOutOID(aWhereIn)]); | |||
end; | |||
</source> | |||
<source lang="delphi"> | |||
begin | |||
// NOT OK | |||
// Equality test | |||
aOID := inst.OID; | |||
vQuery.SQL.Add(Format('WHERE oid=''%s''',[aOID])); | |||
vQuery.SQL.Add(Format('WHERE oid='''+aOID+''',[])); | |||
vQuery.SQL.Add(Format('WHERE oid=%s',[vQuery.translator.dbOutStr(aOID)])); | |||
vQuery.SQL.Add(Format('WHERE oid=%s',[vQuery.translator.dbOutVariant(aOID)])); | |||
// In test | |||
aWhereIn := '('''+aOID+'')'; | |||
vQuery.SQL.Add(Format('WHERE oid in %s',[aWhereIn]); | |||
end; | end; | ||
</source> | </source> | ||
{{tip|Il est recommandé de ne pas utiliser de Query broker ni de curseur avec du code SQL. En général, ceux-ci peuvent être remplacés par des sélecteurs ou des vues locales.}} | {{tip|Il est recommandé de ne pas utiliser de Query broker ni de curseur avec du code SQL. En général, ceux-ci peuvent être remplacés par des sélecteurs ou des vues locales.}} | ||
===Fonctions spécifiques SQL=== | |||
Dans certain cas il peut être nécessaire de convertir des OIDs numériques et alphanumériques dans des requêtes SQL | |||
Il existe deux fonctions SQL pour réaliser ces conversions | |||
* OIDToNumeric ( iOIDChar : CHAR_(12) ) | |||
: Retourne la valeur numérique d'un OID caractère | |||
* NumericToOID (iDatabasePrefix : CHAR_(16), iOIDInt:BigInt ) | |||
: Retourne la valeur alphanumérique d'un OID numérique | |||
{{tip|N'utiliser pas ces fonctions dans le script métier, il n'est jamais nécessaire de gérer le format des OIDs dans le code métier}} | |||
Voir aussi: | Voir aussi: | ||
* [[Translateurs_SQL_(tech)|Translateur]] | |||
* [[Selecteur_(tech)|Sélecteurs]] | * [[Selecteur_(tech)|Sélecteurs]] | ||
* [[Vue_locale_(langage)|Vues locales]] | * [[Vue_locale_(langage)|Vues locales]] | ||
[[category:Version900]] | |||
[[category: | |||
[[Category:Base de données]] | [[Category:Base de données]] | ||
[[Category:Framework]] | [[Category:Framework]] | ||
Dernière version du 9 septembre 2022 à 13:52
{{#images:version900-32x32.png|stock}}
Une base en OIDs numériques stocke les OID en entier 64 bits au lieu de les stocker en chaîne de caractères.
Les avantages sont :
- Gain de taille, la taille d'un oid numérique est de 8 octets alors que la taille d'un oid caractère est de 32 octets
- Gain de performance, le serveur SQL est plus performant dans la manipulation d'entier.
- Gain réseau, le volume de données échangé est réduit.
| Tip : Seul le stockage est différent, le framework et le code métier utilisent toujours des OIDs au format caractère en interne |
Struture interne
| nom | taille | Remarque |
|---|---|---|
| LID | 16 bits | Local OID, incrément propre à chaque client |
| GID | 32 bits | Root OID, stocké dans la séquence RootOID, incrémenté par chaque client à la connexion |
| OTP | 16 bits | identifie la classe, grâce à la table sysOTPs |
Revue de code métier
Les éléments suivants doivent être revue pour s'assurer que le code métier est correctement implémenté :
- Queries brokers
- Curseurs utilisant une construction SQL
Les points à vérifier sont :
- Utilisation de dbOutOID() pour encoder les OIDs dans les requêtes
Support de l'encodage d'OID par translateur :
| Fonction | Supporte l'encodage d'OID | Remarque |
|---|---|---|
| dboutOID() | Oui | |
| dbOutStr() | Non | |
| dbOutVariant() | Non | |
| dbOutWhereString('oidXXX','=',' ') | Oui | oidXXX is NULL |
| dbOutWhereString('oidXXX','<>',' ') | Oui | oidXXX is NOT NULL |
| dbOutWhereString('oidXXX','=',aOID) | Oui | |
| dbOutWhereString('oidXXX','=',dbOutStr(aOID)) | non | |
| dbOutWhereVariant('oidXXX','=',aOID) | oui |
Exemples :
<source lang=delphi> //Procedure TestQueryBroker; var vQuery:TQuery; aOID,xOID:TOID; inst:WFClasseA; ctn:Integer; begin
//find first instance inst := WFClasseA.Find(,,True,[]); if not Assigned(inst) then Exit; aOID := inst.OID;
vQuery := QueryBroker({URL},'Test','WFClasseA');
vQuery.Sql.Add('SELECT oid FROM '+ClassManager.FindClassTableName('WFClasseA'));
vQuery.SQL.Add(Format('WHERE oid=%s',[vQuery.translator.dbOutOID(aOID)])); //!! Important use dbOutOID() to encode oid
//
ctn := 0;
vQuery.Open;
vQuery.First;
while not vQuery.Eof do
begin
ctn := ctn+1;
xOID := vQuery.Fields[0].AsVariant; // OK, Fields[] return the OID in char format
vQuery.Next;
end;
vQuery.Close;
//
if (ctn=1) and (aOID=xOID)
then showMessage('success')
else showMessage(Format('failed :%d, %s / %s',[ctn,aoid,xoid]));
end; </source>
<source lang="delphi"> begin
// OK
// Equality test
aOID := inst.OID;
vQuery.SQL.Add(Format('WHERE oid=%s',[vQuery.translator.dbOutOID(aOID)]));
// Null test
vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereString('oid','=','NULL')]));
vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereString('oid','<>','NULL')]));
vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereString('oid','=',)]));
vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereString('oid','<>',)]));
vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereString('oid','=',aOID)]));
vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereNull('oid')]));
vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereNotNull('oid')]));
// In test
aWhereIn := '('+aOID+)';
vQuery.SQL.Add(Format('WHERE oid in %s',[vQuery.translator.dbOutOID(aWhereIn)]);
end; </source>
<source lang="delphi"> begin
// NOT OK
// Equality test
aOID := inst.OID;
vQuery.SQL.Add(Format('WHERE oid=%s',[aOID]));
vQuery.SQL.Add(Format('WHERE oid=+aOID+,[]));
vQuery.SQL.Add(Format('WHERE oid=%s',[vQuery.translator.dbOutStr(aOID)]));
vQuery.SQL.Add(Format('WHERE oid=%s',[vQuery.translator.dbOutVariant(aOID)]));
// In test
aWhereIn := '('+aOID+)';
vQuery.SQL.Add(Format('WHERE oid in %s',[aWhereIn]);
end; </source>
| Tip : Il est recommandé de ne pas utiliser de Query broker ni de curseur avec du code SQL. En général, ceux-ci peuvent être remplacés par des sélecteurs ou des vues locales. |
Fonctions spécifiques SQL
Dans certain cas il peut être nécessaire de convertir des OIDs numériques et alphanumériques dans des requêtes SQL
Il existe deux fonctions SQL pour réaliser ces conversions
- OIDToNumeric ( iOIDChar : CHAR_(12) )
- Retourne la valeur numérique d'un OID caractère
- NumericToOID (iDatabasePrefix : CHAR_(16), iOIDInt:BigInt )
- Retourne la valeur alphanumérique d'un OID numérique
| Tip : N'utiliser pas ces fonctions dans le script métier, il n'est jamais nécessaire de gérer le format des OIDs dans le code métier |
Voir aussi: