DB2 Manual

103
DB2 - 1 -

Transcript of DB2 Manual

Page 1: DB2 Manual

DB2

- 1 -

Page 2: DB2 Manual

DB2

TABLE OF CONTENTS

1. INTRODUCTION TO A RELATIONAL DATABASE 052. DB2 OBJECTS 083. COMPONENTS OF DB2 124. DATATYPES ,FUNCTIONS AND OPERATORS 185. EMBEDDED SQL 266. INDICATOR VARIABLE 307. CURSORS 358. ERROR/EXCEPTION HANDLING 429. TRANSACTION PROCESSING 4410. CONCURRENCY AND LOCKING 4711. DB2 INTERACTIVE INTERFACE 58 11.1 SPUFI 59

11.2 DCLGEN 6311.3 CATALOG MANAGER 65

12. SQLCA AND SQLCODES 7012. APPENDIX –A : ASSIGNMENTS 7613. APPENDIX –B : STANDARDS 7914. APPENDIX –C : BIBLOGRAPHY 82

- 2 -

Page 3: DB2 Manual

DB2

DAY-WISE SCHEDULE

DAY 1

INTRODUCTION TO A RELATIONAL DATABASECOMPONENTS OF DB2DATATYPES, FUNCTIONS AND OPERATORSSPUFI

DAY 2

EMBEDDED SQLHOST VARIABLESINDICATOR VARIABLESDCLGEN AND SAMPLE PROGRAM

DAY 3

CURSORSERROR /EXCEPTION HANDLINGSAMPLE PROGRAMS ON CURSOR

DAY 4

TRANSACTION PROCESSINGCONCURRENCY AND LOCKINGSTANDARDS

- 3 -

Page 4: DB2 Manual

DB2

INTRODUCTION TO A RELATIONAL DATABASE

- 4 -

Page 5: DB2 Manual

DB2

What is a Data base Management System.

A Database management system (DBMS) is a software package that manages data stored in databases. You use a DBMS to control and use the information stored on your computer system more effectively and efficiently than you can with standard file processing. The DBMS is an additional layer of software between the program and the stored data .It’s the DBMS rather than the application program that has a complete picture of the physical and the logical structure of the data stored.

In a relational system Data is perceived by users as a collection of tables called relations Operators generate new tables from old ones The rows are referred to as tuples Columns are referred to as attributes Each row in a relation is distinct i.e duplicate rows are not allowed Each relation must have a primary key, an attribute or a combination of attributes

whose value uniquely identifies the rows. A relation may also contain foreign keys which reference other relations in a database. Entire information content of the database is represented as explicit data values (as

explicit values in column positions within rows of a table)

DB2

IBM’S Database 2 , commonly referred to as DB2, became generally available in the fall of 1983. DB2 was marketed as a relational database management system for the MVS operating system. It uses tables to represent the data that it manages .

HOW DOES DB2 ORGANIZE AND ACCESS INFORMATION.

Db2 is a database management system. A more complete description is that db2 is a relational database management system that uses the industry standard Structured Query Language (SQL) as a central component . A relational database system presents all information in the form of tables. A table is just a two dimensional array with horizontal rows and vertical columns. The intersection of a row and a column is a value .A value may be a text string , a number or nothing (null value).The name relational database comes from the technical term for a table , a relation . In addition , the formal names for the elements of a relation are tuple (row) and attribute(column). But these aren’t the only terms. A row is called a record and a column is called a field.Although files and tables have similar structures ,they are processed differently . in standard file processing , the unit of processing is a an individual record while in db2 it is an entire table ,which may have one ,many or no rows.

- 5 -

D4

Page 6: DB2 Manual

DB2

- 6 -

Page 7: DB2 Manual

DB2

DB2 OBJECTS

- 7 -

Page 8: DB2 Manual

DB2

STORAGE STRUCTURE

