, Comment Modifier un spool ?

Vous avez un spool généré et vous voulez le modifier, bien sur si vous pouvez agir avant la génération du spool c’est mieux.

Imaginons que vous ne pouvez pas le faire, voici la procédure en quelques étapes pour réaliser cette opération.

Vous devez créer un fichier qui a la longueur de votre spool + 1

CRTPF QTEMP/SPOOLPF RCDLEN(longueur + 1)

Ensuite vous avez besoin d’identifier votre spool
nom_spool, Numero_job, Utilisateur, Nom_job et numero_spool (souvent , on peut utiliser *LAST)

Vous allez copier votre spool en idiquant bien *FCFC

CPYSPLF FILE(NOM_SPOOL) TOFILE(QTEMP/SPOOLPF)
JOB(NUMERO_JOB/UTILISATEUR/NOM_JOB)
SPLNBR(LAST) CTLCHAR(*FCFC)

Vous pouvez alors modifier votre ficher DB généré, par SQL, DFU ou par programme

Votre fichier est modifié, vous allez devoir le recopier pour regénérer un spool.
D’abord, indiquez que vous avez besoin des caractères de contrôle


OVRPRTF FILE(NOM_SPOOL) CTLCHAR(*FCFC)


Transformation de votre fichier DB en SPOOL


CPYF FROMFILE(QTEMP/SPOOLPF) TOFILE(NOM_SPOOL)

Vous pouvez à nouveau gérer votre spool, exemple pour le changer de file :


CHGSPLFA FILE(NOM_SPOOL) JOB(NUMERO_JOB/UTILISATEUR/NOM_JOB)
SPLNBR(*LAST) OUTQ(TLXOFC/FAX)

Conclusion :

Ca reste du bricolage, mais ca peut dépanner.

, Messages CPF1124 et CPF1164

Quand un travail démarre, il crée dans la log système un message CPF1124 et un message CPF1164 quand il se termine.

C’est comme ca qu’on sait qu’un job à tourné

Mais attention, Il existe des travaux pour lesquels les messages CPF1124 et CPF1164 ne sont pas logués dans QHST : il s’agit des SPAWN jobs.

Les travaux QP0ZSPWP & QP0ZSPWT en sont de bons exemples.

Spawn batch jobs : https://www.ibm.com/docs/en/i/7.4?topic=jobs-spawn-batch

Spawn est une fonction qui crée un nouveau processus de travail (processus enfant) qui hérite de nombreux attributs du processus appelant (processus parent). Un nouveau programme est spécifié et commence à s’exécuter dans le processus enfant. Lorsque vous lancez un travail par lots, vous utilisez un travail parent pour transmettre des arguments et des variables d’environnement au travail enfant. L’API spawn() utilise des travaux batch immédiats, des travaux pré-démarrés ou des travaux batch pré-démarrés.

https://www.ibm.com/docs/en/i/7.4?topic=ssw_ibm_i_74/apis/spawn.htm

https://www.ibm.com/docs/en/i/7.4?topic=programs-example-using-process-related-apis

Ca peut être le cas aussi pour les jobs QCTXDMON (IBM transformer)

plus rigolo

Vous pouvez demander à supprimer ces messages

Pour cela vous devez créer une dtaara QWTFMSG dans QUSRSYS :

CRTDTAARA DTAARA(QUSRSYS/QWTFMSG) TYPE(*CHAR) LEN(14) VALUE(‘CPF1124CPF1164’)

Cette valeur est prise en compte au démarrage de vos sous systémes

elle est globale c’est dommage qu’on ne puisse préciser un sous système

Attention


Beaucoup d’outils d’analyse utilise ces messages pour vérifier le bon traitement d’une tache

Nombre maximum de spools par JOB

Nombre de spools d’un job est fixé globalement par la valeur système QMAXSPLF.
Elle est par défaut à 9999 et le maximum 999999 sont changement ne nécessite pas d’IPL.

Il est possible que pour un job cette valeur soit insuffisante pour un asynchrone par exemple qui est chargé de faire de l’impression.

Vous recevrez le message CPF4167

Vous pouvez augmenter cette limite en utilisant une variable d’environnement QIBM_SP_MAXSPLF

ADDENVVAR ENVVAR(QIBM_SP_MAXSPLF)
VALUE(99999)
LEVEL(*JOB)

Pour voir les variables d’environnement d’un travail WRKENVVAR

OU DSPJOB puis option 22

ou

DSPJOB OPTION(*ENVVAR)

Attention, bien mettre *JOB pour limiter la portée de la modification au travail

