Projet JDBCR4

BoTTom |    Changer de couleur
Le projet JDBCR4 de Scott Klement propose une utilisation de JDBC en RPG
 basée sur un programme de service à compiler et téléchargable à l'adresse:
 
 http://systeminetwork.com/files/RpgAndJdbc.zip
 
la documentation est disponible à:
 
 http://www.scottklement.com/presentations/External%20Databases%20from%20RPG.pdf
 
Pour utiliser un Driver JDBC celui-ci doit être de type 4 (écrit en Java)
 il est en général livré sous forme de fichier .jar
 
 MySQL:              mysql-connector-java-3.1.12-bin.jar
 Oracle (thin):      ojdbc14.jar
 SQL Server:         sqljdbc.jar
 (version open source) : jtds-1.2.5.jar  (les n° de version peuvent changer)
 DB2 for i:          jt400.jar
 IBM DB2 (autre OS): db2jcc.jar
 
Placez ce fichier dans un répertoire de l'IFS et modifiez votre CLASSPATH
  par ADDENVVAR ENVVAR(CLASSPATH)
                VALUE('.:/java:/java/mysql-connector.jar') , par exemple.


|    Changer de couleur
 
Ecrivez ensuite un pgm java de test pour vérifier la validité du driver
 
 il vous faut connaitre la classe du driver
 
  SQL Server: com.microsoft.sqlserver.jdbc.SQLServerDriver
       jTDS : net.sourceforge.jtds.jdbc.Driver
  Oracle:     oracle.jdbc.OracleDriver
  MySQL:      com.mysql.jdbc.Driver
  DB2 for i:  com.ibm.as400.access.AS400JDBCDriver
  DB2 Autre:  com.ibm.db2.jcc.DB2Driver
 
 
et l'URL de connexion
 
  SQL Server: jdbc:sqlserver://myserver.example.com:1433
       jTDS : jdbc:jtds:sqlserver://myserver.example.com:1433
  Oracle:     jdbc:oracle:thin:@myserver.example.com:1521:myDataBase
  MySQL:      jdbc:mysql://myserver.example.com/myDataBase
  DB2 for i:  jdbc:as400://myserver.example.com
  DB2 Autre:  jdbc:db2://myserver.example.com:50000/myDataBase
 


|    Changer de couleur
import java.sql.*;
 
public class testMySql
{
    public static void main (String[] parameters)
    {
 
        String mysqlurl = "jdbc:mysql://localhost/mysql";
        String userid    = "root";
        String password  = "xxxxx";
        Connection connection   = null;
 
        try {
            DriverManager.registerDriver(new com.mysql.jdbc.Driver());
 
            connection = DriverManager.getConnection ( mysqlurl,
                                                       userid,
                                                       password );
 
          Statement select = connection.createStatement ();
          ResultSet rs = select.executeQuery("SELECT Host,User FROM user");
 


|    Changer de couleur
 
          while (rs.next ()) {
              System.out.println (rs.getString(1) + "," + rs.getString(2));
          }
 
    }
 
    catch (Exception e) {
          System.out.println ();
          System.out.println ("ERROR: " + e.getMessage());
      }
      try {
          if (connection != null)
              connection.close ();
        }
        catch (SQLException e) {
           // Ignore.
          }
    }
}
 
 


|    Changer de couleur
 
Saisissez,par exemple avec EDTF (pensez bien au CCSID ASCII : 819 ou 1252)
 
 
puis sous QSH, tapez :
 
 ==> javac testMySql.java
 
vérifiez que vous avez obtenu un fichier testMySql.class
 
lancez par
 
 ==> java testMySql
 
vous devez obtenir un résultat sur l'écran de QSH
 
 
Ces tests étant réalisés passont à l'écriture RPG
--------------------------------------------------
 
La première fonction à utiliser est JDBC_Connect
 


|    Changer de couleur
 
 /copy JDBC_H
 
D userid          s             50a
D passwrd         s             50a
D conn            s                   like(Connection)
 
 /free
 
   userid = 'root';
   passwrd = 'xxxxx';
   conn = JDBC_Connect('com.mysql.jdbc.Driver'
                       :'jdbc:mysql://myserver.example.com/myDataBase'
                       :%trim(userid)
                       :%trim(passwrd) );
    if (conn = *NULL);
         errorMsg = 'Unable to connect to MYSQL database!';
         // Afficher le message.
    endif;
 
 /end-free
 


|    Changer de couleur
Si vous avez besoin de propriétés particulières à l'utilisation du driver
  écrivez plutôt :
 
