What am I doing wrong in the code below? Each subsequent fetch from the
cursor seems to load into element 1 of the array.
(There are 42,654 rows to be loaded. Granted, this is an unusually large
number to load, but I'm accessing it by index to build random test data
and loading rows one at a time works great, so I'm not stuck. But I am
curious about this and why I can't get this to work.)
Incidentally, snd-msg is a great replacement for dsply in these
situations--thanks Marco.
After a run of the code below, these are the results:
Allocated default: 100
Allocated after *alloc: 42755
"fetch for 'n' rows" : 42654
Elements before fetch: 0
After First Fetch. Elements: 42654. SQLSTATE: 00000. Allocated: 42755
After Loop Fetch. Elements: 0. SQLSTATE: 02000. Allocated: 42755
Final Elements: 0. Allocated: 42755
If I set rows to fetch to 25,000 these are the results:
Allocated default: 100
Allocated after *alloc: 42755
"fetch for 'n' rows" : 25000
Elements before fetch: 0
After First Fetch. Elements: 25000. SQLSTATE: 00000. Allocated: 42755
After Loop Fetch. Elements: 17654. SQLSTATE: 00000. Allocated: 42755
After Loop Fetch. Elements: 0. SQLSTATE: 02000. Allocated: 42755
Final Elements: 0. Allocated: 42755
This is the demo code:
**free
ctl-opt Option(*nounref: *nodebugio: *srcstmt);
dcl-c SQLSUCCESS '00000';
dcl-c SQLNOMOREDATA '02000';
dcl-ds csz_a dim(*auto : 50000) qualified;
zip int(10);
end-ds;
dcl-s cszCount int(10);
exec sql set option closqlcsr=*endmod;
exec sql declare csz_cur cursor for
select zip
from lennons1.csz where length(trim(city)) <= 20;
// Allocate enough memory/elements
exec sql select count(*) into :cszCount
from lennons1.csz where length(trim(city)) <= 20;
snd-msg ('Allocated default: ' + %char(%elem(csz_a : *alloc)));
%elem(csz_a : *alloc) = cszCount + 1;
snd-msg ('Allocated after *alloc: ' + %char(%elem(csz_a : *alloc)));
// cszCount = 25000; // pick a number, e.g. 25,000
snd-msg ('"fetch for ''n'' rows" : ' + %char(cszCount));
snd-msg ('Elements before fetch: ' + %char(%elem(csz_a)));
exec sql open csz_cur;
exec sql fetch from csz_cur for :cszCount rows into :csz_a;
snd-msg ('After First Fetch. Elements: ' + %char(%elem(csz_a))
+ '. SQLSTATE: ' +SQLSTATE+ '. Allocated: '
+%char(%elem(csz_a : *alloc)));
dow sqlstate <> SQLNOMOREDATA;
exec sql fetch next from csz_cur for :cszCount rows into :csz_a;
Snd-msg ('After Loop Fetch. Elements: ' + %char(%elem(csz_a))
+ '. SQLSTATE: ' +SQLSTATE
+ '. Allocated: ' + %char(%elem(csz_a : *alloc)));
enddo;
snd-msg ('Final Elements: ' + %char(%elem(csz_a)) + '. Allocated: '
+%char(%elem(csz_a : *alloc)));
return;
On 2/14/2024 1:41 PM, Marco Facchinetti wrote:
V7R5:
Dcl-Ds wIn qualified dim(*auto:60000);
Code char(6);
State char(1);
End-Ds;
Dcl-s Limits date dim(3);
Dcl-s wD date;
Dcl-s i int(10) inz(0);
Dcl-s MaxRec int(10) inz(0);
Dcl-s MaxEle int(10) inz(0);
EXEC SQL SET OPTION COMMIT = *NONE;
Limits(1) = d'2000-01-01';
Limits(2) = d'2005-01-01';
Limits(3) = d'2010-01-01';
MaxEle = %elem(wIn:*max);
for i = 1 to %elem(Limits);
wD = Limits(i);
EXEC SQL DECLARE C1 INSENSITIVE SCROLL CURSOR FOR
Select usrcode, userstate
From myfile
Where activesince < :wD;
EXEC SQL OPEN C1;
EXEC SQL GET DIAGNOSTICS :MaxRec = DB2_NUMBER_ROWS;
EXEC SQL FETCH C1 FOR :MaxEle ROWS INTO :wIn;
snd-msg 'Sqlcod: ' + %char(sqlcod)
+ ' Elem: ' + %char(%elem(wIn))
+ ' Rec: ' + %char(MaxRec)
%target(*caller:1);
EXEC SQL CLOSE C1;
EndFor;
*inlr = *on;
return;
Returns:
Sqlcod: 0 Elem: 27818 Rec: 27818
Sqlcod: 0 Elem: 39214 Rec: 39214
Sqlcod: 0 Elem: 53736 Rec: 53736
And it's correct.
HTH
--
Marco Facchinetti
As an Amazon Associate we earn from qualifying purchases.