> Tech > Technique 2: Lire et écrire un ensemble d’enregistrements ayant une valeur commune sur une zone de clé

Technique 2: Lire et écrire un ensemble d’enregistrements ayant une valeur commune sur une zone de clé

Tech - Par iTPro - Publié le 24 juin 2010
email

Dans les applications de gestion, on est très souvent amené à  lire un ensemble d'enregistrements " détail " partageant un enregistrement " maître " commun. Par exemple, lire les enregistrements articles de la ligne pour l'enregistrement d'une commande. Normalement, en RPG, ce type d'opération est mis en oeuvre au moyen

d’un chemin d’accès par clé pour le fichier détail,
en spécifiant une clé composite (par exemple une clé avec MasterId comme zone
de clé majeure et Seq comme zone de clé mineure). Dans un programme RPG, il
faut coder une opération SetLL pour que le pointeur se positionne sur le premier
enregistrement ayant la valeur de clé majeure spécifiée (par exemple MasterId)
et exécute ensuite les opérations ReadE en boucle jusqu’à  ce qu’il n’y ait plus
d’opérations ayant la même valeur de clé majeure.


La figure 2a montre l’essentiel de cette implémentation. Pour
des raisons de place, j’ai omis la structure de données des informations, ainsi
que les opérations d’ouverture et de fermeture de fichiers, qui sont identiques
à  celles de la figure 1a. La déclaration de KList spécifie seulement la zone
de la clé majeure (c’est-à -dire SlcMasterId). Le code opération SetLL spécifie
à  cette clé partielle de positionner le pointeur du fichier. Bien que ce ne
soit pas indispensable, je recommande de vérifier que l’opération est parvenue
à  pointer un enregistrement ayant une valeur majeure égale à  celle spécifiée,
comme je l’ai fait avec la fonction intégrée %Equal de cet exemple. (Ce qui
permet de détecter la condition  » empty set  » à  un emplacement plus pratique
du code, et évite une opération d’I/O inutile lorsqu’il n’y a aucun enregistrement
correspondant à  la clé partielle). L’opération ReadE utilise la même KList et
emploie la fonction intégrée %Eof pour déterminer quand il n’y a plus d’enregistrements
ayant la même valeur de clé majeure.


La technique SQL est un peu plus simple : elle consiste à  déclarer
un curseur incluant seulement l’ensemble d’enregistrements souhaités (c’est-à -dire
ceux ayant une valeur de zone commune), puis à  l’ouvrir pour lire tous les enregistrements
disponibles. Pour extraire les enregistrements dans l’ordre, par la/les zone(s)
de clés mineure, il faut ajouter une clause Order By spécifiant cette/ces zone(s).
SQL ne nécessite pas de chemin d’accès à  clés pour ce type d’accès, bien que
celui-ci donne de meilleures performances pour de nombreuses applications.


La figure 2b montre le code SQL essentiel, qui ressemble beaucoup
à  celui de la figure 1c, à  la différence près que l’instruction Fetch est exécutée
en boucle, parce que l’ensemble de résultats du curseur peut inclure plusieurs
enregistrements. La déclaration de curseur possède aussi une clause Order By
MasterId, Seq pour classer les enregistrements extraits par la zone de clé mineure.
Comme la clause Where limite l’ensemble de résultats aux enregistrements avec
la même valeur de clé majeure, il n’est pas nécessaire de coder la zone de la
clé majeure sur la clause Order By pour obtenir la séquence correcte. Cependant,
coder la clé complète peut aider l’optimiseur à  trouver un chemin d’accès sur
clé correspondant et à  améliorer ainsi les performances. L’état SQL (c’est-à -dire
SqlStt) défini par l’opération Fetch contrôle la boucle. L’instruction Open
Cursor aboutira, même s’il n’y a pas d’enregistrements ayant la valeur de la
clé majeure spécifiée. La boucle se terminera tout simplement, une fois que
la première exécution de l’instruction Fetch aura renvoyé l’état SQL SqlStateNoRow.
On peut déterminer qu’il n’a été trouvé aucun enregistrement pour la valeur
de la clé majeure spécifiée, en ajoutant du code pour compter le nombre d’instructions
Fetch réussies.


SQL/400 permet de lire plusieurs enregistrements à  chaque exécution
d’une instruction Fetch, plaçant les résultats dans une série de structures
hôtes


