For Programmers: Free Programming Magazines  


Home > Archive > Cobol > February 2006 > embedded SQL in COBOL









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author embedded SQL in COBOL
Frank Swarbrick

2006-02-13, 9:55 pm

Greetings.

We are considering (or I should say "we are considering considering")
utilizing DB2 for some of our mainframe data. Currently we use DL/I
databases and VSAM files. I know that there are many advantages to using a
relational database. I have a few questions about what I perceive as being
possible divantages.

We currently have a database record type that has almost 400 unique fields
in it. Whenever we have a program that accesses that record type we simply
read it in to a COBOL group data item. We then use as many of the fields as
are required by the business rules to be performed, and then (assuming we
want to update the record) we write back the COBOL group data item.

So if we were to move this record in to a relational database table what
would we want to consider when it comes to data access. I'm guessing that
we could, assuming we kept the data in the same order, say something like

EXEC SQL
SELECT *
INTO :my-record
FROM MYTABLE
WHERE MYACCT = :my-acct
END-EXEC

That's pretty simple. We could then update it using

EXEC SQL
UPDATE MYTABLE
SET * = :my-record
WHERE MYACCT = :my-acct
END-EXEC

Acutally, I'm not sure that my "SET" phrase is even allowed. If it isn't,
then how might I specify what I am attempting?

In any case, the above might be efficient if my program was dealing with
most of the fields. I can't imagine specifying 200 different fields in the
SELECT and INTO clauses. But where do you draw that line? Obviously if you
just care about a few fields you just SELECT those few. Do you still
utilize the same COBOL group data item (copybook)? Do you just define the
few you're interested, within the SQL DECLARE SECTION? If you do the latter
then I worry that every programmer will use a different COBOL data name for
each field.

When you want to update the record (row) do you, again, specify ever field
that you (may have) update? Or do you just basically "update all"? And if
you do that, specifically when the database is a remote database, does all
of the data get transmitted back to the database? Or does the "client" keep
track and know that this field and this field and this field haven't
changed, so it does not send those fields back to get updated?

Am I just worrying myself over nothing?

What about fields that allow NULL values? From what I've read, and I may
not be interpretting it correctly, you have to specify an "indicator
variable" for each NULLABLE field that you are selecting on. Does this
cause pain when coding? Does it make sense just to go ahead and declare
every field NON NULLABLE?

As you may be able to tell, I am getting all of my information from books
and manuals. (Speaking of which, can anyone recommend some good books?) I
don't have DB2 at work where I can play with it. I do have it at home (DB2
Express-C -- it's free!), but I don't have a COBOL compiler at home. So I
really can't test anything out, COBOL-wise, at the moment.

Anyway, I have more concerns, but I'll get to them at a later time.

Thanks for any help.
Frank


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

2006-02-14, 7:55 am

Frank Swarbrick wrote:
> In any case, the above might be efficient if my program was dealing with
> most of the fields. I can't imagine specifying 200 different fields in the
> SELECT and INTO clauses. But where do you draw that line? Obviously if you
> just care about a few fields you just SELECT those few. Do you still
> utilize the same COBOL group data item (copybook)? Do you just define the
> few you're interested, within the SQL DECLARE SECTION? If you do the latter
> then I worry that every programmer will use a different COBOL data name for
> each field.


I can't speak to the IBM/DB2 world, but as far as the Unisys 2200/RDMS
world, you want to address each field separately. If you have 10 fields
in your database, and the last 5 can be null, you'll have something like...

Exec SQL
Select Field_1, Field_2, Field_3, Field_4, Field_5,
Field_6, Field_7, Field_8, Field_9, Field_10
Into :field-1, :field-2, :field-3, :field-4, :field5,
:field-6 :field-6-ind, :field-7 :field-7-ind,
:field-8 :field-8-ind, :field-9 :field-9-ind,
:field-10 :field-10-ind
From This_Table
Where The_Key = :the-input-key
End-Exec

Now, you have to make an efficiency decision - do you always select all
the columns? Do you want to have logical groupings of the fields that
folks can select?

