SQL 400 Valid XHTML 1.1Cette page est conforme à la norme CSS!Mise à jour 03-2013
SOMMAIRE

Présentation
Select & Join , With
Fonctions
Fonctions personnalisées
Mise à jour
Exemples
SQL en RPG
SQL en Cobol
SQL en CL


PRESENTATIONRetour en haut de page

Cette page constitue un mini-cours sql 400 dans lequel on décrit :
  • la syntaxe du SELECT et des jointures de tables JOIN,
  • la syntaxe des mises à jour de données,
  • une liste des principales fonctions pré-définies,
  • quelques fonctions utilisateur personnalisées avec leurs sources,
  • des exemples de requêtes spécifiques.
On y montre aussi l'utilisation de SQL dans des programmes RPG 3, 4, Cobol et CL.

SELECT et JOIN , WITHRetour en haut de page

Syntaxe de l'instruction SELECT

SELECT     (DISTINCT)
           f1.zone1 AS nouveaunom1, f2.zone2, ...
           FROM fichier1 f1, fichier2 f2, ...
		   JOIN fichier3 ...
           WHERE conditions1
           GROUP BY zone3, zone4, ...
           HAVING conditions2
           ORDER BY zone5, zone6, ...
           FETCH FOR x ROWS ONLY
f1 alias du fichier
l'alias est obligatoire dès que deux fichiers ont les mêmes noms de champs
zone1 nom de champ d'une table
constante
fonction ou expression
conditions1 zone1 = 'ABC'
zone1 > 2
zone1 <= zone2
zone1 BETWEEN 3 AND 4
AND, OR, NOT, ( )
IN (sous requete)
LIKE '%val_eur%' (% = joker pour n caractères, _ = joker 1 car.)
Zone IS NULL, zone IS NOT NULL
conditions2 idem conditions1 mais limité aux champs du group by
zone5 nom de champ
n° d'ordre de l'expression sans le select
Fetch ... extrait les x premiers enregistrements sélectionnés



Syntaxe de l'instruction JOIN

JOIN ou INNER JOIN Jointure par égalité entre deux fichiers
SELECT * from fic1 join fic2 on fic1.zone1 = fic2.zone1
équivaut à 
select * from fic1, fic2 where fic1.zone1=fic2.zone1
LEFT OUTER JOIN Jointure avec manquants
Permet la jointure même si les lignes de la seconde table n'existent pas
(au lieu de faire des sélections avec SELECT ... NOT IN (select ...) ... )
select * from fic1 left outer join fic2 on fic1.zone1 = fic2.zone1
On peut tester les champs de fic2 avec :
Select ... where fic2.zone is null (donne les non-correspondances)
Select ... where fic2.zone is not null (identique à JOIN)
EXCEPTION JOIN Combine LEFT OUTER JOIN et test IS NULL
select * from fic1 exception join fic2 on fic1.zone1 = fic2.zone1


Instructions SELECT imbriquées

Certaines requêtes complexes exigent de procéder en plusieurs requêtes successives. On peut éviter ceci en imbriquant les select; il suffit de remplacer un nom de fichier par une instruction select avec la syntaxe suivante :
( select * from ... ) abc 
abc représente l'alias de la sous-requête ainsi constituée.
Cette sous requête peut contenir également des jointures.

Syntaxe de l'instruction WITH

L'instruction WITH permet de définir des requêtes utilisées de façon répétitive au sein d'une requête plus générale.
Cette méthode présente deux avantages :
  • réduit le nombre de lignes de code nécessaires,
  • optimise le temps de traitement en réalisant des sélections communes, donnant ainsi à traiter une table temporaire plus réduite
Au lieu de
SELECT     a.numcli, b1.solde, i1.libelle, b2.solde, i2.libelle
           from client a
           inner join balance b1 on b1.numcli = a.numcli and b1.compte = 'ENCOURS' and b1.date = '2012-09-30'
           inner join intitul i1 on i1.compte = b1.compte
           inner join balance b2 on b2.numcli = a.numcli and b2.compte = 'COURANT' and b2.date = '2012-09-30'
           inner join intitul i2 on i2.compte = b2.compte
on peut écrire
WITH bal as (select b.numcli, b.compte, b.solde, i.libelle
             from       balance b
             inner join intitul i on i.compte=b.compte
             where b.date='2012.09.30' 
            )
SELECT     a.numcli, b1.solde, i1.libelle, b2.solde, i2.libelle
           from       client a
           inner join bal b1 on b1.numcli = a.numcli and b1.compte = 'ENCOURS'
           inner join bal b2 on b2.numcli = a.numcli and b2.compte = 'COURANT'

Fonctions pré-définiesRetour en haut de page

La plupart des fonctions opèrent sur les données de chaque enregistrement.
D'autres, au contraire, produisent des données récapitulatives d'un groupe d'enregistrements.

Fonctions de détail
Calcul
+ - * /
ABS() Valeur absolue
INT() Partie entière

Caractères
CHAR() Transforme une zone numérique en alpha
CONCAT() Concatène des chaines de caractères (parfois noté  !!)
Concat(a, concat(b, c)) équivaut à a  !!  b  !! c
On peut aussi écrire a concat(b), équivalent à a  !! b
Autre possibilité (sauf sql interactif)  : || - 2 barres verticales)
DECIMAL() Transforme une zone alphanumérique en nombre
decimal('1') -> 1
decimal ('1')/100 -> 0,01000000000000
decimal(decimal ('1')/100, 4, 2) -> 0,01
LENGTH() Longueur d'une zone. Combiner avec strip pour obtenir la taille effective, sans les blancs de fin
length(strip(zone))
LEFT() Partie gauche d'une zone (pas de fonction right)
left('abcd', 2) -> ab
La fonction right (n caractères droits) peut être simulée par
substr(texte , length(strip(texte, trailing))+1
-min(length(strip(texte)), n), n)
LOWER() Transforme une chaine de caractères en minuscules. On peut aussi utiliser LCASE
POSSTR() Donne la position de la chaine2 dans la chaine 1
posstr(chaine1, chaine2)
STRIP() Supprime les espaces dans une chaine de caractères
strip (zone, trailing) à droite
strip (zone, leading) à gauche
strip (zone, both) ou strip(zone) à gauche et à droite
SUBSTR() Extraction de sous-chaine
Substr(zone, début, longueur)
Par exemple, pour remplacer dans un n° de fax les points par des espaces
update ir6_0fggg/zztie set nfax =  
left(nfax, posstr(nfax, '.')-1) !!  substr(nfax,posstr(nfax, '.' )+1)   where posstr(nfax, '.') > 0 

Attention la longueur doit être un entier; si elle provient d'un champ de la base, il peut être nécessaire de convertir la valeur (cast x as integer)
UPPER() Transforme une chaine de caractères en majuscules. On peut aussi utiliser UCASE

Comparaison
CASE Calcul d'une valeur selon des conditions
select case when sens ='D' then mon1 else 0-mon1 end as val ...
On peut avoir plusieurs when avant le else
IFNULL() Remplace une valeur nulle par une autre. On peut l'utiliser dans le cas de jointures externes gauches non correspondantes
ifnull(zone, 'ZZZZZ') met 'ZZZZZ' si zone est nulle

Dates
DATE(), DAY(), MONTH(), YEAR() Transforme une chaine en date, extrait jj, mm, aaaa
Ex  : select day(date('17.12.2005')) -> 17
DAY(s), MONTH(s), YEAR(s) Transforme un nombre en durée, que l'on peut utiliser en calcul de dates
Ex  : select date('17.12.2005') - 3 day + 1 months -> 14/01/06
Divers
RRN() Donne le n° d'enregistrement dans le fichier (ou son alias)
select rrn(a) from fichier a



