Aller au contenu

Service SQL IBM i (AS/400) · Fonction scalaire et Procédure

QSYS2.QCMDEXC

Exécuter une commande CL depuis SQL

Exécute une commande CL depuis SQL, en procédure avec CALL ou en fonction scalaire dans une requête : un lien direct entre SQL et le CL.

À quoi ça sert

Ce service existe sous deux formes. La procédure s'appelle avec CALL QSYS2.QCMDEXC('commande') et exécute la commande CL passée en texte, par exemple dans un bloc SQL comme dans l'exemple d'IBM (DLYJOB). La fonction scalaire renvoie une valeur (1 si la commande a réussi dans l'exemple d'IBM) et peut donc s'employer dans un SELECT.

La fonction scalaire ouvre des possibilités puissantes : dans l'exemple d'IBM, on met en attente (HLDJOB) tous les travaux dont l'instruction SQL tourne depuis plus de deux heures, en une seule requête sur ACTIVE_JOB_INFO. L'exécution se fait avec les droits de l'utilisateur courant.

Résultat réel sur un IBM i 7.5

Ce que nous avons exécuté :

CALL QSYS2.QCMDEXC('CHGDTAARA DTAARA(JOBISQL/DEMO) VALUE(''Modifiée par QCMDEXC'')');
SELECT DATA_AREA_LIBRARY, DATA_AREA_NAME, DATA_AREA_TYPE, LENGTH, DATA_AREA_VALUE FROM QSYS2.DATA_AREA_INFO WHERE DATA_AREA_LIBRARY = 'JOBISQL' AND DATA_AREA_NAME = 'DEMO'

Ce que l'IBM i a renvoyé le 01/10/2026 (1 ligne au plus) :

DATA_AREA_LIBRARY DATA_AREA_NAME DATA_AREA_TYPE LENGTH DATA_AREA_VALUE
JOBISQL DEMO *CHAR 50 Modifiée par QCMDEXC

Données anonymisées : les noms de système, de profils, de bibliothèques, de postes et les adresses IP ont été remplacés. Les objets du schéma JOBISQL sont des objets de démonstration créés pour ce site.

L'exemple d'IBM

Utiliser QCMDEXC pour exécuter une commande CL, et mettre en attente les travaux dont une instruction SQL a démarré il y a plus de 2 heures.

-- Description: Use QCMDEXC to execute CL command 
 BEGIN 
   CALL QSYS2.QCMDEXC('QSYS/DLYJOB DLY(5)'); 
 END;
-- Description: Hold jobs that started running an SQL statement 
     -- more than 2 hours ago. 
 SELECT JOB_NAME,   
       CASE WHEN QSYS2.QCMDEXC('QSYS/HLDJOB ' CONCAT JOB_NAME) = 1 THEN 'Job Held' 
            ELSE 'Job not held' 
         END AS HLDJOB_RESULT 
  FROM TABLE (QSYS2.ACTIVE_JOB_INFO (DETAILED_INFO=> 'ALL'))  
  WHERE SQL_STATEMENT_START_TIMESTAMP < CURRENT TIMESTAMP - 2 HOURS;

Bon à savoir

Une requête qui exécute une commande par ligne agit réellement sur le système : testez d'abord le SELECT sans l'appel à QCMDEXC pour vérifier les lignes ciblées.