Download as pdf or txt
Download as pdf or txt
You are on page 1of 10

Static SQL on DB2 for zOS Packages, Collections

(0:05 - 0:15)
Good morning. Welcome to the webinar. My name is David Simpson.

(0:17 - 0:36)
I will be your host for the next few minutes, or close to an hour, I suppose. And the topic
today is Static SQL on DB2-ZOS. So, thanks for tuning in.

(0:37 - 0:59)
This webinar is a little bit different than some of the topics that I have presented here in the
past. It's a little more of a beginner topic. And when I say beginner, it's just kind of basic to
the way we operate with SQL that runs natively on the mainframe, usually.

(1:00 - 1:28)
But I find it's a topic that there's still a lot of confusion on. And actually, I had a few people
ask me recently, what class should I take if I just want to understand packages and plans and
collections, and how all of that stuff works. And we do have this stuff embedded in some of
our classes, but I thought it was a good topic that would make for a good 45-minute webinar
or so.

(1:28 - 1:52)
So, I put this together over the last few weeks, and hopefully you'll find it helpful. Hopefully,
those of you who already do have a firm grasp on this stuff can share this with your
colleagues that don't. So, thanks for tuning in.

You've got my email address on the screen there. Again, my name is David Simpson. You can
always reach me at that email address.

(1:52 - 2:03)
You can follow us on Twitter. And that's a great way to get in touch with me. I don't mind
interacting with you guys at all.

(2:03 - 2:19)
It's one of the ways I stay in touch with what goes on in the real world. I've talked about me
in the past and what my background and experience is on past webinars. So, if you want to
know more about me, you can go back and look at some of the replays on that.

(2:19 - 2:51)
The replay for this one will be available either later today or maybe tomorrow. So, if you
want to share this with friends and colleagues, you'll be able to do that. The link for that is
down at the bottom here, www.themisinc.com. And you can use that link both to look at
the replay of this webinar later.

(2:52 - 3:06)
You'll see the other webinars that we've done over the last couple of years. We've been
trying to do about one a month on various topics, some of them DB2, some of them Oracle.
We've got a couple of MQ topics out there.

(3:09 - 3:26)
And a few Java ones as well. So, we've kind of covered the spectrum of the kinds of classes
that we teach. And you can get little samples of what we teach and what it looks like and
take away a little bit of free information from these webinars.

(3:26 - 3:38)
As I said, we've been doing them for about two years at a clip of about one a month. So,
there's a bunch of them out there now. Also, if you'd like to get the slides for today's
webinar, they are also already out there right now.

(3:39 - 3:58)
Again, the link is www.themisinc.com. And right at the top, you will see a slot where the
replay for this is going to go. And you can download the slides right now, even if you'd like
to follow along. So, please take advantage of that.

(3:59 - 4:08)
A little bit of word from our sponsor. Themis Education is the company that I work for. We
teach classes.

(4:09 - 4:21)
Some of our offerings are listed at the top there. We do a lot of DB2, a lot of Oracle, Java.
And the mainframe is one of our areas of core competence.

(4:22 - 4:42)
And with a specific emphasis on DB2. So, if you check out the rest of our website there,
which you can get to from that link as well, you'll see an awful lot of our offerings. One of
the things you will see on our website is our public schedule, which I will show you a couple
of things I want to highlight there in just a minute.

(4:43 - 4:56)
But also be aware, if you've got a large enough group at your site, that we can come to you
as well. We also do a lot of distance learning on the public schedule especially. So, we've got
a lot of options for how you can get trained now.

(4:58 - 5:20)
And if you have more questions about that, you can feel free to contact me offline. We have
a couple of classes coming up that I wanted to make you aware of. Starting actually next
week, we have both of our beginning and advanced cross-platform SQL being offered next
week in the distance learning environment.

(5:20 - 5:40)
All of these that you're seeing here are guaranteed to run by the end of the year on these
dates. So, we also have some more DB2-specific SQL classes on December 12th specifically.
And November 29th, we've got the performance and tuning, DB2 SQL performance and
tuning.

