, , , Préciser la bibliothèque dans un SELECT INTO

Vous avez dans un programme RPGLE un select into en SQL à faire, mais vous devez choisir la bibliothèque ou se trouve le fichier !

Voici 3 solutions pour éviter le hard codage

1ére solution

Cette solution est plus adaptée à un curseur.

Formater une variable exemple sqlstm

sqlstm = ‘select votrezone from ‘ + votre_lib + ‘/votre_table’ ;

exec SQL
declare curs01 Cursor
for sqlstm ;

exec SQL
prepare sqlstm
from :sqlstm ;

exec SQL
open curs01 ;

exec sql
fetch next
from curs01
into :votrezone ;

On est d’accord, c’est un peu lourd

Voici une alternative

Si vous êtes en convention de nommage *SYS, vous pouvez utiliser la liste de bibliothèques

exec sql
call qcmdexc( ‘addlible ‘ concat :votre_lib) ;
// select sans bibliothèque
exec sql
select mazone into : wmazone from matable ;

Si vous êtes en convention de nommage *SQL, vous devez préciser le schéma courant – par défaut c’est le profil utilisateur.
// select sans bibliothèque
exec sql
set schema :votre_lib ;

exec sql
select mazone into : wmazone from matable ;

A noter que dans la cas d’une convention de nommage *SQL, toutes vos tables doivent être dans la même bibliothèque, en cas de jointure par exemple

Il existe effectivement une autre alternative avec dynamic SQL,

Merci Birgitta pour cette précision .

Avec dynamic SQL et VALUES … INTO:
Exemple:
CmdSQL = ‘Values( Select Count(*) from ‘ + %Trim(YourSchema) + ‘.YourTable ‘ +
‘ ) into ?’;

Exec SQL Prepare DynSQL from :CmdSQL;
Exec SQL Execute DynSQL using :YourResult;

, , Zones numériques étendues

Voici une petite expérience à faire sur les zones étendues

Commençons par créer un fichier PF comme ceci

A R TESTAF
A NUMERO 5
A NOM 30
A PRENOM 30

Compilez-le

on lui met des données

par exemple par SQL

INSERT INTO GDATA/TESTA VALUES(‘AAAAA’, ‘Carlsen’, ‘Magnus’)
INSERT INTO GDATA/TESTA VALUES(‘BBBBB’, ‘Vachier-Lagrave’, ‘Maxime’)
INSERT INTO GDATA/TESTA VALUES(‘CCCCC’, ‘Firouzja’, ‘Alireza’)

Si on fait un DSPPFM, on voit ceci

On décide de changer NUMERO et de le passer en numérique

On a donc le fichier décrit comme suit

A R TESTNF
A NUMERO 5S 0
A NOM 30
A PRENOM 30

Vous le compilez

vous décidez de récupérer les données

par un CPYF

CPYF FROMFILE(TESTA)
TOFILE(TESTN)
MBROPT(*REPLACE) FMTOPT(*NOCHK)

vous faites DSPPFM du fichier TESTN, voici le résultat :

Vous faites un select * from TESTN voici le résultat :

C’est étonnant non ?

Si vous faites un contrôle de données vous n’avez pas d’erreur

SELECT * FROM TABLE(SYSTOOLS.VALIDATE_DATA_FILE(‘GDATA’, ‘TESTN’));

Vous allez me dire pourquoi ne pas faire le nouveau fichier comme une table, allons y ?

CREATE TABLE GDATA.TESTS (
NUMERO NUMERIC(5, 0) NOT NULL DEFAULT 0 ,
NOM CHAR(30) CCSID 1147 NOT NULL DEFAULT  » ,
PRENOM CHAR(30) CCSID 1147 NOT NULL DEFAULT  » )
RCDFMT TESTS

On récupère a nouveau des données

CPYF FROMFILE(TESTA)
TOFILE(TESTN)
MBROPT(*REPLACE) FMTOPT(*NOCHK)

Si on fait un DSPPFM voici le résultat :

Si on fait un select * from TESTS :

conclusion

Si vous copiez des données alpha dans du numérique étendu

1/ En DDS

Les données sont fausses dans le fichier et interprétées à l’exécution SQL
attention si vous lisez en RPG les données ne sont pas chargées et il n’y a pas d’erreur !

