Télécharger Exsql4wd.zip

Ma page de téléchargement

Le site des accès [alter]natifs

 

De Eric ROUMEGOU

ALL Rigts reserved © 2003

WinDev®, WebDev® et HyperFile® sont des marques déposées par PC SOFT.  

Utiliser les accès natifs avec Windev7.5.

 

 

Introduction.. 2

Hyperfile et SGBD.. 2

Les accès alternatifs. 2

Les accès PC SOFT. 2

Se rendre indépendant de la base comme des accès utilisés. 2

Les SGBD.. 2

Les accès alternatifs. 2

Avant de démarrer.. 3

Les accès aux bases. 3

Les tables de l’exemple. 3

Les accès. 3

L’exemple. 3

Quelques techniques de programmation.. 4

Composer l’ordre SELECT. 4

Lire les données de la requête. 4

Faire un insert de la Table. 5

Faire un Update de la Table. 5

Le blocage de ligne. 6

 


 

Introduction

Hyperfile et SGBD

Inutile de revenir sur les nombreux débats entre moteur HyperFile et SGBD. Comme toujours en matière d’informatique, il y a des avantages, des inconvénients, des afficionados et des détracteurs pour chaque solution.

Pour ma part, je m’oriente systématiquement vers les SGBD standards du marché  pour des questions de performances, d’ouverture et de pérennité. Choisir un SGBD, c’est la garantie de pouvoir utiliser n’importe quel outil de développement ou produit du marché.

Et quand - c’est l’objet de ce travail- je peux à tout moment changer de SGBD en fonction des besoins, d’un existant, de contraintes économiques sans rien modifier à mes applications, je me félicite d’avoir opté pour des standards.

Les accès alternatifs

J’ai découvert ces accès en 2003 et depuis je les utilise comme beaucoup d’autres développeurs de la communauté. J’ai pu apprécier la qualité de ces produits et surtout la disponibilité et la réactivité de leurs auteurs.

Ce sont des solutions très sérieuses car fiables et économiques.

Pour plus d’informations, je vous renvoie au site dédié à ces accès

http://sql4wd.rbesset.net

Les accès PC SOFT

Je les ai beaucoup utilisés avec des bases de données Oracle. Cela fonctionnait de façon très satisfaisante.

PC SOFT à d’ailleurs rajouté beaucoup d’accès natifs et l’on a maintenant des solutions pour les SGBD suivants (MySQL, Oracle, SQLserver, Sybase, DB2,Informix, Progress)

La plupart de ces accès sont payants. Même si le prix est raisonnable, on peut hésiter à acquérir tous ces accès juste pour tester l’éligibilité de ses produits avec chaque SGBD.

C’est l’intérêt des accès alternatifs.

 

Se rendre indépendant de la base comme des accès utilisés

Telle a été mon approche.

Lassé de gérer deux types de codes (mySQL et Oracle), et tenté par la possibilité de rajouter une 3ème base de données complètement gratuite (SQLite) à mes applicatifs, je me suis décidé à revoir tout mon code avec des classes pour répondre aux problèmes suivants.

Les SGBD : Je suis parti sur MySQL, Oracle et SQLite.

Comment gommer les différences de langage SQL et fonctionnalités entre ces SGBD ?

C’est l’objet de la classe c_GestionSQL

Les accès alternatifs : C’est mon choix et il est guidé par des considérations économiques.

Question technique, il n’y a pas de soucis, mais la pérennité de ces accès est peut-être plus incertaine. Même si les sources sont disponibles, je n’aurais pas forcément les compétences pour suppléer leurs auteurs en cas de gros problèmes.

Je dois donc à tout moment pouvoir revenir sur l’utilisation des accès payants. Il manque aussi l'accès SQL Server parmi les accès alternatifs..

C’est l’objet de la classe c_NatifSQL qui va "émuler" les accès alternatifs en utilisant les ordres SQL du WLangage.

 

Avant de démarrer

 

Une fois que vous aurez téléchargé le projet exemple sous forme de fichiers Zip, il vous faut effectuer un certain nombre d'opérations pour tester les différents accès.

Les accès aux bases.

 

Le fichier .Ini

Les chaînes de connexions sont paramètrées dans le fichier EWSQL4WD.ini. Veuillez en premier lieu, renseigner ces valeurs en fonction de votre environnement.

 

Les tables de l’exemple

Vous trouverez des scripts de création des tables pour Oracle, mySQL et SQLite dans le rep SQL.

Il y a deux tables QUID et PERMIS.

 

Les accès

Les dll des accès alternatifs se trouvent dans le rep Exe.

Pour les accès PC SOFT, veuillez utiliser celles que vous avez acquises chez l’éditeur.

L’exemple

 

