Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines | New: Database administration forum
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

length and occurs depending on
I have what I believe to be an interesting "problem".  Take the following
variable length group, TS-PAGE-OF-TRANSACTIONS.

05  TS-PAGE-OF-TRANSACTIONS.
07  TS-TRAN-BKPG-CNT  PIC S9(03) COMP SYNC.
07  TS-TRAN-TABLES.
10  TS-TRAN-DTL-LINE
OCCURS 13 TIMES
PIC X(79).
10  TS-TRAN-DESC-LINE   OCCURS 11 TIMES.
15  TS-TRAN-DESC        OCCURS 4 TIMES
PIC X(61).
15  TS-TRAN-BKPG-SUB    OCCURS 4 TIMES
PIC S9(03) COMP.
07  TS-TRAN-BKPG-TABLE.
10  TS-TRAN-BKPG-DESC   OCCURS 0 TO 44 TIMES
DEPENDING ON TS-TRAN-BKPG-CNT
PIC X(61).

The actual variable length table is TS-TRAN-BKPG-TABLE.  The can be zero
through 44 occurances, depending on various things.  I then write the whole
group to a CICS TS queue.  In order to write the minimum size necessary I
set TS-TRAN-BKPG-CNT to the actual number of occurances od
TS-TRAN-BKPG-DESC.  I then use the COBOL "LENGTH OF" operator to calculate
TS-LEN-TRAN.  See the following...

* at this point TS-TRAN-BKPG-CNT will have already been set to some value
between 0 and 44 inclusive
COMPUTE TS-LEN-TRAN = LENGTH OF TS-PAGE-OF-TRANSACTIONS.
EXEC CICS
WRITEQ TS
QUEUE   (TS-QUEUE)
FROM    (TS-PAGE-OF-TRANSACTIONS)
LENGTH  (TS-LEN-TRAN)
END-EXEC.

This all works fine because we know the value of TS-TRAN-BKPG-CNT.

However, when I want to *read* it from the TS queue (this will be a new
pseudo-conversational task, so all previous working-storage will be cleared)
I have to set TS-LEN-TRAN to the *largest* size that TS-PAGE-OF-TRANSACTIONS
could possibly be.  Right now I do this as follows:

* At this point we do not yet know the value of TS-TRAN-BKPG-CNT
* We need to set it to 44 so that TS-LEN-TRAN will be set to the maximum
length that
* TS-PAGE-OF-TRANSACTIONS can possibly be
MOVE 44 TO TS-TRAN-BKPG-CNT.
COMPUTE TS-LEN-TRAN = LENGTH OF TS-PAGE-OF-TRANSACTIONS.
EXEC CICS
READQ TS
QUEUE   (TS-QUEUE)
INTO    (TS-PAGE-OF-TRANSACTIONS)
ITEM    (WS-ITEM)
LENGTH  (TS-LEN-TRAN)
END-EXEC.

I'm trying to figure out if there's anyway I can avoid hard coding the
setting of TS-TRAN-BKPG-CNT to 44.  The following does *not* work:

COMPUTE TS-TRAN-BKPG-CNT =
LENGTH OF TS-TRAN-BKPG-TABLE / LENGTH OF TS-TRAN-BKPG-DESC (1).

This is because TS-TRAN-BKPG-CNT must already be *set* to 44 in order for it
to return a *result* of 44.

Any thoughts?

Thanks,
Frank


---
Frank Swarbrick
Senior Developer/Analyst - Mainframe Applications
FirstBank Data Corporation - Lakewood, CO  USA

Report this thread to moderator Post Follow-up to this message
Old Post
Frank Swarbrick
04-22-05 01:55 AM