exemple :

fTESTN if e disk
read(e) TESTN ;
if %error ;
dsply ‘ici’ ;
else ;
dsply ‘la’ ;
dsply NOM ; ;
endif ;
*inlr = *on ;

2/ En SQL

Le données sont converties lors du CPYF, mais elles ne sont pas bonnes : on passe ici de AAAAA à 11111

Faites attention si vous récupérez des données numériques étendues vous pourriez avoir des surprises

Dernière remarque

Il n’y pas de problème avec des données packées :
En DDS, RPG ou SQL erreur à la lecture.
En SQL, impossible de copier les données.

Vous voulez avoir des informations sur des exécutions SQL.

La meilleure méthode est de prendre la requête que vous voulez analyser et de l’exécuter dans Visual Explain.

Mais ce n’est pas toujours possible , dans le cas d’une chaine avec du SQL embarqué .

Si vous avez fait du SQL statique vous pouvez avoir des informations au niveau des programmes par PRTSQLINF.

Dans certains cas, on n’a pas ces possibilités. Le plus simple est alors de ce mettre en debug et d’exécuter votre chaine, attention ce n’est pas un mode à mettre en place en production, ça augmente considérablement les informations de log.

Vous devez démarrer le debug, le plus souvent en indiquant que vous autorisez les mises à jour sur les fichiers de production.
==>strdbg updprod(*yes)

Vous lancez ensuite votre traitement qui va générer un log avec des messages de votre optimiseur SQL, ce sont des messages id CPI43xx

Il vous suffit ensuite d’analyser votre log et regarder si certains messages vous donnent des informations intéressantes.
exemple :
CPI432F index à ajouter

Pour vous aider nous avons fait cet outil DBGSQLJOB que vous retrouverez ici et qui vous facilite la démarche
https://github.com/Plberthoin/PLB/tree/master/GTOOLS

Vous soumettez votre programme comme ceci
sbmjob cmd(DBGSQLJOB cmd(call monpgm) ) job(dbgsql)

et vous obtenez un fichier dbgsql dans la bibliothèque indiquée (par défaut *curlib) qui contiendra les messages de votre optimiseur.

Vous n’avez plus qu’a les analyser ensuite par select * from DBGSQL .

Limitation :
Dans cet outil, nous traitons en commit(*none) les requêtes SQL, si ce n’est pas le cas chez vous, adaptez le mode.

Rappel :
80 % de votre performance SQL c’est les index , suivez les recommandations de INDEX ADVISOR.

Vous installez de nouveaux PCs et vous désirez savoir les ports à ouvrir pour pouvoir accéder à vos partitions IBMi.

Voici une liste de ports à ouvrir en priorité

Pour ACS :


23 requis TELNET
449 requis arborescence du serveur IBM i
8470 à 8476 (voir RDI)

Pour RDi :


446 Requis (DRDA : connecteur base de données entre serveurs)
449 (as-srvmap) requis arborescence du serveur IBM i
3825 (Debugger) : débogage RDi
4300 (STRRSESVR) débogage via RDi (permet le rappel par l’IBM i du client RDi)
8470 (as-central) requis : Gestion des licences
8471 (as-database) requis base de données
8472 (as-dtaq) requis : serveur de file d’attente de données
8473 (as-file) requis : serveur de fichiers
8474 (as-netprt) serveur d’impression réseau
8475 (as-rmtcmd) requis : envoi de commandes
8476 (as-signon) requis : serveur ouverture de session

Merci à Jean-Marie pour son aide !

, Afficher un panel de groupe

Voici un dernier poste sur la série UIM , pour vous aider à tester vos panneaux de groupe

il existe une API QUHDSPH pour faire cet affichage

Vous trouverez une exemple, une commande DSPPNLGRP ici

https://github.com/Plberthoin/PLB/tree/master/GTOOLS

.

.

Vous pouvez maintenant créer un

Un menu UIM

Convertir un menu SDA en UIM

Générer un squelette d’aide pour vos commandes

Et tester votre panneaux d’aide

Vous pouvez allez plus loin , en apprenant le langage UIM et ses subtilités.

, , Réplication de mot de passe

