SQL Dynamique

18-12-2006 à 17:46:46
Bonjour à tous,

Je suis actuellement en train de travailler sur un projet nécessitant l'emplois du SQL/RPG dynamique.

Voici mon problème:

Lorsque j'écris le programme je ne connais rien:
- ni le fichier
- ni la bibliothèque
- ni les données (zones de fichier) à récupérer.

Le but est d'écrire un programme de conversion DB2->XLD (format XML propriétaire MS Excel) en ne passant que le nom d'un fichier et sa bibliothèque. Je sais que cela est possible, mais je ne trouve pas l'information.

Merci de votre aide
  • Liens sponsorisés



18-12-2006 à 14:32:20
18-12-2006 à 17:46:46
Pour la partie SQL, c'est facile à faire avec SQL dynamique. Voir exemple ci-dessous dans lequel on va employer la SQLDA (SQL Descriptor Area).

Procédure

1/ Commit/Rollback anihilés.

2/ Preparation de l'instruction avec une clause PREPARE pour :
- s'assurer qu'il n'y a pas d'erreur(s) dans la requête passée en paramètre
- passer la requête au DESCRIBE qui suit.

3/ DESCRIBE pour que SQL :
- indique le nombre de zones de la requête (1er decribe)
- décrive les zones qui constituent la requête et dépose le résultat dans la DS SQLDA (2ième describe).

4/ Itération "nbre de zones" fois :
- Récupération du nom de la zone
- Récupération du type de la zone (packé, étendu, alphanum, date, etc.)
- Récupération longueur de la zone et, le cas échéant, du nbre de décimales

Il te faudra à ce niveau convertir chaque zone en format XML

Pour connaître les autres valeurs du SQLTYPE, voir la doc SQL DB2 UDB pp. 854 et s. à l'adresse suivante:
http://publib.boulder.ibm.com/iseries/v5r2/ic2924/index.htm?info/rzahf/rzahfli0.htm

Exemple (un peu trop long à mon gré pour figurer dans un post):

h DftActGrp( *No )
H Option( *SrcStmt: *NoDebugIO )

* -------------------------------------------------------------------------------------
* Lecture SQLDA pour recuperer les nom de zones
* et leurs definition a partir d'une requete sql
* sous forme indiquee dans le parametre en entree.
* Parametre en entre => Requete sql 'ex: SELECT * FROM FICHIER'
* Nb maximum de zones=> 999
* -------------------------------------------------------------------------------------

* -------------------------------------------------------------------------------------
* sql Descriptor Area
* -------------------------------------------------------------------------------------
d sqlDA DS based(psqlDA)
d sqlDAId 8a
d sqlDABc 10i 0
d sqlN 5i 0
d sqld 5i 0
d sql_VAR 80a dim(1)

d sqlVAR DS based(psqlVAR)
d sqlType 5i 0
d sqllendec 5i 0
d wlong 1a overlay(sqllendec:1)
d wdec 1a overlay(sqllendec:*next)
d sqlRes 12a
d sqlData 17 32*
d sqlInd 33 48*
d sqlNameLen 5i 0
d sqlName 30a

* sqlDA pointers
d psqlDA s *
d psqlVAR s *

* sqlDA sizes
DnsqlDA s 5i 0
DszsqlDA s 10i 0

* Colone descrp.
d dsColonne ds inz
d pLong 10i 0
d aLong 1a
d pdec 10i 0
d adec 1a

* Variables de travail

D i s 5i 0
D pa_Requete s 9999
D w_pa_Requete s like(pa_Requete)

D w_ds_zon ds 89 inz
d w_typ 1a
d w_lng 5i 0
d 1a overlay(w_lng : 1)
d w_lng_a 1a overlay(w_lng : *next)
d w_dec 5i 0
d 1a overlay(w_dec : 1)
d w_dec_a 1a overlay(w_dec : *next)
d w_Nom 84a

d w_tb_Zon ds dim(999) qualified inz
d w_typ 1a
d w_lng 5i 0
d w_dec 5i 0
d w_Nom 84a

d dsp s 52a

c *entry plist
c parm pa_Requete

c/exec sql set option commit = *none
c/end-exec

c eval *inlr = *ON
c eval w_pa_Requete = %trim(pa_Requete)

* Preparation instruction
C/exec sql PREPARE Sqlstm FROM :w_pa_Requete
C/end-exec

* Erreur sql
c if sqlcod not = 0
c return
c endif

c eval szsqlDA = 16
c eval psqlDA = %alloc(szsqlDA)
c eval sqlDA = *LOVAL
c eval sqlN = 0

*ÀLecture initiale sqlDA pour determiner le nb de zones a extraire
*ÀRemarque : mettre en premier lieu sqlN a 0
C/exec sql DESCRIBE Sqlstm INTO :sqlDA
C/end-exec

c if sqld > 999
c return
c endif

*ÀPosition sur 1ere occurence zone de la requete sql dans sqlDA
c eval psqlVAR = %addr(sql_VAR)

* Itere nbre de zones fois
c for i = 1 to sqld
c eval w_ds_zon = *loval
c eval w_dec = 0

* Determine leÀtypeÄde la zone en cours

c select

*À-- Packed ou zoned decimal
c when sqlType = 484 or sqlType = 485 or
c sqlType = 488 or sqlType = 489
c eval w_typ = 'N'
*À -- Longueur
c eval w_lng_a = wlong
* À -- Decimales
c eval w_dec_a = wdec

*À-- Date
c when sqlType = 384 or sqlType = 385
c eval w_typ = 'D'
*À -- Longueur
c eval w_lng = sqllendec

*À-- Time
c when sqlType = 388 or sqlType = 389
c eval w_typ = 'T'
*À -- Longueur
c eval w_lng = sqllendec

*À-- Timestamp
c when sqlType = 392 or sqlType = 393
c eval w_typ = 'S'
*À -- Longueur
c eval w_lng = sqllendec

*À-- Chaine de caracteres de longueur fixe
c when sqlType = 452 or sqlType = 453
c eval w_typ = 'A'
*À -- Longueur
c eval w_lng = sqllendec

c endsl

* Stockage dans tableau
c eval w_Nom = sqlName
c eval w_tb_Zon(i) = w_ds_zon

* Convertir ici en XML à la place du DSPLY
* En fuschia, lignes à retirer
c eval dsp = w_typ + '/' +
c %char(w_lng) + '/' +
c %char(w_dec) + '/' +
c w_Nom

c dsply dsp


* Lecture occurence suivante de sqlDA
c eval psqlVAR = psqlVAR + 80
c endfor

c return






--Message édité par philippe le 18-12-06 à 17:48:03--

--Message édité par philippe le 18-12-06 à 17:49:46--

--Message édité par philippe le 18-12-06 à 18:25:19--

--Message édité par philippe le 18-12-06 à 18:33:08--
  • Liens sponsorisés