Home | The Company | Publications | Products | Links | Tips |
---|
DEFINE DATA LOCAL 01 STUDENT-ENROLLMENT VIEW OF STUDENT-ENROLLMENT-001 02 STDTENRM-TYPE-CD (A1) 02 STDT-WSU-NUM (N9) 02 ACTRM-CY4 (N4) 02 ACTRMTY-CD (N1) 02 STDTENRM-EFCTV-BGN-DATE8 (N8) 02 STDTENRM-EFCTV-END-DATE8 (N8) 02 CLBLK-TYPE-CD (A2) 02 CLBLK-TITLE-CD (A4) 02 ORGNUN-WSU-NUM-ADMNG (N9) 02 CLBLK-CY4 (N4) 02 STDTENRM-KEY-007 * 01 #STDTENRM-KEY-007-S (A27) INIT <'L000232350'> 01 REDEFINE #STDTENRM-KEY-007-S 02 #STDTENRM-TYPE-CD-SS (A1) 02 #ORGNUN-WSU-NUM-ADMNG-SS (N9) 02 #STDT-WSU-NUM-SS (N9) 02 #STDTENRM-EFCTV-BGN-DATE8-SS (N8) * 01 #STDTENRM-KEY-007-E (A27) INIT <'L000232350'> 01 REDEFINE #STDTENRM-KEY-007-E 02 #STDTENRM-TYPE-CD-EE (A1) 02 #ORGNUN-WSU-NUM-ADMNG-EE (N9) 02 #STDT-WSU-NUM-EE (N9) 02 #STDTENRM-EFCTV-BGN-DATE8-EE (N8) * END-DEFINE * MOVE 12345678 TO #STDT-WSU-NUM-EE #STDT-WSU-NUM-SS MOVE 0 TO #STDTENRM-EFCTV-BGN-DATE8-SS MOVE *DATN TO #STDTENRM-EFCTV-BGN-DATE8-EE * * verify the start and end key values are right * * WRITE 'KEYS ARE:' / #STDTENRM-KEY-007-S #STDTENRM-KEY-007-E / / * READ STUDENT-ENROLLMENT IN LOGICAL BY STDTENRM-KEY-007 STARTING FROM #STDTENRM-KEY-007-S THRU #STDTENRM-KEY-007-E * WRITE 'KEY IS: ' STUDENT-ENROLLMENT.STDTENRM-KEY-007 STUDENT-ENROLLMENT.CLBLK-CY4 STUDENT-ENROLLMENT.CLBLK-TITLE-CD END-READ * IF *COUNTER > 0 WRITE 'FOUND' STUDENT-ENROLLMENT.STDTENRM-KEY-007 STUDENT-ENROLLMENT.CLBLK-CY4 STUDENT-ENROLLMENT.CLBLK-TITLE-CD END-IF * ENDAnd here is what I get:
KEYS ARE: L00023235001234567800000000 L00023235001234567819970923 KEY IS: L00023235001234567819970602 1997 SUMM KEY IS: L00023235001234567819970825 1997 FAL1 FOUND L00023235001234567819970602 1997 SUMMThe last line SHOULD be:
FOUND L00023235001026909519970825 1997 FAL1because 19970825 is before the requested end range of 19970923. And in fact it showed the record just fine while within the READ loop, but not outside of the loop, and not if I used AT END OF DATA within the loop.
To make it work properly I removed the THRU caluse and did the test mayself. This is a bit spooky, we use READ FROM/THRU all over the place!!!
Is there a known problem with THRU or ENDING AT with READ on superdescriptors? I searched QUEST and found nothing.
We are running Natural 2.2.7.
This is not a problem or a bug or an error. As you probably know, the READ statement is traversing the inverted list built for that superdescriptor starting at the first value. When the value in the THRU clause is reached or exceeded, the loop is escaped and the record(s) for the associated ISNs for that value are never actually read. Think about the fact that if you didn't have an entry in the inverted list for the THRU value... you wouldn't want to have that/(those) records read for the value you DID come across that exceeded your end value.
Because the THRU value is reached and the loop is escaped, the previous record read is the value that is still contained in your view STUDENT-ENROLLMENT.
Perhaps you could make the #STDT-WSU-NUM-EE value be the next student number and leave #STDTENRM-EFCTV-BGN-DATE8-EE set to zero. Or you could recode the program to use ESCAPE BOTTOM logic to break out of the loop and not use the THRU clause.
Other (unsolicited) recommendations: use (D) format fields for dates instead of alphas or numerics. Also, if you usually need to get to the most current record hronologically, add a date-compliment field (N8 and value equals 99999999 - YYYYMMDD of STDTENRM-EFCTV-BGN-DATE8) that you can use in you superdescriptor(s) in place of STDTENRM-EFCTV-BGN-DATE8. That way you will only have to read one record to get the latest one and not all of them for a given student (or whatever).
Brian Johnson
Cutler-Hammer
Pittsburgh, PA
++++++
Thanks folks, but I still have an Issue here. I obviously didn't make my point.
First let me say I *KNOW* that Natural is doing the checking, not ADABAS, and that it actually reads one more record beyond the THRU value.
Second let me apologize for the misleading output. I was trying to disguise the student's id by over-typing it with 12345678. And I missed replacing it on the last line, where I said "IT SHOULD BE:...". That typo made it look like what I expected was greater than my requested ending value, when in fact it was not.
I would like to respond to Skip's point, when he said: The problem you are running into is that NATURAL keeps calling ADABAS for the "next" record until NATURAL gets the first record that is GREATER THAN the THRU value. NATURAL then exits the loop. And, as you found out, the data area has that last record in it.
In fact I never saw values greater than what I asked for in the THRU clause. That is OK. It is as it SHOULD be.
What I saw was that Natural showed me the records I wanted as long as I was within the loop, but when I left the loop and tried looking at the same variables, they were one *behind* where they should be. They showed me the SUMM (SUMMER) session, not the FAL1 (FALL) session.
Here is the range I asked for:
FROM : L 0002323500 12345678 00000000 THRU : L 0002323500 12345678 19970923Here is what I saw from within the loop:
L 0002323500 12345678 19970602 1997 SUMM L 0002323500 12345678 19970825 1997 FAL1So far, so good... but...then...
FOUND L 0002323500 12345678 19970602 1997 SUMMWhat happened to the FAL1 record? It *IS* within the from/thru range. The last time I checked, 19970825 is less than 19970923. And it *was* available all the time I was in the loop! To me that is a bug. Either give it to me or don't!! Don't give it to me and then take it away!
Oh, and Skip, I DON'T WANT the data after the loop. I only what I asked for in the from/thru range. Thanks for the suggestion anyway.
Skip had said:
One solution you could use to get at the data after the loop is to code >something like
the following in the READ loop:
> AT END OF DATA > if key > thru-value >* /* do key check just in case you got to >* /* real EOF before exceeding THRU value > move old(field1) to field1 > .... > move old(fieldn) to fieldn > end-if > END-ENDDATA >- - - - - - - - - - - - - - - - - - - - - - - Darrell Davenport
++++++
After all the comments on this I would ask two more questions.
1) Did you get the same results if you used line reference number of the if *counter > 0 statement?
2) This the last record displayed in the read loop, the last value for the superdescriptor (did it reach end of file)?
Phil Hansens
Database Administrator (DBA)
(517) 636-9480
++++++
It is possible to use read from/thru with a super-d. All you need to do is include the super in your local or define data. Once this is done you can use the true clause.
++++++
Steve wrote:
Strange indeed. As noted by some of the responses, Natural should be 2
records ahead of where you seem to be. Not only should
L 0002323500 12345678 19970825 1997 FAL1have been read, the next record that caused you to escape the READ loop should have been read also.
This would really be strange then since they must have the first non valid value, otherwise you would not have escaped the loop.
Yes, Steve, that is exactly what happened.
The variables were referenced with VIEWNAME.FIELDNAME outside of the
loop and they contained the previous record!
Someone guessed that perhaps the FAL1 record was end-of-file.
So, maybe it never made it to the local data area.
I also wondered about that.
I will try to get some time to check that possibility.
- - - - - - - - - - - - - - - - - - - - - - -
Darrell Davenport
Natural Administrator,
Washington State University.
++++++
Thanks to all for testing that FROM/THRU stuff for me.
Our problem must be somehting to do with an end-of-file condition,
or a corrupted file where associator does not match data.
It seems to be localized to this file and record.
I tried it on other files and it works OK.
It certainly had me going for a while though.
Since this is a test record on a test file,
I don't think I'll persue it too much more... other than asking the
DBA to run some file-verification utilities on it.
Although it is rare, it won't be the first time we had a corrupted file.
- - - - - - - - - - - - - - - - - - - - - - -
Darrell Davenport
Natural Administrator,
Washington State University.
= = = = = =
I was alarmed by Darrell's report, so wrote the following simple program to
test this against the EMPLOYEES file. The result seems to substatiate that
following the read loop, the record greater than the THRU is the one
available within the program -- which makes the data or file Darrell is
dealing with suspect? This was with Natl 2.2.8.
0010 DEFINE DATA LOCAL 0020 1 EV VIEW OF EMPLOYEES 0030 2 NAME 0040 2 DEPT 0050 2 DEPT-PERSON 0060 * 0070 1 SK (2) 0080 2 DEPT (A6) INIT <'COMP21','COMP21'> 0090 2 NAME (A20) INIT <' ',H'FF'> 0100 1 REDEFINE SK 0110 2 #SK (A26/2) 0120 END-DEFINE 0130 * 0140 READ EV BY DEPT-PERSON = #SK(1) THRU #SK(2) 0150 DISPLAY EV.DEPT EV.NAME 0160 END-READ 0170 WRITE EV.DEPT EV.NAME 0180 END 0190 Page 1 DEPARTMENT NAME CODE ---------- -------------------- COMP21 DAMMBACH COMP21 LIST COMP21 MOELLER COMP21 SPAEHT COMP25 GROTHEW. David Wimberly