Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Tutoriel pour apprendre à gérer une base de données MySQL
Avec les composants natifs de Lazarus, par Alcatîz

Le , par Alcatîz

52PARTAGES

10  0 
Gestion d'une base de données MySQL avec les composants natifs de Lazarus
Un tutoriel pour débuter en douceur

Dans ce tutoriel, vous apprendrez à gérer une base de données MySQL en utilisant les composants natifs de Lazarus (SQLdb).

Trois exemples d'applications, de complexité croissante, vous sont proposés. Ils vont de l'utilisation exclusive de contrôles spécialisés en bases de données à celle de contrôles classiques. Quelques petits exercices (facultatifs) vous mettront au défi.


Gestion d'une base de données MySQL avec les composants natifs de Lazarus

Cet article est sans prétention ; son but est juste de vous guider en douceur dans la réalisation de vos premières applications utilisant une base de données MySQL, sous Lazarus.
Comme illustration, nous simulons la gestion d'une petite société de location de voitures.

Et vous ?
Que pensez-vous de ce tutoriel ?
Quels composants utilisez-vous pour vos applications bases de données ?

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de Alcatîz
Responsable Pascal, Delphi et Assembleur https://www.developpez.com
Le 09/09/2017 à 17:19
Voilà le genre de remarques qui vont permettre d'améliorer ou corriger le tutoriel.

Citation Envoyé par thewolf Voir le message
Dans l'exemple 1, il faudrait ajouter "Dans l'inspecteur d'objets, renommez la fiche principale (Form1 par défaut) en MainForm." comme c'est le cas dans l'exemple 2.
Bonne idée, c'est fait.

Citation Envoyé par thewolf Voir le message
Dans III-A :

Pour suivre ce tutoriel, j'utilise localhost mais à quoi correspond exactement "192.168.0.1", je suppose que c'est si la base est sur un site distant. Cela m'intéresserait d'en savoir un peu plus, au cas où ...
Mon réseau local fonctionne (comme 90% des réseaux domestiques, sans doute) dans la plage d'adresses 192.168.0. Mon serveur Apache/MySQL a comme IP fixe 192.168.0.1 et distribue à mon PC de travail (et à tous les PC connectés, d'ailleurs) une adresse 192.168.0.xxx. Tu peux éventuellement simuler un réseau local et monter un serveur sur une machine virtuelle.

Citation Envoyé par thewolf Voir le message
IV-A : il faut ajouter l'unité db à la clause uses sinon EDatabaseError n'est pas reconnu.
En effet ! C'est fait.

Citation Envoyé par thewolf Voir le message
IV-C : tel que le code est proposé, à l'ouverture du programme, le dbgrid affiche la liste des tables (ce qui est logique puisque c'est la requête sql en cours et que l'événement lbTablesSelectionChange n'est pas encore déclenché).
Pour contourner ce problème, j'ai ajouté la ligne suivante à la fin de la procédure ShowTables :
Code : Sélectionner tout
if SQLQuery1.RecordCount > 0 then lbTables.ItemIndex:= 0;
C'est extrêmement fugace et la solution de contournement n'y change rien, en fait (sans vouloir te froisser). La solution est de lier le DBGrid au DataSource après l'appel à ShowTables. Mais la remarque est bonne et mérite que j'ajoute un petit encadré.

Citation Envoyé par thewolf Voir le message
procedure lbTablesSelectionChange : je pense que la commande "DBGrid1.Clear;" n'est pas utile, je me trompe ?
On dirait bien, en effet. Je l'ai retirée.

Citation Envoyé par thewolf Voir le message
Telle que la procédure est proposée, j'ai un comportement bizarre : quand je change de table, le grid affiche une première colonne vierge en plus de la table demandée.
Ce n'est pas le cas en inversant les deux premières commandes (close en premier puis clear) ! ou en supprimant le clear.
Je n'observe personnellement pas cette colonne supplémentaire. Toutefois, ayant enlevé le clear, je suppose que le souci n'en est plus un pour toi ?

Citation Envoyé par thewolf Voir le message
IV-D : en jouant avec le TDBNavigator, l'utilisation du dernier bouton (refresh) déclenche l'exception
"Must apply updates before refreshing data."
Mince, c'est vrai, le refresh nécessite que la méthode ApplyUpdates du SQLQuery ait été exécutée. Comme ce bouton n'a pas de fonction dans l'exemple, il peut être supprimé dans les propriétés du DBNavigator. Je modifie le chapitre en conséquence.

Citation Envoyé par thewolf Voir le message
procedure CommitChanges : manque la double apostrophe à "d'enregistrement"
Bien vu ! C'est corrigé (et c'était correct dans le code complet à la fin du chapitre).

