La copie d’enregistrements est une opération assez courante pour les applications métier créées avec My Visual Database. Habituellement, cela se fait à l’aide d’un formulaire en mode édition et d’une astuce avec la valeur de la propriété dbGeneralTableID du bouton responsable de la sauvegarde des données.

Une autre façon d’obtenir une copie d’un enregistrement de table consiste à utiliser une requête SQL.

INSETR INTO cycle (code,type,description) SELECT code,type,description FROM cycle WHERE id=1Langage du code : SQL (Structured Query Language) (sql)

Cet exemple crée une copie de l’enregistrement avec ID=1 pour la table de cycle, qui comporte trois champs : code, type et description.

Est-il possible de copier un enregistrement sans connaître la structure de la table ? Peut! Pour ce faire, nous avons besoin d’une table temporaire (cette technologie est supportée dans les SGBD SQLite et MySQL).

function DB_CopyRecord( ATableName: string; AID: integer ):integer;
// fonction universelle pour copier un enregistrement
begin
   // créer une table temporaire avec une structure identique à l'enregistrement copié
   SQLExecute('CREATE TEMPORARY TABLE tmp AS SELECT * FROM ['+ATableName+'] WHERE id = '+IntToStr(AID));
   // réinitialiser la valeur du champ ID
   SQLExecute('UPDATE tmp SET id = NULL');
   // insérer l'enregistrement en arrière
   SQLExecute('INSERT INTO ['+ATableName+'] SELECT * FROM tmp');
   // obtenir l'ID de la nouvelle entrée
   Result := Last_Insert_ID();
   // supprimer la table temporaire
   SQLExecute('DROP TABLE tmp');
end;
Langage du code : Delphi (delphi)

L’entrée de la procédure est le nom de la table et l’identifiant de l’enregistrement à copier. La sortie est l’ID de la copie.

Au niveau de la base de données, l’unicité d’enregistrement dans les projets My Visual Database est prise en charge uniquement pour le champ ID requis, de sorte que la commande de la ligne 7 consiste à le définir sur NULL. Ceci est nécessaire pour que lorsque vous insérez une copie (ligne 9), la valeur du champ ID soit automatiquement définie par le SGBD lui-même.

Exemple d’utilisation d’une procédure dans laquelle le champ portant le nom est modifié sur la copie.

var
  tmpIDOrder: integer;
  tmpIDNewOrder: integer;
begin
  ...
  tmpIDNewOrder := DB_CopyRecord( 'order', tmpIDOrder ); 
  SQLExecute('UPDATE [order] SET name = (SELECT name FROM [order] WHERE id = '+IntToStr(tmpIDNewOrder)+') || " (копия)" WHERE id = '+IntToStr(tmpIDNewOrder));
Langage du code : JavaScript (javascript)

Note

Une fonctionnalité de la commande SQLQuery est le verrouillage de la base de données SQLite, donc si vous décidez d’utiliser la procédure DB_CopyRecord() pour copier plusieurs enregistrements, assurez-vous de ne pas l’appeler à l’intérieur de la boucle qui utilise l’ensemble de données ouvert par SQLQuery commande. Cette exigence est due au fait que la commande DROP TABLE nécessite un accès complet à la base de données.

Vous pouvez contourner cette limitation en remplaçant la boucle while et SQLQuery par une boucle for et SQLExecute. Comme vous n’avez besoin que des ID d’enregistrement pour la copie, vous pouvez extraire et convertir en tableau. Vous trouverez ci-dessous un exemple de code pour copier les détails de la commande :

var
  tmpID: integer;
  tmpIDOrder: integer;
  tmpListID: array of string;
  i: integer;

  tmpSQL: string;
begin
  ...
  tmpSQL := 'SELECT GROUP_CONCAT(id) FROM orderPosition WHERE id_order = '+IntToStr(tmpIDOrder);
  tmpListID := SplitString(SQLExecute(tmpSQL),',');
  for i:=0 to length(tmpListID) - 1 do
  begin
    tmpID := DB_CopyRecord( 'orderPosition', StrToInt( tmpListID[i] ) ) );
    ...
  end;

  ...
end;Langage du code : Delphi (delphi)

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *