I do this in Delphi with FireDAC on Firebird:
with TFDQuery.Create do
try
...
SQL.Text := 'INSERT INTO t(c1) SELECT c2 FROM t2 WHERE c2 = 0';
ExecSQL;
WriteLn(RowsAffected);
finally
Free;
end;
Why does .RowsAffected
return 1
even when no records are inserted (when SELECT
wouldn't match any row)?
I do this in Delphi with FireDAC on Firebird:
with TFDQuery.Create do
try
...
SQL.Text := 'INSERT INTO t(c1) SELECT c2 FROM t2 WHERE c2 = 0';
ExecSQL;
WriteLn(RowsAffected);
finally
Free;
end;
Why does .RowsAffected
return 1
even when no records are inserted (when SELECT
wouldn't match any row)?
1 Answer
Reset to default 0Change your ExecSQL to an Open
Open('INSERT INTO T2 (C2) SELECT C1 FROM T1 WHERE C1=0 RETURNING 1');
OK, it's a trick but now you can check that RowsAffected and RecordCount are equal
showmessage(Format('rows affected %d, rows inserted %d',[FDQuery1.RowsAffected,FDQUery1.RecordCount]));
tested with Firebird 5 perhaps older versions (<4) don't accept this.
Why always>=1 ? should be a good question for @dmitry arefiev
For fb<=4 what about
function InsertCount(Q : TFDQuery) : integer;
begin
Try
Q.ExecSQL('INSERT INTO T2 (C2) SELECT C1 FROM T1 WHERE C1=0');
Q.Open('SELECT COUNT(1) FROM T1 WHERE C1=0');
Result:=Q.Field[0].asInteger;
Except
Result:=0;
End;
end;
SET COUNT;
and then executing the statement. Maybe Firedac does a shortcut and always reports 1 for an insert (i.e. they only consideredINSERT ... VALUES ...
which always produces one row (or an error), and notINSERT ... SELECT ...
which can produce 0 or more rows). – Mark Rotteveel Commented Mar 15 at 10:06