Re: length and occurs depending on
"Frank Swarbrick" <Frank.Swarbrick@efirstbank.com> wrote in message
news:3cqhijF6oi4baU1@individual.net...
> I have what I believe to be an interesting "problem".  Take the following
> variable length group, TS-PAGE-OF-TRANSACTIONS.
>
> 05  TS-PAGE-OF-TRANSACTIONS.
>   07  TS-TRAN-BKPG-CNT  PIC S9(03) COMP SYNC.
>   07  TS-TRAN-TABLES.
>     10  TS-TRAN-DTL-LINE
>                         OCCURS 13 TIMES
>                         PIC X(79).
>     10  TS-TRAN-DESC-LINE   OCCURS 11 TIMES.
>         15  TS-TRAN-DESC        OCCURS 4 TIMES
>                         PIC X(61).
>         15  TS-TRAN-BKPG-SUB    OCCURS 4 TIMES
>                         PIC S9(03) COMP.
>   07  TS-TRAN-BKPG-TABLE.
>     10  TS-TRAN-BKPG-DESC   OCCURS 0 TO 44 TIMES
>                           DEPENDING ON TS-TRAN-BKPG-CNT
>                         PIC X(61).
>
> The actual variable length table is TS-TRAN-BKPG-TABLE.  The can be zero
> through 44 occurances, depending on various things.  I then write the
whole
> group to a CICS TS queue.  In order to write the minimum size necessary I
> set TS-TRAN-BKPG-CNT to the actual number of occurances od
> TS-TRAN-BKPG-DESC.  I then use the COBOL "LENGTH OF" operator to calculate
> TS-LEN-TRAN.  See the following...
>
> * at this point TS-TRAN-BKPG-CNT will have already been set to some value
> between 0 and 44 inclusive
> COMPUTE TS-LEN-TRAN = LENGTH OF TS-PAGE-OF-TRANSACTIONS.
> EXEC CICS
>   WRITEQ TS
>     QUEUE   (TS-QUEUE)
>     FROM    (TS-PAGE-OF-TRANSACTIONS)
>     LENGTH  (TS-LEN-TRAN)
> END-EXEC.
>
> This all works fine because we know the value of TS-TRAN-BKPG-CNT.
>
> However, when I want to *read* it from the TS queue (this will be a new
> pseudo-conversational task, so all previous working-storage will be
cleared)
> I have to set TS-LEN-TRAN to the *largest* size that
TS-PAGE-OF-TRANSACTIONS
> could possibly be.  Right now I do this as follows:
>
> * At this point we do not yet know the value of TS-TRAN-BKPG-CNT
> * We need to set it to 44 so that TS-LEN-TRAN will be set to the maximum
> length that
> * TS-PAGE-OF-TRANSACTIONS can possibly be
> MOVE 44 TO TS-TRAN-BKPG-CNT.
> COMPUTE TS-LEN-TRAN = LENGTH OF TS-PAGE-OF-TRANSACTIONS.
> EXEC CICS
>   READQ TS
>     QUEUE   (TS-QUEUE)
>     INTO    (TS-PAGE-OF-TRANSACTIONS)
>     ITEM    (WS-ITEM)
>     LENGTH  (TS-LEN-TRAN)
> END-EXEC.
>
> I'm trying to figure out if there's anyway I can avoid hard coding the
> setting of TS-TRAN-BKPG-CNT to 44.  The following does *not* work:
>
> COMPUTE TS-TRAN-BKPG-CNT =
>   LENGTH OF TS-TRAN-BKPG-TABLE / LENGTH OF TS-TRAN-BKPG-DESC (1).
>
> This is because TS-TRAN-BKPG-CNT must already be *set* to 44 in order for
it
> to return a *result* of 44.
>
> Any thoughts?
>

It is 25 years since I wrote a CICS COBOL Program and in my day we had to
use GETMAIN to allocate the storage before writing the Queue. (Of course, we
were REAL programmers... :-)) I see from your code that this is no longer
required. :-)

I think there is a fundamental misunderstanding here, Frank. The length does
NOT need to be set when you READ.

CICS will set the length into the parameter you specify. (Well, it did when
I used it, but we didn't have INTO - 'into' implies you already have the
storage allocated and should therefore know its length...)

I would have coded:

EXEC CICS
READQ TS
QUEUE   (TS-QUEUE)
SET    (TS-POINTER)
ITEM    (WS-ITEM)
LENGTH  (TS-LEN-TRAN)
END-EXEC.

CICS would have grabbed storage for the area corresponding to TS-POINTER,
read the item on the queue indicated by ITEM, and placed the length of it
into LENGTH

It is then a trivial exercise to calculate the number of occurrences that
are required in your TS-TRAN-BKPG-CNT as:

(TS-LEN-TRAN - fixed part of record) / length of  TS-TRAN-BKPG-DESC

...which is pretty close to what you suggested.

The only fly I can see in this ointment is that INTO doesn't work like that,
and actually requires the length to be in it before the read.

If that is the case, then why not simply define a buffer area of say, 4096
bytes and read into that? Then you can work out how much data you actually
received (I can't believe it doesn't put it into TS-LENGTH, but I don't have
access to the latest CICS stuff), calculate the value for TS-TRAN-BKPG-CNT
as shown, and, once you have set the number of occurrences correctly, MOVE
the record from the data buffer to your record definition.

SUMMARISING:

1. I believe that a CICS READQ will SET the length it gets. (If I am wrong,
and INTO doesn't work like that, then use a fixed length buffer and do the
job that CICS SHOULD have done...calculate the length you actually
received).

2. Once you have the actual data length of the item, you can easily
calculate (and set into the TS-TRAN-BKPG-CNT field), the  the number of
occurrences of your variable data.

No hard coding.

Hope this helps,

Pete.




Report this thread to moderator Post Follow-up to this message
Old Post
Pete Dashwood
04-22-05 01:55 AM


Re: length and occurs depending on

Pete Dashwood wrote:
> "Frank Swarbrick" <Frank.Swarbrick@efirstbank.com> wrote in message
> news:3cqhijF6oi4baU1@individual.net...
> (snip) 
>
> it
> 
>
>
> It is 25 years since I wrote a CICS COBOL Program and in my day we had to
> use GETMAIN to allocate the storage before writing the Queue. (Of course, 
we
> were REAL programmers... :-)) I see from your code that this is no longer
> required. :-)
>
> I think there is a fundamental misunderstanding here, Frank. The length do
es
> NOT need to be set when you READ.

Mr. Dashwood, I beg to differ.

If you are doing a READQ TS with the INTO option the LENGTH field must
be initialized with the maximum length.  Think about it.  The temp
storage queue record might be as big as 32K bytes.  If the queue
record is too big large for the INTO field, how is CICS to know when
to raise the LENGERR condition or EIBRESP value?  How else is the
program supposed to know when the data is truncated?