Fonctions de regroupement

AVG() Calcul de la moyenne
COUNT() Comptage du nombre d'enregistrements
select count(*) from ...
select count(distinct zone) from ...    
compte le nombre de valeurs différentes de zone
MIN(), MAX() Calcul de la valeur mini (maxi) d'une zone
SUM() Calcul du total d'un champ numérique

Fonctions utilisateur personnaliséesRetour en haut de page

Il est possible d'ajouter à SQL des fonctions personnalisées, développées à l'aide de divers langages : procédures sql ou langage de haut niveau.
Ci-dessous quelques fonctions d'usage divers et leurs sources.
Elles peuvent être appelées dans des requêtes, soit SQL, soit QM, de la même manière que des fonctions pré-définies.

La création s'effectue par une instruction create function dans une session sql.
En cas de modification d'une fonction ou d'un programme, il est nécessaire de recréer l'ensemble des fonctions. Supprimer celles qui existent par un drop function.


ZZB - Retourne le nombre demandé d'espaces

create function mabib/zzb (plong int)
    returns varchar(100)
    language sql
    begin
        declare bl char(100);
        set bl=' ';
    return(left(bl, plong) ) ;
end
Exemple d'appel : select zzb(10) ... retourne 10 espaces.

ZZDN - Transforme une date en nombre AAAAMMJJ

CREATE FUNCTION mabib/ZZDN  ( DATE8   DATE )

RETURNS DECIMAL(8)
LANGUAGE SQL
SET OPTION DATFMT=*ISO

BEGIN
   DECLARE WDAT    DECIMAL(8);

   SET WDAT    =   YEAR(  DATE8 ) * 10000
                   + MONTH( DATE8 ) * 100
                   + DAY(   DATE8 )
                   ;

   RETURN ( WDAT    );
END
Exemple d'appel : select zzdn(current date) from ... retourne, le 26/02/2010, 20100226.

ZZND - Transforme un nombre AAAAMMJJ en date

CREATE FUNCTION mabib/ZZND  ( DATE8   DECIMAL(8) )

RETURNS DATE
LANGUAGE SQL
SET OPTION DATFMT=*ISO

BEGIN
    DECLARE WDATCAR CHAR(10);
    DECLARE WAA     CHAR(4 );
    DECLARE WMM     CHAR(2 );
    DECLARE WJJ     CHAR(2 );
    DECLARE WDATSOR DATE;

    -- DECOMPOSER LA DATE  AAAA MM JJ
    SET WDATCAR = SUBSTR( CHAR( 100000000 + DATE8 ), 2, 8 );
    SET WAA     = SUBSTR( WDATCAR, 1, 4 );
    SET WMM     = SUBSTR( WDATCAR, 5, 2 );
    SET WJJ     = SUBSTR( WDATCAR, 7, 2 );
  
    -- RECOMPOSER EN JJ.MM.AAAA
    SET WDATCAR = CONCAT( WJJ, '.' );
    SET WDATCAR = CONCAT( TRIM( WDATCAR ), WMM );
    SET WDATCAR = CONCAT( TRIM( WDATCAR ), '.' );
    SET WDATCAR = CONCAT( TRIM( WDATCAR ), WAA );

    SET WDATSOR = DATE( WDATCAR );
    RETURN ( WDATSOR );
END
Exemple d'appel : select zznd(20100226) + 3 days from ... retourne 01/03/10.

ZZP - Complète une chaine par des blancs à droite

    300 CREATE FUNCTION mabib/ZZP (PCHAINE VARCHAR(100),  PLONG INT)
    400 RETURNS VARCHAR(100)
    500 LANGUAGE SQL
    600 BEGIN
    700 RETURN(LEFT(CONCAT(PCHAINE, ZZB(100)), PLONG) ) ;
    800 END;
Exemple d'appel : select zzp(zone, 20) renvoie le champ zone, tronqué ou complété par des blancs, sur une longueur de 20 caractères.

ZZR - Opère des substitutions de sous-chaines de caractères

Cette fonction se décompose en trois parties :
  • le programme en RPGLE qui exécute le traitement proprement dit,
  • la fonction sql ZZRP qui appelle le programme,
  • la fonction sql ZZR qui encapsule le tout.
Programme ZZRG en RPGLE

  SEQNBR*...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8
    100       *************************************************************************
    200       *
    300       *  Programme de la fonction sql ZZRP : remplacement d'une sous-chaine
    400       *  de caractère dans une chaine.
    500       *  Toutes les occurences sont traitées.
    600       *
    700       *************************************************************************
    800       *****   VARIABLES
    900       *
   1000       * position de recherche
   1100      Dpos              s              3  0
   1200       * longueur de la chaine insérée
   1300      Dlon              s              3  0
   1400       * chaine de travail
   1500      Dchn              s            100
   1600       * fin de boucle
   1700      Dfin              s              1
   1800       *
   1900       *****   PARAMETRES  provenant de la fonction sql
   2000       *
   2100      C     *entry        plist
   2200       * parametres d'entree
   2300       *         chaine à remplacer
   2400       *         chaine de remplacement
   2500       *         chaine complète
   2600      C                   parm                    paremp          100
   2700      C                   parm                    prempp          100
   2800      C                   parm                    pchaine         100
   2900       * parametres de sortie
   3000       *         chaine modifiée
   3100      C                   parm                    pretour         100
   3200       * indicateurs sur parametres
   3300       *         1 par parametre
   3400      C                   parm                    ppe1              2
   3500      C                   parm                    ppe2              2
   3600      C                   parm                    ppe3              2
   3700      C                   parm                    pps1              2
   3800       * zones de communication
   3900      C                   parm                    psql              5
   4000      C                   parm                    pz1             139
   4100      C                   parm                    pz2             128
   4200      C                   parm                    pz3              70
   4300       *****   TRAITEMENT
   4400       *
   4500       *  La chaine resultante est composée de 3 parties : avant la chaine
   4600       *  à modifier, la nouvelle chaine puis après la chaine à modifier
   4700       *                 aaaaaaaaaaaaBBcccccccccccc
   4800       *  Le remplacement de la chaine s'effectue en insérant à la place la
   4900       *  nouvelle chaine, qui peut etre de longueur différente, et en bouclant
   5000       *  pour trouver toutes les occurences.
   5100       *
   5200      c                   eval      chn=pchaine
   5300      c                   eval      lon=%len(%trim(prempp))
   5400      c                   eval      fin='0'
   5500      c                   eval      pos=1
   5600      c                   dow       fin = '0'
   5700       *  Si la chaine à modifier est au début, il n'y a pas de partie "avant" à
   5800       *  concaténer
   5900       *
   6000       *  position de la chaine à remplacer, à partir de la dernière recherche
   6100      c                   eval      pos=%scan(%trim(paremp): chn : pos)
   6200       *    non trouvée -> recopier la chaine initiale et terminer
   6300      C                   if        pos < 1
   6400      c                   eval      pretour=chn
   6500      c                   eval      fin='1'
   6600      c                   endif
   6700       *    au début  -> recopier la nouvelle plus la suite
   6800      C                   if        pos =1
   6900      c                   eval      pretour=%trim(prempp) +
   7000      c                             %subst(chn : pos+%len(%trim(paremp)))
   7100      c                   endif
   7200       *    au milieu -> recopier début + nouvelle + fin
   7300      C                   if        pos >1
   7400      c                   eval      pretour=%subst(chn: 1: pos-1) +
   7500      c                             %trim(prempp) +
   7600      c                             %subst(chn: pos+%len(%trim(paremp)))
   7700      c                   endif
   7800       * continuer la recherche pour l'occurence suivante, en sautant la
   7900       * chaine insérée
   8000      c                   eval      pos=pos+lon
   8100      c                   eval      chn=pretour
   8200      c                   enddo
   8300      c                   seton                                        lr
                                  * * * *  F I N  D U  S O U R C E  * * * *