(5:42 - 6:01)
So, all of these are all ready to go. They're all offered via distance learning, meaning it'll be a
live instructor, but you can take it from really anywhere in the world in the comfort of your
home. So, again, if you want to check out the website, you'll see more about all of these and
other classes.

(6:01 - 6:18)
If you have specific questions, you can feel free to use my email address to get to me. I will
put the email address back up on the board at the end of the webinar in case you didn't
have a chance to get it a couple of minutes ago. So, the topic today is static SQL.

(6:19 - 6:55)
Static SQL on DB2 for ZOS specifically. The mainframe is a little unique in this area because
we are used to static SQL as being kind of the default because of our mainframe heritage
because most of the applications that we supported 15 and 20 years ago on the mainframe
were written in COBOL. COBOL lends itself very nicely to the use of static SQL.

(6:56 - 7:23)
On other platforms, if you go to Oracle or SQL Server or even DB2 on Linux units and
Windows, those folks are a little bit more used to dynamic SQL as being the default. Well,
what's the difference between the two? Static SQL is SQL that we have coded in a program.
We have delimited it to separate it from the rest of our application code.

(7:24 - 7:39)
And in COBOL, we delimit it with the exec SQL and exec delimiters. So everything in
between those delimiters is SQL and not COBOL. And we then send it through a
precompiler.

(7:40 - 8:17)
The precompiler actually pulls out the SQL, rewrites it essentially as COBOL, and then deals
with it separately. Dynamic SQL is an SQL statement that you send off to DB2 dynamically
from your program. And this is typically done, and this can be done in COBOL, but in this day
and age, it's more commonly done by things like Java or .NET or off-platform, off-the-
mainframe things that are connecting up to DB2 to do something, and they send it an SQL
statement and it runs.

(8:18 - 8:38)
The major difference there is static SQL is known to DB2 ahead of runtime. We've
preprocessed it and compiled it even, if you will, or bound it in DB2 terms. Where dynamic
SQL is DB2 doesn't necessarily know about it until it shows up and tries to run.

(8:39 - 9:11)
So dynamic SQL, you're typically building a variable in your program that has a SQL
statement in it and then somehow, depending on which platform you're using, sending that
up to DB2 and saying, Hey, run this. So we're going to focus today on static SQL, and with
the assumption that you're using things like COBOL to run static SQL. On other platforms,
the main way we get static SQL is by stored procedures, and that's also a fairly common
thing to do on the mainframe as well.

(9:12 - 10:01)
So if you have a Java program that is connecting up to DB2 to run some things, then if you
want that to be static SQL, one of the main ways we would do that is by calling a stored
procedure where this same process comes into play that we're about to talk about. The
slide that we have in front of us here is one that, when I was fairly new to DB2, going back to
about 1993 or 4, somebody drew this on a paper napkin for me to explain it, and I have
drawn the same picture on paper napkins for others countless times since. And when I
started teaching, I made a slide out of it so I didn't have to sketch it on the paper napkin
anymore.

(10:01 - 10:42)
But this is the compile process or the program preparation process for something like
COBOL. I'm going to use COBOL a lot as the example, but keep in mind, there's lots of
languages that support static SQL on the mainframe, things like PL1 or even C or C++,
Assembler, lots of languages we can use on that mainframe that all support static SQL in the
same way. So you'll see a couple of examples coming up that are COBOL, but just keep in
mind, it could be really any of those languages that are native to the mainframe and support
and have a precompiler supported by DB2.

(10:43 - 11:10)
So up at the top there, we see our source code, the source code coming in to my program
right up here. So that's a module or a text file essentially that has your COBOL source code
in it and then mixed into that source code is SQL. And we've delimited and tagged the SQL
with that execsql delimiter.

(11:11 - 11:37)
We also could have declgens, and declgens are nothing more than copybooks, usually
describing the tables in COBOL terms that are going to be used by this program. And both of
these things come into a process called the precompile. So the precompile's function in life
is to separate the SQL from the COBOL.

(11:38 - 11:53)
And COBOL goes off to the left and SQL goes off to the right. The module coming out to the
left there, we call that the modified source. And usually in your JCL, that'll actually be a
temporary data set.

