FAQ DelphiConsultez toutes les FAQ
Nombre d'auteurs : 124, nombre de questions : 934, dernière mise à jour : 23 octobre 2024 Ajouter une question
Cette FAQ a été réalisée à partir des questions fréquemment posées sur les forums Delphi et Delphi et bases de données de www.developpez.com et de l'expérience personnelle des auteurs.
Nous tenons à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose soient correctes. Les auteurs font le maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous souhaitez y apporter des corrections ou la compléter, contactez un responsable (lien au bas de cette page).
Nous espérons que cette FAQ saura répondre à vos attentes. Nous vous en souhaitons une bonne lecture.
L'équipe Delphi de Developpez.com.
- Comment gérer simplement un champ auto-incrément ?
- Comment relier des requêtes en maître/détail ?
- Comment comparer des dates/heures dans une requête SQL ?
- Comment insérer une chaîne dans une requête SQL ?
- Comment réaliser une condition insensible à la casse ?
- Comment effectuer des requêtes multiples ?
- Comment connaître le nombre de lignes d'un ensemble de résultats par requête ?
- Comment trouver tous les enregistrements pour un champ contenant une chaîne XXX ?
- Comment n'afficher que les enregistrements commençant par la valeur d'un TEdit ?
- Comment concaténer du texte dans une requête ?
Toutes les bases de données ne fournissent pas forcément de champs de type auto-incrément, et surtout la possibilité de connaître la prochaine valeur de ces champs. Dans le cas d'Interbase, il faut créer un générateur et un trigger pour chaque table de la base, plus une requête pour récupérer la valeur courante dans Delphi.
La méthode présentée ci-dessous vous permettra de générer un identifiant numérique valide pour n'importe quelle table de votre base.
Les avantages sont les suivants :
- très peu de code ;
- aucune modification de la base ;
- utilisable pour tout type de base supportant SQL.
Mais elle a de sérieux inconvénients :
- utilisable uniquement en mode mono-utilisateur, à cause des possibilités de violation de clef ;
- coûteuse en performances pour les tables volumineuses.
Si vous êtes néanmoins intéressé, voici la méthode.
Etape 1 : Créer le composant requête
Commencez par placer un composant requête dans un DataModule ou sur une fiche accessible par l'ensemble de l'application si nécessaire.
Code delphi : | Sélectionner tout |
1 2 | Name := SQLRequeteID DataBaseName := ... |
Etape 2 : Créer la fonction
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 | function NouvelID(Table, Clef: String): Integer; begin with SQLRequeteID do begin Close; SQL.Clear; SQL.Add('select max(' + Clef + ') from ' + Table); ExecQuery; Result := Fields[0].AsInteger + 1; Close; end; end; |
Etape 3 : Utilisation de la fonction
Code delphi : | Sélectionner tout |
prochain_numero := NouvelID('CLIENT', 'NO_CLI');
Prenons l'exemple d'une relation entre les tables CLIENT et FACTURE.
Requête maître (associée à un composant DSClient : TDataSource)
Code delphi : | Sélectionner tout |
1 2 | SQLClient.SQL.Add := 'SELECT cli_no, cli_nom, cli_prenom, cli_telephone, ville'; SQLClient.SQL.Add := 'FROM client'; |
Requête détail (associée à un composant DSFacture : TDataSource)
Code delphi : | Sélectionner tout |
1 2 3 | SQLFacture.SQL.Add := 'SELECT cli_no, fac_no, fac_date, fac_montant_ttc'; SQLFacture.SQL.Add := 'FROM facture'; SQLFacture.SQL.Add := 'WHERE cli_no = :cli_no'; |
Méthode 1 : Propriété DataSource
Selon le jeu de composants que vous utilisez (BDE, IBX ,dbExpress...), vos requêtes disposent ou non d'une propriété DataSource. Dans l'inspecteur d'objets, mettez DSClient dans la propriété DataSource de SQLFacture.
Méthode 2 : Evènement OnAfterScroll
L'évènement OnAfterScroll d'un ensemble de données se déclenche après chaque changement d'enregistrement. L'expression cli_no présente dans la requête de SQLFacture correspond à un paramètre dynamique de cette requête, nous allons donc devoir lui affecter manuellement ses valeurs.
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 | procedure TMyForm.SQLClient.AfterScroll(Sender: TDataSet); begin SQLFacture.Close; SQLFacture.ParamByName('cli_no').AsInteger := SQLClient.FieldByName('cli_no').AsInteger; SQLFacture.Open; end; |
La comparaison des dates et heures exigent que le format soit respecté. Celui-ci pouvant dépendre du SGBD utilisé, il est conseillé d'utiliser systématiquement des paramètres pour la comparaison des dates :
Code delphi : | Sélectionner tout |
1 2 | DataSet1.SQL.TEXT:='SELECT * FROM UneTable WHERE ChampDate<:UneDate'; DataSet2.ParamByName('UneDate').AsDateTime:=Now; |
La comparaison des dateq sans notion d'heure est parfois aléatoire sur la limite. TDateTime contenant toujours une notion d'heure et celle-ci étant parfois remplie aléatoirement. Par Exemple, au lieu de comparer ChampDate<=:UneDate avec UneDate=Now, il vaut mieux comparer ChampDate<:UneDate avec UneDate=Now+1. Ainsi l'heure éventuellement contenue dans ChampDate n'aura pas d'effet sur le résultat
Le moyen le plus simple pour insérer correctement une chaine dans le texte d'une requête SQL est d'utiliser la fonction QuotedStr afin d'ajouter en début et fin les apostrophes, mais aussi de convertir correctement les apostrophes situés en milieu de chaine.
Code delphi : | Sélectionner tout |
1 2 | Query1.SQL.Text:='SELECT * FROM TOTO' +' WHERE CODE='+QuotedStr(Edit1.Text); |
Pour réaliser une condition insensible à la casse dans une requête SQL, le plus simple est de mettre en majuscule les termes avant comparaison. Pour cela utiliser l'opérateur UPPER :
Code delphi : | Sélectionner tout |
1 2 | IBQuery1.SQL.Text:='SELECT * FROM UneTable WHERE UPPER(Champ2)=:Valeur'; IBQuery1.ParamByName('Valeur').AsString:=UpperCase(UneChaine); |
La propriété SQL des composants de type requête ne peut gérer qu'une seule requête SQL complète à la fois. Pour effectuer plusieurs requête à la suite il faut mettre à jour la propriété SQL entre chaque requête et les exécuter une à une.
Dans le cadre d'un transaction, celle-ci peut être démarrer avant la première requête et validée ou annulée à la fin de la dernière requête.
À noter aussi que la RxLib (incluse dans la JVCL) contient un composant capable d'exécuter des scripts SQL.
La propriété recordCount permet de connaître le nombre de lignes d'un ensemble de résultats. Malheureusement, dans certains cas cette propriété échoue. Il est alors recommandé de résoudre le problème par requête grâce à l'instruction SQL Count.
Nous vous fournissons deux exemples mettant en oeuvre cette instruction.
1) Avec les composants de connection par le BDE.
La fonction BDEenregCount permet de connaître le nombre de lignes d'une table. Cette fonction attend en entrée le nom de la base de données ainsi que le nom de la table.
Cette fonction retourne -1 en cas d'échec.
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | function BDEenregCount(_dataBaseName, _tableName: string):longInt; begin with TQuery.Create(nil) do try DatabaseName := _databaseName; sql.Text := 'SELECT COUNT(*) FROM '+ _tableName; try Active := true; result := fields[0].AsInteger; except result := -1; end; finally free; end; end; |
2) Avec les composants de connexion ADO
La fonction ADOenregCount permet de connaître le nombre de lignes d'une table. Cette fonction attend la valeur de la chaîne de connexion ADO ainsi que le nom de la table.
Cette fonction retourne -1 en cas d'échec.
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | function ADOenregCount(_connectionString, _tableName: string):longInt; begin with TADOQuery.Create(nil) do try ConnectionString := _connectionString; sql.Add('SELECT COUNT(*) FROM '+ _tableName); try Open; result := fields[0].AsInteger; except result := -1; end; finally free; end; end; |
Pour extraire d'une table tous les enregistrements pour lesquels un champ doit contenir partiellement une chaîne de caractères, nous devons procéder par requête et utiliser l'instruction LIKE du langage SQL.
Exemple
Retourne tous les clients dont le nom contient les lettres MA
Code delphi : | Sélectionner tout |
Query1.sql.Text := 'Select * from clients where nom LIKE '+quotedStr('%MA%')
Remarque
Vous trouverez la définition de la fonction Like à cet endroit ainsi que des exemples de son utilisation.
Pour répondre à ce problème, il faut construire une requête SQL utilisant :
- l'opérateur Like pour comparer une valeur à des valeurs similaires,
- la fonction QuotedStr qui permet de gérer les apostrophes en début et fin de chaîne.
Ce qui nous permet de construire la clause WHERE permettant de filtrer notre ensemble de données.
Code delphi : | Sélectionner tout |
Query1.sql.Text := 'SELECT * FROM MaTable WHERE MonChamp LIKE '+quotedStr(Edit1.Text+'%');
Puisque la fonction Like est employée alors le caractère _ « underscore » sera considéré comme un joker. C'est-à-dire que si nous instruisons la propriété Text du composant Tedit avec la valeur suivante : M_A
…alors la requête nous renverra tous les enregistrements de longueur minimale trois caractères et pour lesquels MonChamp à le caractère M en première position et le caractère A en troisième position.
Il faut utiliser l'opérateur || pour concaténer deux champs. Par exemple (exemple sur la base DBDemos, table animals.dbf), une requête qui retourne une colonne composée du nom et de la localité :
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 | procedure TForm1.Button1Click(Sender: TObject); begin Qyery1.SQL.Clear; Query1.SQL.Text := 'select name ||' + QuotedStr(' ESPACE ') + ' || area from animals.dbf'; Query1.Open; ShowMessage(Query1.Fields[0].AsString); //==>retourne Angel Fish ESPACE Computer Aquariums end; |
Proposer une nouvelle réponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour çaLes sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.