>
> CICS will set the length into the parameter you specify. (Well, it did whe
n
> I used it, but we didn't have INTO - 'into' implies you already have the
> storage allocated and should therefore know its length...)
>
> I would have coded:
>
> EXEC CICS
>      READQ TS
>      QUEUE   (TS-QUEUE)
>      SET    (TS-POINTER)
>      ITEM    (WS-ITEM)
>      LENGTH  (TS-LEN-TRAN)
> END-EXEC.
>
> CICS would have grabbed storage for the area corresponding to TS-POINTER,
> read the item on the queue indicated by ITEM, and placed the length of it
> into LENGTH.

This is true, of course.  But if you use the SET option you cannot
READQ directly into WORKING-STORAGE.  You must define a pointer for a
LINKAGE SECTION item, GETMAIN it, and establish addressability to it.
You must do the GETMAIN every time the program is re-entered.  And
you still have the possibility of reading a temp storage queue record
larger than your space allocation.

>
> It is then a trivial exercise to calculate the number of occurrences that
> are required in your TS-TRAN-BKPG-CNT as:
>
> (TS-LEN-TRAN - fixed part of record) / length of  TS-TRAN-BKPG-DESC
>
> ...which is pretty close to what you suggested.
>
> The only fly I can see in this ointment is that INTO doesn't work like tha
t,
> and actually requires the length to be in it before the read.

This is true.

>
> If that is the case, then why not simply define a buffer area of say, 4096
> bytes and read into that? Then you can work out how much data you actually
> received (I can't believe it doesn't put it into TS-LENGTH, but I don't ha
ve
> access to the latest CICS stuff), calculate the value for TS-TRAN-BKPG-CNT
> as shown, and, once you have set the number of occurrences correctly, MOVE
> the record from the data buffer to your record definition.

That's certainly one solution that would work.

>
> SUMMARISING:
>
> 1. I believe that a CICS READQ will SET the length it gets. (If I am wrong
,
> and INTO doesn't work like that, then use a fixed length buffer and do the
> job that CICS SHOULD have done...calculate the length you actually
> received).

READQ TS always sets the LENGTH field equal to the length actually
retrieved, whether you use SET or INTO.  But if you use the INTO
option, you must initialize the LENGTH field with the maximum length
of the working-storage field, and you must do it before executing the
READQ command.  If you are using INTO, and the TS Queue record is
longer than the maximum length, you get a LENGERR condition.

That's just the way it works.

>
> 2. Once you have the actual data length of the item, you can easily
> calculate (and set into the TS-TRAN-BKPG-CNT field), the  the number of
> occurrences of your variable data.
>
> No hard coding.

I agree that hard-coding the maximum length is a less desirable
solution, because it makes future changes a little more difficult.  I
do see it done that way quite often, even for fixed-length TS queue
records when it would be quite easy to use LENGTH OF.

It ought to be possible to compute the the maximum length in a way
that simplifies future maintenance, but I can't figure out an easy way
to do it without defining a constant for the maximum number of
occurrences.

Truthfully, the programmers in my shop avoid ODO like the plague, and
given that CICS stands for "Core Is Cheap, Sucker", it's easier to use
a fixed-length queue record.

An interesting problem is how to get rid of those TS Queue MAIN
records when transactions are aborted.  We had to use a CICS TASK Exit
to purge them.  Typically the queue name is the Transaction ID plus
the Terminal ID.  The exit program would build the key and delete any
outstanding TS queues.  Of course, Frank's shop may put all TS Queues
to the VSAM AUX Temp Storage File rather than to MAIN storage, so
memory leaks might not be a problem for him.  At least in the old
days, TS queues in MAIN storage were considerably faster than in AUX.

>
> Hope this helps,
>
> Pete.
>

I calculate the maximum length of the 05 area as 6485 bytes, but
please check my work for errors!  (I apologize for snipping that
portion of the original post).  That's small enough that it could be
passed in a COMMAREA, without using a TS Queue.  Of course, I don't
know if Frank Swarbrick's program already has other data being passed
that would put the COMMAREA over the 32K limit.

Another advantage to using COMMAREA is that it doesn't leave TS Queues
in memory if the transaction abends.  There's less chance of storage
creep that way.

An interesting problem!

--
http://arnold.trembley.home.att.net/


Report this thread to moderator Post Follow-up to this message
Old Post
Arnold Trembley
04-22-05 08:55 AM


Re: length and occurs depending on
Frank (and Arnold and Pete),
I know just enough to be dangerous in this area and I do *NOT* know if the
following CICS (on z/OS) option is available for VSE, but ...

You *might* want to look at the LENGTH translator option - described (for CI
CS
TS V3.1 - for z/OS) at:

[url]http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/dfhp3b00/2.1.5.1.19[/ur
l]


--
Bill Klein
wmklein <at> ix.netcom.com
"Arnold Trembley" <arnold.trembley@worldnet.att.net> wrote in message
news:22%9e.623343$w62.158596@bgtnsc05-news.ops.worldnet.att.net...
>
>
> Pete Dashwood wrote: 
>
> Mr. Dashwood, I beg to differ.
>
> If you are doing a READQ TS with the INTO option the LENGTH field must be
> initialized with the maximum length.  Think about it.  The temp storage qu
eue
> record might be as big as 32K bytes.  If the queue record is too big large
 for
