При работе с компонентом TADOQuery в Delphi при выполнении SQL-запроса типа UPDATE может возникнуть ситуация, когда свойство RowsAffected всегда возвращает -1. В документации указано, что значение -1 указывает на ошибку в запросе, однако запрос выполняется корректно, и изменения в базе данных производятся. Даже использование инструкции SET NOCOUNT OFF не приводит к изменению поведения.
Описание проблемы
Разработчик столкнулся с проблемой, при которой после выполнения SQL-запроса на обновление данных с использованием компонента TADOQuery в среде разработки Delphi, свойство RowsAffected возвращает -1. Это указывает на ошибку, согласно документации, но поскольку обновление данных происходит корректно, предполагается, что проблема кроется в настройках компонента. Пример кода, используемого разработчиком, представлен ниже:
var
adoUpdateQuery: TADOQuery;
blnUpdatedOK: Boolean;
begin
adoUpdateQuery := TADOQuery.Create(nil);
adoUpdateQuery.DisableControls;
adoUpdateQuery.Connection := adcMiddleTierDB;
adoUpdateQuery.ExecuteOptions := [eoExecuteNoRecords];
adoUpdateQuery.SQL.Text := 'UPDATE MyTable SET Status = 1 WHERE Status = 0';
try
adoUpdateQuery.ExecSQL;
blnUpdatedOK := (adoUpdateQuery.RowsAffected > 0);
// Остальная часть кода
end;
Разработчик использует Delphi XE2 и подключается к базе данных MS SQL Server 2008R2.
Возможные решения
Проверка настройки eoExecuteNoRecords: В комментариях было предложено проверить, не влияет ли настройка eoExecuteNoRecords на поведение свойства RowsAffected. По документации, если эта опция указана, провайдер не возвращает информацию об успехе выполнения запроса.
Использование TADOCommand: Альтернативным решением может быть использование компонента TADOCommand с передачей параметра для сохранения количества затронутых строк:
var
AffectedRows: Integer;
begin
adoUpdateCommand.Execute(AffectedRows, EmptyParam);
end;
Разделение запросов: Разработчик обнаружил, что проблема заключается в том, что в одном запросе сначала меняется база данных, а затем выполняется обновление. Использование команды USE в том же запросе, что и обновление, приводит к тому, что свойство RowsAffected не работает. Решение заключается в выполнении запроса на смену базы данных отдельно:
try
// Необходимо изменить базу данных в отдельном SQL-запросе, чтобы RowsAffected работал
adoUpdateQuery.SQL.Text := 'USE MyDatabase;';
adoUpdateQuery.ExecSQL;
adoUpdateQuery.SQL.Text := 'UPDATE MyTable SET Status = 1 WHERE Status = 0';
adoUpdateQuery.ExecSQL;
blnUpdatedOK := (adoUpdateQuery.RowsAffected > 0);
end;
Использование нескольких инструкций: Можно объединить инструкции обновления и выборки количества затронутых строк в одном запросе, добавив дополнительную инструкцию SELECT @@rowcount после UPDATE:
adoUpdateQuery.SQL.Add( 'USE MyDatabase;' );
adoUpdateQuery.SQL.Add( 'UPDATE MyTable SET Status = 1 WHERE Status = 0;' );
adoUpdateQuery.SQL.Add( 'SELECT @@rowcount;' );
adoUpdateQuery.Open;
try
LRowCount := adoUpdateQuery.Fields[0].AsInteger;
finally
adoUpdateQuery.Close;
end;
Использование метода ExecSQL: Также стоит отметить, что метод ExecSQL компонента TADOQuery возвращает количество затронутых строк, что позволяет упростить код:
blnUpdatedOK := (adoUpdateQuery.ExecSQL > 0);
Заключение
При работе с компонентом TADOQuery в Delphi важно учитывать, что свойство RowsAffected может не работать корректно в определенных условиях, например, при использовании опции eoExecuteNoRecords или при выполнении нескольких инструкций в одном запросе. Разделение запросов на отдельные операции и использование метода ExecSQL может помочь решить проблему с получением количества затронутых строк после выполнения UPDATE.
Разработчик столкнулся с проблемой в Delphi, где свойство `RowsAffected` TADOQuery возвращает `-1` после корректного выполнения запроса UPDATE, что не соответствует документации.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.