L'ajout d'un enregistrement dans un fichier de données s'effectue avec la fonction HAjoute() .
Voici un exemple de code simple qui fonctionne :
POUR i = 1 _À_ 65535HRAZ(SOCIETE)SOCIETE.Nom = "Société "+iHAjoute(SOCIETE)FIN
La fonction HAjoute() est idéale pour des ajouts ponctuels, c'est-à-dire une dizaine d'ajout à la suite. Dès lors que l'on souhaite effectuer des ajouts en masse. Cette solution s'avère relativement lente.
Une première optimisation est d'utilisation la fonction HEcrit() .
Voici un exemple de code simple qui fonctionne :
POUR i = 1 _À_ 65535HRAZ(SOCIETE)SOCIETE.Nom = "Société "+iHEcrit(SOCIETE, HNbEnr(SOCIETE)+1)FINHRéindexe(SOCIETE)
La combinaison des fonctions HEcrit() + HRéindexe() permet d'optimiser les ajouts en masse. Effectivement après chaque appel à la fonction HAjoute() une réindexation du fichier de données est effectuée. Donc le fait d'effectuer une réindexation à la toute fin permet de gagner du temps de traitement.
Cependant une solution plus rapide existe : construire une requête SQL d'ajout multiple directement avec la commande "INSERT INTO".
Voici un exemple de code simple qui fonctionne :
sReqInsert est une chaîne = "INSERT INTO SOCIETE (Nom) VALUES "sReqValues est une chaînesReqValue est une chaîne = "('%1')"POUR i = 1 _À_ 65535sReqValues += [","]+ ChaîneConstruit(sReqValue, "Société "+i)FINsReqComplete est une chaîne = sReqInsert + sReqValuessdInsert est une Source de DonnéesHExécuteRequêteSQL(sdInsert, hRequêteDéfaut, sReqComplete)
J'attire votre attention sur plusieurs points critiques avec cette méthode :
1) Le fait d'utiliser la fonction ChaîneConstruit() avec une requête SQL en dur n'est pas recommandée. En effet, cela ouvre à des failles de sécurité (par exemple : l'injection SQL).
2) Une taille excessive d'une requête SQL peut provoquer une exception WLangage® provoquée par la saturation mémoire du système.
Voici un exemple de code non optimisé :
sPersonnelNom, sPersonnelPrenom, sSocieteNom est une chaînePOUR TOUT PERSONNEL(sPersonnelNom, sPersonnelPrenom, sSocieteNom) = (PERSONNEL.Nom, PERSONNEL.Prenom, "")SI HLitRecherchePremier(SOCIETE, IDSOCIETE, PERSONNEL.IDSOCIETE) ALORSsSocieteNom = SOCIETE.NomFIN// ... Traitement avec les 3 chaînes ...FIN
Pour chaque enregistrement du fichier de données PERSONNEL, une recherche sur la SOCIETE est effectuée. C'est-à-dire que toutes les rubriques du fichier de données PERSONNEL sont lues puis un enregistrement dans le fichier de données SOCIETE est lu et ses variables HFSQL sont mises à jour.
Une première optimisation peut être réalisée sur la recherche dans le fichier de données SOCIETE. Effectivement il est inutile d'effectuer une recherche sur une SOCIETE déjà lue.
Une deuxième optimisation peut être réalisée avec l'utilisation du mot clé SANSSAUVEPOSITION.
Voici un exemple de code simple qui fonctionne :
taSociete est un tableau associatif (*,*,wlEntier_8) de chaînesPersonnelNom, sPersonnelPrenom, sSocieteNom est une chaînePOUR TOUT PERSONNEL SANSSAUVEPOSITION(sPersonnelNom, sPersonnelPrenom, sSocieteNom) = (PERSONNEL.Nom, PERSONNEL.Prenom, "")SI taSociete[PERSONNEL.IDSOCIETE]..Vide ALORStaSociete[PERSONNEL.IDSOCIETE] = HLitRecherchePremier(SOCIETE, IDSOCIETE, PERSONNEL.IDSOCIETE) ? SOCIETE.Nom sinon ""FINsSocieteNom = taSociete[PERSONNEL.IDSOCIETE]// ... Traitement avec les 3 chaînes ...FIN
La meilleure solution est de tout faire dans une requête SQL. Ainsi seules les rubriques réellement souhaitées sont récupérées. Et il y a moins d'aller-retour entre l'applicaton et le serveur de base de données.
Voici un exemple de code simple qui fonctionne :
sPersonnelNom, sPersonnelPrenom, sSocieteNom est une chaînereqPersonnel est une Requête SQL =[SELECT PERSONNEL.Nom AS P_Nom, PERSONNEL.Prenom AS P_Prenom, SOCIETE.Nom AS S_NomFROM PERSONNELLEFT JOIN SOCIETE ON SOCIETE.IDSOCIETE = PERSONNEL.IDPERSONNELORDER BY SOCIETE.Nom, PERSONNEL.Nom, PERSONNEL.Prenom]SI HExécuteRequête(reqPersonnel) _ET_ (HNbEnr(reqPersonnel) > 0) ALORSPOUR TOUT reqPersonnel SANSSAUVEPOSITION(sPersonnelNom, sPersonnelPrenom, sSocieteNom) = (reqPersonnel.P_Nom, reqPersonnel.P_Prenom, reqPersonnel.S_Nom)// ... Traitement avec les 3 chaînes ...FINFINHAnnuleDéclaration(reqPersonnel)
La jointure "LEFT JOIN" permet de récupérer tout le personnel même ceux qui ne sont dans aucune société.
Il est important d'utiliser les fonctions HAnnuleDéclaration() ou HLibèreRequête() afin de libérer les ressources au plus tôt.
Une autre optimisation peut être réalisée en utilisant la fonction "TOP" qui permet de ne récupérer que les X premiers enregistrements s'il est inutile d'en récupérer beaucoup.