Fonctions ZZR et ZZRP en SQL

    400 -- FONCTION DE TRAITEMENT
    500 CREATE FUNCTION mabib/ZZRP
    600 (P1 CHAR(100), P2 CHAR(100), P3 CHAR(100))
    700 RETURNS CHAR(100)
    800 EXTERNAL NAME IR6_0EXP/ZZRG
    900 RETURNS NULL ON NULL INPUT
   1000 LANGUAGE RPGLE
   1100 NO SQL
   1200 PARAMETER STYLE SQL
   1300 ;
   1400
   1500 -- FONCTION D'APPEL
   1600 CREATE FUNCTION mabib/ZZR
   1700 (P1 VARCHAR(100), P2 VARCHAR(100), P3 VARCHAR(100))
   1800 RETURNS VARCHAR(100)
   1900 LANGUAGE SQL
   2000 BEGIN
   2100 RETURN(ZZRP(CHAR(P1), CHAR(P2), CHAR(P3))) ;
   2200 END
   2300 ;
Exemple d'appel : update fichier set zone=zzr('é', 'E', zone) met à jour le champ zone, dans lequel les 'é' sont remplacés par des 'E'.

Mise à jour de donnéesRetour en haut de page

Syntaxe de l'instruction UPDATE

La forme la plus simple est la suivante :
UPDATE fichier SET zone1=’abcd’ WHERE zone2=5
On peut également mettre à jour une table à partir des données d’une autre table :
UPDATE fica SET zone2 = (SELECT mazone2 FROM ficb WHERE zone1=mazone1)
                         WHERE zone1 IN (SELECT mazone1 FROM ficb)
ATTENTION :
  • le deuxième where est nécessaire au cas où la jointure entre fica et ficb ne se ferait pas ; dans ce cas la valeur retournée est NULL et provoque une erreur,
  • une seule valeur doit être retournée ; ajouter éventuellement une clause distinct dans le premier select.
Ou encore :
UPDATE fica SET (zone2, zone3) = (SELECT mazone2, mazone3
                                  FROM ficb WHERE zone1=mazone1)

Syntaxe de l'instruction INSERT

Les valeurs à insérer sont des constantes ...
INSERT INTO fichier (zone1, zone2, ...) VALUES(‘a’, 5, ...)
... ou proviennent d’un autre fichier
INSERT INTO fichier (zone1, zone2, ...) SELECT ... from fichier2
La spécification des zones destinataires (entre parenthèses) est facultative si l’on insère des données dans tous les champs.

Syntaxe de l'instruction DELETE

DELETE FROM fichier WHERE ...

ExemplesRetour en haut de page

Renumérotation de lignes Suiv.

Le but est de renuméroter une table de 10 en 10.
Pour ceci on suppose que notre table contient un champ NUM et un champ TEXTE.

La stratégie est la suivante :
  • créer une correspondance entre les anciens et les nouveaux numéros de lignes,
  • recopier les données en remplaçant les anciens numéros par les nouveaux.
Création de la correspondance
SELECT Count(tab.texte)*10 AS numnou, Tab.num
FROM Tab, Tab AS Tab2
WHERE Tab.num >=tab2.num
GROUP BY Tab.num
La sortie s'effectue dans une table temporaire.
Recopie des données
SELECT tabtmp.numnou AS num, Tab.texte 
	   FROM tabtmp INNER JOIN tab ON tabtmp.num = Tab.num
Autre solution avec requêtes imbriquées
SELECT tabtmp.numnou AS num, Tab.texte 
	   FROM 
   (
      SELECT Count(tab.texte)*10 AS numnou, Tab.num
      FROM Tab, Tab AS Tab2 
      WHERE Tab.num >=tab2.num
      GROUP BY Tab.num
   ) tabtmp
   INNER JOIN tab ON tabtmp.num = Tab.num

Extraction de spoule Préc.Suiv.

Il s'agit ici de récupérer des données d'un fichier spoule (grand livre), sachant que celui-ci est constitué de lignes d'entetes compte et de lignes de détail d'écritures.
La ligne d'entete se décompose ainsi :
  • Position 10: la mention 'Compte',
  • Position 19: le n° de compte (10 car.),
  • Position 32: l'intitulé du compte (30 car.).
La ligne détail a la structure suivante :
  • Position 07: la date en format jj/mm/aa; le / l'identifiera,
  • Position 23: le n° de pièce (10 car.),
  • Position 95: le montant sous forme xx.xxx.xxx,xx.

Le fichier spoule est préalablement copié (CPYSPLF) dans un fichier ayant 200 caractères de long, nommé SPLF.
Le processus se décompose ensuite en 4 phases :
  • extraire les n° des lignes d'entete,
  • extraire les n° des lignes de détail,
  • rapprocher les n° des lignes d'entete et de détail,
  • rechercher les données à partir des rapprochements entre les entetes et les détails.
Extraction des n° des lignes d'entete, dans un fichier SPLFE

    SELECT RRN(splf) as rang from splf                
    WHERE substr(splf , 10, 6) = 'Compte'           
Extraction des n° des lignes de détail, dans un fichier SPLFD

    SELECT RRN(splf) as rang from splf                
    WHERE substr(splf , 9, 1) = '/'          
Rapprochement des n° de lignes entete et détail, dans un fichier SPLFR

    SELECT max(e.rang) as range, d.rang as rangd      
    FROM splfe e, splfd d
    WHERE e.rang < d.rang
    GROUP BY d.rang
	
Extraction des données, dans un fichier SPLFX

    SELECT substr(a.splf, 19, 10)  as compte,        
           substr(a.splf, 32, 30)  as intitu,
           substr(b.splf, 7, 8)    as datepi,
           substr(b.splf, 23, 10)  as piece,
           case when substr(b.splf, 106, 1)=' ' then 0 else              
                decimal(                                                              
                  substr(b.splf, 95, 2) !!
                  substr(b.splf, 98, 3) !!
                  substr(b.splf, 102, 6)
                  , 12, 2)
           end as montan                                                         
    FROM splfr c, splf a, splf b 
    WHERE rrn(a)=c.range and rrn(b)=c.rangd 

Recherche de maximum dans un groupe Préc.

On est parfois amené à rechercher la valeur associée à une valeur maximum dans un groupe. Par exemple, prendre pour un client la valeur d'une donnée statistique correspondant à la dernière valeur connue à une certaine date d'arrêté.
Exemple :
Date (aaaamm)Montant
2012011000
2012021500
2012031200
2012041400

Par la fonction max, on ne peut obtenir simultanément la date voulue (ex: 201203) et la valeur correspondante (1200). Il faut d'abord trouver 201203 puis, en reprenant cette valeur, une sous-requête extrait la bonne valeur.
La solution est de composer une expression qui combine la période et le montant (dans cet ordre puisque la date est le critère important), et d'en rechercher le maximum.
Pour des valeurs numériques, en estimant le montant maximum possible, on pourrait calculer les expressions :
  • date * 1 000 000 + montant
  • date * 1 000 000
