Read in dynamic sequence

Can someone please clarify the internal workings of the READ #file DYNAMIC #direction STARTING FROM #key statement.

To summarise my issue, I need to extract and print interest rates from a file over a specific period (start and end date Eg 01 Jan 2009 - 31 Dec 2009). Whenever the interest rate changes, a new record is added to the file. The date the interest rate changes is the descriptor in YYYYMMDD -format (N8).

I setup the key with the period start date ‘20090101’ and #direction variable to ‘D’. The first read finds the interest rate effective on the start date (actual date was 20081115). I then change direction to ‘A’, fluff around and then drop thru to the END-READ. However the next READ exits the loop as its reads past the STARTING FROM #key value. (Next rate change was 20090205.)

I would have though that the READ should continue to the end of file or I explicitly executed an ESCAPE BOTTOM after reading past the period end date.

I know the problem can be solved using WITH REPOSITION and ESCAPE TOP REPOSITION or with READ #file VARIABLE and multiple loops, but I really want to know why the READ #file DYNAMIC exits after changing direction and reading past the start key. Is this they way it’s supposed to work?

Let me know if you require any additional information or a sample file and code.

Thanks.

This behavior is implied by Adabas. The first call establishes a “boundary” as of your STARTING FROM value that you cannot pass. You can reproduce this behavior using Natural’s ADACALL utility.

Thanks for the reply Rainer.

However it sort of defeats the purpose of the READ IN DYNAMIC SEQUENCE if Adabas uses the starting value as a boundary and doesn’t let you cross it. It must have been designed for a different purpose to how I tried to use it.

Regards.

Hi Colin,

I would like to look at the sample file and code if you are ok.

Colin,

maybe someone in the Adabas forum or Adabas support can shed more light on this.

Colin,

The reason for this is that your construct of the READ statement being all records logically by a superdescriptor starting from a certain value and up (unbounded on the upper end) constitues a record set. When you reach your starting value coming back down, you have left your defined record set and the loop escapes (effectively like a READ descending starting from the top and ending at your given start value).

What you really want to do instead is construct your read as a completely unbounded record set (no starting from or ending at clause) and then take advantage of the REPOSITION logic.

I am providing an example below of how you can do what you effectively want to do (read past the point you started from on the way back down):

DEFINE DATA LOCAL
1 CM VIEW OF CUST-MASTER
2 VISTA-CUST-NUM
2 VISTA-CUST-NAME
1 #CUST-START(A6)
1 #COUNT(P2)
1 #SEQ(A1) INIT<‘A’>
END-DEFINE
*
#CUST-START := ‘023456’
*
READ CM WITH REPOSITION IN DYNAMIC #SEQ SEQUENCE BY VISTA-CUST-NUM
= #CUST-START
ADD 1 TO #COUNT
IF #COUNT = 10
IF #SEQ = ‘A’
#SEQ := ‘D’
#CUST-START := VISTA-CUST-NUM
ESCAPE TOP REPOSITION
END-IF
END-IF
DISPLAY VISTA-CUST-NUM VISTA-CUST-NAME #SEQ
END-READ
END

You can see how I have defined the whole file as the record set, so there is no loop ending condition besides reaching the 1st logical record or the last.

Hope this helps!

Hi Ats, Rainer and Brian

Below is a simplified version of the file and my code.
The task is to print the interest rate changes for a nominated period (Eg. 01Jan2009 to 31Dec2009).

RATES-FILE (Interest Rates)
EFF-DATE(N8) RATE(P3.4)
20080912 6.8
20081115 7.2
20090205 6.8
20090405 6.4
20090812 6.3
20091214 6.2
20100201 6.4

DEFINE DATA LOCAL
1 INT-RATE VIEW OF RATES-FILE
2 EFF-DATE
2 RATE
*
1 #START-DATE(N8)
1 #END-DATE(N8)
1 #DIRECTION(A1)
END-DEFINE
*
MOVE 20090101 TO #START-DATE
MOVE 20091231 TO #END-DATE
MOVE ‘D’ TO #DIRECTION
*
READ INT-RATE DYNAMIC DIRECTION BY EFF-DATE STARTING FROM #START-DATE
IF #DIRECTION = ‘A’ AND
EFF-DATE > #END-DATE
ESCAPE BOTTOM
END-IF
IF #DIRECTION = ‘D’
MOVE ‘A’ TO #DIRECTION
WRITE #START-DATE RATE
ELSE
WRITE EFF-DATE RATE
END-IF
END-READ
END

Expected Output.
20090101 7.2
20090405 6.4
20090812 6.3
20091214 6.2

Actual Output
20090101 7.2

I ended up coding a READ VARIABLE statement in a FOR loop, which gives the requried output. Viz.

DEFINE DATA LOCAL
1 INT-RATE VIEW OF RATES-FILE
2 EFF-DATE
2 RATE
*
1 #START-DATE(N8)
1 #END-DATE(N8)
1 #DIRECTION(A1)
1 #J(I1)
END-DEFINE
*
MOVE 20090101 TO #START-DATE
MOVE 20091231 TO #END-DATE
MOVE ‘D’ TO #DIRECTION
*
FOR #J = 1 TO 2
READ INT-RATE VARIABLE DIRECTION BY EFF-DATE STARTING FROM #START-DATE
IF #DIRECTION = ‘D’
WRITE #START-DATE RATE
MOVE ‘A’ TO #DIRECTION
ESCAPE BOTTOM
ELSE
IF EFF-DATE > #END-DATE
ESCAPE BOTTOM
END-IF
WRITE EFF-DATE RATE
END-IF
END-READ
END-FOR
END

As I said it’s a simplified version, and doesn’t allow for a rate being changed on the period start date, or a rate not being present on the first read.

Brian, I can see from your example (thanks) how the WITH REPOSITION and the ESCAPE TOP REPOSITION jumps over the boundary to solve the problem. I’ve only previously used the WITH REPOSITION for a dynamic change of key value, not direction.

My original request was why ADABAS “remembers” the start position, and doesn’t let you cross it without additional coding.

My assumed logic was a bit like the programme editor. If your first command is to SCAN forward for END-DEFINE, it doesn’t then stop you using PF7 to check the DATA AREAS. Since you control the direction for each read, there is really no reason to set a boundary at all.

Thanks everyone for your input to this. I just wish I was getting wiser a lot faster than I’m getting older!

Does anyone have a simple but real life example of coding the READ IN DYNAMIC SEQUENCE where it is important to exit the loop when trying to cross the start record?

Thanks and regards,