D userid          s             50a
D passwrd         s             50a
D conn            s                   like(Connection)
D prop            s                   like(Properties)
 /free
 
   userid = 'root';
   passwrd = 'xxxxx';
   prop = JDBC_Properties();
 
   JDBC_setProp(prop: 'user' : %trim(userid) );
   JDBC_setProp(prop: 'password' : %trim(passwrd));
   JDBC_setProp(prop: 'connectTimeout': '60' );
 
   conn = JDBC_ConnProp('com.mysql.jdbc.Driver'
                        :'jdbc:mysql://myserver.example.com/myDataBase'
                        :prop) );
 
   JDBC_freeProp(prop);


|    Changer de couleur
 
par exemple la propriété databaseName pour SQL server ou naming pour jt400
 
 (voir la liste des propriétés pour chaque driver)
 
 Bien sur vous pouvez (en allant à la "pêche" aux informations) utiliser des
   drivers non cités ici, comme celui pour PostGreSql(org.postgresql.Driver)
 
une fois connecté, vous devez distinguer deux types d'ordres
 
 Les ordres immédiats
 
     sont interprétés et exécutés dans la foulée
 
 
 Les ordres préparés
 
    sont interprétés une fois et exécutés, éventuellement, plusieurs fois.
 
    lors de la préparation, ils peuvent contenir des marqueurs (?), qui
     seront remplacés par des valeurs à l'exécution.
 


|    Changer de couleur
 
 JDBC_ExecUpd( connexion : 'ordre SQL ne retournant rien')
 
   Exécute un ordre SQL comme CREATE..., UPDATE, DELETE, etc (pas de SELECT)
 
   retourne :
 
              0 pour un ordre n'affectant aucune ligne
              n le nombre de lignes affectées
             -1 pour un ordre SQL en erreur
 
 exemple :
 
 /free
 
   rc = JDBC_ExecUpd( conn : 'delete from clients'
                                  + ' where nocli = 999 ');
           if (rc < 0);
            // signaler une erreur
           endif;
 
 


|    Changer de couleur
 
 JDBC_ExecQRry(connexion : 'ordre SQL de type SELECT')
 
   Exécute un ordre SQL retournant un jeu de résultats
 
   retourne :
 
              un objet ResultSet
              *NULL pour un ordre SQL en erreur
 
 exemple :
D Resset          s                   like(ResultSet)
 
 /free
 
   resset= JDBC_ExecQry( conn : 'select nocli, raisoc, ville, tel'
                                  + ' from clients where dep = 44');
           if (resset = *null);
            // signaler une erreur
           endif;
 
 


|    Changer de couleur
 Pour lire un ResultSet utilisez les fonctions suivantes :
 
  JDBC_nextRow( ResultSet )
 
    se positionne sur la ligne suivante.
    Retourne *OFF en cas de "fin de fichier", *ON dans le cas contraire
 
  JDBC_getCol(ResultSet : NumCol )
 
    Retourne la valeur d'une colonne dont on fournit le n° dans le SELECT
     (la première colonne porte le n° 1)
 
 
  JDBC_getColByName( ResultSet : NomColonne )
 
    Retourne la valeur d'une colonne dont on fournit le nom
 
  JDBC_freeResult( ResultSet )
 
    Ferme le ResultSet et libère la mémoire
     (comme un CLOSE de curseur en SQLRPGLE)
 


|    Changer de couleur
Exemple :
 
 /free
 
    dow JDBC_nextRow(Resset);
         Dept = JDBC_getCol(Resset: 1);
         EmpNo = %int(JDBC_getCol(Resset: 2));
         Name = JDBC_getCol(Resset: 3);
 
     // traitement des données lues.
 
    enddo;
 
    JDBC_freeResult(Resset)
 
 La fonction GetCol retourne toujours une chaîne, quelque soit le type
  dans la base de données, à vous de convertir
 
     pour convertir en numérique : %int(), %uns(), %dec()
     pour les dates/heures       : %date(), %time(), %timestamp()
     pour les variables Unicode  : %ucs2()
 


|    Changer de couleur
 