The total collection of stored data is divided up into a number of disjoint databases . Each database is divided into a number of disjoint spaces – several table spaces and index spaces. A space is a dynamically extendable collection of pages ,where a page is a block of physical storage (it is a unit of i/o i.e the unit transferred between primary and secondary storage in a physical i/o operation. The pages are given size of either 4k or 32 k. Each table space contains one or more stored tables . a stored table is is a physical representation of a base table .

DATABASE:

A Database in DB2 is a collection of logically related objects –that is a logical collection of stored tables that belong together in some way ,together with their associated indexes and the various spaces that contain those tables and indexes . it thus contains a set of table spaces (each containing one or more stored tables ) together with a set of index spaces (each containing exactly one index). A given stored table and all its associated indexes must be wholly contained within a single database. Objects are grouped together into the same database primarily for operational reasons .Tables can be moved from one database to another without having any logical impact on user or user programs.

TABLE SPACES:

A table space can be thought of as a logical address space on secondary storage that is use to hold one or more stored tables (logical because it is typically not just a set of physically adjacent areas) . As the amount of data in those table grows (or as the number increases), so storage will be acquired from the appropriate storage group and added to the table space accordingly. One table space can be approx. 64 billion bytes in size and there is effectively no limit to the number of table spaces in a database ,nor to the no. of databases . Fundamentally the table space is the storage unit for recovery and re-organization purposes; i.e. it is the unit that can be recovered via the recover utility . If the table space is very large , however , recovery and re-organization could take a very long time.DB2 therefore provides the option to partition a large table space into simple , partitioned and segmented forms. A simple table space can contain more than one stored table , though one is usually the best option. One reason for having more than one is that stored records for different stored tables can be clustered together in such a way as to improve access times to logically related data. In particular , certain join queries would then be handled more efficiently since the I/O operations would be reduced.Partitioned table spaces are intended for stored tables that are sufficiently large. A partitioned table space thus contains exactly one stored table , partitioned in accordance with value ranges of a partitioning columns or column combination. Individual partitions of a partioned table space are independent of each other in the sense that they can be independently recovered or reorganized.They can also be associated with different storage groups i.e. it is possible to store different partitions on different devices and thereby spread the table space I/O load.

- 8 -

Page 9: DB2 Manual

DB2

SEGMENTED TABLE SPACE:

Like simple table spaces, they can contain any number of stored tables ;unlike simple table spaces , however, segmented table spaces do not support any kind of cross table clustering- that is they do not allow records for different stored tables to be interleaved on a single page. Instead , they keep the tables physically separated.

INDEX SPACE

An index space is to an index what a table space is to a stored table. However, since the correspondence between indexes between indexes and index spaces is always one to one, there are no data definition statements for index spaces; instead, the necessary index space parameters are specified on the corresponding index definition statements. Thus for e.g. there is no create index space; instead the index space is created automatically when the corresponding index is created. Like Table spaces ,index spaces can be reorganized and recovered independently.

INDEX

Index in db2 are based on a structure known as B-tree. A b-tree is a multilevel, tree structured index with the property that the tree is always balanced; i.e. all its leaf entries in the structure are equidistant from the root of the tree, and this property is maintained as new entries are inserted into the tree and existing entries are deleted. As a result, the index provides uniform and predictable performance for retrieval operations. A given table can have any number of associated indexes. Also if the installation follows our recommendation that every base table have a primary key, then every stored table will have at least one index, namely the primary index. To perform an exhaustive search on a given stored table according to a given index, the data manager will access all records in that stored table in the sequence defined by that index and since that sequence may be quite different from the stored table’s physical sequence, a given data page might be accessed many times. It follows that an exhaustive search via a physical sequence unless the index concerned is a clustering index for which the sequence defined by the index is the same as, or close to, the physical sequence. The index is used to control the physical placement of the indexed records. Clustering indexes are extremely important for optimization purpose. The optimizer will try to choose an access path that is based on a clustering index, if one is available, and if clustering sequence is appropriate for the sql under consideration.

- 9 -

Page 10: DB2 Manual

DB2

STORAGE GROUPS:

A storage group is a named collection of direct access volumes, all of which are the same device type. Each table space and each index space normally has an associated storage group. When storage is needed for the space or partition , it is taken from the specified storage group. Within each Storage group, spaces and partitions are stored using VSAM linear data sets .

SYNONYM: Is an alternate name for a base table or view. Each user can assign his or her own synonyms for any table or view that was created by some other fully qualified name.

VIEW:

It is a predefined selection of data in base tables. It is a virtual table that does not physically exist but is processed as a table. It is derived from one or more base tables, or views or combinations of views and tables. The view definition is stored in the DB2 catalog. Changes to the data in the view can change the data in the base table.

CATALOG :

Contains information about every DB2 object that is maintained by it. Whenever a DB2 object is created, dropped or altered by any ddl statement or whenever control over the object is changed by any dcl statement of sql, an entry is made in the appropriate catalog table. Catalog table can be accessed using sql, they however cannot be updated by a user(but done so by the system).To retrieve information from the DB2 catalog, the select privilege on the catalog is needed. Some of the catalog tables are : SYSTABLES SYSSTOGROUP SYSTABLESPACE

- 10 -

Page 11: DB2 Manual

DB2

COMPONENTS OF DB2

- 11 -

Page 12: DB2 Manual

DB2

SYSTEM STRUCTURE:

The major components of DB2 are SYSTEM SERVICES LOCKING SERVICES DATABASE SERVICES

- 12 -

Page 13: DB2 Manual

DB2

SYSTEM SERVICES:

This component handles all system wide tasks including connections to other MVS subsystems. It also handles system startup and shut down operator communication. Managing the system log : The system log is a set of predefined disk data sets that are

used to record information for recovering user and system data in the event of a failure. When an active log data set becomes full (or on operator command ), DB2 switches to a new data set and copies the old one to an archive log data set on disk or tape. When the active data sets are full, they are recycled. Information regarding the data sets themselves is recorded in the BOOT STRAP DATA SET (BSDS).

Gathering system wide statistics, performance and accounting information.

LOCKING SERVICES:

Provided by an MVS subsystem called the IMS Resource Lock Manager (IRLM). Despite the “IMS” in its name , the IRLM does not really have anything to do with it. It is a general purpose lock manager which controls the concurrent access to db2 data.

DATABASE SERVICES:

The primary purpose of the database component is to support the definition , retrieval and update of database data- to implement the functions of the sql. The necessary support is provided by a series of five sub components : Precompile Bind Runtime Supervisor Data Manager Buffer Manager

Together these components support the preparation of the application programs for execution and the subsequent execution of those programs. The functions of the individual components are as follows:

PRECOMPILER

This component is a preprocessor for the host language. Its function is to analyse the host language source module stripping out all the sql statements it finds and replaces them by the host language CALL statements. From the sql it encounters, the precompiler constructs a database request module which becomes the input to the bind component.

- 13 -

Page 14: DB2 Manual

DB2

THE PROCESS:

Searches for and expands DB2 related include members . Searches for sql statement in the body of the programs source code . Creates a modified version of the source program in which every sql statement in the

program is commented out and a call to the db2 runtime interface module along with applicable parameters , replaces each original sql statement.

Extracts all sql statements from the program and places them in a dbrm to ensure that these two items are inextricably tied.

Reports on the success or failure of the precompile process. The precompiler searches for sql statements embedded in EXEC SQL and END-

EXEC.

- 14 -

Page 15: DB2 Manual

DB2

BIND:

This component is the compiler for the sql statements. It reads the sql statements from the DBRM’S and produces a mechanism to access data as directed by the sql statements being bound. The bind plan accepts as input one or more DBRM’s produces from the previous DB2 program precompilation. The output of the bind plan is an application plan containing executable logic representing optimized access paths to DB2 data. An application plan is executable only with a corresponding module. Before u can run a DB2 program, regardless of the environment, an application plan name must be specified.The major functions of bind are: Parsing and syntax checking Optimization Authorization Check that DB2 tables and columns being accessed conforms to the corresponding

DB2 catalog information.

BIND PLAN vs. BIND PACKAGE:

In some cases however, a DBRM may not be bound directly into a plan. Instead it may first be bound into a package and then finally, the packages may be bound into a plan. There are certain disadvantages of directly binding the DBRM’s into an application plan :

If an individual DBRM needed to be recompiled for any reason(for eg some index was dropped),the entire plan had to be recompiled and rebound.

If multiple plans involved the same DBRM , that same DBRM had to be compiled multiple times –and , if that DBRM ever needed to be recompiled , then all relevant plans had to be recompiled and rebound in their entirety.

Adding a new DBRM to an existing plan required (again) a recompilation and rebind of the entire plan.

Partly as a consequence of the foregoing points, bind and rebind times are becoming unacceptably high in some DB2 installations and availability was suffering as a result.

The package concept was introduced to remedy these deficiencies. If a given DBRM needs to be recompiled, all that has to be done is an appropriate package bind –it is not necessary to recompile the entire plan. Indeed, it may not be necessary to do a new plan bind to incorporate the new package either.

- 15 -

Page 16: DB2 Manual

DB2

RUNTIME SUPERVISOR:

The runtime supervisor is resident in main memory when the application program is executing. Its job is to oversee that execution. When the application program requests some database operation to be performed (wishes to execute some sql), control first goes to the runtime supervisor, which uses control information in the application plan to request the appropriate operations on part of the data manager.

DATA MANAGER:

The data manager can be thought of as a very sophisticated access method. It performs all of the normal access method functioning such as search, retrieval, update , index maintenance etc. Broadly speaking, the data manager is the component that manages the physical database(s). It invokes other system components as necessary in order to perform detailed functions such as locking, logging, I/O operations etc during the performance of its basic task.

BUFFER MANAGER:

The buffer manager is the component responsible for physically transferring data between external storage and virtual memory. It employs sophisticated techniques to get the best performance out of the buffer pools under its care and to minimize the amount of physical I/O actually performed.

- 16 -

Page 17: DB2 Manual

DB2

DATATYPE FUNCTIONS AND

OPERATORS

- 17 -

Page 18: DB2 Manual

DB2

INTRODUCTION:

The basic data object is the scalar value ;the object appearing at the intersection of a given row and a given column of a given table. Each scalar value is of some scalar data type. For each such data type, there is also an associated format for writing literals of that type. Scalar objects can be operated upon by means of certain scalar operators. DB2 also provides certain scalar functions which can be regarded as scalar operators. Scalar objects and operators can be combined to form scalar expressions.

- 18 -

Page 19: DB2 Manual

DB2

- 19 -

Page 20: DB2 Manual

DB2

- 20 -

Page 21: DB2 Manual

DB2

NUMERIC OPERATORS:

ARE : +,-,*,/

FUNCTIONS:

CONCATENATION ( ): can be used to concatenate two character strings or two graphic strings. E.g (INITIALS || LASTNAME)

CHAR: Converts a date, time ,timestamp to its character string representation.

DATE: Converts a scalar value to a date.

DAY: Extracts the day portion of a date or a timestamp.

DAYS: Converts a date or timestamp to a number of days.

DECIMAL: Converts a number to decimal representation.

DIGITS: Converts a number(decimal or integer) to a character string representation.

FLOAT: Converts a number to a floating point representation.

HEX: Converts a scalar value to a character string representing a internal HEX code

HOUR: Extracts the hours portion of a time or timestamp.

INTEGER: Converts a number to integer representation.

LENGTH: Computes the length of the scalar value in bytes .

MICROSECOND: Extracts the microsecond portion of a timestamp.

MINUTE: Extracts the minute portion of a date or timestamp.

SECOND: Extracts the second portion of a date or timestamp.

SUBSTR: Extracts a part of the string from a string.Assume = ‘AARTI’ e.g. SUBSTR(SNAME,1,3) would extracts ‘AAR’

TIME: Converts a scalar value to time.

TIMESTAMP: Converts either (a) Single scalar value or

- 21 -

Page 22: DB2 Manual

DB2

(b) a pair of scalar values (representing a date and time resp.) to a timestamp VALUE: Converts a null value into a non null value. e.g. Select custno,fname,lname,value(‘(H):’||homeph,’(w):’|| workph, ’no phone’)

VARGRAPHIC: Converts a character sting to a graphic string.

YEAR: Extracts the year portion of a date or timestamp.

SPECIAL REGISTERS

Each individual user is assigned an authorization ID. That id is used to sign on to the system, and serves as the primary id for the user in question. Tables and other objects that are purely private to that user will typically be created under the control of, and hence be owned by the primary id.

Each functional area(eg each department) in the organization is also assigned an authorization id. However, that id is typically not given the sign-on authority; users sign on to the system under their primary id. Once signed on, users can operate under their primary id or using the sql statement (SET CURRENT SQLID) they can switch to a secondary id. An external subsystem such as IBM’s RACF keeps track of the secondary id(s) that can legitimately be used by a given primary id. A given primary id can have any number of secondary ids also that the same secondary id can be used by any number of primary ids.

- 22 -

Page 23: DB2 Manual

DB2

SCALAR EXPRESSIONS

Six types of scalar expression are Numeric Character String Graphic String Date Time Timestamp expressions

Assignments :Assignment operations are performed when values are retrieved from the DataBase orstored into the DataBase.

Comparisons :The general form of a comparison is Comparand operator comparand where

Two comparands must be compatible The operator is any of the following > , <, = ,>= ,<= , ~=

ExamplesWEIGHT * 454=1000SUBSTR (PNAME,1,1) = ‘C’FINAL_DATE = REVIEW DATE - CURRENT DATESUM (QTY) =500

- 23 -

Page 24: DB2 Manual

DB2

NULLS :

Means missing information. The problem with missing information is that is frequently encountered in the real world. For example , historical records sometimes include such entries as “date of birth not known:; meeting agenda’s often show a speaker as “to be announced” and police records may have entries as “present whereabouts not known”. Hence it is desirable to have some way of dealing with such situations in our formal database systems. SQL systems like DB2 represent missing information by means of special markers called NULLS. For e.g. we might say loosely that the weight of some part is null. What we mean by such a statement is that (a) the part exists (b) of course , it has a weight but (c) we do not know what that weight is. Instead we mark that slot as null.In general any column can contain nulls unless the definition of that column explicitly specifies NOT NULL. If a given column is allowed to contain nulls, and a row is inserted into the table and no value is provided for that column, DB2 will automatically place a null in that position. In DB2, a column that can accept nulls is physically represented in the stored database by two columns, the data column itself and a hidden indicator column ,one byte wide ,that is stored as a prefix to the actual data column.NOT NULL WITH DEFAULT means that the column in question cannot contain NULLS, but that it is nevertheless still legal to omit a value for the column on insert. If a row is inserted and no value is provided for some column on which not null with default applies,DB2 automatically places one of the following default values in that position: Zero for numeric columns Blanks for fixed length columns Empty (zero-length string) for varying length string columns.

- 24 -

Page 25: DB2 Manual

DB2

EMBEDDED SQL

- 25 -

Page 26: DB2 Manual

DB2

EMBEDDED SQL:

Any SQL statement that can be used at the terminal can also be used in an application program. There are various differences of detail between a given interactive SQL statement and its corresponding embedded form.

Embedded SQL statements are prefixed by EXEC SQL and are terminated by END-EXEC

SQL statements can include references to host variables

Any tables (base tables or views) used in the program must be declared

After any SQL statement has been executed, feedback information is returned to the program in an area called the SQL Communication Area (SQLCA)

The embedded SQL SELECT statement requires an INTO clause specifying the host variables.

- 26 -

Page 27: DB2 Manual

DB2

HOST VARIABLES

- 27 -

Page 28: DB2 Manual

DB2

HOST VARIABLES:Host variables are variables declared in the working storage section and are used by DB2 when it moves data between your program and a table. They are defined according to the rules of programming language.Host variables can appear in SQL data manipulation statements. They are generally used for designating a target for retrieval. Such variables can appear in the following positions : Into clause in select or fetch (target for retrieval) Where or having clause (value to be compared) Set clause in update (value to be assigned) Values clause in insert (value to be inserted)

Example

EXEC SQL Select status , city into :status , :city from employee where sno = :given-sno;END-EXEC

SQL statements can include references to host variables, such references are prefixed with a colon to distinguish them from SQL column names

- 28 -

Page 29: DB2 Manual

DB2

INDICATOR VARIABLES

- 29 -

Page 30: DB2 Manual

DB2

INDICATOR VARIABLE

In general if there is a chance that the source or a retrieval operation might be null, the user should include an INDICATOR VARIABLE in the into clause in addition to the target variable as illustrated in the following example:

EXAMPLE :

EXEC SQL Select status , city Into :status:status-ind, :city:cityind From s Where sno = :Given-Sno END-EXEC.

For processing and finding out whether the fields were NULL or not, a check can be performed as :

IF STATUS-IND < 0 THEN /*STATUS WAS NULL */

Indicator variables can be used in the VALUES clause to insert NULL VALUES.

EXAMPLE: -

IF COLORIND < 0 OR CITYIND < 0

EXEC SQL INSERT INTO P (PNO,COLOR, CITY) VALUES (:PNO,:PCOLOR:COLOR-IND, :PCITY:CITYIND)END-EXEC.

Each indicator variable is a half-word integer (pic S9(4) comp). If defined as an array (occurs clause) ,then it may be used for a list of columns with the

first occurrence of the indicator variable corresponding to the first column in that list using a single indicator variable, Nulls can be handled for all the fields of the table.

The indicator variable will have a negative value if the select returns a null value. If the indicator variable returns a value > 0, it indicates a truncated variable is the

length of the character string before truncation If the Indicator variables contain :

A negative No. indicates that the column has been set to Null The value 2 indicates that the column has been set to Null as a result of Data

Conversion Error A positive or a zero value indicates that the column is not Null

- 30 -

Page 31: DB2 Manual

DB2

If a column, defined as a char data type,is truncated on retrieval because the host variable is not large enough, the indicator Variable, contains the original length of the truncated column

EXAMPLE: -

01 DEPT-INDICATORS. 10 DEPT-IND OCCURS 5 TIMES PIC S9(4) COMP. EXEC SQL

SELECT DEPTNO, DNAME, MGR, HO, LOC INTO :DCLDEPT: DEPT-IND

FROM DEPT WHERE DEPTNO = ‘A00’

END-EXEC

Indicator variables can appear on the right hand side of an assignment in the SET clause to set a value to NULL.

EXAMPLE: -

IF RANKIND = < 0

EXEC SQL UPDATE S SET STATUS = :STATUS:STATUS-IND

WHERE CITY =’LONDON’END-EXEC.

- 31 -

Page 32: DB2 Manual

DB2

A SAMPLE PROGRAM

- 32 -

Page 33: DB2 Manual

DB2

IDENTIFICATION DIVISION.PROGRAM-ID. PRG1.AUTHOR. AARTI.ENVIRONMENT DIVISION.DATA DIVISION.WORKING-STORAGE SECTION.

EXEC SQLINCLUDE EMPDCL

END-EXEC.EXEC SQL

INCLUDE SQLCAEND-EXEC.

PROCEDURE DIVISION.1000-UPDATE-PARA.

MOVE 3999 TO X.EXEC SQL

INSERT INTO EMP(X)VALUES (:X)

END-EXEC.EXEC SQL

COMMIT WORKEND-EXEC.STOP RUN.

- 33 -

Page 34: DB2 Manual

DB2

CURSORS

- 34 -

Page 35: DB2 Manual

DB2

CURSORS:

A mechanism allowing an application program to retrieve a set of rows. The cursor facility allows a COBOL program to gain addressability to individual row occurrences of a many-rows result table

Following steps to be performed to use cursors Declare cursor : to define cursor Open cursor : to create result table Fetch cursor : to retrieve rows from cursor, one at a time to be executed in a loop Close cursor : to close the cursor

Declaring (defining) a cursor is done in the data division of your program. This is purely declarative in nature. Therefore no information is being retrieved from the database yet. The Cursor name should begin with a letter and must not exceed 18 characters.When the open statement is encountered the select in the cursor declaration is executed. The open cursor statement not only executes the selection of data from the DB2 database but also establishes the initial position of the cursor in the results table. One program can have multiple cursors.

Declaring a CursorEXEC SQL DECLARE cursor CURSOR FOR SELECT col1, col2.... FROM table WHERE condition [FOR UPDATE OF col1, col2 ..]END-EXEC

Opening a CursorEXEC SQL

OPEN cursorEND-EXEC

Fetching a row from cursor :EXEC SQL

FETCH cursor INTO : host var1, :host var2,...END-EXEC.

Closing a cursor :EXEC SQL

CLOSE cursorEND-EXEC.

- 35 -

Page 36: DB2 Manual

DB2

Example-Based on a Single Table

Operations Involving Cursors :-

EXEC SQL DECLARE X CURSOR FOR SELECT S#, SNAME, STATUS

FROM S WHERE CITY = :YEND-EXEC.

EXEC SQLOPEN X

END-EXEC.

LOOP UNTIL NO MORE ROWS OR ERROR

EXEC SQLFETCH X INTO :S#,:SNAME.:SNAME-IND

END-EXEC.

PROCESSING STATEMENTS .

EXEC-SQLCLOSE X

END-EXEC.

- 36 -

Page 37: DB2 Manual

DB2

DATA MODIFICATION:

Often an application program must read data and then based on its value, either update or delete data. One can use the UPDATE or DELETE SQL statements to modify and delete rows from DB2 tables. These statements are similar to select statements which operate on a set of data at any given point of time.

This is accomplished with a cursor and a special clause of the update and delet statements usable only by embedded SQL namely :WHERE CURRENT OF. The cursor is declared with a special FOR UPDATE OF CLAUSE.

A for update of clause appears with:

Select statement to indicate what columns can be updated when retrieved The columns to be updated must be listed in the for update of clause or the declare You do not have to select a column to update it

Rules for Update

The select statement must be on a single table and not on a join If the declare cursor statement contains a subquery it must not be on the same table as

the main query You cannot use distinct, group by, order by or built-in functions Only those columns are eligible for updation which are selected in the for.. update

clause

The current forms of UPDATE & DELETE

EXEC SQL UPDATE table SET field = : exp [, field = : exp] WHERE CURRENT OF cursorEND-EXEC.

EXEC SQL DELETE FROM table WHERE CURRENT OF cursorEND-EXEC.

- 37 -

Page 38: DB2 Manual

DB2

Example: (Use of Cursor)

EXEC SQL Declare C1 cursor for

Select Deptno, Deptname, Mgrno From DeptWhere ADMRDEPT = :ADMRDEPT

for update of MGRNOEND-EXEC.

PROCEDURE DIVISION.

MOVE ‘A00’ TO ADMRDEPT.

EXEC SQLOPEN C1

END-EXEC.

PERFORM 200-MODIFY-DEPT-INFO UNTIL NO-MORE-ROWS.

EXEC SQLCLOSE C1

END-EXEC.

200-Modify-Dept-Info.

EXEC SQLFetch C1 into :deptno, : deptname, : mgrno

END-EXEC.

If sqlcode < 0GO TO 9999-error-paragraph.

If sqlcode = +100Move ‘NO’ to more-rows

ElseEXEC SQL

Update Dept Set MGRNO = ‘00000’ Where current of C1

END-EXEC.

- 38 -

Page 39: DB2 Manual

DB2

DATA RETRIEVAL

Pseudocode for retrieving data from an application join ,using cursors:

EXEC SQL Declare Deptcur cursor for

Select Deptno, Deptname From Dept

END-EXEC.

EXEC SQLDeclare Empcur cursor for

Select empno, salary from emp where workdept = :hv-workdept

END-EXEC.

EXEC SQL Open DeptcurEND-EXEC.

Loop until no more dept rows or error

EXEC SQLFetch deptcur into :Deptno , :Deptname

END-EXEC.

Move deptno to HV-WORKDEPT

EXEC SQLOpen Empcur

END-EXEC.

Loop until no more employee rows or error

EXEC SQLFetch empcur into

:empno, :salaryEND-EXEC.

Process retrieved dataEnd Loop (2)End of Loop (1)

- 39 -

Page 40: DB2 Manual

DB2

WITH HOLD OPTION:

This is an optional specification on a cursor declaration. The significance can be understood by considering what happens in its absence.Suppose we need to process some large table, one row at a time by means of a curso and update a few of the as we go. It is often desirable to divide the work up into batches and to make the processing of each batch into a separate transaction (by issuing a separate commit at the end of each one); thus, e.g. a table of one million rows might be processed by a sequence of 10,000 transactions, each one dealing with just 100 rows. This way , for e.g. if it becomes necessary to roll a given transaction back, then at most 100 updates will have to be undone, instead of potentially as many as a million.

The problem with this approach ,however is that every time we issue a commit, we implicitly close the cursor, thereby losing our position within the table. The first thing each transaction has to do, therefore is to execute some re-positioning code in order to get back to the row that is due to be processed next. And that re-positioning code can often be quite complex, especially if the processing sequence is determined by a combination of several columns.

If the cursor declaration specifies with hold, however, commit does not close the cursor, instead, leaves it open, positioned such that the next FETCH will move it to the next row in sequence. The possibly complex code for repositioning is thus no longer required.

However it is important to note that the first operation on the cursor following the commit must be fetch. Update and delete current are illegal.

- 40 -

Page 41: DB2 Manual

DB2

ERROR / EXCEPTION HANDLING

- 41 -

Page 42: DB2 Manual

DB2

WHENEVER:

The whenever statement has the syntax :

EXEC SQLWHENEVER condition action

END-EXEC.

Where “condition” is one of the following :

NOT FOUND means SQLCODE = 100

SQLWARNING means SQLCODE >0 & NOT = 100

SQLERROR means SQLCODE < 0

“ACTION ” specifies a CONTINUE or a GO TO statement.

The whenever statement causes the program to automatically check the sqlcode. Based on the value it finds, it takes the action you specify. Some application programmers prefer (for structured reasons) to avoid the whenever statement, and use all specific error checking after each SQL statement is issued. If you omit the action for a whenever statement, the default of continue will apply for that condition.There is no limit to the no. of whenever statements you can use.

Example using ‘WHENEVER’

1000-INQUIRY.

EXEC SQL WHENEVER SQLERROR GOTO 1000-UNDOEND-EXEC.

EXEC SQL SELECT FLD1, FLD2 INTO : FLD1, :FLD2 FROM EMP-TABLE WHERE CODE = 113END-EXEC.

1000-UNDODISPLAY ‘ERROR! CAN’T PROCEED’

EXEC SQL ROLLBACK

END-EXEC.

1000-EXIT. EXIT.

- 42 -

Page 43: DB2 Manual

DB2

TRANSACTION PROCESSING

- 43 -

Page 44: DB2 Manual

DB2

WHAT IS A TRANSACTION ?

A transaction is a logical unit of work. Consider the following example. Suppose for the sake of example the parts table contains an additional column totqty representing the total quantity for the part in question. The value of the totqty for any part is supposed to be equal to the sum of all sp.qty values taken all over sp rows for that part. Now consider the following sequence of operations, the intent of which is to add a new shipment (S5,P1,1000) to the database:

EXEC SQL WHENEVER SQLERROR GOTO UNDO

END-EXEC.

EXEC SQL INSERT INTO SP VALUES (‘S5’,’P1’,1000)END-EXEC.

EXEC SQL UPDATE P SET TOTQTY = TOTQTY + 1000 WHERE P# = ‘P1’END-EXEC

EXEC SQL COMMIT WORKEND-EXEC.

UNDO: EXEC SQL

ROLLBACK END-EXEC

FINISH: RETURN

The insert adds the new shipment to the sp table, the update updates the totqty column for the part p1 appropriately.

The point of example is that what is presumably intended to be a single atomic transaction “create a new shipment” –infact involves 2 updates to the database. What is more is that the database is not consistent even between thise two updates. Thus a logical unit of work is not necessarily just one SQL operation ; rather it is a sequence of several such operations, in general, that transforms a consistent state of the database into another consistent state, without necessarily preserving consistency at all intermediate points. Now it is clear that what must not be allowed to happen in the example is for one of the

- 44 -

Page 45: DB2 Manual

DB2

two updates to executed and the other not (because then the database would be in an inconsistent state). Ideally we would want that both the updates are done, but we cannot have such a guarantee: there is always a chance that things will go wrong. For example a system crash may occur between the two updates.

But a system that supports transaction processing does provide the next best thing to such a guarantee. Specifically, it guarantees that if the transaction executes some updates and then a failure occurs, for whatever reason before the transaction reaches its normal termination, the those updates will be undone. Thus the transaction either executes in its entirety or is totally cancelled.

The system component that provides this atomicity is know as the transaction manager and the COMMIT WORK and ROLLBACK WORK are the keys to the way it works.

The COMMIT WORK operation signals successful end-of-transaction :it tells that transaction manager that a logical unit of work has been successfully completed.

The ROLLBACK operation by constrast, signals unsuccessful end-of-transaction indicating an inconsistent state and all the updates made by the logical unit of work must be rolled back or undone.

SYNTAX:

COMMITThe SQL commit statement takes the formEXEC SQL COMMIT [WORK]END-EXEC.

ROLLBACK

The SQL ROLLBACK statement takes the form

EXEC SQL ROLLBACK [WORK]END-EXEC

- 45 -

Page 46: DB2 Manual

DB2

CONCURRENCY AND LOCKING

- 46 -

Page 47: DB2 Manual

DB2

THREE CONCURRENCY PROBLEMS:

DB2 is a shared system; i.e. it is a system that allows any number of transactions to access the same database at the same time. Any such system requires some kind of concurrency control mechanism to ensure that current transactions do not interfere with each others operation and DB2 includes such a mechanism namely locking.There are essentially three ways in which things can go wrong- three ways. They are The lost update problem The uncommited dependency problem The incorrect analysis problem The lost update problem:

Consider the situation as shown in the figure:

Transaction A retrieves some row R at time t1 ; transaction B retrieves the same row at time t2; transaction A updates the row(on the basis of the values seen at time t1) at time t3; and transaction B updates the same row (on the basis of the value seen at time t2, which are the same as seen at time t1) at time t4. Transaction A’s update is lost at time t4, becauses transaction B overwrites it without even looking at it.

- 47 -

Page 48: DB2 Manual

DB2

The uncommitted dependency problem:

This problem arises if one transaction is allowed to retrieve (or update) a row that has been updated by another transaction and has not yet been committed by that other transaction. For if it has not been committed, there is always a possibility that it never will be committed but will be rolled back instead- in which case the first transaction will have data that now no longer exists. Consider the figure given below:

In this example , transaction A sees an uncommitted update at time t2. That update is then undone at time t3. Transaction A is therefore operating on false assumption that row R has the value as seen at time t2, where as in fact , it has whatever value it had prior to time t1. As a result, transaction A may well produce incorrect output.

Inconsistent analysis problem:

This problem could be a simple summation problem.

- 48 -

Page 49: DB2 Manual

DB2

How DB2 solves these problems: DB2’s concurrency control mechanism is based on a technique called locking. The basic idea of locking is simple: when a transaction needs and assurance that some of the object it is interested in typically a database row - will not change in some unpredictable manner while its back is turned , it acquires a lock on that object and there by to prevent them from changing it. The first transaction is thus able to carry out its processing in the certain knowledge that the object in question will remain in stable state for as long as that transaction wishes it to

The two types of locks that can be placed are shared lock(S) and exclusive lock (X). We assume that if a transaction requests a lock that is currently not available , the transaction simply waits until it is. In practice, the installation can specify a maximum wait time ; then if any transaction ever reaches this threshold in waiting for a lock, it “times out” and the lock request fails ( a negative SQLCODE is returned)

From the compatibility matrix , two inferences can be drawn:

If transaction A holds an X lock on row R , then a request from transaction B for a lock of either type on R will cause B to go into a wait state. B will wait until A’s lock is released.

If transaction A hold a shared lock (S) lock on row R , then A request from transaction B for an X lock on R will cause B to go into a wait

state (and B will wait until A’s lock is released);

A request from transaction B for an S lock on R will be granted (that is , B will now also hold an S lock on R)

- 49 -

Page 50: DB2 Manual

DB2

Transaction requests for row locks are always implicit. When a transaction successfully fetches a row , it automatically acquires an S lock on that row. When a transaction successfully updates a row, it automatically acquires and X lock on that row. If it already holds an S lock on that row,as it will in FETCH/UPDATE or FETCH/DELETE SEQUENCE, then the update or delete “promotes the S lock to X level.

The lost update problem revisited

The above figure shows what would happen to the interleaved execution under the locking mechanism of DB2. As one can see, transaction A’s update at time t3 is not accepted because it is an implicit request for an X lock on R, and such a request conflicts with the S lock already held by transaction B; so A goes into a wait state. For analogous reasons , B goes into a wait state at time t4. Now both transaction are unable to proceed, so there is no question of any update being lost.DB2 thus solves the lost update problem by reducing it to another problem but at least it does solve the original problem. This problem is called the deadlock problem, discussed later.

- 50 -

Page 51: DB2 Manual

DB2

The uncommitted dependency problem revisited

Transaction A’s operation at time t2 is not accepted , because it is an implicit request for a lock on R, and such a request conflicts with the X lock already held by B; so A goes into a wait state and remains so until B reaches a synchpoint(either commit or rollback), when B’s lock is released and A is able to proceed; and at that point A sees a committed value (either the pre – B value, if B terminates and with a ROLLBACK , or the post – b value otherwise. Either way, A is no longer dependent on an uncommitted update.

- 51 -

Page 52: DB2 Manual

DB2

Deadlocks . A 'deadlock' occurs when program A locks page X exclusively and attempts to lock page Y, while program B has already locked page Y exclusively and attempts to lock page X. Neither program can continue without the required lock. DB2 cancels one of the processes (the one with the fewest log records) with a time out code. To avoid this situation, you can:

Use the same sequence of update. Both programs should advance along the tables in ascending key order; this makes it less likely that they will cross each other's paths and attempt to lock the same page. Both programs should access various tables in the same sequence, for the same reason.

Avoid clashing updates through different paths (if possible). The problem with such updates can be exemplified as follows:

User A is updating page 1 using index X for access to the data; User B is updating page 2 using index Y for access to the data.

However, each index also references the data on the other page (i.e., Index X references data on page 2 and index Y references data on page 1).

Therefore, after the data is reached by means of one index, and after that data is updated, each query must modify the other index so it would reflect the new, updated data. However, that other index is still locked by the other query.

Such deadlocks are hard to avoid. You may watch out for some conditions which make this situation more likely:

Large number of indexes on a table, with frequent deletes or updates. Multi-row updates and deletes. Large value used for SUBPAGES for the index. Use frequent COMMITs. The chance that a page needed by program A

will already be held by program B is thereby reduced.

Use cursor with FOR UPDATE OF ... This technique locks with INTENT UPDATE, ahead of time, all the pages which you will need. This is a more relaxed lock than an exclusive lock, but it still prevents other programs from locking one of your pages exclusively. Thus, less contention, fewer deadlocks and fewer time outs will occur.

- 52 -

Page 53: DB2 Manual

DB2

Explicit locking facilities

In addition to the implicit locking mechanism described earlier, DB2 provides certain explicit facilities which the programmer should be aware of. The explicit facilities consists of : the SQL statement LOCK TABLE , the ISOLATION PARAMETER on the bind plan command, the table space LOCKSIZE parameter and the ACQUIRE/RELEASE PARAMETER on the bind plan.

LOCK TABLE :

Depending on the versions, this command either locks up the table or an entire table space

SYNTAX

LOCK TABLE table IN mode MODE

Where “mode” is SHARE or EXCLUSIVE & “table” must designate a base table not a view.Once a lock is acquired no other transaction will be able to access any part of the table in any way - until the original lock is released. When that original lock is released depends on the RELEASE parameter on BIND.The Lock table statement can be used to control locks from within a DB2 application program. Every individual page lock uses system resources in storage and processing timeA single table lock reduces the storage and processing time required by the many small locks. This results in saving of system resources.

- 53 -

Page 54: DB2 Manual

DB2

ISOLATION PARAMETER:

Specifies the isolation level for the application plan being bound.DB2 supports two isolation levels for every transaction Cursor Stability (CS) Repeatable Read (RR)

These are used while cursor manipulation

Cursor Stability

DB2 takes a lock on the page the cursor is accessing and releases the lock on that page, when the cursor moves onto a different page(This is not done when we use FOR UPDATE of statement in cursor)The lock on the last page is released at commit time (or at Thread de-allocation time)

Repeatable Read

In cursor stability, while your transaction reads data, other transaction could change the data you have already read. In repeatable read, DB2 holds all page locks while the cursor is moving all till the transaction commits (or till thread deallocation).Cursor Stability provides more /higher concurrency while repeatable read provide more consistency.

The problem with CS is that a transaction operating at that level may have a record changed “behind its back” as in inconsistent analysis problem and so may produce a wrong answer.

By contrast, a transaction that operates under isolation level RR, can behave completely as if it were executing in a single user system.

- 54 -

Page 55: DB2 Manual

DB2

LOCKSIZE PARAMETER:

Physically, DB2 locks data in terms of pages or tables or table spaces, depending on what was specified as the LOCKSIZE for the relevant table space in the CREATE or ALTER TABLESPACE operation.

For a given table space, the LOCKSIZE can be specified as PAGE, TABLE, TABLE SPACE or ANY.

TABLESPACE : means all locks acquired on data in the tablespace will be at the tablespace level

TABLE : means locks acquired on data in the tablespace will be at the table level

PAGE : means locks acquired on data in the tablespace will be at the page level whenever possible.

ANY : (Which is the default) means that DB2 itself will decide the appropriate physical unit of locking for the tablespace for each plan .Defaults to a page lock, but if the no. of pages that are locked exceeds an installation default, DB2 does a lock escalation and automatically locks a larger unit.

- 55 -

Page 56: DB2 Manual

DB2

ACQUIRE/RELEASE PARAMETERS

DB2 always implicitly acquires locks of some kind

The acquire and release parameters on the BIND command specify when such tablespace level locks are to be acquired and released .For ACQUIRE, the possible specifications are USE & ALLOCATE; For RELEASE, they are COMMIT & DEALLOCATE

While Binding, DB2 allows us to specify transaction level lock acquiring and releasing parameters.

ACQUIRE:

ACQUIRE (use) - This option tells DB2 to take locks at the time of SQL statements execution. This is DB2 default.

ACQUIRE (allocate) - This option tells DB2 to take all necessary locks at the start of the transaction.

RELEASE:

Similar to the DB2 acquire parameters, there are 2 release parameters.

RELEASE (commit) - This option tells DB2 to release all locks of transaction commit time. This is the DB2 default.Release (de-allocate) - This option tells DB2 to release all locks only when the program ends (i.e. the thread is de-allocated).

All combinations except ACQUIRE (Allocate) and RELEASE (commit) are allowed.

For more concurrency, use ACQUIRE (use) and RELEASE (commit). This is the DB2 default.

For better performance, use ACQUIRE (ALLOCATE) and RELEASE (DEALLOCATE).

- 56 -

Page 57: DB2 Manual

DB2

DB2 INTERACTIVE INTERFACE

- 57 -

Page 58: DB2 Manual

DB2

The DB2 INTERACTIVE INTERFACE (DB2I):

This interface provides following:

Ability to execute SQL statements interactively

To invoke prewritten application programs

Ability to issue operator commands

Ability to invoke database utilities

Ability to produce application programs for execution.

INVOKING (DB2I)

Log on to TSO and enter ISPF. From ISPF menu, select DB2I. The DB2I main menu will offer following options.

SPUFI DCLGEN PROGRAM PREPARATION PRECOMPILE BIND/REBIND/FREE RUN DB2 COMMANDS UTILITIES

- 58 -

Page 59: DB2 Manual

DB2

SPUFI

Supports the interactive execution of SQL statements from a TSO terminal

You can create a text file containing one or more SQL statements (using the ISPF editor), then execute that file via SPUFI, and then use “ISP Browse” to browse through the results of these statements (which will have been written to another text file).

Intended primarily for application programmers who wish to test the SQL portions of their programs.

- 59 -

Page 60: DB2 Manual

DB2

- 60 -

Page 61: DB2 Manual

DB2

- 61 -

Page 62: DB2 Manual

DB2

- 62 -

Page 63: DB2 Manual

DB2

DCLGEN

Allows the user to invoke the declarations generator program

Program preparation : precompilation compilation or assembly linkage editor processing bind processing program execution (TSO only)

- 63 -

Page 64: DB2 Manual

DB2

- 64 -

Page 65: DB2 Manual

DB2

- 65 -

Page 66: DB2 Manual

DB2

- 66 -

Page 67: DB2 Manual

DB2

- 67 -

Page 68: DB2 Manual

DB2

- 68 -

Page 69: DB2 Manual

DB2

- 69 -

Page 70: DB2 Manual

DB2

- 70 -

Page 71: DB2 Manual

DB2

- 71 -

Page 72: DB2 Manual

DB2

- 72 -

Page 73: DB2 Manual

DB2

- 73 -

Page 74: DB2 Manual

DB2

- 74 -

Page 75: DB2 Manual

DB2

Appendix –A ASSIGNMENTS

- 75 -

Page 76: DB2 Manual

DB2

Consider the following tables :

Table : EMPLOYEE

EMPNO - INTEGER PRIMARY KEYENAME - CHAR (20) NOT NULLJOB - VARCHAR(10)

MGR - INTEGERHIREDATE - DATESAL - DECIMAL(10, 2)COMM - DECIMAL(6, 2)DEPTNO -INTEGER FOREIGN KEY

Table: DEPT

DEPTNO - INTEGER PRIMARY KEYDNAME - VARCHAR(10)LOCATION - VARCHAR(10)

I. Use SPUFI to execute the SQL statements

a) List employees hired after 01/09/81 and working in the accounting dept.b) List the BIG BOSS of the company (who does not report to anyone).c) List all the employees whose names begin with N and the third character is J.d) List all employees hired during the year ‘82.e) List all dept details from the DEPT table which has atleast one employee.f) Count the total no. of clerks.g) List the minimum salary of various categories of employees department wise such that the salary is greater than 1500.h) List the employees in the ascending order within each dept.i) List the names of all the clerks along with the name of their departments.j) Find the minimum salary of MANAGERS in various departments.