We've done it one of two ways. The most common way is a copybook - we
have a working-storage copybook for the data layouts, and a procedure
copybook to do the select. The other way is to have a data copybook,
and a subprogram to manipulate it. (I prefer this - and, if you can
swap out these types of modules, I'd recommend it.)

> When you want to update the record (row) do you, again, specify ever field
> that you (may have) update? Or do you just basically "update all"? And if
> you do that, specifically when the database is a remote database, does all
> of the data get transmitted back to the database? Or does the "client" keep
> track and know that this field and this field and this field haven't
> changed, so it does not send those fields back to get updated?


I don't think the "Set * = :my-rec" will work. Update will likely need
to address each field individually. Here is where you need to make
decisions similar to the ones you made for selects. One thing to keep
in mind, though, is that an update on a primary key field equates to a
delete and an insert - so, if you do code an "update all" paragraph,
exclude the primary key fields from your update statement.

> Am I just worrying myself over nothing?


No - embedded SQL is pretty easy once you get it down, but it is a
challenge to learn.

I'm hesitant to come out with more specifics, for fear that I'd be
leading you down a wrong road. There should be lots of IBM E-SQL
experience here that can fix anything I've said above that doesn't
apply, and expand further. (Dynamic SQL is an option too - you don't
have to have the select statement hard-coded. However, you *do* have to
have the INTO fields hard-coded, so that can be tricky too.)

> What about fields that allow NULL values? From what I've read, and I may
> not be interpretting it correctly, you have to specify an "indicator
> variable" for each NULLABLE field that you are selecting on. Does this
> cause pain when coding? Does it make sense just to go ahead and declare
> every field NON NULLABLE?


That's what some folks in our shop would rather us do. I disagree -
nulls are great at indicating what they mean. In our network database,
the database is defined with picture clauses, like COBOL is. So, if you
see a time in the database of "0000", that means "no time." Well, in
reality, "0000" is midnight - but, our folks are used to seeing "2400".
(We've tried convincing some of the die-hards that there's no such
time as 2400, but to no avail.)

Any of your date fields, if they're going to be blank, need to be null.
Relational databases are picky about the data going into a date or
date/time field being something that actually parses or casts into a
valid date/time.

Feel free to e-mail me at work if you would like more information along
this line. My last name is summers, there's a dot between my first and
last names, and the domain is "gunter" dot "af" dot "mil".

--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~
~ / \ / ~ Live from Montgomery, AL! ~
~ / \/ o ~ ~
~ / /\ - | ~ daniel@thebelowdomain ~
~ _____ / \ | ~ http://www.djs-consulting.com ~
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
~ GEEKCODE 3.12 GCS/IT d s-:+ a C++ L++ E--- W++ N++ o? K- w$ ~
~ !O M-- V PS+ PE++ Y? !PGP t+ 5? X+ R* tv b+ DI++ D+ G- e ~
~ h---- r+++ z++++ ~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~
Sergey Kashyrin

2006-02-14, 7:55 am

Frank,

Unfortunately for you
> SET * = :my-record

will not work.

You have to set each field separately :-(((
--
SK

"Frank Swarbrick" <Frank.Swarbrick@efirstbank.com> wrote in message
news:45cq33F5rm4oU1@individual.net...
> Greetings.
>
> We are considering (or I should say "we are considering considering")
> utilizing DB2 for some of our mainframe data. Currently we use DL/I
> databases and VSAM files. I know that there are many advantages to using
> a
> relational database. I have a few questions about what I perceive as
> being
> possible divantages.
>
> We currently have a database record type that has almost 400 unique fields
> in it. Whenever we have a program that accesses that record type we
> simply
> read it in to a COBOL group data item. We then use as many of the fields
> as
> are required by the business rules to be performed, and then (assuming we
> want to update the record) we write back the COBOL group data item.
>
> So if we were to move this record in to a relational database table what
> would we want to consider when it comes to data access. I'm guessing that
> we could, assuming we kept the data in the same order, say something like
>
> EXEC SQL
> SELECT *
> INTO :my-record
> FROM MYTABLE
> WHERE MYACCT = :my-acct
> END-EXEC
>
> That's pretty simple. We could then update it using
>
> EXEC SQL
> UPDATE MYTABLE
> SET * = :my-record
> WHERE MYACCT = :my-acct
> END-EXEC
>
> Acutally, I'm not sure that my "SET" phrase is even allowed. If it isn't,
> then how might I specify what I am attempting?
>
> In any case, the above might be efficient if my program was dealing with
> most of the fields. I can't imagine specifying 200 different fields in
> the
> SELECT and INTO clauses. But where do you draw that line? Obviously if
> you
> just care about a few fields you just SELECT those few. Do you still
> utilize the same COBOL group data item (copybook)? Do you just define the
> few you're interested, within the SQL DECLARE SECTION? If you do the
> latter
> then I worry that every programmer will use a different COBOL data name
> for
> each field.
>
> When you want to update the record (row) do you, again, specify ever field
> that you (may have) update? Or do you just basically "update all"? And
> if
> you do that, specifically when the database is a remote database, does all
> of the data get transmitted back to the database? Or does the "client"
> keep
> track and know that this field and this field and this field haven't
> changed, so it does not send those fields back to get updated?
>
> Am I just worrying myself over nothing?
>
> What about fields that allow NULL values? From what I've read, and I may
> not be interpretting it correctly, you have to specify an "indicator
> variable" for each NULLABLE field that you are selecting on. Does this
> cause pain when coding? Does it make sense just to go ahead and declare
> every field NON NULLABLE?
>
> As you may be able to tell, I am getting all of my information from books
> and manuals. (Speaking of which, can anyone recommend some good books?)
> I
> don't have DB2 at work where I can play with it. I do have it at home
> (DB2
> Express-C -- it's free!), but I don't have a COBOL compiler at home. So I
> really can't test anything out, COBOL-wise, at the moment.
>
> Anyway, I have more concerns, but I'll get to them at a later time.
>
> Thanks for any help.
> Frank
>
>
> ---
> Frank Swarbrick
> Senior Developer/Analyst - Mainframe Applications
> FirstBank Data Corporation - Lakewood, CO USA



Pete Dashwood

2006-02-14, 7:55 am


"Sergey Kashyrin" <ska@resqnet.com> wrote in message
news:TReIf.47$Hf.130176@news.sisna.com...
> Frank,
>
> Unfortunately for you
> will not work.
>
> You have to set each field separately :-(((


Or not... :-)

You COULD define the table with one column that was a single varchar field,
containing the entire COBOL record definition.

Then you simply fetch the column into a single Host variable that is
redefined as the COPY book...

Update whichever fields you use in the COBOL definiton as you do now, and
UPDATE the one column using the one host variable.

(In effect, you are using the RDB simply as a storage repository which is
really what your current VSAM KSDS is...)

Ideally, the whole data storage requirement should be rebuilt to utilise RDB
technology (simplify, and go to second and third normal form). In the real
world there is seldom time or money for proper solutions (unless you are
building from scratch).

If it is always accessed on the same key ("my-acct" in the example) then
that field would need to be defined separately, maybe at the start of the
record. Some implementaions of SQL allow grouped fields, others don't. I
wouldn't be above duplicating the key fields into a header, but then you
need to amend the programs to set the header before replacing the data, or
do it as a stored procedure (on the database) that is triggered every time
the record is updated.

Solutions can be as simple or as complex as you can tolerate... :-)

Pete.

> --
> SK
>
> "Frank Swarbrick" <Frank.Swarbrick@efirstbank.com> wrote in message
> news:45cq33F5rm4oU1@individual.net...
>
>



Michael Mattias

2006-02-14, 7:55 am

"Pete Dashwood" <dashwood@enternet.co.nz> wrote in message
news:45e2ltF68u0vU1@individual.net...
>"Sergey Kashyrin" <ska@resqnet.com> wrote in message
> news:TReIf.47$Hf.130176@news.sisna.com...
[color=darkred]
>Or not... :-)


>You COULD define the table with one column that was a single varchar field,
>containing the entire COBOL record definition...


If you're selling from your private stash, it's obviously worth top dollar.

MCM





Robert Jones

2006-02-14, 6:55 pm


Top posting

While I can see the logic of Pete's suggestion to use a VARCHAR, I
would be very reluctant to use it, I prefer Daniel's approach of using
copybooks and/or subroutines. This allows you to continue to access
the former files as though they were still files for your pre-existing
program code, while allowing new programs and some amendments to the
old programs to use SQL more appropriately.

Robert

Pete's message snipped

Pete Dashwood wrote:

> You COULD define the table with one column that was a single varchar field,
> containing the entire COBOL record definition.
>
> Then you simply fetch the column into a single Host variable that is
> redefined as the COPY book...
>
> Update whichever fields you use in the COBOL definiton as you do now, and
> UPDATE the one column using the one host variable.
>
> (In effect, you are using the RDB simply as a storage repository which is
> really what your current VSAM KSDS is...)
>
> Ideally, the whole data storage requirement should be rebuilt to utilise RDB
> technology (simplify, and go to second and third normal form). In the real
> world there is seldom time or money for proper solutions (unless you are
> building from scratch).
>
> If it is always accessed on the same key ("my-acct" in the example) then
> that field would need to be defined separately, maybe at the start of the
> record. Some implementaions of SQL allow grouped fields, others don't. I
> wouldn't be above duplicating the key fields into a header, but then you
> need to amend the programs to set the header before replacing the data, or
> do it as a stored procedure (on the database) that is triggered every time
> the record is updated.
>
> Solutions can be as simple or as complex as you can tolerate... :-)
>
> Pete.
>


Frank Swarbrick

2006-02-14, 6:55 pm

LX-i<lxi0007@netscape.net> 02/13/06 9:23 PM >>>
>Frank Swarbrick wrote:
the[color=darkred]
you[color=darkred]
the[color=darkred]
latter[color=darkred]
for[color=darkred]
>
>I can't speak to the IBM/DB2 world, but as far as the Unisys 2200/RDMS
>world, you want to address each field separately. If you have 10 fields
>in your database, and the last 5 can be null, you'll have something

like...
>
>Exec SQL
> Select Field_1, Field_2, Field_3, Field_4, Field_5,
> Field_6, Field_7, Field_8, Field_9, Field_10
> Into :field-1, :field-2, :field-3, :field-4, :field5,
> :field-6 :field-6-ind, :field-7 :field-7-ind,
> :field-8 :field-8-ind, :field-9 :field-9-ind,
> :field-10 :field-10-ind
> From This_Table
> Where The_Key = :the-input-key
>End-Exec
>
>Now, you have to make an efficiency decision - do you always select all
>the columns? Do you want to have logical groupings of the fields that
>folks can select?
>
>We've done it one of two ways. The most common way is a copybook - we
>have a working-storage copybook for the data layouts, and a procedure
>copybook to do the select. The other way is to have a data copybook,
>and a subprogram to manipulate it. (I prefer this - and, if you can
>swap out these types of modules, I'd recommend it.)


Can you elaborate a bit on this? I am definitely more a fan of using
subprograms than I am of using procedure division copybooks. Do your
subprograms simply take in a key as input, do a SELECT for all (*) and then
populate the working-storage copybook with the results, which are then
passed back to the caller? Or do you allow the caller to tell the
subprogram (somehow) which fields it is interested in? If the latter, how
do you do this simply and extensibly (is that a word?)?



field[color=darkred]
if[color=darkred]
all[color=darkred]
keep[color=darkred]
>
>I don't think the "Set * = :my-rec" will work. Update will likely need
>to address each field individually. Here is where you need to make
>decisions similar to the ones you made for selects. One thing to keep
>in mind, though, is that an update on a primary key field equates to a
>delete and an insert - so, if you do code an "update all" paragraph,
>exclude the primary key fields from your update statement.


Again, where do you figure out which fields you are interested in updating.
Does the calling program only send those fields that it wishes to update
back to the subprogram, which then only does UPDATE for those fields?

>
>No - embedded SQL is pretty easy once you get it down, but it is a
>challenge to learn.
>
>I'm hesitant to come out with more specifics, for fear that I'd be
>leading you down a wrong road. There should be lots of IBM E-SQL
>experience here that can fix anything I've said above that doesn't
>apply, and expand further. (Dynamic SQL is an option too - you don't
>have to have the select statement hard-coded. However, you *do* have to
>have the INTO fields hard-coded, so that can be tricky too.)
>
may[color=darkred]
>
>That's what some folks in our shop would rather us do. I disagree -
>nulls are great at indicating what they mean. In our network database,
>the database is defined with picture clauses, like COBOL is. So, if you
>see a time in the database of "0000", that means "no time." Well, in
>reality, "0000" is midnight - but, our folks are used to seeing "2400".
> (We've tried convincing some of the die-hards that there's no such
>time as 2400, but to no avail.)


I like the idea of nulls. I just don't like the way they have to be handled
in COBOL. I love the new feature in C#, where you can define a field as,
say, type "int&" (instead of just "int"). You can then see if the field is
"null", and if it's not null then you can check for it's actual value. You
don't need separately defined "indicator" fields. Ah well...

Thanks for your help.

Frank


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

2006-02-14, 6:55 pm

Pete Dashwood<dashwood@enternet.co.nz> 02/14/06 6:01 AM >>>
>
>"Sergey Kashyrin" <ska@resqnet.com> wrote in message
>news:TReIf.47$Hf.130176@news.sisna.com...
>
>Or not... :-)
>
>You COULD define the table with one column that was a single varchar field,


>containing the entire COBOL record definition.
>
>Then you simply fetch the column into a single Host variable that is
>redefined as the COPY book...
>
>Update whichever fields you use in the COBOL definiton as you do now, and
>UPDATE the one column using the one host variable.
>
>(In effect, you are using the RDB simply as a storage repository which is
>really what your current VSAM KSDS is...)


Hmm, that is certainly an option, but if I'm not going to use an RDB as an
RDB then I'm not sure of the point in buying an RDBMS!

>Ideally, the whole data storage requirement should be rebuilt to utilise

RDB
>technology (simplify, and go to second and third normal form). In the real


>world there is seldom time or money for proper solutions (unless you are
>building from scratch).


No doubt. I was only using my existing databases as an example. If we were
to do these we'd probably start slow and actually develop new databases
first for projects that need them. Converting existing databases would come
later down the line, and would certainly entail a great deal of
forethought.

Thanks,
Frank

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

2006-02-15, 7:55 am


"Robert Jones" <rjones0@hotmail.com> wrote in message
news:1139942605.883031.174130@f14g2000cwb.googlegroups.com...
>
> Top posting
>
> While I can see the logic of Pete's suggestion to use a VARCHAR, I
> would be very reluctant to use it, I prefer Daniel's approach of using
> copybooks and/or subroutines.


So do I... :-) I mentioned the approach in passing because someone said you
HAD to define every field... You don't. It is just probably the best way...

Pete.


Pete Dashwood

2006-02-15, 7:55 am


"Frank Swarbrick" <Frank.Swarbrick@efirstbank.com> wrote in message
news:45f2ibF6fbnfU2@individual.net...
> Pete Dashwood<dashwood@enternet.co.nz> 02/14/06 6:01 AM >>>
>
>
> Hmm, that is certainly an option, but if I'm not going to use an RDB as an
> RDB then I'm not sure of the point in buying an RDBMS!
>


Exactly. But if what you are doing is using the RDB to emulate what you do
now, then it is hardly "usng an RDB as an RDB" is it? :-)

> RDB
>
>
> No doubt. I was only using my existing databases as an example. If we
> were
> to do these we'd probably start slow and actually develop new databases
> first for projects that need them. Converting existing databases would
> come
> later down the line, and would certainly entail a great deal of
> forethought.


The important thing is not to simply convert the structure of existing
databases (unless you are happy to do that just as a quick interim
solution.) I have tools that convert ISAM and VSAM KSDS structures into true
RDBs in third normal form, but I wouldn't pretend that they are as good as
if you redesigned the applications from scratch.The main advantage they
offer is that they open the data up to access by standard tools, rather than
having to write a COBOL program every time you want to update or fetch the
data, in a new way. Such tools also facilitate the conversion of the
programs that access the data.

There is no substitute for proper modelling and design of databases, (using
the standard three normalizations, then possibly building redundancy back
in, or distributing the data for optimization if required) based not on data
structure but on access requirements.

Pete.


2006-02-15, 7:55 am

In article <45f2ibF6fbnfU2@individual.net>,
Frank Swarbrick <Frank.Swarbrick@efirstbank.com> wrote:
>Pete Dashwood<dashwood@enternet.co.nz> 02/14/06 6:01 AM >>>


[snip]

>
>Hmm, that is certainly an option, but if I'm not going to use an RDB as an
>RDB then I'm not sure of the point in buying an RDBMS!


Consider the possibility that... Management demands 'we move to a
database' and then provides minimal training to the personnel, whose
understanding of data-manipulation remains at the VSAM stage.

Nahhhhhh, that could *never* happen... could it?

DD

LX-i

2006-02-15, 7:55 am

Frank Swarbrick wrote:
> Can you elaborate a bit on this?


I sure can - look for something this evening, CST...


--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~
~ / \ / ~ Live from Montgomery, AL! ~
~ / \/ o ~ ~
~ / /\ - | ~ daniel@thebelowdomain ~
~ _____ / \ | ~ http://www.djs-consulting.com ~
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
~ GEEKCODE 3.12 GCS/IT d s-:+ a C++ L++ E--- W++ N++ o? K- w$ ~
~ !O M-- V PS+ PE++ Y? !PGP t+ 5? X+ R* tv b+ DI++ D+ G- e ~
~ h---- r+++ z++++ ~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~
Michael Mattias

2006-02-15, 7:55 am

<docdwarf@panix.com> wrote in message news:dsv076$r0i$1@reader2.panix.com...
> In article <45f2ibF6fbnfU2@individual.net>,
> Frank Swarbrick <Frank.Swarbrick@efirstbank.com> wrote:
>
> [snip]
>
is[color=darkred]
an[color=darkred]
>
> Consider the possibility that... Management demands 'we move to a
> database' and then provides minimal training to the personnel, whose
> understanding of data-manipulation remains at the VSAM stage.



Management shortsightedness aside, if one steps out of the VSAM trees to
look at the VSAM forest... a good understanding of both ESDS and KSDS VSAM
provides the fundamentals for understanding any relational DBMS.

MCM








Frank Swarbrick

2006-02-15, 6:55 pm

Pete Dashwood<dashwood@enternet.co.nz> 02/15/06 3:20 AM >>>
>
>"Frank Swarbrick" <Frank.Swarbrick@efirstbank.com> wrote in message
>news:45f2ibF6fbnfU2@individual.net...
and[color=darkred]
is[color=darkred]
an[color=darkred]
>
>Exactly. But if what you are doing is using the RDB to emulate what you do


>now, then it is hardly "usng an RDB as an RDB" is it? :-)


Emulating what we do now was never my intention. I'm just trying to somehow
relate what we have now to what we would do with an RDB, just so I can get
some better understanding of the similarities and differences.

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

real[color=darkred]
>
>The important thing is not to simply convert the structure of existing
>databases (unless you are happy to do that just as a quick interim
>solution.) I have tools that convert ISAM and VSAM KSDS structures into

true
>RDBs in third normal form, but I wouldn't pretend that they are as good as


>if you redesigned the applications from scratch.The main advantage they
>offer is that they open the data up to access by standard tools, rather

than
>having to write a COBOL program every time you want to update or fetch the


>data, in a new way. Such tools also facilitate the conversion of the
>programs that access the data.
>
>There is no substitute for proper modelling and design of databases,

(using
>the standard three normalizations, then possibly building redundancy back
>in, or distributing the data for optimization if required) based not on

data
>structure but on access requirements.


Now if only I had some idea what the "standard three normalizations" are!
(Acutally, I just googled and found some info, so I'll take a look at that.
But you're welcome to elaborate, if you want to take the time.)

Frank

Frank Swarbrick

2006-02-15, 6:55 pm

<docdwarf@panix.com> 02/15/06 3:36 AM >>>
>In article <45f2ibF6fbnfU2@individual.net>,
>Frank Swarbrick <Frank.Swarbrick@efirstbank.com> wrote:
>
>[snip]
>
[color=darkred]
an[color=darkred]
>
>Consider the possibility that... Management demands 'we move to a
>database' and then provides minimal training to the personnel, whose
>understanding of data-manipulation remains at the VSAM stage.
>
>Nahhhhhh, that could *never* happen... could it?


It's just the opposite, in this case. I'm trying to push RDBMS to
management. Well, it's not that management is against it. We currently
have Oracle on the "distributed apps" side. But on the mainframe (VSE/ESA)
side Oracle does not have a client interface available (much less a
server!). So we'd have to go with DB2, and spend all the money that that
entails for something we "already have". That is assuming we don't go with
a third party middle tier in order to access Oracle. Those are available,
but I'm personally somewhat resistant against a middle layer.

Frank


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

2006-02-15, 6:55 pm

In article <45h1a8F6ood7U3@individual.net>,
Frank Swarbrick <Frank.Swarbrick@efirstbank.com> wrote:
><docdwarf@panix.com> 02/15/06 3:36 AM >>>
>
>It's just the opposite, in this case.


There I go, getting things backwards again.

>I'm trying to push RDBMS to
>management. Well, it's not that management is against it. We currently
>have Oracle on the "distributed apps" side. But on the mainframe (VSE/ESA)
>side Oracle does not have a client interface available (much less a
>server!). So we'd have to go with DB2, and spend all the money that that
>entails for something we "already have". That is assuming we don't go with
>a third party middle tier in order to access Oracle. Those are available,
>but I'm personally somewhat resistant against a middle layer.


Another layer = another place for things to screw up, aye... I do not know
much about VSE/ESA but I know that one can set up Linux regions on an MVS,
might something like that be available and/or useful?

DD

Frank Swarbrick

2006-02-15, 6:55 pm

<docdwarf@panix.com> 02/15/06 9:19 AM >>>
>In article <45h1a8F6ood7U3@individual.net>,
>Frank Swarbrick <Frank.Swarbrick@efirstbank.com> wrote:
is[color=darkred]
an[color=darkred]
>
>There I go, getting things backwards again.
>
(VSE/ESA)[color=darkred]
with[color=darkred]
available,[color=darkred]
>
>Another layer = another place for things to screw up, aye... I do not know


>much about VSE/ESA but I know that one can set up Linux regions on an MVS,


>might something like that be available and/or useful?


In fact that is exactly what I am thinking. Mostly because DB2 Server for
VSE is nowhere near as full featured as DB2/UDB for Linux. DB2/VSE will be
the client (application requestor, in DB2 parlance), and DB2/UDB on Linux
for zSeries would be the database server (application server).

Having the RDBMS on mainframe Linux still requires client support on the
mainframe OS where all of the applications exist. So even though Oracle
runs just fine on mainframe Linux, since there is no VSE client driver there
is no way that VSE can directly access it. Alas...

Oh, and to clarify your terminology, Linux does not run *on* MVS (now called
z/OS). z/OS is an operating system. Linux is an operating system. VSE/ESA
(now z/VSE) is an operating system. All of these operating systems will run
on zSeries (mainframe) processors, just in the way that Windows, Solaris and
Linux can run on Intel processors. One great advantage to the mainframe is
that they support z/VM (Virtual Machine) which is an OS specifically
designed to host other operating systems. So saying that z/OS, z/VSE and
"z/Linux" (can) run under z/VM would be quite true. z/VM "virtualizes" the
zSeries processor so that more than one OS can run (at the same time) on the
same single zSeries machine.

(z/VM is *somewhat similar* to VMWare for Intel. The main difference being
that VMWare is an application that runs under an operating system (Windows
or Linux), which runs on the "bare metal", and the guest OS's run under
VMWare. With z/VM it is both the OS *and* the VM that runs on the bare
metal, essentially combining those two levels in to one. To diagram:

Intel processor (the bare metal) -> Windows or Linux -> VMWare -> Guest
operating systems
zSeries processor (the bare metal) -> z/VM -> Guest operating systems

Probably more than you ever wanted to know, but...

Frank


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

2006-02-15, 6:55 pm

In article <45h6i8F6pn1tU1@individual.net>,
Frank Swarbrick <Frank.Swarbrick@efirstbank.com> wrote:
><docdwarf@panix.com> 02/15/06 9:19 AM >>>


[snip]

>
>In fact that is exactly what I am thinking.


We are in agreement? Then one of us must be wrong, he cried, Wildely.

[snip]

>Oh, and to clarify your terminology, Linux does not run *on* MVS (now called
>z/OS). z/OS is an operating system. Linux is an operating system. VSE/ESA
>(now z/VSE) is an operating system. All of these operating systems will run
>on zSeries (mainframe) processors, just in the way that Windows, Solaris and
>Linux can run on Intel processors.


[snip]

>Probably more than you ever wanted to know, but...


Not at all. Greatly appreciated, old boy.

DD

LX-i

2006-02-15, 9:55 pm

Frank Swarbrick wrote:
> LX-i<lxi0007@netscape.net> 02/13/06 9:23 PM >>>
>
> Can you elaborate a bit on this? I am definitely more a fan of using
> subprograms than I am of using procedure division copybooks. Do your
> subprograms simply take in a key as input, do a SELECT for all (*) and then
> populate the working-storage copybook with the results, which are then
> passed back to the caller? Or do you allow the caller to tell the
> subprogram (somehow) which fields it is interested in? If the latter, how
> do you do this simply and extensibly (is that a word?)?

[snip]
> Again, where do you figure out which fields you are interested in updating.
> Does the calling program only send those fields that it wishes to update
> back to the subprogram, which then only does UPDATE for those fields?


Well, generally speaking, our selects select *all* fields (unless
there's a known up-front requirement to only select a few fields). Even
then, that requirement is met with skepticism, because we don't know
future requirements - and making a select only return a few fields
likely wouldn't be applicable to the next requirement.

Our updates, though, generally do *not* update from the retrieval data
area (unless it's specifically an "update all" sequence). We have
separate input variables for the updates. Inserts do generally use the
data area, and deletes require nothing but the deletion criteria
(preferably the primary key), but for those we use the input data as well.

In the copybook version of this, we have three "entry points" (distinct
pieces that can be copied into the program at a specific place). The
-WSA version has working-storage, the -INQ has selects, and the -UPD has
updates, inserts, and deletes. We've also numbered them - so, for
example, the Scheduled_Run table is proc R190, and it's entry points are
R190-Scheduled-Run-WSA, R190-Scheduled-Run-Inq, and R190-Scheduled-Run-Upd.

The subprogram version requires a little more planning, but is in some
ways preferable. There are two working-storage entry points in this
case; the first contains two 01-levels - one for data, and one for
"input" variables. The other contains constants to pass to the
subroutine to tell it which routine needs to be performed. I'll detail
those first.

[Contrived example loosely based on real table]

01 R190-Data.
12 R190-Primary-Key Pic X(09).
12 R190-More-Stuff Pic X(25).
12 R190-Last-Ran-Date Pic X(19).
12 R190-Last-Ran-Date-Ind Pic S9 Sign Leading Separate.
12 R190-Nullable-Stuff Pic X(56).
12 R190-Nullable-Stuff-Ind Pic S9 Sign Leading Separate.
...
12 R190-The-Last-Field Pic X(02).
12 R190-The-Last-Field-Ind Pic S9 Sign Leading Separate.
12 Pic X(500).

01 R190-Input-Data.
12 R190-Input-PK Pic X(09).
12 R190-Lots-of-Input-Vars Pic X(80).
12 Pic X(200).

(and, in the second one)

01 R190-Method-List.
12 R190-Select-by-Primary-Key Pic 9(02) Value 1.
12 R190-Select-by-More-Stuff Pic 9(02) Value 2.
...
12 R190-Delete-by-Primary-Key Pic 9(02) Value 37.

[end somewhat contrived example]

Notice the fillers at the end of R190-Data and R190-Input-Data. These
are there for future use, and this is what enables you to be able to
swap out the subroutines (if you have a dynamic linking environment)
without changing the main programs. If you have to add a new variable,
just use some of the space out of the filler; the size of the parameter
being passed remains the same, and the old programs won't be bothered by
the presence of a new variable. By the same token, if you drop a
column, you can simply filler-out the data and input variables, and the
data will remain in sync. (Of course, with this, if you grow past the
filler, you may well get stuck recompiling.)

Also, the Unisys 2200 has a feature called "Common Storage", where you
can define variables in a "common-storage section", and as long as you
define them the same way, the subroutines can access that data by
default. We define our SQLState variable that way, so subroutines can
do SQL, and if they have an error, the caller can handle it. This saves
our subroutines from having to handle SQL errors themselves. If you
can't do that in your environment, you could add a 4th parameter where
you pass the SQLState value back.

Finally, in the subprogram, you'll copy the first working-storage entry
into the linkage section, and the second into the working-storage section.

[contrived subprogram]

data division - working-storage section.
Copy R190-Scheduled-Run-Meth.

linkage section.
Copy R190-Scheduled-Run-WSA.

01 Input-Parameter Pic 9(02).

procedure division
using R190-Data R190-Input-Data Input-Parameter.

srDriver.

Evaluate Input-Parameter
When R190-Select-by-Primary-Key
Perform [internal name]
When R190-Select-by-More-Stuff
Perform [internal name]
...
End-Evaluate
..

[end contrived subprogram snippet]

Given this, your call would look something like

Call "Scheduled-Run"
Using R190-Data R190-Input-Data R190-Select-by-Primary-Key
End-Call

Doing things like this, as opposed to defining lots of entry points to
your subprogram, allows you to add methods at will - again, all
swappable without causing problems for existing production code.

> may
>
> I like the idea of nulls. I just don't like the way they have to be handled
> in COBOL. I love the new feature in C#, where you can define a field as,
> say, type "int&" (instead of just "int"). You can then see if the field is
> "null", and if it's not null then you can check for it's actual value. You
> don't need separately defined "indicator" fields. Ah well...


Nulls are a bit more code in COBOL, but you get used to them. In our
implementation, though, if you select a field that is null, the data in
the "data" variable is not touched - so, you really *really* need to
check indicator variables if they're there. You can also get around
that by sticking an "Initialize R190-Data" (for example) in the
individual paragraphs of the subprogram. (You don't want to do it in
the driver, since R190-Data is prefilled for inserts and "update all"s.)

I hope that's been helpful to you. Of course, in the subprogram, you
can have whatever kind of work variables you need. You'll also want to
make sure you address issues of reentrancy and concurrent execution, if
that's how your environment operates - you may want to add a
working-storage block for work variables in the linkage section to make
sure your work variables are activity-specific.

Lots of fun stuff... :)

--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~
~ / \ / ~ Live from Montgomery, AL! ~
~ / \/ o ~ ~
~ / /\ - | ~ daniel@thebelowdomain ~
~ _____ / \ | ~ http://www.djs-consulting.com ~
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
~ GEEKCODE 3.12 GCS/IT d s-:+ a C++ L++ E--- W++ N++ o? K- w$ ~
~ !O M-- V PS+ PE++ Y? !PGP t+ 5? X+ R* tv b+ DI++ D+ G- e ~
~ h---- r+++ z++++ ~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~
James J. Gavan

2006-02-15, 9:55 pm

LX-i wrote:
> Frank Swarbrick wrote:
>

Frank,

Just read Daniel's detailed reply. This is NOT THE SOLUTION for you, but
just an outline of what I do using OO with Net Express. Maybe you can
get some ideas from it, and if possible try and emulate OO by using
Entry Points.

I still have 'Learner' plates up for SQL - fortunately with N/E, having
defined your DB (MS Access in my case), it allows you to select Query
Type and it generates from EXEC to END-EXEC including the troublesome
NULLs. (The N/E feature also generates a copyfile required by both SQL
and your COBOL programs).

Pete Dashwood advised 'don't get seduced by add-on features from various
DBs available and use the (R)DBMS as a 'repository'. I took him at his
word sticking with a Three-Tier System approach :-

..............
. DBI Main .
..............
^
^
.............. ............. ............ .........
.. Edit . . Materials . . Materials. .SQL .
.. Materials .>>>. DBI .>>>. Table .>>>.Errors .
.............. ............. ............ .........

DBI above = Database Interface. Not shown in the above flowchart is a
template for Dialogs to which I pass creation parameters(properties) and
subsequently send data or receive data back - using the class Edit
Materials as the Controller, (The Stromboli to Pinocchio and his little
friends :-) ).

Materials DBI - solely devoted to the one Table and is used to pass
invokes to the Materials Table to create a Sorted Collection which I
want in a Listbox in the Materials Dialog. Rather than repeat code in
DBI Materials there's a super class DBI Main where I construct any empty
Collections/Lists I require. The actual filling, (population) of the
Collection occurs in Materials DBI.

Materials Table - that so far is the only 'program' that contains any
SQL statements and obviously if I hit errors I invoke SQL Errors to
generate a message box.

I recall you were concerned with one or more programmers writing
programs updating different fields in a common table - so was I - so my
only accessing is in Materials Table. The methods I have are :-

Delete Record - DELETE FROM
getSpecNoGrade - SELECT DISTINCT (just so I can print the ID)
MakeCollection - CURSOR SELECT DISTINCT
ReadRecord - SELECT DISTINCT
RewriteRecord - UPDATE
WriteRecord - INSERT INTO

Rewrite and Write with a DB ? I stayed with COBOL names - then
EditMaterials could use the same invoke messages with either a DB Table
or a COBOL File.

This particular Table "MakeCollection", I only require a listing in
ascending sequence by Material IDs (ANSI codes used by ASME) - so my
requirement is simple. Look back at the flowchart when I invoke
MaterialsTable from MaterialsDBI. See code below. I pass the object
reference of MaterialsDBI (lnk-DBI) and the method literal
(lnk-MethodName) that the data is to be returned to. When in the SQL
Table I pass each row back to the DBI - best explained with code :-

(Nothing unique about the Cursor #'s - they are just the next one that
N/E generates).

EXEC SQL
DECLARE CSR57 CURSOR FOR SELECT DISTINCT
`A`.`MatID`
,etc....
FROM `Materials` A
END-EXEC

EXEC SQL OPEN CSR57 END-EXEC
PERFORM UNTIL SQLSTATE <> "00000"
EXEC SQL
FETCH CSR57 INTO
:A-MatID:A-MatID-NULL *> NULLs are what N/E generates

,:A-MainType:A-MainType-NULL
,etc....
END-EXEC

Evaluate true

when SQLSTATE = "00000"
initialize ls-MatListRecord
move A-MatId to Mat-Id
move A-SpecNo to Mat-SpecNo
move A-GradeNo to Mat-GradeNo
move A-MainType to Mat-MainType
move A-SubType to Mat-SubType
invoke lnk-DBI lnk-MethodName using ls-MatListRecord

*> Note : above data is returned to lnk-DBI to add
*> the appropriate collection/dictionary entry

***If you like, at this point there is a 'break' in the CURSOR routine
***with some row info being returned to a specific method in ***MaterialsDBI

when SQLSTATE = "02000" *> no more rows
EXIT PERFORM
when other
move A-MatID to ws-ErrorID
invoke self "setErrorMessage"
set TableError to true
EXIT METHOD
End-evaluate

END-PERFORM
EXEC SQL CLOSE CSR57 END-EXEC

Now given up front that I had a series of regularly used CURSOR SELECTS,
yes I would be inclined to put them into Materials Table - and still
could, just so long as I recompile the Materials DBI and Table with any
added methods.

An alternative to that could be one standard CURSOR SELECT and have the
data returned to new additional method-names in Materials DBI where the
relevant columns are stripped off to give me new collections.

I don't know how you could 'interrupt' the CURSOR SELECT as illustrated
above - that's one for you :-).

Your UPDATES, without knowing the impact/performance because of volumes,
in my ignorance, I would go with ONE BIG BANG and have just one method
of INSERT or UPDATE - with 400 columns you would have a HUGE method
spreading over several sheets of paper. In my case I pass the full
record from Edit Materials to the appropriate method in the SQL Table.
But if viable, I would suggest write once and it works for all situations.

When it comes to DB Tables, it's not a comparison of apples to oranges,
but apples(McIntosh) to apples(Granny Smith).

As I said this is not a solution but some of what I'm doing may give you
ideas. If interested I can send you the source code.

BTW - Daniel - God speed and protection. With your youthful enthusiasm
you are kinda 'special' to many of us.

Jimmy, Calgary AB
Pete Dashwood

2006-02-16, 7:55 am


"Michael Mattias" <michael.mattias@gte.net> wrote in message
news:4gGIf.48158$dW3.11680@newssvr21.news.prodigy.com...
> <docdwarf@panix.com> wrote in message
> news:dsv076$r0i$1@reader2.panix.com...
> is
> an
>
>
> Management shortsightedness aside, if one steps out of the VSAM trees to
> look at the VSAM forest... a good understanding of both ESDS and KSDS VSAM
> provides the fundamentals for understanding any relational DBMS.
>


Michael, I believe this is the very first time I have seen a post from you,
in all the years we have both frequented CLC, with which I disagreed.

I was surprised at what you wrote.

I'm surprised because I spent years learning about and using VSAM (and ISAM
on mainframes before it) and was considered something of an expert on these
topics (I wrote an access method using VSAM RRDS in 1978 (RAM), that I
believe is still in use today at a London bank...), Yet I see no similarity
at all between the Codd and Date relational model and "flat" VSAM files.
Neither do I see experience with VSAM (in any of its incarnations) as being
useful when it comes to relational database design. I could agree that a
"good understanding of both ESDS and KSDS" (and I'll throw in RRDS for
nothing :-)) might be useful for designing networked or even hierarchical
DBs (although most shops who wanted these would use Adabas or IMS), but for
Relational?

Am I missing something here? What angle are you coming from?

Pete.


Pete Dashwood

2006-02-16, 7:55 am


"Frank Swarbrick" <Frank.Swarbrick@efirstbank.com> wrote in message
news:45h13dF6ood7U2@individual.net...
<snip>
>
> Now if only I had some idea what the "standard three normalizations" are!
> (Acutally, I just googled and found some info, so I'll take a look at
> that.
> But you're welcome to elaborate, if you want to take the time.)
>

OK, the following might help... I put it together years ago and distribute
it as part of a package I provide with the tools I mentioned.

This is necessarily a shallow treatment, but if you examine the examples
carefully, you should get the idea :-)

Description of Normalization



Normalization is the process of organizing data in a database. This includes
creating tables and establishing relationships between those tables
according to rules designed both to protect the data and to make the
database more flexible by eliminating two factors: redundancy and
inconsistent dependency.

Redundant data wastes disk space and creates maintenance problems. If data
that exists in more than one place must be changed, the data must be changed
in exactly the same way in all locations. A customer address change is much
easier to implement if that data is stored only in the Customers table and
nowhere else in the database.

What is an "inconsistent dependency"? While it is intuitive for a user to
look in the Customers table for the address of a particular customer, it may
not make sense to look there for the salary of the employee who calls on
that customer. The employee's salary is related to, or dependent on, the
employee and thus should be moved to the Employees table. Inconsistent
dependencies can make data difficult to access; the path to find the data
may be missing or broken.

There are a few rules for database normalization. Each rule is called a
"normal form." If the first rule is observed, the database is said to be in
"first normal form." If the first three rules are observed, the database is
considered to be in "third normal form." Although other levels of
normalization are possible, third normal form is considered the highest
level necessary for most applications.

As with many formal rules and specifications, real world scenarios do not
always allow for perfect compliance. In general, normalization requires
additional tables and some customers find this cumbersome. If you decide to
violate one of the first three rules of normalization, make sure that your
application anticipates any problems that could occur, such as redundant
data and inconsistent dependencies.

NOTE: The following descriptions include examples.

First Normal Form

· Eliminate repeating groups in individual tables.



· Create a separate table for each set of related data.



· Identify each set of related data with a primary key.



Do not use multiple fields in a single table to store similar data. For
example, to track an inventory item that may come from two possible sources,
an inventory record may contain fields for Vendor Code 1 and Vendor Code 2.

But what happens when you add a third vendor? Adding a field is not the
answer; it requires program and table modifications and does not smoothly
accommodate a dynamic number of vendors. Instead, place all vendor
information in a separate table called Vendors, then link inventory to
vendors with an item number key, or vendors to inventory with a vendor code
key.

Second Normal Form

· Create separate tables for sets of values that apply to multiple
records.



· Relate these tables with a foreign key.



Records should not depend on anything other than a table's primary key (a
compound key, if necessary). For example, consider a customer's address in
an accounting system. The address is needed by the Customers table, but also
by the Orders, Shipping, Invoices, Accounts Receivable, and Collections
tables. Instead of storing the customer's address as a separate entry in
each of these tables, store it in one place, either in the Customers table
or in a separate Addresses table.