En calculant le max de chacune on obtient 201203001200 et 201203000000. En faisant la différence des 2, on obtient le montant; en divisant la seconde par 1 000 000, on obtient la date.
Avec des zones alphanumériques, on procède par concaténation et extraction de sous-chaînes.

SQL dans les programmes RPGRetour en haut de page

Le langage sql peut être intégré directement dans des programmes RPG, soit pour des requêtes de mise à jour comme celles exposées dans le cours plus haut, soit pour remplacer les classiques ordres de lecture (Chain, Read) par l'intermédiaire d'un curseur.

Un programme simple illustre les principes de base de l'utilisation du sql dans un rpg.
Le même programme est écrit en RPG3 et en RPG4/Free.

Un curseur sélectionne des enregistrements d'un fichier. Cette sélection est lue en ordre inverse (à partir de la fin) et imprimée.
Le fichier, nommé ZSQL, comporte dans l'ordre 10 enregistrements de UN à DIX.


Utilisation de SQL dans un programme RPG 3

Le source est de type SQLRPG.

Voir ci-dessous la liste source et, plus bas, le source généré par les ordres sql.
  SEQNBR*...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0
    100       *****************************************************************
    200       *   TEST DE COMMANDES SQL INTEGREES - RPG 3
    300       *      . LECTURE D'UN FICHIER A PARTIR DE LA FIN
    400       *      . IMPRESSION DES DONNEES LUES
    500       *
    600       *   COMPILER LE PGM AVEC L'OPTION  COMMIT *NONE
    700       *****************************************************************
    800      FQSYSPRT O   F     132            PRINTER
    900       *****************************************************************
   1000       *   TRAITEMENT
   1100       *****************************************************************
   1200       *
   1300      C                     EXSR INIT
   1400       *
   1500       ***   DECLARATION DU CURSEUR
   1600       *
   1700      C/EXEC SQL
   1800      C+ DECLARE CUR SCROLL CURSOR FOR
   1900      C+     SELECT * FROM ZSQL
   2000      C+     WHERE ZSQL > 'R    '
   2100      C/END-EXEC
   2200       *
   2300       ***   OUVERTURE DU CURSEUR
   2400       *
   2500      C/EXEC SQL
   2600      C+ OPEN CUR
   2700      C/END-EXEC
   2800       *
   2900       ***   BOUCLE DE LECTURE
   3000       *
   3100      C                     MOVEL'0'       FIN
   3200       *  -----  POSITION EN FIN DE FICHIER
   3300      C/EXEC SQL
   3400      C+ FETCH LAST FROM CUR INTO :ZZZONE
   3500      C/END-EXEC
   3600      C                     EXSR TSTFIN
   3700      C           FIN       DOWEQ'0'
   3800       *  -----  TRAITER LES DONNEES
   3900      C                     EXCPTLIG
   4000       *  -----  LECTURE SUIVANTE
   4100      C/EXEC SQL
   4200      C+ FETCH PRIOR FROM CUR INTO :ZZZONE
   4300      C/END-EXEC
   4400      C                     EXSR TSTFIN
   4500      C                     ENDDO
   4600       *
   4700      C                     SETON                     LR
   4800       *****************************************************************
   4900       *   ROUTINES
   5000       *****************************************************************
   5100       *
   5200       ***   DETECTION FIN DE FICHIER
   5300       *
   5400      C           TSTFIN    BEGSR
   5500      C           SQLCOD    IFNE 0
   5600      C                     MOVEL'1'       FIN
   5700      C                     ENDIF
   5800      C                     ENDSR
   5900       *
   6000       ***   INIT DU PROGRAMME
   6100       *
   6200      C           INIT      BEGSR
   6300      C                     MOVEL*BLANKS   ZZZONE 30
   6400      C                     MOVEL'0'       FIN     1
   6500      C                     ENDSR
   6600       *****************************************************************
   6700       *   SORTIE IMPRIMANTE
   6800       *****************************************************************
   6900      OQSYSPRT E  1             LIG
   7000      O                         ZZZONE
                                  * * * *  F I N  D U  S O U R C E  * * * *