Conseil :


Il n’est pas conseillé de changer la valeur système QMAXSPLF qui vous protégé d’un job qui boucle

, Comparer 2 monitors de base de données

Vous avez collecté 2 monitors de base de données, du genre avant après une mise en prod et vous voulez les comparer

La première solution est d’utiliser ACS
SQL Performance Center
Moniteur de performances

Mais vous pouvez faire des opérations assez similaire en utilisant SQL

https://www.ibm.com/docs/en/i/7.4?topic=formats-sql-table

Voici 2 exemples de requêtes

En nombre en ID record

WITH dbmon1 (QQRID, total1) AS (
         SELECT QQRID,
                COUNT(*)
             FROM votrebib.QZGxxxxxx     << monitor 1
             GROUP BY QQRID
     ),
     dbmon2 (QQRID, total2) AS (
         SELECT QQRID,
                COUNT(*)
             FROM votrebib.QZGyyyyyyy     << monitor 2
             GROUP BY QQRID
     )
    SELECT dbmon1.QQRID,
           dbmon1.total1,
           dbmon2.total2
        FROM dbmon1
             JOIN dbmon2
                 ON dbmon1.QQRID = dbmon2.QQRID

En temps d’exécution

WITH dbmon1 (QQRID, total1) AS (
         SELECT QQRID,
                sum(QQETIM - QQsTIM )
             FROM votrebib.QZGxxxxxxx    << monitor 1
             GROUP BY QQRID
     ),
     dbmon2 (QQRID, total2) AS (
         SELECT QQRID,
                 sum(QQETIM - QQsTIM )
             FROM votrebib.QZGyyyyyyyy   << monitor 2 
             GROUP BY QQRID
     )
    SELECT dbmon1.QQRID,
           dbmon1.total1,
           dbmon2.total2
        FROM dbmon1
             JOIN dbmon2
                 ON dbmon1.QQRID = dbmon2.QQRID

Après il vous faudra enquêter sur les différences que vous avez constaté

Exemple :


Avec l’ID , 3002 vous aurez les indexs à créer

, TR2 pour la V7R5

Les annonces de la TR2 pour la V7R5 sont sorties

Voici quelques infos sur les nouveauté de la TR

des nouvelles vues SQL
par exemple pour manipuler les fichiers SAVF
QSYS2.SAVE_FILE_INFO
QSYS2.SAVE_FILE_OBJECTS

sur les audits

Nouvelles fonctions table AUDIT_JOURNAL_XX pour analyser les types suivants
AP, AX, OR, PA, PF, PU, RA, RO, and RZ

ZLIB supporté par SQE

Sur DB2 , nouvelles fonctions SQL pour manipuler les dates et les heures

ADD_DAYS scalar function
ADD_HOURS scalar function
ADD_MINUTES scalar function
ADD_SECONDS scalar function
ADD_YEARS scalar function

Mais la principale nouveauté c’est l’arrivée de

Geospatial Analytics dans DB2 , c’est celle de Watson

https://www.ibm.com/docs/en/i/7.5?topic=analytics-best-practices-considerations

Vous voulez une définition regardez ici

https://fr.wikipedia.org/wiki/Analyse_spatiale

Ca préfigure de grosses nouveautés en matière d’analyse de données

RDV pour les premiers tests

plus d’informations ici

https://www.ibm.com/support/pages/ibm-i-75-tr2-enhancements

, , Database Information Finder

Si vous n’administré pas au quotidien votre base de données, mais que vous devez intervenir ponctuellement,
Vous avez un lien qui référence les principales opérations à faire et qui peut vous aider

https://www.ibm.com/docs/en/i/7.5?topic=database-information-finder

Vous avez 5 manières de chercher

DB2 tasks
SQL quick reference
DB2 and SQL examples
SQL statements
DB2 topics

Sélectionner l’information dans la liste et faite GO

Nous on utilise souvent la première

DB2 tasks

Vous voulez ajouter une zone, Appuyer vers Go, ca vous emmènera vers des liens qui référencera les opérations à effectuées.

Rappel :

Pour les exemples, vous avez aussi ACS qui en propose une liste

dans exécution de scripts SQL

, Comparer 2 fichiers

Vous devez comparer le contenu de 2 fichiers sur votre IBMi

Voici 3 Solutions, il en existe sans doute d’autres …

Première solution

En utilisant SQL et la fonction Table COMPARE_FILE

dans notre on a limité aux données

https://www.ibm.com/docs/en/i/7.4?topic=services-compare-file-table-function