(11:53 - 12:09)
In other words, we don't keep that. It's just the COBOL code scrubbed of its SQL ready to go
into the compiler. Out the other side of that, we get the SQL, and it goes into a module
called a database request module.

(12:09 - 12:22)
Again, it's just a text file coming out of your precompiler database request module. If you
look inside that, it's just showing you your SQL. It's just your SQL.

(12:23 - 12:45)
And that SQL is parsed and tagged, and it's not pretty. And beginning about in version 8, it's
in Unicode, so if you're looking at it with your editor or browsing it on the mainframe, you're
not even going to be able to read it anymore because we usually look at things in EBCDIC on
the mainframe. But at its core, it's just the text of your SQL.

(12:47 - 13:14)
It's not an executable on its own. It's just got your SQL extracted from the program and
parsed and tagged and put in a format that the bind process can read. On the left side there,
your COBOL stuff goes through a compile and link edit, and you get a load module just like
you had compiled any COBOL program before.

(13:15 - 13:30)
On the right side, your DBRM or your SQL goes through a process called bind. And a bind
produces a package or plan. Beginning in version 10, your really only choice was package.

(13:32 - 13:49)
And that package is, you can think about it like the compiled SQL or the executable stuff, the
stuff DB2 needs to actually run that SQL at runtime. So all of this happens ahead of runtime.
It's part of the program preparation or compile.

(13:51 - 14:02)
And out of the bottom here now, my application or my program is split into two pieces. I've
got the COBOL stuff and the SQL stuff. And the COBOL stuff is in a load module.

(14:02 - 14:28)
The SQL stuff is in a package or plan, which is stored actually inside of DB2. So that package
is not something that spits out into an output data set, but it's actually stored internally
inside DB2. So because my application is now split into two pieces, at runtime I'm going to
have to have some way to get them back together.

(14:29 - 15:05)
In other words, when my program is running COBOL stuff, I'm over here, and then it does its
first call to an SQL statement, and we're going to have to go find this package to run the
stuff that makes up that SQL. So the way DB2 keeps track of all of this is that the
precompiler generates what we call a consistency token. That consistency token, you can
think of it like a timestamp that is placed actually in the modified source and in the DBRM
and carried through down to the bottom.

(15:08 - 15:39)
That consistency token, it's actually just a big hex thing, but you can think of it like a
timestamp that's generated by the precompiler. So DB2 will be able to determine at runtime
that we have appropriately matched up the load module with the package that we're
running. So this is going to become really important later when you're trying to debug that
whole minus 805 SQL code thing.

(15:39 - 16:03)
That's everybody's favorite SQL message. So that consistency token we're going to come
back to later. But this is the guts of our program preparation, and most of this stuff is usually
found in a proc that you execute.

(16:03 - 16:26)
In other words, you change the source module for the program that you want to compile,
and then you type sub, and all of this stuff comes out. When I teach new DB2 developers, I
often ask them, what's a bind? How would you define a bind? And the most common
answer I get is, well, it's the last step of my proc. I know I've got to have it.
(16:27 - 16:49)
I know that if I don't get it right, then bad things happen when I try and run the program.
But a lot of people are not too terribly interested in figuring out what goes on in there. So
that's what we want to talk about today is this whole bind process and what gets produced
and what happens when I screw it up.

(16:52 - 17:18)
So let's go ahead and take a look at some of the steps that are in this proc and see what we
can find. Now, as I said, usually compiles are done in JCL procs. This one I actually broke out
into a set of steps in JCL without using the proc so that we can see what all the steps
actually do.

(17:21 - 17:39)
What you're seeing here is the JCL for the precompiler, that precompile step. It's actually a
module in DB2 called DSN HPC for the free compiler. And you see we've got a bunch of
parms we send in.

(17:39 - 17:57)
We tell it what language we're using and a bunch of options that we'll talk about, a couple
of those in just a second. We also have a bunch of files coming and going here that we
should probably look at. So things like, no, there's my source code.

(17:57 - 18:13)
There's a DD in the precompiler called sysin. And I've got a partition data set there that has
a member called lotsa sq1. So that is a COBOL program source code.

