, , , , , , , ACS (Access Client Solutions) version 1.1.9.12

20 avril 2026. Cette version apporte desévolutions sur l’éxecution de script SQL !

PTF IBM i

Pour mettre à jour la version disponible sur IBM i :

  • 5770SS1 V7R3M0 SJ09232
  • 5770SS1 V7R4M0 SJ09233
  • 5770SS1 V7R5M0 SJ09234
  • 5770SS1 V7R6M0 SJ09235

Run SQL Script

SELF

Nouvelle option :

Permet le support de l’outil SELF (SQL Error Logging Facility). Cf SQL Error Logging Facility (SELF) – IBM Documentation

Concrètement, cela modifie la liste des erreurs qui sont tracées dans la vue SQL_ERROR_LOG. Cette liste est stockée dans la variable globale SYSIBMADM.SELFCODES, avec quelques valeurs spéciales (*ALL, *ERROR, *WARN, *NONE).

Fichiers physiques source

Amélioration de la fenêtre de dialogue pour la sauvegarde en fichiers sources :

Gestion des fins de ligne

Les caractères LF (x’25’) ne sont plus insérés en fin de ligne dans le cas d’une sauvegarde en fichier source :

Il n’y pas d’impact à l’éxecution (RUNSQLSTM), mais plus de confort !

Gestion de la taille des lignes

Lors de l’enregistrement, au lieu de tronquer les lignes, un message permet d’avertir :

Exemples SQL

13 nouveaux exemples pour les services SQL :

  • SELF – System-wide controls
  • SELF – Job-level controls
  • SELF – Log Queries
  • SELF – Removing historical rows
  • SELF – Initial Stack
  • SELF – Top occurrences
  • SELF – QA use case exampleSecurity – Who is creating objects in the IFS root
  • Security – Who is creating objects in the /QOpenSys subdirectory
  • Security – IFS first-level directories that are open to attack
  • Security – IFS subdirectory object attack vector check
  • Security – IFS home directory ownership
  • Generate spreadsheet and send email example

Références

[IBM i Access – ACS Updates]

, , , Trouver le type d’un fichier

Pour connaitre le type d’un fichier, vous pouvez vous baser sur le type du Fichier .PDF, .JPG, etc …

Ou vous baser sur le nombre magique , ou signature binaire soit les 4 premiers octets en Hexa 

SELECT HEX(SUBSTR(LINE, 14)) AS SIGNATURE
FROM TABLE(QSYS2.IFS_READ_BINARY(‘/home/test.pdf’))
FETCH FIRST 1 ROW ONLY;

Voici un exemple sur 4 fichiers que vous pouvez trouver sur votre partition   

SELECT CASE
         WHEN HEX(SUBSTR(LINE,1,4)) = '25504446'
         THEN 'PDF'
         WHEN HEX(SUBSTR(LINE,1,4)) = '89504E47'
         THEN 'PNG'
         WHEN HEX(SUBSTR(LINE,1,4)) = 'FFD8FFE0'
         THEN 'JPG'
         WHEN HEX(SUBSTR(LINE,1,4)) = '504B0304'
         THEN 'ZIP'
         ELSE 'Autre' // inconnu
       END AS TYPE 
FROM TABLE(QSYS2.IFS_READ_BINARY('/home/vert.jpg'))
FETCH FIRST 1 ROW ONLY;

Résultat :

Conclusion :

C’est simple, et efficace, il y a sans doute d’autres manières de faire

, Les spools fantômes

Vous avez des spools que vous ne voyez pas et vous ne pouvez pas agir dessus

==>WRKOUTQ

en Face de votre Outq vous avez 918 et quand quand vous regarder dans l’outq vous en avez que 37 par exemple

que faire

Vous regardez par SQL, vous les voyez tous

SELECT  
       OUTPUT_QUEUE_NAME, SPOOLED_FILE_NAME, USER_DATA, JOB_NAME, FILE_NUMBER
FROM QSYS2.OUTPUT_QUEUE_ENTRIES 
WHERE  OUTPUT_QUEUE_NAME = ‘votre outq’;

Même par sql vous ne pouvez pas les effacer , c’est un probléme de spool fantômes , souvent le système n’a pas pu les écrire probléme d’espace disque par exemple, que faire ?

