Aller au contenu

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 %ERROR et %STATUS au lieu d'arrêter le programme.
Effet
Remplace l'enregistrement verrouillé par la dernière lecture et libère le verrou. %FOUND et %EOF ne changent pas. Sans lecture avec verrou juste avant, l'instruction échoue avec %STATUS 1221 (message RNQ1221 sans (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.