Il s’agit de deux fenêtres Type Table et Mode Fiche. (QUID_TAB et QUID_FIC)

Elles permettent de gérer une table QUID qui est une gestion d’invite que j’utilise lorsque j’ai besoin de demander un choix à l’utilisateur. On définit le texte de cette invite, et les options possibles.

Vous pouvez bien sûr ré-utiliser cet exemple dans vos propres développements.

 

Le code de ces fenêtres a été généré par mon module de RAD. C'est pourquoi tout le code est centralisé dans des procédures afin de limiter mes opérations de transfert par copier coller.

Par ailleurs, j’ai du supprimé un certain nombre d’options qui ne sont pas utiles pour l’exemple.


Quelques techniques de programmation

 

J'ai tiré quelques lignes de l'exemple Exsql4WD, pour expliquer quelques techniques de programmation avec les classes de gestion SQL et les accès alternatifs.

N'hésitez pas à me signaler toute erreur et/ou amélioration que vous jugerez utiles.

Composer l’ordre SELECT

 

monsql est un c_GestionSQL

 

monsql:AddWhere(pWhere)

monsql:SetSGBD(gBase)

monsql:AddSelect("QUID","QUID_ID")       //Id Invite

monsql:AddSelect("QUID","QUID_TITRE")          //Titre de l'invite

monsql:AddSelect("QUID","QUID_TEXTE")          //Texte de l'invite

monsql:AddSelect("QUID","QUID_OPTION")         //Options autorisées

monsql:AddSelect("QUID","QUID_OBLIG")          //Obligatoire Oui=1

// EquiJointure

//monsql:AddJoin("QUID.ID=TABLEJOINTE.ID","INNER")

monsql:AddWhere(pWhereFiltre)

monsql:AddOrder(pOrder)

monsql:AddWhere(pWhere)

Commande=monsql:Rtv_ReqSQL()

 

Le principe est simple. On va passer par la méthode des classe c_GestionSQL, :

-         les zones composant le select monsql:AddSelect.
Il est possible d’écrire aussi monsql:AddSelect("QUID.QUID_ID")

-         les jointures monsql:AddJoin

-         les clauses where monsql:AddWhere(pWhere)

-         la clause Order monsql:AddOrder

 

et c’est la méthode monsql:Rtv_ReqSQL() qui nous retournera la commande SQL correspondante  en fonction du SGBD (défini par monsql:SetSGBD(gBase))

 

Lire les données de la requête

 

 

SI PAS fSQL:mySQLExec(Commande,lCurreq) ALORS

      fSQL:mySQLMsgBox("Erreur sur requete "+RC+Commande)

      fSQL:mySQLFerme(lCurreq)

      RENVOYER Faux

SINON

      fSQL:mySQLPremier(lCurreq)

      TANTQUE PAS fSQL:mySQLEnDehors

            NumCol=0

            NumCol++;QUID_ID=fSQL:mySQLCol(lCurreq,NumCol) //Id Invite

            NumCol++;QUID_TITRE=fSQL:mySQLCol(lCurreq,NumCol)    //Titre de

            NumCol++;QUID_TEXTE=fSQL:mySQLColLong(lCurreq,NumCol)      //Texte de

            NumCol++;QUID_OPTION=fSQL:mySQLCol(lCurreq,NumCol)   //Options

            NumCol++;QUID_OBLIG=fSQL:mySQLCol(lCurreq,NumCol)

 

            fSQL:mySQLSuivant(lCurreq)

      FIN   //TANTQUE   pas fSQL:mySQLEnDehors

 

FIN

fSQL:mySQLFerme(lCurreq)

 

C’est la technique (SQLpremier, SQLSuivant) que j’utilise le plus souvent.

Notez qu’avec SQLPremier SQLSuivant, il faut utiliser mySQLCOL (et mySQLColLong).au lieu de mysSQLLitCol

Cela est sans conséquence pour les accès alternatifs, voire pour l’accès Oracle PCSoft, mais pour l’accès Natif mySQL PC SOFT, SQLLitCol de fonctionne pas dans une boucle SQLPremier.

Les méthodes SQLColLong et SQLLitColLong ont été créées pour améliorer les performances de lecture sur l'accès mySQL4WD. Elles sont présentes pour compatibilité sur les autres accès. Il faut les utiliser dès que la colonne à récupérer est supérieure à 255 Caractères.

 

Pour utiliser SQLLitCol, il faut utiliser le SQLFetch

 

      TANTQUE     fSQL:mySQLFetch(lCurReq)

            table2.IMP_PosDeb=fSQL:mysqllitcol(lCurReq,1) 

            table2.IMP_Posfin=fSQL:mysqllitcol(lCurReq,2)