Third Normal Form

· Eliminate fields that do not depend on the key.



Values in a record that are not part of that record's key do not belong in
the table. In general, any time the contents of a group of fields may apply
to more than a single record in the table, consider placing those fields in
a separate table.

For example, in an Employee Recruitment table, a candidate's university name
and address may be included. But you need a complete list of universities
for group mailings. If university information is stored in the Candidates
table, there is no way to list universities with no current candidates.
Create a separate Universities table and link it to the Candidates table
with a university code key.

EXCEPTION: Adhering to the third normal form, while theoretically desirable,
is not always practical. If you have a Customers table and you want to
eliminate all possible interfield dependencies, you must create separate
tables for cities, ZIP codes, sales representatives, customer classes, and
any other factor that may be duplicated in multiple records. In theory,
normalization is worth pursuing; however, many small tables may degrade
performance or exceed open file and memory capacities.

It may be more feasible to apply third normal form only to data that changes
frequently. If some dependent fields remain, design your application to
require the user to verify all related fields when any one is changed.

Other Normalization Forms

Fourth normal form, also called Boyce Codd Normal Form (BCNF), and fifth
normal form do exist, but are rarely considered in practical design.
Disregarding these rules may result in less than perfect database design,
but should not affect functionality.

**********************************

Examples of Normalized Tables