Dans le code généré, on remarque la DS SQLCA et plusieurs data structures consacrées chacune à un ordre sql (commentaire généré à droite de la ligne).

 SEQUENCE  *...1....+....2....+....3....+....4....+....5....+....6....+....7...*  INDIC  DO    MODIF      LIGNE  PROGRAMME
      100   *****************************************************************                  10/05/10
      200   *   TEST DE COMMANDES SQL INTEGREES - RPG 3                                        11/05/10
      300   *      . LECTURE D'UN FICHIER A PARTIR DE LA FIN                                   10/05/10
      400   *      . IMPRESSION DES DONNEES LUES                                               10/05/10
      500   *                                                                                  10/05/10
      600   *   COMPILER LE PGM AVEC L'OPTION  COMMIT *NONE                                    19/02/04
      700   *****************************************************************                  10/05/10
           H                                                                                              *****
      800  FQSYSPRT O   F     132            PRINTER                                           10/05/10
      900   *****************************************************************                  11/05/10
     1000   *   TRAITEMENT                                                                     11/05/10
     1100   *****************************************************************                  11/05/10
     1200   *                                                                                  11/05/10
     1200  ISQLCA       DS                                                                                        SQL
     1200  I*      SQL communications area                                                                        SQL
     1200  I I            X'0000000000000000'       1   8 SQLAID                                                  SQL
     1200  I                                    B   9  120SQLABC                                                  SQL
     1200  I                                    B  13  160SQLCOD                                                  SQL
     1200  I                                    B  17  180SQLERL                                                  SQL
     1200  I                                       19  88 SQLERM                                                  SQL
     1200  I                                       89  96 SQLERP                                                  SQL
     1200  I                                       97 120 SQLERR                                                  SQL
     1200  I                                    B  97 1000SQLER1                                                  SQL
     1200  I                                    B 101 1040SQLER2                                                  SQL
     1200  I                                    B 105 1080SQLER3                                                  SQL
     1200  I                                    B 109 1120SQLER4                                                  SQL
     1200  I                                    B 113 1160SQLER5                                                  SQL
     1200  I                                    B 117 1200SQLER6                                                  SQL
     1200  I                                      121 131 SQLWRN                                                  SQL
     1200  I                                      121 121 SQLWN0                                                  SQL
     1200  I                                      122 122 SQLWN1                                                  SQL
     1200  I                                      123 123 SQLWN2                                                  SQL
     1200  I                                      124 124 SQLWN3                                                  SQL
     1200  I                                      125 125 SQLWN4                                                  SQL
     1200  I                                      126 126 SQLWN5                                                  SQL
     1200  I                                      127 127 SQLWN6                                                  SQL
     1200  I                                      128 128 SQLWN7                                                  SQL
     1200  I                                      129 129 SQLWN8                                                  SQL
     1200  I                                      130 130 SQLWN9                                                  SQL
     1200  I                                      131 131 SQLWNA                                                  SQL
     1200  I                                      132 136 SQLSTT                                                  SQL
     1200  I*  End of SQLCA                                                                                       SQL
     2500  ISQL000      DS                                                                                        OPEN
     2500  I I            64                    B   1   20SQL001                                                  hd-len
     2500  I I            2                     B   3   40SQL002                                                  stmnt£
     2500  I I            0                     B   5   80SQL003                                                  invmrk
     2500  I I            '0'                       9   9 SQL004                                                  dataok
     2500  I                                       64  64 SQL005
     3300  ISQL006      DS                                                                                        FETCH
     3300  I I            64                    B   1   20SQL007                                                  hd-len
     3300  I I            3                     B   3   40SQL008                                                  stmnt£
     3300  I I            0                     B   5   80SQL009                                                  invmrk
     3300  I I            '0'                       9   9 SQL00A                                                  dataok
     3300  I                                       65  94 SQL00B                                                  ZZZONE
     4100  ISQL00C      DS                                                                                        FETCH
     4100  I I            64                    B   1   20SQL00D                                                  hd-len
     4100  I I            4                     B   3   40SQL00E                                                  stmnt£
     4100  I I            0                     B   5   80SQL00F                                                  invmrk
     4100  I I            '0'                       9   9 SQL00G                                                  dataok
     4100  I                                       65  94 SQL00H                                                  ZZZONE
     1300  C                     EXSR INIT                                                     10/05/10
     1400   *                                                                                  10/05/10
     1500   ***   DECLARATION DU CURSEUR                                                       11/05/10
     1600   *                                                                                  10/05/10
     1700  C*EXEC SQL                                                                          14/01/03
     1800  C* DECLARE CUR SCROLL CURSOR FOR                                                    10/05/10
     1900  C*     SELECT * FROM ZSQL                                                           10/05/10
     2000  C*     WHERE ZSQL > 'R    '                                                         10/05/10
     2100  C*END-EXEC                                                                          14/01/03
     2200   *                                                                                  10/05/10
     2300   ***   OUVERTURE DU CURSEUR                                                         10/05/10
     2400   *                                                                                  10/05/10
     2500  C*EXEC SQL                                                                          10/05/10
     2600  C* OPEN CUR                                                                         10/05/10
     2700  C*END-EXEC                                                                          10/05/10
     2500  C                     Z-ADD-4        SQLER6                                                            SQL
     2500  C           SQL003    IFEQ 0                                                 B001                      SQL
     2500  C           SQL004    ORNE *LOVAL                                             001                      SQL
     2500  C                     CALL 'QSQROUTE'                                         001                      SQL
     2500  C                     PARM           SQLCA                                    001                      SQL
     2500  C                     PARM           SQL000                                   001                      SQL
     2500  C                     ELSE                                                   X001                      SQL
     2500  C                     CALL 'QSQLOPEN'                                         001                      SQL
     2500  C                     PARM           SQLCA                                    001                      SQL
     2500  C                     PARM           SQL000                                   001                      SQL
     2500  C                     END                                                    E001                      SQL
     2800   *                                                                                  10/05/10
     2900   ***   BOUCLE DE LECTURE                                                            10/05/10
     3000   *                                                                                  10/05/10
     3100  C                     MOVEL'0'       FIN                                            10/05/10
     3200   *  -----  POSITION EN FIN DE FICHIER                                               10/05/10
     3300  C*EXEC SQL                                                                          10/05/10
     3400  C* FETCH LAST FROM CUR INTO :ZZZONE                                                 10/05/10
     3500  C*END-EXEC                                                                          10/05/10
     3300  C                     Z-ADD-4        SQLER6            3                                               SQL
     3300  C                     CALL 'QSQROUTE'                                                                  SQL
     3300  C                     PARM           SQLCA                                                             SQL
     3300  C                     PARM           SQL006                                                            SQL
     3300  C           SQL00A    IFEQ '1'                                               B001                      SQL
     3300  C                     MOVELSQL00B    ZZZONE                                   001                      SQL
     3300  C                     END                                                    E001                      SQL
     3600  C                     EXSR TSTFIN                                                   10/05/10
     3700  C           FIN       DOWEQ'0'                                               B001   10/05/10
     3800   *  -----  TRAITER LES DONNEES                                                      10/05/10
     3900  C                     EXCPTLIG                                                001   10/05/10
     4000   *  -----  LECTURE SUIVANTE                                                         10/05/10
     4100  C*EXEC SQL                                                                          10/05/10
     4200  C* FETCH PRIOR FROM CUR INTO :ZZZONE                                                10/05/10
     4300  C*END-EXEC                                                                          10/05/10
     4100  C                     Z-ADD-4        SQLER6            4                      001                      SQL
     4100  C                     CALL 'QSQROUTE'                                         001                      SQL
     4100  C                     PARM           SQLCA                                    001                      SQL
     4100  C                     PARM           SQL00C                                   001                      SQL
     4100  C           SQL00G    IFEQ '1'                                               B002                      SQL
     4100  C                     MOVELSQL00H    ZZZONE                                   002                      SQL
     4100  C                     END                                                    E002                      SQL
     4400  C                     EXSR TSTFIN                                             001   10/05/10
     4500  C                     ENDDO                                                  E001   10/05/10
     4600   *                                                                                  10/05/10
     4700  C                     SETON                     LR                    1             09/01/03
     4800   *****************************************************************                  10/05/10
     4900   *   ROUTINES                                                                       10/05/10
     5000   *****************************************************************                  10/05/10
     5100   *                                                                                  10/05/10
     5200   ***   DETECTION FIN DE FICHIER                                                     10/05/10
     5300   *                                                                                  10/05/10
     5400  C           TSTFIN    BEGSR                                                         10/05/10
     5500  C           SQLCOD    IFNE 0                                                 B001   10/05/10
     5600  C                     MOVEL'1'       FIN                                      001   10/05/10
     5700  C                     ENDIF                                                  E001   10/05/10
     5800  C                     ENDSR                                                         10/05/10
     5900   *                                                                                  10/05/10
     6000   ***   INIT DU PROGRAMME                                                            10/05/10
     6100   *                                                                                  10/05/10
     6200  C           INIT      BEGSR                                                         10/05/10
     6300  C                     MOVEL*BLANKS   ZZZONE 30                                      10/05/10
     6400  C                     MOVEL'0'       FIN     1                                      10/05/10
     6500  C                     ENDSR                                                         10/05/10
     6600   *****************************************************************                  10/05/10
     6700   *   SORTIE IMPRIMANTE                                                              10/05/10
     6800   *****************************************************************                  10/05/10
     6900  OQSYSPRT E  1             LIG                                                       10/05/10
     7000  O                         ZZZONE                                                    10/05/10
           * * * * *   F I N   D U   S O U R C E   * * * * *

Utilisation de SQL dans un programme RPG 4 / FREE

Le source est de type SQLRPGLE.

Il mixe la syntaxe RPG4 standard et free, ainsi qu'un reste de RPG3.
Le programme montre quelques particularités de ces syntaxes.
Noter l'importance de la carte H et le fait que les procédures doivent être écrites après les cartes O.