// etc

 

      FIN //TANTQUE     fSQL:mySQLFetch(lCurReq)

 

fSQL:mySQLFerme(lCurReq)

 

 

Faire un insert de la Table

            monsql:RAZ()

            monsql:SetCurrentTable(MyTable)

            monsql:SetSGBD(gBase)

            SI {PrimaryKey}<>0 ALORS monsql:AddInsert("QUID_ID",QUID_ID)

            monsql:AddInsert("QUID_TITRE",Quote(QUID_TITRE))

            monsql:AddInsert("QUID_TEXTE",Quote(QUID_TEXTE))

            monsql:AddInsert("QUID_OPTION",Quote(QUID_OPTION))

            monsql:AddInsert("QUID_OBLIG",QUID_OBLIG)

 

            Commande=monsql:CreeOrdreSQL("INSERT")

 

 

On positionne sur la table à mettre à jour monsql:SetCurrentTable

On ajoute les colonnes et la valeur à insérer monsql:AddInsert. Les chaînes alpha doivent être formatées avec la fonction Quote.

On récupère l’ordre INSERT correspondant.

Rmq : j’utilise les identifiants auto incrément avec mySQL et SQLite. Cela n’existe pas pour Oracle où j’utilise les séquences Oracle. Dans le cas de mySQL et SQLite, cette colonne n’est pas passée à l’ordre INSERT (car à 0) d’où le test SI {PrimaryKey}<>0 ALORS monsql:AddInsert("QUID_ID",QUID_ID)

 

Faire un Update de la Table

 

            monsql:RAZ()

            monsql:SetCurrentTable(MyTable)

            monsql:SetSGBD(gBase)

            monsql:AddUpdate("QUID_ID",QUID_ID)      //Id

            monsql:AddUpdate("QUID_TITRE",Quote(QUID_TITRE))

            monsql:AddUpdate("QUID_TEXTE",Quote(QUID_TEXTE))

            monsql:AddUpdate("QUID_OPTION",Quote(QUID_OPTION))

            monsql:AddUpdate("QUID_OBLIG",QUID_OBLIG)

            monsql:AddWhere(PrimaryKey+"= "+{PrimaryKey})

            Commande=monsql:CreeOrdreSQL("UPDATE")

 

Le blocage de ligne

 

Pour bloquer les enregistrements sélectionnés, vous pouvez utiliser les méthodes mySQLBloque. Pour ma part, je n’aime pas bloquer toute la requête, car si j’ai des tables liées dans ma requête (ex récupérer le nom du client pour affichage), je n’ai pas forcément envie de bloquer l’enregistrement client alors que je veux bloquer sa commande. Je préfère effectuer le blocage grâce à une requête plus limitée de type Select MonId from MatablePrimaire.

C’est le travail de la méthode BloqueLigne de c_GestionSQL

 

                        monsql:RAZ()

                        monsql:SetCurrentTable(MyTable)

                        monsql:SetPrimaryKey(PrimaryKey)

                        monsql:SetSGBD(gBase)

                        monsql:AddSelect("QUID","QUID_ID")                     //Id Invite

                        monsql:AddSelect("QUID","QUID_TITRE")              //Titre de l'invite

                        monsql:AddSelect("QUID","QUID_TEXTE")             //Texte de l'invite

                        monsql:AddSelect("QUID","QUID_OPTION")                      //Options autorisées

                        monsql:AddSelect("QUID","QUID_OBLIG")             //Obligatoire Oui=1

                        monsql:AddWhere(pWhere)

                        Commande=monsql:Rtv_ReqSQL()

                        // Blocage de la ligne et débute la transaction

                        SI ModeAppel="MODIFY" ALORS

                                   SI PAS monsql:BloqueLigne(0,Quoi) ALORS

                                               Erreur(monsql:m_MsgErreur)

                                               gWhere=""                   // Ne pas réafficher

                                               Ferme

                                   FIN

                        FIN

La méthode Bloque_Ligne va créer une requete de type SELECT QUID_ID FROM QUID WHERE QUID_ID=2 et ce sont ces lignes qui seront bloquées. La requête a été générée grace au méthode SetCurrentTable, SetPrimaryKey et la valeur de la clé récupérée du membre m_ClauseWhere.

Si ces lignes sont déjà bloquées, un message personnalisé monsql:m_MsgErreur sera renvoyé.

 

 

La collection de procédures globales FonctionSQL

Les fonctions et procédures peuvent parfois faire double emploi avec les méthodes de la classe c_GestionSQL. Ce sont d'ailleurs ces procédures qui ont été adaptées en classe. Je les ais conservées car elles sont quelque fois plus facile à utiliser que les classes, et surtout par compatibilité avec mes anciens projets.

Il y a par ailleurs quelques fonctions complémentaires utiles.