Aller au contenu
*DTAARA · *LDA · CL, RPG IV colonné, full free, SQL

Les zones de données, une valeur partagée entre programmes

Ce qu'est une DTAARA, ses trois types et la *LDA de chaque travail, puis trois exemples : un compteur de factures verrouillé, une zone de paramètres découpée en morceaux, et la *LDA transmise à un travail soumis. En CL, en RPG IV colonné, en full free et en SQL, tout exécuté sur un IBM i 7.5.

3types : *CHAR, *DEC, *LGL
1 024caractères de *LDA par travail
11programmes CL et RPG exécutés
30 sd'attente avant CPF1063 sur une zone verrouillée

En une phrase

Une zone de données (*DTAARA) est un objet qui contient une seule valeur, texte, nombre ou indicateur, que des programmes et des travaux différents lisent et modifient : un compteur, un paramètre, un état.

Une zone de données, c'est quoi

Un objet d'une bibliothèque, comme un programme ou un fichier, mais qui ne contient qu'une valeur, sans enregistrements ni clé. IBM le décrit comme un moyen de « communiquer et stocker les données utilisées par différents programmes à l'intérieur d'un travail ou entre les travaux ». La valeur est écrite sur disque à chaque modification : elle survit à l'arrêt du programme et du système.

TypeContenuLongueur maximalePar défautValeur initiale
*CHARCaractère2 000 caractères32, ou la longueur de la valeur initialeBlancs
*DECNumérique condensé24 chiffres, dont 9 décimales15 chiffres, dont 5 décimales0
*LGLLogique110

Pour qu'un programme CL puisse lire une zone *DEC, sa longueur totale ne doit pas dépasser 15 chiffres. Un quatrième type, *DDM, désigne une zone d'un autre système.

Les zones spéciales

Trois zones existent sans qu'on les crée. Elles n'ont pas de bibliothèque et ne demandent aucun droit :

NomZoneCaractèresPortée
*LDAZone de données locale1 024Une par travail ; aucun autre travail ne la voit. Un travail soumis par SBMJOB en reçoit une copie (démonstration plus bas).
*GDAZone de données de groupe512Une par groupe de travaux (travaux de groupe), invisible hors du groupe.
*PDAParamètres d'initialisation de programme2 000Seulement dans un travail à démarrage anticipé.

Créer et afficher une zone de données

Les zones des exemples, dans la bibliothèque JOBIDTA : un compteur numérique, une zone de paramètres de 50 caractères, et une zone qui recevra la *LDA d'un travail soumis.

