DB2
DB2
DB2
DB2
November, 1995
ER/CORP/CRS/DB01/002 Ver1.2 1
Modification Log
ER/CORP/CRS/DB01/002 Ver1.2 2
Infosys Contents
TABLE OF CONTENTS
1. ………………………………………………………………………………… 8
2. ………………………………………………………………………………… 13
2.1. OBJECTIVES
2.2. THREADS
2.3. AUTHID
2.4. ADDRESS SPACES
2.5. USING THREE-PART TABLE AND VIEW NAMES
2.6. REVIEW QUESTIONS
3. ………………………………………………………………………………… 16
OBJECTS ………………………………………………………………………. 16
3.1. OBJECTIVES
3.2. OBJECTS
3.2.1. Physical Objects
3.2.1.1. Database
3.2.1.1.1. DBD
3.2.1.2. Tablespace
3.2.1.3. Storage groups
3.2.1.4. Tablespace parameters
3.2.1.5. Segmented tablespace
3.2.1.6. Simple tablespace
3.2.1.7. Partitioned tablespace
3.2.1.8. Indexspace
3.2.2. Logical Objects
3.2.2.1. Table
ER/CORP/CRS/DB01/002 Ver1.2 3
3.2.2.1.1. Data types
3.2.2.1.2. Concept of NULL
3.2.2.1.3. Synonyms and Aliases
3.2.2.1.4. COMMENT ON
3.2.2.1.5. LABLE ON
3.2.2.2. Index
3.2.2.3. View
3.2.2.3.1. View Merge
3.2.2.3.2. View Materialization
3.2.2.4 Catalog table
3.2.2.5 The DB2 Directory
3.3. REVIEW QUESTIONS
4. …………………………………………………………………………… 44
4.1. OBJECTIVES
4.2. DB2’S SUPPORT
4.3. FOREIGN KEYS AND NULLS
4.3.1. Adding Keys
4.4. CONSTRAINTS WHEN INTEGRITY CHECKING IS IN EFFECT
4.5. CYCLES
4.6. DELETE-CONNECTED TABLES
4.7. REVIEW QUESTIONS
5. …………………………………………………………………………..
INDEXING
5.1. OBJECTIVES
5.2. STRUCTURE OF THE BTREE NODE
5.3. SELECTING COLUMNS TO INDEX
5.4. COLUMNS TO AVOID INDEXING
5.5. MULTIPLE INDEXES
5.6. VALUE OF CLUSTERING
5.7. INDEX CARDINALITY AND COMPOSITE INDEXES
5.8. IMPACT OF COLUMN ORDERING IN INDEXES
5.9. INTERSECTION TABLES
5.10. HIGH REDUNDANCY INDEXES
5.11. MAINTAINING CLUSTERING
5.12. INDEX MONITORING
5.13. REVIEW QUESTIONS
6. ……………………………………………………………………………
CONCURRENCY CONTROL
6.1. OBJECTIVES
6.2. LOCKS
ER/CORP/CRS/DB01/002 Ver1.2 4
6.2.1. Lock Escalation Limits
6.3. ISOLATION LEVEL
6.4. INTENT LOCKS
6.5. ACQUIRE AND RELEASE PARAMETERS
6.6. EXPLICIT LOCKS STATEMENTS
6.7. DEADLOCKS
6.8. REVIEW QUESTIONS
7. ………………………………………………………………………….
THE OPTIMIZER
7.1. OBJECTIVES
7.2. THE OPTIMIZER
7.3. THE EXPLAIN COMMAND
7.4. HOW DOES EXPLAIN WORK
7.5. REVIEW QUESTIONS
8.1. OBJECTIVES
8.2. PRECOMPILATION OF THE PROGRAM
8.3. ISSUE THE BIND COMMAND
8.4. COMPILE THE PROGRAM
8.5. LINK THE PROGRAM
8.6. RUN THE PROGRAM
8.7. REBINDING
8.8. REVIEW QUESTIONS
……………………………………………………………………………………..
9.1. OBJECTIVES
9.2. USER IDENTIFICATION
9.3. GRANT AND REVOKE
9.3.1. GRANT
9.3.2. REVOKE
9.4. THE GRANT OPTION
9.5. BUNDLED PRIVILEGES
9.6. REVIEW QUESTIONS
……………………………………………………………………………………
1 ……………………………………………………………………………
DB2 UTILITIES
ER/CORP/CRS/DB01/002 Ver1.2 5
10.1. OBJECTIVE
10.2. REVIEW QUESTIONS
11 ……………………………………………………………………………
11.1. OBJECTIVES
11.2. QUERY MANAGEMENT FACILITY (QMF)
11.2.1. Query By Example (QBE)
11.2.2. QMF PROC
11.3. DATA EXTRACT FACILITY (DXT)
11.4. SPUFI – SQL PROCESSOR USING FILE INPUT
11.5. DB2 INTERACTIVE : DB21
11.5.1. DCLGEN
11.5.2. Defaults
12 ………………………………………………………………………..
PROGRAM DEVELOPMENT
12.1. OBJECTIVES
1 THE COBOL PROGRAM
1.1. Commit/Rollback for Cobol Programs
1.2. The Cobol SQL Statement Delimiter
2 CODING THE WORKING-STORAGE SECTION
2.1. The SQL Communication Area (SQLCA)
2.1.1. Define SQLCA
2.1.2. The precompiler-generated SQLCA
2.1.3. Using the SQLCA
2.1.3.1. Using the SQLCODE field
2.1.3.2. The WHENEVER exceptional condition
2.1.3.3. The meaning of SQL fields
2.2. Define the Tables / Views to be Used
2.2.1. Define the tables / views via DCLGEN
2.2.2. DECLARE TABLE statement generated by DCLGEN
2.2.3. Including the DCLGEN output
2.2.4. Coding the DECLARE TABLE statement
2.3. Define Host Variables
2.3.1. Table row description generated by DCLGEN
2.3.2. Using host variables in SQL statements
2.4. The Indicator variables
2.4.1. Defining the indicator variable
2.4.2. Using indicator variables on “read” (SELECT, FETCH)
2.4.3. Using indicator variables on UPDATE and INSERT
1.1. Objectives
- DB2
- DB2’s attachment facilities
- DBRM
- Bind process
- DB2 objects
- Catalog tables
- Unit of work
- Referential integrity
ER/CORP/CRS/DB01/002 Ver1.2 9
1.2. Introduction
DB2 Is a Relational DBMS developed by IBM for computers running under MVS,
its most advanced operating system for large computers. DB2 supports SQL
(structured query language), which has been standardized by ANSI (American National
Standards Institutes) and ISO (International Standards Organization) and has become
the standard for all relational DBMSs.
DB2 co-operates with attaches to is the technical term-any of three MVS subsystems
environments : IMS, CICS, and TSO. These subsystems cooperate with DB2 facilities
to provide such services as data communications and control of transactions, which are
group of database operations that must be coordinated to avoid the introduction of errors.
CICS is a teleprocessing monitor, a program for controlling online transactions those
that execute as they are entered from a terminal allowing users to interact with the
computer. IMS/DB/DC is a well established nonrelational DBMS, which includes a
teleprocessing monitor. TSO also contains a teleprocessing monitor that can be used by
DB2. DB2 applications running under TSO may be online or batch.
CICS attachment facility ADB2 subcomponent that uses the MVS subsystem
interface (SSI) and cross storage linkage to process requests from CICS to DB2 and to
coordinate resource commitment.
IMS attachment facility A DB2 subcomponent that uses MVS subsystem interface
(SSI) protocols and cross-memory linkage to process requests from IMS to DB2 and to
coordinate resource commitment.
TSO attachment facility A DB2 facility consisting of the DSN command processor
and DB21. Applications that are not written for the CICS or IMS environments can
run under the TSO attachment facility.
The precompiler output include a database request module (DBRM) which contains
SQL statements extracted from the source program. The SQL statements in a DBRM
are those executable statements that must be bound before they can be executed. The
DBRM is kept as a member of a partitioned data set (library) and is given the name of
the program. It also contains a consistency token to distinguish it from other DBRMs
derived from other versions of the program.
The bind process establishes a relationship between an application program and its
relational data. This step is necessary before you can execute your program. Currently,
DB2 allows you two basic ways of binding a program : to a package, or directly to an
application plan. If your application is to make use of remote units of work, then you
must use packages.
ER/CORP/CRS/DB01/002 Ver1.2 10
During the precompilation process, the DB2 precompiler produces both modified
source code and a database request module (DBRM) for each application program. The
modified source code must be compiled and link edited the application program can be
run. DBRMs must go through the bind process.
When determining the maximum size of a plan, several physical limitations must be
considered, including the time required to bind the plan, the size of the EDM
(environmental descriptor manager, which manages application plans and packages)
pool, and fragmentation. There are no restrictions to the number of DBRMs that can
be included in a plan. However, packages provide a more flexible method for
handling large numbers of DBRMs within a plan. As a general rule, it is suggested
that the EDM pool be at least 10 times the size of the largest DBD or plan, whichever
is greater.
Even when they are bound into packages, all programs must be designated in an
application plan. BIND PLAN establishes the relationship between DB2 and all
DBRMs in that plan. Plans can specify explicitly named DBRMs, packages,
collections of packages, or a combination of these elements. The plan will contain
information about the designated DBRMs and about the data the application program
intends to use. It is stored in the DB2 system catalog.
Verifies that the process binding the program is authorized to perform the data
accessing operations requested by your program’s SQL statements. When you issue
BIND, you can specify an authorization ID as the owner of the plan or package. The
owner can be any one of the authorization Ids of the process performing the bind. The
bind process determines whether or not the owner of the plan or package is authorized
to access the data the program requests.
Selects the access paths needed to access the DB2 data your program wants to process.
In selecting an access path, DB2 considers indexes, table sizes, and other factors. DB2
considers all indexes available to access the data and decides which ones (if any) to use
when selecting a path to the data.
ER/CORP/CRS/DB01/002 Ver1.2 11
Application Catalog table
A DB2 object is something that can be defined using an SQL CREATE statement The
objects are classified as follows :
Tables Indexes
Views
Table spaces
Storage groups
Data bases
Synonyms
Aliases
Each DB2 maintains a set of tables containing information about the data it manages.
These tables are collectively known as the catalog. The catalog tables contain
information about DB2 objects such as tables, views, and indexes.
With appropriate authorization, you can retrieve data from catalog tables by using SQL
statements, just as you would with any other table. Each DB2 ensures that at all times
its catalog contains accurate descriptions of the objects that the DB2 controls.
A unit of work is a logically distinct procedure containing one or more steps that change
one or more pieces of data. If all the steps complete successfully, you want the data
changes made to become permanent. But, if any of the steps fail to complete
successfully, you want all modified data to be returned to the value before the procedure
began.
For example, suppose two employees in the sample table DSN8230.EMP exchange
offices. Their office phone numbers need to be exchanged in the PHONENO column.
ER/CORP/CRS/DB01/002 Ver1.2 12
You would use two UPDATE statements to make each phone number current. Both
statements, taken together, are a unit of work. You want both statements to complete
successfully ; if say, only one statement was successful, then you would want both
phone numbers rolled back to their original value before attempting another update.
When a unit of work completes, all locks implicitly acquired by that unit of work after it
begins are released, allowing a new unit of work to begin.
The amount of processing time used by a unit of work in your program determines the
length of time DB2 prevents other users from accessing that locked data. Several
programs trying to use the same data concurrently require each program’s unit of work
to be kept as short as possible in order to minimize the interference between the
programs.
The condition that exists when all intended references from data in one column of a table
to data in another column of the same or a different table are valid. Maintaining
referential integrity requires enforcing referential constraints on all LOAD, RECOVER,
INSERT, UPDATE and DELETE operations.
ER/CORP/CRS/DB01/002 Ver1.2 13
2
2.1. Objectives
- Threads
- AUTHID
- Address Spaces
- Table naming
ER/CORP/CRS/DB01/002 Ver1.2 14
2.2. Threads
2.3. AUTHID
Allows you to specify the primary authorization ID of the owner of the new package.
That ID is the name owning the package, and the name associated with all accounting
and trace records produced by the package.
Each DB2 subsystem consists of three or four tasks started from the operator console.
As shown in the figure below. Each of these started tasks run in a portion of the CPU
called an address space.
The Database Services Address Space (DBAS), provides the facility for the
manipulation of DB2 data structures. The default name for this address space is
DSNDBM1. This component is responsible for the execution of SQL and the
management of buffers, and contains the core logic of the DBMS. The DBAS consists
of three components, each of which performs specific tasks : the Relational Data System,
the Data Manager, and the Buffer Manager.
The System Services Address Space (SSAS), coordinates the attachments of DB2 to
other subsystems (CICS, IMS/DC, or TSO). SSAS is also responsible for all logging
activities.
DSNMSTR is the default name for this address space.
Intersystem Resource Lock Manager (IRLM) is responsible for the management of all
DB2 locks. The default name of this address space is IRLMPROC.
Distributed Data Facility (DDF) is optional. This is required only when distributed
database functionality is needed.
ER/CORP/CRS/DB01/002 Ver1.2 15
2.5 Using Three-Part Table and View Names
A three part table or view name consists of three identifiers separated by periods :
Suppose that you want the name, employee number, and department ID of every
employee whose last name ends in “son” in table EMP at location DALLAS. If you
have the appropriate authority, you could run the following query :
• What is a thread ?
• What is a AUTHID ?
• What are the address spaces ?
• What is a DBRM ?
• What is DBAS ?
• What is IRLM ?
• What is DDF ?
ER/CORP/CRS/DB01/002 Ver1.2 16
3
Object
3.1. Objectives
- Physical objects
- Database
- DBD
- Tablespace
- Simple tablespace
- Segmented tablespace
- Partitioned tablespace
- Storage groups
- Tablespace parameters
- Indexspace
- Logical objects
- Table
- Data types
- Concept of NULL
- Synonyms and Aliases
- OMMENT ON
- LABEL ON
- Index
- View
- View merge
- View materialization
- Catalog tables
- DB2 Directory
ER/CORP/CRS/DB01/002 Ver1.2 17
3.2. Objects
DB2 manages data through a system of logical and physical entities called objects. For
example, tables, indexes and databases are objects. Objects that describes the data in
the way users and developers think about it, are called logical objects ; for example,
tables, and views are logical objects. Objects that refer to the way data are actually
stored in the system, are called physical objects ; for example, database and tablespace
are physical objects (which will be discussed in detail in the coming sections).
3.2.1.1. Database
Database is a collection of logically related objects. Stored data is split into disjoint
databases.
A DB2 database is a set of table spaces and index spaces which are related in that the
index spaces contain indexes on the tables in the table spaces. Databases are used
primarily for administration : whenever a table space is created, it is assigned, explicity
or implicitly to an existing database. That table space is then part of the database, along
with any tables defined for the table space and any indexes defined for the tables. All
these objects are under the control of any one that has been grated certain authority over
the database. An agent with that authority can take appropriate administrative actions
for the objects. Such actions include dropping existing objects in the database, creating
new ones, and examining the data in the tables.
A database is defined using the CREATE DATABASE statement. One DB2 system
can manage upto 65,279 separate database.
Although several application systems can operate on the same database and each program
can access many databases transparently, there are number of advantages to defining a
separate database for each subject area.
ER/CORP/CRS/DB01/002 Ver1.2 18
3.2.1.1.1. DBD
3.2.1.2.Tablespace
A page set used to store the records of one or more tables. Space is dynamically
extendable collection of pages.
A table space is a storage structure. Depending on its nature, a table space can hold one
or more tables. All tables are kept in table spaces. There are three types of
tablesapces.
1. Segmented tablespace
2. Simple tablespace,
3. Partitioned tablespace
Maintenance for the data sets of a storage structure can be left to DB2. If it is left to
DB2, the storage structure has an associated storage group. The storage group is
essentially a list of DASD volumes on which DB2 can allocate data sets for associated
storage structures. The association between a storage structure and its storage group is
made, explicity or implicitly, by the statement that creates the storage structure.
Spaces in a given database do not all have to have same storage group. All spaces
sharing a storage group need not be from the same database. For convenience, defaults
for spaces and storage groups are defined, so that a naïve user can ignore these aspects.
Storage group and bufferpool in the definition will be defaults if no storage group and
bufferpool are specified during creation of tablespace.
ER/CORP/CRS/DB01/002 Ver1.2 19
CREATION OF A TABLESPACE
PCTFREE OPTION
PCTFREE specifies the percentage of free space to be left free on each page.
PCTFREE free space allows for insertion of new records and for expansion of
variable length fields.
FREEPAGE OPTION
FREEPAGE specifies the number of pages to be loaded between each page left free. It
is useful for finding a near page for inserting a new record.
Estimates of free space requirements need not be exact. The developer can monitor the
number and frequency of relocated rows and the loss of clustering and adjust free space
before re-organisation to achieve the desired re-organisation schedule.
ER/CORP/CRS/DB01/002 Ver1.2 20
• Subtract unnecessary free space, if re-orgnisation is not needed for the scheduled
re-organisation. Because free space reduces the number of rows that can fit in a
page and thereby increases I/O.
Adding columns
While adding new columns, more space may be required. Additional freespace may be
allocated by specifying it with the PCTFREE parameter in the ALTER TABLESPACE
command. This can be done before ore after the values for the new column are entered.
Done before – no row relocation. After – row relocation may be required (a row is
never broken up between pages). The correct choice depends on table size and
frequency of update. Large table with update values known : create space first. Small
table, with infrequent update : keep adding, do re-organisation on schedule.
The amount by which a VARCHAR field can expand can be estimated roughly. The
possible amount of expansion of each row is the difference between the minimum and
maximum description contained in the VARCHAR column. The probable amount of
expansion depends on a number of factors related to update patterns. For example, the
percentage of rows changed and the average size of the changes are some of the factors.
CLOSE OPTION
The CLOSE parameter is used during tablespace creation to tell DB2 How to handle
opening and closing of tablespace’s VSAM datasets. CLOSE = YES is the default and
causes the tablespace to be opened each time a plan is executed and closed after
execution. Closing also takes place when work is committed. CLOSE = NO will open
the tablespace when it is first accessed, and will keep it open till DB2 is shut down or
the tablespace is stopped.
BUFFERPOOL OPTION
There are 4 bufferpools BP0, BP1, BP2 and BP32 which DB2 provides. It can
analyse usage patterns and decide what data to keep in buffers to minimize secondary
storage access. The administrator has to allocate memory to these bufferpools. BP0 is
compulsory as DB2 uses it for catalog tables, joins, utilises and sorts. BP32 is also
compulsory if any table has rows longer than 4 k bytes (or if any joins result in rows
longer than 32K bytes) thereby needing 32K byte pages. An access to a table having
32K byte pages is equivalent to 8 physical accesses and every effort should be made to
keep the need for this as low as possible.
Other than BP0 and BP32 the administrator has several choices for the
remaining bufferpools.
ER/CORP/CRS/DB01/002 Ver1.2 21
Under 1, the principle is that most applications will open a table and its associated
index. Thus this approach will prevent the tables and indexes of an application from
contending for bufferspace.
The idea in 2 is to avoid non-priority applications from blocking out buffer space from
priority applications. This has drawbacks. When priority applications are not active,
bufferpool space is wasted. Also as the number of priority applications builds up, they
will contend with each other. Further the priority of an application changes over time
and hence the assignment of applications to bufferpools needs to be managed.
The third approach leaves the problem of bufferpool management to DB2. Its
algorithms will allocate bufferspace according to actual use. In general this is a good
strategy because DB2’s algorithm are time tested. Anotehr good reason for leaving this
department to DB2 is that when 97.5% of a bufferpools’ pages are in use, then DB2
automatically switches off many of its sophisticated buffer management techniques.
The chance of this happening is significantly less with one large bufferpool than with a
few smaller ones.
In general, large bufferpools are good performance wise. As the bufferpool fills up,
sophisticated features are shutoff one by one. 50% full – buffered writing of updated
pages to disk is shut off 90% synchronous prefetch (getting 32 pages at a time rather
than 8) will be shut off 95% - one I/O is performed for each page. These can cause
significant performance degradation.
LOCKSIZE
It is the size of the physical object to be locked during concurrent access to the
database. There are three lock sizes. They are page, table and tablespace locks. Table
locksize is available only in SEGMENTED tablespaces. The tablespace creator can
leave the decision of the size of the lock to DB2 by specifying a LOCKSIZE of ANY.
DB2 usually locks by PAGE. This is alos the default if nothing is specified. Choice of
locking unit involves a concurrency/efficiency trade-off. Locking at lower levels of
granularity allow high degree of concurrency, but involve more CPU time for checking
the presence of locks.
When application plans are bound, DB2 chooses the locksize, types and
duration of each lock depending on the LOCKSIZE specified in the CREATE
TABLESPACE, type of SQL statement being executed and the BIND parameters
chosen.
For tablespace that usually have moderate updates, but occasionally have heavy
updates, PAGE locksize can be specified in the CREATE TABLESPACE. Any program
ER/CORP/CRS/DB01/002 Ver1.2 22
that wishes to perform extensive updates would lock the tablespace before doing its
updates.
ERASE OPTION
DB2 provides two methods for deleting the data when the tablespace is dropped. First,
it will merely drop the database from the system, leaving the data in DASD until it is
written over. For this, the option is ‘ERASE NO’. The second delete option fills the
data of the tablespace with zeros. The option for this is ‘ERASE YES’.
SEGSIZE
SEGSIZE keyword in the CREATE TABLESPZE specifies the segment size in multiples
of 4 pages ranging from 4 to 64 pages.
It specifies the size of the VSAM datasets that DB2 will create for the tablespace. DB2
assigns the space to primary area and a secondary area which it uses when the primary
area is full. The key for selecting the most efficient primary and secondary quantity
sizes is determining a primary amount that is certain to hold the tablespace but not so
large that it wastes storage.
In this, tablespace is split up into segments of equal size. Segments are of 4 to 64 pages
size in increments of 4 pages.
1. It can house one or more table ; there is no limit on the number of tables,
2. Each segment is dedicated to a table ; a table can occupy multiple segments,
3. All segments in a table space must be of same size,
4. A segment size of 64 or 32 pages maximises the benefits of prefetch,
5. To avoid wasting storage space for tables smaller than 64 pages, table and
segment sizes should be approximately the same.
Because DB2 treats each segment separately when allocating free pages, FREEPAGE
should be set with segment
ER/CORP/CRS/DB01/002 Ver1.2 23
Blocks , with each block containing information about a segment. Each
segment block includes a pointer to the next segment block that applies to the same
table, 4 bits of information are kept per segment. This encodes information such as
whether there is enough space in the segment for inserting a row in sequence, for
increasing a the length of a variable length row, etc, basically this information could help
DB2 in avoiding the data page in many situations thus increasing efficiency.
The segmented tablespace allows for the mass delete algorithm which reads and
updates only the space map table and avoids altogether the data pages (this however has
the disadvantage that it cannot return the number of rows deleted). Mass delete is
possible only when the delete statement has no predicate.
Segmented tablespaces also allow skipping of pages that do not hold date of a
table. This is not possible in a non-segmented that contains multiple tables.
Utilities for copying and recovering data operate at the level of a tablespace and
not table level. Thus if related tables are put into one segmented tablespace then such
operations can be done in one shot on them. This can of course be a disadvantage when
the operation needs to be performed on only one of the tables.
The REORG utility which, among other things, reallocates free space and returns
rows which are out of sequence to their proper place works better for multiple tables in a
segmented tablespace than for multiple tables in a non-segmented tablespace. It will not
recluster a a clustering index if more than one table one table occupies a non-segmented
tablespace.
Opening a tablespace requires about 1.2K of virtual space. Thus if several tables
are put in single tablespace then the same 1.2 K will serve to access all the tables in the
tablespace.
Both simple and segmented types can provide storage space for one or more tables, but
segmented tablespaces are better for managing multiple tables. Simple tablespace should
almost never be used for managing multiple tables.
1. Simple tablespace can house one or more table; there is no limit on the number
of table.
2. Rows from multiple tables can be interleaved on a page under the developers
control and maintenance.
One advantage of such interleaving is, if table S and SP were assigned to the same table
space, them it would be possible to store all the shipments for supplier S1 close to the
ER/CORP/CRS/ DB01/002 Ver 1.2 24
stored record for supplier S1, all the shipments for supplier S2 close to the stored record
for supplier S2, and so on. Queries such as “get details of supplier S1 and all
corresponding shipments’ – in particular, certain join queries can be handled very
efficiently, since the number of I/O operation would be reduced. But neither the
optimizer nor the REORG utility will understand such a clustering.
A partitioned tablespace allows a table to be divided by rows into partitions that the
system can manage separately. Each partition can be placed on different storage devices,
and freespace can be allocated by partition. A partitioned tablespace must have a
clustering index. DB2 allows up to 64 one GB partitions, each in its own VSAM dataset,
partitions can be larger-up to 4 GB each, but the total tablespace size connot exceed 64
GB.
Large table ( more than 1 million rows ) should generally be kept partitioned. Frequently
accessed portions can be kept on fast media. DB2’s utilities lock tablespace when they
work. The utilities can work at the partition level. Thus the locks will be in force for a
shorter duration.
As the number of indexes grows, the benefits of partitioning reduce as the effort in
reorganising indexes will be prohibitive. The clustering index is kept partitioned and
needs little maintenance. The first 40 bytes of a partitioning index identifies the partition
number. All other indexes cover the entire tablespace. Re-organisation of a partition
requires reorganiation of all of these large indexes and may cost almost equal to the cost
of reorganising the entire database.
FREEPAGE 0
LOCKSIZE PAGE
BUFFERPOOL BP 0
CLOSE NO;
3.2.1.8 Indexspace
A page set used to store the entries of one index. Indexes are also kept in storage
structures. Unlike table spaces, each index space holds one and only one index. DB2
storage structures—table or index spaces—are managed by access method services.
1. There is exactly one index per indexspace. Table and its associated indexes must
be stored in a single datebase.
2. Indexspace is created when the associated index is creatd.
3. Indexpages are 4 K pages. A portion of the index page can be locked.
4. Indexspace for a partitioned tablespace is considered to be partitioned. Individual
partitions can be assigned to diiferent storage groups.
5. Index is a B-tree.
Create index
Only one index is allowed per indexspace. Thus CREATE INDEX also creates the
INDEXSPACE.
Subpage locks
Index pages are 4K bytes, Index pages can be locked by subpage increment (1,2/2,1/4
1/8 and 1/16). A SUBPAGE value of 1 indicates that the entire page will be locked, 4 is
the default which is used if no value is specified. The subpage value must be large
enough to contain multiple key values, their RID’s and some free space. Poor response
may sometimes be because of index contention rather than table contention. In these
cases response can be improved by increasing the value of the SUBPAGE parameter.
This cannot be done by an ALTER and needs dropping and recreation of the index.
The index for the partitioned tablespace given above is crated as shown below.
BUFFERPOOL BP 0
CLOSE NO;
3.2.2.Logical objects
3.2.2.1 Table
ER/CORP/CRS/ DB01/002 Ver 1.2 27
Users perceive a table as a rectangular array of values. Typically, a table represents some
class of entities, and each row represents a member of that class, while each column
represents an attribute of the members. The rows of table have no intrinsic order, but the
columns do. Moreover, each column has a name, by which it can be referred to in SQL
statements.
Each value in a table has a data type. The data type indicates how value is represented in
storage . All the values in a given column have the same data types , which is the data
type of the column.
The data type of a column determines what you can and cannot do with it. For example,
you cannot insert character data, like a last name, into a column whose data type is
numeric.
The data types are divided into three general categories: string, numeric, and datetime.
FLOAT(n)
Datetime Data
DATE Designates a point in time according to the
Gregorian calendar.
TIME Designates a time of day according to a 24
– hours clock.
TIMES STAMP Designates a date and time as previously
defined by the DATE and TIME data
types. The time includes a fractional part in
microseconds.
Note: Character strings can contain both single-byte and double-byte characters. Such
strings are commonly referred to as mixed data strings.
The basic rule for operations is that the data types of the operands involved must be
compatible. The compatibility rule also applies to other operations such as UNION and
concatenation. The compatibility matrix for data types is shown in table 3.
Note :- * The compatibility of date time values is limited to assignment and comparison
Datetime values can be assigned to character string columns and to character string variables. See Chapter 3 of SQL Reference for
more information about datetime assignments.
A valid string representation of a date can be assigned to a date column or compared to a date.
A valid string representation of a time can be assigned to a time column or compared to a time.
A valid string representation of a timestamp can be assigned to a timestamp column or compared to a timestamp.
a null value indicates the absence of a column value in a row . A null value is not the
same as zero or all blanks.
When a table is created in DB2, each column is defined to have a specific data type.
Depending on how it is defined, a column may allow null values. A null value in a
column tells DB2that the actual value is unknown. Because of this, logical expressions,
such as those as that compare a column value to a constant, could evaluate to true, false,
or unknown.
AWHERE clause can specify a column that, for some rows, contains a null value.
Normally, values from such a row are not retrieve, because a null value is neither less
than, equal to, nor greater than the value specified in the condition. To select values from
rows that contain null values, specify;
You can also use a predicate to screen out null values, specify:
When a null value is encountered, its value is treated as if it were higher than all other
values. Therefore, a null value appears last in an ascending sort and first in a descending
sort. If there are null values in the column you specify in the GROUP BY clause, DB2
considers those null values in the GROUPS BY column to be equal, and returns a single-
row result summarizing the data in those rows with null values.
All data types include the null value. The null value is a special value that is distinct
from all nonnull values and thereby denotes the absence of a (nonnull) value. Although
all data types include the null value, columns defined as NOT NULL cannot contain null
values.
these are alternate names for tables and views. Synonyms can only used to refer to
objects that exist locally, but aliases can be used to refer to remote objects as well as local
objects.
Synonym. In SQL, an alternative name for a table or view. Synonyms can only be used
to refer to objects at the substem in which the synonmy is defined.
ER/CORP/CRS/ DB01/002 Ver 1.2 36
Alias. An alternate name that can be used in SQL statements to refer to a table or view
in the same or a remote DB2 subsystem.
An alias, like a synonym, is a DB2 object that represents a table or a view. Unlike a
synonym, an alias can represent remote tables and views, and it can be used by anyone,
not just its creator. In addition, you do not need DB2 authority to use it. However,
you must have authority to use the table or view that it represents.
A reference to an alias could a one-two, or three-part name. The rules are basically the
same as those used to refer to a table or view.
A one-part name refers to a local alias. If the statement being executed is dynamic, the
owner of the alias is your current SQL authorization ID. Otherwise, it is the value
specified on the AQUALIFIER bind option. If a value is not specified on the
QUALIFIER bind option, then the owner of your package or plan is the qualifier of the
alias.
A two-part name also refers to a local alias. As is true for a table or view, the first
qualifier identifies the owner.
A three-part name could refer to either a local or a remote alias. As is true for a table or
view, the first qualifier specifies the location, and the second qualifier identifies the
owner. If the alias is remote, it must represent a table or view at its own location.
Assume now that the alias SMITH.DALEMP has been defined at your local subsystem
for the table DALLAS.DSN 8230.EMP. You could then substitute the alias for this
table name. The result would look like this :
An advantage to using a locally defined alias is that the SQL statements in which it
appears need not be changed if the table or view for the alias is either moved to another
location or renamed. To make these statements valid, drop the original alias and create
it again, and, for embedded SQL, rebind the program in which it appears.
The effect of using an alias or a synonym in an SQL statement is that of text substitution.
For example, if A is an alias or synonym for table Q.T, one of the steps involved in the
preparation of SELECT *FROM A is the replacement of ‘A’ by ‘A.T’ .
An alias can be defined on the name of a table or view, including tables and
views that are not at the current server. A synonym can only be defined on the name of
a table or view at the current server.
Dropping a table or view has no effect on its aliases. But dropping a table or
view does drop its synonyms.
An alias is a qualified name that can be used by any authorization ID. A synonym
is an unqualified name that can only be used by the authorization ID that created it.
An alias defined at one DB2 subsystem can be used at another DB2 subsystem.
A synonym can only be used at the DB2 subsystem where it is defined.
When an alias is used, an error occurs if the name that it designates is undefined
or is the name of an alias at the current server. (Note, however, that the name can
designate an alias defined at another server if the alias represents a table or view at this
other server), When a synonym is used, this error cannot occur.
3.2.2.1.4. COMMENT ON
The COMMENT ON statement adds or replaces comments in the descriptions of tables,
views, aliases, or columns in the DB2 catalog at the current server.
3.2.2.1.5. LABEL ON
The LABEL ON statement adds or replaces labels in the descriptions of tables, views
aliases, or columns in the catalog at the current server.
LABEL ON DSN8230.DEPT
(MGRNO IS ‘MANAGER’S EMPLOYEE NUMBER’,
ADMRDEPT IS ADMINISTERING DEPARTMENT);
3.2.2.2. Index
An index is an ordered set of pointers to rows of a base table. When you request the
creation of an index, DB2 builds, this structure and maintains it automatically.
When you request the creation of an index, you specify a key. The key consists of one
or more columns of the table. In the CREATE statement, you identify these columns
and their order of appearance in the key.
The key has a value for each row in the table for which the index is defined. The value is
based on the values for that row of the columns in the key. The value of a key with two
or more columns is the concatenation of the column values in the specified order.
ER/CORP/CRS/ DB01/002 Ver 1.2 39
3.2.2.2 View
Views provide an alternative way of looking at the data in one or more tables. Like
tables, views have rows and columns with no inherent order of rows. You specify view
names in the FROM clause of the SELECT statement in the same way that you specify
table names. You can create views and authorize their use for many table-like
operations.
When you create a view, you specify a query in the CREATE VIEW statement. The
result table defined by this query is then the table the view represents in operations
involving the view. This is sometimes termed the view table to distinguish it from the
view’s definition. Looked at this way, the view table might change as changes are made
to the base tables for the view, but the view definition remains the same.
The view is named XYZ. The view table consists of certain values in the table
DSN8230. The values are those in the EMPNO and HIREDATE columns for the rows
representing employees in departments A00 and D11. For the view table, these columns
have the names EMPLOYEE and WHEN_HIRED.
A table has a storage representation, but a view does not. After an operation involving
a view is ended, the view table disappears. A view’s definition is stored in the catalog.
No data is stored and, therefore, no index can be created for a view. However, an index
created for a table on which a view is based can improve the efficiency of operations
involving the view.
For example, a view can show summary data for a given table, combine two or more
tables in meaningful ways, or show only rows that are pertinent to the process using the
view.
Some valid operations on tables are not valid on views or the definition of views, for
example, read-only views cannot be used to insert, update, or delete rows in their base
ER/CORP/CRS/ DB01/002 Ver 1.2 40
tables. Also, the keyword, UNION, Cannot be used in the definition of a view. There
might be times when no single table contains all of the data that you need. Instead, the
data is scattered among several tables. DB2 provides views so you can look at parts of a
table or at data from several combined tables.
A view does not contain data ; it is a stored definition of a set of rows and columns. A
view scan present any or all of the data in one or more tables, and in most cases, can be
used interchangeably with tables.
When a program accesses the data defined by a view, DB2 processes the view’s
definition. This results in a set of rows the program can access with SQL statements.
Views that can be updated are subject to the same referential constraints as the tables
upon which they are defined.
Use the CREATE VIEW statement to define a view and given the view a name, just as
you do for a table.
This view adds each department manager’s name to the department data in the
DSN8230. DEPT table. Now that the view VDEPTM exists, you can manipulate the
data in it just a s you would manipulate the data in DSN8230. DPET and
DSN8230.EMP. However a view defined on more than one table cannot be used for
update operations. It is considered a read-only view. To see all of the data in the view,
you can execute the following statement.
SELECT
FROM VDEPTM;
When you define a view, DB2 stores the definition of the view in the DB2 catalog but
does not store any data for the view since the data already exists nit the source tables or
tables. Views are kept up to date automatically as the tables on which they are based are
updated. You can use views to limit access to certain kinds of data, such as salary
information. Views can also be used to the following :
Make a subset of a table’s data available to an application. For example, a view based
on the employee table might contain rows for a particular department only.
Combine data from two or more tables and make the combined data available to an
application. By using a SELECT statement that matches values in one table with those
in another table, you can create a view that presents data from both tables. However,
data defined by this type of view can only be selected. You cannot update, delete, or
insert data into a view that joins two tables.
When using views in an application program, whether to simplify a table, to get more or
different data than a single table contains, ore prevent a user from seeing classified
columns, you must be aware of the restrictions that apply to some views.
Because a view does not contain data, special rules apply for inserting, deleting, or
updating rows in a view. If the view is merely a subset (or a rearrangement) of a base
table’s rows or columns :
The owner of the plan or package that contains the program must be authorized to update,
delete, or insert rows into the view. You are so authorized if you have created that view
and have privileges for the table on which the view is based. Otherwise, to bind the
program you have to obtain authorization via a GRANT statement.
When inserting a row into a table (via a view), the row must have a value for each
column of the table that does not have a default value. If a column in the table on which
the view is based is not specified in the view’s definition, and if the column does not
have a default value, you cannot insert rows into the table via the view.
In the view merge process, the statement that references the view is combined with the
subselect that defined the view. This combination creates a logically equivalent
statement. This equivalent statement is executed against the database. Consider the
following statements.
Column VC1 occurs as the argument of a column function in the view referencing
statement. The values of VC1, as defined by the view defining subselect, are the result
of applying the column function SUM (C1) to groups after grouping the base table T1
by column C2. There is no equivalent single SQL SELECT statement which can be
executed against the base table T1 to achieve the intended result. There is no way to
specify that column functions should be applied successively.
In the previous example, DB2 performs view materialization, which is a two step
process.
1. The view’s defining subselect is executed against the database and the results are
placed in a temporary table.
2. The view’s referencing statement is then executed against the temporary table to
obtain the intended result.
Whether a view needs to be materialized depends upon the attributes of the view
referencing statement, or logically equivalent referencing statement from a prior view
merge, and the view’s defining subselect.
Each DB2 catalog table maintains data about an aspect of the DB2 environment.
The catalog tables describe such things as table spaces, tables, columns, indexes,
privileges, application plans, and packages. Data in the catalog tables is available to
authorized users of DB2 through normal SQL query facilities.
DB2 Catalog Links and relationships between the DB2 Catalog tables.
The catalog tables are updated by DB2 during normal operations in response to
SQL data definition statements, SQL control statements, and certain commands and
utilities.
The SYSIBM.SYSCOLUMNS table contains one row for every column of each table
and view.
The SYSIBM.SYSDATABASE table contains one row for each database, except for
database DSNDB01.
The SYSIBM.SYSDBAUTH table records the privileges held by users over databases.
The SYSIBM.SYSDBRAM table contains one row for each DBRM (database request
module) of each application plan.
The SYSIBM.SYSFIELDS table contains one row for every column that has a field
procedure. It can also contain up to ten additional rows for every column that serves as
the first column in an index key. The additional rows, which contain statistics, can be
added when the index is scanned by the RUNSTATS utility. The column for the added
rows need not have a fieldprocedure.
The SYSIBM.SYSFOREIGNKEYS table contains one row for every column or every
foreign key.
The SYSIBM.SYSKEYS table contains one row for each column of an index key.
The SYSIBM.SYSLINKS table contains information about the links between DB2
catalog tables.
The SYSIBM.SYSPACKAGE table contains a row for every package bound at the local
DBMS, regardless of the location of the binder.
The SYSIBM.SYSPACKLIST table contains one or more rows for every local
application plan bound with a package list. Each row represents a unique entry in the
plan’s package list. The entry could choose an individual package or all the packages in
a given collection.
The SYSIBM.SYSPLAN table contains one row for each application plan.
The SYSIBM.SYSRELS table contains one row for every referential constraint.
The SYSIBM.SYSSTMT table contains one or more rows for each SQL statement of
each DBRM.
The SYSIBM.SYSSTOGROUP table contains one row for each storage group.
The SYSIBM.SYSSNONYMS table contains one row for each synonym of a table or
view.
The SYSIBM.SYSTABAUTH table records the privileges held by users on table nad
views.
The SYSIBM.SYSTABAUTH table records the priviliges held by users on tables and
views.
The SYSIBM.SYSTABLESPACE table contains one row for each table space.
The SYSIBM.SYSVIEWS table contains one or more rows for each view.
The DB2 directory is composed of five “tables”. These tables, however, are not true
DB2 tables because they are not addressable using SQL. Let us call these “tables”
structures. These structures control DB2 housekeeping tasks and house complex control
structures used by DB2. Brief description of these five structures are given below :
SCT02 The SCT02 structure holds the skeleton cursor tables (SKCTs) for DB2
For DB2 application plans. These skeleton cursor tables contain the
instructions for implementing the access path logic determined by the DB2
optimizer. The BIND PLAN command causes skeleton cursor tables to
be created in the SCT02 structure.
SPT01 This structure houses skeleton package tables, which contain the access
Path information for DB2 packages. The BIND PACKAGE command
causes this table to be created in this structure.
DBD01 Database descriptors, or DBDs, are stored in the DBD01 DB2 Directory
Structure.
SYSUTIL This structure monitors the execution of all on-line DB2 utilities.
SYSLGRNG Information from the DB2 logs are recorded on SYSLGRNG for
tablespace updates.
4.1. Objectives
- Referential integrity
- DB2’s support of referential integrity
- Constraint when RI is in effect
- Self-referencing tables
- Cycles
- Delete-connected tables
Referential integrity rules could be of three types, restrict (action rejected), cascade
rule (deletion will be cascade) and neutralise rules (NULLs substituted approximately).
CREATE TABLES
(SN CHAR(6) NOT NULL,
SNAME CHAR(20) NOT FULL WITH DEFAULT,
STATUS SMALLINT NOT NULL WITH DEFAULT,
CITY CHAR (15) NOT NULL WITH DEFAULT,
PRIMARY KEY (SN)
IN DAGKWB.STSP ;
Primary and Foreign key columns need not have the same NULL defaults. Whether
foreign keys should be allowed to be null or not depends on the situation. In the S, P, SP
situation it would not make sense. But in an employee table, the department number
could conceivably be null if the employee is yet to be assigned.
ALTER TABLES
PRIMARY KEY (SN)
After this is done, DB2 does not allow any access to the table till it checks out that no
violations of the foreign key already exist in the table. Any violations found are written
ER/CORP/CRS/ DB01/002 Ver 1.2 50
to an exception table. A foreign key and the associated constraints can be dropped for
batch updates. After this, when the foreign key is redefined, the CHECK DATA utility
should be used to verify that all is well.
This can possibly cause a violation of entity integrity. At bind time DB2 recognises this
and flags it an error.
S1 SMITH 20 LONDON -
S2 JONES 10 PARIS S1
S3 BLAKE 30 PARIS S2
JSUP
J# PRIMARY_S SECONDARY_S
J1 S1 S2
J2 S1 S2
J3 S2 S3
DELETE FROM S
WHERE S NOT IN
(SELECT SECONDARY_S
FROM JSUP
WHERE JSUP.SECONDARY_S = S.S#);
The results of this statement, however, will be different depending on the order in which
the rows are processed. If S# = S1 is evaluated in the subselect first, the NOT IN clause
evaluates as true because S1 is not a secondary supplier. Therefore, S1 is deleted from
the S table. Since it is a primary key value and a cascade rule is in effect, the S1 rows in
ER/CORP/CRS/ DB01/002 Ver 1.2 51
JSUB table also deleted. When S# = S2 is evaluated in the subselect, the NOT IN clause
also returns true, since the previous cascade delete had eliminated the two jobs in which
S2 had been secondary supplier. S2, therfore, is also deleted and its deletion cascades to
eliminate the J3 row. Now, when S# = S3 is evaluated in the subselect, the NOT IN
clause returns true and S3 is deleted.
Suppose, however, that S3 were the first value from the S table to be evaluated in
the sublselect. In that case, the NOT IN clause would return false because, at this point in
the processing, the J3 row will exists, with S3 as its secondary supplier, and S3 row will
not be deleted.
To avoid these anomalies, DB2 will not allow deletions based on a subselect that
references the table from which the deletions are being made.
Self reference
A single table can include both a primary key and a related foreign key. This is called
self reference.
S_O
DELETE RESTRICT is of little practical use. The DELETE SET NULL rule is not
suitable for a self referencing constraint because it holds the potential for unpredictable
results.
If DELETE SET NULL were in effect, when the S# =S1 row was deleted, S1 in
S_OWNER column would be set to NULL. If the rows were processed in order, when
the S# = S2 row was deleted, S2 in S_OWNER column would be set to NULL.
Eventually, all rows in the table would be deleted. If the rows are not processed in order,
then less number of rows will be deleted.
Therefore by definition, the foreign key in a self referencing table must specify
DELETE CASCADE rule.
In a self referencing table, more than one row cannot be inserted with a subselect.
Because, depending upon the order of insertion some rows from subquery may get
inserted or not get inserted.
4.5 CYCLES
One table is a primary key table to other and the second is a primary key table to the first.
Cycles could involve more than tow tables also. DELETE CASCADE may not be used
in a tow table cycle. In a cycle involving more tables, at least one of the foreign keys
must employ the RESTRICT or SET NULL rule.
tables related by foreign keys are delete connected because the presence or absence of
values in one table effects delete processing in the other. When transitive dependencies
occur, there can be problems. For example A may be delete connected with B which is
delete connected with C, thereby implying that C is delete connected with A. through
another path C may be directly or indirectly delete connected with A. C is thus delete
connected with A in more than one way. If the nature of delete connection is different
then different orders of processing will yield different results. Thus DB2 requires that the
foreign keys that establishes table’s multiple delete connections must all be defined to
have the same delete rule and the rule may not be the SET NULL rule. Attempts to
violate this rule will be prohibited.
5.1 Objectives
Indexing
This chapter deals with indexing and performance. In this chapter we will discuss about.
Sometimes DB2 can satisfy the query by doing a scan of the index only without
going to the data pages at all (matching or non-matching scans without data reference).
the leaf page level must hold enough index entries and associated pointers
to point to point to all rows in a table. For unique indexes, the leaf node holds one entry
and one pointer. The pointer is a 4 byte RID indicating the row’s position in the data
pages. The leaf page in a non-unique index has space for a value and up to 255 pointers.
If more than 255 occurrences of a particular value exist then a new leaf node with the
value and 255 more pointer is created, and so on. A single index page contains 3660
bytes of usable space. The remaining space may be used for control Information.
Updating a value on which a table is indexed may cause it to be moved from one page to
another. When a table is loaded or recovered each index to it must be built or rebuilt.
When tablespaces are reorganised indexes must be rebuilt.
If a table has less than 7 pages the optimizer would generally not use an index
even if one exists, because a complete scan will be faster. Possible exceptions to this
arise when joins or referential intergrity checking are involved.
nonclustering indexes are beneficial on columns that are searched often, or used injoins
of small percentages of their rows. Foreign keys are good candidates. Indexing columns
on which aggregates are often performed (SUM, COUNT, etc.), is also beneficial as DB2
can satisfy the query without accessing the data pages. The same reasoning applies to
MAX, MIN, etc.
Example:
If there is an index on QTY, then only leaf nodes of the index pages need to be accessed.
From that, we can find out the SUM (QTY) without accessing data pages at all.
Clustering indexes should be selected with care since only one is allowed per
table. God for columns with high rebundancy that are searched over ranges of values.
Hence clustered index should not be created on primary key or unique keys. Foreign key
columns are usually highly rebundant, and are used in joins. They are good candidates
for clustering indexes.
MAX and MIN can be satisfied in one index access of descending or ascending
index repectively. If a predicate is predicate is specified in a query with an aggregate
function, a matching scan can be used to narrow the search, before the aggregrate is
applied. Processing all leaf pages will require much fewer I/Os than scanning all data
pages since many more leaf nodes than data records will fit into a page. Clustering is
useful when all the values need to be processed in sequence. Without a clustering index,
DB2 will need to sort to satisfy queries involving GROUP BY, ORDER BY or
DISTINCT. While inserting, if a clustering index exists, it will be used. If no clustering
index exists, a non-clustering index may be chosen by the optimizer. This will be the
first index created for the table. Initially values are inserted as if this were the chosen
clustering index. Re-organisation will however not preserve this clustering.
Example:
Consider a table A with cardinality of 20,000 and assume these 20,000 rows are
uniformly distributed among 100 pages. Consider a column of the table A with
cardinality of 100.
These 200 rows may uniformly get distributed among 100 pages. A page will
have 2 rows for a given value of the column. The, for a equality condition, at the worst
case, we need to access each page twice. In this condition, using index is of little use.
Suppose if the number of distinct values is 400, then number of rows slected for a value
will be 50 and a page has only 0.5 row for a particular equality condition.
Sometimes indexes will be needed for locating infreqently occuring data in skewed
tables.
Useful for satisfying queries involving multiple predicates jointed by AND and OR. The
qualifying RIDs obtained through the individual indexes are sorted an merged. The
resulting RIDs will be in order and hence reduce the number of page accessed (list
prefetch)
If a non-clustering index is used for accessing data, then a given data page may be
accessed multiple times. Clustering indexes allow for merge join without sorting the
inner and outer tables. Indexes will be used in joins only if the joining columns are of the
same data type and length. This kind of mismatch is sometimes the cause of poor
performance. Use of functions to achieve compatibility also will not help as this will
negate the use of indexes.
Example:
Consider an employee table with 10,000 rows located on 200 data pages, Employees
distributed uniformly across 20 offices. Consider locating all employees in a particular
office (500 rows will be returned). With a non-clustering index the leaf pages will point
to the 500 RIDs. Thus 500 I/Os will be required, with some of the 200 data pages being
read more than once. In some cases list prefetch will be employed. In this the RIDs will
be sorted and sequential prefetch will be used, in which 32 pages will be obtained in one
I/O. each page need be read only once. Thus the number of I/Os will be 200/32.
DB2 analyses the extent of rebundancy and decides whether a tablespace scan or index
scan is preferred. It estimates what percentage of the total number of row will be
returned by the SELECT. This is the FILTER FACTOR. With composite indexes the
individual filter factors are multiplied. There may not always be complete information
available to DB2. The following information is kept by DB2.
Consider keeping a composite index on city and weight. If there were far fewer entries
with CITY = ‘XYZ’ than parts with weight > 500, then putting city before part will be
useful because a matching scan for XYZ, 500 followed by a sequential scan will read
about half of all the XYZ entries to satisfy the query. If weight were put first, then a
matching scan for 500, XYZ followed by a sequential search of all parts with weight
greater than 500 may be needed. Columns with high filtering capability should be put
first.
Updating these requires heavy I/O. this is because the RID’s have to be added to the list,
which may cause page splitting and consequently locking of index and loss of
concurrency. If several rebundant columns are indexed in a table, then update and delete
processing can be very slow. Delete processing is even slower as it involves deleting and
shifting of RIDs to the left from each rebundant index. Low cardinality columns should
ideally not be indexed. If at all needed, some other column can be added to increase the
cardinality to improve performance.
DB2 keeps track of which columns are clustered. After RUNSTATS the percentage of
clustering is determined. If it is above 95%, then the column is considered to be
clustered. Clustering is maintained as long as free pages and freespace in pages will
allow it. After that clustering will be disturbed, till reorganisation is done again. The
percentage of clustering is used by DB2 to determine if an index should be used. The
optimizer will go by the value recorded in SYSIBM.SYSINDEXES for
CLUSTERRATIO. If RUNSTATS is not executed, then the optimizer can be misled to
make a wrong choice. Periodically re-organisation should be done. To identify the tables
which are marked as clustered but are in fact below 80% clustering the administrator my
use SQL:
REOGR will not recluster an index when multiple tables share a simple tablespace.
Running REORG does not cause automatic rebind. Typcially, after a REORG,
RUNSTATS should be used so that the optimizer can use current information on future
bind operations.
tow utilities are provided for index monitoring, viz., SYSPLANDEP and EXPLAIN.
SYSPLANDEP can be used to find the programs using an index. If very little use is
being made the index can be dropped. EXPLAIN command can be used to determine
ER/CORP/CRS/ DB01/002 Ver 1.2 59
what access path is chosen by the optimizer for a plan. The user can then explore
alternate ways of stating quering to make best use of available indexes, or to create new
indexes.
6.1 Objectives
6.2 Locks
Page, table and tablespace level locking is provided. Index can be locked at page or
subpage levels. While creating tablespaces the level of locking can be specified.
Locksize of ANY will allow DB2 to determine lock size. For indexes also, the locksize
can be specified at creation time. However if tablespace lock is in effect, then the index
level locks will not be used.
DB2 uses share locks while responding to SLELCT statements. Exclusive locks are used
for INSERT, UPDATE and DELETE. When DB2 attempts to insert a row and finds the
corresponding page locked, it will put it on the next available unlocked page. This avoids
lock delays but contributes to unclustering. DB2 user X, S and U locks, and the
corresponding protocols. Exclusive lock bars any access to the locked resource. It is the
corresponding protocols. Exclusive lock bars any access to the locked resource. It is
necessary to read a row before it can be updated or deleted, and during this read, the
update lock allows other to read the page and acquire a share lock. An update lock must
wait for any share lock to be released so that an exclusive lock can be taken before the
actual update or delete. The update lock is queued with share locks to get an exclusive
lock.
Isolation level means the extent to which the transaction islolates the data is accessed.
* Consider a program that is scanning a file and preparing a list of parts available before
reserving those parts. It might assume that some part was available but this situation may
change (because of these update of other transaction) before the program finishes,
thereby causing errors in its output.
* Another possibility with cursor stability is that row may be processed twice or not at
all. This can happen when program B changes the value of a field in the range already
processed by program A into one that is yet to be processed by A. Or B may change a
value from a range yet to be processed into one already processed thus causing A to miss
the concerned record.
Repeatable read avoids these problems, but affects concurrency and runs the risk of lock
promotion to table or tablespace level. If a subfile needs to be processed then the locks
will be in place for a long time. Often cursor stability is used in conjunction with
scheduling constrints that minimise the problem of double or missed processing.
Every table is created with a timestamp field. Whenever a record is read, the timestamp
is read into the host variable and before actual updation of the record, the record is read
again and new timestamp value is compared with the old timestamp value. If they don’t
match (It is due to the updation of the field by other transaction.), the transaction will be
rolled back and started again. By this mechanism, lost update problem is avoided to a
greater percentage.
Because DB2 supports locking at multiple levels of granularity, it uses the concept of
intent locking at the tablespace level to reduce the amount of processing to manage locks.
Intent Share – The transaction intends to read but not update data pages and therefore
take S locks against them. It will tolerate concurrent transactions taking S, IS, SIX, IX or
U locks.
Intent Exclusive – The transaction intends to change data. It will tolerate other
transactions taking an IS lock on the tablespace, which allows them to read data by taking
S page locks at the page level.
Page locks are always taken when they are needed, and released when commit or rollback
takes place. At the tablspace level developers have some control (specified at bind time)
over when locks are acquired or released.
If ACQUIRE parameter is specified with USE then the tablespace lock is imposed at the
time the concerned SQL statement is executed. If the value is ALLOCATE then DB2
locks all the tablspaces when the plan is allocated.
ACQUIRE (ALLOCATE) reduces concurrency. Also locks not needed may be taken.
Program execution cannot begin till all tablespaces referenced by program are available.
Reduces deadlocks.
ACQUIRE (USE) is the default. Also used by DB2 for referential intergrity checks,
irrespective of user’s choice. DB2 always follows the user’s choice of RELEASE
parameter.
Generally a COMMIT should be done before requesting terminal input. If this is not
done then locks will be in force during operator delays. In some cases when the input
data will be used in update, the old value may be part of the screen, and therefore should
not be allowed to be changed. Therefore the locks should stay in place till the update is
done. Another way to handle this is to commit before terminal input, but reread the
row again after the input to test that no update has taken place. This reread can
sometimes be avoided, by specifying WHERE clauses in the UPDATE that specify all
the old values. If any change has taken place, the update will fail.
Generally COMMITS should be done after heavy update. Alternately, all updates
should be places just before commit points.
Whenever an object is created or dropped, catalog tables and the DBD (Database
Descriptor, which contains descriptive information about objects) are locked. This will
prevent other users from creating objects or binding plans. Thus applications which are
frequently executed should not generally create or drop objects dynamically. If this is
done, a COMMIT should be done after object creation so that the locks can be
released.
IF RELEASE (COMMIT) has been specified then after commit all locks will be
released. Cursors which were in effect should be reopened, if they are to be reused. If
the cursor has not fetched all its rows, then the last key value should be saved and used
to set the correct restart point.
LOCK TABLE statement within a program overrides all lock sizes and types that would
otherwise be in effect for the specified tables. This can be used for programs that do
heavy update activity. It is a good alternative to RR isolation level when a high
percentage of rows will be updated.
LOCK TABLE is not permitted against views. It will give runtime error.
Deadlocks are resolved by rolling back a transaction with fewest log records. Usually
this is the one for which the lock was most recently taken. Inserts usually cause
deadlocks because they involve locking of multiple indexes. More indexes imply more
deadlocks. By default DB2 checks for deadlocks every 15 seconds. When a deadlock
is encountered and resolved, SQL return code is sent -91 if ROLLBACK has been
done, or –913 if the program is requested to issue the rollback. IRLM (Intersystem
Resource Lock Manager) controls all locks. If a lock request cannot be serviced within
60 seconds a negative SQL code is returned.
7.1. Objectives
The DB2 optimizer is integral to the operation of SQL statements. The optimizer, as its
name implies, determines the optimal method of satisfying a SQL request. For
example, consider the following statement.
Based on this information, the optimizer analyzes the possible access paths and chooses
the best one for the given query. An access path is the navigation logic used by DB2 to
access the requisite data. A tablespace scan using sequential prefetch is an example of a
DB2 access path.
Based on models developed by IBM for estimating the cost of CPU and I/O time, the
impact of uniform and nonuniform data distribution, and the state of tablespace and
indexes, the optimizer usually arrives at a good estimate of the optimal access path.
Note : Many factors can cause the DB2 optimizer to choose the wrong access path,
such as incorrect or outdated statistics in the DB2 catalog, an improper physical or
logical database design, an improper use of SQL (for example, record-at-a-time
processing), or bugs in the logic of the optimizer (occurs infrequently). In addition, the
optimizer does not contain optimization logic for every combination and permutation of
SQL statements.
The EXPLAIN command in DB2 describes the access path selected by the DB2
optimizer for SQL query. The information provided by EXPLAIN is invaluable for
determining the following :
• The work DB2 does “behind the scenes” to satisfy a single SQL statement
• Whether DB2 is using available indexes, and, if indexes are used, how DB2 is
using them
• The order in which DB2 tables are accessed to satisfy join criteria
• Whether a sort is required for the SQL statement
ER/CORP/CRS/ DB01/002 Ver 1.2 68
• Tablespace locking requirements for a statement
A single SQL statement, or a series of SQL statements in a package or plan, can be the
subject of an EXPLAIN. When EXPLAIN is requested, the SQL statements are passed
through the DB2 optimizer, and the access paths that DB2 chooses are externalized, in
coded format, into a PLAN_TABLE.
The PLAN_TABLE is nothing more than a standard DB2 table that must be defined
with predetermined columns, data types, and lengths.
Refer to your DB2 manual for all the columns and their datatypes in the PLAN_TABLE.
You can create PLAN_TABLE as you create any other table in DB2. Note that the
PLAN_TABLE will be created in the default database (DSNDB04) and
STOGROUP(SYNDEFLT) in a DB2 generated tablespace, unless specified otherwise.
If a PLAN_TABLE already exists, the LIKE clause of CREATE TABLE can be used to
create PLAN_TABLEs for individual users based on a master PLAN_TABLE. It is a
good idea to have a PLAN_TABLE for every application programmer, for every
individual owner of every production DB2 plan and every DBA and system
programmer.
To EXPLAIN a single SQL statement, precede the SQL statement with the EXPLAIN
command as follows :
After issuing the EXPLAIN command on your statements, you can inspect the result in
PLAN_TABLE. You can use a simple SQL query to retrieve this information. For
example.
A common method of retrieving access path data from the PLAN_TABLE is to use QMF
to format the results of a simple SELECT statement.
8.1. Objectives
DB2 programs must be parsed and modified before normal compilation. This is
accomplished by the DB2 precompiler. The precompiler performs the following
functions :
• Places a timestamp token in the modified source and the DBRM to ensure that
these two items are inextricably tied
• Reports on the success or failure of the precompile process
There are two types of BINDs: BIND PLAN and BIND PACKAGE.
BIND PLAN accepts as input one or more DBRMs produced from previous DB2
program precompilations, one or more packages produced from previous BIND
PACKAGE commands, or a combination of DBRMs and package lists. The output of
ER/CORP/CRS/ DB01/002 Ver 1.2 72
the BIND PLAN command is an application plan containing executable logic
representing optimized access paths to the DB2 data. An application plan is executable
only with a corresponding load module. Before you can run a DB2 program, regardless
of environment, an application plan name must be specified.
The BIND PACKAGE command accepts as input a DBRM and produces a single
package containing optimized access path logic. There can be only one DBRM per
package. You can then bind packages into an application plan using the BIND PLAN
command. A package is not executable, and can not be specified when a DB2 program
is being run. You must bind a package into a plan before using it.
• Reads the SQL statements in the DBRM and checks the syntax of those
statements
• Checks that the DB2 tables and columns being accessed conform to the
corresponding DB2 catalog information
• Performs authorization validation
• Optimizes the SQL statements into efficient accesspaths
DBRM/PLAN/PACKAGE/COLLECTION/VERSIONS
Previously, the two principal activities performed by BIND (“package bind” and “plan
bind”) were collapsed into a single process, in which all of the DBRMs for a given
application were simultaneously compiled into optimized code and bound together into
the required application plan. This scheme, however, suffered from a number of
disadvantages.
The package concept was introduced to remedy such deficiencies. A package is the
compiled form of a DBRM, and a plan is essentially just a list of packages (for
compatibility DBRMs are also allowed as input for the PLAN BIND) therefore ;
It is possible to add a new package to an existing plan without having to do a new plan
bind, because of the concept of package collection. Each package belongs to exactly
one collection. When a plan is bound, the input to the bind operation can be specified as
any combination of packages and / or collections (and/or DBRMs). And specifying a
collection is equivalent to specifying all of the packages in that collection including
packages that may be added to the collection after the plan bind is done.
Before the availability of packages, when programmers wanted to use an old version of
a program, they were forced to rebind the program’s plan using the correct DBRM. If
the DBRM was unavailable, they had to repeat the entire program preparation process.
When using packages, you can keep multiple versions of a single package that refer to
different versions of the corresponding application program. This enables the
programmer to use a previous incarnation of a program without rebinding.
You can specify a version identifier as a parameter to the DB2 precompiler. Other than
this, versioning is automatic and requires no programmer or operator intervention.
- When a package is bound into a plan, all versions of that package are
bound into the plan
- When a program is executed specifying that plan, DB2 checks the
versions identifier of the link that is running and finds the appropriate
package version in the plan
- If that version does not exist in the plan, the program will not run
- To use a previous version of the program, simply restore and run the load
module.
The modified source data set produced by the DB2 precompiler must then be compiled.
DB2 does not need to be operational in order to compile the program.
The compiled source is then link-edited to an executable load module. The appropriate
DB2 host language interface module must also be included by the link edit step. This
interface module is based on the environment (TSO, CICS, or IMS/DC) in which the
program will execute.
The output of the link edit step is an executable load module, which can then be run with
a plan containing the program’s DBRM or package. The link edit procedure does not
require the services of DB2. Therefore, the DB2 subsystem can be inactive when your
program is being link edited.
After a program has been prepared, two separate physical components are produced a
DB2 plan and a link edited load module. Neither is executable without the other. The
plan contains the access path specifications for the SQL statements in the program. The
ER/CORP/CRS/ DB01/002 Ver 1.2 75
load module contains the executable machine instructions for the host language statement
sin the program.
When you run an application program containing SQL statements, you must specify the
name of the plan that will be used. The plan name must include the DBRM that was
produced by the precompile process that created the load module being run. It must be
understood that a load module is forever tied to a specific DBRM. This is enforced by a
timestamp token placed into both the DBRM and the modified source by the DB2
precompiler.
At execution time, DB2 checks that the tokens indicate the compatibility of the plan and
the load module. If they do not match, DB2 does not allow the SQL statements in the
program to be run. A-818 SQL code is returned for each SQL call attempted by the
program.
If a load module is run outside the control of DB2, the program abends at the first SQL
statement.
- Automatic
- Forced
Rebinding of plans and packages will be needed if DB2 has marked them as “invalid” or
the user decides the BIND his package again.
If an object is dropped, DB2 examines the catalog to see which packages (if any) are
dependent on that object. Finding such packages it marks them as “invalid”. When the
Runtime Supervisor retrieves such as package for execution, it sees the “invalid” marker,
and therefore invokes BIND to reproduce a new package-I.e., to choose some different
access strategy and to recompile the original SQL statements in accordance with that new
strategy. Assuming the recompilation is successful, the new package effectively replaces
the old one, and Runtime Supervisor continues with that new package.
For example, if an index has been dropped then the package using this index will be
marked “invalid” and DB2 will perform BIND again on this package at runtime. This
will be transparent to the user. If a table has been dropped then (re) BIND on the affected
package will be successful only if another table with the same name and functionality has
been recreated.
An user may opt for BINDing a package again. This can happen, for example, if a new
index has been created and the user wants the optimizer to consider this index also while
deciding about the access path. Creation of new index does not lead to automatic
reBIND.
1. The view mechanism, which can be used to hide sensitive data from unauthorised
users.
(a) When GRANT or REVOKE statement is executed, it stores the privilege type, object,
grantor and grantee in the catalog.
(b) Whenever user does operation for which security is executed, it stores the privilege
type, object, grantor and grantee in the catalog.
1. Each individual user is assigned an authorisation ID to log in to the system and that is
the primary ID for the user in question. All objects created by a particular user will
belong to that user.
In order to be able to perform any operation on any object, the user must hold
appropriate privilege for the operation and the object in question. Otherwise, the
operation will be rejected with an appropriate error message.
DB2 recognises a wide of privileges. Every privilege falls into one of the
following classes:
• Use privileges: Privileges for doing certain system resources, namely storage
groups, tablespaces, and buffer pools, etc.,
• System privileges: Privileges for doing certain system wide operations such as the
creation of a new database
There are certain bundled privileges, which serve as shorthand for collections of other
privileges. For example, the system administration privilege (SYSSADM) is shorthand
for the collection of all other privileges in the system.
When DB2 is first installed, part of the installation process involves the
designation of a user as the system administrator for DB2 system. So initially only one
user exists who can do all jobs; and later on, he can grant privileges to other users.
Next, a user who creates an object is automatically given full privileges on that
object.
9.3 GRANT
Table privileges:
Database privileges:
Use privileges:
System privileges:
9.3.2 REVOKE
If user U1 grants some privilege to some other user U2, user U1 can subsequently revoke
the privilege from U2. This is done by REVOKE statement. The general format of
REVOKE statement is:
Revoking a given privilege form a given user causes all packages dependent on that
privilege to be marked invalid and causes automatic rebind on the next invocation of each
such package. This is similar to what happens when an object such as an index is
dropped.
If user U1 has the authority to grant a privilege P to another user U2, then user U1 also
has the authority to grant the privilege P to the user U2 “with the GRANT option”. This
means user U2 in turn has the authority to grant the privilege P to another user. For
example:
User U1:
USER U2:
Then the revocation will cascade (that is, U2’s GRANT to U3, etc., will also be revoked
automatically).
• SYSDM
SYSADM authority allows the holder to execute any operation that the system
supports.
• SYSCTRL
SYSCTRL (system control) authority allows the holder to execute any operation
that the system supports, except for operations that access database contents (e.g.,
operations such as “create storage group” is allowed, but SQL data manipulations
are not).
• DBADM
• DBMAINT
• SYSOPR
SYSOPR (system operator) authority allows the holder to carry out console
operator functions on the system (such as starting and stopping system trace
activities).
-CHECK
-COPY
-DIAGNOSE
-LOAD
-MERGECOPY
-MODIFY
-QUIESCE
-RECOVER
-REORG
-REPAIR
-REPORT
-RUNSTATS
-STOSPACE
CHECK The CHECK INDEX utility tests whether indexes are consistent with the
data they index, and issues warning messages when an inconsistency is
found.
COPY Creates upto four image copies of a tablespace or a data set within a
table space. There are two types of image copies.
a full image copy is a copy of all pages in a table space or data set.
LOAD The LOAD utility loads data into one or more tables in a table sapce,
replaces the contents of a single partition, or replaces the contents of an
entire tablespace. The LOAD DATA statement describes the data to
be loaded and provides information needed forallocating resources.
The loaded data isprocessed by any edit or validation routine associated
with the table, and any field procedure associated with any column of
the table.
MERGECOPY Merges image copies produced by the COPY utility. The utility can
merge several incremental copies of a table space to make one
incremental copy, or it can merge incremental copies with a full image
copy to make a new full image copy.
RECOVER Recovers data to the current state. You can also RECOVER to a prior
copy or a specified log RBA. The largest unit of data recovery is the
table space ; the smallest is the page. You can recover one table space,
a list of table spaces, a data set, pages within an error range, ora single
page. Data is recovered from image copies of a t able space and databae
log change records. If the most recent full image copy data set
isunusable, and there are previous image copy data set existing in the
system, RECOVER uses the previous image copy data sets.
If the RECOVER utility cannot use the latest primary copied data set
as a starting point for recovery, it attempts to use the backup copied
data set, if one is available. If neither image copy is usable, it attemps
to fall back to a previous recoverable point.
REPAIR Repairs data. The data can be your own data, or data you should not
normally access, such as space map pages and index entries.
STOSPACE Updates DB2 catalog columns that indicate how much space is
allocated for storage groups and related table spaces and indexes.
11.1. Objectives
Objectives of this chapter is to briefly introduce you to the facilities of DB2 like
• The user constructs the query (SQL) in a QMF work area called QUERY
• The user issues RUN QUERY to execute the query stored in QUERY. The
result is stored in another work area called DATA.
• QMF creates a default from for the QUERY which is kept in the work area
called FORM
• The user views the report with DISPLAY REPORT
• The user may issue DISPLAY FORM to edit the form of the report in FORM
• The user then issues DISPLAY REPORT to prouce a revised report corresponding
to the revised form.
• The Query need not be run again. The result has been kept in DATA and
DISPLAY REPORT uses the current FORM to format and display the current
DATA.
• The user can issue PRINT REPORT to obtain a hard copy of the report.
• The user can also issue DISPLAY CHART to display a chart or graph using the
results of the query.
• The current query and associated FORM, DATA can be saved using SAVE
QUERY command.
the procedure can be saved for later use using the SAVE PROC command and
executed later using the RUN PROC command
• a product used to extract data from existing system files and convert it in DB2
compatible data.
• based on the information provided through a set of SQL like statements. DXT
extracts and converts the original data formats into standard relations formats.
• the DXT scenario involves
• a convenient way of testing SQL statements before embedding them into the
application program.
• is used mostly by application developers and database or system administrators
• the user can create a text file containing via SPUFI is
MENU
11.5.1. DCLGEN
11.5.2. Defaults
Under defaults the user may choose things like language, lines per page of listing,
message level, string delimiter, type of decimal point to be displayed and JCL card
for the JCL generated by DB21.
This entire chapter is taken from the book ‘DB2 for Application Programmers’ by
Pacifico Amarga Lim from page 60 to 132. Please read this chapter keeping in mind
that no changes have been made to the original text.
10
The Cobol programs are written in the usual way, except that access to DB2 resoruces
are done via SQL statements, not READ file-name, WRITE record-name, and so on -
batch Cobol) or READ DATASET, WRITE DATASET, and so on (Cobol running
under CICS/VS). The programmer therefore uses the same SELECT, INSERT,
UPDATE, and DELETE statements we have previously discussed. In addition, the
FETCH, OPEN, and CLOSE statements are also used.
One minor difference between SQL statements in Cobol and those used in SPUFI is
that the former are delimited by the “EXEC SQL” and “END-EXEC” statements.
The semicolon (;) delimiter is not used. Thus:
E-EC SQL
SELECT ENPDEPT, SU-CEMPS4LARY
END-EXEC
Instead of
SELECT EMPDEPT, SUMCEMPS4LARY................’
There are three fields that are very important. They are :
3. SQLWARNO. If equal to “W”, then at least one of the warning flag fields
(SQL WARN1 to SQLWARNA) is set to a value. This field may contain a “W”
even if SQLCODE is zeroes. See section 2.1.3.3.
There are two ways to do this. The easiest way is to allow the precompiler to generate
this area with the following statement in the WORKING-STORAGE section.
EXEC SQL
INCLUDE SQLCA
END-EXEC.
Optionally, the user may use the Cobol COPY statement to copy the area from a source
statement library.
01. SQLCA
05 SQLCAID PIC X (8)
05 SQLCABC PIC S9 (9) COMP.
05 SQLCODE PIC S9 (9) COMP.
05 SQLERRM.
49 SQLERRML PIC S9 (4) COMP.
49 SQLERRMC PIC X (70).
05 SQLERRP PIC X (8)
05 SQLERRD OCCURS 6 TIMES
PIC S9 (9) COMP.
05 SQLWARN.
10 SQLWARN0 PIC X (1)
10 SQLWARN1 PIC X (1)
10 SQLWARN2 PIC X (1)
10 SQLWARN3 PIC X (1)
10 SQLWARN4 PIC X (1)
10 SQLWARN5 PIC X (1)
10 SQLWARN6 PIC X (1)
10 SQLWARN7 PIC X (1)
10 SQLWARN8 PIC X (1)
10 SQLWARN9 PIC X (1)
10 SQLWARNA PIC X (1)
After the execution of each SQL statement, the programmer may investigate any field in
the SQLCA. The most important fields are discussed in the following sections.
There are two common uses of the SQLCODE field. First, it is used to determine if
any error occured on the execution of an SQL statement ; checking is therefore
usually done right after the execution of the SQL statement. For instance ;
EXEC. SQL
SELECT
END-EXEC
IF SQLCODE EQUAL TO ZEROES
OK, Ccontinue
esle execute error routine
A second use is when processing the output table row by row via a cursor (FETCH
statement) ; see the next chapter). A value of 100 signifies the “no record found”
condition, which for the FETCH statement, means “end of rows”.
The method of using SQL CODE as previously explained is the only way to process
exceptional conditions if we prefer to treat each condition differently from the others.
For most programs, this is the safest and best method, not subject to errors when a
program is modified. In addition, the programmer may take any action (say, doing
a CALL, which is not allowed in the following alternate method).
However, if we prefer to treat each condition the same way anywhere in the program,
the programmer may actually just use the SQLCODE indirectly by simply specifying
the WHENEVER exceptional condition, which may becoded anywhere in the
Procedure Division but must execute ahead of the SQL statement we want to control.
The format is :
EXEC SQL
WHENEVER (NOT FOUND / SQLWARNING / SQLERROR
(GO TO label / CONTINUE)
END-EXEC
An example is :
EXEC SQL
WHENEVER NOT FQUN
GO TO Error-routine
END-EXEC
. . . .
. . . .
EXEC SQL
SELECT . . . .
END-EXEC
If the “NOT FOUND” condition is true for the SELECT statement (SQL-CODE =
100), the program then automatically executes “Error-routine”.
9. SQLWARN1 : Has the value of ‘W’ if at least one column’s value was
truncated in the host variable. This always happens when truncating character
data items but may or may not happen for numeric items.
10. SQLWARN 2 : Has the value of ‘W’ if null values were ignored in the
computation of a built-in function (AVG, SUM, and so on. This value is set
only during preprocessing, never at run time.
11. SQLWARN 3 : Has the value of ‘W’ if the number of items in the
SELECT list is not equal to the number of target variables in the INTO clause.
13. SQLWARN 5 : Has the value of ‘W’ if a WHERE clause associated with
a SELECT statement has exceeded a DB2 internal limitation.
14. SQLWARN 6 : Has the value of ‘W’ if the last SQL statement executed
caused DB2 to terminate a logical unit of work. This is set to ‘S’ when DB2
issues an SQLCODE that is severe (-805, - 86, and so on).
17. SQLWARN 9 : Has the value of ‘W’ if blocking was cancelled for a cursor
because of insufficient storage in the user partition.
18. SQLWARNA : Has the value of ‘W’ if blocking was cancelled for a cursor
because a blocking factor of atleast two rows could not be maintained.
Although optional, the programmer should define the table(s) or views to be used. It
both serves as a documentation, as well as provides an extra measure of control since
during the precompile step (see section 4,) DB2 will verify it against the names used in
SQL statements.
The DCLGEN function is option 2 of the DB2 interactive (DB21) Primary Option
Menu (see Fig 4.2). It may also be invoked directly in TSO via the TSO command
“DSN” with the subcommand “DCLGEN”. Lastly, it may be run in batch.
The two advantages of using DCLGEN over the DECLARE TABLE statement (see
section 2.2.2) is that it uses the table definition in the DB2 catalog and there are
therefore no possible coding errors. In addition, the corresponding Cobol record
description (see host variable, section 2.3), is also generated.
1. The SOURCE TABLE NAME entry is the table or view from which we generate
the DECLARE statement and Cobol data-names.
2. DATA SET NAME contains the output of DCLGEN. The library name is used
in the Precompile panel (Fig. 1.1.6) and Compile / Link / Run panel (Fig.11.8)
of Chapter 11. The member name is the one specified in the EXEC SQL
INCLUDE statement section 2.2.2) that brings the declaration and Cobol data-
names into the Working-storage section.
3. The DATA SET PASSWORD entry is used if the output DCLGEN is password
protected.
4. ACTION is ignored for sequential data sets. For partitioned data sets,
REPLACE will replace an old version or create a new one ; ADD creates a new
version.
ER/CORP/CRS/ DB01/002 Ver 1.2 99
=====>
Enter table name for which declarations are required :
1. SOURCE TABLE NAME ------ ‘XLIM.EMPTABLE’
5. COLUMN LABEL NO
(enter YES for column label)
Figure 10.2
The DCLGEN panel
5. COLUMN LABEL is normally NO.
7. FIELD NAME PREFIX (up to 28 characters) specifies the prefix for the fields
in the generated output (which correspond to table or view columns). The fields
will then be generated as prefix 001, prefix 002, and so on. The prefix is
usually not specified so the field names will be instead identical to the column
names in the table or view.
To bring the DECLARE TABLE output into the appliction program, the programmer
codes in the working-storage section :
EXEC SQL
INCLUDE EMPTABDL
END-EXEC
* ACTION (REPLACE)
* APOST
As we have seen, the DECLARE statement is one of the outputs of the DCLGEN
procedure (the other is the Cobol record description). If DCLGEN is not used, the
DECLARE statement may be coded by the programmer and the format is similar to one
for creating the tables or views. The format is :
Host variables are those that are usedin the application program. Naturally, they
are defined according to the rules of the programming language (Cobol, for instance).
Those for the tables or views are either automatically generated in DCLGEN or
specifically defined by the programmer.
When DCLGEN is notused, the programmer must code the host varibles for the tables
and views, a processthat is error prone. Using DCLGEN is thus better since the DB2
catalog is used.
When used in SQL statements, Cobol data-names must be prefixed with a colon (:). It
goes without saying that they do not have the colon prefix when used in regular Cobol
statements (meaning non-SQL statements.
************************************************************************
***
COBOL DECLARATION FOR TABLE XLIM EMPTABLE
************************************************************************
***
01 DCLEMPTABLE
10 EMP NO
PIC X (5)
10 EMPNAME
PIC X (30)
10 EMPDEPT
PIC XXX 10 EMPSALARY
Note that in the three previous examples, the ones with the colon prefix are the Cobol
data-names generated by DCLGEN and those without prefixes are the original table
column names.
An indicator variable is defined in working storage for a column that can have a NULL
value. On a SELECT or FETCH statement, DB2 will place a negative value in the
variable if the column has a NULL value. The corresponding Cobol data-name is not
changed and therefore retains whatever value it received from a previous SELECT or
FETCH statement. On an UPDATE or INSERT statement, the programmer places a
negative value in the variable to indicate to DB2 that a NULL value is to be used for
the column. In this case, the column cannot be defined in the table as NOT NULL.
EXEC SQL
SELECT EMPNAME, EMPSALARY
INTO : EMPNAME, : EMPSALARY:EMPSALARY-IND
FROM XLIM.EMPTABLE
2. Other fields may or may not also have inicator variables. An example of using
an array indicator variable is :
EXEC SQL
SEELECT EMP NO, EMPNAME, EMPDEPT, EMPSALARY
INTO : DCLEMPTABLE : EMPTABLE-IND
FROM XLIM.EMPTABLE
WHERE EMPNO = :SEARCH-DEPT
END - EXEC
Note that a negative value in EMPTABLE-IN(1) means a NULL value in the first
data-name under DCLEMPTABLE ; a negative value in EMPTABLE-IND(2) means a
NULL value in the second data-name under DCLEMPTABLE, and so on.
The same SELECT, UPDATE, INSERT and DELETE statements we have seen before
are coded where needed right in the procedure division, and interspersed with regular
Cobol statements. In addition, we will learn the use of the FETCH statement when
processing rows in an application program.
A unit of recovery is that portion of processing where the program tells DB2 that all
updates (successful INSERT, UPDATE and DELETE statements) in that unit should
be either committed (to be written to the physical device) or rolled back
(disregarded). Because DB2 takes log records for a unit of recovery, a user’s decision
to commit or roll back will be done, even if the action is not completed because of
abnormal termination of processing (say, the DB2 subsystem crashes or your program
abends). In this case, it is eventually done either by DB2 (if only the program bombs
or during emergency restart of DB2 or the system.
A unit of recovery has both a start and an end. At end, DB2 will do a physical write of
updated rows if the end is triggered with the SQL COMMIT statement or normal end
of job (for a batch program or CICS SYNCPOINT command or normal task
termination (for a CICS appliction program).
In some cases, choosing the unit of recovery is a user judgement call. For instance,
one may choose to wait for every 1 rows updated before they are committed as final if
the user judges it to offer the best tradeoff between efficiency and allowing greater
concurrency. More commits incur a greater overhead processing, but allow more users
to share the data.
The update of these 3 tables must be synchronized as one unit of recovery since if one
is not completed (say, due to a program bomb or power failure), we want all inserts
and updated to be rolled back (not committed.
By definition, an incomplete unit of recovery (that is, with no end) is not really a unit
of recovery. Thus, if the program bombs, all uncommitted updates are lost
(automatically rolled back).
We have learned that under SPUR, the SPUR main panel will allow the user to select
an automatic commit or roll back or efer that decision to a later time (at which point he
or she may commit or roll back the changes).
For application programs, if the program doesnot so specify, DB2 will not commit any
update, unless the batch application program normally ends or the CICS task normally
terminates.
EXEC SQL
COMMIT
END-EXEC
Efficiency, the reduction of deadlocks, and data integrity are three reasons for the
timing of the commit process.
Since DB2 implicitly secures a lock on uncommitted updates (this preventing other
programs from accessing data in those pages), prolonging the commit process results
in other programs having to wait longer to access DB2 data. For a heavily-used table,
this promotes lower concurrency (lower degree of sharing among many users), hence
less overall efficiency.
It is therefore important that the programmer does the commit or roll back as soon as
feasible, especially for heavily-used tables, to allow a larger level of concurrency.
DB2’s data “blocks” are called pages and when updating single tables (especially if
very large), we may issue the commit for each row if we are processing randomly; we
may wait for several rows if we are processing in sequence. The physical rewrite of
pages (which results from the commit) incurs some overhead and doing a single
rewrite for multiple rows that are upated gains some efficiency.
If we are updating more than one table, and they must be synchronized, we may do the
commit when we have reached a consistent unit of recovery. For instnce, in an Order
Entry application, once we have updated both the Order table and ordered-item table
(to enter the order) and the Inventory table (to reduce inventory by the items being
ordered), we may issue the SQL COMMIT statement.
The problem of deadlocks is discussed in more detail on page 106. For now, let it
suffice to say that the more pages users hold on to, the greater the chance that two or
more users cannot continue processing because they need data on pages held by
somebody else. The timely commit of updates therefore reduces this problem.
If the system goes down or the program bombs, any uncommitted update is lost. Doing
a commit therefore makes sure that updated rows are made final on physical device.
Any user request for commit only requests DB2 to commit all changes within that unit of
recovery. DB2 writes log records to guarantee that even if the system crashes or the
program bombs before any physical write is done, the updates are eventually written out
to the physical device.
DB2 does not immediately do a physical write since pages of updated data in the buffers
are written out only at checkpoint intervals, which are specified at installation time.
An exception is if the buffer pool is full and a user needs additional data to be brought to
the buffer, DB2 will use the least frequently used page, writing it out first if it contains
uncommitted updates. This actually allows more pages to be already in the buffer when
users request data.
The SQL ROLLBACK statement rolls back all changes to rows, instead of committing
them. In the same manner as the SQL COMMIT statement, it tells DB2 that the
program is finished with the uncommitted rows and that changes in the current unit of
recovery should be ignored. As far as improving concurrency, it has the same effect
as the COMMIT statement.
EXEC SQL
ROLLBACK
END-EXEC
Actual program examples are shown in Chapters 12, 13 and 14 for the moment, we
will just show how they will look like in Figures 10.5 and 10.6.
WORKING-STORAGE SECTION
......
EXEC SQL
INCLUDE member-name (output of DCLGEN)
END-EXEC
**** Code indicate variables (if any)
EXEC SQL
INCLUDE SQLCA
END-EXEC.
PROCEDURE DIVISION
EXEC SQL
SELECT EMPNAME, EMPSALARY
I NTO : EMPNAME : EMP SALARY
FROM XLIM. EMPTABLE
WHERE EMP NO = EMP NO
END-EXEC.
IF SQLCODE EQUAL TO ZEROS
MOVE EMPNAME TO .......
ELSE error routine.
5. The SELECT statement to select a specific row and bring it to the Cobol
datanames EMPNAME and EMPSALARY.
Figure 10.6 is an example of a coded program (with the CLGEN output printed out and
with certainCobol program headers omitted). Here we display the employee number
and name of employees in the Employee table based on employee numbers keyed in
an “in-line” card file (//CARDIN D* JCL entry).
........
SELECT EMPLOYEE-CARDIN ASSIGN TO CARDIN
WORKING-STORAGESECTION
********************************************************************
* DCLGEN TABLE (XLIN,EMPTABLE)
* LIBRARY (XLIN.DB2.COBOL(EMPTABDL)
* ACTION (REPLACE)
* APOST
*
* IS THE DCLGEN CONMAND THAT MADE THE FOLLOWING STATEMENTS
******************************************************************************
EXEC SQL DECLARE XLIM.EMPTABLE TABLE
(EMP NO CHAR (5) NOT NULL
EMPNAME CHAR (30) NOT NULL WITH DEFAULT
EMPDEPT CHAR (3) NUT NULL WITH DEFAULT
EMP SALARY DECIMAL 7,0) NULL
) END-EXEC.
********************************************************************************
* COBOL DECLARATION FOR TABLE XLIM.EMPTABLE
********************************************************************************
01. DCLEMPTABLE
10 EMPNO PIC X (5)
10 EMPNAME PIC X (30)
10 EMPDEPT PIC XXX
*********************************************************************************
* THE NUMBER OF COLUMNS DESCRIBEDBY THJS DECLARATIONIS 4
*********************************************************************************
01 W005 - EMPLOYEE - NUMBER PIC X (5)
01 W005 - END -OF -FILE-SE PIC X.
88 W005 - CARDIAN-HAS -ENDED VALUE ‘Y’
EXEC SQL
INCLUDE SQLCA
END -EXEC.
PROCEDURE DIVISION
ER/CORP/CRS/ DB01/002 Ver 1.2 110
OPEN INPUT EMPLOYEE -CARDIN
MOVE ‘N’ TO W005 - END - OF - FILE - SW.
PERFORM C060 - READ-EMPLOYEE-CARDIN.
PERFORMN C040-PROCESS-ONE -EMPLOYEE
UNTL W005-CARDIN - HAS-ENDED.
CLOSE EMPLOYEEE- CARDIN.
GOBACK.
C040-PROCESS-ONE-EMPLOYEE.
EXEC SQL
SELECT EMPNAME
INTO :EMPNAME
FROM XLIMEMPTABLE
WHERE EMPO = :W005- EMPLOYEE-NUMBER
END-EXEC.
IF SQLCODE EQUAL TO ZEROES
DISPLAY W005 -EMPLOYEE -NUMBER ‘EMPNAME’
ELSE DISPLAY W005-EMPLOYEE -NUMBER ‘ MAJOR ERROR’
PERFORMC060 -READ-EMPLOYEE - CARDIAN.
1. The CICS tanslaton step is the only optional step. It is only done for command-
level CICS application programs and it generates two outputs.
2. The PRECOMPILE stepchecks that the SQL statements are free of syntax errors.
in addition, if there is a DECLARE TABLE statement (automatically generated
by DCLGEN), the table nzmes and column names in the statement are verified.
PRECOMPILE generates three outputs.
b. The database request moule (DBRM), which contains a parse tree version
fthe SQL atements in a program. this will be the input tothe BIND
process
Step 3.
c. The modified source program in userid.temp.cobol, but with each SQL statement
replaced mostly by a series of Call Statements.
Useri.temp.cobol is the input to the compile in Step 4.
a. It catches the SQL statements for valid table, view, and column names 78.
c. It determined via the Optimizer module how the data will be accessed, including
whether top use any existing index or not.
d. It converts the DBRMs into one application plan. These are control structures
used by DB2 during program execution. The application plan is stored in the
DB2 catalog. In DB2, it is the plan, not the corresponding program(s) that a user
is authorized to execute.
4. The compile process, which generates the usual output, including the listing in
userid.temp.list.
The BIND process is done before the execution of the corresponding application. Since
data access os resolved during BIND, not at program execution, this results in greater
efficiency. Note that in SPUFI, data access is resolved during the execution of SQL
statements, thus making it inherently less efficient than the corresponding application
program.
The user may do the rebind of any previous plan, incluing an invalidated plan. If not,
DB2 will attempt an automatic rebnd of aninvaidated plan without any user intervention,
at the time of the plan is next run. however, if the attempt fails (for ni stance, a program
accesses a column that since the last bind has been deleted fromthe table), DB2, will
inform the user and change the plan statusfrom invalidated to deactivated. The plan
cannot then be executed until the user makes the corrections to programs, tables, and so
on.
Once the programmer has coded the program (using TSO/ISPF), he or she may then
execute the steps in Figure, 11.1. There are two ways to do this:
Note that the interactive panels (for PRECOMPILE, BIND, RUN an others) we will learn
to use not implement Figure 11.1 nteractively. They merely generate control information
that implements Figure 11.1 when later run in TSO background or foreground.
An even better option is to copy userid.temp.cntl into a separate data set, since the former
is lost at TSO logoff. This is shown in Section 8 later in this chapter. This saves time
and effort since there is now no need to use the DB21 program preparation steps. The
programmer simply recalls the saved JCL, generally changes a few JCL statements
(such as program name), then resubmits it to run in TSO batch.
Note however that each combination of functions (precompile only, bind only,
precompile-bind-run, etc.) generates a different procedure. Each one has to be saved
separately.
Once in TSO, the programmer selects DB21, possibly via the ISPF Primary Option
Menu.
The programmer selects option 3, which will then generate the program preparation
panel in Figure 11.5.
==>
Select one of the following and press ENTER
5 BIND/REBIND (BIND/REBIND/FREE
application plans)
===>
Enter the following :
1 INPUT DATA SET NAME … ===>
userid.DB2. COBOL (COBOL)
2 DATA SET NAME QUALIFIER ===> TEMP (For building data
set names)
3 PREPARATION ENVIRONMENT ===> EDITJCL (FOREGROUND,
BACKGROUND, EDITJCL)
4 RUN TIME ENVIRONMENT ….. ===> TSO (TSO, CICS, IMS)
5 STOP IF RETURN CODE >= ===> 8
(Lowest terminating return code)
6 OTHER OPTIONS ………… ===>
2. The DATA SET NAME QUALIFIER is TEMP. This is used in the BIND
process.
4. The RUN TIME ENVIRONMENT is TSO, unless we access the DB2 resources
via CICS or IMS.
6. The OTHER OPTIONS entry is a list of parameters you want included in this
program preparation process ; for instance, options to the CICS/VS command
language translator.
ER/CORP/CRS/ DB01/002 Ver 1.2 118
7. The CHANGE DEFAULT entry is usually Y the very first time so the
programmer can see what the defaults are. In addition, the programmer usually
codes the JCL Job statement that will be used instead of the default when the job
is later submitted.
12. In like manner, the COMPILE OR ASSEMBLE options are both Y. Note that
COMPILE, LINK (item 13), and RUN (Item 14) use the same panel.
13. The LINK option has N for display since we will enter the necessary information
along with the previous COMPILE OR ASSEMBLE step.
14. The RUN option has N for display since we will enter the necessary information
along with the previous COMPILE OR ASSEMBLE step.
1. This panel appears if we choose “Y” for the Display panel column of the
CHANGE DEFAULTS.
3. Entry 9 is the Job statement coded by the programmer and will be used in place
of the defaults. This will appear in the generated JCL that is submitted to run
(Fig. 1.10).
DB2I DEFAULTS
===>
Change defaults as desired :
1 DB2 NAME ……………. ===> DSN (Subsystem identifier)
2 DB2 CONNECTION RETRIES ===> 0 (How many retries for
DB2 connection)
3 APPLICATION LANGUAGE ===> COBOL (COBOL, COB2, ASM, FORT,
PLI)
ER/CORP/CRS/ DB01/002 Ver 1.2 119
4 LINES/PAGE OF LISTING ===> 60 (A number from 5 to 999)
5 MESSAGE LEVEL ……. ===> I (Information, Warning, Error,
Severe)
6 COBOL STRING DELIMITER ===> (DEFAULT, ‘OR”)
7 SQL STRING DELIMITER ===> (DEFAULT, ‘OR”)
8 DECIMAL POINT …… ===> (. OR ,)
9 DB2I JOB STATEMENT : Optional if site has a SUBMIT exit)
PRECOMPILE
===>
Enter precompiler data sets :
1. This panel appears if we choose “Y” for the Display panel column of the
PRECOMPILE entry of Figure 11.5.
2. If this panel is accessed via the Progra-n Preparation panel (Fig. 11.5), the
INPUT DATA SET NAME contains the value specified in that panel.
4. If this panel is accessed via the Program Preparation panel (Fig. 11.5), the
DSNAME QUALIFIER entry contains the value specified in that panel.
5. The DBRM DATA SET entry is the DBRM library for the precompiler output
(which becomes input to BIND). If this panel is accessed via the Program
preparation panel (Fig. 11.5) it is initially blanks. When you press ENTER, the
6. If this panel is accessed via the Program Preparation panel, the WHERE TO
COMPILE entry is the same as the PREPARATION ENVIRONMENT of that
panel.
7. The OTHER OPTIONS entry are precompiler options that will override the
installation standards. Many of these are identical to the options for compile.
Examples are APOST to specify the single quotes as the literal delimiter, FLAG (x,y)
to specify the level of diagnostic messages, and so on.
BIND
===>
Enter DBRM data set name(s) :
1. This panel appears if we choose “Y” for the Display panel column of the BIND
entry of Figure 11.5.
2. If this panel is accessed via the program preparation steps, the LIBRARY entry
contains the value specified in the DBRM DATA SET entry of the
Precompile step.
3. The MEMBER entry is the DBRM itself. For a partitioned data set, its default
value is the member name of the INPUT DATA SET NAME entry of the
program preparation panel. For a sequential data set, it is the second qualifier of
the data set.
5. The MORE DBRMS entry allows the programmer to enter more DBRMs via
another panel.
6. The PLAN NAME entry is the name of the application plan created during
BIND. The default value for a partitioned data set is the member name of the
INPUT DATA SET NAME of the program preparation panel. For a sequential
file, it is the second qualifier.
10. The PLAN VALIDATION TIME specifies when full validity checking is to be
done. BIND means do it during the BIND process, which is the efficient way.
RUN means do it during program execution, which has to be used if
authorization is not granted by the time BIND is done.
11. The RESOURCE ACQUISITION TIME entry determines when you want the
system to acquire resources for your program. USE means acquire it when first
used in the program ; LLOCATE means acquire it when first used in the plan is
allocated (the program starts). Specifying USE promotes greater concurrency.
12. The RESOURCE RELEASE TIME entry determines when you want the system
to release resources taken by your program. COMMIT means release them
when committed (SQL COMMIT or SQL ROLL BACK statements).
13. The EXPLAIN PATH SELECTION entry allows the user to query DB2 about
how it navigates through the table to access the data.
===>
9 PARAMETERS …… ===>
10 SYSIN DATA SET ===> TERM
11 SYSPRINT DS….. ===> TERM
1. This panel appears if we choose “Y” for the Display panel column of the
COMPILE OR ASSEMBLE entry of Figure 11.5.
2. The programmer may include upto two libraries for the compile phase.
3. The OPTIONS entry are compiler options that will override the installation
standards, for instance, ADV.
6. The PARAMETERS entry is a list of parameters you want passed to the runtime
process or the program.
7. By default, the SYSIN DATA SET and SYSPRINT DS entries are TERM.
1. DB2 saves the JCL statements in userid.temp.cntl. This data set will be
retained until TSO logoff. As suggested in Section 8 later in this chapter, this
is best copied into a programmer-owned data set.
2. The programmer adds JCL statements for the batch files. The programmer may
now submit the job with the SUB command.
The DB2-generated JCL statements (in userid.temp.cntl) are lost at TSO logoff.
Therefore, it is generally best for the programmer to copy it into his or her own data set.
As mentioned before, note that each combination of functions selected (precompile
only, bind only, precompile-bind-run, etc.) generates a different procedure.
Each must be saved separately. The programmer may conveniently just resubmit one
of the saved versions of the JCL, after making minor changes.
One change is the JCL statements for batch files. Others are the “INPUT” entry for the
program data set name (line 00030 of Fig. 11.10) and the “PLAN” entry for the plan
name (line 000036).
The programmer may select one row from a source table(s) or view and bring it
immediately into the application program. This option is used only if there is at most
only one row selected because the column(s) used in the selection criteria (WHERE
clause) only contains unique values (the column was defined with UNIQUE INDEX).
An example is a selection based on employee number (which is unique).
If this processing style is used where the selection criteria uses a column that may
contain non unique values, an error will result if DB2 finds more than one row.
For SELECT operations, there are only two values of SQLCODE that are of interest to
the user: a value of 0 (no error) or a value of 100 (“no record found”) on either the
SELECT statement itself or the FETCH statement (if processing multiple rows). On a
negative value, the row is not read into the program.
The use of SQLCODE is shown in the discussion of program logic and the program
examples.
Figure 12.1 is the DCLGEN output for the XLIM.EMPTABLE Employee table. We will
use it in all our program examples. Note that we have both the DECLARE TABLE
statement and the table row description.
***************************************************************************
* DCLGEN
* TABLE (XLIM.EMPTABLE)
* ACTION (REPLACE)
* APOST
In this chapter, we will use Figure 12.2 as the input to our program. It contains the
current data on the XLIM.EMPTABLE Employee table.
If the selection criteria (WHERE clause) specifies a column (s) defined with a unique
index, then at most only one row can be selected. In our example, we assume this case for
the employee number column. The general program logic is shown in Figure 12.3.
WORKING-STORAGE SECTION
.....
EXEC SQL
INCLUDE member-name (from DLGEN output)
END-EXEC.
EXEC SQL
INCLUDE SQLCA
END EXEC.
PROCEDURE DIVISION.
......
*** set EMPNO to the correct value ***
EXEC SQL
SELECT EMPNAME,
EMPSALARY
1. At the beginning, we have to set the Cobol data-name EMPNO to the correct
value. It will be used as the search criteria.
3. The INTO clause brings the data for the selected columns into the Cobol data-
names specified (note the colon prefix). Thus,:EMPNAME
and:EMPSALARY are the Cobol data-names generated by DCLGEN (see Fig.
12.1).
4. We check the SQLCODE field and if zero, we know the select was successful and
we may continue or else we did not get any row.
We will now print selected rows (one row per selection) from XLIM.EMPTABLE (Fig.
12.2), Selection is based on employee numbers coded in an in-line “card file”, unless the
salary value of the employee is nulls, where we bypass the row. Figure 12.4 is the
program listing.
1. Lines 001400 to 002600 are the in-line card file that contains the employee
numbers, and print file.
2. Lines 002800 to 006800 are the various data-names such as counters and the print
lines.
003500 01 W005-DETAIL-LINE
3. Lines 006900 to 007100 generate the communication area data block shown in
Figure 10.1
4. Lines 007200 to 007400 include the DCLGEN output shown in Figure 12.1
5. Lines 007600 to 008200 are the house-keeping routines and the main-loop
control.
6. Lines 008500 to 009500 control the processing of rows selected from the
employee number entered in the in-line card file. Since the employee number is
a unique index, we actually select at most only one row.
b. Lines 008700 to 008900 perform the laying out of the columns if there was a row
selected; or else we only lay out the employee number from the original card file
(so we can later print an error message).
c. Lines 009000 to 009200 lay out the SQULCODE, plus the literal *** if it is not
zero. Note that an SQLCODE value of zeros will print as blanks because of line
004800.
d. Lines 009600 to 010200 lay out the detail line, then blank it out for the next row.
7. Lines 009600 to 010200 lay out the row columns (from lines 008700 to 008800)
only if a row was selected.
a. Lines 009700 to 009900 simply lay out the columns that will never contain
nulls (see Fig. 12.1).
8. Lines 010300 to 011600 are the routines to print the detail and header lines.
9. Lines 011700 to 012900 is the statement to select one row. Note that we use the
INTO clause, which brings that single row selected row selected into the data-
names specified in the clause.
b. Lines 012300 to 012600 specify the corresponding Cobol data-names that will
get the value from the row. Note that each is prefixed with a colon.
c. Line 012600 shows the use of the indicator variable for a column that may
contain nulls: if not specified, there is an SQLCODE error if the column does
contain nulls.
d. Line 012800 is the selection criteria. We know that there will be at most only
one row selected since EMPNO is defined with a unique index.
10. Lines 013000 to 013200 read the in-line card file to get the employee numbers
used in the selection process.
1.6 Additional JCL Statements and In-line Card File
Assuming that we use “EDITJCL” in entry 3 of Figure 11.5 in Chapter 11, DB2 will
generate most of the JCL statements for us. However, we still have to include those for
the batch files.
For our program example, these are for the display output, the in-line “card file,” and the
print file. Thus:
/ / SYSOUT DD SYSOUT=*
/ / LSTOUT DD SYSOUT=*
/ / CARD IN DD *
0015
00010
00600
00008.
/*
Note that from the previous additional JCL statements, the employee numbers are not in
sequence. The program will just do a random read of the input table as each input card is
read. From the current data in XLIM.EMPTABLE (Fig. 12.2), we can see that we
process in sequence, employee numbers ‘00015’, ‘0010’, and ‘0008’. Employee number
00600 does not exist in the table.
1. Employee number ‘00015’ is printed out. SQLCODE is zero, hence the “RETURN
CODE” column in the detail line shows spaces.
2. Employee number ‘00010’ is printed out. Since the salary value is nulls, we print our
‘NULLS***’ in the salary column.
3. Employee number ‘00600’ is not in the table. The SQLCODE is 100, which we print
out as +100.
In many cases, there are multiple rows that satisfy a particular selection criteria (that is,
the column used in the WHERE clause is nonunique). Since Cobol does not allow the
programmer to bring all such rows”en masse” to program, the only way to process this
condition is by using a cursor fetch the data, one row at a time. The style shown in
Section I will not work.
The cursor name, which is not defined as a Cobol data-name, is defined in a DECLARE
statement that has the SELECT statement subordinated to it. The DECLARE statement
is nonexecutable code, and is coded either in the PRCEDURE DIVISION (preferably,
for better documentation) or in the WORKING –STORAGE section. The subordinate
SELECT statement (which is coded just like any other SELECT statement) identifies the
subset of the input table(s) that will serve as the “temporary cursor table” (see Section
2.1.1) from which the program fetches data, one row at a time. Processing is then similar
to that of a sequential file.
The format of the DECLARE statement is:
EXEC SQL
DECLARE cursor-name CURSOR FOR
SELECT EMPNAME, EMPSALARY
FROM XLIM.EMPTABLE
WHERE EXMPDEPT=:SEARCH-DEPT
END-EXEC
2. The SELECT operand specifies the rows in the “temporary cursor table”.
3. The WHERE operand specifies the rows in the “temporary cursor table”. In our
example, they are all rows where the value of the EMPDEPT column is equal to that
of the Cobol SEARCH-DEPT data-name. If this operand is missing, all rows are
used.
The SELECT Operand of the DECLARE cursor-name statement defines the group that
serves as the “temporary cursor table” from which individual rows are later fetched. For
instance, if we use Figure 12.2 as the original table and code the following:
EXEC SQL
DECLARE EMPCSR CURSOR FOR
SELECT EMPNO, EMPNAME, EMPSALARY
FROM XLIM.EMPTABLE
WHERE EMPDEPT = ‘005’
END-EXEC.
Before cursor processing starts, the program must execute the SQL statement OPEN
cursor-name. This also brings the cursor to the first row the “temporary cursor table”. In
figure 12.6,this is the row belonging to employee number ‘00008’; in Figure 12.7, this is
the row belonging to employee number ‘00150’.
EXEC SQL
OPEN Cursor-name
END-EXEC
2.3 FETCH Statement to Read One Row
For an open cursor, the FETCH statement gets one row at a time to the program. The
format is:
EXEC.SQL
FETCH cursor-name
INTO:data-name,:data-name2.
END-EXEC.
Note that SQLCODE is equal to 100 if there are not more rows (“no record found”
condition).
Once the program is finished with processing the “temporary cursor table” (or at any
time), the CLOSE cursor-name statement is executed. The format is:
EXEC.SQL
CLOSE cursor-name
END-EXEC.
1. The DECLARE cursor-name statement identifies the cursor, the columns selected,
and the search criteria.
a. The column-names in the SELECT clause (EMPNAME, EMPSALARY) are
those of the table.
b. Note that if the WHERE clause is missing (as we will show in the program
example in Fig. 12.9), we are reading the whole table.
2. We set the Cobol data-name SEARCH-DEPT to the correct value since it is used as
the search criteria.
WORKING-STORAGE SECTION
…..
EXECSQUL
INCLUDE member-name (from DCLGEN output)
END EXEC.
…..
END SQL
INCLUDE SQLCA
PROCEDURE DIVISION.
…..
EXEC.SQL
DECLARE cursor-name CURSOR FOR
SELECT EMPNAME.EMPSALARY
FROM XLIM.EMPTABLE
WHERE EMPDEPT =:SEARCH-DEPT
END-EXEC.
*** set SEARCH-DEPT to the correct value ***
EXECSQL
OPEN cu-sor-name
END.EXEC.
PERFORM C200-PROCESS-EMPLOYEE-ROW UNTIL SQLCLDE = 100
EXECSQL
CLOSE cursor-name
END-EXEC.
C200-PROCESS-EMPLOYEE-ROW
FETCH cursor-name
INTO:EMPNAME
:EMPSALARY
END.EXEC.
IF SQLCODE TO EQUAL TO ZEROS
OK continue.
Employee
Number NAME Salary
(EMP NO) (EMP NAME) (EMPSALARY)
If the program can use the original table (for instance, it does not care about the
sequence of the rows being fetched), then this “temporary cursor table” is just a
concept. DB2 will simply use the original table and point the cursor to the current row
being processed.
This is in fact the case in Figure 12.6 As we said, only three rows can be fetched from
the table.
If the program requires rows fetched to be in a specific sequence, the ORDER BY clause
is specified. If DB2 decides that using an existing index is more efficient than doing a
sort, then DB2 will still use the original table as the “temporary cursor table”,
otherwise, a sort is done. In the latter, DB2 first selects the needed rows, then sorts
them as the “temporary cursor table” in a temporary file. In short, it exists as a
physical entity, independent of the original table. For instance, if we use Figure 12.2 as
the input the code the following (we assume there is no index by EMPNAME).
EXEC SQL
DECLARE EMPCSR CURSOR FOR
SELECT EMPNQ, EMPNAME, EMPSALARY
FROM XLIM.EMPTABLE
WHERE EMPDEPT = ‘005’
ORDER BY EMPNAME
END-EXEC.
Note that Figure 12.7 shows a physical entity, implemented by DB2 in a temporary
file.
Before cursor processing starts, the program must execute the SQL statement OPEN
cursor-name. This also brings the cursor to the first row of the “temporary cursor
table”. In figure 12.6, this is the row belonging to employee number ‘00008’, in
Figure 12.7, this is the row belonging to employee number ‘00150’.
The format is :
EXEC SQL
Open cursor-name
END-EXEC.
For an open cursor, the FETCH statement gets one row at a time to the program. The
format is :
EXEC SQL
FETCH cursor-name
INTO:data-name1:data-name2
END-EXEC
Note that SQL CODE is equal to 100 if there are no more rows (“no record found”
condition).
Once the program is finished with processing the “temporary cursor table” (or at any
time), the CLOSE cursor-name statement is executed. The format is :
EXEC SQL
CLOSE Cursor-name
END-EXEC
b) Note that if the WHERE clause is missing (as we will show in the
program example in Fig. 12.9), we are reading the whole table.
END-EXEC
*** Set SEARCH-DEPT to the correct value ***
EXEC SQL
OPEN cursor-name
END-EXEC.
PERFORM C200-PROCESS-EMPLOYEE-ROW UNTIL SQLCODE=100
EXEC SQL
CLOSE cursor-name
END-EXEC.
C200-PROCESS-EMPLOYEE-ROW
EXEC SQL
FETCH cursor-name
INTO:EMPNAME
END-EXEC.
IF SQLCODE TO EQUAL TO ZEROS
OK Contine
Figure 12.8 Program logic : multiple-row selection
ER/CORP/CRS/ DB01/002 Ver 1.2 140
3. As part of the Main-loop routine, we open the cursor, perform the processing of
all rows, then close the cursor.
4. The FETCH statement has the INTO clause, which brings the data for the
selected columns into the Cobol data-names specified. Thus, :EMPNAME and
EMPSALARY are the Cobol data-names generated by DCLGEN
5. We check the SQLCODE field and if zero, we know the FETCH was successful
and we may continue, if the value is 100, then this is the “end of file” condition.
We will now print all rows in the XLIM.EMPTABLE Employee table. Figure 12.9 is
the program listing. The following apply :
2. Lines 002000 to 005100 are the various data-names such as counters and the
print lines.
3. Lines 005200 to 005400 generate the communication area data block shown in
Figure 10.1 1 on page 62.
4. Lines 005-00 to 005700 include the DCLGEN output shown in Figure 12.1.
Clause as the row selection criteria, however there is no WHERE clause and we are in
fact selecting all rows.
10. Lines 008600 to 009200 lay out the row columns (from line 008200, only if a
row was selected.
a. Lines 008700 to 008900 simple layout the columns that will never contain
nulls (seefig.12.1).
b. Lines 009000 to 009200 check the w005-SALARY –INDV indicator
variable to see if DB2 detected nulls (a negative value for W005-
SALARY-INDV) for the EMPSALARY column (see line 011300). If so,
we display the ‘NULLS’ literal instead of the actual salary value.
11. Lines 009300 to 010600 are the routines to print the details and header lines.
12. Lines 0101800 to 011400 implement the statement to fetch one row. Note that we
use the INTO clause, which brings the row selected into the date names specified
in the SELECT clause of theDECLARE cursor-name statement (lines 005900 to
006600).
a. lines 011000 to 011300 specify the Cobol date-names that will get the
value from the row. Note that each is prefixed with a colon.
b. Line 011300 shows the use of the indicator variable for a column that may
contain nulls; if not specified, there is an SQULCODE error if the column
does contain nulls.
13. Lines 011500 to 011600 set the “end of row” switch once SQLCODE becomes
100.
Assuming that we use “EDITJCL” in entry 3 of Figure 11.5 in Chapter 11,DB2 will
generate most of the JCL statement for us. However, we still have to include those for the
batch files.
For our program example, these are for the display output and print file. Thus:
//SYSOUT DD SYSQUT=*
//LSTOUT DD SYSOUT=*
Employee DEPT
Number NAME NUMBER Salary
In most types of update, the programmer first selects a row before it is updated. This is
because the row is printed out, verified, and so on before the update is made. This type
of processing uses many of the same cursor processing techniques shown in the previous
chapter.
Since we are processing using a cursor, we must also code the DECLARE statement in
the same manner as in Chapter 12. The format is:
EXEC SQL
DECLARE CURSOR-NAME CURSOR FOR
SELECT EMPNAME, EMPSALARY
FROM XLIM, EMPTABLE
WHERE EMPDEPT=: SEARCH-DEPT
FOR UPDATE OF COLUMN-NAMEL,
COLUMN-NAME2,
END-EXEC.
The “FOR UPDATE OF …” clause is an additional clause that specifies the column(s)to
be updated. Note also that this statement merely defines the criteria for update; the actual
update is done only with the UPDATE statement.
the UPDATE or DELETE statement, as with any other update or delete statement, may
update or delete multiple rows if we use the “WHERE column-name=date-name” clause
and there are multiple rows with the value name of data-name. We have seen this using
SPUFI and we explain its use in programs in Chapter 14.
In this chapter, we deal with the common situation where we update / delete the same
row we have just fetched, without updating/deleting any other row. This is done by
coding the ‘WHERE CURRENT OF cursor-name” clause instead of the “WHERE
column-name=; date-name’ clause in the UPDATED/DELETE statement that updates or
deletes the row brought into the program by the last FETCH statement.
EXEC SQL
UPDATE XLIM. EMPTABLE
SET column 1= . . . . .
Column2= ……….
WHERE CURRENT OF CURSOR-names
END-EXEC.
The “WHERE CURRENT OF cursor-name” clause cause the update of the very same
row brought into the program by the last FETCH statement.
If DB2 creates a physical temporary cursor table then the “WHERE CURRENT OF
cursor-name “ clause cannot be used, since the cursor would then be pointing to the
former and not the original table. In this case, to update/delete rows in the original table,
we have to use instead the ‘WHERE column-name =; data-name” clause. However, we
cannot then guarantee that we are updating /deleting only one row(as we could if we
Update/delete using the current cursor), unless the value of column-name is unique.
In an update/ delete not using the WHERE CURRENT OF CLUASE, this mean there
was now row updated or deleted, In an update using the WHERE CURRENT OF clause,
this means that the corresponding FETCH statement resulted in the “end of rows”
condition.
Many installations limit the number of pages that a given user can own (lock) at any
given time. This is the NUMLKTS parameter specified when DB2 is installed.
If the user has chosen LOCK-SIZE PAGE and DB2 has determined that a user already
owns lock on the maximum number of pages, it will not execute any further statement
that will cause another page lock and instead generates an SQLCODE value of –904 .
The user should then either issue a COMMIT statements (SYNCPOINT command in
CICS/VS) or ROLLBACK statement (SYNCPOINT ROLLBACK command in
CICS/VS) before continuing.
In most cases, the programmer should just commit, then continue, using the current input
that caused the SQLCODE value of –904.
Note that this problem occurs only for page locking, if we choose LOCKSIZE PAGE not
LOCKSIZE ANY, in most situations, LOCKSIZE ANY is actually preferred since we
then allow DB2 to choose the lock size, usually starting with page lock, but with the
possibility it to table space lock.
On the other hand, if the user has chosen LOCKSIZE ANY and DB2 has determined that
a user already owned lock on the maximum number of pages, on the next statement that
would otherwise cause another a the page lock , it will simply promote the page lock to
table space lock, with the user not even aware of it. Processing continues as usual.
The dead lock conditions is very well known, even in nondatabase applications. In DB2
it can occur even more frequently, because there are so many users, each one having
locks on pages scattered all over the table space and needing other pages that other
users may have locks on.
ER/CORP/CRS/ DB01/002 Ver 1.2 147
Figure13.1 shows the deadlock condition
Depending on certain conditions, DB2 will choose which user will be sacrificed, and
which one allowed to continue. For the program to be sacrificed, it will either
automatically have its pages rolled back, with an SQLCODE of –911, or have an
SQLCODE of –913, with the program itself doing the roll back.
1. The DECLARE cursor-name statement identifies the cursor, the columns read
into the program, the search criteria, and the FOR UPDATE OF clause that
specifies the column(s) that are updated.
END-EXEC.
*** set SEARCH-DEPT to the CORRECT VALUE***
EXEC SQL
OPEN CURSOR-NAME
END-EXEC.
PERFORM C200-PROCESS-EMPLOYEE-ROW UNTIL SQLCODE=100.
EXCE SQL
CLOSE Acursor-name
END-EXEC,.
2. We set the Cobol data –name SEARCH –DEPT to the correct value. It will be
used as the search criteria.
3. As part of the Main- loop routine , we open the cursor, process all rows, then
close the cursor.
4. The FETCH statement has the INTO clause, which brings the data for the
selected columns into the Cobol date-names specified. Thus, ;EMPNAME and
;EMPASALARY are the coblol data-names generated by DCLGEN ( see fig.
12.1)
We not run a program that reads “card images” from an in-line card files, which contain
department numbers and salary updating information. For each department number read,
we process corresponding departments in the XLIM,EMPTABLE Employee table, For
each row belonging to a department, we increase the salary.
Employees Department
Number Name Number Salary
(EMPNO) (EMPNAME) (EMPDEPT) (EMPSALARY)
column by the salary undating information in the “card”. Except when the original salary
value is NULLS, where no update is done.
The program shown in figure 13.4 shows that for the SQLCODE, we only check for the
“end of table” (SQLCODE 100) and deadlock conditions (sqlcode-911 or-913). We are
not concerned with the condition of number of pages going beyond the maximum
allowed (SQLCODE-904) since we assume LOCKSIZE ANY.
ER/CORP/CRS/ DB01/002 Ver 1.2 151
The following apply:
1. Lines 001200 to 001800 pertain to the input file containing the department
number and salary updating information.
b. Lines OOZOOO to 002600 are the various data-names s-ch as counters and
switches.
3. Lines 002700 to 002900 generate the communication area data block shown in
Figure 10.1.
4. Lines 003000 to 003200 include the DCLGEN out put shown in Figure12.1.
5. Lines 003400 to 004000 implement the DECLARE statement that specifies the
cursor name (EMPCSR), the columns selected, the row selection criteria, and the
clause’FOR UPDATE OF “column-name”.
a. Line 003600 specifies the column we want read into the program, Note that in
general, this column(s) is naturally the one(s) we want to process(say to print)
in the program. It does not have to be the same columns (s) that is updated
(FOR UPDATE OF clause), although in our example it just happens to be the
same.
b. Line 003900 specifies the column to be updated.
6. Lines 004100 to 004700 are the housekeeping routines and the Main –loop
control.
7. Lines 004800 to 007100 process each department read in the in-line card file.
8. lines 007200 to 007500 process departments with at least one row until there are
no more rows or DB2 determine a deadlock.
004800 020-PROCESS-EACH-DEPT
004900 EXE SQL
005000 OPEN EMMPCSR
005100 END-EXEC
005200 PERFORM C-100 FETCH-ONE-ROW
005300 IF SQLCODE = 100
005400 DISPLAY ‘PROG1304 -- DEPT ‘W005-EMPDEPT
005500 ‘HAS NO TABLE DATE’ UPON SYSOUT
005600 ELSE PERFORM C040-PROCESS-GOOD-DEPT.
005700 IF SQLCODE = (-911 OR -913)
005800 DISPLAY ‘PROG1304 - DE (T ‘W005-DMPDEPT
005900 ‘BYPASSED DUE TO DEADLOCK’ UPON SYSOUT
006000 IF SQLCODE = -913
006100 EXEC SQL
006200 ROLLBACK
006300 END-EXEC
006400 ELSE NEXT SENTENCE
006500 ELSE EXEC SQL
006600 CLOSE EMPCSR
006700 END-EXEC
006800 EXEC SQL
006900 COMMIT
007000 END-EXEC.
007100 PERFORM C-120-READ-UPDATE-INPUT
007200 C040-PROCESS-GOOD-DEPT.
007300 PERFORM C060-PROCESS-EACH-DEPT-ROW UNTIL SQLCODE = 100
007400 OR SQLCODE = -911
007500 OR SQLCODE = -913
007600 C060-PROCESS-EACH-DEPT-ROW
007700 IF W005-SALARY-INDV LESS THAN ZERO
007800 NEXT SENTENCE
007900 ELSE PERFORM C080-UPDATE-THIS-ROW
008000 PERFORM C100-FETCH-ONE-ROW
008100 C080-UPDATE-THIS-ROW
008200 ADD W005-SALARY-INCREASE TO EMPSALARY.
008300 EXEC SQL
008400 UPDATE XLIM.EMPTABLE
008500 SET EMPSALARY = :EMPSALARY
008600 WHERE CURRENT OF EMPCSR
008700 END-EXEC.
008800 C100-FETCH-ONE-ROW
008900 EXEC SQL
009000 FETCH EMPCSR
009100 INTO :EMPSALARY:W005-SALARY-INDV
009200 END-EXEC
009300 C120-READ-UPDATE-INPUT
009400 READ UPDATE-INPUT-INTO W005-UPDATE-RECORD
009500 AT END, MOVE ‘Y’ TO W005-END-OF-UPDATE-RECORDS
a. Lines 008200 adds the salary updating data from the in-line card file to the
original salary data from the row( from line 009100).
b. Lines 008300 to 008700 update the current row (from line 008600), the
columns updated is EMPSALARY, which picks up the data in the data-
name EMPSALARY (now containing the correct value.)
11. Lines 008800 to 009200 fetch on row from the table. The EMPSALARY data
from the row (from line 003600) are brought to the data-name EMPSALARY.
12. LINES 009300 TO 009500 read the in-line card file for the department number
and the corresponding salary updating information.
/ / SYSOUT DD SYSOUT = *
/ / CARD I N DD
0 0 5 00500
0 0 3 00 700
Note that for department numbers ‘005’ and ‘003’. We update all rows, except those with
salary value of NULLS, all rows for department number ‘005’ and ‘003’ had their salary
value updated by $ 500 and $700 respectively.
Lines 006800 to 007000 in Figure 13.4 committed update changes, in our example, we
did this for all rows belonging to a department. The programmer should issue the
COMMIT statement when feasible to optimize concurrency. However, when processing
using cursors, any commit or rollback automatically closes all open cursors.
If there are too many updates between the OPEN/CLOSE of single cursor, the program
may be holding on to too many pages, with the ensuring problems of lower concurrence
and deadlock potential. To avoid this problem, the programmer may be forced to commit
changes even before he or she is finished with the temporary cursor table. This of course
automatically closes the cursor.
WORKING-STORAGE SECTION
…….
EXEC SQL
INCLUDE SQLCA
END-EXEC.
EXEC SQL
INCLUDE EMPTABDL
END-EXEC.
EXEC SQL
INCLUDE EMPTABDL
END-EXEC.
PROCEDURE DIVISION
…….
EXEC SQL
DECLARE cursor-name CURSOR FOR
SELECT EMPNO, EMPSALARY
FROM XLIM.EMPTABLE
WHERE EMPNO > :W005-EMPNO-UPDATED
FOR UPDATE OF EMPSALARY
END-EXEC.
MOVE ‘00000’ TO W005-EMPNO-UPDATED
PERFORM C020-PROCESS-ALL-ROWS UNTIL W005-NO-NORE-ROWS.
GOBACK.
C020-PROCESS-ALL-ROWS
MOVE ZEROS TO W005-NUMBER-ROWS-UPDATED
EXEC SQL
OPEN cursor-name
END-EXEC.
PERFORM C080-FETCH-ONE-ROW
PERFORM C040-PROCESS-GROUP-OF-ROWS UNTIL W005-NO-NORE-ROWS
OR W005-NUMBER-ROWS-UPDATED = 3.
EXEC SQL
COMMIT
END-EXEC
END-EXEC
ADD 1 TO W005-NUMBER-ROWS-UPDATED
C080-FETCH-ONE-ROW
EXEC SQL
FETCH cursor-name
INTO :W005-EMPNO-UPDATED
:EMPSALARY:005-SALARY-INDV
END-EXEC.
IF SQLCODE = 100
MOVE ‘Y’ TO W005-END-OF-ROWS.
1. The DECLARE cursor-name statement identifies the cursor, the columns(s) read
into the program, the search criteria, and the FOR UP DATE OF clause that
specifies the columns(s) that are updated.
c. The WHERE clause makes sure that any OPEN cursor-name statement
gets the row where the value of EMPNO is greater than the value of the
data-name W005-EMPNO-UPDATED (originally set to ‘00000’ ) by
putting the value of the last row fetches into WOOS-EMPNO-UPDATED,
we can process the whole table correctly even with repeated open and
close of the cursor.
3. The FETCH statement has the INTO clause, which brings the data for the selected
columns into the Cobol data-names specified. The use of w005-EMPNO-
We will run a program that adds $ 500 to all salary columns, except when the original
value is NULLS. We use figure 13.5 as the input. The program listing in figure 13.7.
1. Lines 001600 to 002200 are the various data-names such as counters and switches.
a. Line 002000 shows the value of +500 which we will add to the salary column of all
rows, except those with NULLS for values.
2. Lines 002300 to 002500 generate the communication area data block show in
Figure10.1
4. Lines 003000 to 003600 implement the DECLARE statement that specifies the cursor
name (EMPSCR), the columns selected, the row selection criteria, and the
clause”FOR UPDATE OF “ column-name”.
ER/CORP/CRS/ DB01/002 Ver 1.2 160
a. Line 003200 specirfies the columns (s) we want read into the program. They do
not have to be same columns that are updated 9FOR UPDATE OF clause).
5. Line 003700 sets the proper value to W005-EMPNO-UPDATED. This makes sure
that we initially fetch the first row in the table (from line 003400)
6. Line 004300 zeros out the update counter. We do a commit after updating three
rows.
7. Lines 004700 to 005000 process each groups for the three possible conditions.
8. Lines 005100 to 005900 display the range of bypassed rows if DB2 detected a
deadlock.
9. Lines 006000 to 006500 do the close and commit if we have reached the end of rows
or have updated three rows already.
10. Lines 006700 to 007000 show that we update only those rows where salary is not
NULLS.
a. line 007300 saves the first employee number in the group. It is used to display
the range of by passed rows if DB2 detects a deadlock from lines 005100 to
005900).
a. line 008400 is important since it places the employee number of the current row
into W005-EMPNO-UPDATED. When we reopen the cursor the next times to
process the next group because of line 003400, we start at the first employee
number after the last one fetches.
Figure 13.8 is the group process on the first of the cursor. We process up to the fourth
row(employee number 00015) since we do not include the row with NULLS value for
salary.
ER/CORP/CRS/ DB01/002 Ver 1.2 161
Employee Department
Number Name Number Salary
(EMPNO) (EMPNAME) (EMPDEPT) (EMPSALARYY
Employee
Number Salary
(EMPNO) (EMPSALARY)
1. 00005 0030700
2. 00008 0029500
3. 00010 Nulls Temporary cursor
Table
4. 00015 0030000
5. 00150 0031500
6. 00170 Nulls
7. 00190 0030500
Figure 13.10 is the group processed on the second open of the cursor.
We process until the end of the table.
Employee
Number Salary
(EMPNO) (EMPSALARY)
1. 00005 0030700
2. 00008 0029500
3. 00010 Nulls
4. 00015 0030000
5. 00150 0031500
6. 00170 Nulls Temporary cursor
table
7. 00190 0030500
ER/CORP/CRS/ DB01/002 Ver 1.2 162
Figure 13.10 Temporary cursor table. Second open.
Just like that of update, in most types of delete, the programmer first selects the row
before it is deleted. This is because the row is printed out, verified, and so on before
the delete is made. This type of processing uses the same cursor processing technique
we saw in Section 1 of this chapter. The procedure is :
1. Code the usual DECLARE cursor statement in either the Procedure Division
(preferred for better documentation), or working-storage section. Thus :
EXEC SQL
DECLARE cursor-name CURSOR FOR
SELECT EMPNAME, EMPSALARY
FROM XLIM.EMPTABLE
WHERE EMPDEPT = :SEARCH-DEPT
END-EXEC.
2. In the procedure Division, code the DELETE statement after the corresponding
FETCH statement. The format of the DELETE statement is :
EXEC SQL
DELETE FROM table-name
WHERE CURRENT QF cursor-name
END-EXEC.
3. As before, also code the OPEN, FETCH, and CLOSE cursor-name statements.
We explained earlier in this chapter (Section 1.3.2) that when using the “WHERE
CURRENT OF current-name” clause, only the conceptual temporary cursor table may
be used. This means that the program must use the original table. If DB2 creates a
physical temporary cursor table, then the “WHERE CURRENT OF cursor-name”
clause cannot be used, since the cursor would then be pointing to the former and not the
original table. In this case, to delete rows in the original table, we have to use instead
the “WHERE column-name = :data-name” clause. However, we cannot then guarantee
that we are deleting only one row (as we could if we delete using the current cursor),
unless the value of column-name is unique.
1. The DECLARE cursor-name statement identifies the cursor, the columns read
into the program, and the search criteria.
b) The WHERE clause makes sure that any OPEN cursor-name statement
gets the row where the value of EMPNO is greater than the value of the
data name W005-EMPNO-DELETED (originally set to ‘00000’). By
putting the value of the last row fetched into W00S-EMPNO-DELETED,
we can process the whole table correctly even with reputed open and close
of the cursor.
WORKING-STORAGE SECTION
……
EXEC SQL
INCLUDE SQLCA
END-EXEC
EXEC SQL
INCLUDE EMPTABDL
END-EXEC
PROCEDURE DIVISION
…….
EXEC SQL
DECLARE cursor-name CURSOR FOR
SELECT EMPNO, EMPSALARY
FROM XLIM.EMPTABLE
WHERE EMPNO > :W005-EMPNO-DELETED
END-EXEC.
MOVE ‘00000’ TO W005-EMPNO-DELETED
PERFORM C020-PROCESS-ALL-ROWS UNTIL W005-NO-MORE-ROWS
GOBACK
C020-PROCESS-ALL-ROWS
MOVE ZEROS TO W005-NUMBER-ROWS-DELETED
EXEC SQL
OPEN cursor-name
END-EXEC.
PERFORM C080-FETCH-ONE-ROW
PERFORM C040-PROCESS-GROUP-OF-ROWS UNTIL W005-NO-MORE-ROWS
OR W005-NUMBER-ROWS-DELETED = 10
EXEC SQL
COMMIT
END-EXEC
EXEC SQL
CLOSE cursor-name
END EXEC
ER/CORP/CRS/ DB01/002 Ver 1.2 164
C040-PROCESS-GROUP-OF-ROWS
EXEC SQL
DELETE XLIM – EMPTABLE
WHERE CURRENT OF cursor-name
END-EXEC.
ADD 1 TO W005-NUMBER-ROWS-DELETED
C080-FETCH-ONE-ROW
EXEC SQL
FETCH cursor-name
INTO : W005-EMPNO-DELETED
:EMPSALARY:005-SALARY-INDV
END EXEC.
IF SQLCODE = 100
MOVE ‘Y’ TO W005-END-OF-ROWS.
3. The FETCH statement has the INTO clause, which brings the data for the
selected columns into the Cobol data-names specified. The use of W005-
EMPNO-DELETED brings the employee number of the latest row fetched into
this dataname.
We use the same data in Figure 13.8 as the input data for the delete. 2.3.1. Program
listing : Delete the Current Row. We now delete all rows where the salary value is
NULLs. Figure 13.12 is the program listing.
We now delete all rows where the salary value is. NULLS. Figure 13.12 is the
program listing.
1. Lines 001600 t0 002100 are the various data-names such as counters and
switches.
2. Lines 002200 to 002400 generate the communication area data block shown in
Figure 10.1
3. Lines 002500 to 002700 include the DCLGEN output shown in Figure 12.1.
4. Lines 002900 to 003400 implement the DECLARE statement that specifies the
cursor name (EMPCSR), the columns selected, and the row selection criteria.
a) Line 003100 specifies the column(s) we want read into the program.
6. Line 004100 zeros out the delete counter. We do a commit after deleting ten
rows.
7. Lines 004500 to 004800 process each group for the three possible conditions.
8. Lines 004900 to 005700 display the range of bypassed rows if DB2 detected a
deadlock.
9. Lines 005800 to 006300 do the close and commit if we have reached the end of
rows or have deleted ten rows already.
10. Lines 006600 to 007600 show that we delete only those rows where salary is
NULLs.
a) Line 007100 saves the first employee number in the group. It is used to
display the range of bypassed rows if DB2 detects a deadlock (from
lines 004900 to 005700).
“EDITJCL” in entry 3 of Figure 11.5 in Chapter 11, DB2 will generate most of the
JCL Statements for us. However, we still have to include additional JCL statements.
In this example, this is the display output. Thus :
/ / SYSOUT DD SYSOUT =
Figure 13.13. is the updated table from the program in Figure 13.6.
Employee Department
Number Name Number Salary
(EMPNO) (EMPNAME) (EMPDEPT) (EMPSALARY)
Note that we have deleted the two rows in Figure 13.8, where the salary is NULLs.
We mentioned in the previous that most update and delete operations use a cursor.
However, a program may still do a noncursor update or delete in the same manner we
did it in SPUFI in Chapter 9. We remember that in this case, all rows that meet the
criteria (based on the WHERE clause) are updated. This is different from an update
using the current cursor, where only the row we are currently processing is updated.
The noncursor update using SPUFI and Cobol program are basically identical. The
statement is issued at the point in the program we want the update done. The format is :
EXEC SQL
UPDATE table-name
SET column -name 1 = expression1,
Column -name2 = expression 2 ……….)
END-EXEC
The SET operand specifies the column(s) and the corresponding value(s) for the
update ; the WHERE clause specifies the criteria for selecting the rows to be updated
and is very important because all rows will be updated if is missing.
Employee Department
Number Name Number Salary
(EMPNO) (EMPNAME) (EMPDEPT) (EMPSALARY)
For our program example, we read update cards containing both old and new
department numbers. Rows which match the old department number are updated with
the new department numbers. The program listing is Figure 14.2
1. Lines 0011000 to 001800 describe the input file containing the old and new
department numbers.
2. Lines 002000 to 002600 are the various data-names such as counters and
switches.
3. Lines 002700 to 002900 generate the communication area data block shown in
Figure 0.1.
4. Lines 003000 to 003200 include the DCLGEN output shown in Figure 12.1.
5. Lines 003400 to 004000 are the housekeeping routines, including the Mainloop
routine.
6. Lines 004100 to 006000 process each department read from the in-line card
file.
a) Lines 004200 to 004600 update all rows with the same department
number as that read from the card.
7. Lines 006200 to 006400 read the in-line card file for the department number of
departments to be deleted.
Assuming that we use “EDITJCL” in entry 3 of Figure 11.5 in Chapter 11, DB2 will
generate most of the JCL statements for us. However, we still have to include those for
batch files. In this example, these are for the display output and the card file. Thus :
// SYSOUT DD SYSQUT = *
// CARDIN DD *
003 045
005 046
/*
2.4. Output Table : Noncursor Update
Using Figure 14.1 as input, Figure 14.3 is the output of the program. Note that the
original department numbers ‘003’ and ‘005’ have been changed to ‘045’ and ‘046’
respectively.
Employee Department
Number Name Number Salary
(EMPNO) (EMPNAME) (EMPDEPT) (EMPSALARY)
3. NONCURSOR DELETE
EXEC SQL
DELETE FROM table-name
(WHERE clause)
END-EXEC
The WHERE clause specifies the criteria for selecting the row(s) to be deleted. Just
like that of UPDATE, this clause is very important because all rows will be deleted if it
is missing.
For our program example, we read delete cards containing department numbers. Rows
which match the department number are deleted. The input is Figure 14.3. The
program listing is Figure 14.4.
1. Lines 001100 to 001800 describe the input file containing the department
number of departments to be deleted.
2. Lines 002000 to 002400 are the various data-names such as counters and
switches.
3. Lines 002500 to 002700 generate the communication area data block shown in
Figure 10.1
4. Lines 002800 to 003000 include the DCLGEN output shown in Figure 12.1.
5. Lines 003200 to 003800 are the housekeeping routines, including the Mainloop
routine.
6. Lines 003900 to 005800 process each department read in the in-line card file.
a) Lines 004000 to 004300 delete all rows with the same department
number as that read from the card.
b) Lines 004400 to 004700 commit the deletes.
c) Lines 004800 to 005700 display an error message if the department
processing is interrupted by DB2 due to deadlock condition. If
SQLCODE is 913, we do a roll back.
7. Lines 005900 to 006100 read in-line card file for the department number of
departments to be deleted.
Assuming that we use “EDITJCL” in entry 3 of Figure 11.5 in Chapter 11, DB2 will
generate most of the JCL statements for us. However, we still have to include those for
batch files. In this example, these are for the display for the display output and the
deleting card file. Thus :
Using Figure 14.3 as the input, Figure 14.5 is the output of the program. Note that
department numbers ‘006’ and ‘045’ from Figure 14.3 have been deleted.
Employee Department
Number Name Number Salary
(EMPNO) (EMPNAME) (EMPDEPT) (EMPSALARY)
4. INSERT
The style is similar to those in Chapter 9. We can either insert a single row (as in
Chapter, Section 1.5) or do a mass insert (as in Chapter 9, Section 1.7). The format for
a single row insert is :
EXEC SQL
INSERT INTO table-name
(column -name1, column name2……..)
VALUES string1, string 2………,)
1. The column list (column names) is optional. If it is not specified, the sequence
of string values corresponds to the sequence of the columns of the tables as
created. If it is specified, columns and strings have a one-to-one correspondence
and do not have to match the original sequence of the columns in the table.
2. If a column is missing in the column list and it was defined as “NOT NULL
WITH DEFAULT” when the table was created, DB2 will generate the default
value (zeroes for numeric columns, spaces for nonnumeric columns).
3. If a column is missing and it was defined as “NOT NULL” there is an error and
the INSERT operation is not done.
For our program example, we insert rows based on data cards. The input is Figure
14.5. The program listing is Figure 14.6.
1. Lines 001100 to 001800 are the input file containing the data to be inserted.
2. Lines 002000 to 003400 are the various data-names such as counters and
switches.
3. Lines 003500 to 003700 generate the communication area data block shown in
Figure 10.1.
4. Lines 003800 to 004000 include the DCLGEN output shown in Figure 12.1.
004900 C020-PROCESS-ALL-ROWS
005000 MOVE ZEROES TO W005-NUMBER-ROWS-INSERTED
005100 MOVE W005-RECORD-COUNT TO W005-FIRST-RECORD-POINTER
005200 PERFORM C040-PROCESS-ROW-GROUP
005300 UNTIL W005-NO-MORE-INSERTS
005400 OR W005-NUMBER-ROWS-INSERTED = 10
005500 OR SQLCODE = (-911 OR –913)
005600 IF SQLCODE = 0
005700 EXEC SQL
005800 COMMIT
005900 END-EXEC
006000 ELSE IF SQLCODE = (-911 OR -913)
006100 COMPUTE W005-LAST-RECORD-POINTER
006200 = W005-RECORD-COUNT - 1
006300 DISPLAY ‘PROG1406 -- INPUT ‘W005-FIRST-RECORD-POINTER
006400 ‘ TO ’ W005-LAST-RECORD-POINTER
006500 BYPASSED DUE TO DEADLOCK UPON SYSOUT
006600 IF SQLCODE = -913
006700 EXEC SQL
006800 ROLLBACK
006900 END-EXEC.
007000 C040-PROCESS-ROW-GROUP
007100 MOVE W005-EMPNO TO EMPNO.
007200 MOVE W005-EMPNAME TO EMPNAME
007300 MOVE W005-EMPDEPT TO EMPDEPT
007400 IF W005-EMPSALARY NUMERIC
007500 MOVE 0 TO W005-EMPSALARY TO EMPSALARY
007600 MOVE W005-EMPSALARY TO EMPSALARY
007700 ELSE MOVE – 1 TO W005-SALARY-INDV.
007800 EXEC SQL
007900 INSERT INTO XLIM.EMPTABLE
008000 (EMPNO,
008100 EMPNAME,
008200 EMPDEPT,
008300 EMPSALARY)
008400 VALUES (:EMPNO,
008500 :EMPNAME,
008600 : EMPDEPT,
008700 : EMPSALARY : W005-SALARY-INDV)
008800 END-EXEC.
ER/CORP/CRS/ DB01/002 Ver 1.2 177
009000 IF SQLCODE = 0
009100 ADD 1 TO PERFORM C060-READ-INSERT-INPUT
009200 C060-READ-INSERT-INPUT
009300 READ INSERT-INPUT INTO W005-INSERT-RECORD
009400 AT END, MOVE ‘Y’ TO W005-END-OF-INSERT-RECORDS
009500 IF NOT W005-NO-MORE-INSERTS
009600 ADD 1 TO W005-RECORD-COUNT.
009700
e) Lines 007100 to 007300 lay out columns which will never have null
values.
f) Lines 007400 to 007700 lay out the salary column. We indicate via an
indicator variable whether or not we want DB2 to use nulls (if the input
is not numeric).
7. Lines 009200 to 009600 read the in-line card file for the input data.
Assuming that we use “EDITJCL” in entry 3 of Figure 11.5 in Chapter 11, DB2 will
generate most of the JCL for us. However, we still have to include those for batch files.
In this example, these are for the display output and the input card file. Thus :
/ / SYSQUT DD SVSOUT = *
/ / CARDIN DD *
00600 LIM, P. 005 0034000
00763 WARNER, P. 006 0031500
Using Figure 14.5 as the input, Figure 14.7 is the output of the program in Figure
14.6.
Employee Department
Number Name Number Salary
(EMPNO) (EMPNAME) (EMPDEPT) (EMPSALARY)
Note that we have added the data for employee numbers ‘00600’ and ‘00763’.
The programmer may do a mass insert of rows from current tables. The style is similar
to that of Chapter 9, Sections 1.7 and 1.8.
(W&K) Gabrielle Wiorkowski & David Kull, “DB2 Design & Development Guide”
ADDISON-WESLEY Publishing 1992.