Citation Envoyé par thewolf Voir le message
Est-il possible d'avoir un peu plus d'explications sur le fonctionnement des 3 contrôles nécessaires à la connexion du programme à la base de données (j'ai l'habitude d'utiliser sqlite avec un seul composant : TSqlite3Dataset et c'est bien plus simple). D'où notamment ici :
- "if SQLTransaction1.Active" : pourquoi vérifier la transaction et pas la connexion ?
- "SQLQuery1.ApplyUpdates;" : je suppose que cela applique les changements ... mais à quoi ?
- "SQLTransaction1.Commit;" : du coup, que fait cette commande ?
Sur le wiki, il y a un diagramme expliquant la hiérarchie et les liens entre les différents composants : http://wiki.freepascal.org/SQLdb_Pro...re_des_classes.

  • "if SQLTransaction1.Active" : ce test évite de déclencher une exception "Operation cannot be performed on an inactive dataset".
  • "SQLQuery1.ApplyUpdates" : le SQLQuery mémorise tous les changements dans son dataset interne ; exécuter ApplyUpdates permet d'envoyer les modifications vers le serveur.
  • "SQLTransaction1.Commit" : par défaut, MySQL travaille en mode autocommit, c'est-à-dire que toute requête entraîne des modifications directes dans la base de données. Mais pas avec les composants SQLdb, qui utilisent des transactions. C'est en quelque sorte le composant TSQLTransaction qui décide si les modifications doivent être appliquées (commit), annulées (rollback), etc.
    Un petit saut vers la FAQ MySQL pourrait peut-être t'éclairer mieux que moi ?

Je te remercie en tout cas pour toutes tes remarques. Je t'ai d'ailleurs rajouté à la liste des relecteurs techniques du tutoriel.

4  0 
Avatar de tintinux
Membre éprouvé https://www.developpez.com
Le 05/09/2017 à 9:52
Bonjour

phpMyAdmin est une solution pour administrer en mode web les bases MySQL, elle a l'avantage d'être identique sous tous les systèmes d'exploitation, mais elle nécessite d'installer un serveur web, pas toujours utile, et parfois avec des difficultés sans rapport avec Lazarus ou MySql.

Pour une utilisation locale, sous Windows ou Linux avec Wine, je crois qu'il est beaucoup plus agréable d'utiliser l'excellent HeidiSql

Il est d'ailleurs installé, très rapidement, en même temps que MariaDb pour Windows.
3  0 
Avatar de tourlourou
Modérateur https://www.developpez.com
Le 29/08/2017 à 21:38
Bonsoir,

Je me suis pour l'instant arrêté à la fin du chapitre IV : merci pour ce tutoriel très clair et progressif.

Pour la seconde question, je précise que je n'ai pas de gros besoins en matière de BDD, qu'ils sont monopostes, et que je n'apprécie guère les composants d'accès aux données... Être obligé d'en utiliser une tripatouillée et de les lier alors qu'il n'y a pas vraiment moyen de faire autrement (le DBGrid au DataSource, ce dernier au Query, etc.) m'agace un peu ! Mais bon, parce que mes besoins sont limités et que je suis un peu râleur...

Bref,
2  0 
Avatar de Gouyon
Membre éprouvé https://www.developpez.com
Le 04/09/2017 à 21:09
Ça complète bien l'article que j'avais écrit http://remi-gouyon.developpez.com/tutoriels/databases/creation-premiere-appli-bdd/ et inversement
2  0 
Avatar de thewolf
Membre régulier https://www.developpez.com
Le 07/09/2017 à 16:33
Dans l'exemple 1, il faudrait ajouter "Dans l'inspecteur d'objets, renommez la fiche principale (Form1 par défaut) en MainForm." comme c'est le cas dans l'exemple 2.

Dans III-A :
HostName
192.168.0.1 (dans ma configuration) ou localhost (si votre serveur MySQL tourne sur votre machine)
Pour suivre ce tutoriel, j'utilise localhost mais à quoi correspond exactement "192.168.0.1", je suppose que c'est si la base est sur un site distant. Cela m'intéresserait d'en savoir un peu plus, au cas où ...

IV-A : il faut ajouter l'unité db à la clause uses sinon EDatabaseError n'est pas reconnu.

IV-C : tel que le code est proposé, à l'ouverture du programme, le dbgrid affiche la liste des tables (ce qui est logique puisque c'est la requête sql en cours et que l'événement lbTablesSelectionChange n'est pas encore déclenché).
Pour contourner ce problème, j'ai ajouté la ligne suivante à la fin de la procédure ShowTables :
Code : Sélectionner tout
if SQLQuery1.RecordCount > 0 then lbTables.ItemIndex:= 0;


procedure lbTablesSelectionChange : je pense que la commande "DBGrid1.Clear;" n'est pas utile, je me trompe ?
Telle que la procédure est proposée, j'ai un comportement bizarre : quand je change de table, le grid affiche une première colonne vierge en plus de la table demandée.
Ce n'est pas le cas en inversant les deux premières commandes (close en premier puis clear) ! ou en supprimant le clear.

IV-D : en jouant avec le TDBNavigator, l'utilisation du dernier bouton (refresh) déclenche l'exception
"Must apply updates before refreshing data."

