Reputation: 2520
Collegues, I am new in Firebird. I'am trying to call procedure (p_procedure
) in cursor cycle and insert result into table (tmp_port
).
execute block
as
declare contr integer;
declare IN$DT date;
declare cur_list_of_cont cursor for (select first 100 contracts.doc from TABLE_1);
begin
delete from tmp_port;
IN$DT = getdate()-2;
open cur_list_of_cont;
while (ROW_COUNT > 0) do
begin
fetch cur_list_of_cont into contr;
insert into tmp_port (
DT,
....)
select
:IN$DT as DT,
...
from p_procedure (0, :contr , :IN$DT);
if (ROW_COUNT = 0) then leave;
suspend;
end
close cur_list_of_cont;
end;
The problem is that only single, fisrt row processed from cur_list_of_cont. Why other 99 rows are not processed?
UPDATE
FireBird Server version is 2.5
UPDATE
In this realization it works fine:
begin
IN$DT = getdate()-2;
FOR select first 100 contracts.doc from TABLE_1
INTO :contr
DO
BEGIN
insert into tmp_port (
DT,
....)
select
:IN$DT as DT,
...
from p_procedure (0, :contr , :IN$DT);
END
SUSPEND;
end;
It will be better if the first example works too. How to do it?
Upvotes: 3
Views: 2153
Reputation: 109239
The problem is that you are using ROW_COUNT
incorrectly. As documented in the Firebird 2.5 language reference:
Description: The
ROW_COUNT
context variable contains the number of rows affected by the most recent DML statement (INSERT
,UPDATE
,DELETE
,SELECT
orFETCH
) in the current trigger, stored procedure or executable block....
- After a
FETCH
from a cursor,ROW_COUNT
is 1 if a data row was retrieved and 0 otherwise. Fetching more records from the same cursor does not incrementROW_COUNT
beyond 1.
The while (ROW_COUNT > 0)
might be false if nothing was deleted, you might also exit the loop if your procedure returns no rows and therefor nothing was inserted.
If you look at the example of using FETCH
, you can modify your code to:
open cur_list_of_cont;
fetch cur_list_of_cont into contr;
while (row_count > 0) do
begin
insert into tmp_port (
DT,
....)
select
:IN$DT as DT,
...
from p_procedure (0, :contr , :IN$DT);
fetch cur_list_of_cont into contr;
end
close cur_list_of_cont;
However, given your code, you should consider using FOR SELECT
as it is easier in most cases.
Upvotes: 4