TIPS AS400 IBMi

  • Afficher la version de l’OS400

    DSPDTAARA QUSRSYS/QSS1MRI

  • Recherche de source sur la machine

    Votre source a été supprimé?
    Comment vérifier si il existe une copie de sauvegarde quelque part sur la machine?

    SELECT * FROM syspartitionstat WHERE system_table_member = 'MONSOURCE'

  • Taille d’une bibliothèque

    SELECT SUM(objsize) FROM TABLE(QSYS2.OBJECT_STATISTICS('MABIB', '*ALL'))

    Additionner 2 bibliothèques :
    VALUES (SELECT SUM(objsize) FROM TABLE(QSYS2.OBJECT_STATISTICS('MABIB', '*ALL'))) +
    (SELECT SUM(objsize) FROM TABLE(QSYS2.OBJECT_STATISTICS('MABIB2', '*ALL')))

  • Chercher les programmes en erreur de niveau

    Permet de repérer les programmes RPG qui vont planter en erreur de niveau suite à une évolution de la base de données.

    1) Lister les références des programmes dans un fichier temporaire :
    DSPPGMREF PGM(BIBPGM/*ALL) OUTPUT(OUTFILE) OBJTYPE(*PGM) OUTFILE(QTEMP/LISTEPGM)

    2) Croiser les « format level ID » entre la liste des références des programmes et la liste des fichiers
    SELECT whlib, whpnam, whlnam, whfnam, whrfnm
    FROM qtemp.listepgm
    LEFT JOIN sysfiles ON whfnam=system_table_name AND whrfnm=format_name
    WHERE whrfsn
    <> format_level_id
    AND system_table_schema IN ('BIBFICHIER1' , 'BIBFICHIER2')

    On obtient la liste des programmes de la bibliothèque BIBPGM en erreur de niveau sur les fichiers des bibliothèques BIBFICHIER1 et BIBFICHIER2 :

    Il n’y a plus qu’à recompiler le ou les programmes trouvés (dans l’exemple BIBPGM/ADDCUST). La méthode fonctionne aussi pour les PRTF et les DSPF.

  • Comparer 2 tables en utilisant EXCEPT

    EXCEPT en SQL permet d’extraire les différences entre 2 tables.

    Exemple : 2 tables article avec des contenus différents


    1) Extraire les lignes de ARTICLE qui ne sont pas dans ARTICLE2 :
    SELECT * FROM article
    EXCEPT
    SELECT * FROM article2

    Résultat : Casquette jaune

    2) Extraire les lignes de ARTICLE2 qui ne sont pas dans ARTICLE :
    SELECT * FROM article2
    EXCEPT
    SELECT * FROM article

    Résultat : Beret noir

    3) Il est possible de comparer sur une ou plusieurs colonnes choisies.
    Par exemple, extraire les couleurs de ARTICLE2 qui ne sont pas dans ARTICLE :
    SELECT couleur FROM article2
    EXCEPT
    SELECT couleur FROM article

    Résultat : noir

    A noter, il est possible de comparer 2 fichiers source avec EXCEPT :
    1- OVRDBF FILE(SOURCE1) TOFILE(BIB1/QRPGSRC) MBR(PGM1)
    2- OVRDBF FILE(SOURCE2) TOFILE(BIB2/QRPGSRC) MBR(PGM2)
    3- SELECT * FROM source1 EXCEPT SELECT * FROM source2


  • Lister les bibliothèques, les tables et les colonnes avec SQL

    Lister les bibliothèques :
    SELECT * FROM sysschemas

    Par exemple, les 10 plus grosses bibliothèques :
    SELECT * FROM sysschemas
    ORDER BY schema_size DESC
    LIMIT 10

    Lister les tables :
    SELECT * FROM systables

    Par exemple, lister les tables d’une bibliothèque :
    SELECT * FROM systables
    WHERE table_schema ='maBib'


    Lister les colonnes :
    SELECT * FROM syscolumns

    Lister les colonnes d’une table :
    SELECT * FROM syscolumns
    WHERE table_name='maTable' AND table_schema='maBib'

  • Copier un spoule dans l’IFS
    1. CRTPF FILE(QTEMP/SPOULE) RCDLEN(132)
    2. CPYSPLF FILE(NOM_SPOULE) TOFILE(QTEMP/SPOULE)
    3. CPYTOSTMF FROMMBR('/QSYS.LIB/QTEMP.LIB/SPOULE.FILE/SPOULE.MBR') TOSTMF('/home/mon_user/spoule.txt') STMFCCSID(*PCASCII)
  • Superviser mon AS400 avec Metabase

    Metabase est un outil de visualisation des données sous forme d’un dashboard graphique.
    Exemple d’utilisation :

    Requêtes utilisées pour cette exemple :
    1) % occupation disque
    SELECT SYSTEM_ASP_USED FROM qsys2.system_status_info

    2) Nombre de travaux intéractifs
    SELECT count(*) FROM TABLE(active_job_info()) where job_type=’INT’

    3) Nombre de travaux en message
    SELECT count(*) FROM TABLE(active_job_info()) WHERE job_status='MSGW'

    4) Palmarès du nombre de spoules par utilisateur
    SELECT job_user , count(*) AS nombre FROM TABLE(QSYS2.SPOOLED_FILE_INFO(USER_NAME =>'*'))
    WHERE job_user'QTCP'
    GROUP BY job_user
    ORDER BY nombre DESC
    LIMIT 10

    5) Palmarès des plus gros fichiers
    SELECT objlib concat '/' concat objname , objsize
    FROM TABLE(QSYS2.OBJECT_STATISTICS('*ALLUSR', 'FILE'))
    WHERE objowner NOT LIKE 'Q%' AND objattribute='PF'
    ORDER BY objsize DESC LIMIT 15

  • Boucle de lecture en SQLRPGLE

    Exemple : Lecture de la table utilisateur en filtrant les habitants de PARIS

    **FREE
    // Déclaration des variables
    dcl-s nom char(30);
    dcl-s prenom char(30);
    dcl-s ville char(20) inz('PARIS');
    
    // Définition du curseur C01
    exec sql
      declare C01 cursor for
      select NOM , PRENOM
      from UTILISATEUR
      where VILLE = :ville
      order by NOM , PRENOM;
    
    // Ouverture du curseur 
    exec sql
      open C01;
    
    // Boucle de lecture
    dow sqlcode = 0;
      exec sql
        fetch C01 into :nom , :prenom ;
      if sqlcode = 0;
        // lecture réussie, je fais mon traitement ici
      endif;
    enddo;
    
    // Fermeture du curseur
    exec sql
      close C01;
    
    *inlr = *on;
    return;
  • Importer un SAVF depuis l’IFS

    – Création du savf (par exemple dans qtemp) :
    CRTSAVF FILE(QTEMP/MONSAVF)
    – Importation du savf depuis l’IFS :
    CPYFRMSTMF FROMSTMF('/home/monprofil/monsavf') TOMBR('/qsys.lib/qtemp.lib/monsavf.file') MBROPT(*REPLACE)

  • Remplacer des caractères dans une chaîne de caractères

    Utilisation de %SCANRPL( from : to : source { : start } )

    **FREE
    dcl-s chaine varchar(50);
    chaine = 'AZ500 IBMi AZ500 IBMi AZ500';
    chaine = %SCANRPL('Z5' : 'S4' : chaine); // chaine = 'AS400 IBMi AS400 IBMi AS400'
    chaine = %SCANRPL(' IBMi ' : ' ' : chaine); // chaine = 'AS400 AS400 AS400'chaine = %SCANRPL(' ' : '' : chaine); // chaine = 'AS400AS400AS400'
  • Agrégation de données avec LISTAGG

    SELECT item ,
    LISTAGG(TRIM(couleur), ',') WITHIN GROUP(ORDER BY couleur)
    AS couleurs
    FROM article
    GROUP BY item

    Explications :
    LISTAGG permet de lister dans une colonne les données issues de plusieurs lignes.
    LISTAGG(colonne_à_concaténer , 'séparateur') WITHIN GROUP(ORDER BY colonne_de_tri)

    Dans l’exemple donné, le SQL transforme le fichier article suivant

    en 2 lignes composées de la colonne item et d’une colonne de couleurs séparées par la virgule

  • Agrandir la ligne de commande

    Sur une ligne de commande : CALL QCMD

    On obtient 4 lignes :

    Et pour avoir encore plus grand : F11=Plein écran

  • Faire du ménage dans l’IFS selon la date des fichiers

    Par exemple, supprimer tous les fichiers pdf de plus d’1 an dans un répertoire :
    SELECT
    QCMDEXC('rmvlnk objlnk(''' CONCAT TRIM(CAST(path_name AS VARCHAR(200))) CONCAT ''')') FROM TABLE(qsys2.ifs_object_statistics( '/home/monRepertoire'))
    WHERE path_name LIKE '%.pdf' AND CREATE_TIMESTAMP < CURRENT_TIMESTAMP - 1 YEARS

    Explications :
    ifs_object_statistics permet de lister les fichiers d’un répertoire de l’IFS
    exemple :
    SELECT CAST(path_name AS VARCHAR(100))
    FROM TABLE(qsys2.ifs_object_statistics('/home/monRepertoire'))

    RMVLNK est la commande IBMi qui permet la suppression d’un fichier de l’IFS
    QCMDEXC permet d’exécuter une commande IBMi en SQL

  • Trouver le programme appelant dans un RPG

    Permet dans un RPG d’identifier son programme appelant. Cela peut servir par exemple pour conditionner certaines actions ou laisser une trace dans un fichier log.

    en SQLRPGLE :
    dcl-ds N PSDS;
    nom_du_pgm CHAR(10) POS(1);
    end-ds;
    dcl-s appelant char(10);


    EXEC SQL

    SELECT program_name INTO :appelant
    FROM TABLE(stack_info('*'))
    WHERE program_name not in (' ' , :nom_du_pgm)
    AND ordinal_position <
    ( SELECT ordinal_position FROM TABLE(stack_info('*')) WHERE
    program_name=:nom_du_pgm LIMIT 1)
    LIMIT 1;

    Explications :
    stack_info permet de récupérer la pile de programme en cours. Le SQL proposé identifie dans la pile le programme au dessus du programme en cours.

  • Trouver le FQDN de la machine

    CHGTCPDMN + F4

  • Supprimer les doublons dans un fichier

    DELETE FROM monfichier a
    WHERE RRN(a) NOT IN ( SELECT MAX(RRN(b)) FROM monfichier b
    WHERE (a.cle1, a.cle2) = (b.cle1, b.cle2) )

    Explications :
    La fonction RRN permet de récupérer le numéro d’enregistrement de la ligne.
    Le SQL supprime donc les doublons (clé1+clé2 dans l’exemple) qui ne correspondent pas au dernier numéro d’enregistrement.

    Si on veut conserver le premier doublon et non le dernier doublon, il faut remplacer MAX par MIN :
    DELETE FROM monfichier a
    WHERE RRN(a) NOT IN ( SELECT MIN(RRN(b)) FROM monfichier b
    WHERE (a.cle1, a.cle2) = (b.cle1, b.cle2) )

    Pour simplement chercher les doublons, on peut utiliser :
    SELECT * FROM monfichier a
    WHERE RRN(a) NOT IN ( SELECT RRN(b) FROM monfichier b
    WHERE (a.cle1, a.cle2) = (b.cle1, b.cle2) )

  • Lister les tables d’une bibliothèque avec la dernière date d’utilisation

    SELECT SUBSTR(table_name, 1 , 12) , last_used_timestamp FROM systablestat WHERE table_schema = 'MaBibliotheque'

  • Trouver le numéro du jour de la semaine sans calendrier

    Permet d’affecter à la variable jour le numéro du jour de la semaine du jour comme suit :
    1:Lundi 2:Mardi 3:Mercredi 4:Jeudi 5:Vendredi 6:Samedi 7:Dimanche
    (et sans s’appuyer sur un calendrier!)

    en SQLRPGLE :
    EXEC SQL
    SET :jour= (CASE WHEN DAYOFWEEK(CURRENT_DATE) = 1 THEN 7 ELSE DAYOFWEEK(CURRENT_DATE)-1 END);

    Explications : la fonction SQL DAYOFWEEK permet de récupérer le numéro de jour d’une date dans sa numérotation anglaise (1:Dimanche 2:Lundi 3:Mardi …) d’où le dayofweek()-1

  • Récupérer la date du au format AAAAMMJJ

    Free RPG :
    dcl-s dateDuJour char(8);
    dateDuJour = %char(%date():*ISO0);

  • Obtenir le type, le modèle, le n° de série, le nom de la machine et le n° de partition

    SELECT machine_type, machine_model, serial_number, host_name, partition_id
    FROM qsys2.system_status_info

  • Compter le nombre de spoules par utilisateur

    SELECT count(*) FROM TABLE(qsys2.spooled_file_info(USER_NAME => 'ProfilAS400'))

    Si besoin, la commande qui permet de supprimer tous les spoules d’un d’utilisateur :
    DLTSPLF FILE(*SELECT) SELECT(ProfilAS400)

    Pour avoir le palmarès des utilisateurs avec le plus de spoules :
    SELECT job_user , count(*) AS nombre
    FROM TABLE(QSYS2.SPOOLED_FILE_INFO(USER_NAME =>'*'))
    GROUP BY job_user
    ORDER BY nombre DESC