**********************************



Normalization Examples:



Unnormalized table:



Student# Advisor Adv-Room Class1 Class2 Class3

-------------------------------------------------------

1022 Jones 412 101-07 143-01 159-02

4123 Smith 216 201-01 211-02 214-01

First Normal Form: NO REPEATING GROUPS

Tables should have only two dimensions. Since one student has several
classes, these classes should be listed in a separate table. Fields Class1,
Class2, & Class3 in the above record are indications of design trouble.

Spreadsheets often use the third dimension, but tables should not. Another
way to look at this problem: with a one-to-many relationship, do not put the
one side and the many side in the same table. Instead, create another table
in first normal form by eliminating the repeating group (Class#), as shown
below:



Student# Advisor Adv-Room Class#

---------------------------------------

1022 Jones 412 101-07

1022 Jones 412 143-01

1022 Jones 412 159-02

4123 Smith 216 201-01

4123 Smith 216 211-02

4123 Smith 216 214-01

Second Normal Form: ELIMINATE REDUNDANT DATA

Note the multiple Class# values for each Student# value in the above table.
Class# is not functionally dependent on Student# (primary key), so this
relationship is not in second normal form.

The following two tables demonstrate second normal form:



Students: Student# Advisor Adv-Room

------------------------------

1022 Jones 412

4123 Smith 216



Registration: Student# Class#

------------------

1022 101-07

1022 143-01

1022 159-02

4123 201-01

4123 211-02

4123 214-01

Third Normal Form: ELIMINATE DATA NOT DEPENDENT ON KEY

In the last example, Adv-Room (the advisor's office number) is functionally
dependent on the Advisor attribute. The solution is to move that attribute
from the Students table to the Faculty table, as shown below:



Students: Student# Advisor

-------------------

1022 Jones

4123 Smith



Faculty: Name Room Dept

--------------------

Jones 412 42

Smith 216 42



Hope this helps,



Pete.


Michael Mattias

2006-02-16, 6:55 pm

"Pete Dashwood" <dashwood@enternet.co.nz> wrote in message
news:45j4g3F6r3huU1@individual.net...
>
> "Michael Mattias" <michael.mattias@gte.net> wrote in message
VSAM[color=darkred]
>
> Michael, I believe this is the very first time I have seen a post from

you,
> in all the years we have both frequented CLC, with which I disagreed.
>
> Yet I see no similarity
> at all between the Codd and Date relational model and "flat" VSAM files.
> Neither do I see experience with VSAM (in any of its incarnations) as

being
> useful when it comes to relational database design. I could agree that a
> "good understanding of both ESDS and KSDS" (and I'll throw in RRDS for
> nothing :-)) might be useful for designing networked or even hierarchical
> DBs (although most shops who wanted these would use Adabas or IMS), but

for
> Relational?
>
> Am I missing something here? What angle are you coming from?


I think you actually DO agree. My point was on the design side: if one has
designed VSAM ESDS/KSDS databases, he understands data types, normalization
and how and why keys/indexes are used. The identical skills are both
necessary and essential to designing a database when using an RDBMS.

True, the effective use of an RDBMS allows (requires?) a bit more creativity
because generally the RDMBS supports more "'paths" by which to get at data,
but the same principles apply.

The actual nuts and bolts coding for [optimal] data access will differ
dramatically, but using either VSAM ESDS/KSDS or an RDBMS, there are at the
core but a handful of access routines to develop; e.g., 'read' , 'read
next/prior', ' 'write" , 'open' , and 'close'.

And at that, even in the most complex situation - get qualified data in
some order for which there is no key- the coding itself is pretty similar:

Using VSAM : Open, Read [next] ,Qualify, RELEASE (to sort), loop; RETURN
(from sort), process, loop, close down
Using RDBMS: DECLARE CURSOR (with WHERE and ORDER BY), Open Cursor, FETCH
[next], process, loop, close down.

Looks the same to me other than a few minor syntax things.

MCM









Pete Dashwood

2006-02-17, 7:55 am


"Michael Mattias" <michael.mattias@gte.net> wrote in message
news:TC%If.6672$rL5.3763@newssvr27.news.prodigy.net...
> "Pete Dashwood" <dashwood@enternet.co.nz> wrote in message
> news:45j4g3F6r3huU1@individual.net...
> VSAM
> you,
> being
> for
>
> I think you actually DO agree. My point was on the design side: if one has
> designed VSAM ESDS/KSDS databases, he understands data types,
> normalization
> and how and why keys/indexes are used. The identical skills are both
> necessary and essential to designing a database when using an RDBMS.
>
> True, the effective use of an RDBMS allows (requires?) a bit more
> creativity
> because generally the RDMBS supports more "'paths" by which to get at
> data,
> but the same principles apply.
>
> The actual nuts and bolts coding for [optimal] data access will differ
> dramatically, but using either VSAM ESDS/KSDS or an RDBMS, there are at
> the
> core but a handful of access routines to develop; e.g., 'read' , 'read
> next/prior', ' 'write" , 'open' , and 'close'.
>
> And at that, even in the most complex situation - get qualified data in
> some order for which there is no key- the coding itself is pretty similar:
>
> Using VSAM : Open, Read [next] ,Qualify, RELEASE (to sort), loop;
> RETURN
> (from sort), process, loop, close down
> Using RDBMS: DECLARE CURSOR (with WHERE and ORDER BY), Open Cursor,
> FETCH
> [next], process, loop, close down.
>
> Looks the same to me other than a few minor syntax things.
>

OK, I see your point.

However none of these actions address the Relational model and the
mathematical purity which it guarantees. An RDB, when properly designed is
as efficient (in terms of data storage (not necessarily in terms of
access)), as it can be. (the model guarantees it). The fact that there are
actions like READ, UPDATE etc (just as there are in VSAM) should not be
taken to mean they are the same...

Designing VSAM systems would be good experience (as you pointed out) in the
use of keys to access data, but that is about where the similarity ends.
Data types are irrelevant to the design of a relational database. It is a
logical model. In fact, experience designing VSAM and flat file systems
where the data structure IS really important, could be counter productive
when it comes to defining relations for a relational DB.

One system is concerned with data structure, the other is concerned with
data access patterns and relationships. I have never known anyone try and
normalize a VSAM system (I accept that with increased knowledge today, there
may be people who do, but I believe most of them would simply go to a
RDBMS).

I understand it is possible (as you described) to view both systems in terms
of the access facilities, but to do so is, in my opinion, to lose much of
the richness of the relational model and it's physical implementation via a
RDB.

Still, whatever works... :-)

