Fil d’Ariane du forum – Vous êtes ici :ForumForums techniques: AS/400Requete de comptage a envoyer dan …
Vous devez vous identifier pour créer des messages et des sujets.

Requete de comptage a envoyer dans un CSV

Bonjour,

Je m'arrache les cheveux depuis plusieurs jours pour envoyer le résultat d'un comptage sql dans un fichier CSV via du cobol . Le tout doit tourner exclusivement sous linux .

Je dois sortir un classement par age et quantité de personne :

Colonne 1 > classe d'age
Séparateur > point virgule
Colonne 2 > quantité de personne dans la classe d'age
Extension du fichier > .csv

A noter je ne sais pas comment découper les instructions SQL venant d'oracle . Elles sont longues. Faut il créer des chaines et demander à cobol une compilation de concaténation de chaines ? Faut il adapter le sql à "cobol" au même titre que sql sur MySQL ou PHPMyAdmin voir Oracle ?

Voici ce que j'essaie de faire :

       IDENTIFICATION DIVISION.
       PROGRAM-ID. calcs218.
      *programme de calcul du S2 2018
       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       SPECIAL-NAMES.
           DECIMAL-POINT IS COMMA.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.

      * declaratif du fichier de resultat
          SELECT ficresah18      ASSIGN TO DISK.

       DATA DIVISION.
       FILE SECTION.     
    
       FD  ficresah18            LABEL RECORD STANDARD
           VALUE OF FILE-ID "/dossierdesortie/calcs218.csv".
       01  ENR-ficseq.                            
           02 ficseq-age         PIC 9(4).
           02 sep1               PIC X value ";".        
           02 ficseq-qte         Pic s99999.        

       WORKING-STORAGE SECTION.

      * bibliotheque sql pour cobol
           Exec sql include sqlca end-exec.
      * debut des declaratifs sql 
           Exec sql begin declare section end-exec.
 
      * wdbase pour ouverture bdd et environnement de travail
       01  wdbase          pic x.
      * pour avoir message erreur avec debugage
       01  ws-erreur       pic -(6)9.
       01  where-error       pic x(72).

       01  wscli           pic X(8) value space.
       01  CODE-RET        pic s9(9) comp-5 value 0.
       
      * fin de declaratif sql
           Exec sql end declare section end-exec.
           
      * declaratif des variables autres que sql
             
      * debut du programme
       PROCEDURE DIVISION.             
      * ouverture d'environnement de la bdd
           MOVE "R" TO WDBASE.
           call "opendb" using wdbase.

           OPEN output ficresah18.

       GENERAL.
                  
           exec sql declare CurseurA cursor for           
       
           select
      * calcul de difference de date dans oracle
      * probleme ligne longue comment la faire passer dans cobol limité à 72 caractere ?
           trunc( ((to_date('20181001','YYYYMMDD')-to_date(datenaiss,'YYYYMMDD'))/365.25) , 0 ) into :ficseq-age ,
      * comptage de quantite  
           count ( distinct (pcle)) into :ficseq-qte  
           from fr.client
      * lien entre table client et commande  
           inner join fr.tabcommande on tabcommande.c1clte = client.pcle
      * date correspondant au S2 2018
           where c1datcde between 20180701 and 20181231
      * dans la chaine texte au format AAAAMMJJ MM et JJ 
      * ne doivent pas etre egale a zero
           and substr(datenaiss,7,2) not like '00' 
           and substr(datenaiss,5,2) not like '00'
      * annee differente de 9999 
           and substr(datenaiss,1,4) != 9999
      * annee superieur a 1900
           and substr(datenaiss,1,4) > 1900 
      * la ligne n'est pas un doublon
           and Pnom3 not like '%DBL%'
      * la difference des dates est superieur strictement a 50 ans
      * probleme ligne longue comment la faire passer dans cobol limité à 72 caractere ?
           and trunc( ((to_date('20181001','YYYYMMDD')- to_date(datenaiss,'YYYYMMDD'))/365.25) , 0 ) > 50
      * groupage du comptage par age
      * probleme ligne longue comment la faire passer dans cobol limité à 72 caractere ?
           group by trunc( ((to_date('20181001','YYYYMMDD')-to_date(datenaiss,'YYYYMMDD'))/365.25) , 0 )
      * ordonancement du comptage par age
      * probleme ligne longue comment la faire passer dans cobol limité à 72 caractere ?
           order by trunc( ((to_date('20181001','YYYYMMDD')- to_date(datenaiss,'YYYYMMDD'))/365.25) , 0 )  asc
           
           END-EXEC.
           
           exec sql open CurseurA end-exec.
           
           exec sql fetch CurseurA into :ENR-ficseq end-exec.
                       
      * probleme ligne longue comment la faire passer dans cobol limité à 72 caractere ?
      * comment faire comprendre a cobol , qu'il doit recuperer le resultat de la colonne 1 de la requete sql pour le stocker l'element 1 du descriptif du format de fichier ?
      * move un_truc_sql_???? to le_meme_champ_dans_le_fichier
           move trunc( ((to_date('20181001','YYYYMMDD')- o_date(datenaiss,'YYYYMMDD'))/365.25) , 0 ) to ficseq-age .
      * j'envoi le separateur a lui meme qui est deja declare et dispose deja d'un symbole dans le descriptif du format de fichier
      * si on ne met rien de move a sep1 cela me semble illogique ????? en gros il se recupere lui meme
           move sep1 to sep1.
      * meme chanson comment recupere le comptage sql dedans ?           
           move count ( distinct (pcle)) to ficseq-qte.
      * j'ecris dans le fichier csv de sortie
           write ENR-ficseq before 1.
 
       FIN-GENERAL.
       
       CLOSE ficresah18.
       STOP RUN.