==>STRSPLRCL OUTQ(votre bib/votre outq) vous pouvez indiquer *all/*all

vous aurez ce message dans QSYSOPR

Derrière vous pouvez contrôler tout est redevenu normal cohérent entre la vue et le wrkoutq

Pour en savoir plus
https://www.ibm.com/support/pages/node/643567

, Automatiser les datamarts

un petit rappel, il existe depuis quelque temps un mini ETL qui permet de mettre en place un suivi des codes d’audit pour avoir des statistiques et même un visuel dans Navigator for i

Vous voulez créer un datamart sur plusieurs code exemple PW et AF

et avoir un rafraichissement régulier sur la journée

Vous devez créer vos datamarts avant de commencer

En SQL

CALL QSYS2.MANAGE_AUDIT_JOURNAL_DATA_MART(
JOURNAL_ENTRY_TYPE => ‘Votre code’,
DATA_MART_LIBRARY => ‘Votre bib’,
STARTING_TIMESTAMP => CURRENT DATE – 30 DAYS,
ENDING_TIMESTAMP => CURRENT TIMESTAMP,
DATA_MART_ACTION => ‘CREATE’
);

ou dans l’interface Navigator for i
Journal d’audit


Gérer magasin de donnée

Ca va créer des fichiers dans la bibliothèque choisie

AUDIT_JOURNAL_XX nom SQL
AJ_XX en nom systéme

Vous pouvez les interroger par SQL

exemple:

SELECT

    ENTRY_TIMESTAMP,

    USER_PROFILE_NAME,

    OBJECT_NAME

FROM votrebib.AUDIT_JOURNAL_DO

ORDER BY ENTRY_TIMESTAMP DESC;

Nous allons donc créer un fichier de paramétrage qui contiendra les informations de votre datamart code, bibliothèque, type de rafraichissement , et durée de rétention

Création de la table

CREATE TABLE votrebib/PARMART (
CODE_SUIVI CHAR ( 2) NOT NULL WITH DEFAULT,
BIBLIO CHAR ( 10) NOT NULL WITH DEFAULT,
MISEAJOUR CHAR (10) NOT NULL WITH DEFAULT
duree CHAR ( 03) NOT NULL WITH DEFAULT )

Exemple insertion data dans cette table

INSERT INTO GDATA/PARMART VALUES(‘AF’, ‘PLBMART’, ‘*CONTINUE’, ‘030’)

Nous allons créer un programme AUDITREF

             PGM        PARM(&TIMa &timlim)                           
/*--------------------------------------------------------*/          
/* Ce programme sert de robot pour rafraichir un datamart */          
/* exemple toutes les 2 heures, 120 minutes               */          
/*--------------------------------------------------------*/          
dcl &tima  *char 3  /* Fréquence de rafraichissement en minutes */    
dcl &timlim *char 6 /* Heure d'arret du robot                   */    
/* Fichier de paramétrage des datamart à rafraichir */                
             DCLF       FILE(PARMART)                                 
