Instruction RPG full free · IBM i (AS/400) · Écriture et contrôle des fichiers
UPDATE
Modifier l'enregistrement lu
Réécrit dans le fichier l'enregistrement qui vient d'être lu, avec les nouvelles valeurs des zones.
Syntaxe
UPDATE format;
UPDATE format structure;
UPDATE format %FIELDS(zone1 : zone2);
UPDATE(E) format;
format- Le nom du format d'enregistrement (
CLIENTWR). structure- Facultatif : structure de données qui fournit les valeurs à réécrire.
%FIELDS(zone : …)- Facultatif : ne réécrire que les zones citées. Les autres gardent la valeur du fichier, même si le programme les a changées.
(E)- Une erreur positionne
%ERRORet%STATUSau lieu d'arrêter le programme. - Effet
- Remplace l'enregistrement verrouillé par la dernière lecture et libère le verrou.
%FOUNDet%EOFne changent pas. Sans lecture avec verrou juste avant, l'instruction échoue avec%STATUS1221 (messageRNQ1221sans (E)).
À quoi ça sert
Un UPDATE agit toujours sur le dernier enregistrement lu du fichier : on lit avec CHAIN, READ, READE…, on change les zones, on écrit. Le fichier doit être déclaré avec usage(*update). La lecture pose un verrou, UPDATE le lève.
Le mot-clé %FIELDS permet de dire précisément ce qui change, au lieu de réécrire tout le format comme on le faisait en RPG IV en colonnes.
Exemple 1 : Modifier un client, avec %FIELDS
**free
// UPDATE : modifier l'enregistrement qui vient d'etre lu.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-f clientw usage(*update : *output : *delete) keyed
extdesc('JOBISQL/CLIENTW') extfile(*extdesc);
dcl-s ancien like(solde);
// On lit le client 100 (CHAIN le verrouille), on change deux zones.
chain (100) clientw;
ancien = solde;
solde = solde + 500;
ville = 'Nimes';
update clientwr;
chain (100) clientw;
snd-msg 'Apres UPDATE : [' + %trim(ville) + '] ' + %char(solde);
// UPDATE avec %FIELDS : seule la zone SOLDE est reecrite, VILLE reste intacte.
ville = 'Paris';
solde = solde + 1;
update clientwr %fields(solde);
chain (100) clientw;
snd-msg 'Avec %FIELDS : [' + %trim(ville) + '] ' + %char(solde);
// Remise en etat de l'enregistrement.
solde = ancien;
ville = 'Montpellier';
update clientwr;
chain (100) clientw;
snd-msg 'Restaure : [' + %trim(ville) + '] ' + %char(solde);
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Apres UPDATE : [Nimes] 1750.50
Avec %FIELDS : [Nimes] 1751.50
Restaure : [Montpellier] 1250.50
Après CHAIN, le solde et la ville du client 100 changent et update clientwr; les écrit. Dans le second UPDATE, %fields(solde) écrit seulement le solde : la ville mise à Paris dans le programme n'arrive pas dans le fichier, elle reste Nimes. Le dernier UPDATE remet les valeurs d'origine.
Exemple 2 : UPDATE refusé : pas de verrou
**free
// UPDATE : sans lecture avec verrou juste avant, l'instruction est refusee.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-f clientw usage(*update : *output : *delete) keyed
extdesc('JOBISQL/CLIENTW') extfile(*extdesc);
// Cas 1 : le CHAIN ne trouve rien (client 999), il n'y a rien a modifier.
chain (999) clientw;
snd-msg 'CHAIN 999 : trouve = ' + %char(%found(clientw));
update(e) clientwr;
snd-msg 'Cas 1 CHAIN rate : erreur = ' + %char(%error) + ', statut = ' + %char(%status(clientw));
// Cas 2 : CHAIN(N) lit sans verrouiller, l'enregistrement ne peut pas etre modifie.
chain(n) (200) clientw;
update(e) clientwr;
snd-msg 'Cas 2 CHAIN(N) : erreur = ' + %char(%error) + ', statut = ' + %char(%status(clientw));
// Cas 3 : une seule modification par lecture. Le second UPDATE est refuse.
chain (200) clientw;
update(e) clientwr;
snd-msg 'Cas 3 premier UPDATE: erreur = ' + %char(%error);
update(e) clientwr;
snd-msg 'Cas 3 second UPDATE : erreur = ' + %char(%error) + ', statut = ' + %char(%status(clientw));
// Sans (E), le programme s'arrete sur le message RNQ.
chain (999) clientw;
update clientwr;
snd-msg 'Cette ligne ne s''affiche pas';
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
CHAIN 999 : trouve = 0
Cas 1 CHAIN rate : erreur = 1, statut = 1221
Cas 2 CHAIN(N) : erreur = 1, statut = 1221
Cas 3 premier UPDATE: erreur = 0
Cas 3 second UPDATE : erreur = 1, statut = 1221
Erreur : RNQ1221 - MAJ ou SUP sur fichier CLIENTW, sans opération d'entrée préalable.
Trois situations où UPDATE n'a plus d'enregistrement verrouillé : le CHAIN n'a rien trouvé, la lecture était un CHAIN(N) (sans verrou), ou un premier UPDATE a déjà consommé la lecture. Chaque fois, %STATUS vaut 1221. Sans (E), le programme s'arrête sur RNQ1221.
Le piège
Un UPDATE par lecture, et seulement après une lecture qui verrouille. Un CHAIN raté, un CHAIN(N) ou un deuxième UPDATE de suite donnent l'erreur 1221 (exemple 2). Dans une boucle, relisez avant chaque UPDATE, et testez %FOUND après le CHAIN.