Deuxième solution

En utilisant ACS

Elle se base également sur la fonction table COMPARE_FILE

Sélectionner le premier fichier à comparer

sélectionner le deuxième fichier à comparer

Choisissez l’option uniquement les datas

Vous pouvez exporter votre résultat au format csv par exemple

Troisième solution


Un petit script maison

select ‘a except b’ , a.* from fady/clients a
except
select ‘a except b’ , b.* from fady/clientssv b
union all
select ‘c except d’ , c.* from fady/clientssv c
except
select ‘c except d’ , d.* from fady/clients d

Conclusion :

A vous de choisir la solution qui vous convient

Attention cependant au COMPARE_FILE qui se base sur le RRN et un enregistrement recrée à l’identique avec un rrn différent sera considéré comme nouveau !

Merci a ceux qui m’ont aidé pour cette publication

Il existe un comcept dans SQL sur les tables qui s’appelle les zones cachées.
Je vais essayer de vous expliquer ce que c’est.

Exemple :

CREATE TABLE SALAR (
NUMERO CHAR(6) CCSID 1147 NOT NULL DEFAULT  » ,
NOM CHAR(20) CCSID 1147 NOT NULL DEFAULT  » ,
PRENOM CHAR(30) CCSID 1147 NOT NULL DEFAULT  » ,
SALAIRE DECIMAL(5, 0) NOT NULL DEFAULT 0 IMPLICITLY HIDDEN )

Pour faire simple ces des zones qui n’apparaîtront pas si vous faites un select *


Il y plusieurs buts à cette démarche , caché sommairement des informations ou simplifier des requêtes en cachant des informations utiles et enfin les zones complétables automatiquement les bien connues date, heure et utilisateur de modification.
Maintenant que vous savez ce que c’est je vais vous expliquer l’impact sur vos développements existants.
D’abord bien sûr si vous avez des select * dans vos développements ça produira une erreur si vous respectez les règles de développement vous ne devriez pas en avoir.
Ensuite sur les insert , par défaut il ne connait que les zones non cachées vous devrez indiquer explicitement les zones cachées que vous voulez alimenter.

Conclusion
Ça peut être intéressant dans certains cas pour éviter une vue qui aurait juste pour fonction de limiter les zones.
Attention toutefois, si voulez utiliser cette possibilité toutes les zones sont visibles dans les invites Sql …

Et enfin une zone ajoutée même en hidden change le niveau de format puisqu’il est calculé sur l’ensemble des zones.

, Gestion des clefs SSH

Prérequis

L’utilisateur doit avoir un répertoire initial dans l’IFS. (C’est lui qui sera indiqué par le ~ dans les commandes ci-dessous)
Produits Open Sources :
OpenSSL
SFTP

S’assurer que le service SSH est démarré :

Démarrage du service SSH

S’assurer que le service SSH est démarré :

WRKTCPSTS OPTION(*CNN)

S’il n’est pas démarré, via 5250 :

STRTCPSVR SERVER(*SSHD)

Génération des clefs SSH

En 5250 (QSH ou QP2TERM) :

CALL PGM(QP2TERM)

S’il n’exsite pas, on crée le répertoire .ssh, via la commande mkdir, dans le répertoire par défaut de
l’utilisateur, on lui attribue les droits de lecture, écriture et execution via la commande chmod, puis on execute
la commande ssh-keygen :

mkdir ~/.ssh/
chmod 700 ~/.ssh
ssh-keygen -t rsa -b 2048 -f ~/.ssh/sftp_key -N ''

Voici une idée du résultat obtenu :

Generating public/private rsa key pair.
Your identification has been saved in /home/exploit/.ssh/sftp_key.
Your public key has been saved in /home/exploit/.ssh/sftp_key.pub.
The key fingerprint is:
SHA256:pDxRGtx4YBKbsHTVLpDg8OXyF5VcSBKgfpX4eGXqaGY
The key's randomart image is:
+---[RSA 2048]----+
|. +.**BO++.      |
| = Bo*oBB        |
| * =.*o+         |
| . o =.O.        |
| . + O.S         |
| . = .           |
| E .             |
| +               |
|                 |
+----[SHA256]-----+
Informations supplémentaires :
Options
-t Type de clef créée.
-b Nombres de bits dans la clef créée.
-f Fichier de sortie.
-N Phrase de chiffrement.

Mise en place de la configuration des clefs

Côté client

ATTENTION aux droits des fichiers contenus dans le dossier /.ssh qui ne doit contenir, en principe, que les clefs privées et le fichier config (qui est optionnel).

