Question

I'm executing a SQL UPDATE statement using a TADOQuery component and want to inspect the number of rows that were updated. The UPDATE statement is executing fine and the rows are modified accordingly but the .RowsAffected property always returns -1. The documentation states -1 indicates an error with the statement, but as I say it executes fine. I've tried prefixing the statement with SET NOCOUNT OFF but this made no difference. My code is as follows :

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);

I'm using Delphi XE2, connecting to MS SQL Server 2008R2.

Was it helpful?

Solution

Apologies guys, thanks for all your help but I've realised what the problem is. When typing my sample code snippet I failed to include in the SQL that I'm actually changing database as part of the query. The SQL should have shown :

USE MyDatabase; UPDATE MyTable SET Status = 1 WHERE Status = 0

It turns out that the USE command prevents the RowsAffected from working when in the same statement (stops it working in TADOQuery and TADOCommand). I've now fixed the problem by changing my code as follows :

try
  // Need to change database in separate SQL query in order for RowsAffected to work
  adoUpdateQuery.SQL.Text := 'USE MyDatabase;';
  adoUpdateQuery.ExecSQL;
  adoUpdateQuery.SQL.Text := 'UPDATE MyTable SET Status = 1 WHERE Status = 0';
  adoUpdateQuery.ExecSQL;
  blnUpdatedOK := (adoUpdateQuery.RowsAffected > 0);

Thanks

OTHER TIPS

Use a TADOCommand and call it like this:

var
  AffectedRows: Integer;
begin
  adoUpdateCommand.Execute(AffectedRows, EmptyParam);

One possibility is something like this:

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 := adoQuery.Fields[0].AsInteger;
finally
  adoUpdateQuery.Close;
end;

If you have a lot of more statements you can store the RowCounts in a temptable and at the end publish the temptable with a select.

BTW TADOQuery.ExecSQL is a function and returns the number of affected rows. So your code can be more compact

blnUpdatedOK := ( adoUpdateQuery.ExecSQL > 0 );
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top