procedure CommitChanges : manque la double apostrophe à "d'enregistrement"
Est-il possible d'avoir un peu plus d'explications sur le fonctionnement des 3 contrôles nécessaires à la connexion du programme à la base de données (j'ai l'habitude d'utiliser sqlite avec un seul composant : TSqlite3Dataset et c'est bien plus simple). D'où notamment ici :
- "if SQLTransaction1.Active" : pourquoi vérifier la transaction et pas la connexion ?
- "SQLQuery1.ApplyUpdates;" : je suppose que cela applique les changements ... mais à quoi ?
- "SQLTransaction1.Commit;" : du coup, que fait cette commande ?

Bon, me voila arrivé au bout de l'exemple 2, encore merci pour cet excellent tutoriel. Reste à travailler sur l'application complète !
2  0 
Avatar de thewolf
Membre régulier https://www.developpez.com
Le 22/09/2017 à 20:02
Bonjour.


Tant que nous sommes dans l'inspecteur d'objets, nous allons définir les différents champs de la table Voitures dans les propriétés de SQLQueryVoitures. Repérez la propriété FieldDefs et ...
A quoi cela sert-il de définir ainsi les champs, cela a été fait lors de la création de la table et le query va donc récupérer ces informations ... D'ailleurs, que se passerait-il si on fait une erreur et introduit une incohérence (ordre différent, nom mal orthographié, erreur de type, mauvaise taille) ?

Pour l'anecdote, ayant cliqué par mégarde sur le champ "DataField" d'un contrôle alors que son datasource était renseigné, j'ai effectivement été bloqué et ai eu le message comme quoi c'était impossible de récupérer les champs ... mais cela a aussi effacé tout ce que j'avais saisi dans le query !
Du coup, n'ayant pas le courage de recommencer, j'ai continué sans et cela fonctionne parfaitement ainsi !

V-C-1. TDBGrid

Width + MaxWidth
pas de MaxWidth chez moi mais un MaxSize ! Je suppose que c'est équivalent ?

V-C-5
Pourquoi créer une "property Enregistre" avec FEnregistre, la procedure SetEnregistre ?
J'aurais tout simplement déclaré une variable globale au début de la partie implementation.
J'en profite pour cette question : quelle est la différence entre "strict private" et "private" ?
2  0 
Avatar de Alcatîz
Responsable Pascal, Delphi et Assembleur https://www.developpez.com
Le 30/08/2017 à 22:25
Bonsoir,

Difficile d'apporter de l'aide sans quelques informations sur la table à afficher, les composants utilisés, etc.
Et un peu de code.
1  0 
Avatar de Alcatîz
Responsable Pascal, Delphi et Assembleur https://www.developpez.com
Le 04/09/2017 à 21:29
Bonjour,

Citation Envoyé par thewolf Voir le message
je me suis lancé (installation de wamp, ...) mais je bloque à la création des tables de test (II-C) : tout semble bien se passer mais
Dans phpMyAdmin, allez dans le sous-menu Concepteur du menu Plus de notre base de données location, pour vérifier que les relations sont correctes entre les trois tables

les 3 tables sont bien là mais je n'ai pas les flèches verte et bleue matérialisant les relations (pourtant pas d'erreur lors de l'exécution du sql correspondant).

Je découvre dans le menu de gauche la possibilité de créer manuellement une relation mais au moment de la validation, j'ai le message suivant :

Erreur : fonctionnalités relationnelles désactivées

Je suppose qu'il doit y avoir un problème de configuration ... (en cherchant sur le net, que des messages assez anciens parlant de MyIsam et InnoDb, du chinois pour moi !)
En affichant la liste des tables de la DB location, l'une des colonnes, nommée Type, contient le type de moteur de stockage. Si ce n'est pas InnoDB, c'est peut-être que phpMyAdmin n'est pas complètement configuré.

La manipulation suivante permet-elle de sélectionner InnoDB comme moteur par défaut ?

  • Dans le bandeau supérieur, cliquer sur Serveur: localhost ;
  • Sélectionner l'onglet Variables ;
  • Trouver la variable default storage engine ;
  • Cliquer sur Modifier et, dans le champ d'édition, taper InnoDB ;
  • Idem avec la variable storage engine.

Si l'opération échoue, il est peut-être nécessaire de réaliser les étapes de configuration de phpMyAdmin reprise au chapitre II-E de cet autre tutoriel : http://alcatiz.developpez.com/tutori...-mageia/#LII-E : l'importation des tables internes et la modification du fichier config.inc.php.
1  0 
Avatar de thewolf
Membre régulier https://www.developpez.com
Le 05/09/2017 à 11:14
J'ai donc importé les tables internes et modifié phpmyadmin.conf.
Pour la suite, j'ai trouvé 4 fichiers intitulés config.inc.php, aucun ne comporte une section intitulée " Storage database and tables".

Après redémarrage de wamp, rien n'est changé ...

mais après avoir supprimé la base location, puis tout recommencé à partir de sa création, cela fonctionne enfin !

Je vais pouvoir passer à l'étude du tutoriel en lui-même.

Merci.

Christian
1  0 
Avatar de thewolf
Membre régulier https://www.developpez.com
Le 05/09/2017 à 15:14
Il faudrait corriger le script d'insertion de voitures : pour les lignes 5, 9 et 10 le prix est indiqué avec une virgule au lieu du point décimal, ce qui fait planter la requête.
1  0