/* Variable préformatée pour service sql            */                
             DCL        VAR(&SQL) TYPE(*CHAR) LEN(512) VALUE('CALL +  
                          QSYS2.MANAGE_AUDIT_JOURNAL_DATA_MART(JOURNA+
                          L_ENTRY_TYPE => ''XX'', +                   
                          DATA_MART_LIBRARY  => ''0123456789'', +     
                          STARTING_TIMESTAMP => ''0123456789'', +     
                          ENDING_TIMESTAMP   => CURRENT TIMESTAMP, +
                          DATA_MART_ACTION   => ''ADD'')')         
dcl &finfichier *lgl                                               
dcl &timsys *char 6 /* Heure système                            */ 
dcl &timn  *dec  3  /* conversion numérique                     */ 
/* Boucle de lecture  */                                           
chgvar &timn &tima                                                 
boucle:                                                            
             DOUNTIL    COND(&FINFICHIER)                          
             rcvf                                                  
             MONMSG     MSGID(CPF0864) EXEC(LEAVE)                 
CHGVAR %sst(&SQL 66   2) VALUE(&code_suivi)                        
CHGVAR %sst(&SQL 94  10) VALUE(&Biblio)                            
CHGVAR %sst(&SQL 130 10) VALUE(&miseajour)                         
   RUNSQL SQL(&SQL) COMMIT(*NONE)                                  
   monmsg sql0000 exec(do)                                         
             SNDUSRMSG  MSG('Raffraichissement impossible pour,' + 
                          *BCAT &CODE_SUIVI *BCAT 'dans le +         
                          datamart' *BCAT &BIBLIO) MSGTYPE(*INFO)    
   enddo                                                             
enddo                                                                
             SNDPGMMSG  MSGID(CPF9898) MSGF(QCPFMSG) +               
                          MSGDTA('Raffraichisement des datamarts +   
                          terminé') MSGTYPE(*COMP)                   
/* on boucle jusqu'a l'heure limite */                               
rtvsysval qtime &timsys                                              
             IF         COND(&TIMLIM > &TIMSYS) THEN(do)             
                  dlyjob &timn                                       
                  GOTO    CMDLBL(BOUCLE)                             
                  enddo                                              
             SNDPGMMSG  MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('Robot + 
                          de Raffraichisement arrêté') MSGTYPE(*COMP)
endpgm

Voici la commande pour démarrer le robot
ici toute les heures jusqu’à 22 h
Vous pouvez le mettre dans un scheduler

SBMJOB CMD(CALL PGM(VOTREBIB/AUDITREF) PARM((‘060’) (‘220000’)))
JOB(AUDITREF)
JOBQ(QSYSNOMAX)

Vous devrez si vous utilisez le mode continue faire le ménage dans le datamart
Exemple
DELETE FROM PLBMART/AJ_AF WHERE ENTRY_TIMESTAMP < current timestamp – 30 days

    voici un programme de ménage qui se basera sur la zone durée du fichier

                 PGM                                                     
    /*--------------------------------------------------------*/         
    /* Ce programme sert à épurer les datamarts               */         
    /* qui travaillent *CONTINUE                              */         
    /*--------------------------------------------------------*/         
    /* Fichier de paramétrage des datamart à rafraichir */               
                 DCLF       FILE(PARMART)                                
    /* Variable préformatée pour service sql            */               
                 DCL        VAR(&SQL) TYPE(*CHAR) LEN(512)               
    dcl &finfichier *lgl                                                 
    /* Boucle de lecture  */                                             
                 DOUNTIL    COND(&FINFICHIER)                            
                 rcvf                                                    
                 MONMSG     MSGID(CPF0864) EXEC(LEAVE)                   
                 CHGVAR     VAR(&SQL) VALUE('DELETE FROM' *BCAT &BIBLIO +
                              *TCAT '/' *TCAT 'AJ_' *TCAT &CODE_SUIVI +  
                                 *BCAT 'WHERE ENTRY_TIMESTAMP < current + 
                              timestamp - ' *BCAT &DUREE *BCAT 'days') 
                 SNDUSRMSG  MSG(&sql ) MSGTYPE(*INFO)                  
       RUNSQL SQL(&SQL) COMMIT(*NONE)                                  
       monmsg sql0000 exec(do)                                         
                 SNDUSRMSG  MSG('épuration impossible pour,' +         
                              *BCAT &CODE_SUIVI *BCAT 'dans le +       
                              datamart' *BCAT &BIBLIO) MSGTYPE(*INFO)  
       enddo                                                           
    enddo                                                              
                 SNDPGMMSG  MSGID(CPF9898) MSGF(QCPFMSG) +             
                              MSGDTA('Epuration des datamarts +        
                              terminé') MSGTYPE(*COMP)                 
    endpgm   

    Pour automatiser, lancer le une fois par semaine par exemple
    vous pouvez le mettre dans un scheduler

    EPUREAUD SBMJOB CMD(CALL PGM(EPUREAUD) )
    JOB(EPUREAUD)
    JOBQ(QSYSNOMAX)

    Remarque :


    Bien sur votre fichier PARMART devra être en ligne pour vos traitements


    Vous pouvez également opter pour des informations consolidées à la journée le type est alors *REFRESH et vous n’avez à gérer le durée de rétention.

    vous avez un fichier de suivi de vos datamarts, QSYS2.AUDIT_JOURNAL_DATA_MART_INFO

    Exemple :

    select
     * from QSYS2.AUDIT_JOURNAL_DATA_MART_INFO ;

    pour suivre votre datamart :

    SELECT DATA_MART_TABLE,
           BUILD_START,
           BUILD_END,
           BUILD_JOB
        FROM QSYS2.AUDIT_JOURNAL_DATA_MART_INFO
        WHERE DATA_MART_LIBRARY = ‘Votre bib’;

    Vous pouvez améliorer cette exemple en ajoutant par exemple la création des datamarts dans les CLLE ou en faisant tout en SQL…

    Pour en savoir plus sur les datamarts

    https://www.ibm.com/docs/en/i/7.4.0?topic=services-manage-audit-journal-data-mart-procedure