Voir ci-dessous la liste source.
  SEQNBR*...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0
    100       ****************************************************************                                          15/04/13
    200       *  TEST DE COMMANDES SQL INTEGREES - RPG 4 / FREE                                                         15/04/13
    300       *     . LECTURE D'UN FICHIER A PARTIR DE LA FIN                                                           15/04/13
    400       *     . IMPRESSION DES DONNEES LUES                                                                       15/04/13
    500       *                                                                                                         15/04/13
    600       *  COMPILER LE PGM AVEC L'OPTION  COMMIT *NONE                                                            15/04/13
    700       *****************************************************************                                         15/04/13
    800      h dftactgrp(*no) actgrp('QILE') indent(*none)                                                              15/04/13
    900       *                                                                                                         15/04/13
   1000      FQSYSPRT   o    f  132        printer                                                                      15/04/13
   1100       *                                                                                                         15/04/13
   1200       *****************************************************************                                         15/04/13
   1300       *   DECLARATION DES PROCEDURES ET VARIABLES GENERALES                                                     15/04/13
   1400       *****************************************************************                                         15/04/13
   1500      ddeclare_cursor   pr                                                                                       15/04/13
   1600      dopen_cursor      pr                                                                                       15/04/13
   1700      dfetch_last       pr                                                                                       15/04/13
   1800      dfetch_prior      pr                                                                                       15/04/13
   1900                                                                                                                 15/04/13
   2000      Dfin              S              1                                                                         15/04/13
   2100      Dzzzone           S             30                                                                         15/04/13
   2200                                                                                                                 15/04/13
   2300       *****************************************************************                                         15/04/13
   2400       *   TRAITEMENT AVEC SQL FORMAT RPG3                                                                       15/04/13
   2500       *****************************************************************                                         15/04/13
   2600       /free                                                                                                     15/04/13
   2700           // déclaration et ouverture du curseur                                                                15/04/13
   2800           declare_cursor();                                                                                     15/04/13
   2900           open_cursor();                                                                                        15/04/13
   3000                                                                                                                 15/04/13
   3100           //                                                                                                    15/04/13
   3200           // ***   BOUCLE DE LECTURE                                                                            15/04/13
   3300           //                                                                                                    15/04/13
   3400           eval fin = '0';                                                                                       15/04/13
   3500                                                                                                                 15/04/13
   3600           //  -----  POSITION EN FIN DE FICHIER                                                                 15/04/13
   3700           fetch_last();                                                                                         15/04/13
   3800                                                                                                                 15/04/13
   3900           exsr tstfin;                                                                                          15/04/13
   4000           dow    fin='0';                                                                                       15/04/13
   4100               //  -----  TRAITER LES DONNEES                                                                    15/04/13
   4200               except lig1;                                                                                      15/04/13
   4300               //  -----  LECTURE SUIVANTE                                                                       15/04/13
   4400               fetch_prior();                                                                                    15/04/13
   4500               exsr      TSTFIN;                                                                                 15/04/13
   4600           enddo;                                                                                                15/04/13
   4700                                                                                                                 15/04/13
   4800       /end-free                                                                                                 15/04/13
   4900                                                                                                                 15/04/13
   5000       *****************************************************************                                         15/04/13
   5100       *   TRAITEMENT AVEC SQL FREE                                                                              15/04/13
   5200       *****************************************************************                                         15/04/13
   5300       /free                                                                                                     15/04/13
   5400           // déclaration et ouverture du curseur                                                                15/04/13
   5500           exec sql                                                                                              15/04/13
   5600               DECLARE CUR2 SCROLL CURSOR FOR                                                                    15/04/13
   5700                 SELECT * FROM ZSQL                                                                              15/04/13
   5800                 WHERE ZSQL > 'R    ' ;                                                                          15/04/13
   5900           exec sql                                                                                              15/04/13
   6000               OPEN CUR2;                                                                                        15/04/13
   6100                                                                                                                 15/04/13
   6200           //                                                                                                    15/04/13
   6300           // ***   BOUCLE DE LECTURE                                                                            15/04/13
   6400           //                                                                                                    15/04/13
   6500           eval fin = '0';                                                                                       15/04/13
   6600                                                                                                                 15/04/13
   6700           //  -----  POSITION EN FIN DE FICHIER                                                                 15/04/13
   6800           exec sql                                                                                              15/04/13
   6900               FETCH LAST FROM CUR2 INTO :ZZZONE;                                                                15/04/13
   7000                                                                                                                 15/04/13
   7100           exsr tstfin;                                                                                          15/04/13
   7200           dow    fin='0';                                                                                       15/04/13
   7300               //  -----  TRAITER LES DONNEES                                                                    15/04/13
   7400               except lig2;                                                                                      15/04/13
   7500               //  -----  LECTURE SUIVANTE                                                                       15/04/13
   7600               exec sql                                                                                          15/04/13
   7700                   FETCH PRIOR FROM CUR2 INTO :ZZZONE;                                                           15/04/13
   7800               exsr      TSTFIN;                                                                                 15/04/13
   7900           enddo;                                                                                                15/04/13
   8000           eval   *inlr=*ON;                                                                                     15/04/13
   8100                                                                                                                 15/04/13
   8200       /end-free                                                                                                 15/04/13
   8300       *****************************************************************                                         15/04/13
   8400       *   ROUTINES RPG 3                                                                                        15/04/13
   8500       *****************************************************************                                         15/04/13
   8600       *                                                                                                         15/04/13
   8700       ***   DETECTION FIN DE FICHIER                                                                            15/04/13
   8800       *                                                                                                         15/04/13
   8900      C     TSTFIN        begsr                                                                                  15/04/13
   9000      C     SQLCOD        IFNE      0                                                                            15/04/13
   9100      C                   MOVEL     '1'           fin                                                            15/04/13
   9200      C                   ENDIF                                                                                  15/04/13
   9300      C                   ENDSR                                                                                  15/04/13
   9400       ****************************************************************                                          15/04/13
   9500       *  SORTIE IMPRIMANTE                                                                                      15/04/13
   9600       ****************************************************************                                          15/04/13
   9700      Oqsysprt   e            lig1                                                                               15/04/13
   9800      O                                              'RPG3 '                                                     15/04/13
   9900      O                       zzzone                                                                             15/04/13
  10000      Oqsysprt   e            lig2                                                                               15/04/13
  10100      O                                              'FREE '                                                     15/04/13
  10200      O                       zzzone                                                                             15/04/13
  10300       ****************************************************************                                          15/04/13
  10400       *   PROCEDURES POUR SQL RPG3                                                                              15/04/13
  10500       *****************************************************************                                         15/04/13
  10600       *                                                                                                         15/04/13
  10700       * Déclaration du curseur                                                                                  15/04/13
  10800       *                                                                                                         15/04/13
  10900      Pdeclare_cursor   b                                                                                        15/04/13
  11000      C/EXEC SQL                                                                                                 15/04/13
  11100      C+ DECLARE CUR SCROLL CURSOR FOR                                                                           15/04/13
  11200      C+     SELECT * FROM ZSQL                                                                                  15/04/13
  11300      C+     WHERE ZSQL > 'R    '                                                                                15/04/13
  11400      C/END-EXEC                                                                                                 15/04/13
  11500      P                 e                                                                                        15/04/13
  11600                                                                                                                 15/04/13
  11700       *                                                                                                         15/04/13
  11800       * Ouverture du curseur                                                                                    15/04/13
  11900       *                                                                                                         15/04/13
  12000      Popen_cursor      b                                                                                        15/04/13
  12100      C/EXEC SQL                                                                                                 15/04/13
  12200      C+ OPEN CUR                                                                                                15/04/13
  12300      C/END-EXEC                                                                                                 15/04/13
  12400      P                 e                                                                                        15/04/13
  12500                                                                                                                 15/04/13
  12600       *                                                                                                         15/04/13
  12700       * Positionnement en fin de curseur                                                                        15/04/13
  12800       *                                                                                                         15/04/13
  12900      pfetch_last       b                                                                                        15/04/13
  13000      C/EXEC SQL                                                                                                 15/04/13
  13100      C+ FETCH LAST FROM CUR INTO :ZZZONE                                                                        15/04/13
  13200      C/END-EXEC                                                                                                 15/04/13
  13300      pfetch_last       e                                                                                        15/04/13
  13400                                                                                                                 15/04/13
  13500       *                                                                                                         15/04/13
  13600       * Lecture arrière                                                                                         15/04/13
  13700       *                                                                                                         15/04/13
  13800      pfetch_prior      b                                                                                        15/04/13
  13900      C/EXEC SQL                                                                                                 15/04/13
  14000      C+ FETCH PRIOR FROM CUR INTO :ZZZONE                                                                       15/04/13
  14100      C/END-EXEC                                                                                                 15/04/13
  14200      pfetch_prior      e                                                                                        15/04/13
                                  * * * *  F I N  D U  S O U R C E  * * * *