Pete.


2006-02-17, 7:55 am

In article <45lpfoF7al79U1@individual.net>,
Pete Dashwood <dashwood@enternet.co.nz> wrote:

[snip]

>Designing VSAM systems would be good experience (as you pointed out) in the
>use of keys to access data, but that is about where the similarity ends.


That might be dependent on the qualities of one's teachers (or one's
innate abilities to learn), Mr Dashwood; I was taught, e'er-so-long ago,
that data are to live in one place, be read once and written once... these
seem to be remarkably close to the Normalisation Rules posted here
recently.

>Data types are irrelevant to the design of a relational database. It is a
>logical model. In fact, experience designing VSAM and flat file systems
>where the data structure IS really important, could be counter productive
>when it comes to defining relations for a relational DB.


Now I am ... 'where the data structure IS really important'
(emphasis original)? The only 'important data structure' I was taught was
'always leave as many bytes of filler at the end of a record as you can
get away with For Future Use'... or am I missing something? Primary key,
maybe a couple of alternate keys and as many 'external' (in databases
sometimes called 'foreign') keys as possible, that what got hammered into
us.

(The classic example of a file design that *didn't* fit into the
Normalisation Rules was Order History, which usually looked something
like:

01 C01752-ORDHIST-REC.
05 C01752-ORDHIST-CUSTKEY PIC X(10).
05 C01752-ORDHIST-ORDNO OCCURS 1 TO WS-ORDHIST-MAX TIMES
DEPENDING ON A1658-ORDHIST-INX
PIC X(15).

.... where the CUSTKEY came from the A1658-CUSTMAST file (which also has a
COMP-3... errrrr, packed decimal field for the ORDHIST-INX (so you could
know how many orders a customer had placed without making that second read
of the ORDHIST file... useful for generating special offers and
promotions, of course) (and, of course, it was name -INX because the
suffix -IDX was reserved for datanames generated by the INDEXED BY
clause and woe betide the coder who ignored this... or, actually, who *got
caught* ignoring this, somehow one or two or three always managed to slip
into Prod... into the programs that blew up most frequently at 2:am...
funny how that happens... zzzzzZZZZZzzzzzz....

DD

Michael Mattias

2006-02-17, 6:55 pm

<docdwarf@panix.com> wrote in message news:dt4h15$rrb$1@reader2.panix.com...
> Mr Dashwood; I was taught, e'er-so-long ago,
> that data are to live in one place, be read once and written once... these
> seem to be remarkably close to the Normalisation Rules posted here
> recently.
>[...]
>
> (The classic example of a file design that *didn't* fit into the
> Normalisation Rules was Order History, which usually looked something
> like:
>
> 01 C01752-ORDHIST-REC.
> 05 C01752-ORDHIST-CUSTKEY PIC X(10).
> 05 C01752-ORDHIST-ORDNO OCCURS 1 TO WS-ORDHIST-MAX TIMES
> DEPENDING ON A1658-ORDHIST-INX
> PIC X(15).
> [....]
> ... where the CUSTKEY came from the A1658-CUSTMAST file (which also has a
> COMP-3... errrrr, packed decimal field for the ORDHIST-INX (so you could
> know how many orders a customer had placed without making that second read
> of the ORDHIST file...


Excellent example of using one's head instead of blindly following some set
of Postulates.

While using an RDMBS you might not write that A1658-ORDHIST-INX "number of
orders" and instead rely on an in-code "SELECT COUNT .." statement the same
logic applies: You can avoid the second hit on the database by "bending a
rule" and storing a redundant value. Wether or not that second hit *should*
be eschewed is (ta dah!) "application dependent" and rightly the province of
the designer-on-the-scene and not that of some ivory-tower 'guru' who has
produced a well-regarded tome.

But regardless of storage method (KSDS VSAM or RDBMS), I just see too many
similarities in the 'thought process' to dismiss my theory: design skills
acquired using one storage method are highly portable to the other.

MCM





2006-02-17, 6:55 pm

In article <gNkJf.32440$F_3.30695@newssvr29.news.prodigy.net>,
Michael Mattias <michael.mattias@gte.net> wrote:
><docdwarf@panix.com> wrote in message news:dt4h15$rrb$1@reader2.panix.com...


[snip]

>
>Excellent example of using one's head instead of blindly following some set
>of Postulates.


.... and a fine place for a bug to show up when another programming team
adds or changes a program that modifies the Order History file without
also updating the Customer Master... but hey, finding such things is part
of the way I make my living.

>
>While using an RDMBS you might not write that A1658-ORDHIST-INX "number of
>orders" and instead rely on an in-code "SELECT COUNT .." statement the same
>logic applies: You can avoid the second hit on the database by "bending a
>rule" and storing a redundant value. Wether or not that second hit *should*
>be eschewed is (ta dah!) "application dependent" and rightly the province of
>the designer-on-the-scene and not that of some ivory-tower 'guru' who has
>produced a well-regarded tome.


All rules have their exceptions, including this one.

>
>But regardless of storage method (KSDS VSAM or RDBMS), I just see too many
>similarities in the 'thought process' to dismiss my theory: design skills
>acquired using one storage method are highly portable to the other.


In general 'keep it small, flat and fast' is good advice... but one might
do well to take advantage of the available architecture, lest one fall
into the paradigm of 'writing FORTRAN programs in any language'.

('So what if COBOL allows more than eight characters for a data-name...
that takes more resources to compile!')

DD
Douglas Gallant

2006-02-18, 3:55 am

Since you are using UCOB (or OCOB), I'm a little surprised by the use of
Common Storage rather than the COBOL standard EXTERNAL syntax. I haven't
been in the details of RDMS lately but I believe you could declare the
SQLSTATE or the RDMCA that way succesfully.

We still use DMS predominantly and programs have to copy the records, etc to
common-storage (subschema section) to allow for DMS subroutines. Because of
that we NEVER use common-storage for any other reason and use EXTERNAL
instead.

"LX-i" <lxi0007@netscape.net> wrote in message
news:df9d4$43f3d356$45491d7a$22692@KNOLO
GY.NET...
> Frank Swarbrick wrote:
> [snip]
>
> Well, generally speaking, our selects select *all* fields (unless there's
> a known up-front requirement to only select a few fields). Even then,
> that requirement is met with skepticism, because we don't know future
> requirements - and making a select only return a few fields likely
> wouldn't be applicable to the next requirement.
>
> Our updates, though, generally do *not* update from the retrieval data
> area (unless it's specifically an "update all" sequence). We have
> separate input variables for the updates. Inserts do generally use the
> data area, and deletes require nothing but the deletion criteria
> (preferably the primary key), but for those we use the input data as well.
>
> In the copybook version of this, we have three "entry points" (distinct
> pieces that can be copied into the program at a specific place). The -WSA
> version has working-storage, the -INQ has selects, and the -UPD has
> updates, inserts, and deletes. We've also numbered them - so, for
> example, the Scheduled_Run table is proc R190, and it's entry points are
> R190-Scheduled-Run-WSA, R190-Scheduled-Run-Inq, and
> R190-Scheduled-Run-Upd.
>
> The subprogram version requires a little more planning, but is in some
> ways preferable. There are two working-storage entry points in this case;
> the first contains two 01-levels - one for data, and one for "input"
> variables. The other contains constants to pass to the subroutine to tell
> it which routine needs to be performed. I'll detail those first.
>
> [Contrived example loosely based on real table]
>
> 01 R190-Data.
> 12 R190-Primary-Key Pic X(09).
> 12 R190-More-Stuff Pic X(25).
> 12 R190-Last-Ran-Date Pic X(19).
> 12 R190-Last-Ran-Date-Ind Pic S9 Sign Leading Separate.
> 12 R190-Nullable-Stuff Pic X(56).
> 12 R190-Nullable-Stuff-Ind Pic S9 Sign Leading Separate.
> ...
> 12 R190-The-Last-Field Pic X(02).
> 12 R190-The-Last-Field-Ind Pic S9 Sign Leading Separate.
> 12 Pic X(500).
>
> 01 R190-Input-Data.
> 12 R190-Input-PK Pic X(09).
> 12 R190-Lots-of-Input-Vars Pic X(80).
> 12 Pic X(200).
>
> (and, in the second one)
>
> 01 R190-Method-List.
> 12 R190-Select-by-Primary-Key Pic 9(02) Value 1.
> 12 R190-Select-by-More-Stuff Pic 9(02) Value 2.
> ...
> 12 R190-Delete-by-Primary-Key Pic 9(02) Value 37.
>
> [end somewhat contrived example]
>
> Notice the fillers at the end of R190-Data and R190-Input-Data. These are
> there for future use, and this is what enables you to be able to swap out
> the subroutines (if you have a dynamic linking environment) without
> changing the main programs. If you have to add a new variable, just use
> some of the space out of the filler; the size of the parameter being
> passed remains the same, and the old programs won't be bothered by the
> presence of a new variable. By the same token, if you drop a column, you
> can simply filler-out the data and input variables, and the data will
> remain in sync. (Of course, with this, if you grow past the filler, you
> may well get stuck recompiling.)
>
> Also, the Unisys 2200 has a feature called "Common Storage", where you can
> define variables in a "common-storage section", and as long as you define
> them the same way, the subroutines can access that data by default. We
> define our SQLState variable that way, so subroutines can do SQL, and if
> they have an error, the caller can handle it. This saves our subroutines
> from having to handle SQL errors themselves. If you can't do that in your
> environment, you could add a 4th parameter where you pass the SQLState
> value back.
>
> Finally, in the subprogram, you'll copy the first working-storage entry
> into the linkage section, and the second into the working-storage section.
>
> [contrived subprogram]
>
> data division - working-storage section.
> Copy R190-Scheduled-Run-Meth.
>
> linkage section.
> Copy R190-Scheduled-Run-WSA.
>
> 01 Input-Parameter Pic 9(02).
>
> procedure division
> using R190-Data R190-Input-Data Input-Parameter.
>
> srDriver.
>
> Evaluate Input-Parameter
> When R190-Select-by-Primary-Key
> Perform [internal name]
> When R190-Select-by-More-Stuff
> Perform [internal name]
> ...
> End-Evaluate
> .
>
> [end contrived subprogram snippet]
>
> Given this, your call would look something like
>
> Call "Scheduled-Run"
> Using R190-Data R190-Input-Data R190-Select-by-Primary-Key
> End-Call
>
> Doing things like this, as opposed to defining lots of entry points to
> your subprogram, allows you to add methods at will - again, all swappable
> without causing problems for existing production code.
>
>
> Nulls are a bit more code in COBOL, but you get used to them. In our
> implementation, though, if you select a field that is null, the data in
> the "data" variable is not touched - so, you really *really* need to check
> indicator variables if they're there. You can also get around that by
> sticking an "Initialize R190-Data" (for example) in the individual
> paragraphs of the subprogram. (You don't want to do it in the driver,
> since R190-Data is prefilled for inserts and "update all"s.)
>
> I hope that's been helpful to you. Of course, in the subprogram, you can
> have whatever kind of work variables you need. You'll also want to make
> sure you address issues of reentrancy and concurrent execution, if that's
> how your environment operates - you may want to add a working-storage
> block for work variables in the linkage section to make sure your work
> variables are activity-specific.
>
> Lots of fun stuff... :)
>
> --
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~
> ~ / \ / ~ Live from Montgomery, AL! ~
> ~ / \/ o ~ ~
> ~ / /\ - | ~ daniel@thebelowdomain ~
> ~ _____ / \ | ~ http://www.djs-consulting.com ~
> ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
> ~ GEEKCODE 3.12 GCS/IT d s-:+ a C++ L++ E--- W++ N++ o? K- w$ ~
> ~ !O M-- V PS+ PE++ Y? !PGP t+ 5? X+ R* tv b+ DI++ D+ G- e ~
> ~ h---- r+++ z++++ ~
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~



Pete Dashwood

2006-02-18, 6:55 pm

Some quick comments:

1. What you were taught was very good. Sadly, my experience (across many
sites and several continents) has shown this is not often the case.

2. Anybody who uses packed fields for keys, deserves to be pulled out of bed
at 2am... :-)

3. I don't intend to argue this with you or Michael because I really don't
care how either of you define and access your (or your employer's) data. If
you think that using an OCCURS clause helps, well, good luck...

4. Many of the arguments over inefficiency in using multiple tables have
been rendered academic by modern RDBMS where dependant or related tables are
often cached and in memory anyway. Technology has allowed the physical
structure to remain the domain of the DBA (where it properly belongs), and
let the application designer concentrate on the logical relationships and
access pathways. Today's 'smart' RDBMS can monitor access and make
suggestions to the DBA on re-organising data physically, to suit the
pathways encountered in practice. As far as I am aware, there is no such
facility in IDCAMS...

5. There is certainly no gain today in putting fillers into 'record's on a
RDB or defining 'records' with OCCURS clauses, not because it violates some
'ivory tower' rule about second normal form, but because it is simply
unnecessary. The only time I could envision someone doing this is when they
were using the RDB simply as a repository for existing data while it is in a
stage of transition from VSAM to RDB. (Having successfully carried out
several of these transitions and developed tools to help me do it, I have
some insight into this...)

Both of you have ably demonstrated :-) why I might suggest that 'knowing'
about VSAM could be divantageous when it comes to RDB. Everything else I
might want to say on this subject was covered (with examples) in my response
to Frank.

(I DO care about people who ask for help, and don't reject what is offered
because it doesn't fit 'what we do now'...:-))

Pete.



<docdwarf@panix.com> wrote in message news:dt4h15$rrb$1@reader2.panix.com...
> In article <45lpfoF7al79U1@individual.net>,
> Pete Dashwood <dashwood@enternet.co.nz> wrote:
>
> [snip]
>
>
> That might be dependent on the qualities of one's teachers (or one's
> innate abilities to learn), Mr Dashwood; I was taught, e'er-so-long ago,
> that data are to live in one place, be read once and written once... these
> seem to be remarkably close to the Normalisation Rules posted here
> recently.
>
>
> Now I am ... 'where the data structure IS really important'
> (emphasis original)? The only 'important data structure' I was taught was
> 'always leave as many bytes of filler at the end of a record as you can
> get away with For Future Use'... or am I missing something? Primary key,
> maybe a couple of alternate keys and as many 'external' (in databases
> sometimes called 'foreign') keys as possible, that what got hammered into
> us.
>
> (The classic example of a file design that *didn't* fit into the
> Normalisation Rules was Order History, which usually looked something
> like:
>
> 01 C01752-ORDHIST-REC.
> 05 C01752-ORDHIST-CUSTKEY PIC X(10).
> 05 C01752-ORDHIST-ORDNO OCCURS 1 TO WS-ORDHIST-MAX TIMES
> DEPENDING ON A1658-ORDHIST-INX
> PIC X(15).
>
> ... where the CUSTKEY came from the A1658-CUSTMAST file (which also has a
> COMP-3... errrrr, packed decimal field for the ORDHIST-INX (so you could
> know how many orders a customer had placed without making that second read
> of the ORDHIST file... useful for generating special offers and
> promotions, of course) (and, of course, it was name -INX because the
> suffix -IDX was reserved for datanames generated by the INDEXED BY
> clause and woe betide the coder who ignored this... or, actually, who *got
> caught* ignoring this, somehow one or two or three always managed to slip
> into Prod... into the programs that blew up most frequently at 2:am...
> funny how that happens... zzzzzZZZZZzzzzzz....
>
> DD
>



Pete Dashwood

2006-02-18, 6:55 pm


"Michael Mattias" <michael.mattias@gte.net> wrote in message
news:gNkJf.32440$F_3.30695@newssvr29.news.prodigy.net...
> <docdwarf@panix.com> wrote in message
> news:dt4h15$rrb$1@reader2.panix.com...
>
> Excellent example of using one's head instead of blindly following some
> set
> of Postulates.
>
> While using an RDMBS you might not write that A1658-ORDHIST-INX "number of
> orders" and instead rely on an in-code "SELECT COUNT .." statement the
> same
> logic applies: You can avoid the second hit on the database by "bending a
> rule" and storing a redundant value. Wether or not that second hit
> *should*
> be eschewed is (ta dah!) "application dependent" and rightly the province
> of
> the designer-on-the-scene and not that of some ivory-tower 'guru' who has
> produced a well-regarded tome.
>
> But regardless of storage method (KSDS VSAM or RDBMS), I just see too many
> similarities in the 'thought process' to dismiss my theory: design skills
> acquired using one storage method are highly portable to the other.
>
> MCM
>

I disagree. :-)

Pete.


2006-02-18, 9:55 pm

In article <45pjqpF7lpfrU1@individual.net>,
Pete Dashwood <dashwood@enternet.co.nz> wrote:
>Some quick comments:
>
>1. What you were taught was very good. Sadly, my experience (across many
>sites and several continents) has shown this is not often the case.


Eh? Sadly, your experience shows that it is not often the case that what
I was taught was 'very good'? First time you've mentioned that, Mr
Dashwood.

>
>2. Anybody who uses packed fields for keys, deserves to be pulled out of bed
>at 2am... :-)


Anyone who doesn't do what Someone of Sufficient Authority requests finds
another job, too.

>
>3. I don't intend to argue this with you or Michael because I really don't
>care how either of you define and access your (or your employer's) data. If
>you think that using an OCCURS clause helps, well, good luck...


I think that doing what Someone of Sufficient Authority requests often
delays the frequency with which I have to find another job, aye.

>
>4. Many of the arguments over inefficiency in using multiple tables have
>been rendered academic by modern RDBMS where dependant or related tables are
>often cached and in memory anyway. Technology has allowed the physical
>structure to remain the domain of the DBA (where it properly belongs), and
>let the application designer concentrate on the logical relationships and
>access pathways. Today's 'smart' RDBMS can monitor access and make
>suggestions to the DBA on re-organising data physically, to suit the
>pathways encountered in practice. As far as I am aware, there is no such
>facility in IDCAMS...


.... and I don't recall seeing anywhere in the thread where it was
suggested that this had any sort of relevance, Mr Dashwood; might you be
so kind as to explain how this is germane to the discussion?

>
>5. There is certainly no gain today in putting fillers into 'record's on a
>RDB or defining 'records' with OCCURS clauses, not because it violates some
>'ivory tower' rule about second normal form, but because it is simply
>unnecessary. The only time I could envision someone doing this is when they
>were using the RDB simply as a repository for existing data while it is in a
>stage of transition from VSAM to RDB.


Look to my response to 3) above, Mr Dashwood, and you might learn another
reason.

>(Having successfully carried out
>several of these transitions and developed tools to help me do it, I have
>some insight into this...)
>
>Both of you have ably demonstrated :-) why I might suggest that 'knowing'
>about VSAM could be divantageous when it comes to RDB.


I do not understand the difference between knowing and 'knowing' as you
use it above, Mr Dashwood... but you seem to be saying that certain kinds
of ignorance have their advantages.

>Everything else I
>might want to say on this subject was covered (with examples) in my response
>to Frank.
>
>(I DO care about people who ask for help, and don't reject what is offered
>because it doesn't fit 'what we do now'...:-))


You are not the only shop out there, Mr Dashwood, and, as my Sainted
Paternal Grandfather - may he sleep with the angels! - used to say, 'Never
use yourself as a comparative... you'll only be disappointed.'

DD
LX-i

2006-02-19, 3:55 am

Douglas Gallant wrote:
> Since you are using UCOB (or OCOB), I'm a little surprised by the use of
> Common Storage rather than the COBOL standard EXTERNAL syntax. I haven't
> been in the details of RDMS lately but I believe you could declare the
> SQLSTATE or the RDMCA that way succesfully.
>
> We still use DMS predominantly and programs have to copy the records, etc to
> common-storage (subschema section) to allow for DMS subroutines. Because of
> that we NEVER use common-storage for any other reason and use EXTERNAL
> instead.


Well, that's pretty much because I was never taught EXTERNAL. :) (In
fact, I still don't quite know what that does - I should probably look
into it.)


--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~
~ / \ / ~ Live from Montgomery, AL! ~
~ / \/ o ~ ~
~ / /\ - | ~ daniel@thebelowdomain ~
~ _____ / \ | ~ http://www.djs-consulting.com ~
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
~ GEEKCODE 3.12 GCS/IT d s-:+ a C++ L++ E--- W++ N++ o? K- w$ ~
~ !O M-- V PS+ PE++ Y? !PGP t+ 5? X+ R* tv b+ DI++ D+ G- e ~
~ h---- r+++ z++++ ~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~
Pete Dashwood

2006-02-19, 7:55 am



<docdwarf@panix.com> wrote in message news:dt8mej$2h1$1@reader2.panix.com...
>
> In article <45pjqpF7lpfrU1@individual.net>,
> Pete Dashwood <dashwood@enternet.co.nz> wrote:
>
> Eh? Sadly, your experience shows that it is not often the case that what
> I was taught was 'very good'? First time you've mentioned that, Mr
> Dashwood.
>

I have absolutely no doubt you know exactly what the intended meaning is
here. :-)

However, to spare us all the inevitable quote from Wittgenstein, I'll say it
again:

"It makes me , that in my experience, the good teaching the Doc received,
is not the norm." I could go further and say that programmers are often
left to do what they can with what they have, and when what they have is
VSAM they will biild systems based around the structure of the data they are
required to process. The result is often a proliferation of flat fliles
with much redundant and duplicated data. This is no reflection on the
people who built the mess; they did the best they could.

>
> Anyone who doesn't do what Someone of Sufficient Authority requests finds
> another job, too.
>
>
> I think that doing what Someone of Sufficient Authority requests often
> delays the frequency with which I have to find another job, aye.
>


ROFL! The topic is "embedded SQL in COBOL" and we have a Nuremburg defence
from the Doc in support of repeating groups in VSAM 'database' design...
:-)

Ok Mr. Jobsworth, what other bad practices do you justify by the desire not
to change places of employment :-)?

Suppose they told you to ensure that all keys were binary?

Suppose they told you to NEVER use an alternate index?

suppose they said no more than ONE index per dataset?

Suppose they insist that GO TO MUST be used, and every paragraph must be
preceded by an ALTERable paragraph that can direct control around it...?

Suppose they say: "This must be ready by Thursday."

They pay the money; I do what I'm told... more than my job's worth to
challenge Authority... mumble mutter... zzzzzZZZZzzzz

Pete.

(Hey, I just had a thought... maybe the reason I DO change jobs a lot isn't
because I enjoy diversity...:-))



2006-02-19, 7:55 am

In article <45r4snF7qva4U1@individual.net>,
Pete Dashwood <dashwood@enternet.co.nz> wrote:
>
>
><docdwarf@panix.com> wrote in message news:dt8mej$2h1$1@reader2.panix.com...
>I have absolutely no doubt you know exactly what the intended meaning is
>here. :-)
>
>However, to spare us all the inevitable quote from Wittgenstein, I'll say it
>again:
>
>"It makes me , that in my experience, the good teaching the Doc received,
>is not the norm."


Thanks much for the clarification, Mr Dashwood.

[snip]

>
>ROFL! The topic is "embedded SQL in COBOL" and we have a Nuremburg defence
>from the Doc in support of repeating groups in VSAM 'database' design...
>:-)