Côté serveur

S’il n’exsite pas, on crée le répertoire .ssh sur le serveur, via la commande mkdir, dans le répertoire par
défaut de l’utilisateur, on lui attribue les droits de lecture, écriture et execution via la commande chmod :

mkdir ~/.ssh
chmod 700 ~/.ssh

Déposer la clef publique sur le serveur distant puis, ajouter la clef publique au fichier authorized_keys :

cat [sshKey.pub] >> authorized_keys

Puis vérifier le propriétaire et les droits du fichier authorized_keys :

chown [userName] ~/.ssh/authorized_keys
chmod 600 authorized_keys

Supprimer le fichier contenant la clef publique.

ATTENTION aux droits des fichiers contenus dans le dossier /.ssh qui ne doit contenir, en principe, que la clef publique

Tester la liaison SSH

Via QSH ou QP2TERM

ssh -T -i [privateKey] [remoteUserName]@[serverName]

Options :

-T Désactivez l’allocation de pseudo-terminal

-i Fichier privé

Tester la liaison SFTP

Via QSH ou QP2TERM

sftp -i [privateKey] [remoteUserName]@[serverName]

-i Fichier privé

Merci à Julien LAURIER pour sa contribution à l’écriture de cet article.

, , Les tables de conversion

Les tables de conversion sont des objets de type *TBL

Vous en trouvez un grand nombre dans QSYS ou QUSRSYS les 2 plus connues sont

QEBCDIC *TBL QSYS ASCII TO EBCDIC TRANSLATE TO ASCII
QASCII *TBL QSYS EBCDIC TO ASCII TRANSLATE TO EBCDIC

elles servent à convertir une donnée, elle sont utilisées dans certaines commandes FTP ou QUERY Etc …

Vous pouvez également les utiliser vous dans vos développements (bien qu’aujourd’hui SQL semble une meilleur alternative)

Imaginons que vous voulez crypter quelque chose par exemple dans une field proc et que pour vous l’utilisation des API Qc3EncryptData et Qc3DecryptData soit un peu compliqué.

Vous pouvez utiliser cette solution c’est pas le top mais la multiplication des moyens de cryptage ralenti les hackers …

Vous devrez donc créer votre table de conversion
dans un fichier source le plus souvent QTBLSRC

Vous devez alors compiler votre table par la commande CRTTBL …

j’ai choisi pour mon exercice de faire une table alternative, la première fois elle crypte la deuxième elle decrypte

il existe une API système qui s’appelle QCDXLATE qui a un format très simple

https://www.ibm.com/docs/en/i/7.3?topic=ssw_ibm_i_74/apis/QDCXLATE.html

Voici un exemple d’utilisation en RPG et en CLP

les programmes donneront ce résultat

en CLP 

pgm                                                 
dcl &MyValLen *dec (5 0) 30                         
dcl &MyVal *char 30                                 
chgvar &myval 'Bonjour Michel'                      
sndusrmsg ('Avant :' *bcat &myval) msgtype(*info)   
     call QDCXLATE (&MyValLen &MyVal 'CONVERT')     
sndusrmsg ('Premier :' *bcat &myval) msgtype(*info) 
     call QDCXLATE (&MyValLen &MyVal 'CONVERT')     
sndusrmsg ('Second :' *bcat &myval) msgtype(*info)  
endpgm                                              
en RPGLE

**free                                         
 CTL-OPT                                       
   DFTACTGRP(*NO)                              
   DATFMT(*ISO)                                
   OPTION(*SRCSTMT : *NODEBUGIO)  ;            
Dcl-PR Translate  ExtPgm('QDCXLATE');          
 Length         Packed(5:0) const;             
 Data           Char(30) options(*varsize);    
 Table          Char(10)   const;              
End-PR;                                        
dcl-s  Texte  Char(30) ;                       
Texte = 'Bonjour Michel' ;                     
dsply ('Avant : ' + Texte);                    
       Translate(128 : Texte : 'CONVERT');     
dsply ('Premier :' + Texte) ;                  
       Translate(128 : Texte : 'CONVERT');     
dsply ('Second : ' + Texte) ;                
*inlr = *on ;                                  

Conclusion :

Ce n’est pas forcément beaucoup utilisé mais ca peut être utilisé pour des conversions basiques ASCII EBCDIC ANSII etc …

Ne plus utiliser pour mettre en majuscule les fonctions UCASE en RGP ou SQL sont plus performantes et plus simples

un source de table peut être extrait par la commande RTVTBLSRC …