Vous avez plusieurs partitions et vous voulez toutes les mettre à jour quand vous changez votre mot de passe.

Voici une méthode qui peut vous aider

1) Extraction du hash du mot de passe

Vous pouvez utiliser l’API, QSYRUPWD.
Voici un exemple RTVUSRPWD
Vous pouvez trouver les sources ICI,
https://github.com/Plberthoin/PLB/tree/master/GTOOLS

2) Envoi des informations du hash

Réplication des informations de hash par exemple avec une remote dtaara, remote dtaq ou envoi de celle ci par SAVRSTOBJ dans une dtaara ou un fichier.

3) Application du hash sur le nouveau profil

Vous pouvez utiliser l’API, QSYSUPWD
Voici un exemple CHGUSRPWD
Vous pouvez trouver les sources ICI,
https://github.com/Plberthoin/PLB/tree/master/GTOOLS

4) Automatisation

Vous pouvez ensuite automatiser la détection de vos modifications en utilisant un programme d’exit ou les journaux d’audit.

, , Créer un menu UIM

Voici un 2ème post d’une série consacré à UIM (User Interface Manager).

Ce langage peut vous permettre de réaliser des menus standards IBM, en effet tous les menus sont codés en ce langage !

Vous allez devoir saisir un code source au format UIM puis le compiler.
Ça peut être fastidieux à réaliser, c’est pourquoi nous avons réalisé un outil (CRTMNUUIM) qui va vous permettre de réaliser un menu sans aucune compétence dans ce langage.

Vous pouvez le retrouver ici https://github.com/Plberthoin/PLB/tree/master/GTOOLS/

1) Génération du source du menu

vous pouvez indiquer jusqu’à 10 commandes

Exemple

CRTMNUUIM MENU(GAIA/MONMENU)
FICHIER(GAIA/QMNUSRC)
SOCIETE(GAIA)
TITRE(‘Gestion Spools’)
OPTION1(‘Gestion Spools’)
COMMANDE1(WRKSPLF)
OPTION2(‘Gestion Outqs’)
COMMANDE2(‘?WRKOUTQ’)

Si vous avez quelques compétences malgré tout, vous pouvez éditer le source ici MONMENU du fichier source QMNUSRC, en complétant par exemple les aides !

2) Vous pouvez ensuite compiler le menu en indiquant que vous avez un source UIM

CRTMNU MENU(GAIA/MONMENU) TYPE(*UIM) SRCFILE(GAIA/QMNUSRC)

3) Vous avez alors un menu identique à tous les menus IBM

Pour le lancer
GO MENU(MONMENU)

, , Ajouter de l’aide à vos commandes

Vous créez des commandes et vous voudriez leur ajouter de l’aide, ces aides sont écrites dans un langage UIM (User Interface Manager) qui vous permet de générer des panneaux d’aide que vous pouvez ensuite ajouter à vos commandes.
Le langage UIM est un langage de présentation un peu similaire à HTML, il existe de nombreux sites pour l’apprendre.
Pour les commandes, il existe une commande IBMi qui permet de générer une structure qui vous permettra de vous concentrer sur le texte à mettre sans avoir de connaissance approfondie du langage UIM.

Nous avons fait un outil que vous pouvez trouver ici https://github.com/Plberthoin/PLB/tree/master/GTOOLS/
qui vous permettra d’automatiser la génération votre source et voici ce que vous devrez faire ensuite

1) Génération du source en utilisant notre outil

GTOOLS/GENCMDUIM COMMANDE(GTOOLS/SCANSRC)
FICHIER(GTOOLS/QPNLSRC)

2) Modification du source

Vous devez customiser votre source en indiquant vos spécificités

3) Compilation du panel de groupe

CRTPNLGRP PNLGRP(GREFER/SCANSRC)
SRCFILE(GREFER/QPNLSRC)

4) Association de l’aide à la commande

CHGCMD CMD(GREFER/SCANSRC)
HLPPNLGRP(GREFER/SCANSRC)
HLPID(*CMD)

5) Tester votre commande

==>SCANSRC puis <F4> et <F1>

Quelques sites pour vous aider

https://www.rpgpgm.com/2017/02/creating-help-text-using-uim.html

https://www.volubis.fr/news/liens/AF4SRC/ANIMTXT/UIM.htm