Leaving aside that this might be seen as a manifestation of Godwin's
Law... Mr Dashwood, are you saying that 'if I want to work at X's company
then, ultimately, I have to do things in a fashion which X agree with'
such a defense?

>
>Ok Mr. Jobsworth, what other bad practices do you justify by the desire not
>to change places of employment :-)?
>
>Suppose they told you to ensure that all keys were binary?


I'll deal with such a thing when it happens, Mr Dashwood.

>
>Suppose they told you to NEVER use an alternate index?


I've worked on jobsites where that was a requirement, Mr Dashwood.

>
>suppose they said no more than ONE index per dataset?


I've worked on jobsites where that was a requirement, Mr Dashwood.

>
>Suppose they insist that GO TO MUST be used, and every paragraph must be
>preceded by an ALTERable paragraph that can direct control around it...?


I've worked on jobsites where half of that was a requirement - GO TO the
ABEND routine - and as for the other half... I'll deal with such a thing
when it happens.

>
>Suppose they say: "This must be ready by Thursday."


I've either done it or I've said 'Sorry, you need to find someone else,
that is beyond my capabilities for these reasons:...'

>
>They pay the money; I do what I'm told... more than my job's worth to
>challenge Authority... mumble mutter... zzzzzZZZZzzzz


What part of 'if you want us to pay you then you'll fulfill our
requirements' do you find limited to the Third Reich, Mr Dashwood? This
sort of thing might, possibly, be a bit beyond the realm of your
experience; I would suggest you do a bit of research on the relationship
that had been said to exist - for a few year's now, by what I have seen -
between the one who pays the coder... errrrrr, piper and the one who calls
the tune.