Merci de m'aiguiller

Re ,

J'ai refait d'autres tests en rajoutant des étapes de traitements. Toujours rien , Cobol rechigne à effectuer une malheureuse requête sql ... la requête a été au préalable testé sur ORACLE . Celle ci FONCTIONNE sur ORACLE preuve à l'appuie ... Dois je en déduire que le compilateur a été codé par une vraie bande charlot et de pied nickelé ? A croire que oui !

Test 1

IDENTIFICATION DIVISION.
PROGRAM-ID. calcah18.
*programme de calcul de l'ah18
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SPECIAL-NAMES.
DECIMAL-POINT IS COMMA.
INPUT-OUTPUT SECTION.
FILE-CONTROL.

* declaratif du fichier de resultat
SELECT ficresah18 ASSIGN TO DISK.

SELECT ficstockcli ASSIGN TO DISK
ORGANIZATION INDEXED
ACCESS DYNAMIC
RECORD KEY idcli.

SELECT ficstockcliinsert ASSIGN TO DISK
ORGANIZATION INDEXED
ACCESS DYNAMIC
RECORD KEY idcli.

DATA DIVISION.
FILE SECTION.

FD ficresah18 LABEL RECORD STANDARD
VALUE OF FILE-ID "/wrk/calcah18.csv".
01 ENR-ficseq.
02 ficseq-age PIC 9(4).
02 sep1 PIC X value ";".
02 ficseq-qte Pic 9(6).

FD ficstockcli LABEL RECORD STANDARD
VALUE OF FILE-ID "/wrk/ficstockcli.csv".
01 ENR-ficix.
02 idcli PIC X(10).
02 sep1 PIC X value ";".
02 age Pic 9(4).
02 sep2 PIC X value ";".
02 qte Pic 9(6).

WORKING-STORAGE SECTION.

* bibliotheque sql pour cobol
Exec sql include sqlca end-exec.
exec sql include '/fr/cobol/fichier/client' end-exec.
exec sql include '/fr/cobol/fichier/comande1' end-exec.
* debut des declaratifs sql
Exec sql begin declare section end-exec.

* wdbase pour ouverture bdd et environnement de travail
01 wdbase pic x.
* pour avoir message erreur avec debugage
01 ws-erreur pic -(6)9.
01 where-error pic x(72).

01 wscli pic X(8) value space.
01 CODE-RET pic s9(9) comp-5 value 0.

* fin de declaratif sql
Exec sql end declare section end-exec.

* declaratif des variables autres que sql

* debut du programme
PROCEDURE DIVISION.
GENERAL.
* ouverture d'environnement de la bdd
MOVE "R" TO WDBASE.
call "opendb" using wdbase.

OPEN output ficresah18.
OPEN output ficstockcli.