https://larreya.pagesperso-orange.fr/as400/hlphlp.html

Tester les paramètres en CLP

Comment traiter le passage de paramètres en CLP ?

Le principe est le suivant, les paramètres sont passés dans l’ordre et si vous utilisez la zone associée, vous devez l’avoir reçu

Voici 2 méthodes pour vous aider à tester vos paramètres :

La première solution est disponible depuis la version 7.3

Vous avez une nouvelle fonction qui est %parm

exemple

pgm (&parm1 &parm2 )
dcl &parm1 *char 10
dcl &parm2 *char 10
dcl &nbparm *dec 3
dcl &nbparma *char 3
/* test paramètre */

chgvar &nbparm %parms

/* nombre de paramètres */

if cond(&nbparm < 1) then(do)

SNDUSRMSG MSG(‘Paramètre &parm1 non reçu’) MSGTYPE(INFO)
return
enddo
if cond(&nbparm < 2) then(do)
SNDUSRMSG MSG(‘Paramètre &parm2 non reçu’) MSGTYPE(INFO)

return

enddo

/* pour afficher le nombre de paramètres */
chgvar &nbparma &nbparm
SNDUSRMSG MSG(‘Nombre de paramètres’ *bcat &nbparma ) MSGTYPE(*INFO)
endpgm

La deuxième solution est historique il faut traiter le message MCH3601

Exemple :

pgm (&parm1 &parm2 )
dcl &parm1 *char 10
dcl &parm2 *char 10
/* test paramètre /

/* si paramètres non passés on sort */

chgvar &parm1 &parm1

monmsg MCH3601 exec(do)

SNDUSRMSG MSG(‘Paramètre &parm1 non reçu’) MSGTYPE(INFO)
return
enddo
chgvar &parm2 &parm2
monmsg MCH3601 exec(do)
SNDUSRMSG MSG(‘Paramètre &parm2 non reçu’) MSGTYPE(*INFO)
return
enddo
endpgm

, , Nombre d’accès DB d’un travail

Vous voulez avoir une idée du nombre d’entrées-sorties que génère un travail sur votre base de données.

Pour ceci, vous pouvez par exemple utiliser la comptabilité des travaux.

Pour utiliser cette fonctionnalité, vous devez la mettre en œuvre voici comment :

1 ) Créer un récepteur de journal par exemple dans qusrsys ou une de vos bibliothèques
CRTJRNRCV JRNRCV(QUSRSYS/QACGJRN)
2) Créer le journal QACGJRN
CRTJRN JRN(QSYS/QACGJRN)
JRNRCV(QUSRSYS/QACGJRN)
3) Changer la valeur système QACGLVL
CHGSYSVAL SYSVAL(QACGLVL) VALUE(‘*JOB’)

Tous les jobs démarrés à partir de ce moment seront logués

Pour analyser vous avez des postes de type JB
Le plus simple est d’utiliser un fichier modèle
Le fichier modèle qui correspond est QSYS/QAJBACG4

dupliquez le

CRTDUPOBJ OBJ(QAJBACG4)
FROMLIB(QSYS)
OBJTYPE(*FILE)
TOLIB(PLB)
NEWOBJ(WAJBACG4)

Maintenant vous pouvez le remplir en faisant un DSPJRN

DSPJRN JRN(QACGJRN)
JRNCDE((A))
ENTTYP(JB)
OUTPUT(OUTFILE) OUTFILFMT(TYPE4)
OUTFILE(PLB/WAJBACG4)

Vous pouvez alors interroger votre fichier par sql

exemple ici en se limitant au jobs interactifs :

SELECT
JAJOBH as travail,
JAUSRH as utilisateur,
JANBRH as numero,
JADBPT as acces,
JADBGT as creation,
JADBUP as mise_à_jour
FROM PLB.WAJBACG4
WHERE JATYPE = ‘I’

Remarque :
N’oubliez pas supprimer les récepteurs quand vous les avez traité
Si vous voulez arrêter la collecte
CHGSYSVAL SYSVAL(QACGLVL) VALUE(‘*NONE’)

Vous pouvez également utiliser la comptabilité des travaux pour de nombreuses autres informations, pour par exemple estimer vos volumes d’impression.