When it comes to being a consultant I will listen to what I am told is
required of me and if I disagree then I will explain my disagreement,
whether it be in technical terms or aesthetic ones. After I make my say I
will, then, do the job that my client says I will be paid to do; if I
offend them sufficiently - or they me, for that matter - then I'll find
another job.

>
>Pete.
>
>(Hey, I just had a thought... maybe the reason I DO change jobs a lot isn't
>because I enjoy diversity...:-))


Enjoying diversity is one thing, Mr Dashwood... refusing to do the job
that someone is paying you for is another.

DD
Michael Mattias

2006-02-19, 6:55 pm

<docdwarf@panix.com> wrote in message news:dt9svg$9qc$1@reader2.panix.com...
>
> Leaving aside that this might be seen as a manifestation of Godwin's
> Law... Mr Dashwood, are you saying that 'if I want to work at X's company
> then, ultimately, I have to do things in a fashion which X agree with'
> such a defense?


If Pete won't say it, I will : You take the man's paycheck, you follow the
man's rules.

MCM




2006-02-19, 6:55 pm

In article <dt%Jf.10172$rL5.3158@newssvr27.news.prodigy.net>,
Michael Mattias <michael.mattias@gte.net> wrote:
><docdwarf@panix.com> wrote in message news:dt9svg$9qc$1@reader2.panix.com...
>
>If Pete won't say it, I will : You take the man's paycheck, you follow the
>man's rules.


