Page 1 sur 1

SQL en format libre avec variables

Posté : mer. 17 juin 2009, 08:45:26
par Fabrice_Sof
Bonjour,

Je souhaite dans un programme RPG (format libre) rechercher tous les champs d'une table (variable) afin de concaténer une zone avec tous les champs de la table et la valeur de chaque champ.
ex : &CHAMP1=xx1&CHAMP2=xx2&CHAMP3=xx3 etc ...
Pour trouver tous les champs d'une table, il existe la requête :
SELECT COLUMN_NAME FROM SYSCOLUMNS WHERE TABLE_NAME = 'NOM_TABLE ' AND TABLE_SCHEMA='NOM_BIB'

Par contre comment faire pour mettre sous forme de variable le nom de la table ainsi que le COLUMN_NAME ?
Je souhaiterais une aide sur la syntaxe et l'utilisation du "using"
Merci

(sans texte)

Posté : mer. 17 juin 2009, 08:52:01
par cimmelé
Bonjour,

Le nom de la table et la bibliothèque peuvent être stockés dans des variables du programme RPG et utilisés de la manières suivante :

SELECT COLUMN_NAME FROM SYSCOLUMNS WHERE TABLE_NAME = :NomTable AND TABLE_SCHEMA= :NomBib

Cordialement,

Suite ...

Posté : mer. 17 juin 2009, 08:56:46
par Fabrice_Sof
Merci ;

Mais comment récupérer le nombre d'enregistrements COUNT(*) ainsi que la valeur de COLUMN_NAME dans deux variables ?

Tout ceci dans une syntaxe format libre.

récupérer les valeurs SQL dans des champs

Posté : mer. 17 juin 2009, 09:10:46
par cmasse
Je pense qu'il vous manque l'essentiel : la syntaxe du SQL embarqué !!!

Pour récupérer une valeur unitaire :

Code : Tout sélectionner

SELECT COUNT(*)  INTO :nombre from SYSCOLUMNS where ...
pour récupérer des valeurs multiples

Code : Tout sélectionner

/free
EXEC SQL
 DECLARE result CURSOR FOR SELECT COLUMN_NAME FROM SYSCOLUMNS  where ...  ;

puis
EXEC SQL 
  OPEN result;
..
DOU SQLSTATE <> '00000';
   EXEC SQL
    FETCH result INTO &#58;colonne;
     ... 
ENDDO;

enfin 
EXEC SQL
 CLOSE result ;
bonne continuation.

(sans texte)

Posté : mer. 17 juin 2009, 10:03:46
par Fabrice_Sof
Merci Christian ;

J'ai pour autant une erreur de compilation dans la constitution de la seconde requête SQL.

La première me sert à rechercher toutes les zones d'une table donnée.
Je boucle sur chaque zone pour récupérer la valeur de chaque champ pour une clé (WHERE) donnée.

Code : Tout sélectionner

//=============================================*
//    E01_SQLZ      Recherche des zones du fichier                    
//=============================================*
BEGSR E01_SQLZ;                                                       
                                                                      
  EXEC SQL                                                            
    DECLARE result CURSOR FOR SELECT COLUMN_NAME FROM SYSCOLUMNS      
         WHERE TABLE_NAME = &#58;W_Fichier                                
         AND TABLE_SCHEMA= &#58;W_Bibliotheque ;                          
  EXEC SQL                                                            
    OPEN result;                                                      
  DOU SQLSTATE <> '00000';                                            
    EXEC SQL                                                          
    FETCH result INTO &#58;W_Colonne;                                     
    Exsr E01_SQLV;                                                    
  EndDo;                                                              
ENDSR;             
Seconde requête

Code : Tout sélectionner

                   
 //=============================================*
 //    E01_SQLV      Recherche des valeurs du fichier                  
 //=============================================*
 BEGSR E01_SQLV;                                                       
   EXEC SQL                                                            
     DECLARE result2 CURSOR FOR SELECT &#58;W_Colonne                      
          FROM &#58;W_Fichier                                              
          WHERE &#58;W_Cle;                                                
   EXEC SQL                                                            
     OPEN result2;                                                     
   If SQLSTATE <> '00000';                                             
     EXEC SQL                                                          
     FETCH result2 INTO &#58;W_Valeur;                                     
       W_Url= %trimr&#40;W_Url&#41; + '&'                                      
         + %trimr&#40;W_Colonne&#41; + '='                                     
         + %trimr&#40;W_Valeur&#41;;                                           
   EndIf                                                               
 ENDSR;                                                                                                

(sans texte)

Posté : mer. 17 juin 2009, 10:27:28
par Fabrice_Sof
Avec ce code ça compile :

Première requête

Code : Tout sélectionner

BEGSR E01_SQLZ;                                           
                                                          
  w_requete = 'SELECT COLUMN_NAME FROM SYSCOLUMNS' +      
  ' WHERE TABLE_NAME = ' + W_Fichier +                    
  ' AND TABLE_SCHEMA = ' + W_Bibliotheque;                
  EXEC SQL                                                
    PREPARE P1 FROM &#58; w_Requete;                          
  EXEC SQL                                                
    DECLARE C1 CURSOR FOR P1;                             
  EXEC SQL                                                
    OPEN C1;                                              
  DOU SQLSTATE <> '00000';                                
    EXEC SQL                                              
    FETCH C1 INTO &#58;W_Colonne;                             
    Exsr E01_SQLV;                                        
  EndDo;                                                  
ENDSR;                                                    
Seconde requête

Code : Tout sélectionner

BEGSR E01_SQLV;                                                       
  w_requetebis = 'SELECT ' + W_Colonne + ' FROM ' + W_Fichier         
                 + ' WHERE ' + W_Cle;                                 
  EXEC SQL                                                            
    PREPARE P2 FROM &#58; w_Requetebis;                                   
  EXEC SQL                                                            
    DECLARE C2 CURSOR FOR P2;                                         
  EXEC SQL                                                            
    OPEN C2;                                                          
  If SQLSTATE <> '00000';                                             
    EXEC SQL                                                          
      FETCH C2 INTO &#58;W_Valeur;                                        
    WUrl= %trimr&#40;WUrl&#41; + '&'                                          
        + %trimr&#40;W_Colonne&#41; + '='                                     
        + %trimr&#40;W_Valeur&#41;;                                           
  EndIf;                                                              
ENDSR;                                                                

SQL statique et SQL dynamique

Posté : mer. 17 juin 2009, 11:37:49
par cmasse
Effectivement dans du SQL dit "statique" (le code SQL est en "dur" dans le pgm), seules les valeurs peuvent être des variables, en aucun cas le nom de la colonne ou de la table.

le seul moyen est alors le SQL "dynamique" avec des instructions préparées.



bonne pioche !

(sans texte)

Posté : mer. 17 juin 2009, 12:41:54
par Philippe
Pour info, Fabrice aurait pu utiliser la SQLDA avec DESCRIBE ou PREPARE mais c'est plus compliqué à gérer, donc plus lourd à utiliser que le SQL dynamique.

...suite

Posté : mer. 17 juin 2009, 13:20:21
par Fabrice_Sof
Pour autant, j'ai un soucis avec SQLSTATE qui est commun aux deux requêtes SQL.
Peut on dissocier la variable SQLSTATE par rapport aux deux requêtes imbriquées ?