* selection des clients avec age et quantite a 1 par defaut
exec sql declare CurseurB cursor for

select
distinct pcle into :idcli ,
trunc(
(
(to_date('20181001','YYYYMMDD')-to_date(pdatnais,'YYYYMMDD'))
/365.25)
,0
) into :age ,
1 into :qte
from fr.client
inner join fr.comande1 on comande1.c1clte = client.pcle
where c1datcde between 20180701 and 20181231
and substr(pdatnais,7,2) not like '00'
and substr(pdatnais,5,2) not like '00'
and substr(pdatnais,1,4) != 9999
and substr(pdatnais,1,4) > 1900
and Pnom3 not like '%DBL%'
and trunc(
(
(to_date('20181001','YYYYMMDD')-to_date(pdatnais,'YYYYMMDD'))
/365.25)
,0
) > 80
group by trunc(
(
(to_date('20181001','YYYYMMDD')-to_date(pdatnais,'YYYYMMDD'))
/365.25)
,0
)
order by trunc(
(
(to_date('20181001','YYYYMMDD')-to_date(pdatnais,'YYYYMMDD'))
/365.25)
,0
) asc

END-EXEC.

exec sql open CurseurB end-exec.

exec sql fetch CurseurB into :ENR-ficix end-exec.

move pcle to idcli.

move trunc(
(
(to_date('20181001','YYYYMMDD')-to_date(pdatnais,'YYYYMMDD'))
/365.25)
,0
) to age.

move 1 to qte.

write ENR-ficix before 1.

* fichier de sortie avec le nombre de client par age
exec sql declare CurseurC cursor for

select age , count(qte)
from ficstockcli
group by age
order by age as

END-EXEC.

exec sql open CurseurC end-exec.

exec sql fetch CurseurC into :ENR-ficseq end-exec.

move age to ficseq-age.

move count(qte) to ficseq-qte.

write ENR-ficix before 1.

FIN-GENERAL.

CLOSE ficresah18 ficstockcli.
STOP RUN.

Test 2

IDENTIFICATION DIVISION.
PROGRAM-ID. calcah18.
*programme de calcul de l'ah18
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SPECIAL-NAMES.
DECIMAL-POINT IS COMMA.
INPUT-OUTPUT SECTION.
FILE-CONTROL.

* declaratif du fichier de resultat
SELECT ficresah18 ASSIGN TO DISK.

DATA DIVISION.
FILE SECTION.

FD ficresah18 LABEL RECORD STANDARD
VALUE OF FILE-ID "/wrk/calcah18.csv".
01 ENR-ficseq.
02 ficseq-age PIC 9(4).
02 sep1 PIC X value ";".
02 ficseq-qte Pic s99999.

WORKING-STORAGE SECTION.

* bibliotheque sql pour cobol
Exec sql include sqlca end-exec.
exec sql include '/fr/cobol/fichier/client' end-exec.
exec sql include '/fr/cobol/fichier/comande1' end-exec.
* debut des declaratifs sql
Exec sql begin declare section end-exec.

* wdbase pour ouverture bdd et environnement de travail
01 wdbase pic x.
* pour avoir message erreur avec debugage
01 ws-erreur pic -(6)9.
01 where-error pic x(72).

01 wscli pic X(8) value space.
01 CODE-RET pic s9(9) comp-5 value 0.

* fin de declaratif sql
Exec sql end declare section end-exec.

* declaratif des variables autres que sql

* debut du programme
PROCEDURE DIVISION.
* ouverture d'environnement de la bdd
MOVE "R" TO WDBASE.
call "opendb" using wdbase.

OPEN output ficresah18.

GENERAL.

exec sql declare CurseurA cursor for

