FAQ DelphiConsultez toutes les FAQ

Nombre d'auteurs : 123, nombre de questions : 919, dernière mise à jour : 14 juin 2019  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.

Commentez


SommaireBases de donnéesSQL (10)
précédent sommaire suivant
 

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');

Mis à jour le 18 octobre 2013 DidiLogic

Gérer les Compteurs Auto-Incrémentés avec Interbase, par Pascal Barnouin et Sylvain James

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;

Mis à jour le 18 octobre 2013 DidiLogic

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

Mis à jour le 18 janvier 2014 Nono40

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);

Mis à jour le 18 janvier 2014 Nono40

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);

Mis à jour le 18 janvier 2014 Nono40

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.

Mis à jour le 22 janvier 2014 Nono40

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;

Mis à jour le 18 janvier 2014 Pascal Jankowski

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.

Mis à jour le 18 janvier 2014 Pascal Jankowski

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+'%');
Remarque :
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.

Mis à jour le 18 janvier 2014 Pascal Jankowski

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;

Mis à jour le 18 janvier 2014 Giovanny Temgoua

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 ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les 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 © 2019 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.

 
Responsables bénévoles de la rubrique Delphi : Gilles Vasseur - Alcatîz -

Partenaire : Hébergement Web