> the INTO field, how is CICS to know when to raise the LENGERR condition or
> EIBRESP value?  How else is the program supposed to know when the data is
> truncated?
> 
>
> This is true, of course.  But if you use the SET option you cannot READQ
> directly into WORKING-STORAGE.  You must define a pointer for a LINKAGE
> SECTION item, GETMAIN it, and establish addressability to it. You must do 
the
> GETMAIN every time the program is re-entered.  And you still have the
> possibility of reading a temp storage queue record larger than your space
> allocation.
> 
>
> This is true.
> 
>
> That's certainly one solution that would work.
> 
>
> READQ TS always sets the LENGTH field equal to the length actually retriev
ed,
> whether you use SET or INTO.  But if you use the INTO option, you must
> initialize the LENGTH field with the maximum length of the working-storage
> field, and you must do it before executing the READQ command.  If you are
> using INTO, and the TS Queue record is longer than the maximum length, you
 get
> a LENGERR condition.
>
> That's just the way it works.
> 
>
> I agree that hard-coding the maximum length is a less desirable solution,
> because it makes future changes a little more difficult.  I do see it done
> that way quite often, even for fixed-length TS queue records when it would
 be
> quite easy to use LENGTH OF.
>
> It ought to be possible to compute the the maximum length in a way that
> simplifies future maintenance, but I can't figure out an easy way to do it
> without defining a constant for the maximum number of occurrences.
>
> Truthfully, the programmers in my shop avoid ODO like the plague, and give
n
> that CICS stands for "Core Is Cheap, Sucker", it's easier to use a
> fixed-length queue record.
>
> An interesting problem is how to get rid of those TS Queue MAIN records wh
en
> transactions are aborted.  We had to use a CICS TASK Exit to purge them.
> Typically the queue name is the Transaction ID plus the Terminal ID.  The 
exit
> program would build the key and delete any outstanding TS queues.  Of cour
se,
> Frank's shop may put all TS Queues to the VSAM AUX Temp Storage File rathe
r
> than to MAIN storage, so memory leaks might not be a problem for him.  At
> least in the old days, TS queues in MAIN storage were considerably faster 
than
> in AUX.
> 
>
> I calculate the maximum length of the 05 area as 6485 bytes, but please ch
eck
> my work for errors!  (I apologize for snipping that portion of the origina
l
> post).  That's small enough that it could be passed in a COMMAREA, without
> using a TS Queue.  Of course, I don't know if Frank Swarbrick's program
> already has other data being passed that would put the COMMAREA over the 3
2K
> limit.
>
> Another advantage to using COMMAREA is that it doesn't leave TS Queues in
> memory if the transaction abends.  There's less chance of storage creep th
at
> way.
>
> An interesting problem!
>
> --
> http://arnold.trembley.home.att.net/
> 



Report this thread to moderator Post Follow-up to this message
Old Post
William M. Klein
04-22-05 08:55 AM


Re: length and occurs depending on
"Arnold Trembley" <arnold.trembley@worldnet.att.net> wrote in message
news:22%9e.623343$w62.158596@bgtnsc05-news.ops.worldnet.att.net...
>
>
> Pete Dashwood wrote: 
for 
to 
course, we 
longer 
does 
>
> Mr. Dashwood, I beg to differ.
>
> If you are doing a READQ TS with the INTO option the LENGTH field must
> be initialized with the maximum length.  Think about it.  The temp
> storage queue record might be as big as 32K bytes.  If the queue
> record is too big large for the INTO field, how is CICS to know when
> to raise the LENGERR condition or EIBRESP value?  How else is the
> program supposed to know when the data is truncated?

Well Arnold, I think this is a case of premature ejaculation on your part.
:-) Why not read the WHOLE response before grabbing a keyboard?

I mentioned that I wasn't sure how INTO might work and I covered both cases
(it requires a length or it doesn't) in my post.

The request was for 'any thoughts'... I posted mine.
> 
when 
TS-POINTER, 
it 
>
> This is true, of course.  But if you use the SET option you cannot
> READQ directly into WORKING-STORAGE.  You must define a pointer for a
> LINKAGE SECTION item, GETMAIN it, and establish addressability to it.
>    You must do the GETMAIN every time the program is re-entered.  And
> you still have the possibility of reading a temp storage queue record
> larger than your space allocation.
>

I realise that and suggested using a buffer big ennough to accommodate it.
So what exactly is your issue? 
that 
that, 
>
> This is true.
> 
4096 
actually 
have 
TS-TRAN-BKPG-CNT 
MOVE 
>
> That's certainly one solution that would work.
> 

Ah, we agree  that these were NOT bad 'thoughts' then... :-)

However, I didn't do a precise calculation on the record length and I see
from your post below (I always read everything before ejaculating :-)) that
you reckon the size to be 6485, so my quick estimate of 4096 is certainly
insufficient... I hereby extend my buffer to 8192 and declare the problem
solved... :-)
 
wrong, 
the 
>
> READQ TS always sets the LENGTH field equal to the length actually
> retrieved, whether you use SET or INTO.  But if you use the INTO
> option, you must initialize the LENGTH field with the maximum length
> of the working-storage field, and you must do it before executing the
> READQ command.  If you are using INTO, and the TS Queue record is
> longer than the maximum length, you get a LENGERR condition.
>
> That's just the way it works.