(18:13 - 18:33)
And, again, that COBOL program has COBOL in it, and it's got a bunch of delimited SQL
statements in it as well. So that's my source code. We're also going to have an input library
for declgens.

(18:34 - 18:53)
Again, so this is copybooks. The difference between these is, for those of you who are
COBOL developers, you can bring copybooks into a DB2 program one of two ways. You
could say exec SQL include, and that is what's going to be brought in here.

(18:54 - 19:15)
Or you could just say copy, a regular old COBOL copy. The main difference is, where is it
going to be brought in? Is it going to be brought in by the precompiler, or is it going to be
brought in by the compiler? Certain ones we're going to need, you know, the precompiler
needs access to. Your declgens are needed by the precompiler in order to determine what
your tables look like.

(19:18 - 19:45)
So if the precompiler is going to need to see it, then you better do an exec SQL include, and
it will pull it out of this library right here. Or you could concatenate other libraries in here as
well. So my declgens, my includes are going to come out of a library, in this case called
themis.declgen. It's another important distinction to make here is that the precompiler itself
does not talk to a particular DB2 subsystem.

(19:46 - 20:03)
We can run the precompiler even if DB2 is not up and running. The precompiler does not
connect to DB2. The only thing it knows about your tables is what you tell it, and the way we
tell it about the tables that are being used is via these declgens.

(20:03 - 20:45)
So a declgen has two pieces to it, and it's got a description of the table in DB2 terms, and
then it's got a description of the table in COBOL terms. And it's got variables, right, COBOL
data structures that contain COBOL variables for each of the columns on your table. So DB2
doesn't know anything about the actual tables, or I'm sorry, the precompiler, I should say,
does not know anything about the actual tables that you've got defined in DB2, and it
actually doesn't care, and the precompiler is actually not concerned about any particular
DB2 subsystem.

(20:45 - 21:21)
So I can take what comes out of this and bind it against my test DB2 subsystem or my
production DB2 subsystem or any other DB2 subsystem that has the tables that we're
describing here. So the precompiler does not connect to DB2, and what comes out of it
could actually be bound to multiple DB2 systems. So the declgens and the source code come
in, and then what comes out? Well, this syscin is the DD that's going to have the modified
source going out to the compiler.

(21:21 - 21:40)
Now, as I mentioned before, that's usually a temporary data set. So that's what the
ampersand, ampersand, DSNH out. If the compile is just the next step in this JCL stream,
we'll just take this temporary data set in, and there's no real need to preserve it.

(21:41 - 21:56)
It can easily be generated again by running the precompile again. You want to keep your
source code, and you want to keep the load module that comes out, but I don't really need
this modified source member. This is just going to be what goes into the compiler.

(21:57 - 22:18)
We'll actually see a small sample of what that looks like in a moment. And then we have one
other output from the precompiler, and that is the DBRM. So I've got a DBRM member,
themis.db2.dbrmlib, and then my member name is lotsa.sq1, the name of the program.

(22:19 - 22:34)
So that is going to be where that database request module, or DBRM, goes. And remember,
the DBRM is just the SQL that was extracted out of this source code. So we've got two
inputs, really, and two outputs.

(22:34 - 22:45)
Declogens and source code come in, DBRMs and modified source go out. Modified source
goes to the compiler. The DBRM goes off to the process called bind.
(22:48 - 23:14)
Now, another thing we should look at on the precompile is this version. A lot of confusion
about versioning, and I'm going to try and talk about it a little bit in a moment, but this
version auto parameter going into the precompile is what asks db2 to please version the
package that's going to be resulting from this when I do the bind. If I don't have this, then
versioning will be off.

(23:16 - 23:50)
And all that means is I'm only going to have one copy of this program in a particular
collection in db2 at a time. If versioning is on, and in this case we're saying db2
automatically generate the version ID, then every bind that I do that comes out, you know,
if I compile this program five times, I'll generate five different versions, and therefore five
different packages. In other words, when I do the bind, the subsequent binds will not
overlay the ones that are already there.

(23:52 - 24:15)
When I was first trying to figure out versioning, I was looking in the bind for bind options
related to this version, and that's not where you find them. You actually find it all the way
back up at the precompile. So another way to say this is a DBRM coming out of this is
versioned, and therefore any packages that are created from the DBRM produced will be
versioned.