II. Generate Table Declaration and host variable structure for above tables using the DB2I-DCLGEN option . The dclgens should be stored in the same PDS where the source programs are.

III. Write a COBOL programs to : a. Display the details of the highest paid employee. b. Display the name and salary of the employee whose empno is as passed on as a host variable . If the search returns a NULL value , a NULL INDICATOR should be used to indicate the appropriate error message.

- 76 -

Page 77: DB2 Manual

DB2

IV. Increase the commission of employees, who have completed one year of service with following conditions. (The % increase is w.r.t the salary)

if salary > 10000 and salary < =15000 grant him a commission of 20% if salary > 15000 and salary <= 20000 grant him a commission of 15% if salary > 20000 grant him a commission of 10%

V. Compute and display the total salary of all the employees where the total salary is calculated as TSAL = SALARY + COMMISSION. A additional commission of 10% of salary is granted to those employees who work as salesmen in the firm. (Hint : commission can be null)

Precompile, compile, linkedit, bind and execute the pgm using Jcls.

VI. Use a join to display the dept. name, the location and the other employee details of all those employees who belong to department no. 10.

- 77 -

Page 78: DB2 Manual

DB2

Appendix B - STANDARDS

- 78 -

Page 79: DB2 Manual

DB2

APPLICATION CONSIDERATIONS