OK. Fair enough. I believe 8192 is longer than the max length of the record
whose definition was posted. So that should work without problem. (Man! I'm
so glad I don't do this stuff for a living any more... :-))
> 
>
> I agree that hard-coding the maximum length is a less desirable
> solution, because it makes future changes a little more difficult.  I
> do see it done that way quite often, even for fixed-length TS queue
> records when it would be quite easy to use LENGTH OF.
>
> It ought to be possible to compute the the maximum length in a way
> that simplifies future maintenance, but I can't figure out an easy way
> to do it without defining a constant for the maximum number of
> occurrences.

It is described above.

>
> Truthfully, the programmers in my shop avoid ODO like the plague, and
> given that CICS stands for "Core Is Cheap, Sucker", it's easier to use
> a fixed-length queue record.
>

On this, you will hear no dissent from me. I am also on record as stating my
position that ODO is anathema. The overheads it incurs are simply not worth
the storage savings in these days of cheap storage. It is a remnant (like
many things in COBOL) of a bygone era when priorities were different from
the realities we face today.

> An interesting problem is how to get rid of those TS Queue MAIN
> records when transactions are aborted.  We had to use a CICS TASK Exit
> to purge them.  Typically the queue name is the Transaction ID plus
> the Terminal ID.  The exit program would build the key and delete any
> outstanding TS queues.  Of course, Frank's shop may put all TS Queues
> to the VSAM AUX Temp Storage File rather than to MAIN storage, so
> memory leaks might not be a problem for him.  At least in the old
> days, TS queues in MAIN storage were considerably faster than in AUX.
>
Ah, for the Oldene Dayse when a programmer was worth 10 such as we see
now... :-) 
>
> I calculate the maximum length of the 05 area as 6485 bytes, but
> please check my work for errors!  (I apologize for snipping that
> portion of the original post).  That's small enough that it could be
> passed in a COMMAREA, without using a TS Queue.  Of course, I don't
> know if Frank Swarbrick's program already has other data being passed
> that would put the COMMAREA over the 32K limit.
>

Do you not think, Arnold, that if the COMMAREA was viable, Frank, (who is
demonstrably no slouch when it comes to programming) would be using it...?
:-) It seems to me fair to assume from what was posted, that a TS queue is
to be utilised...

> Another advantage to using COMMAREA is that it doesn't leave TS Queues
> in memory if the transaction abends.  There's less chance of storage
> creep that way.

Undoubtedly. However, there are other considerations for using the COMMAREA
that are way beyond the scope of this particular post. And smart system
design should have a task doing garbage collecting if storage is a
consideration. I definitely like the idea of the terminal ID being part of
the storage queue ID, and your description of using TASK EXIT to clear the
garbage would certainly get my vote.
>
> An interesting problem!

I thought it was pretty mundane, actually, but all problems are
'interesting' until you have a solution... :-)

Pete.




Report this thread to moderator Post Follow-up to this message
Old Post
Pete Dashwood
04-22-05 01:55 PM


Re: length and occurs depending on
"William M. Klein" <wmklein@nospam.netcom.com> wrote in message
news:5E%9e.653112$za2.100755@news.easynews.com...
> Frank (and Arnold and Pete),
>   I know just enough to be dangerous in this area and I do *NOT* know if
the
> following CICS (on z/OS) option is available for VSE, but ...
>
> You *might* want to look at the LENGTH translator option - described (for
CICS
> TS V3.1 - for z/OS) at:
>
>
http://publibz.boulder.ibm.com/cgi-...3b00/2.1.5.1.19
>
>

Thanks Bill. Even though I have no intention whatsoever of  EVER coding CICS
(or even COBOL) on a mainframe again, I respect your judgement enough to go
and have a look.

It seems to me (and maybe I missed something here?) that LENGTH will default
if you don't set it. There is no difference therefore between allowing the
default, or moving a fixed maximum (which was part of my recommended
solution) to the field before using a READQ with INTO.

There are two things going on here:

1. The LENGTH parameter to the CICS Command level interface.
2. The length of the WS item which contains an ODO.

I am impressed to see that CICS has moved on since I last used it, but has
retained enough of value to keep it recognisable.

I still think IMS/DC is/was a better TP monitor, and I still think CICS
macro level was better for programmers (I mean REAL programmers...:-)) than
this new fangled command nonsense that removes all need for Assembler
understanding... Harrumph! :-))

Harrumph again!

Pete.




Report this thread to moderator Post Follow-up to this message
Old Post
Pete Dashwood
04-22-05 01:55 PM


Re: length and occurs depending on
Hi Arnold.  Thanks for responding to Pete.  I started to reply, but you
stated things much more clearly than I!