SQL dans les programmes CobolRetour en haut de page

Le langage sql peut être intégré directement dans des programmes Cobol, comme dans des programmes RPG.
Son usage facilite aussi la lisibilité du programme à cause d'une particularité des fichiers utilisés : créés sous sql, ils comportent des noms de champs comptant jusqu'à 32 caractères. Les noms as400 sur 10 caractères sont de ce fait incompréhensibles (MONCH00001).

Un programme simple montre les particularités du langage, notamment les définitions de champs des tables.

Le source est de type SQLCBLLE.

Voir ci-dessous la liste source, dont certaines lignes ont été ôtées pour un gain de taille, et n'apportant rien de plus à la compréhension du programme.
  SEQNBR*...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 0
    900        IDENTIFICATION DIVISION.
   1000       ***
   1100          PROGRAM-ID. cbl01.
   1200          AUTHOR. DJ.
   1300          DATE-WRITTEN. 11 2011.
   1400
   1900        ENVIRONMENT DIVISION.
   2000       ***
   2100        CONFIGURATION SECTION.
   2200          SOURCE-COMPUTER. IBM-AS400.
   2300          OBJECT-COMPUTER. IBM-AS400.
   2400
   2900        DATA DIVISION.
   3000
   3100       ***
   3200        WORKING-STORAGE SECTION.
   3300
   3400       * DEFINITION DES CHAMPS DES TABLES
   3700
   3800            EXEC SQL BEGIN DECLARE SECTION END-EXEC.
   3900
   4000       * TABLE REP_REPORTACTIONS_AUTO.
   4100
   4200        01  ENR-AUTO.
   4300            05  ra-id                           PIC s9(18).
   4400            05  ra-reportfile                   PIC  x(50).
   4800            05  ra-freqcodeid                   PIC S9(18).
   5300            05  rF-FREQCODE                     PIC  x(3).
   5400            05  rF-FREQCODEDESC                 PIC  x(50).
   5500
   5600       * TABLE FFX00B
   5700
   5800        01  ENR-FFX.
   5900            05  fx-dtpc30.
   6000                10 fx-dtpc30-2          pic xx.
   6100                10 fx-dtpc30-28         pic x(28).
   6110       *     Les champs avec sous-champs doivent être redéfinis pour un fonctionnement correct de sql.
   6200            05  fx-dtpc30x redefines fx-dtpc30 pic x(30).
   6300            05  fx-dtjc10               pic x(10).
   6400            05  fx-dtpc10               pic x(10).
   6700
   6800       * Zones dates
   6900       * Dates début fin en format sql (aaaa-mm-jj)
   7000        01  wd-datedeb.
   7100            05  wd-daa    pic xxxx.
   7200            05  filler    pic x    value "-".
   7300            05  wd-dmm    pic xx.
   7400            05  filler    pic x    value "-".
   7500            05  wd-djj    pic xx.
   7600        01  wd-datedebx redefines wd-datedeb pic x(10).
   7700        01  wd-datefin.
   7800            05  wd-faa    pic xxxx.
   7900            05  filler    pic x    value "-".
   8000            05  wd-fmm    pic xx.
   8100            05  filler    pic x    value "-".
   8200            05  wd-fjj    pic xx.
   8300        01  wd-datefinx redefines wd-datefin pic x(10).
   8400
   8500            EXEC SQL END DECLARE SECTION   END-EXEC.
   8600	
   8610	      * Codes retour SQL 
   8700            EXEC SQL INCLUDE SQLCA         END-EXEC.
   8800
   8900       * ZONES DE TRAVAIL
   9000
   9100        77  finlec     pic x.
   9200        77  selec      pic x.
   9300        01  wfreq.
   9400            05  wfreq1    pic x.
   9500            05  wfreq2    pic xx.
   9600
   9700       * Dates début fin issues de FFX00B (jj/mm/aaaa)
   9800        01  wdatedeb.
   9900            05  wdjj      pic xx.
  10000            05  filler    pic x.
  10100            05  wdmm      pic xx.
  10200            05  filler    pic x.
  10300            05  wdaa      pic xxxx.
  10400        01  wdatefin.
  10500            05  wfjj      pic xx.
  10600            05  filler    pic x.
  10700            05  wfmm      pic xx.
  10800            05  filler    pic x.
  10900            05  wfaa      pic xxxx.
  11000
  11100       * Date pour calcul
  11200        77  wdacalc format date is "%d,%m,@Y".
  11300
  11400       ***
  11500        LINKAGE SECTION.
  11600
  11700       * PARAMETRES RECUS/RETOURNES
  11800        01  pfreqcode.
  11900            05 pfreqcode1      pic x.
  12000            05 filler          pic xx.
  12100        01  pinderr            pic xx.
  12200
  12300       *-------------------------------------------------------------------------
  12400       *  TRAITEMENT
  12500       *-------------------------------------------------------------------------
  12600
  12700        PROCEDURE DIVISION USING pfreqcode pinderr.
  12800
  12900       *** Ouverture fichiers, initialisation de zones
  13000
  13100            Perform init  thru init-fin.
  13200
  13300       *** Boucle de traitement
  13400
  13500        Traitement.
  13600            Perform  Until finlec = "1"
  13700              perform lecligne thru lecligne-fin
  13800              if selec = "1" then
  13900                  perform trtligne thru trtligne-fin
  14000              end-if
  14100            End-perform.
  14200
  14300       *** Fermeture des fichiers et arrêt du programme
  14400            Perform fin   thru fin-fin.
  14500
  14600        Arret.
  14700             Stop Run.
  14800
  14900
  15000       *-------------------------------------------------------------------------
  15100       *  INITIALISATION
  15200       *-------------------------------------------------------------------------
  15300
  15400        init.
  15500
  15600       ***   curseur pour lecture des états à traiter
  15700            exec sql declare c_auto cursor for
  15800              select *
  15900              from         rep_reportactions_auto RA
  16000              inner  join  rep_reportactions_freq RF
  16100                 on  RF.id=RA.freqcodeid
  16200            end-exec.
  16300            exec sql open c_auto end-exec.
  16400            if   sqlcode < 0
  16500                move "11" to pinderr
  16600                move "1"  to finlec
  16700                go to init-fin
  16800            end-if.
  16900
  17000       ***   curseur pour dates
  17100            exec sql declare c_ffx00b cursor for
  17200              select dtjc10,
  17300                     dtpc10,
  17400                     dtpc30
  17700              from         ffx00b
  17800            end-exec.
  17900            exec sql open c_ffx00b end-exec.
  18000            if   sqlcode < 0
  18100                move "12" to pinderr
  18200                move "1"  to finlec
  18300                go to init-fin
  18400            end-if.
  18500
  18600            exec sql fetch c_ffx00b into
  18700              :fx-dtjc10,
  18800              :fx-dtpc10,
  18900              :fx-dtpc30x
  19200            end-exec.
  19300            if   sqlcode not = 0
  19400                move "22" to pinderr
  19500                move "1"  to finlec
  19600                go to init-fin
  19700            end-if.
  19800
  19900            inspect fx-dtpc30 converting 'abcdefghijklmnopqrstuvwxyz'
  20000                                      to 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
  20100            move "H"         to wfreq1
  20200            move fx-dtpc30-2 to wfreq2
  20300
  20400       ***   variables
  20500            move "0"   to finlec.
  20600            move "00"  to pinderr.
  20700        init-fin. exit.
  20800
  20900
  21000
  21100       *-------------------------------------------------------------------------
  21200       *  FIN DU PROGRAMME
  21300       *-------------------------------------------------------------------------
  21400
  21500        fin.
  21600
  21700       ***   fermeture curseurs sql
  21800            exec sql close c_auto end-exec.
  21900            exec sql close c_ffx00b end-exec.
  22000
  22100        fin-fin. exit.
  22200
  22300
  22400
  22500       *-------------------------------------------------------------------------
  22600       *  LECTURE - SELECTION D'UNE LIGNE
  22700       *  LE CURSEUR DOIT ETRE UTILISE APRÈS SA DEFINITION
  22800       *-------------------------------------------------------------------------
  22900
  23000        lecligne.
  23100
  23200            move "0" to selec.
  23300
  23400       ***   Lecture des lignes de paramètres
  23500
  23600            exec sql fetch c_auto into
  23700              :ra-id,
  23800              :ra-reportfile,
  24200              :ra-freqcodeid,
  24700              :rF-FREQCODE,
  24800              :rF-FREQCODEDESC
  24900            end-exec.
  25000
  25100            if sqlcode < 0 or (sqlcode not = 0 and not = 100)
  25200                move "11" to pinderr
  25300                move "1" to finlec
  25400                go to  lecligne-fin
  25500            end-if.
  25600            if sqlcode  = 100
  25700                move "1" to finlec
  25800                go to  lecligne-fin
  25900            end-if.
  26000
  26100       ***   Sélection selon paramètre du programme
  26200            if pfreqcode = "JOU"
  26500                if rf-freqcode = pfreqcode
  26600                    move "1" to selec
  26700                    go to lecligne-fin
  26800                end-if
  26900
  27000            else
  27100
  27200       * cas des Hxx
  27300                if wfreq = pfreqcode and rf-freqcode = pfreqcode
  27400                    move "1" to selec
  27500                    go to lecligne-fin
  27600                end-if
  27700            end-if.
  27800
  27900        lecligne-fin. exit.
  28000
  28100
  28200
  28300       *-------------------------------------------------------------------------
  28400       *  TRAITEMENT D'UNE LIGNE
  28500       *-------------------------------------------------------------------------
  28600
  28700        trtligne.
  28800
  28900       ***   Calculer les dates début et fin de période selon fréquence
  29000
  29100       * prendre les dates dans FFX00B
  29200
  29300            evaluate pfreqcode
  29400
  29500                when "JOU"
  29600                   move fx-dtpc10   to   wdatedeb
  29700                   move fx-dtpc10   to   wdatefin
  29800
  30700                when "H"  thru "H99"
  30800                   move fx-dtjc10   to   wdatedeb
  30900                   move fx-dtpc10   to   wdatefin
  31000       *           date du jour - 7 jours (-9 si vendredi)
  31100                   move function convert-date-time
  31200                       (wdatedeb date "%d/%m/%Y" ) to wdacalc
  31300                   if pfreqcode="HVE"
  31400                       move function subtract-duration
  31500                           (wdacalc days 9) to wdacalc
  31600                   else
  31700                       move function subtract-duration
  31800                           (wdacalc days 7) to wdacalc
  31900                   end-if
  32000                   move wdacalc to wdatedeb
  32100
  32600            end-evaluate.
  32700
  32800       *   et les mettre au format sql (aaaa-mm-jj)
  32900            move   wdjj     to   wd-djj.
  33000            move   wdmm     to   wd-dmm.
  33100            move   wdaa     to   wd-daa.
  33200            move   wfjj     to   wd-fjj.
  33300            move   wfmm     to   wd-fmm.
  33400            move   wfaa     to   wd-faa.
  33500
  33600       ***   Supprimer la ligne existante
  33700
  33800            exec sql
  33900                delete from r_reportactions
  34000                where  id = :ra-id
  34100            end-exec.
  34200            if sqlcode < 0 or (sqlcode not = 0 and not = 100)
  34300                move "13" to pinderr
  34400                move "1" to finlec
  34500                go to  trtligne-fin
  34600            end-if.
  34700
  34800
  34900       ***   Créer la ligne
  35000
  35100            exec sql
  35200                insert into r_reportactions
  35300                ( id,
  35400                  status,
  35500                  reportfile,
  35600                  reportstartdate,
  35700                  reportenddate
  36700                )
  36800                values(
  36900                  :ra-id,
  37000                  0,
  37100                  trim(:ra-reportfile),
  37200                  :wd-datedebx,
  37300                  :wd-datefinx
  38300                )
  38400            end-exec.
  38500            if sqlcode not = 0
  38600                move "14" to pinderr
  38700                move "1" to finlec
  38800                go to  trtligne-fin
  38900            end-if.
  39000
  39100        trtligne-fin. exit.
                                  * * * *  F I N  D U  S O U R C E  * * * *