(24:16 - 24:57)
And we'll talk a little bit more about what that means in a moment. You can see a little bit
about what the modified source does. So in my source code, in the middle here, you see I
have execsql and I'm doing a select into, and what comes out of the modified source is
actually, you'll actually see this code, the execsql, if you were to look at that modified source
member that was the temporary data set, or if you just look at your COBOL compile listing
coming out of the compiler, you will actually see that the execsql stuff commented out.

(24:58 - 25:12)
It doesn't remove it, but it just comments it out for the COBOL compiler. In other words, the
COBOL compiler does not understand how to deal with this, that SQL. Now there is a small
exception to that.

(25:13 - 25:38)
Some of the shops I work with have actually used the integrated precompiler. In other
words, there's flavors of the compiler now that you can use that have the precompiler kind
of integrated into it, so it's one step instead of two. That was introduced probably over ten
years ago, and I don't see a ton of people using it, although I do have a couple of shops that I
work with that use that integrated compiler.

(25:38 - 26:07)
But most shops still go through the precompile-compile-link-edit-bind process. If you look at
that modified source, you'll see the SQL actually commented out, and it will translate it into
calls to this module called dsn-hli. dsn-hli is actually a routine supplied by DB2, by IBM, and
that's where it's actually going to do the results of this SQL.

(26:07 - 26:29)
It's actually going to go find that package in DB2, or look for it anyway, and execute it. And
you notice that it has a whole structure of things that it passes in and out of dsn-hli. So
basically it's going to be saying, please run this program with this consistency token and this
statement number.

(26:30 - 27:09)
So every statement coming out of the precompile will be tagged with a number, and if you
don't override it, that number will be taken from the line number in the precompile listing.
So in other words, a statement beginning on line number 72 will be statement number 72,
and when we run it at runtime, it's going to be calling this dsn-hli, saying this program, this
consistency token, run statement 72. So dsn-hli is calls to a DB2 module, and the actual
module that's going to be run under the covers actually depends on how we link edit this
thing at runtime.

(27:10 - 27:19)
But this is how DB2 is actually going to deal with this at runtime. Go find the package. Well,
call a module that DB2 supplies.

(27:20 - 27:42)
And you see some other generated code down here. This is if you use a whenever
statement, the stuff at the bottom. Sorry about that.

I blanked the screen out for a second. I don't see a ton of people use a whenever. It's just
kind of a way to cheat with error handling.

(27:42 - 28:07)
But if you use the whenever statement, DB2 will also generate this kind of default error
checking down at the bottom. All right, so let's take a look at the bind. So here is a sample
bind.

(28:08 - 28:29)
You notice that the input to the bind is going to be that same DBRM library that we were
looking at before, that came out of the precompiler. The bind control card itself is a little bit
confusing to me. Now notice here we are, and I don't have a pointer at this, but we are
talking about a particular DB2 system here.

(28:29 - 28:58)
So while the precompiler did not attach itself to any particular DB2, the bind process does.
You can think about the bind as it's taking the DBRM at that database request module, has
the SQL for a single COBOL program, and it is binding it to a particular DB2 and a particular
set of tables on that DB2 system. So the precompiler doesn't know for sure what my tables
look like.

(28:59 - 29:21)
The bind does. So if you spell a column name wrong, if you say select last name and you
spell last name wrong in your source code, you might get a warning out of the precompiler
like, yeah, you didn't tell me about any tables that had that column name. But the
precompiler doesn't really know what that table looks like.
(29:21 - 29:35)
The bind does. So if you spell things wrong, the bind is where you'll get the hard errors
saying, yeah, that column doesn't exist or that table doesn't exist. So a lot of your hard
errors actually come out of the bind process.

(29:36 - 29:59)
So here we're telling it I'm going to bind this package on a DB2 subsystem called DB1A, and
then the collection, this is where the syntax gets a little bit confusing for me anyway. I say
bind package, and I'm expecting to put a package name in those brackets, but you actually
put the collection ID. Now we're going to talk about what a collection is in just a second.

You might also like