select
* calcul de difference de date dans oracle
* probleme ligne longue comment la faire passer dans cobol limité à 72 caractere ?
trunc( ((to_date('20181001','YYYYMMDD')-
to_date(pdatnais,'YYYYMMDD'))
/365.25) , 0 ) into :ficseq-age ,
* comptage de quantite
count ( distinct (pcle)) into :ficseq-qte
from fr.client
* lien entre table client et commande
inner join fr.comande1 on comande1.c1clte = client.pcle
* date correspondant au S2 2018
where c1datcde between 20180701 and 20181231
* dans la chaine texte au format AAAAMMJJ MM et JJ
* ne doivent pas etre egale a zero
and substr(pdatnais,7,2) not like '00'
and substr(pdatnais,5,2) not like '00'
* annee differente de 9999
and substr(pdatnais,1,4) != 9999
* annee superieur a 1900
and substr(pdatnais,1,4) > 1900
* la ligne n'est pas un doublon
and Pnom3 not like '%DBL%'
* la difference des dates est superieur strictement a 50 ans
* probleme ligne longue comment la faire passer dans cobol limité à 72 caractere ?
and trunc( ((to_date('20181001','YYYYMMDD')-
to_date(pdatnais,'YYYYMMDD'))/365.25) , 0 ) > 80
* groupage du comptage par age
* probleme ligne longue comment la faire passer dans cobol limité à 72 caractere ?
group by trunc( ((to_date('20181001','YYYYMMDD')-
to_date(pdatnais,'YYYYMMDD'))/365.25) , 0 )
* ordonancement du comptage par age
* probleme ligne longue comment la faire passer dans cobol limité à 72 caractere ?
order by trunc( ((to_date('20181001','YYYYMMDD')-
to_date(pdatnais,'YYYYMMDD'))/365.25) , 0 ) asc

END-EXEC.

exec sql open CurseurA end-exec.

exec sql fetch CurseurA into :ENR-ficseq end-exec.

* probleme ligne longue comment la faire passer dans cobol limité à 72 caractere ?
* comment faire comprendre a cobol , qu'il doit recuperer le resultat de la colonne 1 de la requete sql pour le stocker l'element 1 du descriptif du format de fichier ?
* move un_truc_sql_???? to le_meme_champ_dans_le_fichier
move trunc( ((to_date('20181001','YYYYMMDD')-
to_date(pdatnais,'YYYYMMDD'))/365.25) , 0 ) to ficseq-age .
* j'envoi le separateur a lui meme qui est deja declare et dispose deja d'un symbole dans le descriptif du format de fichier
* si on ne met rien de move a sep1 cela me semble illogique ????? en gros il se recupere lui meme
move sep1 to sep1.
* meme chanson comment recupere le comptage sql dedans ?
move count ( distinct (pcle)) to ficseq-qte.
* j'ecris dans le fichier csv de sortie
write ENR-ficseq before 1.

FIN-GENERAL.

CLOSE ficresah18.
STOP RUN.

Résultat débugage programme 1 :

Pro*COBOL: Release 12.1.0.2.0 - Production on Mar. Mars 12 16:28:53 2019

Copyright (c) 1982, 2014, Oracle and/or its affiliates. All rights reserved.

Valeurs des options système par défaut extraites de : /app/oracle/client/precomp/admin/pcbcfg.cfg

PCB-S-0004: UNSAFE_NULL=YES doit être utilisé avec DBMS=V7 ou V8 et MODE=ORACLE
Erreur à la ligne 82, colonne 17 dans le fichier 20190312_ah18_cobol.eco
trunc(
................1
PCB-S-00400, Symbole "(" rencontré à la place d'un des symboles suivants :

. , : INDICATOR FROM

Erreur à la ligne 87, colonne 14 dans le fichier 20190312_ah18_cobol.eco
) into :age ,
.............1
PCB-S-00400, Symbole "into" rencontré à la place d'un des symboles suivants :

+ - * / = > < NOTEQ_ <= >= AND OR IN AT NOT BETWEEN DAY IS
LIKE RETURNING YEAR || ^= ANGLE_BRK_

PCB-I-0556: Erreur irrécupérable. Corrigez les erreurs précédentes et recompilez
Erreur à la ligne 141, colonne 25 dans le fichier 20190312_ah18_cobol.eco
order by age as
........................1
PCB-S-00400, Symbole "as" rencontré à la place d'un des symboles suivants :