une fois le resultSet créé, vous pouvez obtenir les métaData, soit la
 définition de ce que vous allez recevoir (sorte de DSPFFD)
 
 
   JDBC_getMetaData( ResultSet )
    Retourne un objet MetaData décrivant un ResultSet
 
 
   JDBC_getColCount( MetaData )
    Retourne le nombre de colonnes
 
   JDBC_getColName( MetaData : NumCol))
    retoune le nom d'une colonne dont on fournit le n°
 
   JDBC_getColDspSize( MetaData: NumCol )
    retourne la taille (à l'affichage) d'une colonne
 
   JDBC_getColTypName( MetaData: NumCol )
    retourne le type d'une colonne
 
 


|    Changer de couleur
 
 instructions préparées :
 
 JDBC_PrepStmt( connexion : 'ordre SQL valide')
 
   Retourne un objet PreparedStatement pour l'instruction SQL
 
    L'instruction est "compilée" et ses exécutions utérieures seront
     plus rapides.
 
    peut contenir des marqueurs représentant des valeurs fournies plus tard
 
 
  JDBC_ExecPrepUpd( PreparedStatement )
    Exécute une instruction préparée qui ne retourne pas d'enregistrements
 
  JDBC_ExecPrepQry( PreparedStatement )
    Exécute une instruction préparée qui retourne un jeu d'enregistrements
 
  JDBC_FreePrepStmt( PreparedStatement )
    libère la mémoire associée à l'objet PreparedStatement
 


|    Changer de couleur
Exemple :
 
D Stmt            s                   like(PreparedStatement)
D ResSet          s                   like(ResultSet)
 
 /free
  // suite à une connexion . .
        Stmt = JDBC_PrepStmt( conn : 'Select nocli, raisoc +
                                      dep, ville           +
                                      from clients order by raisoc');
        if ( stmt = *null );
         // signaler l'erreur
        endif
        ResSet = JDBC_ExecPrepQry( Stmt );
        if (ResSet = *null);
         // autre erreur
        endif;
         // lecture des enregistrement comme vu plus haut
 
        JDBC_freeResult( ResSet );
        JDBC_freePrepStmt( stmt );
 


|    Changer de couleur
 
Si vous placez des marqueurs dans l'instruction préparée, vous devez
  fournir des valeurs avant l'exécution par :
 
  JDBC_setString( stmt : numéro paramètre : 'chaîne');
 
  JDBC_setInt( stmt : numéro paramètre : zone binaire);
 
  JDBC_setDouble( stmt : numéro paramètre : zone virg. flottante );
 
  JDBC_setDecimal( stmt : numéro paramètre : zone décimale);
 
  JDBC_setDate( stmt : numéro paramètre : zone date );
 
  JDBC_setTime( stmt : numéro paramètre : zone heure);;
 
  JDBC_setTimestamp( stmt : numéro paramètre : zone horodatage);
 
Exemple :
 
  nocli = 1234;
  JDBC_SetInt( stmt: 1: nocli );


|    Changer de couleur
Exemple complet avec un INSERT :
 
 /free
    Stmt = JDBC_PrepStmt( conn : 'Insert Into clients  +
                                 (nocli, raisoc, dep, ville)
                                 values(? , ? , ? , ?) ');
 
 
    if ( stmt = *null );
     //
    endif
 
    JDBC_setInt ( stmt: 1: 4321 );          // constantes OU variables
    JDBC_setString( stmt: 2: 'Volubis');
    JDBC_setDecimal( stmt: 3: 44);
    JDBC_setString( stmt: 4: 'Carquefou');
 
    if JDBC_execPrepUpd( stmt ) < 0;
     //
    endif;
 
 


|    Changer de couleur
 
 Les fonctions JDBC_getCol et JDBC_Setxxx (int, date, etc...)
  possèdent un paramètre supplémentaire, facultatif, de type indicateur.
 
  sur JDBC_getCol il sera positionné à *ON si la colonne est nulle,
      *OFF dans le cas contraire.
 
  sur JDBC_SetInt et les autres fonctions du même genre, vous l'envoyez
   à *ON pour signaler une valeur nulle, *OFF dans le cas contraire.
 
Vous pouvez aussi utiliser des instructions préparées pour les procédures 
 cataloguées :
 
 JDBC_PrepCall( Connection : 'instruction CALL') // préparation
 
 JDBC_RegisterOutParameter( CallableStatement: ParmNum: DataType )
   // prévient JDBC que ce paramètre est en sortie (valeur retour)
 
 JDBC_ExecCall( CallableStatement )             // Exécution
 
 JDBC_FreeCallStmt( CallableStatement )         // libération mémoire
 


|    Changer de couleur
 
 La fonction JDBC_ExecCall peut retourner *ON si un jeu ou plusieurs jeux
  d'enregistrements sont retournées par la procédure.
 
 JDBC_getUpdateCount( CallableStatement )
   Quand une procédure ne retourne pas de jeu d'enregistrements, nombre de
    lignes modifiées par la procédure.
 
 JDBC_getResultSet( CallableStatement )
  retourne un jeu d'enregistrements comme ExecuteQuery
 
 
 JDBC_getMoreResults( CallableStatement )
  passe au jeu d'enregistrements suivant, retourne *OFF s'il n'y en a pas
 
 
 JDBC_getString(), JDBC_getInt(), JDBC_getShort(), JDBC_getBoolean()
  permettent de récupérer les valeurs des paramètres en sortie
 
 Enfin, il existe deux fonctions pour gérer les transactions :
 
       JDBC_Commit()   et   JDBC_Rollback()





©AF400