Je ne pense pas qu'il existe un moyen d'obtenir le nombre de lignes affectées lorsque vous effectuez des mises à jour, insère et supprime via un TDBgrid ou d'autres composants compatibles DB comme TDBNavigator. La raison en est que les contrôles prenant en charge DB utilisent les méthodes Post et Delete de TDataSet et que ces appels remplacent InternalPost et InternalDelete dans TAdoCustomDataSet. Ils fonctionnent d'une manière fondamentalement différente de l'exécution d'une instruction SQL via la méthode ExecSql de, disons, TAdoQuery.
Par conception, TDataSet.Post et TDataSet.Delete ne doivent affecter qu'une seule ligne, donc si l'opération réussit, vous savez que exactement une ligne a été affectée.
Il convient de noter, mais pas beaucoup d'aide pour ce que vous voulez faire, qu'il y est un moyen de fixer le même gestionnaire d'événements à un certain nombre de descendants TAdoCustomDataSet qui partagent un TADOConnection, comme indiqué dans ce code:
procedure TForm1.FormCreate(Sender: TObject);
var
i : Integer;
begin
for i := 0 to AdoConnection1.DataSetCount - 1 do
AdoConnection1.DataSets[i].AfterPost := AfterPost;
AdoQuery1.Open;
AdoQuery2.Open;
end;
procedure TForm1.AfterPost(DataSet: TDataSet);
var
Q : TAdoQuery;
begin
if DataSet is TAdoQuery then begin
Q := TAdoQuery(DataSet);
Caption := IntToStr(Q.RowsAffected);
end
else
Caption := 'Post';
end;
Bien sûr, si les ensembles de données impliqués ont déjà leurs propres gestionnaires d'événements, vous auriez besoin une certaine structure pour stocker les gestionnaires existants et la chaîne à droite un d'entre eux dans le gestionnaire partagé (fi TForm1.AfterPost au dessus).
Si vous essayez le code ci-dessus et observez ce qui se passe lorsque vous publiez une modification à partir du DBGrid qui reçoit ses données d'un TAdoQuery, vous verrez que, malheureusement, RowsAffected est zéro. En effet, FRowsAffected de TAdoQuery est mis à jour uniquement lorsque sa méthode ExecSql
est appelée et qu'elle n'est pas appelée pour les opérations de jeu de données invoquées via le DBGrid. La différence est que le OnExecuteComplete
d'AdoConnection est appelé à partir de l'objet Command
utilisé pour exécuter ExecSql
de TAdoQuery. Les opérations lancées à partir de DBGrid, otoh, appellent les méthodes de l'objet RecordSet
associé à TAdoCustomDataSet dans ses InternalPost et InternalDelete, et qui n'invoque pas le OnExecuteComplete
d'AdoConnection.
Les objets RecordSet
ont leurs propres ensembles d'événements, voir f.i. RecordSetEvents
dans ADOInt.Pas, et vous pouvez concevoir des gestionnaires d'événements partagés pour de manière similaire à l'exemple d'événement AfterPost
partagé ci-dessus. Cependant, Je ne pense pas que cela ferait quelque chose d'utile pour vous si vous voulez obtenir la valeur RowsAffected pour un TDataset Insert/Update/Delete invoqué du DBGrid (ou, disons un TDBNavigator connecté à son TDataSource).
La raison pour laquelle je dis que c'est que si vous jetez un coup d'oeil au code source pour la méthode InternalPost
du TAdoCustomDataSet
vous verrez qu'il comprend
if State = dsEdit then
UpdateData
else
begin
Recordset.AddNew(EmptyParam, EmptyParam);
try
UpdateData;
except
et le UpdateData
imbriquée fait ses choses par appeler
Recordset.Update(EmptyParam, EmptyParam);
Maintenant, si vous regardez la documentation MS pour RecordSet.Update, vous verrez par exemple
https://msdn.microsoft.com/en-us/library/ecc2bf09.aspx?f=255&MSPPError=-2147217396
qui stipule clairement que si Update
n'affecte pas exactement un enregistrement, une exception est soulevée. J'imagine que c'est ce que @KenWhite avait en tête quand il a dit "Il n'y aura qu'un seul enregistrement mis à jour". Donc, si RecordSet.Update réussit, vous savez qu'une seule ligne a été affectée.
Je n'ai pas vérifié, mais depuis TAdoCustomDataSet.InternalDelete
utilise son objet Recordset
pour faire la suppression, similaire serait probablement vrai de cela.
Utilisez l'événement 'AfterPost' de l'objet ADOQuery ou ADOTable attaché au DBGrid. Il n'y aura qu'un seul enregistrement mis à jour, donc vous connaissez le compte à l'avance. –
@KenWhite, le projet contient environ 100 adocations attachées à dbGrids. Je voulais le faire en utilisant la connexion, mais il semble que c'est impossible. – sddk