SQL dans les programmes CLPRetour en haut de page

On utilise QSH pour lancer une requête à partir d'un CL.
Accessoirement, le source montre l'utilisation d'une sous-routine dans un cl.
Voir ci-dessous la liste source.
  5761WDS V6R1M0  080215                  LISTE SOURCE SEU
  FICHIER SOURCE  . . . . .  DJ/QCLSRC
  MEMBRE  . . . . . . . . .  QSHSQL
  SEQNBR*...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 .
    100 /***********************************************************************
    200 /*     UTILISATION DE SQL EN QSH
    300 /*     ROUTINES EN CL
    400 /*
    500 /*     DJ   02.02.2012
    600 /***********************************************************************
    700 PGM
    800
    900 /*   VARIABLES          */
   1000              DCL        VAR(&CMD) TYPE(*CHAR) LEN(200)
   1100              DCL        VAR(&VAL) TYPE(*CHAR) LEN(10)
   1200              DCL        VAR(&Q) TYPE(*CHAR) LEN(1) VALUE('''')
   1300
   1400 /*   CREATION FICHIER TEST   (QTEMP IMPOSSIBLE CAR /= DANS QSH) */
   1500              DLTF       FILE(DJ/QSHSQL)
   1600              MONMSG     MSGID(CPF0000)
   1700              CRTPF      FILE(DJ/QSHSQL) RCDLEN(10)
   1800
   1900 /*   SUPPRIMER LOG DE QSH */
   2000              ADDENVVAR  ENVVAR(QIBM_QSH_CMD_OUTPUT) VALUE(NONE) +
   2100                           REPLACE(*YES)
   2200
   2300 /*   AJOUT D'ENREGS */
   2400              CHGVAR     VAR(&VAL) VALUE('AAAAA')
   2500              CALLSUBR   SUBR(INSSQL)
   2600              CHGVAR     VAR(&VAL) VALUE('BBBBB')
   2700              CALLSUBR   SUBR(INSSQL)
   2800              CHGVAR     VAR(&VAL) VALUE('CCCCC')
   2900              CALLSUBR   SUBR(INSSQL)
   3000
   3100 /*   ROUTINE D'INSERTION SQL    */
   3200              SUBR       SUBR(INSSQL)
   3300
   3400              CHGVAR     VAR(&CMD) VALUE('DB2 "INSERT INTO +
   3500                           DJ.QSHSQL SELECT ' *CAT &Q *CAT &VAL +
   3600                           *CAT &Q *CAT ' FROM SYSIBM.SYSDUMMY1"')
   3700
   3800              QSH        CMD(&CMD)
   3900
   4000              ENDSUBR
   4100
   4200 ENDPGM
                                  * * * *  F I N  D U  S O U R C E  * * * *