+ - * / . , ( END-EXEC AT ASC DAY DESC ORDER YEAR FOR || @
Symbole "+" a été substitué à "as" pour continuer.

PCB-I-0556: Erreur irrécupérable. Corrigez les erreurs précédentes et recompilez
Erreur à la ligne 118, colonne 26 dans le fichier 20190312_ah18_cobol.eco
exec sql open CurseurB end-exec.
.........................1
PCB-S-00225, Identificateur SQL "CURSEURB" non déclaré
Erreur à la ligne 120, colonne 27 dans le fichier 20190312_ah18_cobol.eco
exec sql fetch CurseurB into :ENR-ficix end-exec.
..........................1
PCB-S-00225, Identificateur SQL "CURSEURB" non déclaré
Erreur à la ligne 145, colonne 26 dans le fichier 20190312_ah18_cobol.eco
exec sql open CurseurC end-exec.
.........................1
PCB-S-00225, Identificateur SQL "CURSEURC" non déclaré
Erreur à la ligne 147, colonne 27 dans le fichier 20190312_ah18_cobol.eco
exec sql fetch CurseurC into :ENR-ficseq end-exec.
..........................1
PCB-S-00225, Identificateur SQL "CURSEURC" non déclaré
* 244-S***************** **
** FD missing for file FICSTOCKCLIINSERT
399 * selection des clients avec age et quantite a 1 par defaut
* 301-S* **
** Unrecognized verb
400 exec sql declare CurseurB cursor for
* 149-S******** **
** No SQL directives have been set
478 move trunc(
* 12-S************** **
** Operand TRUNC is not declared
481 /365.25)
* 641-S*********** **
** '.' missing following procedure name declaration, or unrecognized verb
487 write ENR-ficix before 1.
* 301-S************************** **
** Unrecognized verb
489 * fichier de sortie avec le nombre de client par age
* 301-S* **
** Unrecognized verb
490 exec sql declare CurseurC cursor for
* 149-S******** **
** No SQL directives have been set
537 move count(qte) to ficseq-qte.
* 14-S************** **
** Invalid operand
539 write ENR-ficix before 1.
* 301-S************************** **
** Unrecognized verb
cob64: error(s) in compilation: 20190312_ah18_cobol.cob

Résultat débugage programme 2 :

Pro*COBOL: Release 12.1.0.2.0 - Production on Mar. Mars 12 16:31:57 2019

Copyright (c) 1982, 2014, Oracle and/or its affiliates. All rights reserved.

Valeurs des options système par défaut extraites de : /app/oracle/client/precomp/admin/pcbcfg.cfg

PCB-S-0004: UNSAFE_NULL=YES doit être utilisé avec DBMS=V7 ou V8 et MODE=ORACLE
Erreur à la ligne 66, colonne 18 dans le fichier 20190312_calcul_ah18.eco
count ( distinct (pcle)) into :ficseq-qte
.................1
PCB-S-00400, Symbole "(" rencontré à la place d'un des symboles suivants :

. , : INDICATOR FROM

Erreur à la ligne 66, colonne 37 dans le fichier 20190312_calcul_ah18.eco
count ( distinct (pcle)) into :ficseq-qte
....................................1
PCB-S-00400, Symbole "into" rencontré à la place d'un des symboles suivants :

+ - * / = > < NOTEQ_ <= >= AND OR IN AT NOT BETWEEN DAY IS
LIKE RETURNING YEAR || ^= ANGLE_BRK_

PCB-I-0556: Erreur irrécupérable. Corrigez les erreurs précédentes et recompilez
Erreur à la ligne 97, colonne 26 dans le fichier 20190312_calcul_ah18.eco
exec sql open CurseurA end-exec.
.........................1
PCB-S-00225, Identificateur SQL "CURSEURA" non déclaré
Erreur à la ligne 99, colonne 27 dans le fichier 20190312_calcul_ah18.eco
exec sql fetch CurseurA into :ENR-ficseq end-exec.
..........................1
PCB-S-00225, Identificateur SQL "CURSEURA" non déclaré
349 exec sql declare CurseurA cursor for
* 149-S******** **
** No SQL directives have been set
428 move trunc( ((to_date('20181001','YYYYMMDD')-
* 12-S************** **
** Operand TRUNC is not declared
429 to_date(pdatnais,'YYYYMMDD'))/365.25) , 0 ) to ficseq-age .
* 641-S**************************************** **
** '.' missing following procedure name declaration, or unrecognized verb
434 move count ( distinct (pcle)) to ficseq-qte.
* 14-S************** **
** Invalid operand
cob64: error(s) in compilation: 20190312_calcul_ah18.cob