SQL/400 permet de lire plusieurs enregistrements à  chaque exécution
d’une instruction Fetch, plaçant les résultats dans une série de structures
hôtes. Ceci peut améliorer les performances, comme l’explique l’article  » Tirez
la quintessence de votre base de données grâce à  RPG & SQL ! « . (Pour en savoir
plus sur la mise en oeuvre des rangées de structures hôtes, voir l’article  »
Une approche pas à  pas des structures hôtes de SQL/400 « ).







Figure 2a Code RPG IV pour lire un ensemble d’enregistrement
ayant une valeur de clé majeure commune




* File declaration



FDetail IF E K DISK InfDs( DtlInfDs )

F UsrOpn

.

.

.

* Mnemonics



D True C Const( ‘1’ )

D False C Const( ‘0’ )

.

.

.

* Field that contains desired high-order key value



D SlcMasterId S 9B 0



* Field used to control read loop



D DtlFound S 1A Inz( False )

.

.

.

* Key list



C SlcKey KList

C KFld SlcMasterId

.

.

.

* Subroutines to process a set of records with specified

* high-order key value



* – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –

C PrcNextSet BegSr



C Eval DtlFound = False



C SlcKey SetLL (E) Detail



C Select

C When %Error

C ExSr DetailIOErr

C When %Equal( Detail )

C Eval DtlFound = True

C Other

C ExSr DtlSetNotFound

C EndSl



C DoW DtlFound = True

C ExSr ReadNextRcd

C EndDo



C EndSr

* – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –

C ReadNextRcd BegSr



C SlcKey ReadE (E) DetailR



C Select

C When %Error

C Eval DtlFound = False

C ExSr DetailIOErr

C When %Eof( Detail )

C Eval DtlFound = False

C Other

C ExSr ProcessRcd

C EndSl



C EndSr

* – – – – – – – – – – – – – – – – – – – – – – – – – – – – – –










Figure 2b Code SQL/400 pour lire un ensemble d’enregistrement
ayant une valeur de clé majeure commune



* Mnemonics



D True C Const( ‘1’ )

D False C Const( ‘0’ )

D SqlStateOk C Const( ‘00000’ )

D SqlStateNoRow C Const( ‘02000’ )



* Host variable that contains desired high-order key value



D SlcMasterId S 9B 0



* Fields used to indicate whether cursor is open and

* there are more records to read



D DetailOpen S 1A Inz( False )

D MoreDtlRcds S 1A Inz( False )



* Host record structure declaration



D DetailRcd E DS ExtName( Detail )

.

.

.

* Declare the cursor (this statement is not executable)



C/Exec SQL

C+

C+ Declare DetailTable Cursor

C+ For Select *

C+ From Detail

C+ Where MasterId = :SlcMasterId

C+ Order By MasterId,

C+ Seq

C+ For Fetch Only

C/End-Exec

.

.

.

* == The following statements are repeated for each ==

* == set of records that’s retrieved. ==



* Open the cursor and check status



C/Exec SQL

C+ Open DetailTable

C/End-Exec

C If SqlStt = SqlStateOk

C Eval DetailOpen = True

C Else

C Eval DetailOpen = False

C ExSr DetailSqlErr

C EndIf



* Retrieve the records and check status



C If DetailOpen = True

C Eval MoreDtlRcds = True

C DoW MoreDtlRcds = True

C/Exec SQL

C+ Fetch Next

C+ From DetailTable

C+ Into :DetailRcd

C/End-Exec

C Select

C When SqlStt = SqlStateOk

C ExSr ProcessRcd

C When SqlStt = SqlStateNoRow

C Eval MoreDtlRcds = False

C Other

C Eval MoreDtlRcds = False

C ExSr DetailSqlErr

C EndSl

C EndDo

C EndIf



* Close the cursor and check status

* Set cursor open status to False even if error on Close



C If DetailOpen = True

C Eval DetailOpen = False

C/Exec SQL

C+ Close DetailTable

C/End-Exec

C If SqlStt <> SqlStateOk

C ExSr DetailSqlErr

C EndIf

C EndIf


Téléchargez gratuitement cette ressource

TOP 5 Modernisation & Sécurité des Postes Clients

TOP 5 Modernisation & Sécurité des Postes Clients

Pour aider les entreprises à allier les restrictions liées à la crise et la nécessaire modernisation de leurs outils pour gagner en réactivité, souplesse et sécurité, DIB-France lance une nouvelle offre « Cloud-In-One » combinant simplement IaaS et DaaS dans le Cloud, de façon augmentée.

Tech - Par iTPro - Publié le 24 juin 2010