As for using the COMMAREA, it's not possible in this case.  What our program
really does is reads through a customer's transactions for a certain period
(up to an entire month), builds a "page" of transactions (44 transactions
per page) and writes each page to the TS queue.  So there's not just one
ITEM in the TS queue.  For one particular customer if I look at their March
transactions it takes 734 pages.  That's over 32000 transactions!  Yikes.
If only for this customer alone this is the reason I like the variable
length table.  Because, while each transaction has a tran description and
there are four transactions per tran-detail-line (don't expect to understand
this without knowing more about what we're doing here), not every
transaction has a bkpg description.  So, for this one customer, assuming
none of their 32000 transactions has a bkpg description, I'm saving
1,970,056  bytes of TS queue storage (734 * 3801 = 2,789,934) vs (734 * 6485
= 4,759,990).

Currently I am actually doing this without using ODO.  Instead I have a
simply OCCURS 44 times for the TS-TRAN-BKPG-DESC table and I calculate for
the WRITEQ as
COMPUTE TS-LEN-TRAN = LENGTH OF TS-TRAN-TABLES  + (TS-HOLD-TRAN-BKPG-SUB  *
LENGTH OF TS-TRAN-BKPG-DESC)
and I calculate the length for the READQ simply as
MOVE LENGTH OF TS-PAGE-OF-TRANSACTIONS.

This works fine, but I am now doing some changes to add *another* table to
the end of it, again one where not every transaction in the fixed length
part has a corresponding one in the new table.  So I am trying to have to
ODO's.  It seems to work (so far, but I've only tested one situation so
far), but I still have to hard code the 44 when using the following
calculation (on the READQ):
MOVE 44 TO TS-TRAN-BKPG-CNT
TS-TRAN-OTHER-CNT
MOVE LENGTH OF TS-PAGE-OF-TRANSACTIONS TO TS-LEN-TRAN.

(Yes, I actually use a "variable" name set to a value of 44, but anyway...)

Hope this explains why I'm going through all this trouble.  Well, plus is a
fun intellectual exercise!

Oh, and BTW, we *do* delete the TS queue record after the user has exited
the function.  If we didn't we'd run out of room rather quickly!  (I believe
we do use MAIN storage instead of AUX, unless we run out of MAIN.  But I
could be wrong...)

Frank


---
Frank Swarbrick
Senior Developer/Analyst - Mainframe Applications
FirstBank Data Corporation - Lakewood, CO  USA
 


Pete Dashwood wrote:
> "Frank Swarbrick" <Frank.Swarbrick@efirstbank.com> wrote in message
> news:3cqhijF6oi4baU1@individual.net...
> (snip) 
>
> it
> 
>
>
> It is 25 years since I wrote a CICS COBOL Program and in my day we had to
> use GETMAIN to allocate the storage before writing the Queue. (Of course,
we
> were REAL programmers... :-)) I see from your code that this is no longer
> required. :-)
>
> I think there is a fundamental misunderstanding here, Frank. The length
does
> NOT need to be set when you READ.

Mr. Dashwood, I beg to differ.

If you are doing a READQ TS with the INTO option the LENGTH field must
be initialized with the maximum length.  Think about it.  The temp
storage queue record might be as big as 32K bytes.  If the queue
record is too big large for the INTO field, how is CICS to know when
to raise the LENGERR condition or EIBRESP value?  How else is the
program supposed to know when the data is truncated?

>
> CICS will set the length into the parameter you specify. (Well, it did
when
> I used it, but we didn't have INTO - 'into' implies you already have the
> storage allocated and should therefore know its length...)
>
> I would have coded:
>
> EXEC CICS
>      READQ TS
>      QUEUE   (TS-QUEUE)
>      SET    (TS-POINTER)
>      ITEM    (WS-ITEM)
>      LENGTH  (TS-LEN-TRAN)
> END-EXEC.
>
> CICS would have grabbed storage for the area corresponding to TS-POINTER,
> read the item on the queue indicated by ITEM, and placed the length of it
> into LENGTH.

This is true, of course.  But if you use the SET option you cannot
READQ directly into WORKING-STORAGE.  You must define a pointer for a
LINKAGE SECTION item, GETMAIN it, and establish addressability to it.
You must do the GETMAIN every time the program is re-entered.  And
you still have the possibility of reading a temp storage queue record
larger than your space allocation.

>
> It is then a trivial exercise to calculate the number of occurrences that
> are required in your TS-TRAN-BKPG-CNT as:
>
> (TS-LEN-TRAN - fixed part of record) / length of  TS-TRAN-BKPG-DESC
>
> ...which is pretty close to what you suggested.
>
> The only fly I can see in this ointment is that INTO doesn't work like
that,
> and actually requires the length to be in it before the read.

This is true.

>
> If that is the case, then why not simply define a buffer area of say,
4096
> bytes and read into that? Then you can work out how much data you
actually
> received (I can't believe it doesn't put it into TS-LENGTH, but I don't
have
> access to the latest CICS stuff), calculate the value for
TS-TRAN-BKPG-CNT
> as shown, and, once you have set the number of occurrences correctly,
MOVE
> the record from the data buffer to your record definition.

That's certainly one solution that would work.

>
> SUMMARISING:
>
> 1. I believe that a CICS READQ will SET the length it gets. (If I am
wrong,
> and INTO doesn't work like that, then use a fixed length buffer and do
the
> job that CICS SHOULD have done...calculate the length you actually
> received).

READQ TS always sets the LENGTH field equal to the length actually
retrieved, whether you use SET or INTO.  But if you use the INTO
option, you must initialize the LENGTH field with the maximum length
of the working-storage field, and you must do it before executing the
READQ command.  If you are using INTO, and the TS Queue record is
longer than the maximum length, you get a LENGERR condition.

That's just the way it works.

>
> 2. Once you have the actual data length of the item, you can easily
> calculate (and set into the TS-TRAN-BKPG-CNT field), the  the number of
> occurrences of your variable data.
>
> No hard coding.

I agree that hard-coding the maximum length is a less desirable
solution, because it makes future changes a little more difficult.  I
do see it done that way quite often, even for fixed-length TS queue
records when it would be quite easy to use LENGTH OF.