1.1 Keep the application plans small for easy maintenance otherwise, time may be spent unnecessarily to find out as to which of the underlying objects that were used

in the plan that have been changed or dropped at the time of re-binding the plan.

1.2 Avoid the use of the variable length columns unless there is a potential saving. However , when used, place them at the end of the row as this would improve performance and at the same time allow the users the format they find the most convenient.

1.3 Use “not null” for primary keys, “null” for foreign keys and “not null with default” for other colums.

1.4 When using decimal fields, use odd precision i.e., use DEC(7,2) instead of DEC(6,2).

PROGRAMMING CONSIDERATIONS:

Apart from enforcement of host language programming standards, some of the embedded SQL related programming practices are as follows: Avoid the use of select * as this requires the program to have a variable for each

column defined. When table definitions are altered, select * will cause an abend. Use select with a list of column names instead.

Avoid too many joins or subqueries. However a join should be given preference over a subselect.

When binding DB2 programs, cursor stability should be used instead of repeatable read because under cursor stability,DB2 locks the current page only while in RR, DB2 holds the page locks and releases them at the next commit point.

Use validate (bind) instead of validate (run) because validate at run time can cause contention on the catalog tables because requiring more run time resources.

Do not lock table unless approved by the DBA. Host variables must always have the same format as the corresponding table fields.

