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.