Я не думаю, что есть способ получить количество строк, затронутых при обновлении, вставляет и удаляет через TDBgrid или другие компоненты, поддерживающие DB, такие как TDBNavigator. Причина в том, что элементы управления, поддерживающие DB, вызывают методы Post и Delete TDataSet, а эти вызовы переопределяют InternalPost и InternalDelete в TAdoCustomDataSet. Они работают принципиально иначе, чем выполнение инструкции SQL с помощью метода ExecSql, скажем, TAdoQuery.
По дизайну TDataSet.Post и TDataSet.Delete должны влиять только на одну строку, поэтому, если операция завершается успешно, вы знаете, что была затронута только одна строка.
Стоит отметить, хотя и не очень поможет за то, что вы хотите сделать, что это способ прикрепить один и тот же обработчик события к числу из TAdoCustomDataSet потомков, которые разделяют TADOConnection, как показано в следующем коде:
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;
конечно, если наборы данные, участвующие уже имеют свои собственные обработчик событий, вам потребуется какая-то структура для хранения существующих обработчиков и цепи права одного из них в общем обработчике (фи TForm1.AfterPost выше).
Если вы попробуете приведенный выше код и наблюдаете, что происходит, когда вы публикуете редактирование из DBGrid, который получает данные из TAdoQuery, вы увидите, что, к сожалению, RowsAffected равен нулю. Это потому, что TAdoQuery's FRowsAffected обновляется только тогда, когда вызывается его метод ExecSql
, и он не получает вызовы для операций набора данных , вызываемых через DBGrid. Разница заключается в том, что OnExecuteComplete
AdoConnection вызывается из объекта Command
, используемого для выполнения TAdoQuery's ExecSql
. Операции, инициированные с помощью DBGrid, otoh, вызывают методы объекта RecordSet
, связанного с TAdoCustomDataSet, в его InternalPost и InternalDelete, и не вызывают OnExecuteComplete
AdoConnection.
Объекты RecordSet
имеют свои собственные наборы событий, см. F.i. RecordSetEvents
в ADOInt.Pas, и, возможно, вы могли бы настроить общие обработчики событий для тем же способом, что и общий пример события AfterPost
выше. Тем не менее, Я не думаю, что это сделало бы что-нибудь полезное для вас, если вы хотите получить значение RowsAffected для TDataset. Вставить/Обновить/Удалить, вызванное из DB123 (или, скажем, TDBNavigator, подключенного к его TDataSource).
Поэтому я говорю, что это то, что если вы посмотрите на исходный код для метода в TAdoCustomDataSet
InternalPost
вы увидите, что она включает в себя
if State = dsEdit then
UpdateData
else
begin
Recordset.AddNew(EmptyParam, EmptyParam);
try
UpdateData;
except
и вложенная UpdateData
делает свои вещи на вызывая
Recordset.Update(EmptyParam, EmptyParam);
Теперь, если вы посмотрите на документации MS для RecordSet.Update, вы увидите, например,
https://msdn.microsoft.com/en-us/library/ecc2bf09.aspx?f=255&MSPPError=-2147217396
в котором четко говорится, что если Update
не влияет на ровно одну запись, исключение. Я думаю, это то, о чем говорил @KenWhite, когда он сказал «Будет обновлена только одна запись». Поэтому, если RecordSet.Update успешно завершен, вы знаете, что затронута только одна строка.
Я не проверял, но так как TAdoCustomDataSet.InternalDelete
использует свой объект для удаления, аналогичный, вероятно, будет прав.
Используйте событие AfterPost для ADOQuery или ADOTable, которое подключено к DBGrid. Будет обновлена только одна запись, поэтому вы знаете счет заранее. –
@KenWhite, проект содержит около 100 adoquery, прикрепленных к dbGrids. я хотел сделать это, используя соединение, но это швы невозможно. – sddk