Professional Documents
Culture Documents
April 2004
Developed by
Administrative Technology Services (ATS)
Iowa State University
Ames, IA
Copyright © 1988-2004 Iowa State University Administrative Technology Services. All rights reserved.
Contributors:
Past and present employees of the ISU ATS Center have helped develop and maintain this handbook.
All rights reserved. No part of this writing may be reproduced in any form or by any means without permission in
writing from Iowa State University.
Disclaimer
Although the information contained in this handbook has been used by the contributors and the ISU Administrative
Technology Services, neither the contributors, ISU Administrative Technology Services, Iowa State University, nor
the State of Iowa, express or imply any warranty as to the accuracy and functioning of the information, any program
developed using this information, or any related materials. Distribution does not constitute any such warranty.
Neither the contributors, ISU Administrative Technology Services, Iowa State University, nor the State of Iowa
assume responsibility in connection with this distribution.
It is understood that no claims will be made against the contributors, ISU Administrative Technology Services, Iowa
State University, or the State of Iowa in connection with the information contained in this handbook or with related
materials.
Preface
This handbook is a reference guide to the use of IBM's DB2 System within Administrative Technology Services,
Iowa State University, Ames, Iowa. It gives attention to the development steps an analyst should take in the design
and implementation of DB2 application systems.
This handbook is intended to be a reference source for programmer/analysts to aid them in their development of
application systems using DB2. It contains many hints, tips and techniques that can be used during the development
process.
DB2 Objects
Database
As described above, databases are a collection of DB2 objects. When you define a database, you give a name to an
eventual collection of tables, indexes, and table spaces in which they reside. A single database, for example, may
contain all the data associated with students (students, courses, grades, etc). Databases do not physically exist, but
they are a logical group of DB2 objects that DB2 uses to assign certain authorities and that permit sensible
management of data.
Storage Group
A storage group is a named set of direct access storage device (DASD) volumes from which DB2 automatically
allocates storage space, defines the necessary VSAM datasets, and extends or deletes them as required.
Table Space
A table space is a VSAM dataset in which one or more tables are stored. It is a physical object for which disk space
is allocated using primary and secondary quantities. A table space is broken up into pages of four kilobytes each,
which DB2 uses as the unit of I/O. DB2 utilities (RUNSTATS, REORG, and COPY) all run against table spaces
(not tables).
Table
A table contains data about a given entity. A table is made up of rows (tuples) and columns (attributes). The rows of
a table are unordered, and are physically stored in a table space. For example, a student entity (table) would consist
of a row for each student and columns such as student ID, student name, and student status. A table may be defined
to have a primary key, a column or set of columns whose values uniquely identify each row (student ID in the
student entity).
Index
An index is an ordered set of pointers to the data in a table, stored separately from the table. Each index is based on
the values of data in one or more columns of a table. Once an index is created, it is maintained by DB2, and DB2
decides when to use or not to use the index to access data in a table. Indexes serve two purposes: they are used to
enforce uniqueness of rows in a table, and they enhance the performance of data retrieval operations.
View
A view is a logical table that is derived from combining tables and/or other views into a single, logical table. A view
can also be a subset of columns from a single table or view. Like a table, a view consists of rows and columns, but
unlike a table, the data in a view is not physically stored. A view is defined to DB2 by referencing other views or
tables, and the definition of the view is the only thing that is physically stored in the DB2 Catalog. When a user
references a view, DB2 assembles the data from the underlying tables and views according to the definition. It is
essentially transparent to the user whether the base table or logical view is being used. Views are a powerful tool
used in relational databases, which can be used to simplify SQL coding, and as a security device to restrict which
columns of a table a user can access.
System Design
Start by reviewing the notebook labeled Database Design Information. See a Database Administrator for a
copy of this notebook. It covers various aspects of DB2 Database Design that are very important to know before
your design begins and to ensure that the production system will be flexible and operate efficiently.
Write a summary of the application specifications and get agreement from the client department. Define key data
elements, type of transactions (CICS, QMF, Query Tool or Web based) that will be used the majority of the time,
and the reports needed by the client.
Table Definition
Decide which data elements can be stored in one row and if multiple tables are necessary for data that is related by
one-to-many. Experience with DB2 has shown that high CICS transaction processing can have the data stored in
normalized tables. But high QMF, Query Tool, or Web based query usage requires the data to be stored in slightly
de-normalized tables to avoid large numbers of table JOINS, which increase CPU usage. Try and find a balance
point in between to have both flexibility AND performance. Define table structures and perform normalization of
the data elements and de-normalization if required, documenting the reasons for the de-normalization.
1. There is a maximum of 750 columns per table row, and each row should not be longer than 4000 bytes so that
DB2 can use the more efficient 4K pages rather than 32K pages.
2. Minimize the number of tables with row length less than 32 bytes and greater than 2037.
3. Use NULL as a default value for a column under the following conditions:
• It is used as a Primary or Foreign key when using DB2's Referential Integrity
• It is a DATE type column and the date is normally unknown
5. Use DATE, TIME, and TIMESTAMP data types when date and time fields are required. Be aware that when
using these column types, a valid DATE, TIME, or TIMESTAMP must be in the column. They cannot
contain spaces when defined as NOT NULL WITH DEFAULT.
6. If columns are used in a JOIN, data type and length should be the same.
8. Columns that are frequently updated together should be grouped together in the DB2 table layout to reduce
the amount of DB2 logging when an UPDATE SQL statement is executed.
9. When denormalizing for performance reasons, be sure to document the previous design and the reasons for
the denormalization.
10. When data items from two or more tables are nearly always accessed together, create a single table rather than
multiple separate tables.
Index Definition
Define the index or indexes that will be needed to retrieve the data from the table. The following should be
considered when selecting indexes:
1. Each DB2 table should have at least one index and it should be unique.
3. Avoid unnecessary indexes. Multiple indexes per DB2 table are allowed but try and keep the number of
indexes per table as low as possible.
7. Indexes used mostly by CICS should be defined as unique. Indexes used mostly by QMF, Query Tool, or
Web based can be defined as non-unique.
8. Consider how data will be added (Clustering index consideration). Only one index can be defined as the
CLUSTERING index. This means that the physical sequence of the data in the table matches the physical
sequence of the keys in this index. Be sure that the data that is to be loaded into the table is in clustering
index sequence.
9. Consider table relationships and create indexes on columns that will be used in QMF, Query Tool, or Web
based and batch JOIN operations.
11. Avoid indexes that have a low Cluster Ratio (<45%), unless the index is to be used for direct selection. If a
large number of rows are returned in a batch program, a QMF query, a Query Tool, or a Web based query that
uses a low Cluster Ratio index, the elapsed time of the batch job or the QMF, Query Tool, or Web based
query may actually be higher than if the index did not exist.
2. Keep the length of the key as small as possible and less than 40 bytes.
4. Consider columns that are frequently used in selections, projections, groupings, ordering, or NOT EXISTS.
Remember that the standards for CICS total SQL executions per transaction are as
follows:
30 Any CICS DB2 application program coded with SELECT, UPDATE, INSERT and/or
DELETE SQL statements (usually display/update programs).
80 Any CICS DB2 application program coded with DECLARE CURSOR/FETCH SQL statements
(usually browse programs). No updates, inserts or deletes.
Pre-Implementation Review
(Refer to the System Development Checklist on SIR)
The system number will normally be used as the basis for the DB2 Database Number.
Enter the required information in the System Documentation system under the system number that was previously
defined. The information should include history of the previous system, if any, system objectives, and program flow
for the CICS system.
In developing the CICS system flow, the program numbers will need to be determined. Also the transaction IDs will
need to be determined. Both the program numbers and the transaction IDs will be needed as input to other systems
during the development process.
Emp#: The ATS employee number of the person responsible for this data.
System Num: This field must contain the ‘ssss’ portion of the DATABASE identifier as used in
the Data Dictionary. Every TABLESPACE must be defined within a DB2
DATABASE. All DATABASEs will be defined for the analyst and the analyst
will be granted authority to CREATE new TABLESPACEs and INDEXes within
this DATABASE. The DATABASE name will be DBssssP for production and
DBssssT for test, where 'ssss' is the DATABASE Identifier. A Database
Administrator can help to determine the appropriate value.
Prod Bill: A value of 'Y' or 'N' indicating the billing status of the TABLESPACE.
Rows: The number of rows expected in this TABLE, six months from now.
Avg Char/Row: The average length of each row within the TABLE. If this is a variable length
table, estimate an average length for the rows. If this is a fixed length table, look
at the comments in the middle of the DCLGEN copybook defined for this table.
See the section entitled Data Definition and Relationships Storage in this manual
for the location of this DCLGEN. Use the length defined by 'INTERNAL DB2
TABLE LENGTH = '.
Max Char/Row: The maximum length of each row within the TABLE. Look at the comments in
the middle of the DCLGEN copybook defined for this table. See the section
entitled Data Definition and Relationships Storage in this manual for the location
of this DCLGEN. Use the length defined by 'INTERNAL DB2 TABLE
LENGTH = '.
Format: The value 'F' (fixed) or 'V' (variable) indicating the format.
Page Size: Default is 4096. The only other option is 32768 (32K), which is highly
discouraged. This means that if the table rows are longer than 4096 bytes, a 32k
page size is needed, but consider splitting the table rows into multiple TABLEs
before using a 32K page size.
Page Pctfree: Specify a percentage of each page (4K) to be left empty when loading or
reorganizing the TABLE. This space is used for adding new rows and expanding
the length of existing rows. If no new rows will be added, specify 00 PCTFREE;
otherwise, specify enough freespace to allow entire rows to be added. If AVG
CHAR/ROW = 400, 10% freespace (4096 x .1 = 410) will allow adding 1 row
per page without having to split the page. Use the ‘FS’ function to determine an
efficient value.
Freespace every The value for this field should usually be 000. DB2 allows leaving every Nth
XXX PAGES: page empty when loading a TABLE. There are 150 4K pages per cylinder on a
3380 disk drive. Assuming the TABLE is at least 1 cylinder or greater:
FREEPAGE EVERY 050 PAGES would provide 3 empty pages/cyl or 2%
The FREEPAGE and PCTFREE figures should be based upon the expected
TABLE activity and growth.
Table Name: This is the table name as defined to the Data Dictionary. When a new table is
being entered into the File System, the message: USE Data Dictionary TO ADD
TABLE NAME will be displayed in this field. The field cannot be updated.
After the table name has been entered in the Dictionary, it will appear in this field
the next time that this screen is displayed.
DB2 Format: This is the table name as defined to DB2 to be used in SQL. When a new table is
being entered into the File System, the message: USE Data Dictionary TO ADD
TABLE NAME will be displayed in this field. The field cannot be updated.
After the table name has been entered in the Dictionary, the DB2 Format name is
derived from the Dictionary Table Name, and it will appear in this field the next
time that this screen is displayed. The DB2 Format name is used in application
program SQL code and in QMF, Query Tool, or Web based.
Books: List all copybooks used with this TABLE. Each TABLE used in a COBOL
program must have a DCLGEN copybook, and this copybook name will have a
'D' as the last character. The copybooks are copied from the appropriate libraries
during pre-compiler processing. Be sure that the first book listed is a 'D' suffix
member, then list any other books associated with the table.
After updating the table information be sure to execute the JPLFILE procedure or the 'AC' function so that the create
table SQL statements will be updated in the appropriate PDS. Executing JPLFILE or the 'AC' function on a table ID
will also check to see if any of the indexes require updating, and if so, they will also be updated. Examples of these
statements can be found in Appendix A.
If the DBA analyst ID (Emp# field) for a DB2 table is changed on the File Definition system, refer to the
execute authority scenario chart in the section: DB2 Authorizations. The chart will indicate whether or not
other steps are required for proper execution of associated programs and procedures.
After updating the index information be sure to execute the JPLFILE procedure or the 'AC' function so that the
create index SQL statements will be updated in the appropriate PDS. Executing JPLFILE or the 'AC' function on
the associated table ID will also check to see if any of its indexes require updating, and if so, they will also be
updated. Examples of these statements can be found in Appendix A.
NOTE: The adds, updates, and deletes are applied to the requested DB2 table when the 'RG' function is executed
during working hours. If the 'RG' function is not executed then the changes will be applied during a nightly batch
procedure. Also, authorizations are only needed for DB2 tables, not for DB2 indexes.
1. An analyst who is not the owner of the DB2 table (DBADM), needs to write a program that selects data from
that table.
2. A client department wants to perform QMF, Query Tool, or Web based selects against the DB2 tables that
contains their data. The clients' ADIN ID would be used.
• This permanent file ID will have an LRECL equal to the DB2 table structure, and one row at a time will be
written to the file by an application program or a DB2 Unload utility. The number of records should equal
the number of rows in the table. The data in the file is in a normal sequential format and can be used for
any application purpose.
• Look at the comments in the middle of the DCLGEN copybook (D suffix book) for this table, to determine
the exact length of this file. See the section entitled Data Definition and Relationships Storage in this
manual for the location of this DCLGEN. Use the length defined by 'EXTERNAL LENGTH = ' for the
length of this sequential file.
• This sequential backup file should be used to backup a DB2 table before a large number of updates are
done to ensure that if there was a program error, the table can be reloaded as it was before the program that
contained the error was executed. This file is also used when an UNLOAD or DROP/CREATE/LOAD
procedures are used. Any application program can use the data contained in the file.
Look in the JPL - Job Procedure Language section for a list of sample procedures that use these files. The sample
procedures can be copied to your own procedure numbers and then modified to use the appropriate table names.
The following is a suggested method for naming the sequential backup file:
Data elements that are defined as numeric should have an 'S' prefix in picture clause to make it a signed field. This
will make the COBOL definition compatible with the DB2 column definition.
After all of the column names for the DB2 books have been entered, use the 'PT' function in the Data Dictionary to:
• Create the DCLGEN (Member name = booknamD e.g. DDELMNTD)
• Create the SQL Data Definition Language (DDL) statements to define the table and each column in the
TABLE , in the DB01.PROD.DB2.TABLEDEF partitioned dataset. (Member name = fileid e.g.
DDT0710D)
• Create the DB2 Load Control Records for the TABLE, in the DB01.PROD.DB2.TABLEDEF partitioned
dataset. (Member name = fileid e.g. DDT0710L)
After the data names have been approved for production, use the 'PP' function in the Data Dictionary to:
• Create the DCLGEN (Member name = booknamD e.g. DDELMNTD)
• Create the SQL Data Definition Language (DDL) statements to define the table and each column in the
TABLE , in the DB01.PROD.DB2.TABLEDEF partitioned dataset. (Member name = fileid e.g.
DDB0710D)
• Create the DB2 Load Control Records for the TABLE, in the DB01.PROD.DB2.TABLEDEF partitioned
dataset. (Member name = fileid e.g. DDB0710L)
Refer to the Data Dictionary Manual for further information regarding general Data Dictionary information.
EXEC SQL
DECLARE DD.ELEMENT TABLE
(REF_NUM INTEGER NOT NULL,
OWNER_NAME CHAR(20) NOT NULL,
FLD_FRMT CHAR(1) NOT NULL,
FLD_LEN SMALLINT NOT NULL,
DECIMAL_PLACE SMALLINT NOT NULL,
DEPEND_REF_NUM INTEGER NOT NULL,
DFALT_HDNG VARCHAR(30) NOT NULL,
DFALT_MASK VARCHAR(30) NOT NULL,
OCCURS_CLAUSE VARCHAR(30) NOT NULL)
END-EXEC.
*TABLE LAYOUT: System NAME=DATA DICTIONARY SYSTEM DDELMNTD
* FILE NAME=DATA DICTIONARY ELEMENT FORMATS DDELMNTD
* SKIP PREFIX=YES DDELMNTD
* TABLE NAME=DD.ELEMENT DDELMNTD
* EXTERNAL LENGTH = 129 DDELMNTD
* INTERNAL DB2 TABLE LENGTH = 100 DDELMNTD
* CREATE DATE=05/27/88 DDELMNTD
* ADP CENTER EMPLOYEE NUM= 41 DDELMNTD
* DATABASE NAME=DBDD01P DDELMNTD
* TABLESPACE NAME=DDB0710T DDELMNTD
* DDELMNTD
01 DDELD-DD-ELEMENT-TBL. 1
12 DDELD-DD-REF-NUM PIC S9(9) COMP. 1
12 DDELD-DD-OWNER-NAME PIC X(20). 5
12 DDELD-DD-FLD-FRMT PIC X(1). 25
12 DDELD-DD-FLD-LEN PIC S9(4) COMP. 26
12 DDELD-DD-DECIMAL-PLACE PIC S9(4) COMP. 28
12 DDELD-DD-DEPEND-REF-NUM PIC S9(9) COMP. 30
12 DDELV-DD-DFALT-HDNG. 34
49 DDELL-DD-DFALT-HDNG PIC S9(4) COMP. 34
49 DDELD-DD-DFALT-HDNG PIC X(30). 36
12 DDELV-DD-DFALT-MASK. 66
49 DDELL-DD-DFALT-MASK PIC S9(4) COMP. 66
49 DDELD-DD-DFALT-MASK PIC X(30). 68
12 DDELV-DD-OCCURS-CLAUSE. 98
49 DDELL-DD-OCCURS-CLAUSE PIC S9(4) COMP. 98
49 DDELD-DD-OCCURS-CLAUSE PIC X(30). 100
The Referential Integrity information located on the right side of the screen has been added to allow for the
definition of Referential Integrity (data validation across tables) when DB2 tables/indexes are constructed. See a
Database Administrator if you need to use this feature.
When creating a new data base or adding a new table to an existing data base, the table information and the
authorization information may be added to the File Definition System. See a Database Administrator before
attempting to use JPLFILE or the 'RG' function. This is only when the DB2 table is new and is going to be
DROP/CREATEd for the first time. If either JPLFILE or the 'RG' function is tried, a message will be returned: "See
a DB2 Administrator". The Database Administrator will establish the table, and the owner of the DB2 table will
then be able to perform all DBADM capabilities on that table.
After the Database Administrator has established the table for the first time, submit your 'JPLFILE' member to
update the DB2 file definitions in a PDS. These members are used in the batch JCL jobs for defining DB2 tables
and indexes. The following are examples of the naming conventions for these members:
When a table is going into production, give the table numbers to the Database Administrators so that a daily job can
be set up to do a full image copy or a partial image copy of the tables for recovery purposes.
Batch - DP function
• For the ‘Plan Execute Authority Ids’, enter IDs of other analysts who will be using this program in
their procedure. The authority will be granted to the analyst(s) at bind time.
• If this program calls another DB2 program, the called program ID will need to be listed in the
‘Package Members to bind into this plan’ section.
• If this is a called program, enter ID’s of other analysts who will be calling this program in the
‘Package Execute Authority Ids’ section. This is usually handled by entering ‘PUBLIC’.
DB2 Reminder
Before changing the owner of a DB2 program on the Source Control, be sure that the new owner has all of
the DB2 table privileges granted that are required for the SQL contained in the program. If this is not
verified, the rebind jobs that are automatically initiated could fail.
The File Definition System shows the IDs of the analysts who have DBA authority in Production DB2. When a DB2
table is displayed using the DS function, the DB2 DBA IDs are shown on the lower left side of the screen. The
analyst for each ID has the capability to grant and revoke table authorizations (select, insert, update, and delete)
using the UA function in the File Definition system.
An edit check in the UA function prevents DBAs from granting authority to themselves. This authority is not needed
because it is implied with the DBA authority. Also, the DB2 DBA IDs are shown on the BA screen in the File
Definition system.
DB2 plan/package authorities are completely independent of DBA authority. If analyst-1 owns a program and
analyst-2 wishes to include that program in a JPL procedure, analyst-1 must grant execute authority to analyst-2,
using the DP screen in the Source Control system.
DB2 Authorizations
DB2 authorizations are granted to individual USER ID(s). In limited cases the DB2 authorization is granted to the
special USER ID named 'PUBLIC' which means any USER ID can perform the function.
Specific table access GRANT(s) are maintained in the File System. For changes to be made effective execute the
'RG' function in the File System or wait until the next day.
Specific EXECUTE GRANT(s) are maintained in the Source System. For changes to be made effective the
appropriate BIND must be performed.
If you want the changes in authority to become effective immediately, you will need to execute the XT and the XP
functions in the Source Control System for each program, to issue the grants and/or revokes to test and production
DB2.
If the owner of a program/procedure changes, the scenario chart needs to be reviewed to determine if any
actions need to be taken to maintain valid execution of the programs and procedures.
1. No action required.
2. Analyst #1 must update the Execute Authority Ids ('DP' function of the Source Control system) with Analyst
#2's ID (without spaces). Analyst #1 must then issue the 'XT' and 'XP' functions of the Source Control system to
actually grant the execute authority in DB2.
3. Analyst #1 must update the Table Authorizations ('UA' function of the File Definition system) with Analyst #2's
ID and determine what authority to provide: SELECT, INSERT, UPDATE or DELETE. Analyst #1 can then
let the system grant the defined authority that night or execute the 'RG' function of the File Definition system to
grant the defined authority immediately.
4. Analyst #1 must update the Table Authorizations ('UA' function of the File Definition system) with Analyst #2's
ID and determine what authority to provide: SELECT, INSERT, UPDATE or DELETE. Analyst #1 can then
let the system grant the defined authority that night or execute the 'RG' function of the File Definition system to
grant the defined authority immediately. Analyst #2 must update the Execute Authority Ids ('DP' function of
the Source Control system) with Analyst #3's ID (without spaces). Analyst #2 must then issue the 'XT' and 'XP'
functions of the Source Control system to actually grant the execute authority in DB2.
5. Analyst #2 must update the Execute Authority Ids ('DP' function of the Source Control system) with Analyst
#1's ID (without spaces). Analyst #2 must then issue the 'XT' and 'XP' functions of the Source Control system to
actually grant the execute authority in DB2.
It is important to code all of the DB2 tables used in the program with their appropriate I, I-O, or O access type in the
JPL procedure. The JCL generator will use this information for job sequencing purposes and also for generating
QUIESCE JCL steps in front of any JCL step that performs I/O against DB2 tables. This is very important so that
the tables can be recovered to the QUIESCE point should the program execute in error.
Define job procedures that use DB2 tables as CRITICAL, using the same criteria as for VSAM files. If any
application performs I/O or executes DB2 utilities against DB2 tables in a procedure, then the procedure
must be defined as CRITICAL.
• The DB2 utility program DB2UNLD has been created to unload a DB2 table and write the data to a
sequential file
• The DB2UNLD utility program should be used instead of an application program
• DB2UNLD will use the LRECL and BLKSIZE parameters in the JCL:
1. If they are correct
2. If LRECL is larger than required and BLKSIZE is a multiple of LRECL
• DB2UNLD will override the LRECL and BLKSIZE parameters in the JCL if they are incorrect without
abending. Messages are printed in the SYSOUT dataset if either JCL parameter are overridden.
• Use the 'EXTERNAL LENGTH =' listed in the documentation section of the DCLGEN book as the
LRECL for the sequential file into which the DB2 table data will be unloaded. This is critical for DB2
tables that contain DATE, TIME and TIMESTAMP columns.
This procedure will only be used the first time the table is created or when physical table changes need to be
done.
The programmer/analyst is responsible to insure that the data being loaded satisfies the uniqueness restrictions
of all indexes defined on the table.
If the table structure is going to be changed, three JPL procedures are required to prevent the loss of data
during the conversion:
1. Unload procedure
2. Conversion procedure.
3. Drop/Create/Load procedure
Examples of the above procedures and other types, are located on the JPL system under the following procedure
numbers. They can be copied to specific procedure numbers using the 'CP' function of the JPL system. Be sure to
change all of the file IDs in the procedures after they are copied. Also change the owner ID on the newly created
procedure.
Each month, DB2 tables and indexes are evaluated and reorganized if necessary by the DBA Group.
If the analyst ID for a DB2 JPL procedure is changed on the JPL system, refer to the execute authority
scenario chart in the section: DB2 Authorizations. The chart will indicate whether or not other steps are
required for proper execution of the procedure.
DSNREORG This utility is used to reorganize tables and/or indexes after some amount of
update/insert/delete activity. This makes the table and/or index more efficient since
freespace is reallocated.
DSNRUNST This utility is executed against a table and its associated indexes to collect statistics
about them and store the information in the DB2 catalog. This information is used by
the DB2 Optimizer to determine the most efficient access path to the data.
DSNTIAD This utility allows certain SQL statements to be executed dynamically in a batch
environment.
DSNTUSQL This utility performs an unload of a DB2 table to a sequential file and allows the use
of a WHERE clause. SQL statement, including ORDER BY, must be coded in the
procedure through the use of control cards.
DSNUTILB This utility executes certain DB2 commands to be executed dynamically in a batch
environment.
The Sample COBOL Code listed in the back of this handbook shows examples of the standard syntax that will be
followed for the DECLARE CURSOR, FETCH, SELECT, INSERT, UPDATE and DELETE SQL statements in
application programs:
30 Any CICS DB2 application program coded with SELECT, UPDATE, INSERT and/or
DELETE SQL statements (usually display/update programs).
80 Any CICS DB2 application program coded with DECLARE CURSOR/FETCH SQL
statements (usually browse programs). No updates, inserts or deletes.
A working storage field WSWA-SQL-EXEC-CTR is generated into each new CICS/DB2 program and is
automatically incremented each time an SQL statement is executed. Be sure and code a check in the program to
verify that the value in this field does not exceed the above limits.
2. CICS
• The following SQL commands and/or functions will not be allowed in CICS application programs:
• The following SQL commands and/or functions can be used in CICS application programs ONLY IF the
amount of data that the function is operating against is a small subset (25 rows or less). This can be
determined by the column conditions used in the WHERE clause that is used for the SQL statement. The
SQL statement must also use an index to satisfy the request.
• The following SQL commands and/or functions can be used in CICS application programs ONLY IF the
statement is evaluated with the QMF EXPLAIN function to verify that indexes are used to satisfy the data
request. Also a member of Database Administration team must be contacted to check the SMF
performance data on the statement. An SQL statement that includes a JOIN should be restricted to
maximum of two tables. If the statement does not meet the performance standards be prepared to break it
into separate SQL statements.
• Avoid Index Scans, Table Scans, and Sorts in CICS application programs.
• If an SQLCODE return code indicates that an UPDATE, INSERT or DELETE statement did NOT execute
normally, the CICS transaction should issue the following statement to rollback all DB2 changes made by
previous SQL executions in the CICS transaction. The CICS COBOL generator currently generates this
rollback code for any CICS/DB2 program that updates a DB2 table.
3. Batch
• The following SQL commands and/or functions will not be allowed in batch programs:
• JOIN statements are permitted in batch, but never join more than three (3) DB2 tables in one SQL
statement.
• All JOIN statements must include a WHERE or HAVING clause.
The COBOL generators are set up to handle the various types of read, write, update, insert, delete, etc. operations
that are necessary in DB2. In CICS the I-O operation will correspond to the type of program that is being created.
CHAR Spaces
VARCHAR A String of Length 0
DECIMAL Zeros
INTEGER Zeros
SMALLINT Zeros
DATE (current date)
TIME (current time)
TIMESTAMP (current timestamp)
• Avoid the use of 'OR' and '^=' in the WHERE clause if possible, because of the potential for DB2 doing a full
table scan. There is an exception to the 'OR' and that is with the 1 CURSOR method for CICS Browse
programs. A sample can be found in the programming samples in back of this manual.
• Host variables used in the WHERE clause must be of the same data type and length as the columns they are
being compared against.
• When declaring host variables in the Working Storage section, code any COMP-3 definitions on each host
variable, not at the group level.
• There are some restrictions when using FILLER for host variables involved in a redefines. See a Database
Administrator for details.
• Host variables used in the WHERE clause should be defined as the same length as the column it is being
compared against. The reason for this is that if the lengths are different, the DB2 optimizer may pick a much
less efficient index at bind time to retrieve the data.
• Set the value of the host variables in an SQL cursor before the OPEN CURSOR SQL statement is executed.
• Use the clustered indexes in the JOIN function.
• Be sure and issue a CLOSE CURSOR statement for all open cursors in batch and CICS programs. Even if the
program is to be abended intentionally, issue the CLOSE CURSOR statement.
• If in the application program, the same table is to be accessed simultaneously by separate SQL statements, be
sure and code a separate SQLCODE working storage area for each condition checking routine. This will ensure
that the SQL return code being checked is really the value for the appropriate table access. The COBOL
generators currently generate only one SQLCODE working storage area for each DB2 table accessed in a
program.
• Us the 'AS' clause to name derived columns
• If a SQL statement contains a NESTED TABLE expression a DCLGEN for the NESTED TABLE must be
manually coded.
2. Group level variables can be used, BUT only at the lowest two levels, and also only in the portion of an SQL
statement that deals with column assignments, NOT in the WHERE clause.
4. In a batch COBOL program, a PARM variable cannot be used as a host variable in a DECLARE CURSOR
SQL statement because the variable must be defined before using it in an SQL statement. The solution is to
move the parm value to a working storage variable which in turn is used in the WHERE clause of the
DECLARE CURSOR SQL statement.
If a data element from a non-DB2 DCLGEN, VSAM or sequential copybook is used in an SQL statement, the record
description needs to be INCLUDED instead of COPIED in at precompile time, otherwise the DB2 precompiler will
flag the variable as an unrecognizable host variable. This is because the precompiler does not recognize the COPY
statement. An example is as follows:
EXEC SQL
INCLUDE ALUMSTRB
END-EXEC.
Be sure and put the period after the END-EXEC or unexpected results will occur.
Standards call for the EXEC statement to begin in Col. 12 of the program source record.
Variables that are to be used in an SQL statement should be defined in the Data Division of the program. When the
variable name is coded within the SQL statement, it must be preceded by a ':' so that the DB2 precompiler will
recognize it as a Host Variable.
DB2 uses a special value indicator, called a null value, to stand for an unknown or missing value. A null value is a
value and not a zero value, a blank, or an empty string. It is a special value interpreted by DB2 to mean that no data
has been supplied. A null is not equal to another null since a null is unknown.
When designing a new table, some date columns are good candidates for being defined as null. An example would
be termination date in an employee table. The column would be null for most of the rows in the table, since most of
the employees are active employees.
The following are instructions and guidelines on how to use null values in a table:
1. Date type columns are the only columns that should be defined as null.
3. A COBOL and/or Easytrieve book is required to process a table in its load/unloaded dataset structure.
2. If the data field will be assigned a null value, then move spaces to the data field, then move a question mark (?)
to the 1 byte indicator field. This tells the load utility to make the column null.
Example of load dataset records where the columns are id, last name, first name, date (allow nulls), address, city,
and state:
The first record will load a valid date into the date column and it will not be null. The space after the date value
indicates to not assign nulls to this column. The second record will load a null value into the date column because
the 1 byte after the date field contains a question mark (?).
When a DB2 table is unloaded using the DB2UNLD utility, the output dataset will contain the 1 byte following each
null column. The field will contain either a space or a question mark (?) to indicate the status of the data for the
column. If a question mark (?) is in the 1 byte following the column data, the column data is low values.
There is no need to define elements in the Data Dictionary for the indicator fields for null columns. Once the column
has been defined as null in a DB2 table definition, the Dictionary generates the appropriate indicator variables in the
DCLGEN, COBOL and Easytrieve books.
Examples:
DCLGEN:
DECLARE TABLE ......
(YEAR CHAR(4) NOT NULL WITH DEFAULT,
ID-NUM CHAR(9))
01 UICCD-INFO-TBL.
12 UICCD-YEAR PIC X(4).
12 UICCD-ID-NUM PIC X(9).
01 UICCN-INFO-TBL.
12 UICCN-ID-NUM PIC S9(4) COMP.
COBOL:
01 UICCD-INFO-TBL.
12 UICC-YEAR PIC X(4).
12 UICC-ID-NUM PIC X(9).
12 UICCI-ID-NUM PIC X.
SELECT YEAR
, ID_NUM
INTO :UICCD-YEAR
,:UICCD-ID-NUM :UICCN-ID-NUM
FROM ....
UPDATE ......
SET YEAR = :UICCD-YEAR
,ID_NUM = :UICCD-ID-NUM :UICCN-ID-NUM
WHERE .....
The first host identifier designates the data item variable and the second host identifier designates the null indicator
variable. They are NOT separated by a comma. The purpose of the indicator variable is to specify the null value.
After the Select statement is executed, DB2 places data into the host variables. If the indicator variable UICCN-ID-
NUM contains a negative value, the column is null and the host variable UICCD-ID-NUM is unchanged. It is
important to initialize the data item variable before the Select statement is issued, because previously selected data
can remain in the field if the next row contains nulls in the column. If the indicator variable UICCN-ID-NUM
contains a non-negative value, the column is not null and data is returned into the UICCD-ID-NUM host variable.
The two host identifiers are also used for Insert and Update SQL statements.
• When a null is desired, move a -1 value to the indicator variable and spaces to the data item variable.
• When a valid value is desired, move a 0 (zero) to the indicator variable and data to the data item variable.
The following are examples of coding for nulls in the Where clause:
The previous example shows three multiple WHERE clauses combined into one cursor. Additionally, notice that
the first column of the index appears outside the parenthesis that contains the OR conditions. Be sure to check the
EXPLAIN report after binding the browse program to verify that the desired index is selected and that the MATCH
COLUMNS number is equal to 1.
Unless the cursor is past end of file, this will start the browse. Continue to select rows from the cursor until the
screen is full, I-O limits have been reached, or EOF for that cursor. Close the cursor when the browse is complete, or
when exiting the program.
Programming logic has been developed to provide "Previous Screen" capabilities in browse programs. It will allow
the client to go back to previously viewed screens by using the already defined ascending index. Contact a Database
Administrator for an explanation and sample of this programming logic.
Order By Clause
The Order By clause of any SQL statement, batch or CICS, must use the column name from the table or the name
assigned by a 'AS' clause. Positional (e.g. Order By 2 Desc) are not allowed in an Order By clause.
***********(EXAMPLE #1)*******************
UPDATE DB2.TBL_STATS
SET TBL_ROW_COUNT = :WSWA-ROW-COUNT
WHERE TBL_ID = :WSWA-TBL-ID
In the second example the working storage value will be added to the existing value of the column.
************(EXAMPLE #2)*******************
UPDATE DB2.TBL_STATS
SET TBL_ROW_COUNT = TBL_ROW_COUNT + :WSWA-ROW-COUNT
WHERE TBL_ID = :WSWA-TBL-ID
The reason for this is that our standard is to SELECT the row when the update CICS program is initiated, then add
the amounts and perform an update. Our standard with DB2 is to NOT lock the row when it is SELECTed.
Example #2 shown above ensures that the value being updated is the correct value at the moment of update.
Select only columns that are needed for a particular program, and update only columns that are changed in a
program. It is not necessary to do every column in a table for processing. Make sure that the columns listed in the
CURSOR statement match the host variable names in the FETCH statement. If you are unsure if a column is used in
a program, look at the program cross reference listing for the COBOL/DB2 column name. If the only place the
column is referenced is at the beginning of the Procedure Division in the precompiler generated section, the column
is not used and should be removed.
If the DB2 table contains a VARCHAR element, the length of the field must be moved to the length variable in the
DCLGEN before an INSERT or an UPDATE is performed on the column. One way is to define an area in working
storage that can be scanned backward one character at a time until a non-space value is found. This will define the
length and this value should be moved to the 49 level length field.
hv1 1 10 A
hv2 11 30 A
FILE SYS008
%EZTP macro
SY08-KEY 1 5A
1. A compile of the program is performed, and the object code and DBRM are
stored in staging libraries.
2. The test object code and test DBRM are deleted, and a test bind job is
submitted to bind the staged production code to test DB2, using the
production DBRM.
3. That night, the object code and DBRM are moved from the staging libraries to
the production libraries and a production bind is submitted.
After this initial staging of the production program is complete, you may want to
move the code into production immediately for an emergency situation. The
function 'LI' in the Source Control system must be executed to do this. The
following actions are then performed:
1. The object code and DBRM are immediately moved from the staging libraries
to the production libraries.
4. Be sure that the compile AND bind jobs are complete before trying the
transaction. Since these are two separate jobs, there may be a small time
delay between the compile and bind jobs.
CAUTION --- In CICS, the production bind will hold the plan so that the
client can not use the CICS function until the bind is complete, and any client
in the middle of a transaction using this function will ABEND.
The output from the test and production compiles can be found on RMDS and
SYSD. The production compiles stay on RMDS, and the production binds with
the Explain report are on RMDS for a limited time.
If the bind/Explain report no longer is on RMDS, use the test or production DB2
Information Systems to submit a job that will list the current test or production
Explain report.
Batch When a batch program is checked-in during the day, the following actions are
Compiles/Binds performed:
1. A compile of the program is performed, and the object code and DBRM are
moved directly into the production libraries.
2. The test object code and DBRM are deleted, and a test bind job is submitted
to bind the production code to test DB2, using the production DBRM.
Be sure to check whether or not a BIND is successful before trying to execute a DB2 application program. If
the BIND was not successful and the program is executed, a negative SQL error code will be returned indicating that
the plan is not currently available or that a connection failure has occurred.
The 'XT' function in the Source Control system is for performing a test bind without doing a compile.
Iowa State University ADP Center DB2 Reference Handbook 38
Note: This does not work for an Easytrieve Plus program that is not checked out.
The 'XP' function in the Source Control system is for performing a production bind without doing a compile.
The default parameter for the EXPLAIN option of the bind is set to YES so that each time a bind is done to test or
production a row is added for each SQL statement to a DB2 table. This table is called ADPXXX.PLAN_TABLE,
and the added row(s) indicate whether or not the SQL statement is using an index and whether or not a sort is being
done. Also other information is provided to indicate the efficiency of the SQL code, which is very important to the
performance of the program/system.
After each BIND, the output on the EXPLAIN report must be viewed to ensure an efficient access path has been
selected for the plan. It is very important that this information be viewed and if any questions arise, be sure and see a
Database Administrator. If a DB2 plan has an inefficient access path, it is possible that by altering the SQL
statement in the program, efficiency can be gained.
Previous versions of Explain reports (up to 5) are stored and are available for viewing using QMF or JFT in SYSD.
In QMF, enter PREV_PLANS on the command line and press <enter>. A prompt will display asking which plan ID
to display. In SYSD, a JFT proc has been setup to submit a job to list the previous plans. Choose option 8-JFT,
then 1-DB2, then 1-Prev. A prompt will display asking which plan ID and which printer to direct the output to.
Enter SUB on the command line to submit the job.
2. Batch
• SQL ranks of 1, 2, and 3 are good path selections.
• SQL ranks of 4 and 5 are allowed, but caution must be taken to verify that the entire index or table is
needed by the application program.
• If a SORT is encountered, be aware that this is acceptable up to approximately 8,000,000 bytes (e.g. 20,000
rows with a 400 LRECL). This can be calculated by adding up the lengths of the columns in the SQL
statement that has the sort in the EXPLAIN report. Determine the number of rows that will be returned by
looking at the selection criteria in the WHERE clause. Multiply the number of rows returned times the
LRECL to determine the number of bytes that will be sorted.
Easytrieve Batch
• An Easytrieve program that calls a DB2 program must be coded as a DB2 program. To do this, include the
macro DB2DUMYP prior to the Job statement.
• The DB2 called program number must be entered in the Source Control System as a Package member on the
DP screen of calling program
• The data passed to and from the called program must be defined in a virtual file with a Put statement in the Start
proc. The called program can be accessed by executing the following statement: Call <program name> using
<Virtual file record name>
COBOL II Batch
• The called program name must be defined as a working storage variable in the calling program. By using this
working storage field when making the call to the called program allows the called program to have a dynamic
link with the calling program. This link allows the called program to be changed without having to recompile all
of the programs that call it.
• If the calling program calls a DB2 program then it must be coded as a DB2 program. If the calling program is
not DB2 it may be changed to DB2 by including the DB2DUMYD dummy copybook in its Working Storage
Section.
• In the Source Control System the DB2 called program number must be entered as a Package member on the DP
screen of the calling program
Previous versions of Explain reports (up to 5) are stored and are available for viewing using QMF or JFT in SYSD.
In QMF, enter PREV_PLANS on the command line and press <enter>. A prompt will display asking which plan ID
to display. In SYSD, a JFT proc has been setup to submit a job to list the previous plans. Choose option 8-JFT,
then 1-DB2, then 1-Prev. A prompt will display asking which plan ID and which printer to direct the output to.
Enter SUB on the command line to submit the job.
Explain reports for test programs remain on SYSD for a limited amount of time. If the report is no longer on SYSD,
a current copy of the Explain report can be obtained by using the TEST CICS DB2 Information system to submit a
job to list the report.
Explain reports for production programs remain on RMDS for a limited amount of time. If the report is no longer
on RMDS, a current copy of the Explain report can be obtained by using the PRODC DB2 Information system to
submit a job to list the report.
In the past, slow response time was experienced across many host-based systems because a CICS/DB2 program
contained several table scans. DB2 chose the access path because the production tables were empty when the
program was compiled and bound six months before. Since the number of rows in the tables was very small, there
was no performance impact during that six-month time period. However, the number of rows began to increase.
Large amounts of CPU resources were required to satisfy the SQL statements.
To remedy the performance problem, the program was rebound. Before the program was rebound, Prod-A CICS was
using between 60 to 70 percent of the CPU. After rebinding the program, Prod-A CICS usage was normal, between
25 to 35 percent of the CPU.
It is very important that the Explain reports be reviewed when SQL is added after the formal review process. Work
is being done to help notify the analyst of scans that occur in CICS programs.
The DB2 Explain report places an “eye catcher” statement on the right side of the report indicating any table or
index scans. If you encounter this in any CICS program, it must be addressed to prevent potential performance
problems. Various steps can be taken to eliminate scans depending on the situation. Contact a DBA if you are
having problems with scans in CICS programs.
Purpose of Explain
1. SQL statements specify WHAT is wanted; DB2 determines HOW TO GET IT:
• All SQL statements processed by BIND process
• BIND invokes DB2 OPTIMIZER
• OPTIMIZER determines how data is accessed
S = SHARE
Lock owner and other concurrent users can read but not change data in
tablespace.
SIX = SHARE WITH INTENT EXCLUSIVE Lock owner can read and
change data in tablespace. Concurrent users can read but cannot change
data. When owner reads data, a share (S) page lock is acquired. When
owner changes data, an exclusive (X) page lock is acquired.
The optimum access path selected is primarily based on the use of available indexes. The cost of accessing data
using an index will generally be less than if a scan of a table space(s) is performed.
In DB2, the five different access methods to data are shown below and are listed in probable order of efficiency:
On the EXPLAIN report are 4 columns on the right hand side which indicate SORT, LOCK, JOIN, SCAN. The
program that prints the report uses the information from the chart, to determine whether or not the operation exists.
If it does, an indicator is placed in the appropriate report column.
To view a previous Explain report for a specific program, use the DE function in the DB2 Information System on
PRODC. A batch job is started to retrieve the Explain information.
SQL error codes will appear while testing the DB2 programs. Explanations of the common error messages can be
found in the back of this handbook. The complete list of SQL error codes can be found in the IBM manual entitled
'SQL Messages and Codes' which is accessible on the Administrative Technology Service's Internal Web Resources
page.
Indexes are never explicitly specified in a program or dynamic SQL. DB2 analyzes the catalogs at bind time to see
if an available index can be used to access the data more efficiently.
When updating VSAM and DB2 tables in the same CICS program, perform the DB2 updates before the VSAM
updates for the following reason. If an SQL Error code that is more severe than just a warning is returned on one of
the DB2 updates, the EXEC CICS SYNCPOINT ROLLBACK END-EXEC. can be issued, and all DB2 changes
will be rolled back. If the VSAM changes where processed before the DB2 changes, the DB2 changes would be
rolled back but the VSAM would not, thus creating file discrepancies.
There are 5 types of SQL statements that are most commonly used in application programs. They are:
SELECT INTO This statement is used to select columns for only ONE row of a DB2 table. If
multiple rows are desired, the DECLARE CURSOR/FETCH statements are
needed.
UPDATE This statement is used to update columns for one or more rows of a DB2
table. Care must be taken when coding the WHERE clause to ensure that
only the desired row(s) will be updated. If the WHERE clause is left out of
the statement, all rows in the table are updated.
INSERT This statement is used to insert ONE row into a DB2 table. No WHERE
clause is needed, since DB2 uses the clustering index to determine the
location in the table to insert the row. All indexes associated with the table
are updated to reflect the existence of the new row.
DELETE This statement is used to delete one or more rows of a DB2 table. Care must
be taken when coding the WHERE clause to ensure that only the desired
row(s) will be deleted. If the WHERE clause is left out of the statement, all
rows in the table are deleted. The keys to the deleted rows of the table are
also deleted from the associated indexes.
DECLARE This is a two part set of statements used to select one or more rows from a
CURSOR/FETCH DB2 table. The DECLARE CURSOR statement is coded in the Working
Storage section of the program, while the FETCH statement is coded in the I-
O section of the program.
The 'Order By' and 'For Update of' clauses are mutually exclusive. The 'For
Update of' clause lets you use 'Where Current of Cursor' in the update and
delete SQL statements associated with the cursor, but the access path chosen
by DB2 for the cursor may not be the desired order for the data being
retrieved. If the order of the data is important, use the 'Order By' clause
instead, and use explicit key columns in the update and delete SQL statements
associated with the cursor.
Use DATE, TIME, and TIMESTAMP data types when date and time fields are required. Be aware that when using
these column types, a valid DATE, TIME, or TIMESTAMP must be in the column, they cannot contain spaces.
When performing an INSERT statement, the current date, current time or current timestamp can be inserted into the
column of the row by leaving that particular column name out of the INSERT statement. DB2 recognizes that the
column is not in the INSERT statement and assigns a default, which is the current value.
SQL provides methods of performing more complex queries. The following is a description and example of 3 types
of methods:
Example:
SELECT A.NAME, B.DEPT_NAME
FROM ISU.STAFF A, ISU.ORG B
WHERE A.ID = B.MANAGER
The above example lists manager's name and department name for all departments that have a manager. To
make this list, data had to be selected from two tables. The department names are in ISU.ORG; the managers'
names are in ISU.STAFF. To select from both tables efficiently, they must be joined using a column of data that
appears in both. In this case, the ID column in ISU.STAFF and the MANAGER column in ISU.ORG represent
the employee number. The A and B are used to qualify the columns. The WHERE clause dictates that only
rows be selected in which the employee number for MANAGER is the same as that for the employee ID.
• UNION - This method can be used to merge values from two or more tables into the same columns, but
different rows, for the same report
Example:
SELECT NAME, 'EMPLOYEE '
FROM ISU.STAFF
WHERE YEARS < 3
UNION
SELECT NAME, 'APPLICANT'
FROM ISU.APPLICANT
WHERE EDLEVEL > 14
The above example will list the name of the individual and whether the person is an EMPLOYEE or an
APPLICANT on the same report. The important thing to remember when using UNION is that you are
interleaving the rows of the reports from two (or more) queries. To make sense, these rows should relate to one
another, have the same width, and have the same data type.
• Subselect/Sub Query - A subselect is used within a SELECT statement to supply an unknown value to a
condition of the main query. It is a complete SQL query in itself that appears in a WHERE clause of the main
query. The subselect query is executed by DB2 before the main query to provide a value or a set of values to be
used in the condition portion of the main query.
Example:
SELECT NAME, SALARY
FROM ISU.STAFF
WHERE SALARY > (SELECT AVG(SALARY)
FROM ISU.STAFF)
The above example determines the average salary for all rows in the table ISU.STAFF then uses that average
value to determine the names of the staff members that have a salary which is greater than the overall average.
***NOTE*** The performance of an SQL statement will change very little between its execution in QMF, Query
Tool, or Web based and in batch/CICS programs.
When using the INNER JOIN SYNTAX with the ON clause, all WHERE clauses will be applied after the join is
complete. This is damaging for performance as it is important that some filtering be done earlier. As shown below,
there are two options now. The best one should be chosen in each case. Either stay with the old syntax that uses
commas in the FROM clause and WHERE predicates so that normal join algorithms are used to apply predicates
earlier in the process, or use Table Expression to move the filtering as early in the process as possible.
Wrong Way
SELECT parent.column1,child.column2
FROM parent INNER JOIN child
ON child.id = parent.id
WHERE child.age < 10
Right Way
SELECT parent.column1,child.column2
FROM parent, child
WHERE child.id = parent.id
AND child.age < 10
In the WRONG WAY, the all rows are first joined by ID and after the composite table is built the rows are filtered
for children under the age of 10. In the RIGHT WAY, the child table is filtered for children under the age of 10 prior
to the join. BIG DIFFERENCE! Watch for this to change (WRONG WAY) in the future, maybe even on a
maintenance tape.
Wrong Way
SELECT parent.column1,child.column2
FROM parent INNER JOIN child
ON child.id = parent.id
WHERE child.age < 10
Right Way
SELECT parent.column1,child.column2
FROM parent INNER JOIN
(SELECT column2
FROM child
WHERE age < 10) AS child
ON child.id=parent.id
In the RIGHT WAY, the child table is forced to be filtered prior to the JOIN.
Predicate sequence
It is important to remember, and to evaluate the related effects, that the SQL statement is executed in steps
with the following precise sequence:
• FROM
• Outer or inner join with the ON conditions
• WHERE
• GROUP BY
• HAVING
• SELECT
You must check the sequence of your SQL and the data model of your table if you want to avoid meaningless
results; local predicates that do not apply to the results of the join must be coded in a nested table expression.
For example, say you need a list of all departments and the average salary by department if an individual's salary
exceeds 28000. You use left outer join because some department might have no employee with SALARY > 28000,
and issue the statement:
The result will be wrong because DB2 first executes the outer join and then applies the WHERE clause removing
the employees with SALARY <= 28000. Departments with no employees, or departments where all employees get a
SALARY <= 28000, will not appear in the result table.
To ensure the appropriate sequence and that local predicates apply to a table, you must use nested table expression
as shown in the following SQL statement:
There is no execution of right outer join as such. If you specify RIGHT OUTER JOIN in the SQL statement, DB2
uses the left outer join by switching the position of the tables.
The sequence in which you name the tables in the FROM clause of a left or right outer join is important to ensure
that the result table is correct.
An outer join on more than two tables must be performed in steps. Outer join operates on only two tables at a time.
If you have more (and it is difficult to predict the results) you must join in steps.
With a full outer join you can only use the EQUAL operator and the AND; BETWEEN, LIKE, IN, OR, and NOT
are not allowed.
When two or more tables are JOINED, DB2 Access Path Selection (APS) will choose one of the following JOIN
techniques and record the information in the METHOD column in the PLAN_TABLE:
A sub query can, in turn, include another sub query whose value is substituted into its WHERE clause. In addition, a
WHERE clause can include sub queries in more than one search condition. The sub query can refer to tables and
columns that are different than the ones used in the main query.
The following statement selects the division and location from the ORG table of the employee whose ID in the
STAFF table is 280:
When processing this statement, DB2 first determines the result of the sub query. The result is 66, since the
employee with ID 280 is in department 66. Then the final result is taken from the row of the ORG table whose
DEPTNUMB column has the value of 66. The final result is:
DEPTNAME MGRNO
SPIFFY COMPUTER SERVICE DIV. 000010
When you use a sub query, the database manager evaluates it and substitutes the resulting value directly into the
WHERE clause.
The following example is an non-correlated sub query that lists the employee number and name of employees in
department 'A00' with a salary greater than the average salary of the department:
If you want to know the average salary for every department, the sub query needs to be evaluated once for every
department. You can do this by using the correlation capability of SQL, which permits you to write a sub query that
is executed repeatedly, once for each row of the table identified in the outer-level query. This type of correlated sub
query is used to compute some property of each row of the outer-level table that is needed to evaluate a predicate in
the sub query.
This example shows all the employees whose salary is higher than the average salary of their department:
In this query, the sub query is evaluated once for every department. The result is:
To write a query with a correlated sub query, use the same basic format of an ordinary outer query with a sub query.
However, in the FROM clause of the outer query, just after the table name, place a correlation name. The sub query
may then contain column references qualified by the correlation name. For example, if E1 is a correlation name,
then E1.WORKDEPT means the WORKDEPT value of the current row of the table in the outer query. The sub
query is (conceptually) reevaluated for each row of the table in the outer query.
By using a correlated sub query, you let the system do the work for you and reduce the amount of code you need to
write within your application.
First, you must determine the select-list items. The problem says "List the employees". This implies that the
EMPNO from the DB2.EMP table should be sufficient to uniquely identify employees. The problem also states the
level of education (EDLEVEL) and the employees' departments (WORKDEPT) as conditions. While the problem
does not explicitly ask for columns to be displayed, including them in the select-list will help illustrate the solution.
A part of the query can now be constructed:
Next, a search condition (WHERE clause) is needed. The problem statement says, "...whose level of education is
higher than the average for that employee's department". This means that for every employee in the table, the
average education level for that employee's department must be computed. This statement fits the description of a
correlated sub query. Some property (average level of education of the current employee's department) is being
computed for each row. A correlation name is needed for the DB2.EMP table:
The sub query needed is simple. It computes the average level of education for each department. The complete SQL
statement is:
Suppose that instead of listing the employee's department number, you list the department name. The information
you need (DEPTNAME) is in a separate table (DEPT). The outer-level query that defines a correlation variable can
also be a join query .
When you use joins in an outer-level query, list the tables to be joined in the FROM clause, and place the correlation
name next to any of these table names.
The above examples show that the correlation name used in a sub query must be defined in the FROM clause of
some query that contains the correlated sub query. However, this containment may involve several levels of nesting.
Suppose that some departments have only a few employees and therefore their average education level may be
misleading. You might decide that in order for the average level of education to be a meaningful number to compare
an employee against, there must be at least five employees in a department. So now we have to list the employees
whose level of education is higher than the average for that employee's department, and only consider departments
with at least five employees.
The problem implies another sub query because, for each employee in the outer-level query, the total number of
employees in that person's department must be counted:
SELECT COUNT(*)
FROM DB2.EMP E3
WHERE E3.WORKDEPT = E1.WORKDEPT
Finally, only those employees whose level of education is greater than the average for that department are included:
SELECT LASTNAME, DEPTNAME, EDLEVEL
Iowa State University ADP Center DB2 Reference Handbook 54
FROM DB2.EMP E1, DB2.DEPT
WHERE E1.WORKDEPT = .DEPTNO
AND EDLEVEL >
(SELECT AVG(EDLEVEL)
FROM DB2.EMP E2
WHERE E2.WORKDEPT = E1.WORKDEPT
AND 5 <=
(SELECT COUNT(*)
FROM DB2.EMP E3
WHERE E3.WORKDEPT = E1.WORKDEPT))
-303 This error indicates that there is a possible mismatch between the DB2 columns
selected and the working storage host variables that the DB2 columns are being
selected into. Check to be sure that the host variables are in the same order as the
columns being selected.
-305 A possible cause of this error is that a SELECT statement with column functions did
not return a row and tried to assign a null value to the host variable. This is similar to
a +100 return code for a SELECT statement without any column functions. If you
determine that this "not found" condition is OK, you may want to add another 88 level
to the WS-SQLCODE field that has a value of -305, and add the 88 level item to your
SQL error checking code to prevent an abend.
-551 This message indicates that the user does not have authority to perform an operation.
This message is misleading in that it usually indicates that the object named in the
error message does not exist. The usual problem is that a column, table, or index name
is misspelled. In a Drop/Create step, a -551 may be received when there are previous
errors in the step. Look at each SQL statement starting at the top of step to determine
the first SQL statement that was in error as it may have cause the subsequent -551
errors.
-803 An INSERT or UPDATE SQL statement may return this error code indicating that one
or more unique indexes contains columns of the table such that no two rows can
contain duplicate values. Check the data that is causing the error to determine what
columns are violating the unique constraints and then correct the data.
-805 Plan does not contain a program module. For a CICS application, this could indicate
that the CICS New Copy function failed. Contact a DB2 System Administrator for
verification. In batch, this could indicate that a called program is not bound into the
batch programs application plan.
-811 The means that a direct select in a program has resulted in more than one row. The
Where clause for the statement must be coded to return a result set of just one row.
Normally a direct select should use a unique key index. This can be determined by
looking at the Explain report information.
-818 The timestamps do not match between the compiled object code and the DBRM
library member that was created during a bind. Check to be sure the bind was
successful. If not, correct problem and bind the plan. Another possible cause is that
the JOBLIB statement has been changed and the wrong object code member is being
executed against the wrong DB2 subsystem. Another possible cause is that the
program has been compiled and executed before the most recent bind is complete. The
bind is a separate job from the compile and may get held up if the initiators are very
busy. Always verify that the bind is complete before execution.
-904 In a CICS update program, this could indicate that a full image copy is required before
any updating of the table can take place. Perform a Display Database using the DB2
Information System to determine if an image copy is pending on the requested
tablespace. If a copy is pending, perform a full image copy on the tablespace to
remove the copy pending.
-911 This message possibly indicates that either a LOCK is currently placed on the resource
requested or the resource is STOPPED. Check to make sure that a QMF, Xpeditor or
CEDF session is not holding the resource. A batch job could be executing that is
performing updates/inserts/deletes that is holding locks on given pages until it
completes. You may want to perform a DISPLAY DATABASE using the DB2
Information System to display the status of the requested resource.
S737-24 This abend usually occurs in a Drop/Create step of a procedure. It indicates that one of
the PDS members listed under SYSIN does not exist or that the PDS member named
can not be found. Be sure that JPLFILE, the Dictionary 'PP' and/or 'PT' functions have
been executed successfully against the objects that the batch job is trying to reference.
AEY9 CICS abend error code. May indicate the program compiled but the DB2 Bind was not
successful.
SC03 Abend with return code = 004. This indicates a missing close statement for a non-DB2
file in a COBOL program.
DSNC This is a CICS Call Attach abend and it could be caused by one or more numeric
variables used in SQL UPDATE or INSERT statements not being initialized to zeros
before the SQL statement is executed (similar to a COBOL S0C7). Another possible
cause was that a user was executing the CICS system when an analyst performed a
bind on the plan. The user's transaction was abended.
S047 'Problem Program Attributes' message - The STEPLIB needs to be used instead of a
JOBLIB for DSNT.DSNLOAD and DSNA.DSNLOAD libraries.
S04E In batch, a possible error is that a decimal packed field contained non-numeric data
when an INSERT or an UPDATE SQL statement was executed. Another possibility is
that an SQL WHERE clause in a cursor contains a packed numeric working storage
field that contains non-numeric data when the OPEN CURSOR statement is executed.
Initialize the field or remove it from the SQL statement if not used.
ASPE A 'CICS SYNCPOINT ROLLBACK' statement was executed after a -922 SQL code
was encountered in a CICS/DB2 update program. The CICS RCT table had not been
updated with the transaction Id, and the dynamic transaction backout parameter had
not been set. Have a CICS Support analyst verify the entries in the CICS RCT table
and correct if necessary.
Monthly, the DB2 RUNSTATS utility is executed against every production DB2 table. DB2 Catalog statistics are
collected to determine if tables and/or indexes require reorganization. If a table/index is targeted as a candidate for
reorganization, a E-MAIL message is sent to the analyst in charge of the object. If a REORG or an
UNLOAD/LOAD is currently scheduled to take place against the table/index within a week of receiving the E-
MAIL message, then no other steps are required. If not, follow the instructions provided in the E-MAIL message to
schedule a reorganization.
REORG procedures should be scheduled as soon as possible after notification to reduce client costs and
increase performance.
If a DB2 table is dropped/created or reorganized, a full image copy is required before any updates to the table can be
made. SQL selects can be performed against the table but not updates, inserts, or deletes. The image copy sets a
point of consistency for DB2 recovery. The Image Copy step is automatically generated by the JPL system.
It is not necessary to perform a DROP/CREATE if the desired result is to delete all of the rows in the table. Just
execute a LOAD with a dummy input for the LOAD dataset. The first thing that occurs when the LOAD utility is
started is that all of the rows in the table (and its indexes) are deleted.
If the limit is exceeded, the solution is to code a declare cursor in the program to select the desired rows, but
WITHOUT an Order By clause. Write the selected records to a file, and sort them in the next step using SyncSort.
Automatic Rebinds
Currently a nightly procedure runs that selects all production DB2 application plans that have been invalidated for
one reason or another. Usually, the invalidation of a plan or package is caused by a table being DROP/CREATED.
This procedure performs a REBIND of the application plan and loads the EXPLAIN information into the analyst's
plan_table that owns the plan. A E-MAIL message will be sent to each analyst who has one or more plans selected
for REBIND. The REBIND is different from a BIND in that an EXPLAIN report is not automatically printed.
Reviewing the report(s) will be the responsibility of the analyst.
Use the test or production DB2 Information Systems to submit a job that will list the current test or production
Explain report.
1. Use the ‘DT’ function of the Source Control system to add a new member.
a. Naming convention is xxV999, xx=area, V=constant (for view), 999=sequential number
b. Enter a view qualifier (must be a valid Data Dictionary keyword, e.g. RGSTN)
c. Enter a view name (the client will use the qualifier.name combination to access data, it can’t be
the same as an existing DB2 table or view).
d. Set the type to ‘DB2 View’
2. In Test QMF, code and test the SQL SELECT statement.
3. After verifying the SQL works correctly, add the following lines to the query:
CREATE VIEW view_name
AS
(followed by your SELECT statement)
4. Run the create view statement in test QMF just as you would run a query. You should receive a message
indicating the database has been modified.
5. Save the create view SQL statement as a query within QMF (e.g. SAVE QUERY AS DBV001) using the
name that was entered in the Source Control system.
6. Drop the view from test QMF (e.g. DROP VIEW TBL_INDX_STATS). You should receive a message
indicating the database has been modified.
7. In Source Control, check-in the view. Contact a DB2 System Administrator to add any view authorizations
that are required and to build the view in test and/or production DB2. When the view is created by the DB2
System Administrator, the view name will consist of the view qualifier and the view name, which were
entered on the ‘DT’ screen in Source Control. Example: DB2.TBL_INDX_STATS
8. Contact a Database Administrator if you have questions or are ready to create a new view.
Examples:
Billing note: Since clients are the only ones who can control their queries, it follows that ATS must bill them for any
resources they use. ATS generally will not approve credit for invalid or excessively long queries.
MS Query Summary
1. Do not leave Excel and MS-Query open when it is not in use. Together, Excel and MS-Query use a lot of
resources. Remember: minimizing the application in Windows does NOT release the resources. Save your
Excel spreadsheet and close the Excel application.
2. MS-Query is designed to move smaller amounts of data from a database into Excel and Word applications.
Only select the columns of data that you need. Extra columns of unnecessary data are a waste of time and
resources.
3. When using Excel and MS-Query, do one of the following steps as soon as possible after executing a query:
• Return the data to Excel
• Go to the bottom of the selected data
• Exit the application if finished
By doing one of these steps, DB2 locks are released from the data. The same locking concerns that exist in
QMF, also are present when using MS Query. If one of the steps listed above is not taken, it is possible to lock
out clients or other analysts from updating this data through CICS or batch
4. To stop a query, press the ESC key twice. You can also stop a query by holding the ALT key and pressing the
BREAK key at the same time.
5. If a query is executing longer than 5 minutes, stop the query and contact your supporting analyst. Your analyst
will determine what needs to be done to the SQL to speed up the query. A long-running query is very costly.
6. QMF queries can be downloaded to MS-Query. Contact your supporting analyst if you need to use any existing
QMF queries in MS-Query.
7. Not all queries can be represented graphically, but as long as the SQL is syntactically correct, the SQL
statement will execute in MS-Query. Also, some SQL functions will have to be entered in the SQL window
since MS-Query cannot generate every feature of DB2 SQL.
If the password is already saved as part of the spreadsheet, do the following to remove it:
Open the spreadsheet in which you have saved the password with the query:
• Click somewhere in the range of data from your query.
• Select Data
• Then Get External Data
• Then Data Range Properties
• Remove the check in front of Save Password and save your spreadsheet
The next time you refresh the data or edit the query, you should be prompted for your password.
Also, when using Excel and MS-Query, do one of the following steps as soon as possible after executing a query:
This closes the cursor to DB2 and releases all page locks. If one of these steps is not taken, portions of the database
will contain locks that can prevent other applications from updating the locked data. This is especially important
when queries are executed against production data, in that the locks can cause Production A CICS applications to
receive “-911 Unavailable Resource” messages.
The following is a list of actions that can be taken to assure that the DB2 resources are not being held longer than
necessary:
Use the QMF TABLE EDITOR in production only when necessary, and access only the required rows.
If an SQL UPDATE or DELETE statement must be executed in production, code the WHERE clause to access a
minimal number of rows. If necessary, execute the SQL statement multiple times, changing the WHERE clause for
each execution to affect only small groups of rows.
The following describes how QMF operates and when locking takes place:
Data PAGE(s) that are locked during QMF execution may have a direct affect on any CICS transaction or batch job
that is currently trying to access the data on the locked PAGE(s).
A CICS transaction may have either slow response times or be TIMED OUT due to the lock(s) held by the QMF
session. Also a batch job may abend due to the unavailable resource.
1. On the QMF SQL panel, enter the following statement above the actual SQL statement to be EXPLAINed:
EXPLAIN PLAN SET QUERYNO = 99999 FOR
Example:
EXPLAIN PLAN SET QUERYNO = 99999 FOR
SELECT ID, LAST_NAME, FIRST_NAME
FROM ISU.STAFF
WHERE DEPT IN ('001', '005', '021')
AND STATE = ?
If the SQL statement used a host variable in an application plan, change each host variable in the WHERE
clause to a question mark (?) so that the DB2 optimizer will evaluate each question mark as if it were a host
variable. This is important because DB2 evaluates host variables differently than literals. This way host
variables don't have to be changed to literals for EXPLAIN purposes.
2. Position the cursor on the COMMAND line and type EXPLAIN and then press ENTER.
3. This procedure will execute and the EXPLAIN information will be displayed as a report. The report is very
similar to the BIND EXPLAIN report that is generated after a successful compile of an application program.
Also, information about this report can be found in the EXPLAIN section of this manual.
4. After viewing the report, press the PF6 key to return to the SQL screen. The SQL statement can then be
changed and EXPLAINed again by entering the command EXPLAIN and then pressing ENTER. This process
can be repeated over and over until the desired results are achieved. A helpful tip: type a question mark (?) on
the COMMAND line and press ENTER. This will return the last command entered so that is does not need to
be retyped each time.
If an error is encountered, follow the instructions on the QMF screen to correct the error, and proceed.
SAVE QUERY AS ?
SAVE FORM AS ?
SAVE PROC AS ?
A QMF SAVE prompt panel will be displayed. Follow the instructions on the panel, but be sure to at least enter a
date (MM/DD/YY) as the first piece of data on the COMMENT line of the panel. This is important for management
purposes, as it can be used later with the LIST command to very easily determine the age of the object you have
stored.
Data can also be saved in the common QMF database tables. This common tablespace is small and ONLY
temporary. Data can be saved, but it should be erased as soon as it is no longer needed. Save data is usually done in
a QMF procedure to create a temporary table for the next SELECT statement. To delete the saved data an ERASE
command should be entered in the QMF procedure immediately after the RUN QUERY statement that uses the
saved data. An example of a QMF procedure using the SAVE DATA and ERASE DATA commands is as follows:
RUN QUERY1
BOTTOM
SAVE DATA AS QRY1DATA (CONFIRM=NO
SCOPE Determines whether any governing will occur. A non-zero value (including
null) inhibits all governing for the specified Resource Group. A value of zero
allows governing, as determined by the other options.
TIMEPROMPT Specifies the amount of CPU time that can elapse on a governing cycle before
a cancellation prompt. A null, zero, or negative value inhibits prompting.
TIMELIMIT Specifies the amount of CPU time that can elapse on a governing cycle.
When this value is reached, the command is unconditionally canceled. A
null, zero, or negative value inhibits this type of cancellation.
TIMECHECK Specifies the maximum amount of time that can elapse between time checks
for both cancellation prompting and command cancellation. Based on this
value, the governor sets a timer at the start of each governing cycle. When
the timer decrements to zero, the governor makes the timing checks
appropriate to the TIMEPROMPT and TIMELIMIT options. A null, zero, or
negative value inhibits all time based cancellations, regardless of the values
of those options.
ROWPROMPT Specifies the number of rows that can be retrieved for the current data item
before a cancellation prompt. A null, zero, or negative value inhibits
prompting.
ROWLIMIT Specifies the maximum number of rows that can be fetched for the current
data item. When this number is exceeded, the retrieval operation is canceled.
A null, zero, or negative value inhibits this type of cancellation.
While using QMF, different situations may arise that require assistance from ATS staff. The following information
is broken down by QMF Operational situations and system problems.
Critical:
Locate the supporting analyst to resolve the situation, even if it requires an interruption of a meeting.
If none of your supporting analyst(s) are available, contact the ATS Help Center at 294-8034.
Non-Critical:
Leave a message with your supporting analyst(s) to contact you upon their return, to solve your situation.
Contact the ATS Help Center at 294-8034. The ATS Help Center will contact anyone else on the ATS staff, if
necessary, to resolve the situation. Give a complete description of the steps that were taken just prior to the situation
and any screen messages displayed by the terminal at the time of the situation. The ATS Help Center will contact
your supporting analyst, or any other ATS staff that are needed to resolve the situation.
Now, a third and better alternative is available. Why not take the SQL statement, which already exists, and just
schedule it to be executed in the JPL system?
Work to support this ability through ATS in-house systems has been completed and is ready to be used to satisfy
these types of requests from clients.
Only QMF queries and forms (not procs) are the objects the in-house systems support.
1. Set up a program name on the Source Control System for the SQL query statement. Naming convention:
xxQ999, where xx is the two-digit support area, and Q is in the third position followed by a three-digit sequence
number. Example: DBQ001
2. QMF forms are not required. If, however, you do have QMF forms associated with the QMF query, you will
need to set up a program name on the Source Control System for each form. Naming convention: xxQ999F1,
where the first six characters are the same as the program name assigned to the query; and F is in the seventh
position and is followed by 1. Example: DBQ001F1.
Note: Each form associated with a query must have the same first six-character program name. This is crucial
for the successful application of a form to a query during the execution of the JPL procedure, and makes
identifying the form associated with a query easier.
3. In TEST QMF, code, test, and save the QMF query that you want to schedule using the program name that was
set up in the Source Control System. Use the following command to perform the save: SAVE QUERY AS
xxQ999 (S=Y
4. In TEST QMF, code, test, and save each QMF form that you want to use with the query, using the program
names that were set up in the Source Control System. Use the following command to perform the save: SAVE
FORM AS xxQ999F1 (S=Y
5. In the Source Control System, check-in the query. The form will be checked in automatically for you.
6. Copy the sample procedure 00-59-10 to an appropriate procedure number. Follow the instructions in the sample
procedure to code the control cards correctly. Generate test JCL and test the procedure.
Check-out of the query is to TEST QMF (the associated form is checked out automatically). If you have any
questions, contact a DBA.
• All batch QMF queries must have comments at the beginning explaining the purpose of the query and explain
the possible values for any input parameter.
• Align SQL clauses (SELECT, FROM, WHERE, ORDER BY, GROUP BY, HAVING, UNION) in the first
position on separate lines.
The QMF review process enables ATS staff to learn more about SQL by viewing examples and being aware of an
alternative programming method for clients. As ATS gains experience using this option, the standards may be
formalized and documented. Any comments and/or suggestions should be directed to a DBA..
CHAR Spaces
VARCHAR A String of Length 0
DECIMAL Zeros
INTEGER Zeros
SMALLINT Zeros
DATE 0001-01-01
TIME 00.00
TIMESTAMP 0001-01-01-00.00.00.000000
To provide complete backup and recovery of the data during this process three JPL
procedures are required which perform the following steps: (Note: The first and third
procedures should already exist.)
1. Unload procedure (should already exist)
• Unload the table using the DB2UNLD utility
2. Convert procedure
• Read the unloaded format sequential file into conversion program and write out the new format file which
matches the new DB2 table structure
Based on the type of change you will do either the ‘If Adding Column(s)’ or the ‘If
Changing’ step.
TEST DB2
Data Dictionary
• Add the column(s) to the book(s) associated with the DB2 table.
• Have the new data name(s) reviewed and approved.
• Perform the 'PT' function to update the DECLGEN and the LOAD CONTROL members.
If Adding Column(s)
• Use the DB2 Information System ‘AR’ function to request the new column(s).
• A new file ID was added for the sequential backup so any procedures (except the unload procedure) that used
the old sequential file ID must be changed to use the new sequential file ID.
Application Program(s)
• If an application UNLOAD program exists, the UNLOAD program must be changed to account for the change
in LRECL of the sequential backup if columns have been added, deleted or their names changed in the altered
DB2 table.
• Change any program that selects the entire table or needs to access the new/changed column(s)
• Change any other program that uses the sequential backup file to account for the change in LRECL of the
altered DB2 table.
PRODUCTION DB2
Data Dictionary
• Have the data name status changed from Development to PRODUCTION.
• Perform the 'PP' function to update the DECLGEN and the LOAD CONTROL members.
• Perform the 'PP' function to update the COBOL book if one exists. This also updates the Easytrieve book at the
same time, if one exists.
File System
• Verify that a new sequential backup file ID has been setup to reflect the change in the LRECL of the altered
DB2 table.
• Verify that the DB2 table definition has been changed to reflect the change in LRECL.
If Adding Column(s)
• Use the DB2 Information System ‘AR’ function to request the new column(s).
• A new file ID was added for the sequential backup so any procedures that used the old sequential file ID must
be changed to use the new sequential file ID.
JPL Procedures
• If a new sequential backup file ID was added, verify that ALL procedures using the old sequential file ID have
been changed to use the new sequential file ID.
Application Program(s)
• After testing any programs that were changed to access the new column(s), or that were changed to use the
updated/new sequential backup file ID, check them in to production after the DBA Group notifies you that the
table has been ALTERed.
TEST DB2
Check Existing Index Usage
• Have a DB2 System Administrator check which programs currently use this index
• Verify the impact of the index change on each program
Data Dictionary
• Use ‘IA’ function to change the columns assigned to the existing index
JPL Procedure
• Copy the sample procedure 00-37-69 to a new procedure number
• Change the DEFINE TBL-SPACE record in the first step to the new index Id
• Change the hard coded JCL to reflect the name of the DB2 index. This hard coded JCL will be setup for
production DB2. The ‘DB2.’ prefix on the index name needs to be changed to reflect the creator Id associated
with your table. For example: If your table name is EMPL.DAILY_QUOTA then the creator Id is EMPL. So
the index name would be EMPL.EMB0011I, where EMB0011 is the index that is to be changed. The ‘I’ suffix
is required on all indexes.
• Change the hard coded JCL line DSN=DB01.PROD.DB2.TABLEDEF(DDB9011I), replacing DBB9011I with
the name of the index to be changed (example: EMB0011I)
• Change the IN-OUTPUT DISK record in the second step to the table Id for the index being changed
Test JCL
• Generate test JCL for new procedure
• Change the hard coded JCL so that the ‘B’ in the third position of the index name is a ‘T’. This will need to be
changed in two places in the first step.
• Execute the test JCL
Application Program(s)
• Change the SQL in programs that will be affected by this index change
• Compile/bind and check the Explain report to verify changed index usage
PRODUCTION DB2
JPL Procedure
• Schedule the create index procedure for a non-prime time execution.
Auto Rebind
• When the index is drop/created, all DB2 plans/packages that use the index become invalid.
• A nightly job is executed to rebind these plans/packages.
TEST DB2
File Definition System
• Create a new Index Definition
Data Dictionary
• Use ‘IA’ function to assign DB2 table column names to the newly defined index
JPL Procedure
• Copy the sample procedure 00-37-68 to a new procedure number
• Change the DEFINE TBL-SPACE record in the first step to the new index Id
• Change the IN-OUTPUT DISK record in the second step to the table Id for the new index
Test JCL
• Generate test JCL for new procedure and execute it in test DB2
PRODUCTION DB2
JPL Procedure
• Schedule the create index procedure for a non-prime time execution
NOTES:
1. The USER=ADPXXX parameter is added to execute the TSO batch program. The user must be the owner of
the program(s) or have been granted EXECUTE authority of the programs for the job to execute.
2. This is the entry point program name for executing under TSO.
3. Control statements for the TSO program:
DSN SYSTEM(DSNT) Indicates what version of DB2 (Test or Production).
PROGRAM(DB995) Indicates what program to execute.
PLAN(DB995) Indicates what plan to execute.
PARMS('0123') Indicates the parms to use in the program.
4. The rest of the JCL is the same as that generated for COBOL programs.
Note that there are no JCL statements for the DB2 TABLES.
The field SQLERRD(3) is important in that it will contain the number of rows updated, inserted, or deleted
by DB2 after an SQL statement is executed.
Another SQLCA field that is important is SQLWARN0. If this field is set to 'W', this means that at least one of the
SQL warning flags (SQLWARN1 through SQLWARN7) has also been set. The warning flags that could affect
programs at ATS are as follows:
• SQLWARN1 - If 'W', at least one column's value was truncated when it was stored into a host variable.
• SQLWARN3 - If 'W', the number of host variables specified in the SQL statement is unequal to the number of
columns in the table or view being operated on by the statement.
The CICS COBOL generator currently generates checks for the two warnings listed above.
The batch COBOL generator has been changed to generate an IBM-supplied SQL error code routine that expands an
SQL error code into the complete DB2 error message found in the back of this Handbook. This will be very useful
in that a large number of the SQL error messages contain variables that are filled in and displayed when this error
routine is executed. This should facilitate easier debugging when SQL errors are encountered.
The code can also be added to any existing batch DB2 COBOL or batch DB2 Easytrieve Plus program. The
following code will be generated into new batch DB2 COBOL programs:
The coding technique will be the same for Easytrieve Plus, but just use the appropriate language syntax.