It ought to be possible to compute the the maximum length in a way
that simplifies future maintenance, but I can't figure out an easy way
to do it without defining a constant for the maximum number of
occurrences.

Truthfully, the programmers in my shop avoid ODO like the plague, and
given that CICS stands for "Core Is Cheap, Sucker", it's easier to use
a fixed-length queue record.

An interesting problem is how to get rid of those TS Queue MAIN
records when transactions are aborted.  We had to use a CICS TASK Exit
to purge them.  Typically the queue name is the Transaction ID plus
the Terminal ID.  The exit program would build the key and delete any
outstanding TS queues.  Of course, Frank's shop may put all TS Queues
to the VSAM AUX Temp Storage File rather than to MAIN storage, so
memory leaks might not be a problem for him.  At least in the old
days, TS queues in MAIN storage were considerably faster than in AUX.

>
> Hope this helps,
>
> Pete.
>

I calculate the maximum length of the 05 area as 6485 bytes, but
please check my work for errors!  (I apologize for snipping that
portion of the original post).  That's small enough that it could be
passed in a COMMAREA, without using a TS Queue.  Of course, I don't
know if Frank Swarbrick's program already has other data being passed
that would put the COMMAREA over the 32K limit.

Another advantage to using COMMAREA is that it doesn't leave TS Queues
in memory if the transaction abends.  There's less chance of storage
creep that way.

An interesting problem!

--
http://arnold.trembley.home.att.net/




Report this thread to moderator Post Follow-up to this message
Old Post
Frank Swarbrick
04-22-05 08:55 PM


Re: length and occurs depending on
We do use the LENGTH CICS option, but that would not help in this case.  All
(as far as I know) that the LENGTH option does is uses an implied
LENGTH(LENGTH OF data-area).  Since the "LENGTH OF" still depends on the
value of the ODO variable it (the ODO variable) must still be set to it's
largest value in order for the LENGTH OF operation to return the maximum
size of the entire group.

Thanks,
Frank

---
Frank Swarbrick
Senior Developer/Analyst - Mainframe Applications
FirstBank Data Corporation - Lakewood, CO  USA
 
Frank (and Arnold and Pete),
I know just enough to be dangerous in this area and I do *NOT* know if the

following CICS (on z/OS) option is available for VSE, but ...

You *might* want to look at the LENGTH translator option - described (for
CICS
TS V3.1 - for z/OS) at:


http://publibz.boulder.ibm.com/cgi-...hp3b00/2.1.5.1.
19


--
Bill Klein
wmklein <at> ix.netcom.com
"Arnold Trembley" <arnold.trembley@worldnet.att.net> wrote in message
news:22%9e.623343$w62.158596@bgtnsc05-news.ops.worldnet.att.net...
>
>
> Pete Dashwood wrote: 
for 
to 
we 
longer 
does 
>
> Mr. Dashwood, I beg to differ.
>
> If you are doing a READQ TS with the INTO option the LENGTH field must be

> initialized with the maximum length.  Think about it.  The temp storage
queue
> record might be as big as 32K bytes.  If the queue record is too big large
for
> the INTO field, how is CICS to know when to raise the LENGERR condition or

> EIBRESP value?  How else is the program supposed to know when the data is

> truncated?
> 
when 
TS-POINTER, 
it 
>
> This is true, of course.  But if you use the SET option you cannot READQ
> directly into WORKING-STORAGE.  You must define a pointer for a LINKAGE
> SECTION item, GETMAIN it, and establish addressability to it. You must do
the
> GETMAIN every time the program is re-entered.  And you still have the
> possibility of reading a temp storage queue record larger than your space

> allocation.
> 
that 
that, 
>
> This is true.
> 
4096 
actually 
have 
TS-TRAN-BKPG-CNT 
MOVE 
>
> That's certainly one solution that would work.
> 
wrong, 
the 
>
> READQ TS always sets the LENGTH field equal to the length actually
retrieved,
> whether you use SET or INTO.  But if you use the INTO option, you must
> initialize the LENGTH field with the maximum length of the working-storage

> field, and you must do it before executing the READQ command.  If you are

> using INTO, and the TS Queue record is longer than the maximum length, you
get
> a LENGERR condition.
>
> That's just the way it works.
> 
>
> I agree that hard-coding the maximum length is a less desirable solution,

> because it makes future changes a little more difficult.  I do see it done

> that way quite often, even for fixed-length TS queue records when it would
be
> quite easy to use LENGTH OF.
>
> It ought to be possible to compute the the maximum length in a way that
> simplifies future maintenance, but I can't figure out an easy way to do it

> without defining a constant for the maximum number of occurrences.
>
> Truthfully, the programmers in my shop avoid ODO like the plague, and
given
> that CICS stands for "Core Is Cheap, Sucker", it's easier to use a
> fixed-length queue record.
>
> An interesting problem is how to get rid of those TS Queue MAIN records
when
> transactions are aborted.  We had to use a CICS TASK Exit to purge them.
> Typically the queue name is the Transaction ID plus the Terminal ID.  The
exit
> program would build the key and delete any outstanding TS queues.  Of
course,
> Frank's shop may put all TS Queues to the VSAM AUX Temp Storage File
rather
> than to MAIN storage, so memory leaks might not be a problem for him.  At

