Connaître la clé primaire du dernier enregistrement ajouté à une table SQLite avec FireDAC sous Delphi

Lorsqu'on programme des applications touchant à des bases de données on a souvent besoin de connaître les clés primaires des lignes ajoutées aux tables pour s'en servir de suite.

Dans la plupart des langages de développement une méthode ou fonction du langage ou du driver nous donne accès à cette information.

Avec SQLite c'est un peu particulier : on ne s'en sort pas avec une API du driver, il faut lancer une requête. Du coup FireDAC ne fournit pas de fonction spécifique mais on contourne simplement ce problème.

Il existe plusieurs méthodes pour ajouter des enregistrements à une table en utilisant FireDAC :

  • faire une requête SQL avec le composant TFDQuery
  • la vieille méthode appréciée par les "anciens" ayant connu le BDE, à savoir l'utilisation du composant TFDTable. J'ai encore souvent tendance à faire partie des anciens, tout est bon pour ne pas rédiger soi-même des requêtes SQL !

Pour l'exemple mettons que j'ai une fiche vierge avec un TFDConnection, un TFDQuery et un TFDTable. Ma base de données SQLite contient une table "liste" ayant un champ id de type INTEGER déclaré comme PRIMARY KEY et un champ libelle de type TEXT.

Je reviendrai ultérieurement sur la création de la base de données et le paramétrage de la connexion. Je vais ici me concentrer uniquement sur la récupération d'un ID autoincrémenté de clé primaire. Cet article peut servir de pense bête quand on ne fait pas cette opération tous les jours...

Pour l'insertion avec le composant TFDQuery, il faut utiliser le code suivant ou le faire en partie du côté de l'éditeur de propriétés du composant FDQuery1 (requête SQL + description du paramètre passé et de son type):

  FDQuery1.SQL := 'insert into liste (libelle) values (:libelle)';
  try
    FDQuery1.ParamByName('libelle').AsString := 'nouvelle ligne';
    FDQuery1.ExecSQL;
  except
    // Glups
  end;

Pour l'insertion avec le composant TFDTable, il faut utiliser le code suivant :

  FDTable1.Insert;
  try
    FDTable1.FieldByName('libelle').AsString := 'nouvelle ligne';
    FDTable1.Post;
  except
    FDTable1.Cancel;
  end;

Une fois l'insertion faite, il suffit d'utiliser la ligne suivante pour obtenir l'ID du dernier enregistrement inséré :

id := FDConnection1.ExecSQLScalar('select last_insert_rowid()');

Attention : cet appel concerne le dernier autoincrément utilisé dans la base. SQLite ne devant pas être utilisé par plusieurs programmes ou utilisateurs simultanément cela ne pose pas de problème majeur.

Bien entendu il est préférable de récupérer et traiter cette valeur uniquement si l'insertion s'est bien passée. Dans le cas contraire on prend le risque d'avoir la valeur de la précédente insertion, éventuellement dans une autre table, ou une valeur erronée ne correspondant à rien.

Notez que la méthode TFDConnection.ExecSQLScalar rend bien service dans notre cas. Elle a la particularité de ne renvoyer que la première valeur de la première ligne de l'ensemble de données. Très pratique pour récupérer des statistiques, totaux, ... en laissant le moteur de base de données ou FireDAC faire les calculs.

Voilà, ce sera tout pour ce 14 juillet. Passez une bonne suite de week-end.


Mug Chinese New Year 2023 : year of the rabbitMug Pascal case in Alexandrie