Preferably use dclgen to copy the generated structure in the program. Never code an arithmetic expression as an operand to be compare d to a column in a

where clause because it degrades the performance of the sql statements. Restrict the use of SELECT, DISTINCT, SELECT ….UNION,ORDER BY AND

GROUP BY because they require DB2 to do an internal sort. Use BETWEEN instead of “>= & <=” Error checking

Every SQL statement execution is checked for the sql return code namely SQLCODE. The check is made immediately after execution and the control is passed to the appropriate section of the code based on the return codes.

- 79 -

Page 80: DB2 Manual

DB2

PERFORMANCE IMPROVEMENT GUIDELINES:

Create more indexes. Index creation is always at the cost of the space and poor performance during inserts,

updates and deletes but access can be made faster by defining suitable indexes. Increase the sub-pages. When locking is in effect, to maximize concurrency, data should be stored over large

number of pages. This can be controlled by increasing the sub-pages. Use acquire(use)/release(commit) on bind. The resources are acquired on use and released on commit. This option keeps the

resources for a shorter duration compared to the option acquire(allocate) / release(de-allocate).

Use validate(bind). This option is preferred to validate(run) since validate(run) would check for validity at bind time and re-check at run time for every run.

Reduce internal DB2 sorts.

- 80 -

Page 81: DB2 Manual

DB2

Appendix C - BIBLOGRAPHY

- 81 -

Page 82: DB2 Manual

DB2

- 82 -