> least in the old days, TS queues in MAIN storage were considerably faster
than
> in AUX.
> 
>
> I calculate the maximum length of the 05 area as 6485 bytes, but please
check
> my work for errors!  (I apologize for snipping that portion of the
original
> post).  That's small enough that it could be passed in a COMMAREA, without

> using a TS Queue.  Of course, I don't know if Frank Swarbrick's program
> already has other data being passed that would put the COMMAREA over the
32K
> limit.
>
> Another advantage to using COMMAREA is that it doesn't leave TS Queues in

> memory if the transaction abends.  There's less chance of storage creep
that
> way.
>
> An interesting problem!
>
> --
> http://arnold.trembley.home.att.net/
>





Report this thread to moderator Post Follow-up to this message
Old Post
Frank Swarbrick
04-22-05 08:55 PM


Re: length and occurs depending on
> It seems to me (and maybe I missed something here?) that LENGTH will
default
> if you don't set it.

How does it tell the difference ?

It is set to zero or -1 before your program runs ?


Report this thread to moderator Post Follow-up to this message
Old Post
Richard
04-23-05 01:55 AM


Re: length and occurs depending on
"Frank Swarbrick" <Frank.Swarbrick@efirstbank.com> wrote in message
news:3csk8tF6o7phlU1@individual.net...
> Hi Arnold.  Thanks for responding to Pete.  I started to reply, but you
> stated things much more clearly than I!
>
> As for using the COMMAREA, it's not possible in this case.  What our
program
> really does is reads through a customer's transactions for a certain
period
> (up to an entire month), builds a "page" of transactions (44 transactions
> per page) and writes each page to the TS queue.  So there's not just one
> ITEM in the TS queue.  For one particular customer if I look at their
March
> transactions it takes 734 pages.  That's over 32000 transactions!  Yikes.
> If only for this customer alone this is the reason I like the variable
> length table.  Because, while each transaction has a tran description and
> there are four transactions per tran-detail-line (don't expect to
understand
> this without knowing more about what we're doing here), not every
> transaction has a bkpg description.  So, for this one customer, assuming
> none of their 32000 transactions has a bkpg description, I'm saving
> 1,970,056  bytes of TS queue storage (734 * 3801 = 2,789,934) vs (734 *
6485
> = 4,759,990).
>
See comment on NODEs below...

> Currently I am actually doing this without using ODO.  Instead I have a
> simply OCCURS 44 times for the TS-TRAN-BKPG-DESC table and I calculate for
> the WRITEQ as
> COMPUTE TS-LEN-TRAN = LENGTH OF TS-TRAN-TABLES  + (TS-HOLD-TRAN-BKPG-SUB
*
> LENGTH OF TS-TRAN-BKPG-DESC)
> and I calculate the length for the READQ simply as
> MOVE LENGTH OF TS-PAGE-OF-TRANSACTIONS.
>
> This works fine, but I am now doing some changes to add *another* table to
> the end of it, again one where not every transaction in the fixed length
> part has a corresponding one in the new table.  So I am trying to have to
> ODO's.  It seems to work (so far, but I've only tested one situation so
> far), but I still have to hard code the 44 when using the following
> calculation (on the READQ):
> MOVE 44 TO TS-TRAN-BKPG-CNT
>                      TS-TRAN-OTHER-CNT
> MOVE LENGTH OF TS-PAGE-OF-TRANSACTIONS TO TS-LEN-TRAN.
>
> (Yes, I actually use a "variable" name set to a value of 44, but
anyway...)
>
> Hope this explains why I'm going through all this trouble.  Well, plus is
a
> fun intellectual exercise!
>
> Oh, and BTW, we *do* delete the TS queue record after the user has exited
> the function.  If we didn't we'd run out of room rather quickly!  (I
believe
> we do use MAIN storage instead of AUX, unless we run out of MAIN.  But I
> could be wrong...)
>
> Frank
>

The use of OCCURS and ODO is simply redundant in modern data procesing. The
removal of repeating groups is fundamental to RDB normalization. Whether you
implement the data structure into an RDB or not,  the process of
normalization is 'good' for data. Variable length data should be stored in
collections. Where you put the collection (memory or disk) can be determined
by an attribute of the collection.

This is an application where the use of an OO Collection would be ideal, and
simple. There is a class called NODE that is a collection capable of
maintaining itself (it is ideal for building tree views, as nodes can have
nodes attached) and a single level node would solve this problem elegantly.
(You could also organise a collection of nodes where each node was a
'page'...)Any number of 'lines' can be added to each node, and paging them
back is trivial. The class supports trees or simple flat structures.

IF OO was in use, someone would have written (or should have...) a Class
that would implement nodes into the TS Queue. (That would be a one time
solution of this problem and would work in all future cases, eliminating ODO
altogether...)

Looking at this I can see why the COBOL approach is losing ground. Compared
to modern alternatives it is just clumsy and unwieldy.

I understand that people have to solve things within the constraints of the
environment in which they work.

I wouldn't mind a dollar for every time I wished the environment I was
working in was better...

But then, if wishese were horses, beggars would ride...:-)

Pete.
<snip>




Report this thread to moderator Post Follow-up to this message
Old Post
Pete Dashwood
04-23-05 08:55 AM


Sponsored Links




Last Thread Next Thread Next
Pages (3): [1] 2 3 »
Search this forum -> 
Post New Thread

Cobol archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 04:39 AM.

 
Free MCSE Braindumps | Real Estate Topics

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.