CRTDTAARA DTAARA(JOBIDTA/COMPTEUR) TYPE(*DEC) LEN(7 0) VALUE(1000) TEXT('Dernier numero de facture')
CRTDTAARA DTAARA(JOBIDTA/PARAMS) TYPE(*CHAR) LEN(50) VALUE('ACMRECETTE   20261031N') TEXT('Parametres de l''application')
CRTDTAARA DTAARA(JOBIDTA/RESLDA) TYPE(*CHAR) LEN(10) TEXT('*LDA vue par le travail soumis')
Haut de l'écran DSPDTAARA JOBIDTA/COMPTEUR : type *DEC, longueur 7 0, texte Dernier numero de facture, valeur 1000
DSPDTAARA DTAARA(JOBIDTA/COMPTEUR) : une zone *DEC de 7 chiffres, valeur 1000 (haut de l'écran).
Haut de l'écran DSPDTAARA JOBIDTA/PARAMS : type *CHAR, longueur 50, valeur ACMRECETTE   20261031N sous une règle de positions
DSPDTAARA sur PARAMS : une règle de positions au-dessus de la valeur.

La zone PARAMS est découpée par convention : la société en positions 1 à 3 (ACM), l'environnement en 4 à 13 (RECETTE), la date de clôture en 14 à 21, un indicateur de blocage en 22. Les autres commandes : CHGDTAARA (modifier), RTVDTAARA (lire dans un CL), WRKDTAARA (gérer), DLTDTAARA (supprimer).

Exemple 1 Un compteur partagé

Le numéro de facture suivant

Chaque programme qui crée une facture prend le numéro suivant dans COMPTEUR. Lire, ajouter 1, réécrire : entre la lecture et l'écriture, aucun autre travail ne doit pouvoir faire de même, sinon deux factures auraient le même numéro. D'où le verrou.

RPG IV colonné NUMFAC4

     H* NUMFAC4 : prend le numero de facture suivant dans COMPTEUR
     DCOMPTEUR         S              7P 0 DTAARA
     DTEXTE            S             52A
     C* IN *LOCK : lire et verrouiller ; OUT : ecrire et liberer
     C     *LOCK         IN        COMPTEUR
     C                   EVAL      COMPTEUR = COMPTEUR + 1
     C                   OUT       COMPTEUR
     C                   EVAL      TEXTE = 'Facture numero ' + %CHAR(COMPTEUR)
     C     TEXTE         DSPLY
     C                   EVAL      *INLR = *ON

Full free NUMFACF

**FREE
// NUMFACF : prend le numero de facture suivant dans COMPTEUR
dcl-s compteur packed(7:0) dtaara;

// IN *LOCK : lire et verrouiller ; OUT : ecrire et liberer
in *lock compteur;
compteur += 1;
out compteur;
dsply ('Facture numero ' + %char(compteur));
*inlr = *on;
dcl-s compteur packed(7:0) dtaara;
Le mot-clé DTAARA sans paramètre lie la variable à la zone du même nom, cherchée dans la liste des bibliothèques (*LIBL). La variable doit avoir le type et la longueur de la zone : packed(7:0) pour une zone *DEC de 7 0.
in *lock compteur;
Lit la zone et la verrouille. En colonné : *LOCK en facteur 1, IN en code opération, la zone en facteur 2.
out compteur;
Écrit la nouvelle valeur et libère le verrou. Sans OUT ni UNLOCK, le verrou tombe à la fin du programme.

CL NUMCL

/* NUMCL : prend le numéro de facture suivant dans COMPTEUR       */
             PGM
             DCL        VAR(&NUM) TYPE(*DEC) LEN(7 0)

/* Lire puis réécrire, ce sont deux commandes : on alloue la zone */
/* pour qu'aucun autre travail ne la change entre les deux.       */
             ALCOBJ     OBJ((COMPTEUR *DTAARA *EXCL)) WAIT(10)
             RTVDTAARA  DTAARA(COMPTEUR) RTNVAR(&NUM)
             CHGVAR     VAR(&NUM) VALUE(&NUM + 1)
             CHGDTAARA  DTAARA(COMPTEUR) VALUE(&NUM)
             DLCOBJ     OBJ((COMPTEUR *DTAARA *EXCL))
             SNDPGMMSG  MSG('Facture numéro' *BCAT %CHAR(&NUM))
             ENDPGM

En CL, lire puis écrire demande deux commandes. CHGDTAARA et RTVDTAARA verrouillent la zone chacune pendant leur seule exécution : pour une mise à jour en plusieurs commandes, IBM demande d'allouer la zone par ALCOBJ, et de la libérer par DLCOBJ.

CALL QCMD
ADDLIBLE JOBIDTA
CALL NUMFAC4
CALL NUMFACF
CALL NUMCL
Écran Entrée de commandes : CALL NUMFAC4 affiche Facture numero 1001, CALL NUMFACF Facture numero 1002, CALL NUMCL Facture numéro 1003
Trois programmes, trois langages, un seul compteur : 1001, 1002, 1003.

Le verrou, vu d'un autre travail

Pour voir le verrou, un programme le garde le temps qu'on réponde à un message :

**FREE
// VERROUF : garde COMPTEUR verrouille jusqu'a la reponse
dcl-s compteur packed(7:0) dtaara;
dcl-s reponse char(1);

in *lock compteur;
dsply 'COMPTEUR verrouille, Entree pour liberer' '' reponse;
unlock compteur;
*inlr = *on;
Écran Messages du programme, recadré : DSPLY COMPTEUR verrouille, Entree pour liberer, avec la zone Réponse
VERROUF attend la réponse ; pendant ce temps, COMPTEUR reste verrouillée (capture recadrée).

Pendant l'attente, depuis un autre travail, le service QSYS2.OBJECT_LOCK_INFO montre le verrou :

SELECT LOCK_STATE, LOCK_STATUS, LOCK_SCOPE, JOB_NAME
  FROM QSYS2.OBJECT_LOCK_INFO
 WHERE OBJECT_SCHEMA = 'JOBIDTA' AND OBJECT_NAME = 'COMPTEUR'
LOCK_STATELOCK_STATUSLOCK_SCOPEJOB_NAME
*EXCLRDHELDJOB013920/SAKADM/QPADEV0001

*EXCLRD : exclusif, mais la lecture reste permise. Pendant le verrou, une lecture par DATA_AREA_INFO rend bien 1003. En revanche, la modification attend :

CHGDTAARA DTAARA(JOBIDTA/COMPTEUR) VALUE(5000)
(30 secondes d'attente)
CPF1063 : Impossible d'allouer la zone de données COMPTEUR dans JOBIDTA.

Le compteur n'a pas bougé : il valait toujours 1003. Une fois la réponse donnée, UNLOCK libère la zone et OBJECT_LOCK_INFO ne rend plus aucune ligne.

Exemple 2 Une zone découpée

Une zone de paramètres vue comme une structure

En RPG, une structure de données (DS) liée à la zone découpe PARAMS en sous-zones, en une seule lecture.

RPG IV colonné PARAM4

     H* PARAM4 : la zone PARAMS vue comme une structure de donnees
     DPARAMS           DS            50    DTAARA
     D SOCIETE                 1      3
     D ENVIRON                 4     13
     D CLOTURE                14     21
     D BLOQUE                 22     22
     DTEXTE            S             52A
     C                   IN        PARAMS
     C                   EVAL      TEXTE = 'Societe ' + SOCIETE
     C     TEXTE         DSPLY
     C                   EVAL      TEXTE = 'Environnement ' + ENVIRON
     C     TEXTE         DSPLY
     C                   EVAL      TEXTE = 'Cloture ' + CLOTURE
     C     TEXTE         DSPLY
     C                   EVAL      TEXTE = 'Bloque ' + BLOQUE
     C     TEXTE         DSPLY
     C                   EVAL      *INLR = *ON

Full free PARAMF

**FREE
// PARAMF : la zone PARAMS vue comme une structure de donnees
dcl-ds params len(50) dtaara;
  societe char(3);
  environ char(10);
  cloture char(8);
  bloque char(1);
end-ds;

in params;
dsply ('Societe ' + societe);
dsply ('Environnement ' + environ);
dsply ('Cloture ' + cloture);
dsply ('Bloque ' + bloque);
*inlr = *on;
dcl-ds params len(50) dtaara;
La structure prend la zone PARAMS ; len(50) lui donne la longueur de la zone. En colonné, DS en 24-25, la longueur 50 en 33-39, et chaque sous-zone avec ses positions de début et de fin.
in params;
Sans *LOCK : une simple lecture, sans verrou.
Écran Entrée de commandes : CALL PARAM4 et CALL PARAMF affichent chacun Societe ACM, Environnement RECETTE, Cloture 20261031, Bloque N
Les deux versions lisent les mêmes sous-zones.

En CL, pas de structure : on lit et on modifie une sous-chaîne, donnée par sa position de début et sa longueur. CHGDTAARA ne change alors que ces positions :

/* PARAMCL : lit et modifie une partie de la zone PARAMS          */
             PGM
             DCL        VAR(&SOCIETE) TYPE(*CHAR) LEN(3)
             DCL        VAR(&ENV) TYPE(*CHAR) LEN(10)

/* Une sous-chaîne : (position de début, longueur)                */
             RTVDTAARA  DTAARA(PARAMS (1 3)) RTNVAR(&SOCIETE)
             RTVDTAARA  DTAARA(PARAMS (4 10)) RTNVAR(&ENV)
             SNDPGMMSG  MSG('Société' *BCAT &SOCIETE *CAT +
                          ', environnement' *BCAT &ENV)

/* On ne change que les positions 4 à 13 : le reste est conservé  */
             CHGDTAARA  DTAARA(PARAMS (4 10)) VALUE('PROD')
             RTVDTAARA  DTAARA(PARAMS (4 10)) RTNVAR(&ENV)
             SNDPGMMSG  MSG('Nouvel environnement :' *BCAT &ENV)
             ENDPGM
Écran Entrée de commandes : CALL PARAMCL affiche Société ACM, environnement RECETTE puis Nouvel environnement : PROD ; CALL PARAMF affiche ensuite Environnement PROD, la société, la clôture et le blocage inchangés
PARAMCL passe l'environnement à PROD ; PARAMF le confirme, le reste de la zone est intact.

Exemple 3 La zone de données locale

La *LDA, propre à chaque travail

La *LDA sert à faire passer une valeur d'un programme à l'autre dans le même travail, sans paramètre. LDACL l'écrit, appelle un programme RPG qui la lit, puis soumet un travail :

CL LDACL

/* LDACL : remplit la *LDA, la lit en RPG, puis soumet un travail */
             PGM
             CHGDTAARA  DTAARA(*LDA (1 10)) VALUE('LOT-2026-A')
             CALL       PGM(LDAF)
/* Le travail soumis reçoit une copie de la *LDA                  */
             SBMJOB     CMD(CALL PGM(LDACOP)) JOB(LDACOP)
             ENDPGM

RPG IV colonné LDA4

     H* LDA4 : lit la zone de donnees locale (*LDA) du travail
     D* U en 23 et pas de nom : structure liee a la *LDA
     D                UDS
     D LOT                     1     10
     DTEXTE            S             52A
     C                   EVAL      TEXTE = 'Lot lu dans la *LDA : ' + LOT
     C     TEXTE         DSPLY
     C                   EVAL      *INLR = *ON

Full free LDAF

**FREE
// LDAF : lit la zone de donnees locale (*LDA) du travail
// Sans nom de structure ni de zone : DTAARA(*AUTO) designe la *LDA
dcl-ds *n dtaara(*auto);
  lot char(10);
end-ds;

dsply ('Lot lu dans la *LDA : ' + lot);
*inlr = *on;
D UDS
En colonné, un U en position 23 fait de la DS une structure liée à une zone, lue au démarrage du programme et écrite à la fin. Sans nom, c'est la *LDA.
dcl-ds *n dtaara(*auto);
L'équivalent full free : *AUTO pour la lecture et l'écriture automatiques, et sans nom ni de structure ni de zone, la *LDA.
Écran Entrée de commandes : CALL LDACL affiche DSPLY Lot lu dans la *LDA : LOT-2026-A et Travail 013921/SAKADM/LDACOP soumis à la file d'attente QBATCH de QGPL, puis CALL LDA4 affiche le même lot
LDAF lit le lot écrit par LDACL, et le travail LDACOP part en batch. LDA4, appelé ensuite, lit la même *LDA.

Le travail soumis, lui, recopie sa propre *LDA dans la zone RESLDA, puis modifie sa *LDA :

/* LDACOP : en batch, recopie sa *LDA dans la zone RESLDA         */
             PGM
             DCL        VAR(&LOT) TYPE(*CHAR) LEN(10)
             RTVDTAARA  DTAARA(*LDA (1 10)) RTNVAR(&LOT)
             CHGDTAARA  DTAARA(RESLDA) VALUE(&LOT)
/* Modifier sa *LDA ne change pas celle du travail qui a soumis   */
             CHGDTAARA  DTAARA(*LDA (1 10)) VALUE('MODIFIE')
             ENDPGM
Haut de l'écran DSPDTAARA JOBIDTA/RESLDA : valeur LOT-2026-A
RESLDA contient LOT-2026-A : le travail soumis a reçu une copie de la *LDA.
Haut de l'écran DSPDTAARA *LDA du travail interactif : *CHAR de longueur 1024, valeur LOT-2026-A
Puis DSPDTAARA DTAARA(*LDA) dans le travail interactif : toujours LOT-2026-A, pas MODIFIE. Le travail soumis n'avait changé que sa copie.

La *LDA ne se verrouille pas : IN *LOCK sur elle est refusé à la compilation (RNF7090).

Le piège du full free : les apostrophes

En colonné, DTAARA(COMPTEUR) désigne la zone COMPTEUR. En full free, sans apostrophes, c'est le nom d'une variable (ou d'une constante) qui contient le nom de la zone. Le même mot-clé, recopié du colonné vers le free :

dcl-s numero packed(7:0) dtaara(COMPTEUR);
RNF7030 sev 30 : Le nom ou l'indicateur COMPTEUR n'est pas défini.

En full free, on écrit le nom entre apostrophes, éventuellement avec la bibliothèque, en majuscules : dtaara('JOBIDTA/COMPTEUR') compile sans erreur. Sans parenthèses, c'est le nom de la variable qui sert, comme dans NUMFACF. En colonné, DNUMERO S 7P 0 DTAARA(COMPTEUR) compile aussi : COMPTEUR y est bien le nom de la zone.

Lire une zone de données en SQL

Le service QSYS2.DATA_AREA_INFO existe en vue, pour toutes les zones, et en fonction de table, pour une zone précise. Résultats obtenus après les exemples ci-dessus :

SELECT DATA_AREA_NAME, DATA_AREA_TYPE, LENGTH, DECIMAL_POSITIONS, DATA_AREA_VALUE
  FROM QSYS2.DATA_AREA_INFO
 WHERE DATA_AREA_LIBRARY = 'JOBIDTA'
 ORDER BY DATA_AREA_NAME
DATA_AREA_NAMEDATA_AREA_TYPELENGTHDECIMAL_POSITIONSDATA_AREA_VALUE
COMPTEUR*DEC701003
PARAMS*CHAR50-ACMPROD      20261031N
RESLDA*CHAR10-LOT-2026-A

La fonction de table, avec SUBSTR pour retrouver les sous-zones :

SELECT SUBSTR(DATA_AREA_VALUE, 4, 10) AS ENVIRONNEMENT,
       SUBSTR(DATA_AREA_VALUE, 22, 1) AS BLOQUE
  FROM TABLE(QSYS2.DATA_AREA_INFO(DATA_AREA_NAME => 'PARAMS',
                                  DATA_AREA_LIBRARY => 'JOBIDTA'))
ENVIRONNEMENTBLOQUE
PRODN

Pour modifier une zone depuis SQL, on passe la commande CL à QSYS2.QCMDEXC :

CALL QSYS2.QCMDEXC('CHGDTAARA DTAARA(JOBIDTA/PARAMS (22 1)) VALUE(''O'')')
ENVIRONNEMENTBLOQUE
PRODO

Le résultat est celui de la fonction de table relancée après l'appel : BLOQUE vaut maintenant O.

Les erreurs, et ce qu'elles veulent dire

MessageQuandTexteCause
CPF1063à l'exécution, autre travailImpossible d'allouer la zone de données COMPTEUR dans JOBIDTA.La zone est verrouillée par un autre travail (IN *LOCK, ALCOBJ) : CHGDTAARA a attendu 30 secondes, puis abandonné.
RNF7030à la compilation, full freeLe nom ou l'indicateur COMPTEUR n'est pas défini.DTAARA(COMPTEUR) sans apostrophes : en full free, c'est le nom d'une variable qui contient le nom de la zone.
RNF7090à la compilation*LOCK utilisé en Facteur 1 avec LDA ou PDA comme Facteur 2.IN *LOCK sur la *LDA : elle n'appartient qu'au travail, il n'y a rien à verrouiller.

Sources

Les exemples ont été exécutés sur un IBM i 7.5 (voir la méthode). Les règles viennent de ces sources, consultées le 23 octobre 2026 :

  1. Create Data Area (CRTDTAARA), IBM, IBM i 7.5 CL commands. Types *DEC, *CHAR, *LGL et *DDM ; longueurs maximales (24 chiffres dont 9 décimales, 2 000 caractères, 1) et par défaut (15 5, 32, 1) ; 15 chiffres au plus pour un usage en CL ; zone écrite sur disque à chaque modification.
  2. Change Data Area (CHGDTAARA), IBM, IBM i 7.5 CL commands. *LDA de 1 024 caractères, *GDA de 512, *PDA de 2 000 ; sous-chaîne (début, longueur) ; zone partagée mise à jour en plusieurs commandes : l'allouer par ALCOBJ.
  3. Retrieve Data Area (RTVDTAARA), IBM, IBM i 7.5 CL commands. Lecture de tout ou partie d'une zone dans une variable CL, dans un programme CL seulement.
  4. ILE RPG Reference (SC09-2508-12), IBM, IBM i 7.5 (PDF). Mot-clé DTAARA en full free (nom entre apostrophes, sinon variable ou constante qui le contient) et en colonné ; *AUTO et *USRCTL ; U en position 23 ; *LDA pour une structure sans nom ; IN, OUT, UNLOCK et *LOCK, interdit sur la *LDA ; même type et même longueur que la zone.

Questions fréquentes

Qu'est-ce qu'une zone de données (DTAARA) sur IBM i ?

Un objet de type *DTAARA qui contient une seule valeur : du texte (*CHAR, 2 000 caractères au plus), un nombre (*DEC, 24 chiffres dont 9 décimales au plus) ou un indicateur (*LGL). Elle sert à garder et à partager une valeur entre programmes ou entre travaux : un compteur, un paramètre, un état.

Quelle différence entre une zone de données et la *LDA ?

Une zone de données est un objet d'une bibliothèque, visible de tous les travaux qui ont le droit de la lire. La *LDA (zone de données locale) est une zone de 1 024 caractères propre à chaque travail : aucun autre travail ne la voit. Un travail soumis par SBMJOB en reçoit une copie.

Comment lire une zone de données en CL ?

Avec RTVDTAARA, dans un programme CL : RTVDTAARA DTAARA(PARAMS (4 10)) RTNVAR(&ENV) lit 10 caractères à partir de la position 4. CHGDTAARA la modifie, DSPDTAARA l'affiche.

Comment lire et modifier une zone de données en RPG ?

On la déclare avec le mot-clé DTAARA sur une variable ou une structure de données, puis IN la lit et OUT l'écrit. IN *LOCK la verrouille jusqu'à OUT, UNLOCK ou la fin du programme : c'est ce qu'il faut pour un compteur partagé.

Que se passe-t-il si un autre travail a verrouillé la zone ?

IN *LOCK pose un verrou *EXCLRD : les autres travaux peuvent encore la lire, mais pas la modifier. Sur IBM i 7.5, un CHGDTAARA lancé depuis un autre travail a attendu 30 secondes, puis a échoué avec CPF1063, « Impossible d'allouer la zone de données ».

Peut-on lire une zone de données en SQL ?

Oui, avec QSYS2.DATA_AREA_INFO, en vue pour toutes les zones ou en fonction de table pour une zone précise. Pour la modifier depuis SQL, on peut appeler CHGDTAARA par QSYS2.QCMDEXC.