Aller au contenu

%NULLIND

Indicateur NULL d'une zone

Lit ou positionne l'indicateur qui dit si une zone de fichier est NULL, ce qui permet de traiter des colonnes SQL nullables en RPG natif.

Syntaxe

%NULLIND(zone)
%NULLIND(zone) = *ON | *OFF
zone
Une zone d'un fichier décrit avec des valeurs NULL possibles. Le programme doit avoir alwnull(*usrctl) dans ctl-opt.
Résultat
Un indicateur (*ON si la zone est NULL). La fonction peut aussi se trouver à gauche d'une affectation pour rendre une zone NULL ou non.

À quoi ça sert

Une table SQL peut contenir des valeurs NULL. En lecture native, sans précaution, une zone NULL fait échouer la lecture (statut 1299). Avec alwnull(*usrctl), le programme lit sans erreur et c'est à lui de tester %NULLIND avant d'utiliser la zone.

La fonction sert aussi à écrire : allumer l'indicateur enregistre NULL, l'éteindre enregistre la valeur.

Exemple 1 : Lire les clients sans planter

**free
// %NULLIND : lire une zone qui peut etre NULL dans le fichier.
ctl-opt dftactgrp(*no) actgrp(*new) alwnull(*usrctl);

dcl-f client keyed;

read client;
dow not %eof(client);
  if %nullind(datcre);
    snd-msg %char(numcli) + ' ' + %trim(nom) + ' : date de creation inconnue';
  else;
    snd-msg %char(numcli) + ' ' + %trim(nom) + ' : cree le ' + %char(datcre : *eur);
  endif;
  read client;
enddo;

*inlr = *on;

Résultat réel, compilé et exécuté sur IBM i 7.5 :

100 Dupont SA : cree le 15.03.2020
200 Martin et fils : cree le 02.11.2021
300 Leroy SARL : date de creation inconnue
400 Bernard Transports : cree le 30.06.2019
500 Petit Atelier : cree le 08.01.2024

Le client 300 a une date de création NULL. Grâce à alwnull(*usrctl), la lecture réussit et %NULLIND(datcre) vaut 1 : le programme affiche « date de création inconnue » au lieu d'utiliser la zone.

Exemple 2 : Écrire une date dans une zone NULL

**free
// %NULLIND en ecriture : affecter la zone ne suffit pas, il faut eteindre l'indicateur.
ctl-opt dftactgrp(*no) actgrp(*new) alwnull(*usrctl);

dcl-f f_client usage(*update) keyed;
dcl-ds relu likerec(f_clientr : *input);

chain (300) f_client;
snd-msg 'Avant             : NULL = ' + %char(%nullind(datcre));

// La date est renseignee, mais l'indicateur NULL reste allume
datcre = d'2022-05-01';
snd-msg 'Apres affectation : NULL = ' + %char(%nullind(datcre));
update f_clientr;
chain (300) f_client relu;
snd-msg 'Relecture 1       : NULL = ' + %char(%nullind(relu.datcre));

// On eteint l'indicateur : la date est enfin enregistree
datcre = d'2022-05-01';
%nullind(datcre) = *off;
update f_clientr;
chain (300) f_client relu;
snd-msg 'Relecture 2       : NULL = ' + %char(%nullind(relu.datcre)) + ' ' + %char(relu.datcre);

// Remise en etat : la zone redevient NULL
%nullind(datcre) = *on;
update f_clientr;

*inlr = *on;

Résultat réel, compilé et exécuté sur IBM i 7.5 :

Avant             : NULL = 1
Apres affectation : NULL = 1
Relecture 1       : NULL = 1
Relecture 2       : NULL = 0 2022-05-01

Après la lecture du client 300, la zone est NULL. Affecter une date à datcre ne change rien à l'indicateur (toujours 1) : le premier UPDATE réécrit donc NULL. Il faut éteindre l'indicateur avant l'UPDATE : la relecture suivante donne la date. À la fin, on rallume l'indicateur pour remettre le fichier en l'état.

Le piège

Affecter la zone n'éteint pas son indicateur NULL. Dans le deuxième exemple, la date est bien dans la zone, mais l'UPDATE enregistre quand même NULL, sans message d'erreur. Il faut écrire %nullind(datcre) = *off.

Deux autres points vérifiés : sans alwnull(*usrctl), la compilation refuse la fonction (RNF7420), et la lecture d'une zone NULL échoue au lieu d'être traitée (statut 1299). Enfin, quand la zone est NULL, sa valeur est une valeur par défaut (0001-01-01 pour une date), pas une vraie date.