It just might be, Mr Mattias, that while a consultant could, in fact, know
better than the client what the client needs most... the client, in
general, knows almost as well as the consultant what the client is wishes
to pay for.

'I know you called and paid for the traditional tune to which Hanley set
the words of 'Scotland the Brave'... but *I* think what you really need is
my award-winning rendition of 'It's A Great Day for The Irish'.'

DD

Michael Mattias

2006-02-19, 6:55 pm

<docdwarf@panix.com> wrote in message news:dta6sn$jae$1@reader2.panix.com...
> In article <dt%Jf.10172$rL5.3158@newssvr27.news.prodigy.net>,
> Michael Mattias <michael.mattias@gte.net> wrote:
news:dt9svg$9qc$1@reader2.panix.com...[color=darkred]
company[color=darkred]
the[color=darkred]
>
> It just might be, Mr Mattias, that while a consultant could, in fact, know
> better than the client what the client needs most... the client, in
> general, knows almost as well as the consultant what the client is wishes
> to pay for.


I guess you didn't get the memo: Those of us who are consultants rather than
mere functionaries convinced the client to change his rules.


MCM









2006-02-19, 6:55 pm

In article <yr1Kf.10204$rL5.4011@newssvr27.news.prodigy.net>,
Michael Mattias <michael.mattias@gte.net> wrote:
><docdwarf@panix.com> wrote in message news:dta6sn$jae$1@reader2.panix.com...
>news:dt9svg$9qc$1@reader2.panix.com...
>
>I guess you didn't get the memo: Those of us who are consultants rather than
>mere functionaries convinced the client to change his rules.


Schiller is rarely quoted in the memoranda I receive, Mr Mattias; he is
attributed with coining 'Against stupidity the very gods contend in vain'
and as a consultant I do not presume myself to get results denied such
divinities.

DD

Pete Dashwood

2006-02-20, 3:55 am


<docdwarf@panix.com> wrote in message news:dt9svg$9qc$1@reader2.panix.com...
> In article <45r4snF7qva4U1@individual.net>,
> Pete Dashwood <dashwood@enternet.co.nz> wrote:
>
> Thanks much for the clarification, Mr Dashwood.
>
> [snip]
>
>
> Leaving aside that this might be seen as a manifestation of Godwin's
> Law... Mr Dashwood, are you saying that 'if I want to work at X's company
> then, ultimately, I have to do things in a fashion which X agree with'
> such a defense?
>
>
> I'll deal with such a thing when it happens, Mr Dashwood.
>
>
> I've worked on jobsites where that was a requirement, Mr Dashwood.
>
>
> I've worked on jobsites where that was a requirement, Mr Dashwood.
>
>
> I've worked on jobsites where half of that was a requirement - GO TO the
> ABEND routine - and as for the other half... I'll deal with such a thing
> when it happens.
>
>
> I've either done it or I've said 'Sorry, you need to find someone else,
> that is beyond my capabilities for these reasons:...'
>
>
> What part of 'if you want us to pay you then you'll fulfill our
> requirements' do you find limited to the Third Reich, Mr Dashwood? This
> sort of thing might, possibly, be a bit beyond the realm of your
> experience; I would suggest you do a bit of research on the relationship
> that had been said to exist - for a few year's now, by what I have seen -
> between the one who pays the coder... errrrrr, piper and the one who calls
> the tune.
>
> When it comes to being a consultant I will listen to what I am told is
> required of me and if I disagree then I will explain my disagreement,
> whether it be in technical terms or aesthetic ones. After I make my say I
> will, then, do the job that my client says I will be paid to do; if I
> offend them sufficiently - or they me, for that matter - then I'll find
> another job.
>

OK, I'm glad we cleared that up... :-)
>
> Enjoying diversity is one thing, Mr Dashwood... refusing to do the job
> that someone is paying you for is another.


There are alternatives in between. But I was rattling your chain anyway :-)

Pete.


Pete Dashwood

2006-02-20, 3:55 am


"Michael Mattias" <michael.mattias@gte.net> wrote in message
news:dt%Jf.10172$rL5.3158@newssvr27.news.prodigy.net...
> <docdwarf@panix.com> wrote in message
> news:dt9svg$9qc$1@reader2.panix.com...
>
> If Pete won't say it, I will : You take the man's paycheck, you follow the
> man's rules.
>


It really depends what the man is paying you for. For example, if he is
paying you to help him make the rules, then that statement doesn't
completely apply... :-) (I quite often find myself in that situation;
consultancy (in the true sense) means advising people, and if they need
advice it is usually because they are not too certain about what the rules
in their particular instance need to be.)

I don't disagree with the statement as both you and the Doc expressed it
(and I WAS being mischevious