Vous êtes sur la page 1sur 494

IBML

Getting Started with DB2 Stored Procedures:


Give Them a Call through the Network
Silvio Podcameni, Mark Leung, Michael J. Fischer, Gavin Letham

International Technical Support Organization

http://www.redbooks.ibm.com
This book was printed at 240 dpi (dots per inch). The final production redbook with the RED cover will
be printed at 1200 dpi and will provide superior graphics resolution. Please see “How to Get ITSO
Redbooks” at the back of this book for ordering instructions.

SG24-4693-01
IBML
SG24-4693-01
International Technical Support Organization

Getting Started with DB2 Stored Procedures:


Give Them a Call through the Network

March 1998
Take Note!

Before using this information and the product it supports, be sure to read the general information in
Appendix D, “Special Notices” on page 435.

Second Edition (March 1998)

This edition applies to DB2 for MVS/ESA Version 4.1, DB2 Server for OS/390 Version 5 DB2 for OS/2 Version 2.1.1,
DDCS for OS/2 V2.3.1, DB2 for AIX Version 2.1.1, DDCS for AIX Version 2.3.1, DB2 for OS/2 Version 5, DB2 for AIX
Version 5, DB2 for Windows NT Version 5, DB2 for Windows 95 Version 5, and other current versions and releases
of IBM products. Consult the latest edition of the applicable IBM bibliography for current information on products.

Comments may be addressed to:


IBM Corporation, International Technical Support Organization
Dept. QXXE Building 80-E2
650 Harry Road
San Jose, California 95120-6099

When you send information to IBM, you grant IBM a non-exclusive right to use or distribute the information in any
way it believes appropriate without incurring any obligation to you.

 Copyright International Business Machines Corporation 1996 1998. All rights reserved.
Note to U.S. Government Users — Documentation related to restricted rights — Use, duplication or disclosure is
subject to restrictions set forth in GSA ADP Schedule Contract with IBM Corp.
Contents

Figures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi

Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv

Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii
The Team That Wrote This Redbook . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii
Comments Welcome . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix

Chapter 1. Stored Procedures Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1


1.1 What Are Stored Procedures? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 Why Use Stored Procedures? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 Software Prerequisites for Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.4 The Project Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

Chapter 2. DB2 for MVS/ESA, DB2 for OS/390 and Stored Procedures . . . . . . . . . . . . . . . . . . 7
2.1 Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2 Installation Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2.1 DB2-Established Stored Procedures Address Space . . . . . . . . . . . . . . . . . . . . . . . 10
2.2.2 RACF Considerations for DB2-Established Address Space . . . . . . . . . . . . . . . . . . . 11
2.2.3 Serializing Access to Non-DB2 Resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.2.4 Updating Installation Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.3 Administration Tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.3.1 Defining Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.3.2 DB2 Commands Related to Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . 19

Chapter 3. WLM-Established Stored Procedures Address Spaces . . . . . . . . . . . . . . . . . . . . 25


3.1 Introduction to Workload Management (WLM) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.1.1 What is WLM? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.1.2 WLM Definitions Relationships . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.1.3 Classification Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.2 Application Environments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.2.1 Defining the Application Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.2.2 Specifying Application Environments to WLM . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.3 Compatibility Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.4 Goal Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.5 Managing Application Environments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.5.1 The QUIESCE Option . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.5.2 The RESUME Option . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.5.3 The REFRESH Option . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.6 Handling Error Conditions in the Application Environment . . . . . . . . . . . . . . . . . . . . . . 35
3.7 Defining a Service Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.8 Existing Service Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
3.9 Placing WLM JCL Procedure in a PROCLIB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
3.10 Updating SYSIBM.SYSPROCEDURES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
3.11 RACF Considerations for WLM-Established Address Space . . . . . . . . . . . . . . . . . . . . . 53
3.12 Operations and Problem Determination . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
3.13 Experimenting with Goal and Compatibility Modes . . . . . . . . . . . . . . . . . . . . . . . . . . 56
3.13.1 DB2 and WLM Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
3.13.2 Client and Server Programs Used for Testing Purposes . . . . . . . . . . . . . . . . . . . . 57
3.13.3 WLM Goal Mode Using Automatic Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
3.13.4 WLM Compatibility Mode Using Automatic Control . . . . . . . . . . . . . . . . . . . . . . . 58

 Copyright IBM Corp. 1996 1998 iii


3.14 Implementing OS/390 Resource Recovery Services (RRS) Support . . . . . . . . . . . . . . . . 59
3.14.1 RRS Log Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
3.14.2 Activating the CFRM Policy to Support RRS . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
3.14.3 Making the RRS JCL Procedure Available . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
3.14.4 Adding RRS Subsystem Name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
3.14.5 Starting and Stopping RRS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
3.14.6 RRS Error Samples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

Chapter 4. DB2 Common Servers and DB2 UDB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67


4.1 What Are DB2 Common Servers? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
4.2 Features of DB2 Common Servers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
4.3 DB2 Universal Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
4.3.1 DB2 Connect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
4.3.2 Two-Phase Commit Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
4.3.3 Net.Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
4.3.4 DB2 Universal Database (UDB) Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
4.4 Configuring for Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
4.4.1 The Keep DARI Process Indicator (KEEPDARI) . . . . . . . . . . . . . . . . . . . . . . . . . . 72
4.4.2 The Maximum Number of DARI Processes Indicator (MAXDARI) . . . . . . . . . . . . . . . . 74
4.4.3 Viewing and Updating KEEPDARI and MAXDARI . . . . . . . . . . . . . . . . . . . . . . . . . 75
4.5 Fenced and Unfenced Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
4.6 Registering Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
4.6.1 Creating and Updating DB2CLI.PROCEDURES . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
4.6.2 Querying DB2CLI.PROCEDURES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
4.6.3 Columns of the DB2CLI.PROCEDURES Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

Chapter 5. Interfaces to Application Development . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81


5.1 Embedded SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
5.1.1 Static SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
5.1.2 Dynamic SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
5.2 Call Level Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
5.3 Deciding Which Interface to Use . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
5.3.1 Embedded SQL Advantages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
5.3.2 CLI Advantages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
5.3.3 Using Both Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

Chapter 6. Coding Stored Procedures in DB2 on MVS . . . . . . . . . . . . . . . . . . . . . . . . . . . 85


6.1 General Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
6.1.1 Languages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
6.1.2 LE/370 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
6.2 Rules for Coding Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
6.2.1 Statements in Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
6.2.2 Using System-Directed Access with Stored Procedures . . . . . . . . . . . . . . . . . . . . . 87
6.2.3 Stored Procedure Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
6.2.4 Calling Other Programs from a Stored Procedure . . . . . . . . . . . . . . . . . . . . . . . . . 97
6.2.5 Calling a REXX Procedure from a Stored Procedure . . . . . . . . . . . . . . . . . . . . . . . 98
6.3 Stored Procedure Preparation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
6.3.1 JCL for the Stored Procedure Preparation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
6.3.2 Binding the Stored Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
6.3.3 Privileges Required . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
6.3.4 Making Your Stored Procedure Reentrant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
6.3.5 Resident Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
6.3.6 Defining the Stored Procedure to DB2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
6.3.7 Restricting Access to the SYSIBM.SYSPROCEDURES Table . . . . . . . . . . . . . . . . . . . 104

iv Getting Started with DB2 Stored Procedures


Chapter 7. Coding Stored Procedures for DB2 Common Servers and DB2 UDB . . . . . . . . . . . . 105
7.1 Languages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
7.1.1 Supported Languages for DB2 on the AIX Platform . . . . . . . . . . . . . . . . . . . . . . . . 105
7.1.2 Supported Languages for DB2 on the OS/2 Platform . . . . . . . . . . . . . . . . . . . . . . . 105
7.2 Coding Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
7.2.1 Rules for Coding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
7.2.2 Differences between Stored Procedures and Other Programs . . . . . . . . . . . . . . . . . 106
7.2.3 Receiving Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
7.2.4 Nulls to Reduce Network Traffic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
7.3 Stored Procedure Preparation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
7.3.1 Uppercase and Lowercase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
7.3.2 Makefiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
7.3.3 Module Definition File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
7.4 Stored Procedure Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
7.4.1 REXX Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
7.4.2 C Example 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
7.4.3 C Example 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
7.4.4 The SENDDA and SHOWDA Samples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116

Chapter 8. Coding Client Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117


8.1 Calling Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
8.1.1 The SQL CALL Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
8.1.2 Commit and Rollback . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
8.1.3 Using an SQLDA to Pass Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
8.2 SQL CALL Statement in DB2 on the MVS Platform . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
8.2.1 Specifying the Procedure Name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
8.2.2 Specifying the Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
8.2.3 Examples of SQL CALL Statements to Send Parameters . . . . . . . . . . . . . . . . . . . . 122
8.3 SQL CALL Statement in DB2 on the Workstation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
8.3.1 Embedded SQL Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
8.3.2 Examples of Coding the CALL Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
8.3.3 Searching for Stored Procedures in DB2 on the Workstation . . . . . . . . . . . . . . . . . . 126
8.3.4 Invoking Stored Procedures with DARI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
8.4 CLI and ODBC Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
8.5 Stored Procedure Name Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
8.5.1 DB2 on the Workstation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
8.5.2 DB2 on MVS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
8.5.3 DB2 for OS/400 Server (V3.1 or Later) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
8.6 Case Sensitivity and Stored Procedure Name Folding . . . . . . . . . . . . . . . . . . . . . . . . . 129
8.6.1 Case Sensitivity by Platform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
8.6.2 Stored Procedure Name Folding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
8.7 Client Program Preparation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
8.7.1 DB2 on MVS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
8.7.2 DB2 on the Workstation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
8.8 IBM VisualGen and VisualAge for Basic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
8.9 Invoking Stored Procedures with ODBC Escape Clause . . . . . . . . . . . . . . . . . . . . . . . . 135

Chapter 9. Transferring Multiple Result Sets with Stored Procedures . . . . . . . . . . . . . . . . . . 137


9.1 DB2 CLI/ODBC for DB2 on the Workstation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
9.1.1 Examples Using CLI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
9.1.2 Setting Up a Loopback Connection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
9.2 Multiple Result Sets in DB2 for OS/390 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
9.2.1 Multiple Result Set Stored Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
9.2.2 Writing the DB2 for OS/390 Client to Receive Result Sets . . . . . . . . . . . . . . . . . . . . 152
9.2.3 SQL Extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152

Contents v
9.2.4 DESCRIBE CURSOR Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
9.2.5 Summary of Coding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
9.2.6 Example of Client Program Processing a Single Result Set . . . . . . . . . . . . . . . . . . . 164
9.2.7 Example of Client Program Processing Multiple Result Sets . . . . . . . . . . . . . . . . . . 166
9.2.8 Reasons Why Cursors May Not Be Returned to Client . . . . . . . . . . . . . . . . . . . . . . 170
9.2.9 Example of Client Program Using the DESCRIBE CURSOR SQL Statement . . . . . . . . . 170
9.2.10 SQLCODEs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
9.3 Blocking Rows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
9.3.1 The TR0C2CC2 Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
9.3.2 The TR0C2S Stored Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183

Chapter 10. Coding Considerations for Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187


10.1 ODBC Applications: Setting the Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
10.2 Visual Basic Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
10.2.1 String Data Truncation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
10.2.2 How Microsoft Visual Basic Unicode Affects the Client/Server . . . . . . . . . . . . . . . . 191
10.2.3 RDO Program and SQL_NO_DATA_FOUND Error on the ODBC SQL_SETConnect . . . . . 192
10.2.4 Result Sets Column Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
10.3 Sample ODBC Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
10.3.1 Setting Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
10.3.2 Connecting to the Database Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
10.3.3 Calling the Stored Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
10.3.4 Other Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
10.3.5 Setting Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
10.3.6 Connecting to a Database Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
10.3.7 Calling the Stored Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
10.3.8 Error Handling and Status Checking of ODBC Functions . . . . . . . . . . . . . . . . . . . . 198
10.3.9 Transaction Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
10.3.10 Program Termination . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
10.4 CLI Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
10.5 PowerBuilder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
10.5.1 Configuring CLI/ODBC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
10.5.2 PowerBuilder Client Using Parameters - No Result Sets . . . . . . . . . . . . . . . . . . . . 208
10.5.3 PowerBuilder Client for Single Result Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
10.5.4 PowerBuilder Client for Multiple Result Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
10.6 C Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220

Chapter 11. CLI on DB2 Version 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221


11.1 Introduction to CLI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
11.2 Implementing CLI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
11.3 How to Invoke a Stored Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
11.3.1 Multiple Result Sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
11.3.2 Executing the Client Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
11.4 Coding the Stored Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
11.4.1 Receiving Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
11.4.2 Result Sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
11.5 Precompile/Bind Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
11.6 Compiling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
11.7 Prelinking and Link-editing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
11.8 SYSIBM.SYSPROCEDURES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
11.9 Stored Procedure Address Space Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
11.10 Problem Determination Tracing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
11.10.1 Using the CLI Application Trace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
11.10.2 Using the CLI Diagnosis Trace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
11.10.3 Running with Traces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231

vi Getting Started with DB2 Stored Procedures


11.10.4 Specifying LE Run-Time Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
11.11 Running the CLI Sample Stored Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
11.12 Porting CLI Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
11.12.1 Porting a Sample Result Set CLI Application from AIX to OS/390 . . . . . . . . . . . . . . 236
11.12.2 Differences in Handling Result Sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
11.12.3 CLI Stored Procedure Coding Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . 240
11.12.4 Miscellaneous Programming Hints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249

Chapter 12. Recoverable Resource Manager Services Attachment Facility . . . . . . . . . . . . . . . 255


12.1 Prerequisite Knowledge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
12.2 Capabilities of RRSAF Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
12.3 Task Capabilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
12.4 Programming Languages Supported . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
12.5 Program Size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
12.6 RRSAF Use of Load . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
12.7 Commit and Rollback Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
12.8 Run Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
12.9 RRSAF Language Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
12.10 How to Use RRSAF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
12.10.1 IDENTIFY Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
12.10.2 SIGNON Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
12.10.3 AUTH SIGNON Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
12.10.4 CREATE THREAD Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
12.10.5 TERMINATE THREAD Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
12.10.6 TERMINATE IDENTIFY Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
12.10.7 TRANSLATE Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
12.11 Sample JCL to Use RRSAF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
12.12 Sample Program RRSAFCOB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
12.13 Common RRSAF Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
12.13.1 IDENTIFY Return Code 8 Reason Code 15925393 . . . . . . . . . . . . . . . . . . . . . . . . 263
12.13.2 IDENTIFY Return Code 8 Reason Code 15925250 . . . . . . . . . . . . . . . . . . . . . . . . 263
12.13.3 IDENTIFY Return Code 12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
12.13.4 CREATE THREAD Return Code 12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264

Chapter 13. Accessing Non-DB2 Resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265


13.1 Accessing CICS Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
13.2 Using EXCI in a Stored Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266
13.2.1 Sample Stored Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266
13.2.2 Program Preparation for EXCI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267
13.2.3 CICS Table Definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
13.3 Accessing IMS Databases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
13.3.1 Using Database Resource Adapter Callable Interface . . . . . . . . . . . . . . . . . . . . . . 273
13.3.2 Including APPC Code in the Stored Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . 291
13.4 Using MQSeries for Enqueued Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
13.5 APPC to Access Transactions from a Stored Procedure . . . . . . . . . . . . . . . . . . . . . . . 292
13.5.1 Preparing IMS for APPC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
13.5.2 IMSBMCBM, IMSBMS, and PART . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
13.5.3 IMUBMCBM, IMUBMS and IMS IVP Transactions . . . . . . . . . . . . . . . . . . . . . . . . 295
13.5.4 IMDBMCBM, IMDBMS and IMS IVP Transactions . . . . . . . . . . . . . . . . . . . . . . . . 296

Chapter 14. DB2 Common Server Performance Considerations . . . . . . . . . . . . . . . . . . . . . 299


14.1 Traditional Coding and Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
14.2 Dynamic and Static SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
14.3 Using Compound SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
14.4 Using Unfenced Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302

Contents vii
14.5 Embedded SQL and CLI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
14.6 The KEEPDARI Indicator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
14.7 Keeping Stored Procedures in Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
14.8 Performance Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304

Chapter 15. Debugging DB2 on MVS Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . 305


15.1 CODE/370 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
15.2 CODE/370 Installation Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
15.2.1 Prerequisites for Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
15.2.2 Communications Configuration for CODE/370 . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
15.3 Preparing to Debug Your Stored Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
15.3.1 TEST Compiler Option Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
15.3.2 Viewing the Source Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
15.4 Using the CODE/370 Debug Tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
15.4.1 TEST Run-Time Option . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
15.4.2 Debug Tool Session Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
15.4.3 PWS Debug Tool Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323
15.4.4 Using the Batch Debug Tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328

Chapter 16. IBM VisualAge for Basic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331


16.1 Functions and Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
16.1.1 Environments and Platforms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
16.1.2 Advantages of Using VAB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
16.2 Creating Stored Procedures with VAB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
16.2.1 Preparing the Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
16.2.2 The VAB Language . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
16.2.3 Editing a Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
16.2.4 Developing the Stored Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335
16.2.5 Developing the Client Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
16.3 Debugging and Testing with VAB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340
16.3.1 Setting Breakpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340
16.3.2 The Inspector Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
16.3.3 The Remote Debugger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343
16.4 Testing Code Using QuickTest Dialogs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343
16.5 VAB on the World Wide Web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345

Appendix A. Sample Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347


A.1 Naming Convention . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348
A.2 AIX Samples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351
A.2.1 C Samples on AIX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351
A.2.2 CLI Samples on AIX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351
A.2.3 REXX Samples on AIX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352
A.3 OS/2 Samples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353
A.3.1 C Samples on OS/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
A.3.2 CLI Programs on OS/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
A.3.3 COBOL Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355
A.3.4 REXX Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356
A.3.5 VAB Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356
A.4 Windows Samples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358
A.4.1 C Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
A.4.2 Visual Basic Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
A.4.3 COBOL Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361
A.5 MVS Samples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363
A.6 Using Sample JCL Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368
A.7 C / C + + Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370

viii Getting Started with DB2 Stored Procedures


A.8 CLI Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371
A.9 COBOL Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372
A.10 PL/I Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375

Appendix B. Performance Benchmark and Capacity Planning . . . . . . . . . . . . . . . . . . . . . . 377


B.1 Configurations and Specifications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377
B.2 Workload Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380
B.2.1 Transaction Characteristics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380
B.2.2 Table Characteristics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381
B.2.3 Locking Definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381
B.2.4 Physical Location . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 382
B.2.5 Buffer Pool Allocation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 382
B.3 Results for DDCS for OS/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383
B.3.1 Client Equivalence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384
B.3.2 CPU Utilization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385
B.3.3 Network . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386
B.3.4 DB2 Utilization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389
B.3.5 Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389
B.4 Results for DDCS for AIX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398
B.4.1 Client Equivalence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398
B.4.2 CPU Utilization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399
B.4.3 Network . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401
B.4.4 DB2 Utilization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403
B.4.5 Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
B.5 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 412
B.6 Other Sources of Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413

Appendix C. DB2 Connect Result Set Study . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415


C.1 Configuration and Specifications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415
C.2 Workload Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416
C.2.1 Transaction Characteristics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417
C.2.2 Table Characteristics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418
C.2.3 Locking Definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418
C.2.4 Buffer Pool Allocation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418
C.3 Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419
C.3.1 Client Equivalence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419
C.3.2 CPU Utilization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420
C.3.3 Network . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422
C.3.4 Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423
C.4 DB2 Connect Environment Tuning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428
C.4.1 Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429
C.4.2 DB2 Connect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430
C.4.3 Network . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431
C.5 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 432
C.6 Other Sources of Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433

Appendix D. Special Notices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 435

Appendix E. Related Publications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439


E.1 International Technical Support Organization Publications . . . . . . . . . . . . . . . . . . . . . . 439
E.2 Redbooks on CD-ROMs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439
E.3 Other Publications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439

How to Get ITSO Redbooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443


How IBM Employees Can Get ITSO Redbooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443

Contents ix
How Customers Can Get ITSO Redbooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444
IBM Redbook Order Form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447

ITSO Redbook Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449

x Getting Started with DB2 Stored Procedures


Figures

1. Processing without Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2


2. Processing with Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
3. The Project Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
4. DB2 Stored Procedure Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
5. Stored Procedures Parameters Panel (DSNTIPX) - DB2 Version 4 . . . . . . . . . . . . . . . . . . 9
6. Stored Procedures Parameters Panel (DSNTIPX) - DB2 Version 5 . . . . . . . . . . . . . . . . . 10
7. DB2-Established Stored Procedures Address Space JCL Procedure . . . . . . . . . . . . . . . 11
8. Changing DSNTIJUZ Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
9. Changing the Number of Concurrent TCBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
10. PARMLIST Column String Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
11. START PROCEDURE Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
12. STOP PROCEDURE Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
13. DISPLAY PROCEDURE Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
14. Service Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
15. Workload, Service Classes, and Service Class Periods . . . . . . . . . . . . . . . . . . . . . . . 27
16. Summary of the Performance Goals of a Service Class . . . . . . . . . . . . . . . . . . . . . . . 28
17. Assigning Performance Goals to Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . 29
18. SYSIBM.SYSPROCEDURES, Application Environment, and JCL Procedure . . . . . . . . . . . . 31
19. An Example of the Application-Environment Panel . . . . . . . . . . . . . . . . . . . . . . . . . . 31
20. Relationship Among WLM Definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
21. WLM First Panel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
22. Choose Service Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
23. Definition Menu Panel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
24. Create a Service Policy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
25. Service Policy Selection List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
26. Selecting Workload . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
27. Create a Workload . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
28. Workload Selection List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
29. Definition Menu - Create Service Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
30. Create a Service Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
31. Choose a Goal Type Pop-Up Window - Period 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
32. Average Response Time Goal Pop-Up Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
33. Create a Service Class Panel - Period 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
34. Choose a Goal Type for Period 2 Pop-Up Window . . . . . . . . . . . . . . . . . . . . . . . . . . 43
35. Average Response Time Goal Pop-Up Window - Period 2 . . . . . . . . . . . . . . . . . . . . . . 44
36. Create a Service Class Panel - 2 Service Class Periods . . . . . . . . . . . . . . . . . . . . . . . 44
37. Choose a Goal Type Pop-Up Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
38. Definition Menu - Classification Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
39. Subsystem Type Selection List for Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
40. Create Rules for the Subsystem Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
41. Modify Rules for the Subsystem Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
42. Definition Menu - Application Environments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
43. Create an Application Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
44. Application Environment Selection List Panel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
45. Utility Pull-Down Menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
46. Policy Selection List Panel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
47. Choose Service Definition Panel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
48. SQL Template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
49. Sample Scenario with DB2 Connect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
50. Sample Scenario with Net.Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
51. DB2 UDB Control Center Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

 Copyright IBM Corp. 1996 1998 xi


52. KEEPDARI Set to NO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
53. KEEPDARI Set to YES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
54. Configuring for Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
55. Fenced Stored Procedures (IPC=Interprocess Communication) . . . . . . . . . . . . . . . . . . 76
56. Unfenced Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
57. Format of PARM_LIST Column . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
58. Use of Three-Part Names in Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
59. Client Program Restrictions (Scenario 1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
60. Client Program Restrictions (Scenario 2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
61. Client Program Restrictions (Scenario 3) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
62. SIMPLE Linkage Convention . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
63. SIMPLE WITH NULLS Linkage Convention . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
64. Assigning Values to Input Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
65. Assigning Values to Output Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
66. Calling External Programs from Stored Procedures (Example 1) . . . . . . . . . . . . . . . . . . 97
67. Calling External Programs from Stored Procedures (Example 2) . . . . . . . . . . . . . . . . . . 98
68. Stored Procedure Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
69. Using the DB2 Administration Tool to Manage Stored Procedures . . . . . . . . . . . . . . . . 104
70. Return with SQLZ_DISCONNECT_PROC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
71. Return with SQLZ_HOLD_PROC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
72. Basic Client Application Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
73. Passing Stored Procedure Name (Host Variable) and Parameters (SQLDA) . . . . . . . . . . . 119
74. SQL CALL Statement Syntax in DB2 on the MVS Platform . . . . . . . . . . . . . . . . . . . . . 120
75. The SQL CALL Statement for Embedded SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
76. SQLeproc() and the SQL CALL Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
77. CALL Statement Syntax Used in CLI and ODBC . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
78. DB2 CLI and ODBC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
79. Multiple Result Sets with CLI. Renamed client to MR3C2CC2 / server MR3C2S . . . . . . . . . 137
80. Retrieving One Result Set with CLI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
81. Relationship Among the New SQL Statements and the New Data Type . . . . . . . . . . . . . 153
82. DESCRIBE PROCEDURE Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
83. DESCRIBE Cursor Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
84. Blocking Rows. Renamed Client to TR0C2CC2 / Server TROC2S . . . . . . . . . . . . . . . . . 180
85. ODBC.INI File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
86. ODBC Working Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
87. Define and Initialize Parameters Used by the Stored Procedure . . . . . . . . . . . . . . . . . . 194
88. Defining Variables for Handles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
89. Defining a Return Code Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
90. Connection Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
91. Allocating Handles and Connecting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
92. Issuing the CALL Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
93. Checking ODBC Return Codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
94. Sample Visual Basic Error Routine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
95. Freeing Handles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
96. CLI Sample Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
97. The DB2CLI.INI File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
98. Specify ODBC Drivers During PowerBuilder Install . . . . . . . . . . . . . . . . . . . . . . . . . . 206
99. Update Database Properties Using CCA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
100. Select CLI/ODBC Settings for a Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
101. Invoke CLI/ODBC Advanced Settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
102. Select User Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
103. Create New User Object: Standard Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
104. Select Standard Class Type: Transaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
105. Declare Local External Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
106. Select Stored Procedure from List Box . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211

xii Getting Started with DB2 Stored Procedures


107. PowerScript Sample: Process Stored Procedures Using Parameters . . . . . . . . . . . . . . . 212
108. How a DataWindow Object Is Related to a DataWindow Control . . . . . . . . . . . . . . . . . . 214
109. Design of w_main_window_1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
110. Code Fragment for Single Result Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
111. Modify Result Set Description for qry12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
112. Design of w_qry22 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
113. Code Fragment for Multiple Result Sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
114. Modify Result Set Description for qry22 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
115. Specify Retrieve Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
116. C/CLI Compile: JCL Fragment Showing Parameters . . . . . . . . . . . . . . . . . . . . . . . . . 224
117. JCL Procedure to Compile a CLI Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
118. Example of JCL Procedure for Stored Procedures Address Space . . . . . . . . . . . . . . . . 229
119. Using CLI INI File to Enable Diagnosis and Application Trace . . . . . . . . . . . . . . . . . . . 230
120. Execute DSNAOTRC to Produce FMT and FLW Reports . . . . . . . . . . . . . . . . . . . . . . . 231
121. CLI Application Trace Output Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
122. Formatted Flow Report (FLW) for CLI Diagnosis Trace Example . . . . . . . . . . . . . . . . . . 233
123. Formatted Detail Report (FMT) for CLI Diagnosis Trace Example . . . . . . . . . . . . . . . . . 233
124. Specifying LE Run-Time Options Using DB2 Administration Tool . . . . . . . . . . . . . . . . . . 234
125. Excerpt from Specifying LE Run-Time Option RPTSTG(ON) . . . . . . . . . . . . . . . . . . . . . 234
126. Using Sample mrspcli.c and sr1.c as Clients . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
127. UDB to UDB over Private Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
128. UDB to UDB over DRDA Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
129. UDB to OS/390 (CLI) Using DRDA Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
130. SR1OMS Source Code: CLI Stored Procedure in C . . . . . . . . . . . . . . . . . . . . . . . . . . 240
131. Sample JCL to Invoke EDCICONV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
131. Sample JCL to Convert Coded Chracter Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
132. Translating Code Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
133. System Management Panel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
134. System Environments Panel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
135. Select Change/Show Primary Language Environment . . . . . . . . . . . . . . . . . . . . . . . . 252
136. Change/Show Cultural Convention, Language, or Keyboard Panel . . . . . . . . . . . . . . . . 253
137. DRA Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
138. CODE/370 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
139. CODE/370 PWS Debug Tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
140. SNA Features List Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
141. Transaction Program Definition Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
142. Additional TP Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310
143. TEST Option Syntax: C Compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
144. TEST Option Syntax: COBOL and PL/I Compilers . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
145. TEST Run-time Option Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
146. PWS Debug Tool Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
147. Beginning the Debug Session . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
148. Setting a Breakpoint in the PWS Debug Tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319
149. Checking the Value of a Variable (Part 1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
150. Checking the Value of a Variable (Part 2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
151. Changing the Value of a Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
152. Copying a Command from the Log Area . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
153. Checking the New Value of a Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322
154. Entering the Wait State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322
155. CODE-LISTING Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323
156. CODE-LISTING Window: Setting Breakpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
157. Displaying the Value of a Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
158. Step/Run Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325
159. Step Over Push Button Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325
160. Step Return Push Button Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326

Figures xiii
161. Global Monitor List Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326
162. Debug Tool Command Log Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
163. Selecting the Stored Procedures Catalog Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
164. Stored Procedure Catalog Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
165. IBM VAB Window: Salary Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
166. The VAB Code Editor Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335
167. Stored Procedure Definition Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
168. Local Call Using a Subprocedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
169. Remote Call Using a Stored Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339
170. Setting Breakpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
171. The Inspector Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
172. Using the Immediate Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343
173. The qtText2 QuickTest Dialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
174. The qtArray QuickTest Dialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
175. The QuickTest SmartGuide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345
176. Client Program Naming Convention . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349
177. Stored Procedure Naming Convention . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349
178. Sample JCL sampbld.jcl to Rebuild Sample Data Sets . . . . . . . . . . . . . . . . . . . . . . . . 365
179. Configuration with DB2 for MVS/ESA and DDCS for OS/2 . . . . . . . . . . . . . . . . . . . . . . 378
180. Configuration with DB2 for MVS/ESA and DDCS for AIX . . . . . . . . . . . . . . . . . . . . . . . 379
181. CPU Utilization in Relation to Throughput: DDCS for OS/2 . . . . . . . . . . . . . . . . . . . . . 385
182. Configuration with 3174: DDCS for OS/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 388
183. Aggregate Response Time: DB2 for MVS/ESA and DDCS for OS/2 . . . . . . . . . . . . . . . . 390
184. Response Time for Transaction Tx1: DDCS for OS/2 . . . . . . . . . . . . . . . . . . . . . . . . . 391
185. Response Time for Transaction Tx2: DDCS for OS/2 . . . . . . . . . . . . . . . . . . . . . . . . . 392
186. Response Time for Transaction Tx3: DDCS for OS/2 . . . . . . . . . . . . . . . . . . . . . . . . . 393
187. Response Time for Transaction Tx4: DDCS for OS/2 . . . . . . . . . . . . . . . . . . . . . . . . . 394
188. Response Time for Transaction Tx5: DDCS for OS/2 . . . . . . . . . . . . . . . . . . . . . . . . . 395
189. Response Time for Transaction Tx6: DDCS for OS/2 . . . . . . . . . . . . . . . . . . . . . . . . . 396
190. Response Time for Transaction Tx7: DDCS for OS/2 . . . . . . . . . . . . . . . . . . . . . . . . . 397
191. CPU Utilization in Relation to Throughput: DDCS for AIX . . . . . . . . . . . . . . . . . . . . . . 400
192. Configuration with 3174: DDCS for AIX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402
193. Aggregate Response Time: DDCS for AIX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
194. Response Time for Transaction Tx1: DDCS for AIX . . . . . . . . . . . . . . . . . . . . . . . . . . 405
195. Response Time for Transaction Tx2: DDCS for AIX . . . . . . . . . . . . . . . . . . . . . . . . . . 406
196. Response Time for Transaction Tx3: DDCS for AIX . . . . . . . . . . . . . . . . . . . . . . . . . . 407
197. Response Time for Transaction Tx4: DDCS for AIX . . . . . . . . . . . . . . . . . . . . . . . . . . 408
198. Response Time for Transaction Tx5: DDCS for AIX . . . . . . . . . . . . . . . . . . . . . . . . . . 409
199. Response Time for Transaction Tx6: DDCS for AIX . . . . . . . . . . . . . . . . . . . . . . . . . . 410
200. Response Time for Transaction Tx7: DDCS for AIX . . . . . . . . . . . . . . . . . . . . . . . . . . 411
201. Configuration with DB2 Connect for NT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415
202. CPU Utilization in Relation to Throughput - DB2 Connect for NT . . . . . . . . . . . . . . . . . . 421
203. Response Time for Transaction FEWROWS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423
204. Response Time for Transaction MANYROWS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424
205. Response Time for Transaction Qry1_2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425
206. Response Time for Transaction Qry1_9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426
207. Response Time for Transaction Qry1_17 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427
208. Response Time Comparison (Qry1_2, Qry1_9, Qry1_17) . . . . . . . . . . . . . . . . . . . . . . . 428

xiv Getting Started with DB2 Stored Procedures


Tables

1. Hardware and Software Used - First Edition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5


2. Hardware and Software Used - Second Edition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3. Sample SYSIBM.SYSPROCEDURES Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4. Sample Setup To Test Same Program in DB2- and WLM- Address Spaces . . . . . . . . . . . 52
5. Definitions of Stored Procedure Parameters in C, COBOL, and PL/I . . . . . . . . . . . . . . . 90
6. Null Parameters and SIMPLE Linkage Convention . . . . . . . . . . . . . . . . . . . . . . . . . . 92
7. Null Parameters and SIMPLE WITH NULLS Linkage Convention . . . . . . . . . . . . . . . . . . 92
8. How DB2 for MVS V4 and DB2 for OS/390 V5 Treat Lowercase Names . . . . . . . . . . . . . . 129
9. Stored Procedure Name Folding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
10. Package Creation Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
11. Visual Basic Sample Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
12. Parameter Characteristics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
13. C/C++ Compiler Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
14. Jobs for CLI Sample Stored Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
15. Overview of Support Related to Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . 236
16. Visible Differences in Result Sets Behavior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
17. How NULL Connections Behave for DB2 for OS/390 V5 . . . . . . . . . . . . . . . . . . . . . . . 249
18. POST Codes for Types of DB2 Termination . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
19. AIB Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
20. AIB Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
21. New Reason and Return Codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
22. Existing Reason and Return Codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
23. Sample Programs Used for Performance Measurement . . . . . . . . . . . . . . . . . . . . . . . 299
24. Stored Procedures and Traditional Coding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
25. Static and Dynamic SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
26. Compound, Static, and Dynamic SQL Comparison . . . . . . . . . . . . . . . . . . . . . . . . . . 301
27. Unfenced Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
28. Embedded Dynamic SQL and CLI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
29. KEEPDARI Measurements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
30. Keeping a Stored Procedure in Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
31. Description of the Programs Used in the AIX Environment . . . . . . . . . . . . . . . . . . . . . 353
32. Description of the Programs Used in the OS/2 Environment . . . . . . . . . . . . . . . . . . . . 356
33. Description of the Programs Used in the Windows Environment . . . . . . . . . . . . . . . . . . 362
34. JCL Procedures Used for Our Samples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
35. Description of the C Programs Used in the OS/390 Environment . . . . . . . . . . . . . . . . . . 371
36. CLI Samples on OS/390 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371
37. COBOL Samples on OS/390 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372
38. PL/I Samples on OS/390 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375
39. Description of the REXX Programs Used for APPC/IMS Verification . . . . . . . . . . . . . . . . 376
40. Table Characteristics for DB2 for MVS/ESA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381
41. Physical Storage Characteristics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 382
42. Buffer Pool Characteristics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 382
43. Number of Clients in Relation to Aggregate Throughput: Transactions per Second (DDCS for
OS/2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384
44. CPU Utilization in Relation to Throughput: DDCS for OS/2 . . . . . . . . . . . . . . . . . . . . . 385
45. RAM Utilization on PC500 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386
46. 3745 Utilization in Relation to Throughput: DDCS for OS/2 . . . . . . . . . . . . . . . . . . . . . 387
47. LAN Utilization in Relation to Throughput: DDCS for OS/2 . . . . . . . . . . . . . . . . . . . . . 389
48. Potential Lock Contention for Transaction Tx1: DDCS for OS/2 . . . . . . . . . . . . . . . . . . . 391
49. Potential Lock Contention for Transaction Tx2: DDCS for OS/2 . . . . . . . . . . . . . . . . . . . 392
50. Potential Lock Contention for Transaction Tx3: DDCS for OS/2 . . . . . . . . . . . . . . . . . . . 394

 Copyright IBM Corp. 1996 1998 xv


51. Potential Lock Contention for Transaction Tx4: DDCS for OS/2 . . . . . . . . . . . . . . . . . . . 395
52. Potential Lock Contention for Transaction Tx5: DDCS for OS/2 . . . . . . . . . . . . . . . . . . . 395
53. Potential Lock Contention for Transaction Tx6: DDCS for OS/2 . . . . . . . . . . . . . . . . . . . 396
54. Potential Lock Contention for Transaction Tx7: DDCS for OS/2 . . . . . . . . . . . . . . . . . . . 398
55. Number of Clients in Relation to Aggregate Throughput: Transactions per Second (DDCS for
AIX) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399
56. CPU Utilization in Relation to Throughput: DDCS for AIX . . . . . . . . . . . . . . . . . . . . . . 400
57. RAM Utilization on C10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400
58. 3745 Utilization in Relation to TPS: DDCS for AIX . . . . . . . . . . . . . . . . . . . . . . . . . . . 401
59. LAN Utilization in Relation to Throughput: DDCS for AIX . . . . . . . . . . . . . . . . . . . . . . 403
60. Potential Lock Contention for Transaction Tx1: DDCS for AIX . . . . . . . . . . . . . . . . . . . . 405
61. Potential Lock Contention for Transaction Tx2: DDCS for AIX . . . . . . . . . . . . . . . . . . . . 406
62. Potential Lock Contention for Transaction Tx3: DDCS for AIX . . . . . . . . . . . . . . . . . . . . 408
63. Potential Lock Contention for Transaction Tx4: DDCS for AIX . . . . . . . . . . . . . . . . . . . . 409
64. Potential Lock Contention for Transaction Tx5: DDCS for AIX . . . . . . . . . . . . . . . . . . . . 409
65. Potential Lock Contention for Transaction Tx6: DDCS for AIX . . . . . . . . . . . . . . . . . . . . 410
66. Potential Lock Contention for Transaction Tx7: DDCS for AIX . . . . . . . . . . . . . . . . . . . . 412
67. Table Characteristics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418
68. Buffer Pool Characteristics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418
69. Number of Clients in Relation to Aggregate Throughput (TPS) . . . . . . . . . . . . . . . . . . . 420
70. CPU Utilization in Relation to TPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420
71. LAN Utilization in Relation to TPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422

xvi Getting Started with DB2 Stored Procedures


Preface

This redbook is the result of a residency project conducted at the IBM International Technical Support
Organization (ITSO) San Jose Center. The project tested and implemented stored procedures
executing in DB2 for MVS/ESA, DB2 for OS/390, DB2 for AIX, DB2 for OS/2, and DB2 for Windows NT
servers. Information is provided to guide the reader through the steps required to implement stored
procedures. The material is based on the actual tests performed and experience gained during the
project.

This redbook is written for IBM technical professionals and customer technical personnel responsible
for implementing stored procedures locally or in a client/server environment. A background in
programming, Distributed Relational Database Architecture (DRDA) connectivity among IBM relational
database products, and IBM relational database products and their associated operating systems is
assumed.

The Team That Wrote This Redbook

This redbook was produced by a team of specialists from around the world working at the International
Technical Support Organization San Jose Center.

Silvio Podcameni, a Data Management Specialist for DB2 and DRDA, has been on assignment at the
International Technical Support Organization San Jose Center since August 1994. During his
assignment, he has led projects to produce DRDA and DB2 for MVS/ESA redbooks on such topics as
security, stored procedures, connectivity, and data sharing. Silvio has also conducted workshops
worldwide on DB2 for MVS/ESA data sharing recovery, client/server features of DB2 for OS/390 Server
Version 5, and connectivity. Before his assignment he worked for the Open Systems Center in Brazil
as a DB2 and DRDA specialist.

Mark Leung is a Systems Specialist working for IBM Global Services Australia in Sydney. He joined
IBM Australia in 1989, first working on application development and maintenance, and subsequently as
a DB2 database administrator. During 1996 and 1997, Mark worked at the IBM Toronto Laboratory on
system test for DB2 Universal Database. He is also the co-author of the redbook Visual PL/I for OS/2 .

Michael J. Fischer is a DB2 Technical Specialist, working for Santa Teresa Laboratory, in San Jose,
CA. He joined IBM in 1996 and since then has been responsible for supporting DB2 Data Sharing
customers in the database and application development areas, in Minneapolis, Minnesota. Michael
has aided the implementation of several DB2 Data Sharing systems for customers in Minnesota.

Gavin Letham is a Staff Software Analyst, working at the IBM Toronto Laboratory in Toronto, Ontario,
Canada. He joined IBM in 1993 working in Customer Support for DB2. He has spent the last year
testing DRDA connectivity for DB2 UDB from various workstation platforms.

The authors of the first edition of this document are:

Silvio Podcameni
International Technical Support Organization, San Jose Center

Boudewijn de Bliek
IBM Belgium

Maria Marcela Toledo Valle


IBM Mexico

 Copyright IBM Corp. 1996 1998 xvii


Ricardo Darriba Macedo
IBM Brazil

The technical report presented in Appendix B, “Performance Benchmark and Capacity Planning” on
page 377 is the result of a project conducted at the IBM Santa Teresa Laboratory. This report was
written by:
• Robert Gilles
• Todd Munk
• Hugh Smith
The authors of the technical report thank the following people for the invaluable advice and guidance
provided in the production of the report: Jerry Heglar, IBM Santa Teresa Laboratory; Akira Shibamiya,
IBM Santa Teresa Laboratory; Mark Ryan, IBM Application Business Systems; Serge Limoges, IBM
Toronto Laboratory; and Bill Wilkins, IBM Toronto Laboratory.

The technical report presented in Appendix C, “DB2 Connect Result Set Study” on page 415 is the
result of a project conducted at the IBM Santa Teresa Laboratory. This report was written by:
• Robert Gilles
• Todd Munk
The authors of the technical report thank the following people for the invaluable advice and guidance
provided in the production of the report: Jerry Heglar, Serge Limoges, IBM Toronto Laboratory; Hugh
Smith, and Peter Shum, IBM Toronto Laboratory.

Thanks to the following people for the invaluable advice and guidance provided in the production of
this document:

At IBM Santa Teresa Laboratory:


Curt L. Cotner
Virginia Rhodas
Robert Gilles
Todd Munk
Jerry Goldsmith
Peggy Abelite
Thomas Eng
Hugh Smith
Alice Crema
Wendy L. Koontz
Marichu Scanlon
Jean Nardi
Thomas Sharp
Cherri Vidmar

At IBM Toronto Laboratory

Robert Begg
Nuzio Ruffolo
Frankie Sun

At IBM Strategic Application Evaluation Test

John F. Betz

At ITSO San Jose Center

xviii Getting Started with DB2 Stored Procedures


Hanspeter Nagel

Thanks also to Maggie Cutler, Shirley Weinland Hentzell, and Gail Wojton for their editorial assistance.

Comments Welcome

Your comments are important to us!

We want our redbooks to be as helpful as possible. Please send us your comments about this or other
redbooks in one of the following ways:
• Fax the evaluation form found in “ITSO Redbook Evaluation” on page 449 to the fax number shown
on the form.
• Use the electronic evaluation form found on the Redbooks Web sites:
For Internet users http://www.redbooks.ibm.com
For IBM Intranet users http://w3.itso.ibm.com
• Send us a note at the following address:
redbook@vnet.ibm.com

Preface xix
xx Getting Started with DB2 Stored Procedures
Chapter 1. Stored Procedures Overview

In this chapter, we describe how stored procedures can be used for applications running in a
client/server environment and explain the advantages of using this technique.

1.1 What Are Stored Procedures?

Stored procedures are user-written structured query language (SQL) programs that are stored at the
DB2 server and can be invoked by client applications. A stored procedure can contain most
statements that an application program usually contains. Stored procedures can execute SQL
statements at the server as well as application logic for a specific function.

A stored procedure can be written in many different languages, such as COBOL, OO COBOL, C, C++,
PL/I, FORTRAN, Assembler, and REXX. The language in which stored procedures are written depends
on the platform where the DB2 server is installed.

Local client applications, remote Distributed Relational Database Architecture (DRDA), or remote data
services (private protocol) can invoke the stored procedure by issuing the SQL CALL statement. The
SQL CALL statement is part of the International Organization for Standardization/American National
Standards Institute (ISO/ANSI) proposal for SQL3, an open solution for invoking stored procedures
among database management system vendors that support the SQL ISO/ANSI standard.

The client program can pass parameters to the stored procedure and receive parameters from the
stored procedure.

The DRDA architecture allows SQL CALL statements to use static or dynamic SQL. The version of the
products used during this project only supports the SQL CALL statement as static SQL. Nevertheless,
parameters in the CALL statement, including the stored procedure name, can be supplied at execution
time. Thus, you can use the SQL CALL statement to dynamically invoke any procedure supported by
DB2.

The client program and the stored procedure do not have to be written in the same programming
language. For example, a C client program can invoke a COBOL stored procedure.

The following DB2 servers currently support DRDA stored procedures:


• DB2 for OS/2
• DB2 for AIX
• DB2 for Windows NT
• DB2 for HP-UX
• DB2 for Solaris
• DB2 Universal Database (DB2 UDB)
• DB2 for OS/400
• DB2 for MVS/ESA
• DB2 for OS/390

In this book, we focus on stored procedures running on the following platforms:


• MVS
• AIX

 Copyright IBM Corp. 1996 1998 1


• OS/2
• Windows/NT

1.2 Why Use Stored Procedures?

In previous releases of DRDA, the client system performed all application logic. The server was
responsible only for SQL processing on behalf of the client. In such an environment, all database
accesses must go across the network, resulting in poor performance in some cases. Figure 1 shows
an example of the processing for a client/server application without using stored procedures.

Figure 1. Processing without Stored Procedures

This is a relatively simple model, which makes the application program easy to design and implement.
Because all application code resides at the client, a single application programmer can take
responsibility for the entire application. However, there are some disadvantages to using this
approach.

Because the application logic runs only on the client workstations, additional network input/output (I/O)
operations are required for most SQL requests. These additional operations can result in poor
performance. This approach also requires the client program to have detailed knowledge of the
server′s database design. Thus, every change in the database design at the server requires a
corresponding change in all client programs accessing the database. Also, because the programs run
at the client workstations, it is often complicated to manage and maintain the copies there.

Stored procedures enable you to encapsulate many of your application′s SQL statements into a
program that is stored at the DB2 server. The client can invoke the stored procedure by using only one
SQL statement, thus reducing the network traffic to a single send and receive operation for a series of
SQL statements. It is also easier to manage and maintain programs that run at the server than it is to
manage and maintain many copies at the client machines.

Stored procedures enable you to split the application logic between the client and the server. You can
use this technique to prevent the client application from manipulating the contents of sensitive server
data. You can also use it to encapsulate business logic into programs at the server. Figure 2 on
page 3 shows an example of the processing for a client/server application with stored procedures.

2 Getting Started with DB2 Stored Procedures


Figure 2. Processing with Stored Procedures

The stored procedure can issue static or dynamic SQL statements. Data definition language (DDL),
most data manipulation language (DML), and data control language (DCL) statements can be coded in
a stored procedure.

Stored procedures also enable access to features that exist only on the database server. These
features include commands that run only on the server, software installed only on the server that can
be accessed by the stored procedure, and the computing resources of the server, such as memory and
disk space.

Because stored procedures are defined in DRDA, they also take advantage of DRDA features, such as
data transformation between platforms, database security and accounting, and two-phase commit
support.

1.3 Software Prerequisites for Stored Procedures

The minimum software requirements for using the SQL CALL statement to invoke stored procedures
with DB2 servers are:
• MVS environment
− DB2 for MVS/ESA Version 4 Release 1
− IBM High Level Assembler/MVS Version 1 Release 1
− IBM SAA AD/Cycle C/370 Version 1 Release 2
− IBM C/C++ for MVS/ESA Version 3 Release 1
− IBM COBOL for MVS and VM Version 1 Release 1
− IBM PL/I for MVS and VM Version 1 Release 1
− IBM SAA AD/Cycle Language Environment/370 Version 1 Release 1
• AIX Environment
− DB2 for AIX Version 2
− IBM XL C Version 1 Release 2.1
− IBM C for AIX Version 3 Release 1

Chapter 1. Stored Procedures Overview 3


− IBM C Set++ Version 2 Release 1
− IBM AIX XL FORTRAN Version 2 Release 3
− IBM COBOL Set for AIX Version 1 Release 1
− Micro Focus COBOL Version 3.1.49
• OS/2 Environment
− DB2 for OS/2 Version 2
− IBM C Set++ Version 2 Release 1
− WATCOM FORTRAN 77 32 Version 9.5
− IBM COBOL VisualSet for OS/2 Version 1 Release 1
− Micro Focus COBOL Version 3.1.49
− IBM Procedures Language 2/REXX (supplied as part of OS/2)

1.4 The Project Environment

During this project, we tested many different scenarios with stored procedures in our environment at
the International Technical Support Organization (ITSO) San Jose Center.

Figure 3 shows our project environment.

Figure 3. The Project Environment

We used three PS/2s, one RISC System/6000, and one ES/9000 mainframe. Table 1 on page 5 shows
the hardware and software versions used for the first edition of this book.

4 Getting Started with DB2 Stored Procedures


Table 1. Hardware and Software Used - First Edition
Hardware Software Version
ES/9000 MVS/ESA 5.2.2
DB2 for MVS/ESA 4.1
RISC System/6000 PowerPC AIX 4.1
DB2 for AIX 2.1.1
DDCS for AIX 2.3.1
SDK for AIX 2.1.1
PS/2 Model 95 (server) OS/2 Warp 3.0
DB2 for OS/2 2.1.1
DDCS for OS/2 2.3.1
SDK for OS/2 2.1.1
PS/2 Model 95 (client) OS/2 Warp 3.0
SDK for OS/2 2.1.1
PS/2 Model 80 Windows 3.11
SDK for Windows 2.1.1

Table 2 shows the hardware and software versions used for this second edition.

Table 2. Hardware and Software Used - Second Edition


Hardware Software Version
ES/9000 OS/390 2.4
DB2 for OS/390 5
RISC System/6000 Model 360 AIX 4.2
DB2 Enterprise Edition for AIX 5.0
DB2 Connect for AIX 5.0
SDK for AIX 5.0
PS/2 Model 95 OS/2 Warp 3.0
DB2 Enterprise Edition for OS/2 5.0
DB2 Connect for OS/2 5.0
SDK for OS/2 5.0
PS/2 Model 95 Windows NT 4.0
DB2 Enterprise Edition for Windows NT 5.0
DB2 Connect for OS/2 5.0
SDK for Windows NT 5.0
PS/2 Pentium Windows 95
DB2 Connect Personal Edition for Windows 95 5.0

Some machines were used as both a database client and a database server; others, such as the
Windows 95 client, were used only as a database client.

Our PS/2s and the RISC System/6000 were attached to a 16 MB local area network (LAN) at the ITSO
San Jose Center. The connections between these machines can be made through TCP/IP, APPC,
NetBIOS, or IPX. In our tests we used TCP/IP.

Chapter 1. Stored Procedures Overview 5


A split bridge was used to connect this LAN to the MVS system in Poughkeepsie. The connections
between the DB2 Common Servers in the LAN and the DB2 for MVS/ESA used the APPC protocol. The
connections between the DB2 Universal Database in the LAN and the DB2 Server for OS/390 used the
TCP/IP protocol.

For details about connecting the different DRDA platforms using APPC, refer to the ITSO redbook
Distributed Relational Database Cross Platform Connectivity and Application and using TCP/IP, refer to
the ITSO redbook WOW! DRDA Supports TCP/IP: DB2 Server for OS/390 and DB2 Universal Database .

For this book we used sample programs that are provided with the different products and a number of
programs we developed ourselves. Most of the programs used during this project are on the diskette
shipped with this book. The diskette contains the SG244693.EXE file that when executed, produces the
source for the samples. The SG244693.EXE file can also be downloaded from the Internet at:
ftp://www.redbooks.ibm.com/redbooks/sg244693

Refer to Appendix A, “Sample Programs” on page 347 for the content of the diskette.

6 Getting Started with DB2 Stored Procedures


Chapter 2. DB2 for MVS/ESA, DB2 for OS/390 and Stored Procedures

In this chapter, we describe the support for stored procedures introduced in DB2 for MVS/ESA Version
4.1. Some of the topics we focus on are installation considerations, administration tasks, and new DB2
commands related to the use of stored procedures.

For details on how to code and generate stored procedures for the MVS platform, please refer to
Chapter 6, “Coding Stored Procedures in DB2 on MVS” on page 85. Unless explicitly stated, in this
chapter all references to DB2 refer to DB2 for MVS/ESA (DB2 Version 4) and DB2 for OS/390 (DB2
Version 5).

2.1 Architecture
In this section, we describe the processing flow of the SQL CALL statement. Refer to Figure 4 on
page 8. The flow follows this sequence:
1. A thread must be created for each application that needs DB2 services. If the application is local,
the thread is created when the first SQL statement is executed. If the request comes from a
remote client, the thread is created when the client application issues the SQL CONNECT
statement. After the thread is created, SQL statements can be executed.
2. When a client application issues an SQL CALL statement, the stored procedure name and the I/O
parameters are passed to DB2.
3. When DB2 receives the SQL CALL statement, it searches in the SYSIBM.SYSPROCEDURES catalog
table for a row associated with the stored procedure name. From this table, DB2 obtains the load
module associated with the stored procedure and related information.
4. Stored procedures are executed in address spaces. For DB2 Version 4, only one address space is
available, called the DB2-established address space. For DB2 Version 5, in addition to the
DB2-established stored procedures address space, you can have several work load manager
(WLM) established address spaces. For DB2-established or WLM-established address spaces you
can specify a number of task control blocks (TCBs) in this address space available for stored
procedures. Each stored procedure is executed under one TCB. After searching the
SYSIBM.SYSPROCEDURES table, DB2 searches for an available TCB to be used by the stored
procedure and notifies the stored procedure address space to execute the stored procedure.
5. When DB2 notifies the stored procedures address space to execute a stored procedure, the thread
that was created for the client application is reused for an execution. This has the following
implications:
• CPU cost is low because DB2 does not create a new thread.
• Accounting is on behalf of the client application.
• For static SQL, the OWNER of the client program must have execute privilege on the stored
procedure package. For dynamic SQL issued by the stored procedure, security is checked
against the user of the client program, unless the DYNAMICRULES(BIND) option was specified
when binding the package for the stored procedure. No sign-on or connection processing is
required.
• Any processing done by the stored procedure is considered a logical continuation of the client
application′s unit of work. Thus, locks acquired by the stored procedure are released when the
client application commits or rolls back.
6. The stored procedures address space uses the LE/370 product libraries to load and execute the
stored procedure. Through the SYSIBM.SYSPROCEDURES, you can pass run-time information for
LE/370 when the stored procedure is executed.

 Copyright IBM Corp. 1996 1998 7


7. Control is passed to the stored procedure along with the input and output parameters. The stored
procedure can issue most SQL statements. It also has access to non-DB2 resources.
8. Before terminating, the stored procedure assigns values to the output parameters and returns
control to DB2.
9. DB2 copies the output parameters received from the stored procedure to the client application
parameter area and returns control to the client application.
10. The calling program receives the output parameters and continues the same unit of work.
11. The client application implicitly or explicitly issues the COMMIT statement. With DB2 Version 5, the
client application can implicitly commit as soon as the stored procedure returns control to the
client application. If the client application and the stored procedures used during this execution
update at different sites, the two-phase commit protocol is used.

Figure 4. DB2 Stored Procedure Flow

Although stored procedures are supported from DRDA remote clients, they are also supported locally.
If a local application issues the SQL CALL statement, the distributed data facility (DDF) is not involved
and need not be started.

2.2 Installation Considerations

To enable your DB2 subsystem to use stored procedures, you must specify some parameters during
the installation or migration process.

The DSNTINST CLIST includes a new panel, the stored procedures parameters panel (DSNTIPX; see
Figure 5 on page 9 for DB2 Version 4 and Figure 6 on page 10 for DB2 Version 5). The values on this

8 Getting Started with DB2 Stored Procedures


panel are used to generate a JCL procedure for starting the stored procedures address space. The
parameters and their values are explained below.

 
DSNTIPX INSTALL DB2 - STORED PROCEDURES PARAMETERS
===>

Scrolling backward may change fields marked with asterisks


Enter data below:

1 ACCEPT SQL CALL ===> YES Accept SQL CALL statements (stored
procedure requests)? YES or NO.
* 2 MVS/ESA PROC NAME ===> DB41SPAS Stored procedure JCL PROC name
3 NUMBER OF TCBS ===> 8 Number of concurrent TCBs (1-1000)
4 MAX ABEND COUNT ===> 0 Allowable ABENDs for a procedure (0-255)
5 TIMEOUT VALUE ===> 180 Seconds to wait before SQL CALL fails
5-1800 or NOLIMIT (no timeout occurs)
6 LE/370 RUNTIME ===>

PRESS: ENTER to continue RETURN to exit HELP for more information


 
Figure 5. Stored Procedures Parameters Panel (DSNTIPX) - DB2 Version 4

1 ACCEPT SQL CALL


Indicate whether you want DB2 to support SQL CALL statements. If you want support
for stored procedures, you must enter YES.
2 MVS PROC NAME
This value is the name of the JCL procedure used to start the DB2-established stored
procedures address space.
3 NUMBER OF TCBS
Specify the number of SQL CALL statements to be processed concurrently. Increase
this number if you intend to run many stored procedures concurrently. If you have
DB2 Version 5, we recommend that you use WLM-established stored procedures. That
option provides more flexibility because you can have more than one address space.
We do not recommend specifying too large a number for this parameter because of
virtual storage constraints. For example, if you are using Version 1.4 of LE/370 and
the RUNOPTS recommended in the DB2 for MVS/ESA Application Programming and
SQL Guide , LE/370 uses roughly 100 KB below 16 MB for each TCB. In practice, do
not process more than 50 or 60 TCBs concurrently.
4 MAX ABEND COUNT
Specify the number of times a stored procedure is allowed to terminate abnormally. If
this number is reached, the stored procedure is stopped automatically, and SQL CALL
statements for the stored procedure are rejected until the stored procedure is
explicitly started again or DB2 is restarted.
5 TIMEOUT VALUE
Specify the number of seconds before DB2 ceases to wait for an SQL CALL to be
assigned to one of the TCBs in the stored procedures address space. If the time

Chapter 2. DB2 for MVS/ESA, DB2 for OS/390 and Stored Procedures 9
interval expires, the SQL CALL statement fails. Refer to 2.3.2.3, “DISPLAY
PROCEDURE Command” on page 21.
6 LE/370 RUNTIME
The value specified is for the LE/370 library name. It is placed in the JCL procedure
generated for the stored procedures address space.

After you have selected your options for the stored procedures parameters, the installation process
generates the procedure to start the stored procedures address space.

Figure 6 shows the DSNTIPX panel for DB2 Version 5.

 
INSTALL DB2 - STORED PROCEDURES PARAMETERS
===>

Scrolling backward may change fields marked with asterisks


Enter data below:

* 1 WLM PROC NAME ===> DBC1WLM WLM-established stored procedure


JCL PROC name
* 2 DB2 PROC NAME ===> DBC1SPAS DB2-established stored procedure
JCL PROC name
3 NUMBER OF TCBS ===> 8 Number of concurrent TCBs (1-100)
4 MAX ABEND COUNT ===> 0 Allowable ABENDs for a procedure (0-255)
5 TIMEOUT VALUE ===> 180 Seconds to wait before SQL CALL fails
5-1800 or NOLIMIT (no timeout occurs)

PRESS: ENTER to continue RETURN to exit HELP for more information


 
Figure 6. Stored Procedures Parameters Panel (DSNTIPX) - DB2 Version 5

1 WLM PROC NAME


Indicates the sample JCL for WLM-established stored procedures that is placed in
member DSNTIJMV of the SDSNSAMP data set.
DB2 PROC NAME
This value is the name of the JCL procedure used to start the DB2-established stored
procedures address space.
The other parameters have the same meaning as DB2 Version 4, and the LE/370 information is
specified on the DSNTIPG panel.

2.2.1 DB2-Established Stored Procedures Address Space


All DB2 Version 4 stored procedures are executed in the DB2-established stored procedures address
space. For WLM-established stored procedures address space, refer to Chapter 3, “WLM-Established
Stored Procedures Address Spaces” on page 25.

Figure 7 on page 11 shows an example of the JCL that starts the DB2-established stored procedures
address space generated by the installation process and later customized for our environment.

10 Getting Started with DB2 Stored Procedures


 
//*************************************************************
//* JCL PROCEDURE FOR THE STARTUP OF THE
//* DB2 STORED PROCEDURES ADDRESS SPACE
//* RGN -- THE MVS REGION SIZE FOR THE ADDRESS SPACE.
//* SUBSYS -- THE DB2 SUBSYSTEM NAME.
//* NUMTCB -- THE NUMBER OF TCBS TO BE USED TO
//* PROCESS STORED PROCEDURE REQUESTS.
//*
//*************************************************************
//DB41SPAS PROC RGN=0K,TME=1440,SUBSYS=DB41,NUMTCB=8 1
//IEFPROC EXEC PGM=DSNX9STP,REGION=&RGN,TIME=&TME,
// PARM=′&SUBSYS,&NUMTCB′
//STEPLIB DD DISP=SHR,DSN=DSN410.RUNLIB.LOAD
// DD DISP=SHR,DSN=SYS1.CEE.V1R5M0.SCEERUN 2
// DD DISP=SHR,DSN=DSN410.SDSNLOAD
// DD DISP=SHR,DSN=STDRD2A.STPROC.LOAD 3
//CEEDUMP DD SYSOUT=* 4
//SYSPRINT DD SYSOUT=* 4
 
Figure 7. DB2-Established Stored Procedures Address Space JCL Procedure

You can change this procedure to fit your installation′s needs. As shown in 1, set the REGION size
to REGION=0 to obtain the largest possible amount of virtual storage below and above 16 MB. DB2
Version 4 stored procedures require that you have installed LE/370 Version 1 Release 1 or later. The
LE/370 run-time libraries data set 2 must be available for the stored procedures address space. You
must enter the LE/370 run-time data set name on the DSNTIPX installation panel. You can also include
additional load libraries that contain your stored procedures 3.

To access non-DB2 resources, you also may have to change this procedure to specify the required DD
JCL statements. 4 Also include DD statements for debugging such as CEEDUMP (from LE) and
SYSPRINT (used by C and PL/I) and files specified by the LE run-time option MSGFILE.

However, be aware that there is no commit coordination between the stored procedure and any
recoverable resource you may be accessing, such as CICS or IMS resources. This support is provided
only when you use WLM-established address space (refer to Chapter 12, “Recoverable Resource
Manager Services Attachment Facility” on page 255).

DB2 automatically issues an MVS START command to activate the DB2-established stored procedures
address space during DB2 startup. This address space runs as a DB2 allied address space, providing
an isolated execution environment for the stored procedures. Therefore, you can stop and start the
stored procedures address space without restarting DB2. In addition, because DB2 is isolated from
user program errors, you can test and install new versions of stored procedures without stopping DB2.

2.2.2 RACF Considerations for DB2-Established Address Space


After you have customized the stored procedures address space JCL procedure, if you are using RACF
to protect DB2 data sets, you must update the RACF started procedures table to include an entry for
the DB2-established address space. For WLM-established address spaces, you can use the
authorization ID related to the client application.

The RACF ID and group for the DB2-established stored procedures address space do not have to
match the RACF ID and group name used for the other DB2 address spaces. However, the RACF ID
and group name that you select must have authority to run DB2 call attachment facility (CAF)
application programs.

Chapter 2. DB2 for MVS/ESA, DB2 for OS/390 and Stored Procedures 11
If you access non-DB2 resources such as VSAM files and flat files in your stored procedure, you must
ensure that the RACF ID associated with the stored procedures address space has the privileges
needed for the access. The RACF ID associated with the client application is not checked for privileges
to access non-DB2 resources for stored procedures that run in the DB2-established address space.

2.2.3 Serializing Access to Non-DB2 Resources


Note that when you access non-DB2 resources such as VSAM or QSAM files, DB2 does not provide
serialization for stored procedures that run in the DB2-established address space. The granularity of
data sets allocation and enqueue by MVS is done at address space level, not at task level. If the
NUMTCB symbolic parameter in the stored procedure address space JCL is set to greater than 1, then
two stored procedures could be running concurrently as different tasks, yet under the same address
space. They could be writing to the same file because MVS assumes that serialization has been taken
care of by the application program(s). Task A gets a data set; Task B also tries to obtain the same
data set. Because they are running under the same address space (even though they are running as
different tasks), MVS lets Task B “reuse” the data set. If updates are performed by these stored
procedures, there is a possibility of data corruption. To get around this with NUMTCB greater than 1,
the application programmer should consider using OpenEdition commands such as fopen() when
attempting to open data sets.

Another solution is to use WLM-established address space. You can set up an application
environment that can serialize the execution of the stored procedure.

Or you must provide the serialization in the stored procedure code.

2.2.4 Updating Installation Parameters


You can change the parameters set during the DB2 installation process by running the DSNTINST
CLIST in update mode. However, you can change the values of only the MAX ABEND COUNT and
TIMEOUT VALUE parameters.

If for DB2 Version 4, you choose not to use stored procedures during the installation process but
decide to use them later, you cannot use the DSNTINST CLIST. You must update the DSNTIJUZ
member.

Figure 8 shows the parameters to change in the DSNTIJUZ member.

 
DSN6SYSP AUDITST=NO,
CONDBAT=64,
CTHREAD=70,
.
.
.
STORMXAB=0,
STORPROC=DB41SPAS, <-- (1)
STORTIME=180,
TRACSTR=NO,
TRACTBL=16
 
Figure 8. Changing DSNTIJUZ Parameters

By changing the STORPROC parameter (1) to the name of the stored procedures address space JCL
procedure, support for stored procedures becomes available. In addition, to updating DSNTIJUZ, you
have to manually create the JCL procedure that starts the stored procedures address space.

12 Getting Started with DB2 Stored Procedures


If you try to start the DB2-established stored procedures address space without changing the
DSNTIJUZ member, the following messages are sent to the MVS console for DB2 Version 4:
IEF403I DB41SPAS - STARTED - TIME=13.13.10
DSNX944I @ DSNX9VPN THE STORED PROCEDURE FUNCTION IS NOT AVAILABLE
+DSNX965I DSNX9STP THE DB2 STORED PROCEDURES ADDRESS SPACE FOR 047
SUBSYSTEM DB41 IS STOPPING
IEF404I DB41SPAS - ENDED - TIME=13.13.16

You cannot use the DSNTINST CLIST to change the number of concurrent TCBs. Instead, you must
update the JCL procedure for the stored procedures address space. Figure 9 shows how to change
the number of concurrent TCBs.

 
//DB41SPAS PROC RGN=0K,TME=1440,SUBSYS=DB41,NUMTCB=8 <-- (1)
//IEFPROC EXEC PGM=DSNX9STP,REGION=&RGN,TIME=&TME,
// PARM=′&SUBSYS,&NUMTCB′
//STEPLIB DD DISP=SHR,DSN=DSN410.RUNLIB.LOAD
.
.
.
 
Figure 9. Changing the Number of Concurrent TCBs

Update NUMTCB parameter (1) in the JCL procedure to increase the number of concurrent TCBs
available for stored procedures. However, when you code your stored procedures, do not rely on the
existence of multiple TCBs in the stored procedures address space.

2.3 Administration Tasks

To use stored procedures in a DB2 environment, you have to define the stored procedures to DB2 by
updating the SYSIBM.SYSPROCEDURES catalog table, and use commands to control the stored
procedures execution.

2.3.1 Defining Stored Procedures


When DB2 receives an SQL CALL statement, it searches for information about the stored procedure in
the SYSIBM.SYSPROCEDURES catalog table. To define stored procedures to DB2, you must insert
rows in the SYSIBM.SYSPROCEDURES table.

You can use the INSERT statement or the LOAD utility to insert rows in the SYSIBM.SYSPROCEDURES
table. It is also possible to use the DELETE or UPDATE statement to delete or change any value
previously specified in the SYSIBM.SYSPROCEDURES table.

DB2 uses the information in the SYSIBM.SYSPROCEDURES table to:


• Obtain the load module name associated with the stored procedure name, authorization ID, and LU
name
• Verify the parameters required by the stored procedure
• Validate the parameters supplied by the calling application
• Perform data conversion for the parameters when required DB2 for MVS/ESA
• Specify run-time options for LE/370

Chapter 2. DB2 for MVS/ESA, DB2 for OS/390 and Stored Procedures 13
To reduce I/O operations DB2 caches data read from the SYSIBM.SYSPROCEDURES table. If you
update any column on the SYSPROCEDURES table, you may have to refresh the DB2 buffers related to
the stored procedure you updated. To refresh buffers issue the START PROCEDURE command. Refer
to 2.3.2, “DB2 Commands Related to Stored Procedures” on page 19 for more information about DB2
commands.

2.3.1.1 SYSIBM.SYSPROCEDURES Table Columns: The SYSIBM.SYSPROCEDURES catalog


table columns are described below.
PROCEDURE Specifies the name of the stored procedure. This is the name that is specified in the
SQL CALL statement.
AUTHID The authorization ID associated with the client application. If AUTHID is blank, the row
applies to all authorization IDs. Refer to Table 3 on page 15 for an example of using
the AUTHID column.
LUNAME Specifies the LUNAME of the system running the client application. It can also specify
the local system LUNAME. If LUNAME is blank, the row applies to all systems,
including the local system. Refer to Table 3 on page 15 for an example of using the
LUNAME column.
LOADMOD The name of the MVS load module associated with the stored procedure.
LINKAGE Specifies which linkage convention should be used for this stored procedure. There
are two possibilities:
blank The SIMPLE linkage convention is used. When a stored procedure is
called, input parameters cannot be null. Also, the stored procedure cannot
nullify output parameters.
N The SIMPLE WITH NULLS linkage convention is used. The input
parameters can be null, and an indicator array is passed to the stored
procedure by DB2.
COLLID The collection name for the stored procedure package. If COLLID is blank, the client
application collection name is used.
LANGUAGE Specifies the programming language used to create the stored procedure. Possible
values are ASSEMBLE for Assembler, PLI for PLI, COBOL for COBOL or OO COBOL,
and C f o r C o r C + + .
ASUTIME Specifies the maximum number of service units allowed for each execution of the
stored procedure. If ASUTIME is zero, there is no limit on the service units.
STAYRESIDENT
Determines whether the stored procedure load module is deleted from memory when
the stored procedure ends.
Y The load module remains in memory after the stored procedure ends.
blank The load module is deleted from memory after the stored procedure ends.
IBMREQD Indicates whether the row came from the basic machine-readable material (MRM)
tape. Possible values are Y or N .
RUNOPTS The LE/370 run-time options to use for this stored procedure. If RUNOPTS is blank,
the installation default LE/370 run-time options are used.
PARMLIST Defines the parameter list expected by the stored procedure.
In addition, for DB2 Version 5 SYSIBM.SYSPROCEDURES has the columns described below.
RESULT_SETS Specifies the maximum number of result sets that the stored procedure can return to
the client application.

14 Getting Started with DB2 Stored Procedures


WLM_ENV Specifies the application environment definition for this stored procedure.
PGM_TYPE Specifies how the stored procedure should be executed:
M Is the default, and specifies that the stored procedure executes as a main
program.
S Specifies that the stored procedure executes as a subprogram. This
specification is only valid for WLM-established stored procedure address
spaces. For the implications of a stored procedure running as a
subprogram refer to Chapter 6, “Writing a Stored Procedure as a Main
Program or Subprogram,” in DB2 for OS/390 Application Programming and
SQL Guide .
EXTERNAL_SECURITY
Specifies how MVS protected resources access by the stored procedure should be
checked:
N Is the default, and specifies that access to MVS protected resources should
be checked against the authority of the stored procedure address space.
Y Specifies that access to MVS protected resources should be checked
against the authority of the client that invoked the stored procedure. This
specification is only valid for WLM-established stored procedure address
spaces.
COMMIT_ON_RETURN
Specifies when the unit of work should commit:
N Is the default, and specifies that the client application controls when commit
processing is to be invoked.
Y Specifies that the whole unit of work is committed immediately after control
is returned to the client application as long as the stored procedure
completes successfully.

Table 3 shows an example of a SYSIBM.SYSPROCEDURES table.

Table 3. Sample SYSIBM.SYSPROCEDURES Table


PROCEDURE AUTHID LUNAME LOADMOD ...

1 PROC1 PROG1 ...

2 PROC1 BO LUXEMBRG PROG2 ...

3 PROC2 SILVIO PROG3 ...

4 PROC3 LUTEST PROG4 ...

Note that in Table 3, rows 1 and 2 refer to the PROC1 stored procedure. By creating multiple rows in
the SYSIBM.SYSPROCEDURES table with the same value for the PROCEDURE column, you can
indicate that specified users have access to different versions of the stored procedure. In our case, in
row 1, the AUTHID and LUNAME columns are blank. Any user or location without a specific entry can
use row 1. Row 2 applies only to SQL CALL requests coming from AUTHID BO and LUNAME
LUXEMBRG. When this user invokes the PROC1 stored procedure, a different load module (PROG2) is
loaded. The load module can be a test version of the stored procedure or a version that is specific for
that user.

Row 3 applies to stored procedure PROC2 and AUTHID SILVIO. Because there is no other row for
stored procedure PROC2, user SILVIO is the only one who can call this stored procedure. Because the
LUNAME column is blank, user SILVIO can call this stored procedure from any client program, either
local or remote.

Chapter 2. DB2 for MVS/ESA, DB2 for OS/390 and Stored Procedures 15
Row 4 applies to stored procedure PROC3 and LUNAME LUTEST. Because there is no other row for
stored procedure PROC3, only client programs running LUNAME LUTEST can call stored procedure
PROC3. Because the AUTHID column is blank, any user from LUNAME LUTEST can call stored
procedure PROC3.

As shown in Table 3 on page 15, it is possible to have more than one row in the
SYSIBM.SYSPROCEDURES table for a given stored procedure. DB2 has a search precedence for
determining which row it selects for a specific client. The following is the search precedence that DB2
uses to select the stored procedure:
1. A row with AUTHID and LUNAME matching the caller′ s AUTHID and LUNAME
2. A row with AUTHID matching the caller′ s AUTHID and LUNAME blank
3. A row with AUTHID blank and LUNAME matching the caller′ s LUNAME
4. A row with AUTHID and LUNAME columns blank

Caution
The support for AUTHID and LUNAME may be suppressed in future versions of DB2.

2.3.1.2 Defining the PARMLIST Column: The PARMLIST column in the


SYSIBM.SYSPROCEDURES table is a string that defines the parameters used by the stored procedure.
Figure 10 shows the syntax for the PARMLIST column string,

Figure 10. PARMLIST Column String Syntax

where:
parm-name Is a one- through eight-character string defining the name of the parameter for use in
messages. If you do not specify a name, the position of the parameter in the
parameter list is used in the DB2 messages.
INTEGER or INT
Large integer parameter
SMALLINT Small integer parameter
REAL Single precision floating-point parameter

16 Getting Started with DB2 Stored Procedures


FLOAT, DOUBLE, or DOUBLE PRECISION
Double precision floating-point parameter
DECIMAL or DEC
Decimal parameter. The (integer,integer) optional arguments are, respectively, the
precision and the scale. The precision is the total number of digits from 1 to 31. The
scale is the number of digits to the right of the decimal point from 0 to the value of the
precision.
CHARACTER or CHAR
Fixed-length character string parameter. The (integer) optional argument specifies the
length of the string, from 1 to 254. If you do not specify (integer) argument, the length
is set to 1.
VARCHAR Varying-length character string parameter. The maximum length is specified by the
argument (integer) and varies from 1 to 32765 characters. Although the length of the
VARCHAR parameter can be up to 32765, the DB2 for MVS/ESA LONG VARCHAR
column can be no more than 32704 bytes. If you use a VARCHAR parameter of length
32765 to update a DB2 LONG VARCHAR column, the value is truncated. If your
varying-length character host variables receive values whose length is greater than
9999 characters, compile the COBOL applications in which you use those host
variables with the option TRUNC(BIN). TRUNC(BIN) lets the length field for the
character string receive a value of up to 32767. If you don′t specify TRUNC(BIN) the
maximum length is 9999.
GRAPHIC Fixed-length graphic character string parameter. The (integer) optional argument
specifies the length of the string, from 1 to 127. If you do not specify (integer)
argument, the length is set to 1.
VARGRAPHIC Varying-length graphic character string parameter. The maximum length is specified
by the argument (integer) and varies from 1 to 16383 characters.
FOR subtype DATA
Specifies a subtype for a character string parameter. The subtype can be one of the
following:
SBCS Specifies that the parameter is a single-byte character string.
Character conversion occurs when the parameter passes from a
DRDA requester to a DRDA server.
MIXED Specifies that the parameter holds mixed data. You cannot use this
option when installation option MIXED DATA is NO. Character
conversion occurs when the parameter passes from a DRDA
requester to a DRDA server.
BIT Specifies that the parameter holds bit data. Character conversion
does not occur when the parameter passes from a DRDA requester to
a DRDA server.
IN Specifies the parameter as an input-only parameter to the stored procedure.
OUT Specifies the parameter as an output-only parameter to the stored procedure.
INOUT The parameter is both an input and output parameter to the stored procedure.

As an example, in the following PARMLIST string:


PARM1 CHAR(10) IN, PARM2 INTEGER INOUT, PARM3 INT OUT

PARM1, PARM2, and PARM3 are identifiers for error messages. You can specify any name you want.
The stored procedure associated with this PARMLIST string would expect three parameters:
• An input character parameter of length 10

Chapter 2. DB2 for MVS/ESA, DB2 for OS/390 and Stored Procedures 17
• An integer parameter for both input and output
• An integer parameter for output only

If the number of parameters in the SQL CALL statement does not match the number of parameters
specified in the PARMLIST column for the stored procedures, an SQLCODE -440 is returned to the
client application.

2.3.1.3 COMMIT_ON_RETURN Column Considerations: DB2 Version 5 introduced a new


column, COMMIT_ON_RETURN.

If you specify N for this column, all updates performed by the unit of work are committed when the
client application commits. This is the default.

If you specify Y for this column, all updates performed by the unit of work are committed when control
returns to the client application if the SQLCODE for the CALL statement is zero or has a positive value.
This implies that updates performed before the stored procedure is invoked, are also committed.
Those updates can be done by the stored procedure locally or remotely (through a three-part name or
using RRSAF), or done locally or remotely by the client application before invoking the stored
procedure. Any updates performed by the client application after the execution of the stored
procedure are part of another unit of work. The client application does not need to code the COMMIT
statement. This specification is valid for DB2-established or WLM-established address spaces. This
specification is valid regardless of whether the client application is using CONNECT TYPE 1 or
CONNECT TYPE 2. If the application updated other DRDA servers before invoking the stored
procedures, those updates are also committed upon successful execution of the stored procedure.

The advantage of committing automatically is that all locks acquired previously are released, except
for locks acquired for opened cursors declared with both the WITH HOLD and WITH RETURN options.

If the stored procedure executes a ROLLBACK statement, the COMMIT_ON_RETURN specification of Y


is ignored. In this case, the whole unit of work is placed in a must rollback status.

In a DRDA environment COMMIT_ON_RETURN causes a message to flow back to the application


requester that causes the application requester to issue a COMMIT. This should work with all DRDA
application requesters.

If the client application is running under a TP monitor that does not support this function such as CICS,
IMS, RRS, and Encina, a -925 SQLCODE is returned to the client application. If a ROLLBACK is
requested by the DB2 server, due for example because a ROLLBACK statement was executed by the
stored procedure, a -926 SQLCODE is returned to the client application. The client application can use
this information to either commit or rollback using whatever facilities are provided by the TP monitor.

If the level of the DRDA application requester does not support the commit request from the DRDA
application server, the specification of Y is ignored and no SQLCODE is returned to the client
application. In this case, the client application should explicitly commit or roll back.

The DDCS product does not support the commit request. The DB2 Connect product supports the
commit request with maintenance. Client applications running on DB2 Version 4 need APAR PQ11161
to invoke a stored procedure that has COMMIT_ON_RETURN=Y specified. If APAR PQ11161 is not
applied, the COMMIT_ON_RETURN specification is ignored and no SQLCODE indicating this is returned
to the client application.

If the stored procedure is coded to return multiple result sets you must declare the cursors for the
result sets with the WITH RETURN and WITH HOLD options, otherwise the cursors are closed when
control returns to the client application.

18 Getting Started with DB2 Stored Procedures


If the stored procedure is connected to a location for which updates are not allowed, the client
application gets a -426 SQLCODE.

2.3.2 DB2 Commands Related to Stored Procedures


To support stored procedures operations, the following commands are supported in DB2:
• START PROCEDURE
• STOP PROCEDURE
• DISPLAY PROCEDURE
In a data-sharing environment, these three commands have member scope.

The DISPLAY THREAD command output also provides more information about stored procedures.

2.3.2.1 START PROCEDURE Command: The START PROCEDURE command activates the
definition of stored procedures. It reads and validates information from the SYSIBM.SYSPROCEDURES
table. The START PROCEDURE command also refreshes the DB2 buffers with information from the
SYSIBM.SYSPROCEDURES table.

If the DB2-established stored procedures address space has not been started, it is automatically
started after the START PROCEDURE command is executed.

To execute a START PROCEDURE command, you must have one of the following privileges:
• SYSOPR authority
• SYSCTRL authority
• SYSADM authority
Figure 11 shows the syntax of the START PROCEDURE command.

Figure 11. START PROCEDURE Syntax

procedure-name
Specifies the name of the stored procedure to be started. The information stored in
the SYSIBM.SYSPROCEDURES table for the stored procedure is read and cached.
If you do not specify a value for the procedure-name argument, or you specify (*), all
stored procedures are started.
Example:
-START PROCEDURE(*)
DSNX946I @ DSNX9ST2 START PROCEDURE SUCCESSFUL FOR *

-START PROCEDURE(PPMMSSM0, TS0BMS)


DSNX946I @ DSNX9ST2 START PROCEDURE SUCCESSFUL FOR PPMMSSM0
DSNX946I @ DSNX9ST2 START PROCEDURE SUCCESSFUL FOR TS0BMS

Chapter 2. DB2 for MVS/ESA, DB2 for OS/390 and Stored Procedures 19
partial-name * Starts a set of stored procedures. The names of the stored procedures in the set start
with partial-name and can end with any string.
Example:
-START PROCEDURE(BBMMS*)
DSNX946I @ DSNX9ST2 START PROCEDURE SUCCESSFUL FOR BBMMS*

If an error in the SYSIBM.SYSPROCEDURES table is detected during a START PROCEDURE command,


all rows for that stored procedure are ignored, and the information regarding that stored procedure is
not refreshed.

2.3.2.2 STOP PROCEDURE Command: The STOP PROCEDURE command stops access to one
or more stored procedures. According to arguments you specify, new requests to stopped stored
procedures can be queued or rejected.

If a stored procedure is not running correctly, you can stop the stored procedure and replace or add a
load module associated with a stored procedure.

For the DB2-established stored procedures address space, the STOP PROCEDURE command also
enables you to stop the stored procedures address space.

To execute a STOP PROCEDURE command, you must have one of the following privileges:
• SYSOPR authority
• SYSCTRL authority
• SYSADM authority
Figure 12 shows the syntax of the STOP PROCEDURE command.

Figure 12. STOP PROCEDURE Syntax

procedure-name
Specifies the name of the stored procedure to be stopped.
If you do not specify a value for the procedure-name argument, or you specify (*), all
stored procedures are stopped, and for the DB2-established stored procedures
address space, the address space is terminated. The STOP PROCEDURE command
does not check whether the procedure-name is in the SYSIBM.SYSPROCEDURES
table.
Example:
-STOP PROCEDURE(*)
DSNX947I @ DSNX9SP2 STOP PROCEDURE SUCCESSFUL FOR *

-STOP PROCEDURE(WRONGNAME)
DSNX947I @ DSNX9SP2 STOP PROCEDURE SUCCESSFUL FOR WRONGNAME
partial-name * Stops a set of stored procedures. The names of stored procedures in the set start
with partial-name and can end with any string.
Example:

20 Getting Started with DB2 Stored Procedures


-STOP PROCEDURE(BBMMS*)
DSNX947I @ DSNX9SP2 STOP PROCEDURE SUCCESSFUL FOR BBMMS*
ACTION Specifies what to do with SQL CALL statements received while the procedure is
stopped.
(QUEUE) Causes the request to be queued until the request exceeds the
installation timeout value or the stored procedure is started with the
START PROCEDURE command. This is the default.
(REJECT) Causes the request to be rejected. The client application receives an
SQLCODE -471.

DB2 automatically issues the STOP PROCEDURE ACTION(REJECT) command for any stored procedure
that exceeds the maximum abnormal termination (abend) count. That count is set on the DSNTIPX
panel during DB2 installation. See 2.2, “Installation Considerations” on page 8 for more information.

The effects of the STOP PROCEDURE command do not persist if DB2 is restarted. If you want to
permanently disable a stored procedure, you can:
• Delete the row in the SYSIBM.SYSPROCEDURES table that defines the stored procedure.
• Update the row in the SYSIBM.SYSPROCEDURES table so that the LOADMOD column points to a
nonexistent MVS load module.
• Rename or delete the MVS load module.

2.3.2.3 DISPLAY PROCEDURE Command: The DISPLAY PROCEDURE command displays


statistics about stored procedures accessed by DB2 applications since the last DB2 startup. It displays
one output line for each stored procedure name and load module name combination for which DB2 has
accumulated statistics. In some cases there are multiple rows for a stored procedure.

To execute a DISPLAY PROCEDURE command, you must have one of the following privileges:
• DISPLAY privilege
• SYSOPR authority
• SYSCTRL authority
• SYSADM authority
Figure 13 shows the syntax of the DISPLAY PROCEDURE command.

Figure 13. DISPLAY PROCEDURE Syntax

procedure-name
Specifies the name of the stored procedure to display.
If you do not specify a value for the procedure-name argument, or you specify (*), all
stored procedures that have been accessed by a DB2 application are displayed.
partial-name * Displays a set of stored procedures. The names of stored procedures in the set start
with partial-name and can end with any string.

Chapter 2. DB2 for MVS/ESA, DB2 for OS/390 and Stored Procedures 21
Examples:
-DISPLAY PROCEDURE(*)
DSNX940I @ DSNX9DIS DISPLAY PROCEDURE REPORT FOLLOWS -
PROCEDURE MODULE STATUS ACTIVE MAXACT QUEUED MAXQUE TIMEOUT
BBMMSPR0 STOPREJ 0 0 0 1 1
PPMMSSM1 STOPQUE 0 0 0 1 0
TS0BMS TS0BMS STARTED 0 1 0 1 0
PPMMSSM0 PPMMSSM0 STARTED 0 1 0 0 0
DSNX9DIS DISPLAY PROCEDURE REPORT COMPLETE

-DISPLAY PROCEDURE(BBMMSTS1,WRONGNAME)
DSNX940I @ DSNX9DIS DISPLAY PROCEDURE REPORT FOLLOWS -
PROCEDURE MODULE STATUS ACTIVE MAXACT QUEUED MAXQUE TIMEOUT
BBMMSTS1 STOPQUE 0 0 0 0 0
DSNX9DIS PROCEDURE WRONGNAME HAS NOT BEEN ACCESSED
DSNX9DIS DISPLAY PROCEDURE REPORT COMPLETE

-DISPLAY PROCEDURE(BBMMS*)
DSNX940I @ DSNX9DIS DISPLAY PROCEDURE REPORT FOLLOWS -
PROCEDURE MODULE STATUS ACTIVE MAXACT QUEUED MAXQUE TIMEOUT
BBMMSPR0 STOPREJ 0 0 0 1 1
TS0BMS TS0BMS STARTED 0 1 0 1 0
DSNX9DIS DISPLAY PROCEDURE REPORT COMPLETE

The following is a description of the output fields:


PROCEDURE The name of the stored procedure
MODULE The name of the MVS load module associated with the stored procedure. If a stored
procedure request is queued, this field may contain blanks, as in the first example.
STATUS Shows the status of the stored procedure. Possible values are:
STARTED The stored procedure is started and can accept requests.
STOPQUE The stored procedure is stopped, and the requests are queued.
STOPREJ The stored procedure is stopped, and the requests are rejected.
STOPABN The stored procedure is stopped because of an abnormal termination,
and the requests are rejected.
ACTIVE The number of threads that are currently running the load module
MAXACT The maximum number of threads that have concurrently run the load module since
DB2 was started
QUEUED The number of threads that are waiting for the stored procedure
MAXQUE The maximum number of threads that have waited concurrently for the stored
procedure
TIMEOUT The number of timeouts that occurred while waiting for the stored procedures

If you issue a DISPLAY PROCEDURE command when a STOP PROCEDURE (*) is in effect, the following
output line is also displayed:
DSNX943I @ DSNX9DIS PROCEDURES A THROUGH
Z99999999999999999 HAVE BEEN STOPPED WITH ACTION(QUEUE)

22 Getting Started with DB2 Stored Procedures


2.3.2.4 DISPLAY THREAD Command: To provide more information regarding stored
procedures, some changes have been implemented in the DISPLAY THREAD command output of DB2
for MVS/ESA Version 4.1.

There are two new values for the STATUS column:


• SW - the thread is waiting for the stored procedure.
• SP - the thread is executing the stored procedure.

A new message (DSNV429I) is also included to provide the stored procedure name and the load
module name when a thread is executing a stored procedure.

Example:
-DISPLAY THREAD(*)
DSNV401I @ DISPLAY THREAD REPORT FOLLOWS -
DSNV402I @ ACTIVE THREADS -
NAME ST A REQ ID AUTHID PLAN ASID TOKEN
SERVER SP * 3 SM0PMCC2.EXE STDRD2A DISTSERV 0065 98
V429 CALLING STORED PROCEDURE PPMMSSM0, LOAD MODULE PPMMSSM0
V445-USIBMSC.SC02130I.AC5D2A9757DC=98 ACCESSING DATA FOR <SC02130I>
SERVER SW * 2 BB2MCPR0.EXE STDRD2A DISTSERV 0065 96
V429 CALLING STORED PROCEDURE BBMMSPR0, LOAD MODULE
V445-USIBMSC.SC02130I.AC5D2A740EA8=96 ACCESSING DATA FOR <SC02130I>
DISPLAY ACTIVE REPORT COMPLETE
DSN9022I @ DSNVDT ′ -DISPLAY THREAD′ NORMAL COMPLETION

In this example, the second thread is waiting for stored procedure BBMMSPR0. By issuing a DISPLAY
PROCEDURE command you can get more information to find out why the thread is waiting:
-DISPLAY PROCEDURE(BBMMSPR0)
DSNX940I @ DSNX9DIS DISPLAY PROCEDURE REPORT FOLLOWS -
PROCEDURE MODULE STATUS ACTIVE MAXACT QUEUED MAXQUE TIMEOUT
BBMMSPR0 STOPQUE 0 0 1 1 3
DSNX9DIS DISPLAY PROCEDURE REPORT COMPLETE

In this case, the thread was in a waiting state because the stored procedure was stopped. This wait
period is limited by the time you specified for the TIMEOUT VALUE parameter during installation.

Chapter 2. DB2 for MVS/ESA, DB2 for OS/390 and Stored Procedures 23
24 Getting Started with DB2 Stored Procedures
Chapter 3. WLM-Established Stored Procedures Address Spaces

DB2 Version 5 supports WLM-established stored procedures address spaces in addition to the
DB2-established stored procedures address space, which was already supported in DB2 Version 4.

DB2 for OS/390 Version 5 (with OS/390 Release 3 or above) enables you to run multiple WLM-managed
stored procedures address spaces. With WLM-established stored procedures address space you can:
• Access non-DB2 resources with two-phase commit.
• Execute stored procedures based on individual transaction priorities.
• Achieve workload balancing across multiple stored procedures address spaces.
• Have more flexibility to group or isolate applications.
• RACF check to non-DB2 resources based on the client authorization.
In this chapter, we present an introduction to WLM, and how it interfaces with stored procedure. We
also describe how you can implement WLM-established stored procedures address spaces. In
summary these steps are:
1. Setting up RRS (refer to 3.14, “Implementing OS/390 Resource Recovery Services (RRS) Support”
on page 59 for this task)
2. Setting up WLM
3. Placing the JCL for the WLM-established stored procedures address space in a system procedure
library such as SYS1.PROCLIB
4. Preparing the stored procedure
5. Updating SYSIBM.SYSPROCEDURES

3.1 Introduction to Workload Management (WLM)


In this section, we summarize the main elements of WLM. If you don′t have any WLM definition, this
section helps you understand the relationship among WLM definitions that are required to manage the
performance goals and the implementation of stored procedures. If you are familiar with WLM, you
can skip this section.

Throughout this section, any reference to DB2 refers to DB2 for OS/390.

3.1.1 What is WLM?


WLM provides a solution for managing workload distribution, workload balancing, and distributing
resources to workloads that require these resources based on user definitions. WLM is a component
of OS/390. For a product, such as DB2, to take advantage of WLM, the product must be able to work
cooperatively with the WLM component.

WLM provides two modes of operation: The previous method of performance management using
installation performance specification (IPS) and the installation control specification (ICS), is called the
compatibility mode. The new goal-oriented performance management with the service definition (see
3.1.2, “WLM Definitions Relationships” on page 26) is called goal mode.

The goal mode of operation became possible with the enclave implementation available in MVS 5.2.
The enclave implementation allows a transaction to span multiple dispatchable SRBs or TCBs in one
or more address spaces. OS/390 MVS Workload Management Services , GC28-1773 contains
information about enclaves. Without using an enclave, work can be managed on an address-space
basis only.

 Copyright IBM Corp. 1996 1998 25


3.1.2 WLM Definitions Relationships
You can make all definitions to WLM using ISPF panels. When you invoke the WLM ISPF application,
you get a series of panels where you define your workload and the performance goals for your
workload. One set of definitions of your workload and the performance goals is called a service
definition. The service definition contains all the information about the installation needed for WLM
processing.

You can have several service definitions stored in user data sets, although only one service definition
can be installed (active) in the WLM couple data set for the entire Sysplex environment.

As illustrated in Figure 14, a service definition applies to several supported types of work (such as
DB2, DDF, and CICS), and consists of one or more service policies.

Figure 14. Service Definition

You can have more than one service policy defined in your service definition, although you can have
only one service policy active in the Sysplex. However, not all WLM commands are Sysplex-wide. For
example, you can switch each system in and out of goal mode independently.

For WLM, a workload is a group of related work meaningful for the installation. When defining a
workload to WLM, the name of the workload does not have to match any keyword defined in the
supported products. It is a symbolic name to refer to a group of related work. A workload can be, for
example, all the work created by a development group, all the work started by a set of applications, or
a grouping of DB2 and CICS transactions. As illustrated in Figure 15 on page 27, you associate a
workload with one or more service classes.

26 Getting Started with DB2 Stored Procedures


Figure 15. Workload, Service Classes, and Service Class Periods

You group work that has the same performance characteristics in one service class. In turn, a service
class can have one or more service class periods. The concept of a service class period is that a
piece of work can consume up to a certain limit of resources (service units) with a certain priority.
When the limit is reached, the work switches to the next period, where the priority is lower than that of
the previous period.

A service class period has performance objectives that can be expressed in terms of importance and
goals.

There are five levels of importance, ranging from lowest to highest. When there is not sufficient
capacity for all work in the system to meet its goals, WLM uses importance to determine which work
should give up resources and which work should receive more resources.

There are three kinds of goals:


• Response time goal
These indicate how quickly you want your work to be processed. Typically you assign a response
time goal for short-running work such as a simple stored procedure or an online CICS or IMS
transaction.
• Execution velocity goals
These define how fast work should run when ready, without being delayed for processor, storage,
or I/O access. Execution velocity goals are intended for work for which response time goals are
not appropriate, such as started tasks, or long-running batch work.
• Discretionary goals
These are for low priority work for which you do not have a particular performance goal.
Figure 16 on page 28 summarizes the performance goals of a service class period.

Chapter 3. WLM-Established Stored Procedures Address Spaces 27


Figure 16. Summary of the Performance Goals of a Service Class

3.1.3 Classification Rules


When work arrives or must be initiated in the system, WLM applies a qualifier to apply the appropriate
classification rule and therefore the performance goals of the work. The qualifier applied depends on
the subsystem. For example, for DB2 you can apply qualifiers such as the stored procedure name,
package name, collection name, connection type, and so on.

As illustrated in Figure 17 on page 29, performance goals for stored procedures generally inherit the
performance of the calling client application.

28 Getting Started with DB2 Stored Procedures


Figure 17. Assigning Performance Goals to Stored Procedures

For example, if the stored procedure is invoked by a CICS transaction, IMS transaction, TSO
attachment, CAF, or RRSAF, the stored procedure inherits the performance goals of the client
transaction (in Figure 17, PERFORMANCE GOAL X). For stored procedures invoked through DDF, you
can assign performance goals for the stored procedure that can be independent of the performance
goals assigned to the client, in the following way:
• If the first SQL statement is not an SQL CALL statement, the performance goals used for the unit of
work executed on this DB2 server are those assigned to the client (in Figure 17, PERFORMANCE
GOAL Y). If the unit of work later executes an SQL CALL statement on this DB2 server, the
performance goals used for the stored procedure are those defined for the client.
• If the first SQL statement executed on the DB2 server is an SQL CALL statement, the whole unit of
work uses the performance goals of the stored procedure (in Figure 17, PERFORMANCE GOAL W).
This implies that even after the stored procedure finishes, any new SQL statement executed in this
unit of work has the same performance goals as those defined for the stored procedure.
Up to this point, we have summarized some of the concepts deployed by WLM related to performance.

For implementation and scheduling of stored procedures, the important WLM definition is the
application environment definition.

3.2 Application Environments


We begin by defining the application environment in general.

Chapter 3. WLM-Established Stored Procedures Address Spaces 29


3.2.1 Defining the Application Environment
Throughout this section, a reference to a stored procedures address space is a reference to a
WLM-established stored procedure address space. In this section, we present what an application
environment is, emphasizing its relationship to stored procedures.

An application environment is related to work that is to be scheduled in an address space, such as a


WLM established stored procedures address space. It is a group of application functions requested by
a client. The application environment definition is not linked to performance goals, although WLM can
dynamically manage the number of address spaces to meet the performance goals of the work making
the requests.

Each application environment definition represents one or more stored procedures. You can group
stored procedures that access the same resources and have similar characteristics in one WLM
application environment definition.

To use a WLM-established stored procedures address space, you must define one or more application
environments in the WLM service definition.

If you request that the stored procedures address spaces be automatically managed, WLM starts and
stops stored procedures address spaces as needed. For example, when an SQL CALL statement for a
stored procedure is received by DB2, DB2 informs WLM, which determines whether there is a server
address space to execute the stored procedure. If an address space is available to execute the stored
procedure, the stored procedure is executed in this address space. If there is no address space
available to execute the stored procedure, WLM can create one. Application environments can be
used in either goal mode or compatibility mode. In compatibility mode, the server address space
cannot be automatically created by WLM. In this case, you have to start the address space manually
or through some automation tool.

3.2.2 Specifying Application Environments to WLM


To define an application environment for stored procedures, you have to specify in WLM:
• The application environment name
• DB2, as the subsystem type.
• The JCL procedure name that resides in an accessible PROCLIB library. This JCL is used to start
the address space. You have to specify the JCL procedure name if you want WLM to automatically
start and manage the number of servers in goal mode.
• If you specify a JCL procedure name, you can specify any required start parameters that are to be
passed to the JCL procedure execution. You can, for example, pass as a parameter the number of
TCBs that should be available in the address space.
• Whether or not the address space can be started multiple times and on different MVS systems in a
Sysplex environment.
Figure 18 on page 31 shows the relationship among the information contained in the
SYSIBM.SYSPROCEDURES table, the application environment, and the JCL procedure used to start the
stored procedures address space.

30 Getting Started with DB2 Stored Procedures


Figure 18. SYSIBM.SYSPROCEDURES, Application Environment, and JCL Procedure

Figure 19 shows an example of the Application-Environment panel.

 
Application-Environment Notes Options Help
--------------------------------------------------------------------------
Create an Application Environment
Command ===> ______________________________________________________________

Application Environment . . . ATMENV _________________________ Required


Description . . . . . . . . . Stored Proc for the ATM Appl.___
Subsystem Type . . . . . . . . DB2_ Required
Procedure Name . . . . . . . . JCLATM__
Start Parameters . . . . . . . NUMTCB=10_______________________________
________________________________________
___________________________________

Limit on starting server address spaces for a subsystem instance:


1 1. No limit
2. Single address space per system
3. Single address space per Sysplex
 
Figure 19. An Example of the Application-Environment Panel

On this panel, you enter a specification for each item, as follows:


• Application Environment - Name (one to 18 characters) of the application environment. This name
must match the value specified in the WLM_ENV column of SYSIBM.SYSPROCEDURES, for all
stored procedures that use this application environment. This name can be any name, but it

Chapter 3. WLM-Established Stored Procedures Address Spaces 31


should be meaningful for the group of stored procedures that use this application environment
definition. (For elements other than stored procedures, this name can be up to 32 characters.)
• Description - This is an optional field of up to 32 characters describing the application environment.
• Subsystem Type - You must specify DB2. The subsystem type is provided to workload
management when DB2 is started. Note that subsystem type DB2 is used only for identifying the
DB2 subsystem when DB2 begins to use the application environment. There is no connection
between this value and the classification rules for performance goals. The classification rules for
performance goals are applied as explained in 3.1.3, “Classification Rules” on page 28.
• Procedure Name - This is the one to eight-character name of the JCL procedure that WLM uses to
start the address space. If you specify a procedure name in goal mode, automatic control is in
effect and WLM manages the number of address spaces. If you do not specify a procedure name,
manual control is in effect, and address spaces must be started manually or by an automation tool.
Refer to 3.13, “Experimenting with Goal and Compatibility Modes” on page 56 for the relationship
among WLM mode, JCL procedure name specification, and the APPLENV start parameter.
Since each of these address spaces relates to a DB2 subsystem, it may be convenient to prefix the
name with the subsystem identifier. For example, subsystem DBC1 may have WLM stored
procedures address spaces DBC1WLMx. This way, you can group all address spaces related to
DBC1 easily using SDSF.
• Start Parameters - Start parameters are the parameters required for the JCL procedure defined in
Procedure Name. These are the parameters that WLM passes during the startup of the stored
procedures address space. These parameters passed to the JCL procedure are the same ones
you would use if you started the JCL procedure using the MVS START command. If you specify the
symbolic &IWMSSNM (in DB2SSN=&IWMSSNM), WLM replaces it with the DB2 subsystem name
passed to WLM, when DB2 connects to WLM. This allows the same JCL procedure to be used by
different subsystems. The start parameters pass values for symbolic substitution in the JCL
procedure. They may continue on the next lines; you do not need to code continuation characters.
Put start parameters in single quotes if they contain anything other than alphanumeric or national
characters ($, #, @).
• Limit on starting server address spaces for a subsystem instance - You can limit the number of
address spaces for this application environment. One of the reasons you may want to limit the
number of address spaces is to serialize the execution of a particular stored procedure or for
testing purposes. You have three options:
− No limit
− Single address space per system
− Single address space per Sysplex
The limit of address spaces that you can specify for WLM are particular to a subsystem instance.
For WLM application environments, a subsystem instance is a unique combination of a subsystem
type and a subsystem name. The subsystem types are those specified in the service definition that
contains this application environment. The subsystem name is defined by the subsystem type
when it connects to WLM. For example, you can have a subsystem type of DB2 and the subsystem
name of DBC1, if your DB2 subsystem name is DBC1. For stored procedures, the two options you
have are:
− No limit. In this case, WLM can start any number of address spaces.
− Single address space per system. In this case, WLM can start only one address space for this
application environment.
Option 3 does not apply to stored procedures, because you cannot have a DB2 member receiving
an SQL CALL statement, passing this SQL CALL to be executed on another member in the
Sysplex.

32 Getting Started with DB2 Stored Procedures


3.3 Compatibility Mode

Using application environments in compatibility mode involves manually starting and stopping stored
procedures address spaces. In this case, it is your decision of how many address spaces should be
available at a certain point in time. You have to use the MVS operator START command to start the
stored procedures address space and the MVS operator CANCEL command to stop the stored
procedure address space. Alternatively, you can use some automation tool such as System
Automation for OS/390.

You can issue the following MODIFY command (short form of the command is F) to change from
compatibility mode to goal mode:
F WLM,MODE=GOAL
You can issue the following MODIFY command to change from goal mode to compatibility mode.
F WLM,MODE=COMPAT
When you issue the command to change modes you get the following message:
IWM007I SYSTEM SC62 NOW IN WORKLOAD MANAGEMENT COMPATIBILITY|GOAL MODE
If WLM is already in the specified mode, you get the following message:
IWM008I MODIFY WLM REJECTED, SYSTEM SC62 ALREADY IN WORKLOAD
MANAGEMENT GOAL|COMPATIBILITY MODE
This command takes effect across the whole Sysplex environment. However, if you issue the VARY
WLM,APPLENV= command (explained in 3.5, “Managing Application Environments” on page 34), it
has no effect on the address spaces of MVS systems for which the address space was started using
compatibility mode. This means that if you issue the quiesce or refresh options of the VARY
WLM,APPLENV command on a Sysplex where some systems are running in compatibility mode, the
application environment state on the compatibility mode system remains in the QUIESCING or
REFRESHING state until all address spaces for the application environment on the compatibility mode
system are manually terminated. For more information on the VARY WLM,APPLENV= command refer
to 3.5, “Managing Application Environments” on page 34.

3.4 Goal Mode

In goal mode, you can manually start and stop stored procedures address spaces, or you can let WLM
automatically start and stop stored procedures address spaces. If you want WLM to automatically start
stored procedures address spaces, you must define the JCL procedure name associated with the
application environment. This is called automatic control . Under automatic control, WLM creates the
stored procedures address spaces as started tasks. The startup parameters can be contained in either
the JCL procedure or the application environment. The parameters specified in the application
environment definition override those of the JCL procedure.

When the address spaces are no longer needed, WLM deletes them after a certain time period.

Under automatic control, the quantity of stored procedures address spaces is controlled by WLM. If an
operator starts or cancels the address space under automatic control, WLM:
• Uses address spaces not started by WLM as if they were started by WLM. This means that if an
address space is available, WLM uses it regardless of whether it was started by WLM or by an
operator.
• Terminates the address space not started by WLM. This means that if an address space is not
needed anymore, WLM deletes it regardless of whether it was started by WLM or by an operator.
• WLM also terminates all address spaces if you issue the VARY command with the QUIESCE option.

Chapter 3. WLM-Established Stored Procedures Address Spaces 33


3.5 Managing Application Environments

You can use operator commands to manage application environments. There are options on the VARY
WLM,APPLENV command that allow you to quiesce, resume, or refresh application environments.
These options allow you, for example, to make changes to the JCL procedure, start parameters, and
change application libraries. The resume option also allows you to recover from error conditions that
have caused WLM to stop an application environment.

The action taken for an application environment is saved in the WLM couple data set and is not
discarded across an IPL.

You can query the current state of an application environment using the DISPLAY WLM,APPLENV=
command.

The scope of both the VARY and the DISPLAY commands is Sysplex-wide, regardless of whether you
use DB2 data sharing.

An application environment initially enters the AVAILABLE state when the service policy that contains
the application environment is activated. The AVAILABLE state indicates that the application
environment is available for use and address spaces can be started. You can change the state of an
application environment using the VARY WLM,APPLENV command. This is the format of the command:
VARY WLM,APPLENV=xxxxx,option
where:
xxxxx is the application environment name
option can be QUIESCE, RESUME, or REFRESH

3.5.1 The QUIESCE Option


The QUIESCE option of the VARY WLM,APPLENV causes WLM to terminate the stored procedures
address space upon completion of the execution of the already executing stored procedures.
Additional SQL CALLs are not handled by the address spaces, although the additional SQL CALL
statements can continue to be queued waiting for an address space. If do not want these additional
SQL CALLs to be queued, you should issue the STOP PROCEDURE command with the
ACTION(REJECT) specification. The following is an example:
STOP PROCEDURE(PROC1) ACTION(REJECT)

You can issue the QUIESCE option for an application environment that is in the AVAILABLE state.
When you specify the QUIESCE option, the application environment first enters a QUIESCING state until
all stored procedures address spaces for this application environment terminate. It then enters the
QUIESCED state.

3.5.2 The RESUME Option


The RESUME option of the VARY WLM,APPLENV causes WLM to start or restart a stored procedures
address space that was previously quiesced. When a resume action is issued for an application
environment, it first enters the RESUMING state. For a Sysplex environment, all systems must accept
the request. After all systems accept the request, it then enters the AVAILABLE state.

34 Getting Started with DB2 Stored Procedures


3.5.3 The REFRESH Option
The REFRESH option requests the termination of existing stored procedures address spaces and starts
new ones in their place. Existing address spaces finish the current execution of the stored procedures
and end. The new address spaces process any requests that eventually were queued.

You should use the REFRESH option to refresh a copy of the load module containing the stored
procedure program.

You can specify the REFRESH option for an application environment that is in the AVAILABLE state.
When you specify the REFRESH option, it first enters the REFRESHING state until all address spaces
terminate. It then enters the AVAILABLE state.

3.6 Handling Error Conditions in the Application Environment


WLM stops the creation of new address spaces when one of the following conditions exists:
• JCL errors in the procedure associated with the application environment
• Coding errors in the stored procedure that cause five unexpected terminations of the address
space
• Five operator cancellations of the stored procedures address space within 10 minutes
• Failure of the address space to connect to WLM
The application environment first enters the STOPPING state, then the STOPPED state after all systems
in the Sysplex have accepted the action. In STOPPED state, no new address space are created. An
existing address space continues to be operational and can execute new stored procedure requests.

When the application environment is in STOPPED state, you can make changes to libraries, JCL
procedure, or any other changes needed to repair the condition that caused WLM to stop address
space creation. After you solve the problem, use the RESUME option of the VARY WLM command.

3.7 Defining a Service Definition

Chapter 5, “Assigning Stored Procedure to WLM Application Environments” in DB2 for OS/390
Administration Guide outlines the steps to create an application environment in a service definition for
the WLM-managed stored procedures address spaces.

If your installation is already running WLM, you already have an active service policy within a service
definition. In this case, you have only to define an application environment for your stored procedure
or for each group of stored procedures. Refer to 3.8, “Existing Service Definition” on page 50 for a
description of how to perform this task.

If you don′t have WLM installed, ask your systems programmer to install it for you. After the
installation is complete, you have to perform the tasks described in this section. Figure 20 on page 36
shows the relationship among the WLM definitions.

Chapter 3. WLM-Established Stored Procedures Address Spaces 35


Figure 20. Relationship A m o n g WLM Definitions

When using the WLM ISPF application, you have to enter most of the information manually. If some
information for a definition was already specified on one panel and the same type of information is
required on other panels, you can enter a question mark to list the available choices.

To start the definitions for WLM, perform the following steps:


1. From ISPF, allocate the appropriate WLM data sets and invoke the WLM ISPF application. Typically
this is done by typing the command
tso ex ′ sys1.sblscli0(iwmarin0)′
or by issuing the following command:
TSO WLM
You then see the panel displayed in Figure 21 on page 37.

36 Getting Started with DB2 Stored Procedures


 
File Help
--------------------------------------------------------------------------

Command ===> ______________________________________________________________

W W L M M
W W L MM MM
W W W L M M M
WW WW L M M
W W LLLLL M M

Licensed Materials - Property of IBM

5645-001 (C) Copyright IBM Corp. 1997.


All rights reserved.

ENTER to continue
 
Figure 21. WLM First Panel

A Sysplex installation may run different levels of OS/390 among its members. If you get an
IWMAM052 message because of mismatch in levels of WLM service definition functionality and the
WLM ISPF application, contact your systems programmer to ensure you are using the appropriate
data sets.
2. Press Enter to get the panel displayed in Figure 22.

 
File Help
--------------------------------------------------------------------------

Command ===> ______________________________________________________________

_______________________________________________
| Choose Service Definition |
| |
| Select one of the following options. |
| 3_ 1. Read saved definition |
| 2. Extract definition from WLM |
| couple data set |
| 3. Create new definition |
| |
| |
| |
_______________________________________________
ENTER to continue
 
Figure 22. Choose Service Definition

3. Select option 3 to create a new definition. The panel shown in Figure 23 on page 38 is displayed.

Chapter 3. WLM-Established Stored Procedures Address Spaces 37


 
File Utilities Notes Options Help
--------------------------------------------------------------------------
Functionality LEVEL001 Definition Menu WLM Appl LEVEL004
Command ===> ______________________________________________________________

Definition data set . . : none

Definition name . . . . . ITSO_SJ (Required)


Description . . . . . . . Sysplex at ITSO San Jose________

Select one of the


following options. . . . . 1_ 1. Policies
2. Workloads
3. Resource Groups
4. Service Classes
5. Classification Groups
6. Classification Rules
7. Report Classes
8. Service Coefficients/Options
9. Application Environments
10. Scheduling Environments
 
Figure 23. Definition M e n u Panel

4. Fill in the definition name, which can be any name, and the description.
5. Select option 1 to define a service policy. The panel shown in Figure 24 is displayed.

 
Service-Policy Notes Options Help
--------------------------------------------------------------------------
Create a Service Policy
Command ===> ______________________________________________________________

Enter or change the following information:

Service Policy Name . . . . . DAYTIME (Required)


Description . . . . . . . . . Policy from 9:00 am to 5:00 pm

_____________________________________________________________
| Selection List empty. Define a service policy. (IWMAM100) |
_____________________________________________________________
 
Figure 24. Create a Service Policy

6. Give the policy a name, and optionally a description and press END (PF3) to get to the service
policy selection list. The panel shown in Figure 25 on page 39 is displayed.

38 Getting Started with DB2 Stored Procedures


 
Service-Policy View Notes Options Help
--------------------------------------------------------------------------
Service Policy Selection List Row 1 to 1 of 1
Command ===> ______________________________________________________________

Action Codes: 1=Create, 2=Copy, 3=Modify, 4=Browse, 5=Print, 6=Delete,


7=Override Service Classes, 8=Override Resource Groups,
/=Menu Bar
----Last Change-----
Action Name Description User Date
__ DAYTIME Policy from 9:00 am to 5:00 pm DB2RES1 1997/11/03
******************************* Bottom of data ********************************
 
Figure 25. Service Policy Selection List

7. Press END (PF3) to get back to the Definition Menu panel shown in Figure 26.

 
File Utilities Notes Options Help
--------------------------------------------------------------------------
Functionality LEVEL003 Definition Menu WLM Appl LEVEL004
Command ===> ______________________________________________________________

Definition data set . . : none

Definition name . . . . . ITSO_SJ (Required)


Description . . . . . . . Sysplex at ITSO San Jose

Select one of the


following options. . . . . 2__ 1. Policies
2. Workloads
3. Resource Groups
4. Service Classes
5. Classification Groups
6. Classification Rules
7. Report Classes
8. Service Coefficients/Options
9. Application Environments
10. Scheduling Environments
 
Figure 26. Selecting Workload

8. Select option 2 to create a workload, and the Create Workload panel shown in Figure 27 on
page 40 is displayed.

Chapter 3. WLM-Established Stored Procedures Address Spaces 39


 
Workload Notes Options Help
--------------------------------------------------------------------------
Create a Workload
Command ===> ______________________________________________________________

Enter or change the following information:

Workload Name . . . . . . . . DB2RES (Required)


Description . . . . . . . . . Residency for Stored Procedures_

_______________________________________________________
| Selection List empty. Define a workload. (IWMAM200) |
_______________________________________________________
 
Figure 27. Create a Workload

9. Give the workload a name, which can be any name and optionally a description. Press END (PF3)
and the Workload Selection List panel is displayed as shown in Figure 28

 
Workload View Notes Options Help
--------------------------------------------------------------------------
Workload Selection List Row 1 to 1 of 1
Command ===> ______________________________________________________________

Action Codes: 1=Create, 2=Copy, 3=Modify, 4=Browse, 5=Print, 6=Delete,


/=Menu Bar
----Last Change-----
Action Name Description User Date
__ DB2RES Residency for Stored Procedures DB2RES1 1997/11/03
******************************* Bottom of data ********************************
 
Figure 28. Workload Selection List

10. Press END (PF3) to get back to the definition menu and select option 4 to add a service class as
shown in Figure 29 on page 41.

40 Getting Started with DB2 Stored Procedures


 
File Utilities Notes Options Help
--------------------------------------------------------------------------
Functionality LEVEL003 Definition Menu WLM Appl LEVEL004
Command ===> ______________________________________________________________

Definition data set . . : none

Definition name . . . . . ITSO_SJ (Required)


Description . . . . . . . Sysplex at ITSO San Jose

Select one of the


following options. . . . . 4__ 1. Policies
2. Workloads
3. Resource Groups
4. Service Classes
5. Classification Groups
6. Classification Rules
7. Report Classes
8. Service Coefficients/Options
9. Application Environments
10. Scheduling Environments
 
Figure 29. Definition M e n u - Create Service Classes

11. Press Enter and the panel shown in Figure 30 is displayed.

 
Service-Class Notes Options Help
--------------------------------------------------------------------------
Create a Service Class Row 1 to 1 of 1
Command ===> ______________________________________________________________

Service Class Name . . . . . . STPCDDF (Required)


Description . . . . . . . . . Stored Procedures from DDF
Workload Name . . . . . . . . DB2RES (name or ?)
Base Resource Group . . . . . ________ (name or ?)

Specify BASE GOAL information. Action Codes: I=Insert new period,


E=Edit period, D=Delete period.

---Period--- ---------------------Goal---------------------
Action # Duration Imp. Description
i_
******************************* Bottom of data ********************************
 
Figure 30. Create a Service Class

12. Fill in the following information:


• The Service Class Name can be any name.
• The Workload Name should match the one previously defined.
• There is no need for a base resource group.
• Choose “I” to insert a period under action.
Press Enter and the pop-up window shown in Figure 31 on page 42 is displayed.

Chapter 3. WLM-Established Stored Procedures Address Spaces 41


 
Service-Class Notes Options Help
- ___________________________________________ ----------------------------
| Choose a goal type for period 1 | ss Row 1 to 1 of 1
C | | _____________________________
| |
S | 1_ 1. Average response time | ired)
D | 2. Response time with percentile |
W | 3. Execution velocity | or ?)
B | 4. Discretionary | or ?)
| |
S | | I=Insert new period,
E | |
___________________________________________
---Period--- ---------------------Goal---------------------
Action # Duration Imp. Description
i
******************************* Bottom of data ********************************
 
Figure 31. Choose a Goal Type Pop-Up Window - Period 1

13. Choose a goal type according to your performance goals. For this example, we chose 1 for
Average response time. Press Enter and the Average response time goal pop-up window shown in
Figure 32 is displayed.

 
Service-Class Notes Options Help
- ___________________________________________ ----------------------------
| Choose a goal type for period 1 | ss Row 1 to 1 of 1
C | | _____________________________
| |
S | 1 1. Average response time | ired)
D ____________________________________________________________________
W | Average response time goal |
B | |
| Enter a response time of up to 24 hours for period 1 |
S | |
E | Hours . . . . . 0__ (0-24) |
| Minutes . . . . 0__ (0-99) |
| Seconds . . . . 3_____ (0-9999) |
A | |
| Importance . . 1 (1=highest, 5=lowest) |
* | Duration . . . 10000____ (1-999,999,999, or | ********
| none for last period) |
| |
| |
| F1=Help F2=Split F5=KeysHelp F9=Swap F12=Cancel |
____________________________________________________________________
 
Figure 32. Average Response Time Goal Pop-Up Window

14. On this pop-up window, enter the values of your choice for the response time, importance, and
duration, for the first service class period. When you press Enter, the panel displayed in Figure 33
on page 43 is displayed.

42 Getting Started with DB2 Stored Procedures


 
Service-Class Notes Options Help
--------------------------------------------------------------------------
Create a Service Class Row 1 to 2 of 2
Command ===> ______________________________________________________________

Service Class Name . . . . . . STPCDDF (Required)


Description . . . . . . . . . Stored Procedures from DDF
Workload Name . . . . . . . . DB2RES (name or ?)
Base Resource Group . . . . . ________ (name or ?)

Specify BASE GOAL information. Action Codes: I=Insert new period,


E=Edit period, D=Delete period.

---Period--- ---------------------Goal---------------------
Action # Duration Imp. Description
__
i_ 1 10000 1 Average response time of 00:00:03.000
******************************* Bottom of data ********************************

_________________________________________________________________________
| Press EXIT to save your changes or CANCEL to discard them. (IWMAM970) |
_________________________________________________________________________
 
Figure 33. Create a Service Class Panel - Period 1

15. To create another service class enter “I” under action and the Choose a goal type for period 2,
pop-up window shown in Figure 34, is displayed.

 
Service-Class Notes Options Help
- ___________________________________________ ----------------------------
| Choose a goal type for period 2 | ss Row 1 to 2 of 2
C | | _____________________________
| |
S | _1 1. Average response time | ired)
D | 2. Response time with percentile | es from DDF
W | 3. Execution velocity | or ?)
B | 4. Discretionary | or ?)
| |
S | F1=Help F2=Split F5=KeysHelp | I=Insert new period,
E | F9=Swap F12=Cancel |
___________________________________________
---Period--- ---------------------Goal---------------------
Action # Duration Imp. Description
__
i 1 10000 1 Average response time of 00:00:03.000
******************************* Bottom of data *******************************
 
Figure 34. Choose a Goal Type for Period 2 Pop-Up Window

16. For this definition, we also chose 1 for Average response time. After you press Enter, the Average
response time goal pop-up window shown in Figure 35 on page 44 is displayed.

Chapter 3. WLM-Established Stored Procedures Address Spaces 43


 
Service-Class Notes Options Help
- ___________________________________________ ----------------------------
| Choose a goal type for period 2 | ss Row 1 to 2 of 2
C | | _____________________________
| |
S | 1 1. Average response time | ired)
D ___________________________________________________________________
W | Average response time goal |
B | |
| Enter a response time of up to 24 hours for period 2 |
S | |
E | Hours . . . . . 0_ (0-24) |
| Minutes . . . . 0_ (0-99) |
| Seconds . . . . 50____ (0-9999) |
A | |
| Importance . . 2 (1=highest, 5=lowest) |
| Duration . . . _________ (1-999,999,999, or |
* | none for last period) | *******
| |
| |
| F1=Help F2=Split F5=KeysHelp F9=Swap F12=Cancel |
____________________________________________________________________
 
Figure 35. Average Response Time Goal Pop-Up Window - Period 2

17. On this pop-up window, enter values of your choice for the response time, importance, and
duration, for the service class period 2. If this is the last service class period, you do not specify a
duration. When you press Enter, the panel displayed in Figure 36 is displayed.

 
Service-Class Notes Options Help
--------------------------------------------------------------------------
Create a Service Class Row 1 to 3 of 3
Command ===> ______________________________________________________________

Service Class Name . . . . . . STPCDDF (Required)


Description . . . . . . . . . Stored Procedures from DDF
Workload Name . . . . . . . . DB2RES (name or ?)
Base Resource Group . . . . . ________ (name or ?)

Specify BASE GOAL information. Action Codes: I=Insert new period,


E=Edit period, D=Delete period.

---Period--- ---------------------Goal---------------------
Action # Duration Imp. Description
__
__ 1 10000 1 Average response time of 00:00:03.000
__ 2 2 Average response time of 00:00:50.000
******************************* Bottom of data *******************************
 
Figure 36. Create a Service Class Panel - 2 Service Class Periods

18. Press PF3 to save changes and exit. The panel shown in Figure 37 on page 45 is displayed.

44 Getting Started with DB2 Stored Procedures


 
Service-Class View Notes Options Help
--------------------------------------------------------------------------
Service Class Selection List Row 1 to 1 of 1
Command ===> ______________________________________________________________

Action Codes: 1=Create, 2=Copy, 3=Modify, 4=Browse, 5=Print, 6=Delete,


/=Menu Bar

Action Class Description Workload


__ STPCDDF Stored Procedures from DDF BATPIG
******************************* Bottom of data ********************************
 
Figure 37. Choose a Goal Type Pop-Up Window

19. Press PF3 again to get back to the definition menu panel (Figure 29 on page 41).
You can now associate a stored procedure with classification rules. Choose option 6 as shown in
Figure 38.

 
File Utilities Notes Options Help
------------------------------------------------------------------------
Functionality LEVEL001 Definition Menu WLM Appl LEVEL004
Command ===> ___________________________________________________________

Definition data set . . : none

Definition name . . . . . ITSO_SJ (Required)


Description . . . . . . . Sysplex at ITSO San Jose

Select one of the


following options. . . . . 6__ 1. Policies
2. Workloads
3. Resource Groups
4. Service Classes
5. Classification Groups
6. Classification Rules
7. Report Classes
8. Service Coefficients/Options
9. Application Environments
10. Scheduling Environments
 
Figure 38. Definition M e n u - Classification Rules

The panel shown in Figure 39 on page 46 is displayed. Some subsystem types already come
predefined.

Chapter 3. WLM-Established Stored Procedures Address Spaces 45


 
Subsystem-Type View Notes Options Help
------------------------------------------------------------------------
Subsystem Type Selection List for Rules Row 1 to 12
Command ===> ___________________________________________________________

Action Codes: 1=Create, 2=Copy, 3=Modify, 4=Browse, 5=Print, 6=Delete,


/=Menu Bar

------Class-------
Action Type Description Service Report
__ ASCH Use Modify to enter YOUR rules
__ CICS Use Modify to enter YOUR rules
__ DB2 Use Modify to enter YOUR rules
3_ DDF Use Modify to enter YOUR rules
__ IMS Use Modify to enter YOUR rules
__ IWEB Use Modify to enter YOUR rules
__ JES Use Modify to enter YOUR rules
__ LSFM Use Modify to enter YOUR rules
__ OMVS Use Modify to enter YOUR rules
__ SOM Use Modify to enter YOUR rules
__ STC Use Modify to enter YOUR rules
__ TSO Use Modify to enter YOUR rules
******************************* Bottom of data *************************
 
Figure 39. Subsystem Type Selection List for Rules

20. On the definition menu panel, you can select the subsystem types for which your client program
invokes the stored procedure. Just as an example, we choose DDF. For an explanation of how the
performance policies apply to stored procedures, refer to 3.1.3, “Classification Rules” on page 28.
Enter 3 under action to modify the rules of the DDF subsystem type. The panel in Figure 40 is
displayed.

 
Subsystem-Type Xref Notes Options Help
--------------------------------------------------------------------------
Modify Rules for the Subsystem Type Row 1 to 1 of 1
Command ===> ____________________________________________ SCROLL ===> PAGE

Subsystem Type . : DDF Fold qualifier names? Y (Y or N)


Description . . . DRDA Stored Procedures

Action codes: A=After C=Copy M=Move I=Insert rule


B=Before D=Delete row R=Repeat IS=Insert Sub-rule
-------Qualifier------------- -------Class--------
Action Type Name Start Service Report
DEFAULTS: STPCDDF ________
is__ 1 si dbc1_ ___ STPCDDF ________
***************************** BOTTOM OF DATA ******************************
 
Figure 40. Create Rules for the Subsystem Type

21. On this panel:


a. Type any description for Description.
b. Type one of your defined service class names for DEFAULTS.
c. Under Action, type is to insert a subrule.

46 Getting Started with DB2 Stored Procedures


d. Type si for Type to indicate the DB2 subsystem type.
e. Type the DB2 subsystem name under Name.
f. Type one of your defined service class names under Service for DB2 applications running
under DDF.
For this example, the service class specified as the default is the same as the service class
specified for the DB2 subsystem DBC1. In a real environment, the service class for the stored
procedure is likely to be different from the default. Press Enter and the panel on Figure 41 is
displayed.

 
Subsystem-Type Xref Notes Options Help
--------------------------------------------------------------------------
Modify Rules for the Subsystem Type Row 1 to 2 of 2
Command ===> ____________________________________________ SCROLL ===> PAGE

Subsystem Type . : DDF Fold qualifier names? Y (Y or N)


Description . . . DRDA Stored Procedures

Action codes: A=After C=Copy M=Move I=Insert rule


B=Before D=Delete row R=Repeat IS=Insert Sub-rule
-------Qualifier------------- -------Class--------
Action Type Name Start Service Report
DEFAULTS: STPCDDF ________
____ 1 SI DBC1 ___ STPCDDF ________
____ 2 PR STPC1___ ___ STPCDDF ________
****************************** BOTTOM OF DATA ******************************

__________________________________________
| Qualifier name is required. (IWMAM724) |
F1=Help F2 __________________________________________ F8=Down
 
Figure 41. Modify Rules for the Subsystem Type

22. On this panel:


a. Type PR under Type to indicate this is a stored procedure.
b. Type the stored procedure name under Name.
c. Type the service class that you want this stored procedure to execute.
The DB2 for OS/390 Administration Guide has a more complete example of how to fill in this panel.
Press PF3 to save your changes and press PF3 once again to get to the Definition Menu panel as
shown in Figure 42 on page 48

Chapter 3. WLM-Established Stored Procedures Address Spaces 47


 
File Utilities Notes Options Help
--------------------------------------------------------------------------
Functionality LEVEL003 Definition Menu WLM Appl LEVEL004
Command ===> ______________________________________________________________

Definition data set . . : none

Definition name . . . . . ITSO_SJ (Required)


Description . . . . . . . Sysplex at ITSO San Jose

Select one of the


following options. . . . . 9__ 1. Policies
2. Workloads
3. Resource Groups
4. Service Classes
5. Classification Groups
6. Classification Rules
7. Report Classes
8. Service Coefficients/Options
9. Application Environments
10. Scheduling Environments
 
Figure 42. Definition M e n u - Application Environments

23. Choose option 9 to define the application environment for a stored procedure (or a group of stored
procedures) and the Create an Application Environment panel (Figure 43) is displayed.

 
Application-Environment Notes Options Help
--------------------------------------------------------------------------
Create an Application Environment
Command ===> ______________________________________________________________

Application Environment . . . WLM_ENV1 Required


Description . . . . . . . . . stored procedures
Subsystem Type . . . . . . . . DB2 Required
Procedure Name . . . . . . . . DBC1WLM1
Start Parameters . . . . . . . DB2SSN=&IWMSSNM,NUMTCB=2,APPLENV=′ WLM_EN
V1′_____________________________________
___________________________________

Limit on starting server address spaces for a subsystem instance:


1 1. No limit
2. Single address space per system
3. Single address space per sysplex
 
Figure 43. Create an Application Environment

24. Specify details for the application environment. Refer to 3.2.2, “Specifying Application
Environments to WLM” on page 30 for an explanation of each entry field. Press END (PF3) to get
back to the application environment selection list, and the Application Environment Selection List
panel in Figure 44 on page 49 is displayed.

48 Getting Started with DB2 Stored Procedures


 
Application-Environment Notes Options Help
--------------------------------------------------------------------------
Application Environment Selection List Row 1 to 1 of 1
Command ===> ______________________________________________________________

Action Codes: 1=Create, 2=Copy, 3=Modify, 4=Browse, 5=Print, 6=Delete,


/=Menu Bar

Action Application Environment Name Description


__ WLM_ENV1 stored procedures
******************************* Bottom of data ********************************
 
Figure 44. Application Environment Selection List Panel

Press END (PF3) to get back to the definition menu


25. Place the cursor at the Utilities pull-down, press Enter and the pull-down menu shown in Figure 45
is displayed.

 
File Utilities Notes Options Help
----- ___________________________________________________ ----------------
Funct | 1 1. Install definition | Appl LEVEL004
Comma | 2. Extract definition | _________________
| 3. Activate service policy |
Defin | 4. Allocate couple data set |
| 5. Allocate couple data set using CDS values |
Defin ___________________________________________________
Description . . . . . . . Sysplex at ITSO San Jose

Select one of the


following options. . . . . ___ 1. Policies
2. Workloads
3. Resource Groups
4. Service Classes
5. Classification Groups
6. Classification Rules
7. Report Classes
8. Service Coefficients/Options
9. Application Environments
10. Scheduling Environments
 
Figure 45. Utility Pull-Down M e n u

26. Select option 1 to install the definition created. When the definition is installed, the following
message appears on the definition menu panel:
Service definition was installed. (IWMAM038)
27. Place the cursor at the Utilities pull-down and press Enter. Select option 3 to activate a service
policy and the Policy Selection List panel shown in Figure 46 on page 50 is displayed.

Chapter 3. WLM-Established Stored Procedures Address Spaces 49


 
File Utilities Notes Options Help
- _________________________________________________________________________
F | Policy Selection List Row 1 to 6 of 15 |
C | Command ===> ________________________________________________________ |
| |
D | The following is the current Service Definition installed on the WLM |
| couple data set. |
D | |
D | Name . . . . : ITSO_SJ |
| |
S | Installed by : DB2RES1 from system SC62 |
f | Installed on : 1997/11/03 at 21:02:40 |
| |
| Select the policy to be activated with ″ / ″ |
| |
| Sel Name Description |
| _ DAYTIME Policy from 9:00 am to 5:00 pm |
_________________________________________________________________________
 
Figure 46. Policy Selection List Panel

28. Select the service policy (we have only one) and press Enter.

3.8 Existing Service Definition


If your installation is already using a WLM service definition, for scheduling purposes you need only
add at least one application environment for your stored procedure (or group of stored procedures). In
addition, you can define a service class with appropriate service class periods for the stored
procedure.

To work with an already defined WLM service definition, invoke the WLM ISPF application and select
option 2 Extract definition from the Choose Service Definition panel shown in Figure 47.

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

Command ===> ______________________________________________________________

_______________________________________________
| Choose Service Definition |
| |
| Select one of the following options. |
| 2_ 1. Read saved definition |
| 2. Extract definition from WLM |
| couple data set |
| 3. Create new definition |
| |
| |
| |
_______________________________________________
ENTER to continue
 
Figure 47. Choose Service Definition Panel

50 Getting Started with DB2 Stored Procedures


Use option 9 to define an application environment or option 4 to define a service class. How to fill in
the definitions for the application environment and service class is described in 3.7, “Defining a
Service Definition” on page 35.

3.9 Placing WLM JCL Procedure in a PROCLIB


You have to place the JCL procedure in an accessible PROCLIB data set, such as SYS1.PROCLIB. The
member name must match the procedure name specified in the application environment definition.

Here is an example of this JCL:


//*************************************************************
//* JCL PROCEDURE FOR THE STARTUP OF THE
//* DB2 STORED PROCEDURES ADDRESS SPACE
//* RGN -- THE MVS REGION SIZE FOR THE ADDRESS SPACE.
//* SUBSYS -- THE DB2 SUBSYSTEM NAME.
//* NUMTCB -- THE NUMBER OF TCBS TO BE USED TO
//* PROCESS STORED PROCEDURE REQUESTS.
//*
//*************************************************************
//DBC1WLM2 PROC RGN=0K,DB2SSN=DBC1,NUMTCB=8,APPLENV=
//IEFPROC EXEC PGM=DSNX9WLM,REGION=&RGN,TIME=NOLIMIT,
// PARM=′&DB2SSN,&NUMTCB,&APPLENV.′
//STEPLIB DD DISP=SHR,DSN=DSN510.SDSNLOAD
// DD DISP=SHR,DSN=CEE.SCEERUN
To avoid JCL errors when WLM starts the procedure, you may want to check the JCL by running the
following job, with TYPRUN=SCAN and using the parameter string you have for start parameters in
the application environment definition. Here is an example:
//CHECKING JOB (999,POK),′ SAVE TIME′ , NOTIFY=&SYSUID.,
// CLASS=A,MSGCLASS=T,REGION=5000K,
// TYPRUN=SCAN,
// MSGLEVEL=(1,1)
// EXEC DBC1WLM2,DB2SSN=DBC1,NUMTCB=2,APPLENV=WLMENV2

3.10 Updating SYSIBM.SYSPROCEDURES

Update WLM_ENV in SYSIBM.SYSPROCEDURES (or an equivalent view) to associate a stored


procedure with an application environment. We can use SPUFI, QMF or the DB2 administration tool
(5688-515) with V5 run-under support to update or insert a row. If using QMF, issue the draw
command:
draw sysibm.sysprocedures (type=insert
You get the SQL template shown in Figure 48 on page 52:

Chapter 3. WLM-Established Stored Procedures Address Spaces 51


 
SQL QUERY MODIFIED LINE 1

INSERT INTO SYSIBM.SYSPROCEDURES (PROCEDURE, AUTHID, LUNAME, LOADMOD,


LINKAGE, COLLID, LANGUAGE, ASUTIME, STAYRESIDENT, IBMREQD, RUNOPTS,
PARMLIST, RESULT_SETS, WLM_ENV, PGM_TYPE, EXTERNAL_SECURITY,
COMMIT_ON_RETURN)
VALUES ( NULLS
-- ENTER VALUES BELOW COLUMN NAME DATA TYPE LENGTH NO
, -- PROCEDURE CHAR 18 NO
, -- AUTHID CHAR 8 NO
, -- LUNAME CHAR 8 NO
, -- LOADMOD CHAR 8 NO
, -- LINKAGE CHAR 1 NO
, -- COLLID CHAR 18 NO
, -- LANGUAGE CHAR 8 NO
, -- ASUTIME INTEGER NO
, -- STAYRESIDENT CHAR 1 NO
, -- IBMREQD CHAR 1 NO
, -- RUNOPTS VARCHAR 254 NO
, -- PARMLIST LONG VARCHAR 3000 NO
, -- RESULT_SETS SMALLINT 2 NO
, -- WLM_ENV CHAR 18 NO
, -- PGM_TYPE CHAR 1 NO
, -- EXTERNAL_SECURITY CHAR 1 NO
) -- COMMIT_ON_RETURN CHAR 1 YES
*** END ***

1=Help 2=Run 3=End 4=Print 5=Chart 6=Draw


7=Backward 8=Forward 9=Form 10=Insert 11=Delete 12=Report
OK, insert query for table SYSIBM.SYSPROCEDURES drawn.
COMMAND ===> SCROLL ===> CSR
 
Figure 48. SQL Template

If you are using an existing stored procedure that used the DB2-established address space, you have
to update the WLM_ENV column with the value of the application environment. You also have to
re-link-edit the stored procedure with the DSNRLI module, which is the RRSAF language interface. You
should add the following to the link-edit step:
INCLUDE SYSLIB(DSNRLI)
If you want the stored procedure load module to execute on both the DB2-established and the
WLM-established address spaces, you have to link-edit it with both language interfaces: DSNALI and
DSNRLI. In this case, you must have different names for the stored procedure, that is, two entries in
the SYSIBM.SYSPROCEDURES table, both with the same value for the LOADMOD column.

Table 4. Sample Setup To Test Same Program in DB2- and WLM- Address Spaces
stored procedure address space DB2-established WLM-established

PROCEDURE name MYSTORPROCDB2 MYSTORPROCWLM


LOADMOD name MYPGM MYPGM
Linked with: DSNALI DSNRLI
Load library USER.LOAD.DB2 USER.LOAD.WLM

52 Getting Started with DB2 Stored Procedures


3.11 RACF Considerations for WLM-Established Address Space
For WLM-established address spaces you can use the primary authorization ID related to the client
application. To use the primary authorization ID of the client application, specify the value Y for the
EXTERNAL_SECURITY column of SYSIBM.SYSPROCEDURES. You should specify this option only if you
access non-DB2 resources and you want to check the privileges of the client authorization ID instead of
the WLM-established address space. If you specify N, all considerations described in 2.2.2, “RACF
Considerations for DB2-Established Address Space” on page 11 also apply to WLM-established
address spaces. The following considerations apply if you specify Y for the EXTERNAL_SECURITY
column.

If you have inbound translation, the translated authorization ID is used.

The RACF ID and group name that you select must have authority to run the Recoverable Resource
Manager attachment facility (RRSAF) application programs.

When you access non-DB2 resources such as VSAM files and flat files in your stored procedure, you
must ensure that the RACF ID associated with the client application has the privileges needed for the
access.

Note that when you access non-DB2 resources such as VSAM or QSAM files, DB2 does not provide
serialization for stored procedures that run in the WLM-established address space; you must provide
the serialization in the stored procedure code.

If you try to run a stored procedure with EXTERNAL_SECURITY=Y in a DB2-established address space,
you get a -471 SQLCODE with reason code 00E79009.

3.12 Operations and Problem Determination


If RRS is not active, the WLM address space does not get started. You receive the following message:
+DSNX982I DSNX9WLM ATTEMPT TO PERFORM RRS ATTACH FUNCTION SPAS_ID
FAILED WITH RRS RC = 00000008 RSN = 00F30091 SSN = DBC1
PROC= WLMENV2 ASID = 01FB WLM_ENV = WLMENV2

If you define the symbolic parameter APPLENV with some of the characters in lowercase, the WLM
address space is not started and you get the following message:
IEF403I WLMENV3 - STARTED - TIME=22.14.44
+DSNX981E DSNX9WLM THE PARAMETER APPLEN CONTAINS AN INVALID VALUE
2,WLM_ENVIrONMENT_03 PROC= WLMENV3
IEA995I SYMPTOM DUMP OUTPUT
SYSTEM COMPLETION CODE=0C4 REASON CODE=00000011

When you display the WLM environment, the application environment is in a STOPPED state:
RESPONSE=SC62
IWM029I 22.20.04 WLM DISPLAY 170
APPLICATION ENVIRONMENT NAME STATE STATE DATA
WLM_ENVIRONMENT_03 STOPPED
ATTRIBUTES: PROC=WLMENV3 SUBSYSTEM TYPE: DB2

After you modify the APPLENV parameter in the application environment definition and activate the
policy, you get the following message:

Chapter 3. WLM-Established Stored Procedures Address Spaces 53


IWM001I WORKLOAD MANAGEMENT POLICY DAYTIME NOW IN EFFECT
IWM032I INTERNAL REFRESH FOR WLM_ENVIRONMENT_03 COMPLETED
D WLM,APPLENV=WLM_ENVIRONMENT_03
IWM032I INTERNAL STOP FOR WLM_ENVIRONMENT_03 COMPLETED
IWM029I 22.22.21 WLM DISPLAY 213
APPLICATION ENVIRONMENT NAME STATE STATE DATA
WLM_ENVIRONMENT_03 STOPPING ** NO SYSTEMS **
ATTRIBUTES: PROC=WLMENV3 SUBSYSTEM TYPE: DB2

You can use the following display command to check the active policy name:
D WLM
The result of the command is the following:
D WLM
IWM025I 13.50.04 WLM DISPLAY 806
ACTIVE WORKLOAD MANAGEMENT SERVICE POLICY NAME: DAYTIME
ACTIVATED: 1997/11/02 AT: 23:52:04 BY: DB2RES1 FROM: SC62
DESCRIPTION: Policy from 9:00 am to 5:00 pm
RELATED SERVICE DEFINITION NAME: ITSO_SJ
INSTALLED: 1997/11/02 AT: 23:51:57 BY: DB2RES1 FROM: SC62
WLM VERSION LEVEL: LEVEL004
Use the following display command to check which application environments are defined:
D WLM,APPLENV=*
The result of the command is the following:
D WLM,APPLENV=*
IWM029I 15.45.12 WLM DISPLAY 360
APPLICATION ENVIRONMENT NAME STATE STATE DATA
APENVIRON AVAILABLE
WLMENV1 AVAILABLE
WLMENV2 STOPPED
You can activate another policy by issuing the following command:
V WLM,POLICY=policyname,RESUME

If your client program is hanging, waiting for a response from a stored procedure on OS/390, then
perform the following:
1. Display all threads at the server using -DIS THD(*) LOC(*) and look for the P R O C = field.
DSNV401I =DBC1 DISPLAY THREAD REPORT FOLLOWS -
DSNV402I =DBC1 ACTIVE THREADS -
NAME ST A REQ ID AUTHID PLAN ASID TOKEN
SERVER SW * 2 CMD.EXE DB2V5 DISTSERV 0204 141
V429 CALLING PROCEDURE=PPMMSSMW3 , LOAD MODULE=PPMMSSM0,
PROC= , ASID=0000, WLM_ENV=WLMENV3
V445-09019639.0461.AF813BF41AD8=141 ACCESSING DATA FOR 9.1.150.57
DISPLAY ACTIVE REPORT COMPLETE
DSN9022I =DBC1 DSNVDT ′ -DIS THD′ NORMAL COMPLETION
If it is blank, there can be a problem with the application environment.
2. Issue the display command to check the state of the application environment:
D WLM,APPLENV=WLM_ENV4
IWM029I 23.40.55 WLM DISPLAY 514
APPLICATION ENVIRONMENT NAME STATE STATE DATA
WLM_ENV4 STOPPED
ATTRIBUTES: PROC=WLMENV4 SUBSYSTEM TYPE: DB2
3. If it is in STOPPED state, issue the VARY command with the resume option:

54 Getting Started with DB2 Stored Procedures


VARY WLM,APPLENV=WLM_ENV4,RESUME
IWM034I PROCEDURE WLMENV4 STARTED FOR SUBSYSTEM DBC1 528
APPLICATION ENVIRONMENT WLM_ENV4
PARAMETERS DB2SSN=DBC1,NUMTCB=2,APPLENV=′ WLM_ENV4′
IWM032I VARY RESUME FOR WLM_ENV4 COMPLETED
$HASP100 WLMENV4 ON STCINRDR
IEFC452I WLMENV4 - JOB NOT RUN - JCL ERROR 531

$HASP396 WLMENV4 TERMINATED


4. If you get a JCL error, correct the error and issue the VARY command again:
VARY WLM,APPLENV=WLM_ENV4,RESUME
IWM034I PROCEDURE WLMENV4 STARTED FOR SUBSYSTEM DBC1 551
APPLICATION ENVIRONMENT WLM_ENV4
PARAMETERS DB2SSN=DBC1,NUMTCB=2,APPLENV=′ WLM_ENV4′
IWM032I VARY RESUME FOR WLM_ENV4 COMPLETED
$HASP100 WLMENV4 ON STCINRDR
$HASP373 WLMENV4 STARTED
IEF403I WLMENV4 - STARTED - TIME=23.45.39

For our DB2 subsystem, DBC1, STORTIME is set at 180, indicating that a stored procedure times out
after 180 seconds. Queued requests time out when the STORTIME value is exceeded. If the client
program that invokes the stored procedure is running on a client workstation and the client workstation
cannot interpret the SQLCODE, you get the following message:
SQL0969N There is no message text corresponding to SQL error ″-471″ in the
message file on this workstation. The error was returned from module
DSNX9WCA″ with original tokens ″PPMMSSMW 00E79002 ″ . SQLSTATE=
The explanation for this error is the following:
Explanation: DB2 received an SQL CALL statement for a stored
procedure. The CALL statement
was not accepted because of DB2 reason code 00E79002.
SQLSTATE=55023

If you don′t specify the APPLENV symbolic parameter either in the JCL procedure or in the start
parameters of the application environment definition, then when the address space is started, you get
the following messages:
IWM034I PROCEDURE DBC1WLM2 STARTED FOR SUBSYSTEM DBC1 599
APPLICATION ENVIRONMENT WLMENV2
PARAMETERS DB2SSN=DBC1,NUMTCB=1
$HASP100 DBC1WLM2 ON STCINRDR
$HASP373 DBC1WLM2 STARTED
IEF403I DBC1WLM2 - STARTED - TIME=18.10.35
+DSNX981E DSNX9WLM THE PARAMETER APPLEN CONTAINS AN INVALID VALUE 603
PROC= DBC1WLM2
IEA995I SYMPTOM DUMP OUTPUT 604
SYSTEM COMPLETION CODE=0C4 REASON CODE=00000004
WLM tries to start the address space three times. After failing for three times, the WLM places the
application environment in the STOPPED state. You can verify this by issuing the DISPLAY WLM
command:
D WLM,APPLENV=WLMENV2
IWM029I 18.13.43 WLM DISPLAY 640
APPLICATION ENVIRONMENT NAME STATE STATE DATA
WLMENV2 STOPPED
ATTRIBUTES: PROC=DBC1WLM2 SUBSYSTEM TYPE: DB2

Chapter 3. WLM-Established Stored Procedures Address Spaces 55


Although the application environment is in STOPPED state, DB2 does not stop the queuing of the
stored procedure. If you issue the DISPLAY PROC command, you can verify that the STATUS of the
stored procedure is started:
DSNX940I =DBC1 DSNX9DIS DISPLAY PROCEDURE REPORT FOLLOWS -
PROCEDURE MODULE STATUS ACTIVE MAXACT QUEUED MAXQUE TIMEOUT
PPMMSSMW STARTED 0 0 0 31 0
PPMMSSMW PPMMSSM0 STARTED 0 17 0 30 7
DSNX9DIS DISPLAY PROCEDURE REPORT COMPLETE
If you don′t fix the problem, the client application times out.

If you want to check WLM data sets and usage in a Sysplex environment, you can issue the following
command:
D XCF,COUPLE,TYPE=WLM
You get the following information:
IXC358I 18.45.14 DISPLAY XCF 384
WLM COUPLE DATA SETS
PRIMARY DSN: SYS1.WLMR4.CDS01
VOLSER: TOTDS0 DEVN: 0CEE
FORMAT TOD MAXSYSTEM
05/29/1997 18:39:02 32
ALTERNATE DSN: SYS1.WLMR4.CDS02
VOLSER: TOTDS1 DEVN: 0FEE
FORMAT TOD MAXSYSTEM
05/29/1997 18:39:04 32
WLM IN USE BY ALL SYSTEMS

3.13 Experimenting with Goal and Compatibility Modes

In this section, we show how WLM-established stored procedures behave under goal and compatibility
modes. We also tested automatic control (where WLM knows the name of the JCL procedure to start
the WLM-established stored procedure) and manual control (where WLM does not know the name of
the JCL procedure). We highlight the differences in starting and stopping stored procedures address
spaces using MVS operator commands and WLM commands.

3.13.1 DB2 and WLM Setup


We defined two service classes to WLM:
• SCDB2STP for general stored procedures
• HIGHPRT for high priority work, with the minimum allowed value for average response time.
The following is the extract for the SCDB2STP service class:
* Service Class SCDB2STP - serv class for db2 stored proc

Base goal:

# Duration Imp Goal description


- --------- - ----------------------------------------
1 1000 2 Average response time of 00:00:30.000
2 4 Average response time of 00:04:00.000
The following is the extract for the HIGHPRT service class:

56 Getting Started with DB2 Stored Procedures


* Service Class HIGHPRT - test sched + 1 ad spc

Base goal:

# Duration Imp Goal description


- --------- - ----------------------------------------
1 5 Average response time of 00:00:00.015

3.13.2 Client and Server Programs Used for Testing Purposes


We used modified versions of the PL/I sample stored procedure, for which the source is in member
DSN8EP2 of SDSNSAMP data set. We implemented two versions of the stored procedure. In the first
version, the stored procedure executes as shipped in SDSNSAMP data set, with the inclusion of a
DISPLAY statement to display the date and time string on the console. If you use the DISPLAY
statement, you have to add a SYSOUT DD statement to the WLM-established stored procedure JCL.

For the second version, the DISPLAY statement is with REPLY (DISPLAY and ACCEPT).
dcl response char (1) init(′ R′ ) ;
display (′ respond with ″ ′ | | response || ′ ″ ′ ) reply (response) ;

The program waits for operator response. This way, we could easily start a number of client programs
and control how they are dispatched by entering the required responses through the MVS console.

We invoke this stored procedure using the sm0pmcr2.cmd REXX command from an OS/2 client. This
sample program stored procedure executes commands passed by the client program.

3.13.3 WLM Goal Mode Using Automatic Control


We performed the following tests using WLM in goal mode and having automatic control.

To display the status of the WLMENV2 application environment, we issued the following command:
DISPLAY WLM,APPLENV=WLMENV2
We got the following output:
IWM029I 14.15.07 WLM DISPLAY 998
APPLICATION ENVIRONMENT NAME STATE STATE DATA
WLMENV2 AVAILABLE
ATTRIBUTES: PROC=DBC1WLM2 SUBSYSTEM TYPE: DB2

3.13.3.1 Test WLM Management of Multiple Address Spaces: The following are the tests
performed to check WLM capabilities of managing multiple address spaces:
1. We set the maximum number of TCBs (NUMTCB) for the WLM-established stored procedure to
one. The stored procedure is classified under the general service class, SCDB2STP. When we
started the client program, WLM started up one WLM-established stored procedure. WLM issues
the following messages when the address space is started:
IWM034I PROCEDURE DBC1WLM2 STARTED FOR SUBSYSTEM DBC1
APPLICATION ENVIRONMENT WLMENV2
PARAMETERS DB2SSN=DBC1,NUMTCB=1,APPLENV=WLMENV2
2. We invoked 30 identical client programs using the first version of the stored procedure, which uses
a very small amount of resource and completes in a very short time. Because the performance
goals were met, WLM did not start another address space.
3. We changed the WLM classification so that the stored procedure now uses the high priority service
class, HIGHPRT. We invoked 30 client programs, but now calling the second version of the stored
procedure. We did not reply immediately to the pending message on the MVS console, which

Chapter 3. WLM-Established Stored Procedures Address Spaces 57


made the executing stored procedures wait. WLM starts multiple address spaces for the stored
procedures in order to honor the aggressive service class.
4. We now reply to each console message and each stored procedure completes. All submitted
client programs terminated after the respective replies were entered on the MVS console.
5. After about 8 to 10 minutes, without submitting any more work, WLM brought down all but one
WLM-established stored procedure.

3.13.3.2 Operator Commands: The following are the tests we performed using operator
commands having WLM in goal mode and automatic control:
1. We succeeded in canceling stored procedures address space using an operator command (instead
of QUIESCE). The address space came down with the following command:
C DBC1WLM2,APPLENV=WLMENV2
If WLM decides it needs the address space, WLM starts it again. If WLM decides it no longer
needs them, it does not start them up.
2. We issued the following command with the QUIESCE option:
VARY WLM,APPLENV=WLMENV2,QUIESCE
WLM brought down all address spaces for this application environment and issued the following
message:
IWM032I VARY QUIESCE FOR WLMENV2 COMPLETED

3.13.4 WLM Compatibility Mode Using Automatic Control


We performed the following tests with WLM in compatibility mode and with automatic control:
1. We submitted the client application, without any stored procedures address space started and, as
expected, WLM did not start the address space. For the stored procedure to be executed, we had
to start the address space using the MVS start command.
2. We started the address space and issued the vary command with the QUIESCE option. Unlike goal
mode, the address space is still up. When we issued the display command, we got the following
message, indicating that the application environment was in the QUIESCING state:
IWM029I 16.14.33 WLM DISPLAY 003
APPLICATION ENVIRONMENT NAME STATE STATE DATA
WLMENV2 QUIESCING SC62
ATTRIBUTES: PROC=DBC1WLM2 SUBSYSTEM TYPE: DB2
3. While the address space was in the QUIESCING state, we submitted the client program and the
stored procedure was queued and immediately executed.
4. When we canceled the last address space WLM quiesced the application environment.
5. When no address spaces started, the state of the application environment was QUIESCED, and we
submitted the client application, then the stored procedure was queued.
6. We then issued the start MVS command. The address space was started, but since the state of the
application environment was QUIESCED, the stored procedure was not executed. We got the
following messages when we issued the MVS start command for the stored procedures address
space:
IEF403I DBC1WLM2 - STARTED - TIME=17.48.40
+DSNX968I DSNX9WLM STORED PROCEDURE ADDRESS SPACE IS UNABLE TO CONNECT
TO WLM BECAUSE WLM_ENV = WLMENV2 IS STOPPED OR QUIESCED
- --TIMINGS (MINS.)--
7. When we issued the command to vary the application environment with the resume option, the
stored procedure was executed.

58 Getting Started with DB2 Stored Procedures


3.14 Implementing OS/390 Resource Recovery Services (RRS) Support

To use WLM-established stored procedures address spaces, you have to implement OS/390 resource
recovery services (RRS). You must be running your system in one of two Sysplex environments.
Check the PLEXCFG parameter of IEASYSnn member in SYS1.PARMLIB:
• If the parameter specification is PLEXCFG=(MULTISYSTEM,OPI=NO), it indicates that the system
is to be part of a Sysplex consysting of one or more MVS systems that reside on one or more
processors, and share the same Sysplex couple data sets.
• If the parameter specification is PLEXCFG=(MONOPLEX,OPI=NO), it indicates that the system is
to be part of a single-system Sysplex that must use a Sysplex couple data set. In this case, you
don′t need to have a coupling facility nor set up the whole Sysplex environment.
DB2 requires that RRS be active, because WLM-established stored procedure address spaces use the
new RRS attachment facility (RRSAF), not the call attachment facility (CAF) used for DB2-established
stored procedure address space. You cannot use the CAF in WLM-established stored procedure
address spaces.

As with the implementation of DB2-established stored procedure address spaces, for WLM-established
address spaces, you cannot explicitly code any call to DSNRLI.

RRS is an MVS system logger application that records events related to protected resources. RRS
records these events in five log streams. In a Sysplex environment, these log streams are shared by
the systems of the Sysplex. Before you can start RRS, you must:
1. Define RRS′ s log streams. The log streams can be placed on DASD or in the coupling facility. If
the log streams are placed in the coupling facility, you must:
a. Add definitions for the structure in the CFRM policy.
b. Define the log streams.
c. Activate the new definitions.
2. Set up the RRS procedure in SYS1.PROCLIB.
3. Define the RRS subsytem to MVS.

3.14.1 RRS Log Streams


To set up your log streams, refer to “Preparing to Use System Logger Applications,” in OS/390 MVS
Setting Up a Sysplex and “Understanding RRS Logging Requirements” in OS/390 MVS Programming:
Resource Recovery .

The five log stream names used by RRS are (where gname can be your Sysplex name or any name in
a non-Sysplex environment):
• Main unit-of-recovery log state stream:
ATR.gname.MAIN.UR
• Delayed unit-of-recovery log state stream:
ATR.gname.DELAYED.UR
• Resource manager data log stream:
ATR.gname.RM.DATA
• Restart log stream:
ATR.gname.RESTART
• Archive log stream (This log is recommended but optional.)
ATR.gname.ARCHIVE

Chapter 3. WLM-Established Stored Procedures Address Spaces 59


To define the RRS log streams, use IXCMIAPU, a utility program provided in the SYS1.MIGLIB system
library.

3.14.1.1 Defining the RRS Log Streams to DASD: In a MONOPLEX environment, you must
allocate your log streams to DASD. Here is an example of the JCL to map each RRS log stream to
DASD:
//STEP1 EXEC PGM=IXCMIAPU
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DATA TYPE(LOGR)
DEFINE LOGSTREAM NAME(ATR.gname.RM.DATA)
DASDONLY(YES)
STG_DATACLAS(vsamls)
LS_DATACLAS(vsamls)
DEFINE LOGSTREAM NAME(ATR.gname.MAIN.UR)
DASDONLY(YES)
STG_DATACLAS(vsamls)
LS_DATACLAS(vsamls)
DEFINE LOGSTREAM NAME(ATR.gname.DELAYED.UR)
DASDONLY(YES)
STG_DATACLAS(vsamls)
LS_DATACLAS(vsamls)
DEFINE LOGSTREAM NAME(ATR.gname.RESTART)
DASDONLY(YES)
STG_DATACLAS(vsamls)
LS_DATACLAS(vsamls)
DEFINE LOGSTREAM NAME(ATR.gname.ARCHIVE)
DASDONLY(YES)
STG_DATACLAS(vsamls)
LS_DATACLAS(vsamls)
/*
Note that:
• gname can be any name of your choice. When you start RRS, you must specify for the gname
parameter of the JCL procedure the same gname specified when you created your log streams. If
you do not specify the name when starting RRS, the default is the Sysplex name.
• vsamls is an SMS class defined for linear VSAM files. You can set up a new SMS class or use an
existing SMS class for VSAM linear data sets.
To verify the data classes already defined in SMS, you can invoke the SMS ISPF application,
choose option 4, and list all defined SMS classes.
The log stream (LS) VSAM data sets will be allocated at the time the RRS log streams are defined.
Each data set is prefixed with IXGLOGR and suffixed with A0000000. They will be named as
follows:
IXGLOGR.ATR.gname.ARCHIVE.A0000000
IXGLOGR.ATR.gname.ARCHIVE.A0000000.DATA
The staging (STG) VSAM data sets are allocated at RRS startup. When RRS is canceled, it deletes
the STG data sets. Each data set is prefixed with IXGLOGR and suffixed with the Sysplex name.
They are named as follows:
IXGLOGR.ATR.gname.ARCHIVE.Sysplexn
IXGLOGR.ATR.gname.ARCHIVE.Sysplexn.DATA

If you need to delete the RRS log streams and VSAM data sets generated, you can use the following
example:

60 Getting Started with DB2 Stored Procedures


//STEP1 EXEC PGM=IXCMIAPU
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DATA TYPE(LOGR)
DELETE LOGSTREAM NAME(ATR.gname.RM.DATA)
DELETE LOGSTREAM NAME(ATR.gname.MAIN.UR)
DELETE LOGSTREAM NAME(ATR.gname.DELAYED.UR)
DELETE LOGSTREAM NAME(ATR.gname.RESTART)
DELETE LOGSTREAM NAME(ATR.gname.ARCHIVE)
/*

3.14.1.2 Defining the RRS Log Streams to Use the Coupling Facility: If the RRS log
streams use the coupling facility, you have to update the CFRM policy to add the RRS structures. Here
is an example of the JCL to update the CFRM policy:
//DEFCFRM1 JOB MSGCLASS=X,TIME=10,MSGLEVEL=(1,1),NOTIFY=&SYSUID
//STEP1 EXEC PGM=IXCMIAPU
//SYSPRINT DD SYSOUT=*
//SYSABEND DD SYSOUT=*
//SYSIN DD *
DATA TYPE(CFRM) REPORT(YES)
DEFINE POLICY NAME(CFRM18) REPLACE(YES)
CF NAME(CF01)
TYPE(009672)
MFG(IBM)
PLANT(02)
SEQUENCE(000000040104)
PARTITION(1)
CPCID(00)
DUMPSPACE(2048)

CF NAME(CF02)
TYPE(009672)
MFG(IBM)
PLANT(02)
................
................
................
STRUCTURE NAME(RRS_RM_DATA)
INITSIZE(8000)
SIZE(16000)
PREFLIST(CF02,CF01)
REBUILDPERCENT(5)

STRUCTURE NAME(RRS_MAIN_UR)
INITSIZE(8000)
SIZE(16000)
PREFLIST(CF02,CF01)
REBUILDPERCENT(5)

STRUCTURE NAME(RRS_DELAYED_UR)
INITSIZE(8000)
SIZE(16000)
PREFLIST(CF02.CF01)
REBUILDPERCENT(5)

STRUCTURE NAME(RRS_RESTART)
INITSIZE(8000)
SIZE(16000)

Chapter 3. WLM-Established Stored Procedures Address Spaces 61


PREFLIST(CF02.CF01)
REBUILDPERCENT(5)

STRUCTURE NAME(RRS_ARCHIEVE)
INITSIZE(8000)
SIZE(16000)
PREFLIST(CF02)
REBUILDPERCENT(5)

You can map each log stream to a single structure or you can map log streams of like data types to
the same structure. Here is an example of the JCL to map each RRS log stream to a structure:
//STEP1 EXEC PGM=IXCMIAPU
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DATA TYPE(LOGR)
DEFINE STRUCTURE NAME(RRS_RM_DATA) LOGSNUM(5)
DEFINE STRUCTURE NAME(RRS_MAIN_UR) LOGSNUM(5)
DEFINE STRUCTURE NAME(RRS_DELAYED_UR) LOGSNUM(5)
DEFINE STRUCTURE NAME(RRS_RESTART) LOGSNUM(5)
DEFINE STRUCTURE NAME(RRS_ARCHIEVE) LOGSNUM(5)
DEFINE LOGSTREAM NAME(ATR.gname.RM.DATA)
STRUCTNAME(RRS_RM_DATA)
LS_DATACLAS(vsamls)
DEFINE LOGSTREAM NAME(ATR.gname.MAIN.UR)
STRUCTNAME(RRS_MAIN_UR)
LS_DATACLAS(vsamls)
DEFINE LOGSTREAM NAME(ATR.gname.DELAYED.UR)
STRUCTNAME(RRS_DELAYED.UR)
LS_DATACLAS(vsamls)
DEFINE LOGSTREAM NAME(ATR.gname.RESTART)
STRUCTNAME(RRS_RESTART)
LS_DATACLAS(vsamls)
DEFINE LOGSTREAM NAME(ATR.gname.ARCHIVE)
STRUCTNAME(RRS_ARCHIVE)
/*

If you need to delete the log streams and the structures from the coupling facility, use the following
example:
//STEP1 EXEC PGM=IXCMIAPU
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DATA TYPE(LOGR)
DELETE LOGSTREAM NAME(ATR.gname.RM.DATA)
DELETE LOGSTREAM NAME(ATR.gname.MAIN.UR)
DELETE LOGSTREAM NAME(ATR.gname.DELAYED.UR)
DELETE LOGSTREAM NAME(ATR.gname.RESTART)
DELETE LOGSTREAM NAME(ATR.gname.ARCHIEVE)
DELETE STRUCTURE NAME(RRS_RM_DATA)
DELETE STRUCTURE NAME(RRS_MAIN_UR)
DELETE STRUCTURE NAME(RRS_DELAYED_UR)
DELETE STRUCTURE NAME(RRS_RESTART)
DELETE STRUCTURE NAME(RRS_ARCHIEVE)
/*

62 Getting Started with DB2 Stored Procedures


3.14.2 Activating the CFRM Policy to Support RRS
If your log streams use the coupling facility, you have to activate the updated CFRM policy. To change
the CFRM policy, you have to compile and link-edit the policy. Then you have to activate this new
CFRM policy in your Sysplex. You can activate the updated CFRM policy with the following operator
command:
SETXCF START,POLICY,TYPE=CFRM,POLNAME=polname

3.14.3 Making the RRS JCL Procedure Available


You have to move the ATRRRS procedure from the SYS1.SAMPLIB to your SYS1.PROCLIB as member
RRS. If you use a different name for the procedure, the first four characters of the procedure name
must match the subsystem name as registered in the IEFSSNxx member of SYS1.PARMLIB. Here is
the sample JCL procedure to start RRS:
//RRS PROC GNAME=′ ′ , CTMEM=′ ′
//********************************************************************
//*
//*01* Proc Name: RRS
//*01* Descriptive Name: Start MVS/RRS Address Space and subsystem
//*01* Component: MVS/RRS (SCRRS)
//*
//***PROPRIETARY_STATEMENT********************************************
//* *
//* LICENSED MATERIALS - PROPERTY OF IBM *
//* THIS MACRO IS ″RESTRICTED MATERIALS OF IBM″ *
//* 5645-001 (C) COPYRIGHT IBM CORP. 1997 *
//* SEE COPYRIGHT INSTRUCTIONS *
//* *
//* STATUS= HBB6603 *
//* *
//***END_OF_PROPRIETARY_STATEMENT*************************************
//*
//*01* Function: starts the MVS/RRS Address Space and subsystem
//*01* Notes:
//*
//* The following describes the parameters:
//*
//* o GNAME=rrsgroupname
//*
//* where rrsgroupname is 1-8 characters and the first character
//* is an alphabetic or national (@#$) and the remaining characters
//* are alphabetic, numeric or national (@#$).
//*
//* Default (if no GNAME value provided): Sysplex Name
//*
//* o CTMEM=ctracemembername
//*
//* where ctracegroupname is a 8 character alphabetic, numeric
//* or national (@#$).
//*
//* Default (if no CTMEM value provided): default RRS trace options.
//*
//* If both are specified, they must be separated by atleast 1 blank.
//* They are not positional, but there cannot be a blank imbedded
//* within the keyword=value string, that is, GNAME = PLEX1 is not valid.
//* It must be GNAME=PLEX1.
//*
//* Examples of valid parameter strings:

Chapter 3. WLM-Established Stored Procedures Address Spaces 63


//*
//* PARM=′ GNAME=PLEX1 CTMEM=CTIRRS00′
//* PARM=′ CTMEM=CTIRRS00 GNAME=PLEX1′
//* PARM=′ GNAME=PLEX1 ′
//* PARM=′ CTMEM=CTIRRS00 ′
//*
//*01* Target-Library: SYS1.PROCLIB(ATRRRS)
//*01* Change-Activity:
//* Flag Reason Release YYMMDD Origin Description
//* $L0= RRSSC HBB6603 950719 PDMF: Resource Recovery Service @L0A
//* $P1= PQC1663 HBB6603 960807 PDJK: Put into SYS1.SAMPLIB @P1A
//* $P2= PQC2155 HBB6603 961001 PDV6: Group Name Support @P2A
//* (TRSQ - OW23450)
//*
//*********************************************************************
//RRS EXEC PGM=ATRIMIKE,REGION=4096K,TIME=NOLIMIT,
// PARM=′ GNAME=&GNAME CTMEM=&CTMEM′
//
The GNAME must match the gname specified when defining the log streams.

3.14.4 Adding RRS Subsystem Name


To activate the RRS application you have to define RRS as a subsystem to MVS. To add the RRS
subsystem name to MVS, you must find out with your system programmer the active IEFSSNxx
member of SYS1.PARMLIB. Edit the member to include the following entry:
SUBSYS SUBNAME(RRS) /* RESOURCE RECOVERY SERVICES */
The subsystem name can be RRS or any other name of your choice. Note that the first characters (up
to four) of the JCL procedure name to start RRS must match the subsystem name.

3.14.5 Starting and Stopping RRS


Once you have set address space priority, provided the statement in IEFSSNXX, and know that the
system logger is active, you can start RRS with the following operator command:
START RRS,SUB=MSTR

You can stop RRS with the following operator command:


SETRRS CANCEL
Here are the messages you get when you issue
SETRRS CANCEL
ATR101I CANCEL REQUEST WAS RECEIVED FOR RRS.
ATR143I RRS HAS BEEN DEREGISTERED FROM ARM.
IEF450I RRS RRS - ABEND=S5C4 U0000 REASON=FFFF2222 064
IEF404I RRS - ENDED - TIME=hh.mm.ss
IEF196I IEF472I RRS RRS - COMPLETION CODE - SYSTEM=5C4 USER=0000
IEF196I REASON=FFFF2222
IEF196I IEF373I STEP/RRS /START 1997303.1507
IEF196I IEF374I STEP/RRS /STOP 1997303.1905 CPU 0MIN 03.02SEC
Notice that RRS abends with S5C4 code. No action is necessary for reason code X′FFFF2222′.

3.14.6 RRS Error Samples


In this section, we examine some errors that you may encounter and the possible causes:
• If RRS cannot find one of the log streams, you get the following when starting RRS:

64 Getting Started with DB2 Stored Procedures


IEF403I RRS - STARTED - TIME=20.49.38
ATR221I RRS IS JOINING RRS GROUP gname ON SYSTEM SC53
ATR130I RRS LOGSTREAM CONNECT HAS FAILED FOR 496
MANDATORY LOGSTREAM ATR.gname.RM.DATA.
RC=00000008, RSN=0000080B
IEA989I SLIP TRAP ID=X13E MATCHED. JOBNAME=RRS , ASID=0068.
IXG231I IXGCONN REQUEST=CONNECT TO LOG STREAM ATR.gname.RM.DATA
DID 495
NOT SUCCEED FOR JOB RRS. RETURN CODE: 00000008 REASON CODE: 0000080B
DIAG1: 00000008 DIAG2: 0000F801 DIAG3: 05030004 DIAG4: 05020010
ASA2013I RRS INITIALIZATION FAILED. COMPONENT ID=SCRRS
Action: verify that the define log stream job ran correctly.
• Starting sample procedure member ATRRRS with the MVS subsystem name of RRS, you get the
following error message:
S ATRRRS,SUB=MSTR
................
................
IEF695I START ATRRRS WITH JOBNAME ATRRRS IS ASSIGNED TO USER STC
, GROUP SYS1
IEF403I ATRRRS - STARTED - TIME=14.19.57
ASA2016I ATRR IS NOT A VALID SUBSYSTEM. COMPONENT ID=SCRRS
ASA2013I ATRR INITIALIZATION FAILED. COMPONENT ID=SCRRS
Action: Rename procedure member name from ATRRRS to RRS (or a name that matches your
subsystem name) and restart RRS.

Chapter 3. WLM-Established Stored Procedures Address Spaces 65


66 Getting Started with DB2 Stored Procedures
Chapter 4. DB2 Common Servers and DB2 UDB

In this chapter, we provide an overview of DB2 Common Servers and DB2 UDB and explain their
relationship to stored procedures.

4.1 What Are DB2 Common Servers?

“DB2 Common Servers” is a name that groups six DB2 server products sharing the same DB2 code.
You can think of it as one database system running on different platforms with either an Intel or a UNIX
architecture. The six Common Server products are:
• DB2 for OS/2
• DB2 for AIX
• DB2 for Windows NT
• DB2 for HP-UX
• DB2 for Sun/Solaris
• DB2 for Sinix (Siemens Nixdorf)

4.2 Features of DB2 Common Servers

DB2 Common Servers provide the following features:


• A full-function relational database management system
• A cost-based optimizer supporting extremely complex queries
• Data integrity ensured through declarative referential integrity, forward recovery, and multilevel
concurrency control
• A command line processor for interactive entry of commands and SQL statements
• Flexible management of very large databases
• Support of user-defined functions (UDFs), user-defined types (UDTs), triggers, constraints, large
objects (LOBs), and recursive SQL
• Support of stored procedures
• Inclusion of a graphical database director to manage databases, including configuration, backup
and recovery, directory management, and media management (in UNIX-based products)
• Distributed unit of work
• Support of a wide variety of clients (DOS, Windows, Windows 95, Windows NT, OS/2, Macintosh,
and so on).
• Support of Open Database Connectivity (ODBC) clients
• Support for popular communication protocols
• Support compound SQL
• Distributed Computing Environment (DCE) directory services for simplified management of network
addressing information
• Visual Explain, a visual explanation of the SQL statement access path
• A performance monitor that enables you to monitor and tune the DB2 system

 Copyright IBM Corp. 1996 1998 67


4.3 DB2 Universal Database

The DB2 Universal Database Version 5 (DB2 UDB), announced in December 1996, is the follow-on
product to DB2 Common Servers. DB2 UDB combines the online transaction processing (OLTP)
performance, advanced functions, and relational features of DB2 Common Servers with the parallel
processing and clustering, query performance, and very large database support of DB2 Parallel Edition.

DB2 UDB enhances the integration of an enterprise′s total data resources by various forms of support
for the DB2 family (DB2 for OS/390, DB2 for OS/400, and DB2 for VM and VSE). This support ranges
from new Transmission Control Protocol/Internet Protocol (TCP/IP) support, new Distributed Relational
Database Architecture (DRDA) application server (AS) support, and direct desktop client access with
DB2 Connect for Web enablement and middleware (data replication support and centralized database
systems management). With the use of DataJoiner it is possible to access nonrelational data, such as
IMS and VSAM, and non-IBM databases, such as Oracle, Informix, and Sybase.

DB2 UDB provides:


• Web enablement: DB2 UDB data can be accessed from Web clients through its built-in Java
Database Connectivity (JDBC) support or Net.Data. It is also possible to invoke stored procedures
from a Java application.
• Multimedia: DB2 UDB can manage both traditional and multimedia data. Object-relational
extenders support data types such as image, video, audio, and text as part of the database.
• Scalability: DB2 UDB scales from Intel to UNIX platforms, from notebooks to uniprocessors to
symmetric multiprocessing (SMP) to massively parallel processing (MPP) environments.
• Integration: Replication support, distributed data warehousing, complex querying power, Internet
connectivity, optimized high-performance transaction processing, and database tools are delivered
in one integrated product.
• Openness: DB2 UDB supports leading industry standards and runs on both IBM and non-IBM
platforms, including OS/2, AIX, Windows NT, Windows 95, HP, Sun, SINIX, and SCO.

4.3.1 DB2 Connect


DB2 Connect is the follow-on product to Distributed Database Connection Services (DDCS). DB2
Connect allows stand-alone users or local area network (LAN) clients to access data stored in any
DRDA server such as DB2 for OS/390, DB2 for OS/400, and DB2 for VM and VSE. Applications running
on the client machines work with the host data transparently, as if a local database server managed
the data.

DB2 Connect supports the Advanced Program-to-Program Communication (APPC) and TCP/IP
protocols for connections with all DRDA servers. For the current releases, however, only DB2 for
OS/390 and UDB products support the TCP/IP protocol.

DB2 Connect runs on different platforms including Windows 3.11, Windows 95, Windows NT, OS/2, AIX,
HP, Sun, SINIX, and SCO. The Windows 3.11 and Windows 95 products are available only in
single-user versions.

Figure 49 on page 69 shows a sample scenario with DB2 Connect.

68 Getting Started with DB2 Stored Procedures


Figure 49. Sample Scenario with DB2 Connect

4.3.2 Two-Phase Commit Support


As a DRDA application server, DB2 UDB Version 5.0 supports the two-phase commit processing over
APPC on OS/2 and AIX only. It does not support the two-phase commit processing over TCP/IP on any
platform, although it does support the two-phase commit processing when using the private protocol
(not DRDA).

DB2 Connect is the DRDA application requester for DB2 UDB. DB2 Connect Version 5.0 supports the
two-phase commit processing over APPC on OS/2 and AIX only, but supports the two-phase commit
processing over TCP/IP on all platforms.

4.3.3 Net.Data
Net.Data is an application that runs on a Web server and enables you to create Web pages with access
to DB2 data. Net.Data offers tools for building two-tier and three-tier applications that can access DB2
data by using standard HTML and SQL. A common gateway interface (CGI) processes input from the
HTML pages and sends SQL commands to a DB2 database specified in the application you create with
Net.Data.

Applications can access DB2 data on the Internet server or on other servers, using DB2 Client
Application Enablers (CAEs) and DB2 Connect. With the use of DataJoiner, the application can also
access non-DB2 servers.

Net.Data builds on the database access and reporting capabilities of the previous DB2 WWW
Connection product. However, its function has been enhanced to become a comprehensive Web
development tool for the creation of either simple dynamic Web pages or complex Web-based
applications. In addition, it also supports Internet server application program interfaces (APIs) on the
following servers:
• Netscape Server (NSAPI)
• Microsoft Internet Server (ISAPI)
• IBM Internet Connection Server (ICAPI)

Figure 50 on page 70 shows a sample scenario using Net.Data.

Chapter 4. DB2 Common Servers and DB2 UDB 69


Figure 50. Sample Scenario with Net.Data

4.3.4 DB2 Universal Database (UDB) Tools


DB2 UDB includes tools to perform administrative functions and application development. These tools
enable performance tuning, provide access to remote DB2 UDBs, allow management of different
servers from a single workstation, enable application development, and process SQL queries.

The Control Center is a graphical tool that enables you to manage the local server or remote servers
from a single point of control. With the Control Center you can:
• Create, alter, and drop DB2 objects
• Back up and recover databases and table spaces
• Define replication policies
• Configure databases and communication protocols

The Control Center provides SmartGuide to help you perform complex tasks. As an example, when
you are tuning the performance of your system, SmartGuide can guide you through the process.

The Control Center also has additional facilities to:


• Create miniapplications called scripts . These scripts may contain DB2 commands, SQL
statements, and operating system commands.
• Schedule jobs to run unattended. This facility is useful for tasks such as backups that have to be
executed frequently.

70 Getting Started with DB2 Stored Procedures


• Monitor the system for potential problems or automate actions to correct problems without
operator intervention
• Manage your server, performing tasks such as creating an access profile that can be used at the
client workstations to uniformly set up each client on the network
• Monitor the performance of your DB2 system and analyze and tune SQL statements

Figure 51 shows a typical Control Center window.

Figure 51. DB2 UDB Control Center Window

4.4 Configuring for Stored Procedures

In DB2 V1 Common Servers, the stored procedures SQL CALL statement was not supported, but there
was an interface with similar functions to stored procedures called Database Application Remote
Interface (DARI). This interface is still supported in DB2 Common Servers V2 and DB2 UDB, and it is
possible to use a DARI call to invoke a stored procedure. Because of the DARI interface, the name
DARI is still used in DB2 Common Servers V2 and DB2 UDB, for example, the MAXDARI and KEEPDARI
parameters. In addition, in reference manuals DARI and stored procedures are used synonymously.

Please keep in mind that DARI and stored procedures are two separate interfaces, even though they are
sometimes referred to by the same name .

In the sections that follow, we describe the two parameters in the database manager configuration file
that can affect DB2 common-server stored procedures: KEEPDARI and MAXDARI.

Chapter 4. DB2 Common Servers and DB2 UDB 71


4.4.1 The Keep DARI Process Indicator (KEEPDARI)
The KEEPDARI parameter indicates whether a stored procedure process is kept after completion of a
call to the stored procedure.

If KEEPDARI is set to no (Figure 52 on page 73), a new process is created and destroyed for each
invocation of a stored procedure. Thus only the minimum amount of resources is consumed by the
stored procedure process as the resources are released after each call. However, for each invocation
of a stored procedure, a new process has to be created, thus reducing performance.

If KEEPDARI is set to yes (Figure 53 on page 74), a stored procedure process remains active after the
first call and can be reused for subsequent stored procedure calls. Setting this parameter to yes
results in additional system resources being consumed by the database manager for each process that
is activated, up to the value of the MAXDARI parameter. When KEEPDARI is set to yes , a subsequent
call to a stored procedure first tries to reuse one of the existing processes. If all processes are in use,
an additional stored procedure process is started to handle the call.

In an environment where stored procedures are intensively used relative to the number of nonstored
procedure database requests and system resources are not constrained, we recommend setting the
KEEPDARI parameter to yes . This improves the performance of the stored procedure calls.

72 Getting Started with DB2 Stored Procedures


Figure 52. KEEPDARI Set to NO

Chapter 4. DB2 Common Servers and DB2 UDB 73


Figure 53. KEEPDARI Set to YES

4.4.2 The Maximum Number of DARI Processes Indicator (MAXDARI)


The MAXDARI parameter indicates the maximum number of stored procedure processes that can be
active at the same time at the database server. Once the limit is reached, new stored procedures
cannot be invoked. No more than one stored procedure process can be active for an agent, so the
maximum number of stored procedure processes is also dictated by the maximum number of agents
(MAXAGENTS). Please refer to the Administration Guide for Common Servers and DB2 UDB
Administration Guide for details about the MAXAGENTS parameter.

The default value for the MAXDARI parameter is -1, which means that the actual value used for
MAXDARI is the current value of the MAXAGENTS parameter. If you find that too many system
resources are being used for stored procedure processes, you can reduce the MAXDARI parameter.
As a starting point for tuning the MAXDARI parameter, we recommend setting it equal to the number of
applications allowed to issue stored procedure calls at one time.

74 Getting Started with DB2 Stored Procedures


4.4.3 Viewing and Updating KEEPDARI and MAXDARI
To view or update the KEEPDARI and MAXDARI parameters use the database manager configuration
tool in the database director tool as illustrated in Figure 54 on page 75 or the DB2 command line
processor.

Figure 54. Configuring for Stored Procedures

If you prefer to use the DB2 command line processor, the syntax for viewing the actual settings is:
db2 get database manager configuration

The same command in short form is:


db2 get dbm cfg

You can also use the DB2 command line processor to set parameters. Here is the syntax for setting
the KEEPDARI parameter to yes and the MAXDARI parameter to 100:
db2 update database manager configuration using MAXDARI 100 KEEPDARI yes

The same command in short form is:


db2 update dbm cfg using MAXDARI 100 KEEPDARI yes
To reset MAXDARI to the value of MAXAGENTS issue this command:
db2 update dbm cfg using MAXDARI -1

Note that changes to the database manager configuration file become effective only after they have
been loaded into memory. For these server configuration parameters, changes are loaded into
memory during execution of a db2start command.

Chapter 4. DB2 Common Servers and DB2 UDB 75


4.5 Fenced and Unfenced Stored Procedures

Fenced stored procedures run in a separate process from the database agent processes. This
separation requires that the stored procedure process and the database agent processes communicate
through a router.

In cases where you want the best possible performance, it is also possible to run a stored procedure
directly in the database agent process, thus eliminating the overhead of the communication through
the router.

Fenced is the default option for running stored procedures (Figure 55). Performance is slightly inferior
to that of unfenced stored procedures, but there is an important advantage: As the stored procedure
operates isolated from the database control structures used by the database agent, an erroneous
stored procedure cannot accidentally damage the database manager control structures.

Figure 55. Fenced Stored Procedures (IPC=Interprocess Communication)

When nothing separates the stored procedure from the database control structures used by the
database agent, we refer to stored procedures as being unfenced , trusted , or not-fenced (Figure 56 on
page 77). As an administrator, you are confident that the stored procedure does not accidentally or
maliciously damage the database control structures. You “trust” it to operate in a fashion that does
not jeopardize your database control structures.

Because of the risk of damaging your database control structures, use unfenced stored procedures
only when you have to obtain the maximum performance benefits. In addition, ensure that the
procedure is well coded and has been thoroughly tested before allowing it to run as a unfenced stored
procedure.

To identify a stored procedure as being unfenced, you have to place the procedure in a special
directory, usually the \SQLLIB\FUNCTION\UNFENCED directory. Unfenced stored procedures must be
precompiled with the WCHARTYPE NOCONVERT option. Please refer to 7.3, “Stored Procedure
Preparation” on page 111 for more information.

76 Getting Started with DB2 Stored Procedures


Figure 56. Unfenced Stored Procedures

4.6 Registering Stored Procedures

Unlike DB2 on the MVS platform, there is no table or view in the DB2 system catalog for registering
stored procedures in DB2 Common Server V2. However, you can define a pseudo-catalog table,
DB2CLI.PROCEDURES, to DB2 to register stored procedures.

In DB2 Universal Database V5, DB2CLI.PROCEDURES is replaced by SYSCAT.PROCEDURES and


SYSCAT.PROCPARMS. Refer to DB2 UDB V5 Call Level Interface Guide and Reference for details. To
register a stored procedure in DB2 Universal Database V5, use the CREATE PROCEDURE SQL
statement. To unregister a stored procedure in DB2 Universal Database V5, use the DROP
PROCEDURE SQL statement. These are explained in the SQL Reference .

4.6.1 Creating and Updating DB2CLI.PROCEDURES


You can update DB2CLI.PROCEDURES with information that describes available stored procedures and
the associated parameters of those stored procedures. Use SQLProcedures() and
SQLProcedureColumns() call level interface (CLI) statements to retrieve information about stored
procedures and their attributes.

To create DB2CLI.PROCEDURES do the following:


1. Connect to the database.
2. Go to the SQLLIB\MISC directory (on AIX, sqllib/misc).
3. Issue the following command (except on Windows):
db2 -f STORPROC.DDL -z STORPROC.LOG -t
Please note that the db2 -ft STORPROC.DDL command does not work. Change -ft to -tf to make it
work.

On Windows, the syntax is:


db2cliw -f STORPROC.DDL -z STORPROC.LOG -t

Chapter 4. DB2 Common Servers and DB2 UDB 77


You should see the following messages:
DB20000I The UPDATE COMMAND OPTIONS command completed successfully.

DB20000I The SQL command completed successfully.

DB20000I The SQL command completed successfully.

DB20000I The SQL command completed successfully.

DB20000I The SQL command completed successfully.

You can review these messages in the STORPROC.LOG file.

Updating and maintaining the DB2CLI.PROCEDURES table is the responsibility of the database
administrator. An example of how to insert some rows in the table is provided with the
STORPROC.XMP sample file. To run this sample file once the table is created, do the following:
1. Connect to the database.
2. Go to the SQLLIB\MISC directory (on AIX, sqllib/misc).
3. Issue the following command (except on Windows):
db2 -f STORPROC.XMP -z STORPROC.LOG -t
On Windows, the syntax is:
db2cliw -f STORPROC.XMP -z STORPROC.LOG -t

You should see the following messages:


DB20000I The UPDATE COMMAND OPTIONS command completed successfully.

DB20000I The SQL command completed successfully.

DB20000I The SQL command completed successfully.

DB20000I The SQL command completed successfully.

DB20000I The SQL command completed successfully.

You can review these messages in the STORPROC.LOG file.

You can check the STORPROC.DDL and STORPROC.XMP files for more details about the
DB2CLI.PROCEDURES table. Initially, all users have SELECT authority, and only users with DBADM
authority can insert, delete, or update rows in this table. A user with DBADM authority can grant
privileges to other users.

4.6.2 Querying DB2CLI.PROCEDURES


In the sqllib\samples\cli (for AIX, sqllib/samples/cli) directory, you can find the PROCS and the
PROCCOLS samples. The PROCS sample is a CLI program to list procedures and procedure
parameters using SQLProcedures() and SQLProcedureColumns().

You have to create and load DB2CLI.PROCEDURES and build the samples to run PROCS and
PROCCOLS. To invoke PROCS, enter procs at the command prompt. PROCS interactively asks you to
enter the database name, user ID, password, and a “Procedure Schema Name Search Pattern.” The
procedure schema name search pattern is case sensitive. For the sample schema you can enter:
ExampleSchema
PROCS produces the following output:

78 Getting Started with DB2 Stored Procedures


PROCEDURE SCHEMA PROCEDURE NAME
------------------------- -------------------------
ExampleSchema Sys1!ComputePayroll
(Remarks) Computes payroll
ExampleSchema Sys1!ComputeSales
(Remarks) Computes sales
ExampleSchema Sys1!ComputeTaxes
(Remarks) Computes income taxes
To invoke PROCCOLS, enter PROCCOLS at the command prompt. PROCS interactively asks you to
enter the database name, user ID, password, and the procedure schema name search pattern as
PROCS. In addition, PROCCOLS asks you to enter a “Procedure Name Search Pattern,” which is case
sensitive. Enter one of the sample procedure names, such as:
ComputeSales
PROCS produces the following output:
ExampleSchema.Sys1!ComputeSales
rate, Input, DECimal (7, 3)
currentDate, Input, DATE (10)
employeeProfile, Input_Output, LONG VARCHAR (0)

4.6.3 Columns of the DB2CLI.PROCEDURES Table


In this section, we describe the DB2CLI.PROCEDURES columns. Note that DB2 neither maintains this
table nor checks the information in it during execution of the stored procedure. The columns are as
follows:
1 PROCSCHEMA VARCHAR(18) Not nullable Primary Key
Schema name of the procedure
2 PROCNAME VARCHAR(18) Not nullable Primary Key
Name of the stored procedure specified on the SQL CALL statement
3 DEFINER VARCHAR(8) Not nullable
Definer of the stored procedure (that is, the database administrator who inserted this
row into the table)
4 PKGSCHEMA VARCHAR(18) Not nullable
Schema name of the package to be used when the stored procedure is executed
5 PKGNAME VARCHAR(18) Not nullable
Name of the package to be loaded when the stored procedure is executed
6 PROC_LOCATION VARCHAR(254) Not nullable
External (full path) name of the procedure
7 PARM_STYLE CHAR(1) Not nullable
The convention used to pass parameters to the stored procedure: D DARI convention
8 LANGUAGE CHAR(8) Not nullable
The programming language used to create the stored procedure. Possible values are
COBOL, C (for both C and C++ programs), REXX (OS/2), and FORTRAN for common
servers of DB2. Other products may enable other languages, for example, PL/I and
BASIC.
9 STAYRESIDENT CHAR(1) Not nullable
Determines whether the stored procedure load module is deleted from memory when
the stored procedure ends: Y indicates that the load module remains resident in
memory after the stored procedure ends. Also specify Y when the stored procedure
returns SQLZ_HOLD_PROC to stay resident for a number of calls and then terminates
by returning SQLZ_DISCONNECT_PROC. A blank entry indicates that the load module
is deleted from memory after the stored module terminates. Refer to Chapter 7,

Chapter 4. DB2 Common Servers and DB2 UDB 79


“Coding Stored Procedures for DB2 Common Servers and DB2 UDB” on page 105 for
more details about this parameter.
10 RUNOPTS VARCHAR(254) Not nullable
Reserved (empty string)
11 PARM_LIST VARCHAR(3000) Not nullable
Parameter list of the stored procedure. See Figure 57 for the format of this column
list. The format of this column is similar to the format of the DB2 for MVS/ESA
SYSIBM.SYSPROCEDURES table described in 2.3.1.1, “SYSIBM.SYSPROCEDURES
Table Columns” on page 14.
12 FENCED CHAR(1) Not nullable
An indication of whether or not the procedure runs “fenced.” Y indicates the stored
procedure is fenced; N indicates the stored procedure is not fenced.
13 REMARKS VARCHAR(254) Not nullable
Description of the stored procedure
14 RESULT_SETS SMALLINT Not nullable
The number of result sets that can be returned

Figure 57. Format of PARM_LIST Column

80 Getting Started with DB2 Stored Procedures


Chapter 5. Interfaces to Application Development

In this chapter, we consider the interfaces that you can use to code the stored procedure and the client
application.

DB2 on the workstation and DB2 on MVS support two interfaces for application development:
embedded SQL statements and CLI.

Note that DB2 for MVS/ESA Version 4 does not support CLI natively.

5.1 Embedded SQL

Embedded SQL statements are written within the application programming language; programs written
using embedded SQL statements have to be precompiled by an SQL preprocessor or precompiler
before the actual compilation of the program. There are two types of embedded SQL: static and
dynamic.

5.1.1 Static SQL


The source form of a static SQL statement is embedded within an application program written in a host
language such as C or COBOL. The source program must be processed by an SQL precompiler
before it is compiled. During precompilation, the SQL statements are converted into host language
statements to invoke the database manager. The following is an example of a SELECT INTO static SQL
statement in COBOL:
....
EXEC SQL SELECT FIRSTNME INTO :firstname
FROM employee
WHERE LASTNAME = ′ JOHNSON′ ;
....
The following is an example of an INSERT INTO static SQL statement in C:
....
strcpy (president, data_items[1]);
EXEC SQL INSERT INTO PRESIDENTS (NAME) VALUES (:president);
....

5.1.2 Dynamic SQL


Unlike static SQL statements, dynamic SQL statements are constructed and prepared at run time. The
SQL statement text is prepared by using either the PREPARE and EXECUTE statements or the
EXECUTE IMMEDIATE statement. Dynamic SQL statements also must be precompiled. The following
is an example of a dynamic SQL statement in C:
....
char insert_stmt[80] = ″INSERT INTO ″ ;

strcat(insert_stmt, table_name);
strcat(insert_stmt, ″ VALUES (?)″ ) ;

EXEC SQL PREPARE S1 FROM :insert_stmt;

for (cntr = 0; cntr < num_of_data; cntr++)


{
strncpy(insert_data, data_items[cntr], data_items_length[cntr]);

 Copyright IBM Corp. 1996 1998 81


insert_data[data_items_length[cntr]] = ′ \0′ ;
EXEC SQL EXECUTE S1 USING :insert_data;
}
....

5.2 Call Level Interface


Call level interface (CLI) is an IBM callable SQL interface to the DB2 family of products.

CLI, originally defined by Microsoft, the X/OPEN company, and the SQL Access Group, has been
adopted as an International Standard (ISO/IEC 9057-3: ″SQL, Call Level Interface″).

The CLI is a facility within DB2 for processing dynamic SQL statments.

In using the CLI, precompilation or binding of the code is not required.

CLI uses function calls to pass dynamic SQL statements as function arguments. It does not require
host variables or a precompiler. Programs that use CLI must be written in C. The CLI relies on a set
of function calls that can be embedded in a C program and compiled by a conventional C compiler. By
linking the program to the CLI library, you have access to all the SQL facilities of the system. The CLI
functions conform to a standard that is widely implemented, and therefore usable from a variety of
database products.

The DB2 implementation of CLI is compatible with the widely used Microsoft version called Open
Database Connectivity (ODBC). Various levels of DB2 implement different levels of ODBC. For
example, DB2 Common Server Version 2 supports ODBC Level 1 and most of the functions in ODBC
level 2. DB2 UDB Version 5 supports ODBC Level 3. CLI incorporates both the ODBC and X/Open DB2
CLI functions, both of which are accepted industry standards.

The following is an example of an insert statement using CLI:


....
SQLCHAR insert_stmt[80] = ″INSERT INTO ″ ;
....
strncat((char *)insert_stmt, (char *)table_name, table_name_length);
strcat((char *)insert_stmt, ″ VALUES (?)″ ) ;

rc = SQLPrepare(hstmt, insert_stmt, SQL_NTS);


if (rc != SQL_SUCCESS) goto ext;

SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,


20, 0, insert_data, 21, &insert_data_ind);

for (cntr = 0; cntr < num_of_data; cntr++)


{
strncpy((char *)insert_data, (char *)data_item[cntr], data_item_length[cntr]);
insert_data_ind = data_item_length[cntr];
rc = SQLExecute(hstmt);
if (rc != SQL_SUCCESS) goto ext;
}
....

5.3 Deciding Which Interface to Use

Although you can use both embedded SQL statements and CLI in the same program, usually you have
to choose between embedded SQL and CLI. Both interfaces have their advantages.

82 Getting Started with DB2 Stored Procedures


5.3.1 Embedded SQL Advantages
Embedded static SQL statements have three advantages over CLI and embedded dynamic
SQL—performance, security, and encapsulation:
• The performance of static SQL is usually better. Dynamic SQL statements are prepared at run
time, but static SQL statements are prepared during precompilation.
• In static SQL, authorizations to objects are associated with a package and validated at package
bind time. By encapsulating the access privileges in the package, database administrators need
only grant execute on a particular package to a set of users, so there is no need to grant access to
each database object.
• Depending on how your application interfaces with end users, generally with static SQL statements
users do not have to know the details of the database objects in order to access them. These
details are hidden, encapsulated in the package.

5.3.2 CLI Advantages


The advantages of CLI over embedded SQL are:
• CLI provides function calls that support a consistent way of querying and retrieving database
system catalog information across the DB2 family of database management systems.
• Application programs written with CLI can have multiple concurrent connections to the same
database.
• For DB2 on the workstation platform, only stored procedures called from application programs
written with CLI can return result sets to those programs.
• DB2 CLI increases the portability of applications by removing the dependence on platform-specific
precompilers.
• Individual applications do not have to be bound to each database. Bind files shipped with CLI have
to be bound only once for all CLI applications.

5.3.3 Using Both Interfaces


If the application requires the advantages of both interfaces, it is possible to use embedded SQL for
stored procedures that are called by CLI client applications. In this way you can combine ease of use
for the client application with the performance advantage of static SQL for the stored procedures.

For the workstation platform, you also can access result sets in this way because CLI is used as the
interface for the client applications. On the MVS platform you can use CLI or a supported host
language.

Chapter 5. Interfaces to Application Development 83


84 Getting Started with DB2 Stored Procedures
Chapter 6. Coding Stored Procedures in DB2 on MVS

In this chapter, we explain how to code stored procedures for use with DB2 Version 4 or Version 5
servers. We focus on rules for writing stored procedures, differences among languages, dealing with
parameters, and preparing a stored procedure program.

6.1 General Considerations

Planning to write a stored procedure for DB2 is similar to planning to write any DB2 application. You
can use most of the statements that you typically use in an application program.

The sections that follow contain information to help you in the process of coding stored procedures.

6.1.1 Languages
You can write your stored procedures in many different languages. In DB2 on MVS, you can use C,
C++, COBOL, OO COBOL, PL/I, Assembler, or FORTRAN. You can also use VisualGen to generate
COBOL code for your stored procedure.

To use C++ and OO COBOL, you must ensure that you have APAR PN78797-PTF UN86554 installed in
your DB2 on MVS system. C++ requires that you install LE/370 Version 1 Release 4. OO COBOL
requires LE/370 Version 1 Release 5.

Although you can use the VS COBOL II compiler for DB2 client applications, you cannot use it to
compile stored procedures. To compile stored procedures written in COBOL, you must use the IBM
SAA AD/Cycle COBOL/370 Version 1 Release 1 compiler, or a later version. We used IBM COBOL for
OS/390 and VM 2.1.0 (5648-A25) for our tests.

To take advantage of certain stored procedures features, such as the subprograms feature in DB2 V5,
you need LE/370 Version 1 Release 7. Also, some important stored procedure features in future
versions of DB2 require LE/370 Version 1 Release 7, so we recommend you install LE/370 at this or a
higher level.

Refer to 1.3, “Software Prerequisites for Stored Procedures” on page 3 for compiler levels required to
compile stored procedures.

You can write your client applications using any language that supports SQL statements or CLI
application programming interfaces (APIs). The client program does not have to be written in the
same language as the stored procedure. For more information about coding client applications, see
Chapter 8, “Coding Client Applications” on page 117.

6.1.2 LE/370
LE/370 establishes a common run-time environment for different programming languages. It combines
essential run-time services, such as condition handling and storage management. All of these
services are available through a set of interfaces that are consistent across programming languages.
With LE/370, you can use one run-time environment for your applications, regardless of the
application′s programming language or system resource needs.

DB2 on MVS uses LE/370 to provide a run-time environment for the stored procedure programs. You
can have stored procedures written in different languages. All of these stored procedures can execute
in the same stored procedures address space. Thus, using LE/370, you do not have to specify the

 Copyright IBM Corp. 1996 1998 85


language-specific libraries in the JCL procedure of the stored procedures address space; it is enough
to have the LE/370 run-time library.

LE/370 performs several functions for DB2. It hides the differences among programming languages,
provides the ability to make a stored procedure resident in the stored procedures address space, and
supports a large number of run-time options, including the possibility to debug your stored procedures.
You can use LE/370 run-time options to invoke the CODE/370 debugger or use the VisualDebugger.

If you are using LE/370 Releases 1 or 2, the value of the STAYRESIDENT column in the
SYSIBM.SYSPROCEDURES table is not recognized. In this case, the load module always remains
resident after the first call to the stored procedure.

As other programming languages become supported by LE/370, it will be possible to add support for
them in DB2 on MVS.

6.2 Rules for Coding Stored Procedures

Coding a stored procedure is similar to coding any DB2 application. However, there are some
differences and some rules that you must follow when coding a stored procedure.

Although a stored procedure is invoked through an SQL CALL statement, it is not a subroutine. It can
contain or invoke subroutines, but it must be the main program in the DB2-established address space.
For the WLM-established address spaces, the stored procedure can be executed as a main program or
as a subprogram.

6.2.1 Statements in Stored Procedures

6.2.1.1 Contents of Stored Procedures: A stored procedure can contain both static and
dynamic SQL statements. It can contain DDL, DML, or DCL SQL statements. You can use
instrumentation facility interface (IFI) calls to issue DB2 commands from a stored procedure. You can
reference aliases or three-part names in a stored procedure. However, for DB2 Version 4 and DB2
Version 5, the following SQL statements cannot be used in a stored procedure:
• CALL
• COMMIT
• CONNECT
• RELEASE
• ROLLBACK
• SET CONNECTION
• SET CURRENT SQLID
Future versions of DB2 may support the CALL, CONNECT SET CONNECTION, and RELEASE SQL
statements.

Although for DB2 Version 4 and DB2 Version 5 you cannot issue an SQL CALL statement in your stored
procedure, you can call other programs or routines from a stored procedure by using statements of the
programming language. You can even call a REXX procedure.

If you try to use any of the unsupported SQL statements, your stored procedure and the client program
receive a -751 SQLCODE. This is an exceptional case where the client program directly receives the
failing SQLCODE that the stored procedure receives. When your stored procedure receives a -751
SQLCODE, the DB2 thread associated with it is placed in a “must rollback” state. When the client

86 Getting Started with DB2 Stored Procedures


program receives control back from the stored procedure, it must issue a successful SQL ROLLBACK
statement before it can continue processing. If the client program does not issue the SQL ROLLBACK
statement and terminate, DB2 automatically rolls back the unit of work.

If, because of an error condition, you want to ensure a rollback in the unit of work, you can code the
following ROLLBACK statement in your stored procedure:
IF error-condition THEN
EXEC SQL ROLLBACK END-EXEC.

Because ROLLBACK is an invalid SQL statement for stored procedures, your unit of work is placed in
a “must rollback” state.

6.2.1.2 Call Attachment Facility Calls: In the DB2-established address space, stored
procedures use CAF calls implicitly; therefore, the stored procedure must be link-edited with CAF.

For WLM-established address spaces, DB2 uses the RRSAF attachment, not CAF.

If you do not link-edit the stored procedure with CAF or RRSAF, you must call a stub program to load
and branch to CAF or RRSAF. The implementation of the stub program is described in the DB2 for
MVS/ESA Application Programming and SQL Guide . The advantage of using the stub program is that
your application remains isolated from DB2 code. Therefore, you do not have to link-edit your stored
procedure again if maintenance must be applied in the CAF or RRSAF code. If you try to use explicit
CAF calls (such as CALL DSNALI CONNECT, OPEN, CLOSE, or DISCONNECT) or RRSAF calls (such as
IDENTIFY, SIGNON, CREATE, TERMINATE, or TRANSLATE) in your stored procedure, DB2 rejects the
CALL.

6.2.2 Using System-Directed Access with Stored Procedures


Although you cannot use the SQL CONNECT statement in a stored procedure, you can access remote
tables from a stored procedure by using aliases or three-part names. This access to remote tables is
known as system-directed access and is supported only in DB2 on MVS servers. You cannot use
system-directed access to access other DRDA servers.

Figure 58 shows the use of three-part names in DB2 on MVS stored procedures.

Figure 58. Use of Three-Part Names in Stored Procedures

System-directed accesses are treated as dynamic SQL statements. You do not have to create a
package for the stored procedure at the remote DB2 server that you are accessing with this method.

The stored procedure from which you are using system-directed access can be precompiled using
CONNECT TYPE 1 or 2.

Chapter 6. Coding Stored Procedures in DB2 on MVS 87


Some restrictions apply to what your client program can do if you are using system-directed access
from your stored procedure.

6.2.2.1 Client Program in MVS: If your client program is running under MVS and using
CONNECT TYPE 2, you cannot use the SQL CONNECT statement to connect to the same remote
location that the stored procedure is accessing. If the client program connects to a remote location
through the SQL CONNECT statement and then calls a stored procedure that uses system-directed
access to the same remote location, the stored procedure access fails with an SQLCODE -842.
Figure 59 shows this scenario.

Figure 59. Client Program Restrictions (Scenario 1)

If the client program calls a stored procedure that uses system-directed access to a remote location
and then tries to connect to the same remote location through the SQL CONNECT statement, this
connection fails with an SQLCODE -842. Figure 60 shows this scenario.

Figure 60. Client Program Restrictions (Scenario 2)

If you must access the same remote location from a client program that uses CONNECT TYPE 2, you
can issue an SQL RELEASE statement for the remote location, followed by an SQL COMMIT statement.
These statements must be executed before or after the call to the stored procedure, depending on
when you want to connect to the remote location. If you use these statements, you terminate your unit
of work. If you do not want to terminate your unit of work but still want to access tables at the same
remote location, you can use system-directed access in your client program to the same remote
location that the stored procedure is accessing. In this case, use a three-part name and do not issue
the SQL CONNECT statement.

88 Getting Started with DB2 Stored Procedures


For client programs using CONNECT TYPE 1, you must issue an SQL COMMIT statement before or
after the call to the stored procedure.

6.2.2.2 Client Program in DB2 for OS/2 or AIX: As shown in Figure 61, unlike DB2 on MVS, if
your client program is running on the workstation platform using CONNECT TYPE 2, you can connect in
the same unit of work to the same remote location that is accessed by the stored procedure.

Figure 61. Client Program Restrictions (Scenario 3)

Note that a thread is created in DB2B when you issue the CONNECT statement to connect to DB2B.
When the stored procedure executes the SQL statement with the three-part name specification,
another thread is created in DB2B for the same unit of work. In this scenario, be careful when updates
are made from the client program and the stored procedure on the same data. You may get into a
lock problem situation because the threads are different.

If you have precompiled your program with CONNECT TYPE 1, you must issue an SQL COMMIT
statement before or after the call to the stored procedure that is using system-directed access. If you
do not commit, your client program receives an SQLCODE -30090 when trying to call the stored
procedure or in the SQL CONNECT statement.

6.2.3 Stored Procedure Parameters


DB2 on MVS stored procedures can receive and send back parameters to the client program. When
the client program issues an SQL CALL statement, DB2 builds a parameter list based on the
parameters coded in the SQL CALL statement and the information coded in the
SYSIBM.SYSPROCEDURES table. For details on the SYSIBM.SYSPROCEDURES table, refer to 2.3.1.1,
“SYSIBM.SYSPROCEDURES Table Columns” on page 14.

The PARMLIST column of the SYSIBM.SYSPROCEDURES table defines the parameters used by the
stored procedure. It also defines the data type, size, and purpose (input, output, or both) of the
parameters. The syntax for defining the PARMLIST column is explained in 2.3.1.2, “Defining the
PARMLIST Column” on page 16.

One output parameter you should consider including in your stored procedure is information in the
SQLCA. The SQLCA of the stored procedure is not automatically sent to the client program. Including
some of the SQLCA parameters, such as the SQLCODE, as an output parameter enables you to check
the successful execution of SQL statements of the stored procedure. You can code your stored
procedure to copy some information from the current SQLCA to some output parameter, when the SQL
statement fails. If you want information about all SQL statements in your stored procedure, you must
have one parameter for each SQL statement to send information to the client program.

Chapter 6. Coding Stored Procedures in DB2 on MVS 89


6.2.3.1 Passing Parameters to the Stored Procedure: Your stored procedure must define
the parameters that are passed to it. The definition of the parameters must be compatible with the
data type and size specified in the PARMLIST column. Table 5 on page 90 shows the compatible
definitions for parameters in C, COBOL, and PL/I.

Table 5. Definitions of Stored Procedure Parameters in C, COBOL, and PL/I


PARMLIST C COBOL PL/I

CHAR(n) char v a r [ n + 1 ] PIC X(n) CHAR(n)

CHAR(1) char PIC X(1) CHAR(1)

VARCHAR(n) char v a r [ n + 1 ] 01 p a r m CHAR(n) VAR


49 parm-length PIC S9(4)
USAGE IS COMP
49 parm-text PIC X(n)

SMALLINT short int PIC S9(4) COMP BIN FIXED(15)

INTEGER long int PIC S9(9) COMP BIN FIXED(31)

DECIMAL(x,y) decimal(x,y) PIC S9(x-y)V9(y) DEC FIXED(x,y)


COMP-3.

REAL float COMP-1 B I N FLOAT(21)

FLOAT double COMP-2 B I N FLOAT(53)

GRAPHIC(n) wchar_t var [ n + 1 ] PIC G(n) DISPLAY-1 GRAPHIC(n)


or PIC N(n)

VARGRAPHIC(n) struct 01 parm. GRAPHIC(n) VAR.


{short int parm_len; 49 parm-length PIC S9(4)
wchar_t parm_data [ n ] ; USAGE IS COMP
} parm; 49 parm-data PIC G(n)
USAGE IS DISPLAY-1
or
49 parm-data PIC N(n)

6.2.3.2 Passing Nulls to Stored Procedures: Another issue you must consider when defining
stored procedure parameters is whether the stored procedure accepts nulls as input parameters and
can nullify output parameters. This is defined in the SYSIBM.SYSPROCEDURES table in the LINKAGE
column. There are two possible linkage conventions for the parameters: SIMPLE and SIMPLE WITH
NULLS.

SIMPLE Linkage Convention: If you use the SIMPLE linkage convention, the client application can
pass null only for output parameters; nulls for input parameters are not accepted, and the stored
procedure cannot return nulls in the output parameters.

The stored procedure must have a parameter defined for each parameter passed in the SQL CALL
statement. Figure 62 on page 91 shows the parameter list when you use the SIMPLE linkage
convention.

90 Getting Started with DB2 Stored Procedures


Figure 62. SIMPLE Linkage Convention

SIMPLE WITH NULLS Linkage Convention: If you use the SIMPLE WITH NULLS linkage convention, the
input parameters can be null. You can use indicator variables in the client program or the NULL
keyword of the SQL CALL statement. The stored procedure can also return null values in output
parameters by using the indicator variables.

The indicator variables are passed to the stored procedure as a single parameter, containing an array
of SMALLINT variables, one for each of the stored procedure parameters. Figure 63 shows the
parameter list when you use the SIMPLE WITH NULLS linkage convention.

Figure 63. SIMPLE WITH NULLS Linkage Convention

The stored procedure must contain a parameter for each parameter passed in the SQL CALL
statement and a structure of indicator variables containing one indicator variable for each parameter,
even if you code your stored procedure to receive only one parameter.

The stored procedure must determine which input parameters are null by examining the indicator
variables array. The stored procedure must also assign values to the indicator variables when
returning the output parameters to the client program.

Chapter 6. Coding Stored Procedures in DB2 on MVS 91


The indicator variables array is not defined in the PARMLIST column of the SYSIBM.SYSPROCEDURES
table and is not specified as a parameter in the SQL CALL statement. In the SQL CALL statement in
the client program, the indicator variables are coded after each parameter:
EXEC SQL CALL PROCX (:parm1:indicator1, :parm2:indicator2, ...)
or
EXEC SQL CALL PROCX (:parm1 INDICATOR :indicator1, ...)

Using Nulls to Reduce Network Traffic: When a client program issues an SQL CALL statement, all
specified parameters are sent to the server, regardless of their definition as input or output
parameters.

The stored procedure does not examine values sent by the client application that maps to output
parameters. When you have large output parameters, you may want to avoid the transmission of the
output parameters to the server.

You can use indicator variables for the output parameters to avoid sending large amounts of data
through the network. If the indicator variable associated with the output parameter contains a negative
value, the value of the parameter is not sent to the server, and only a null indicator flows through the
network. This technique can be used with the SIMPLE or the SIMPLE WITH NULLS linkage convention.

You can also prevent large parameters that are defined as INOUT but are only being used in one
direction from being sent in the other direction. All you have to do in the stored procedure or the
client program is set the indicator variables associated with the parameters to a negative value. In
this case, you must be using the SIMPLE WITH NULLS linkage convention. Table 6 shows which
parameters can be nullified by the client application and the stored procedure when the SIMPLE
linkage convention is used.

Table 6. Null Parameters and SIMPLE Linkage Convention


Input Output Input/Output
Client application No Yes No
Stored procedure No No No

Table 7 shows which parameters can be nullified by the client application and the stored procedure
when the SIMPLE WITH NULLS linkage convention is used.

Table 7. Null Parameters and SIMPLE WITH NULLS Linkage Convention


Input Output Input/Output
Client application Yes Yes Yes
Stored procedure Yes Yes Yes

One reason why DB2 on MVS requires the specification of a parameter as input or output is that the
specification reduces the flow of the parameters as follows:
• The values (nulls or some value) of input parameters are not transmitted through the network to
the client application when the stored procedure ends.
• When the stored procedure is called or ends output (or input/output) parameter values are
transmitted through the network only if the associated indicator variable has a positive value. If
the indicator variable has a negative value, the parameter value is not transmitted through the
network.
When the stored procedure executes, output parameters always contain X′00′, regardless of
whether they were transmitted through the network.

92 Getting Started with DB2 Stored Procedures


When you are using the SIMPLE WITH NULLS linkage convention, the stored procedure must always
check and set the indicator variables according to their usage. For example, if an output parameter
was nullified when the client program invoked the stored procedure, the stored procedure must set the
indicator variable to a positive value when you want to return a value other than null to the client
program.

6.2.3.3 Receiving Parameters in the Stored Procedure: DB2 on MVS uses the stored
procedure parameters you define to receive the parameters passed in the SQL CALL statement and
send parameters back to the client program. For DB2 Version 4, it is not possible to use (send or
receive) sets of values (result sets) as parameters. DB2 Version 5 supports multiple result sets.

The client program passes the parameters in the SQL CALL statement, using host variables, constants
(DB2 on MVS only), or an SQLDA. However, the stored procedure in DB2 on MVS always receives the
parameters in program variables. Unlike with DB2 Common Servers or DB2 UDB, you cannot use an
SQLDA to receive parameters. You must consider this difference when porting stored procedures from
one server to the other.

Code examples on how to receive the parameters in a stored procedure are presented below.
Assume that two parameters (PARM1 and PARM2) are being passed. PARM1 is an input parameter
defined as SMALLINT in the SYSIBM.SYSPROCEDURES table, and PARM2 is an output parameter
defined as CHAR(10) in the SYSIBM.SYSPROCEDURES table. The linkage convention for the samples
is SIMPLE WITH NULLS.

You must test the indicator variable for the input parameter to check whether it is null. You must
assign a value to the output parameter and its corresponding indicator variable.

COBOL Stored Procedure:


.
.
.
DATA DIVISION.
LINKAGE SECTION.
* The parameters and the indicator array must be defined in the
* linkage section
01 PARM1 PIC S9(4) COMP.
01 PARM2 PIC X(10).
01 INDARRAY.
05 INDVAR1 PIC S9(4) COMP.
05 INDVAR2 PIC S9(4) COMP.
.
.
PROCEDURE DIVISION USING PARM1, PARM2, INDARRAY.
* The USING clause shows the parameters being passed by the
* the client program
.
.
* You must test the indicator variable for the input parameter
* in order to check if it is null
IF INDVAR1 < 0
PERFORM NULL-PROCESSING
.
.
* You must assign a value to the output parameter and its
* corresponding indicator variable
MOVE ″ALINE″ TO PARM2.

Chapter 6. Coding Stored Procedures in DB2 on MVS 93


MOVE ZERO TO INDVAR2.
* If you want to return a null value to the output parameter
* you must move a negative value to the indicator variable

PL/I Stored Procedure: For PL/I stored procedures, you must specify the compile option,
SYSTEM(MVS), and the run-time option, NOEXECOPS.
*PROCESS SYSTEM(MVS);
SP1: PROCEDURE (PARM1,PARM2,INDSTRUC) OPTIONS(MAIN NOEXECOPS REENTRANT);
/* In the PROCEDURE statement you must specify the two parameters */
/* and the indicator variables structure. */
/* */
DCL V1 BIN FIXED(15),
V2 CHAR (10);
DCL 01 INDSTRUC,
02 INDVAR1 BIN FIXED(15),
02 INDVAR2 BIN FIXED(15);
.
.
.
/* You must test the indicator variable for the input parameter */
/* in order to check if it is null */
IF INDVAR1 < 0 THEN
CALL NULLPROC;
.
.
/* You must assign a value to the output parameter and its */
/* corresponding indicator variable */
PARM2 = ′ ALINE′ ;
INDVAR2 = 0;
/* If you want to return a null value to the output parameter */
/* you must move a negative value to the indicator variable */

C Stored Procedure:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
EXEC SQL BEGIN DECLARE SECTION;
short parm1; /* Declarations of the stored procedure parameters
char parm2[11]; /* and indicator array. Note that the size
struct ind { /* of parm2 is 11. Character strings in C are
short indvar1; /* terminated with a null character.
short indvar2;
} indstruc;
EXEC SQL END DECLARE SECTION;
/* argc contains the number of parameters being passed */
/* argv is an array of strings containing the parameter values */
void main(int argc, char *argv[″ )
{
memcpy(&indstruc,(struct ind *) argv[3] /* Get contents of the
sizeof(indstruc)); /* indicator variables array
if (indstruc.indvar1 < 0) /* Test the input parameter for nulls
{
.
.
.
}
else {

94 Getting Started with DB2 Stored Procedures


parm1 = *(int *) argv[1]; /* Get the value of the input parameter
.
.
.
strcpy(argv[2],parm2); /* Move value to output parameter
indstruc.indvar2 = 0; /* Set output parameter indicator variable

memcpy((struct ind *) argv[3],&indstruc /* Copy indicator array ba ck


sizeof(indstruc)); /* to parameter area
}

If you are using C/370 Version 1 Release 1, your C program may need the following run-time option in
order to receive the parameters correctly:
#pragma runopts(PLIST(MVS))

If the program was ported from another platform and the [ and ] display as a Y and ″ respectively, you
have to edit the source code and type the [ and ] symbols using the hexadecimal values X′AD′ and
X′BD′.

6.2.3.4 Rules for Assigning Parameters: To send input parameters from the client program to
the stored procedure and output parameters from the stored procedure to the client program, DB2
uses a parameter list intermediate area. This intermediate area is based on the data type and size
defined in the PARMLIST column of the SYSIBM.SYSPROCEDURES table.

When passing input variables, DB2 copies the values of the client program variables to the
intermediate area, using the “store assignment” rules of the SQL ISO/ANSI standard. Then DB2
copies the values from the intermediate area to the stored procedures variables, using DB2 rules for
assigning values to host variables. Figure 64 shows the assignment of input parameters.

Figure 64. Assigning Values to Input Parameters

The “store assignment” rules of the SQL ISO/ANSI standard are the same as the DB2 rules for
assigning values to host variables, with one exception: When the input value is a string that is longer
than the target, an error occurs if the excess characters are not blanks. If the excess characters are
blanks, they are discarded, and the truncated string is assigned to the target. When the store
assignment uses DB2 rules, the string is truncated even if the excess characters are not blank.

Chapter 6. Coding Stored Procedures in DB2 on MVS 95


When returning output parameters to the client program, DB2 uses a similar process. DB2 uses an
intermediate area and copies the values of the stored procedure variables to the intermediate area,
using the “store assignment” rules of the SQL ISO/ANSI standard. Then DB2 copies the values from
the intermediate area to the client program variables, using DB2 rules for assigning values to host
variables. Figure 65 shows the assignment of output parameters.

Figure 65. Assigning Values to Output Parameters

6.2.3.5 Data Type Conversion: When passing parameters to a stored procedure, use the same
definitions both for the variables related to the parameters in the client program and those in the
stored procedure. These variables should also be compatible with the definition of the parameters in
the PARMLIST column of the SYSIBM.SYSPROCEDURES table.

In some cases, when you are assigning values to parameters, DB2 may have to use data type
conversion. Data type conversion is performed automatically by DRDA. However, check the
compatibility between SQL data types and the programming language data types.

Character data types are compatible with each other. Variable-length or fixed-length definitions are
compatible with both CHAR and VARCHAR. However, for assignments where SQL ISO/ANSI standard
rules are in effect, it may not be possible to move the values between character strings of different
sizes. In this case, the client program receives an SQLCODE -302 after the SQL CALL statement.
Character data types are not compatible with numeric data types. If your client program tries to pass
character data to numeric stored procedure parameters, an SQLCODE -301 is sent to the client
program after the SQL CALL statement.

Numeric data types are compatible with each other. You can use any numeric data type definition to
assign values to SMALLINT, INTEGER, DECIMAL, REAL, or FLOAT parameter types. However, if the
target parameter cannot receive the value—for example, if a number greater than 32767 is assigned to
a SMALLINT parameter—an an SQLCODE -406 is sent to the client program after the SQL CALL
statement.

Graphic data types are compatible with each other. A GRAPHIC or VARGRAPHIC parameter is
compatible with fixed-length or variable-length graphical programming language data types.

DATE, TIME, and TIMESTAMP SQL data types are not supported as stored-procedure parameter data
types. These data types must be defined as character data types in both the client program and the
PARMLIST column. In this case, no value checking occurs while assigning the parameter values.

96 Getting Started with DB2 Stored Procedures


However, if the stored procedure uses these parameters to perform an SQL operation in a DATE, TIME,
or TIMESTAMP column, an error occurs if the character string is not a valid date-time value.

6.2.4 Calling Other Programs from a Stored Procedure


In DB2 Version 4 or DB2 Version 5, a stored procedure cannot use the SQL CALL statement to invoke
another stored procedure. However, it is possible to call other programs from a stored procedure by
using facilities of the programming language. You can pass parameters to those called programs and
receive parameters from them. Here is a COBOL example of calling a program from a stored
procedure:
CALL ″EXTPROG″ USING PARM1, PARM2, ...

The called programs can be used for specific functions, such as validation of parameters or complex
calculations, and can contain any SQL statements that are valid in a stored procedure.

All called programs that contain SQL statements require a DB2 package. The packages of the called
programs do not have to belong to the same collection as the package of the stored procedure. If you
specify a different collection for the called program, you must code a SET CURRENT PACKAGESET to
the called program collection, before calling the program. After calling the program, you may have to
issue the SET CURRENT PACKAGESET statement to the stored procedure collection, if the stored
procedure has SQL statements after the call. If you do not execute a SET CURRENT PACKAGESET, the
called program package must belong to the same collection as the stored procedure package.

When the stored procedure ends, the CURRENT PACKAGESET special register is restored to the value
it had before the SQL CALL statement. As shown in Figure 66, the collection used for the client
program is COLL1. The package for the stored procedure (PKGSTPC) is in collection COLL2. The
stored procedure invokes a program (ROUTINE3) whose package is in collection COLL3. Therefore,
before invoking ROUTINE3, the stored procedure must use the SET CURRENT PACKAGESET command
to set the collection to COLL3. After execution of ROUTINE3, any SQL statement executed by the
stored procedure is searched in PKGSTPC in collection COLL3. If PKGSTPC was not also bound in
collection COLL3, the SQL statement is not found. If this is the case, you must code in your stored
procedure the SET CURRENT PACKAGESET command to reset the collection to COLL2.

Figure 66. Calling External Programs from Stored Procedures (Example 1)

Chapter 6. Coding Stored Procedures in DB2 on MVS 97


As shown in Figure 67 on page 98, if PKGSTPC was bound in both COLL2 and COLL3, then you are
not required to use the SET CURRENT PACKAGESET command to reset the collection to COLL2.

Figure 67. Calling External Programs from Stored Procedures (Example 2)

On completion of the stored procedure, the CURRENT PACKAGESET register is reset to COLL1.
Therefore, the client program does not have to issue the SET CURRENT PACKAGESET command.

If you are calling the stored procedure from a local DB2 client application, the packages of the stored
procedure and of all called programs must be bound into the client application plan.

The called program does not need to use LE/370. You can even call a REXX procedure

6.2.5 Calling a REXX Procedure from a Stored Procedure


You can call a REXX procedure from a stored procedure. The following is a PL/I example of the code
you can include in your stored procedure to call a REXX procedure:
/*******************************************************************/
/* FUNCTION : CALL A REXX EXEC FROM A PL/I PROGRAM USING IRXJCL */
/* FROM TSO EXTENSIONS VERSION 2 : REXX REFERENCE SC28-1883-1 */
/*******************************************************************/
DCL IRXJCL EXTERNAL OPTIONS(RETCODE, ASSEMBLER) ;
DCL PARAMETER CHAR (100) VARYING ;
DCL 1 PARM_STRUCT
, 5 PARM_LNG FIXED BIN (15)
, 5 PARM_STR CHAR (80)
;
DCL PLIRETV BUILTIN ;
/* DCL LENGTH BUILTIN */

PARM_STR = ′ HI this is a set of parameters passed′ ;


PARM_LNG = LENGTH(PARM_STR) ;
PUT SKIP DATA (PARM_LNG, PARM_STR) ;

FETCH IRXJCL ;
CALL IRXJCL (PARM_STRUCT) ;
PUT SKIP EDIT (′ RETURN CODE FROM IRXJCL WAS : ′ , PLIRETV) (A, F(4)) ;

98 Getting Started with DB2 Stored Procedures


You need to add a SYSEXEC DD statement where the REXX application code resides and any other DD
statements such as SYSTSPRT in the stored procedure address space.

Although you can pass parameters to the REXX procedure, the only way for REXX to pass data back to
the stored procedure is using ISPF variables. So the application of calling a REXX procedure from a
PL/I stored procedure can be limited.

If you want to use a reentrant environment, you must explicitly call the initialization routine, IRXINIT, to
initialize the environment. TSO/E REXX automatically initializes nonreentrant environments only.
When you invoke IRXINIT to initialize a reentrant environment, you must set the RENTRANT flag on.
Refer to OS/390: TSO/E REXX Reference for more information.

6.3 Stored Procedure Preparation

The tasks involved in preparing a stored procedure to run in a DB2 on the MVS environment are
basically the same as the tasks for any DB2 program. You must precompile, compile, and link-edit the
stored procedure. You must also bind a package for the stored procedure. An additional task to be
performed when preparing a stored procedure is the definition of the stored procedure in the
SYSIBM.SYSPROCEDURES TABLE.

6.3.1 JCL for the Stored Procedure Preparation


The following is a sample JCL to prepare a stored procedure written in COBOL for DB2 Version 4:
//STDRD2AB JOB (999,POK),NOTIFY=&SYSUID,
// CLASS=A,MSGCLASS=T,MSGLEVEL=(1,1)
//PREPS01 EXEC DSNHCOB2,MEM=TS0BMS, --> (1)
// COND=(4,LT),
// PARM.PC=(′ HOST(COB2)′ , QUOTE,APOSTSQL,SOURCE,XREF,
// ′ STDSQL(NO)′ ) ,
// PARM.COB=(QUOTE, NOTRUNC, ′ BUF(12288)′ , SOURCE)
//PC.DBRMLIB DD DSN=DSN410.DBRMLIB.DATA(TS0BMS),
// DISP=SHR
//PC.SYSIN DD DSN=STDRD2A.LIB.SOURCE(TS0BMS),
// DISP=SHR
//LKED.SYSLIB DD DISP=SHR,
// DSN=CEE.V1R5M0.SCEELKED --> (2)
// DD DISP=SHR,
// DSN=DSN410.SDSNLOAD
//LKED.SYSLMOD DD DSN=DSN410.RUNLIB.LOAD(TS0BMS), --> (3)
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNALI) --> (4)
MODE AMODE(31) RMODE(ANY) --> (5)
//PREPS02 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT) --> (6)
//DBRMLIB DD DSN=DSN410.DBRMLIB.DATA,DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DB41)
BIND PACKAGE(CENTDB2.SPCOLLID) MEMBER(SPPACKAG) -
LIBRARY(′ DSN410.DBRMLIB.DATA′ ) -
ACT(REP) ISOLATION(CS) VALIDATE(BIND)
END
//

Chapter 6. Coding Stored Procedures in DB2 on MVS 99


Note the following in this JCL:
1. We use the DB2 procedure for preparing COBOL programs.
2. During the link-edit step, we include the LE/370 library. The stored procedure must be link-edited
with LE/370 modules.
3. The stored procedure must be link-edited to a load library that is available to the stored
procedures address space.
4. The stored procedure is a CAF application. It must be link-edited with the DSNALI module. Note
that for a WLM-established stored procedure, you must link-edit the stored procedure with DSNRLI
module.
5. To reduce the storage required below 16 MB, we link-edit the stored procedure with AMODE(31)
RMODE(ANY). This is also a requirement for WLM-established stored procedures address spaces.
6. We include a step to bind the package for the stored procedure.

6.3.2 Binding the Stored Procedure


A stored procedure does not require a plan. You need only bind a package for the stored procedure.
If the client program executes in the DB2 on MVS environment, the client program requires a plan, with
a database request module (DBRM) bound directly in the plan, or with a package for the program.
Figure 68 shows the packages required to invoke a stored procedure.

Figure 68. Stored Procedure Packages

The client program package and the stored procedure package do not have to belong to the same
collection. The COLLID column of SYSIBM.SYSPROCEDURES specifies the collection that contains the
stored procedure package. If the COLLID value is blank, DB2 uses the collection name of the client
program package.

A stored procedure may have more than one package. For example, when you call other programs
that access DB2 resources, each program must have its own package.

The client program requires a plan if it runs in an MVS environment. If it is a remote client, the client
program plan does not have to include the stored procedure package. Up to DB2 Version 5, if the
client program runs in the same location as the stored procedure, the client program plan must include
the stored procedure package and the packages of the programs that the stored procedure invokes.

If your stored procedure does not contain SQL statements (for example, a stored procedure that uses
only IFI calls) it does not require a package to be created.

100 Getting Started with DB2 Stored Procedures


6.3.3 Privileges Required
The privileges required to execute a plan or package containing an SQL CALL statement must include
at least one of the following:
• EXECUTE privilege on the plan or package
• OWNER of the plan or package
• PACKADM authority for the collection (packages only)
• SYSADM authority

Additional privileges are required on each package used by the stored procedure during its execution.
The application server determines the privileges that are required and the authorization ID that must
have the privileges. If the server is DB2 on MVS, the privileges and authorization ID depend on the
syntax for specifying the stored procedure to be invoked in the SQL CALL statement, as we explain in
6.3.3.1, “Specifying a Procedure Name” and 6.3.3.2, “Specifying a Host Variable.”

6.3.3.1 Specifying a Procedure Name: For programs containing an SQL CALL statement that
specifies the procedure name, the owner of the package or plan containing the SQL CALL statement
must have at least one of the following privileges on each package used by the stored procedure
during its execution:
• EXECUTE privilege on the package
• OWNER of the package
• PACKADM authority for the package′s collection
• SYSADM authority

6.3.3.2 Specifying a Host Variable: For programs containing an SQL CALL statement that
specifies a host variable for the procedure name, the privilege set (see below) must include at least
one of the following on each package used by the stored procedure during its execution:
• EXECUTE privilege on the package
• OWNER of the package
• PACKADM authority for the package′s collection
• SYSADM authority
The privilege set is the union of the privileges held by:
• The OWNER of the package or plan containing the SQL CALL statement. In the case of ODBC or
CLI applications, this is the OWNER of the package or plan associated with the ODBC or CLI driver.
• The primary SQL authorization ID of the application process
• The secondary SQL authorization IDs associated with the application process

The difference between specifying a procedure name and a host variable is this: For a procedure
name, the authorization ID of the package or plan OWNER must have one (or more) of the required
privileges, while for a host variable, the authorization ID that must have one (or more) of the privileges
is:
• The package or plan OWNER
• The primary authorization ID executing the SQL CALL
• One of the primary′s secondary authorization ID

Chapter 6. Coding Stored Procedures in DB2 on MVS 101


6.3.4 Making Your Stored Procedure Reentrant
You can improve the performance of your stored procedure if you prepare it to be reentrant. By
preparing the stored procedure as reentrant, you reduce the amount of virtual storage required for the
stored procedures address space because only one copy of the stored procedure is used for many
clients. Having a reentrant stored procedure eliminates the need to load the stored procedure every
time it is called.

To prepare your stored procedure as reentrant, you must compile it as reentrant and link-edit it as
reentrant and reusable. To compile the program as reentrant, you must use the appropriate compiler
option:
• For COBOL, use the RENT compiler option.
• For C, use the RENT compiler option and invoke the C/370 prelink utility. Refer to the C/370
manuals for more information on the prelink utility.
• For PL/I, use PROC OPTIONS(REENTRANT).

Besides compiling the program as reentrant, you must specify the RENT and REUS options for the
linkage editor. This specification is also necessary to produce reentrant and reusable load modules.

Here is sample JCL for compiling and link-editing a reentrant stored procedure:
//PREPS01 EXEC DSNHCOB2, ....
// PARM.COB=(RENT, ....
// PARM.LKED=(RENT, REUS, ...

6.3.5 Resident Stored Procedures


You can make your reentrant stored procedure resident in the stored procedures address space. Set
the STAYRESIDENT column of the SYSIBM.SYSPROCEDURES table to Y.

LE/370 is responsible for handling resident stored procedures. The minimum level of LE/370 to have
stored procedures resident is LE/370 Version 1 Release 3.

If your stored procedure is not reentrant, it cannot stay resident. For nonreentrant stored procedures
you must specify N in the STAYRESIDENT column of the SYSIBM.SYSPROCEDURES table.

We recommend that you implement all production stored procedures as reentrant and reusable and
specify Y in the STAYRESIDENT column of SYSIBM.SYSPROCEDURES.

If you implement your stored procedure with the nonreusable attribute, you must specify N for the
STAYRESIDENT column of SYSIBM.SYSPROCEDURES.

Any other combination can lead to problems. For example, if you implement your stored procedure
with the nonreusable attribute and specify Y in the STAYRESIDENT column of
SYSIBM.SYSPROCEDURES, DB2 on MVS loads one copy of the stored procedure′s load module for
every SQL CALL statement issued for the stored procedure. Eventually, the stored procedures address
space runs out of virtual storage.

If you compile your stored procedure as nonreentrant, you must link-edit it with the NOREUS and
NORENT attributes. If you do not follow this rule, the results will be unpredictable.

102 Getting Started with DB2 Stored Procedures


6.3.6 Defining the Stored Procedure to DB2
You must define your stored procedure to DB2. DB2 Version 4 and DB2 Version 5 use the
SYSIBM.SYSPROCEDURES table to keep information about stored procedures. In future versions, this
may change to use DB2 catalog tables to define stored procedures using DDL.

For more information on the SYSIBM.SYSPROCEDURES table refer to 2.3.1.1,


“SYSIBM.SYSPROCEDURES Table Columns” on page 14.

Every stored procedure must have at least one row in the SYSIBM.SYSPROCEDURES table. You can
populate the table by using SQL statements or the load utility. Listed below is an example of an SQL
INSERT statement to insert data in the SYSIBM.SYSPROCEDURES table of DB2 Version 4 for a stored
procedure with the following characteristics:
• Stored procedure name is TS0BMS.
• Any user on any location can execute it.
• The load module name for the stored procedure is TS0BMS.
• The input parameters cannot be null.
• The collection name for the stored procedure package is TS0BMS.
• The stored procedure is written in COBOL.
• There is no service units limit for the stored procedure.
• It does not stay resident after execution.
• There is only one LE/370 run-time option: TEST(,,,SC02130I).
• It uses two parameters. Each can be used for input and output. The first is a character variable of
length 10, and the second, an integer variable.
INSERT INTO SYSIBM.SYSPROCEDURES
(PROCEDURE, AUTHID, LUNAME, LOADMOD,
LINKAGE, COLLID, LANGUAGE, ASUTIME,
STAYRESIDENT, IBMREQD, RUNOPTS,
PARMLIST)
VALUES(′ TS0BMS′ , -- > PROCEDURE
′ ′, -- > AUTHID
′ ′, -- > LUNAME
′ TS0BMS′ , -- > LOADMOD
′ ′, -- > LINKAGE
′ TS0BMS′ , -- > COLLID
′ COBOL′ , -- > LANGUAGE
0, -- > ASUTIME
′ ′, -- > STAYRESIDENT
′ N′ , -- > IBMREQD
′ TEST(,,,SC02130I)′ , -- > RUNOPTS
′ CHAR(10) INOUT, INTEGER INOUT′ ) ; -- > PARMLIST

You can also use the DSNTIAD sample program to run this insert in your preparation JCL.

For this project we made heavy use of the Database 2 Administration Tool MVS/ESA (DB2 Admin)
program product (5688-515). We installed a beta version which runs under DB2 for OS/390 V5. This is
equivalent to having applied the PTF UQ12144. Its panels simplify many administration tasks, such as:
• Adding and updating entries to the communications database (CDB)
• Adding, updating, and deleting entries in SYSIBM.SYSPROCEDURES
• Starting, stopping, and displaying stored procedures

Chapter 6. Coding Stored Procedures in DB2 on MVS 103


• Starting, stopping, and displaying threads
• Running SQL on the fly with the SQL primary command
• Connecting to remote DRDA AS′s using the CONNECT TO and CONNECT RESET primary
commands
Figure 69 shows the panel to manage stored procedures using the DB2 Administration Tool.

DB2 Admin ---------------- DBC1 Manage Stored Procedures ---------------- 14:25


Option ===>

DB2 System: DBC1


1 - Display/update stored procedures DB2 SQL ID: DB2RES1
2 - Insert stored procedure
3 - Display stored procedure statistics
4 - Start all stored procedures
5 - Stop all stored procedures
6 - Create view on SYSIBM.SYSPROCEDURES
7 - Display views on SYSIBM.SYSPROCEDURES

Stored procedure catalog table/view for options 1-2:


Owner ===> (default is SYSIBM)
Name ===> (default is SYSPROCEDURES)

Figure 69. Using the DB2 Administration Tool to Manage Stored Procedures

If you are changing information in the SYSIBM.SYSPROCEDURES table for a stored procedure already
defined, you may have to issue a START PROCEDURE command to update the information in the DB2
on MVS buffers. If you do not issue the START PROCEDURE command, the old information will still be
used, even after you change the SYSIBM.SYSPROCEDURES table.

6.3.7 Restricting Access to the SYSIBM.SYSPROCEDURES Table


If you are a DB2 administrator, you may not want to grant write privileges on the
SYSIBM.SYSPROCEDURES table to the stored procedure programmers. You can create views on the
SYSIBM.SYSPROCEDURES table that limit the access of the programmers to rows with specific
characteristics. For example, you can have a convention that all programs written by programmer
SILVIO must begin with SL. You can limit SILVIO′s access to only those rows where the value of the
LOADMOD column begins with SL. Use the following SQL CREATE statement:
CREATE VIEW SILVIO.PROCEDURES AS
SELECT PROCEDURE, AUTHID, LUNAME, LOADMOD, LINKAGE, COLLID,
LANGUAGE, ASUTIME, STAYRESIDENT, IBMREQD, RUNOPTS, PARMLIST
FROM SYSIBM.SYSPROCEDURES
WHERE LOADMOD LIKE ′ SL%′
WITH CHECK OPTION;
GRANT ALL ON TABLE SILVIO.PROCEDURES TO SILVIO;

With this technique, you can grant write privileges to programmer SILVIO for this view only.

104 Getting Started with DB2 Stored Procedures


Chapter 7. Coding Stored Procedures for DB2 Common Servers and
DB2 UDB

In this chapter, we discuss the coding of stored procedures that execute in a workstation environment.
Here, any reference to DB2 on the workstation refers to DB2 Common Server or DB2 UDB. As with
any other DB2 on the workstation application, one of the first things you have to decide is which
language and interface to use.

7.1 Languages

DB2 on the workstation supports the C, C++, COBOL, and FORTRAN programming languages
through their precompilers. In addition, DB2 on the workstation supports the REXX language through a
dynamic interpreter.

7.1.1 Supported Languages for DB2 on the AIX Platform


The languages supported on the AIX platform are:
• C
− IBM XL C Compiler Version 1.2.1 or Version 1.3
− IBM C for AIX Version 3.1
• C + +
− IBM C/SET++ for AIX Version 2.1 or Version 3.1
• COBOL
− IBM COBOL Set for AIX Version 1.1
− Micro Focus COBOL Version 3.1 or later
• FORTRAN
− IBM AIX XL FORTRAN/6000 Version 2.3
− IBM XL FORTRAN for AIX Version 3.2

Note: Although DB2 on the AIX platform supports IBM AIX REXX/6000, it is not possible to code stored
procedures in REXX for DB2 on the AIX platform.

7.1.2 Supported Languages for DB2 on the OS/2 Platform


The languages supported on the OS/2 platform are:
• C or C++
− IBM C/Set++ for OS/2 Version 2.1
− IBM VisualAge C++ for OS/2 Version 3
• COBOL
− IBM COBOL VisualSet for OS/2 Version 1.1
− Micro Focus COBOL Version 3.1 or later
• FORTRAN
− WATCOM FORTRAN 77 32 Version 9.5

 Copyright IBM Corp. 1996 1998 105


• REXX
− IBM Procedures Language 2/REXX, which is supplied as part of OS/2

7.2 Coding Considerations


In this section, we discuss the rules for coding stored procedures, explain the differences between
stored procedures and other programs, and provide some examples of how to receive parameters in
stored procedures.

7.2.1 Rules for Coding


A stored procedure must be placed in a library (DLL for OS/2), unless it is a REXX stored procedure. It
executes on the server.

If the stored procedure is written with embedded SQL in one of the supported host languages, it must
be precompiled, compiled, and link-edited. Special compile options must be used (refer to 7.3, “Stored
Procedure Preparation” on page 111 for details), a library (or a function in a library) must be
produced, and the stored procedure must be bound to the database on the server before it can run.
The stored procedure cannot be executed directly from an executable (.EXE file).

If the stored procedure is written with CLI, you do not have to precompile it and you do not have to
bind it to the server, but you do have to compile and link-edit it according to the above rules.

If the stored procedure is written in REXX, there are no precompile, compile, link-edit, or bind tasks.
The stored procedure code resides in a .CMD file.

Note that for all these steps the stored procedure must use the same code page as the database.

For testing, it is usually easier to test first on a single machine. Stored procedures can also be
developed and tested on a stand-alone DB2. Once the stored procedure performs without errors, it
can be moved to a remote server. Remember, when you move a stored procedure to another server,
you have to rebind it to create a package at the new server database.

7.2.2 Differences between Stored Procedures and Other Programs


A stored procedure differs from other programs in the following ways:
• Screen output is not allowed although writing to a file is possible.
• You cannot issue the following SQL statements and commands inside a stored procedure:
− CALL
− CONNECT
− SET CONNECT
− RELEASE
− CONNECT RESET
− CREATE DATABASE
− DROP DATABASE
− BACKUP
− RESTORE
− FORWARD RECOVERY

106 Getting Started with DB2 Stored Procedures


• If the calling application was prepared with the CONNECT TYPE 2 specification, the stored
procedure cannot issue COMMIT or ROLLBACK statements.
• The SQLDA structure is not passed to the stored procedure if the number of elements, SQLD, is set
to 0. In this case, the stored procedure receives a null pointer.
• A stored procedure is not allowed to issue commands that would terminate the current process.
The commands must always return control to the client without terminating the current process.
• When the database manager at the server is started with the db2start command, all environment
variables beginning with DB2 are captured and made available to all stored procedures, including
unfenced stored procedures. The only exception is the DB2CKPTR environment variable, which is
not passed. Note that this is a one-time capture of the environment variables. If the environment
variables are changed at a later stage, the changes are not passed to the stored procedures until a
new db2start command is issued.

7.2.3 Receiving Parameters


Unlike DB2 on the MVS platform, in DB2 on the workstation all parameters passed from the client
program are considered for input and output.

The stored procedure executes when called by the client application. When the stored procedure is
invoked, the following occurs on the server:
1. The database manager generates an SQLDA data structure when the SQL CALL statement is
executed. Host variables are always passed through this SQLDA data structure.
2. The stored procedure accepts the SQLDA data structure from the client application.
3. The stored procedure executes on the database server under the same transaction as the client
application.
4. If output data is to be sent back from the stored procedure to the client, the output variables of the
SQLDA are used. The same variables can be used for both input and output.
5. The stored procedure copies the SQLCA information explicitly to the SQLCA parameter of the
stored procedure so that the calling program can check whether the stored procedure executed
correctly.
6. The stored procedure finishes processing and returns control to the client.

The parameters of the SQL CALL statement are treated as both input and output parameters and
converted to the following format for the stored procedure:
struct sqlda *inoutsqlda;
struct sqlca *sqlca;
void *reserved1, *reserved2;

SQL_API_RC SQL_API_FN proc_name( reserved1, reserved2, inoutsqlda, sqlca)

Unlike DB2 on the MVS platform, when the stored procedure is invoked in DB2 on the workstation, the
database manager provides the SQLDA to the stored procedure, regardless of how you code the CALL
statement in the client application. In other words, an SQLDA is passed to the stored procedure
regardless of whether you issue the CALL statement using host variables or the SQLDA.

Because the database manager automatically allocates the SQLDA structure at the database server,
do not allocate it, and do not alter any storage pointer for the input and output parameters. If you
attempt to replace a pointer with a locally created storage pointer, you receive an error with an
SQLCODE -1133.

Chapter 7. Coding Stored Procedures for DB2 Common Servers and DB2 UDB 107
7.2.3.1 C Example: In this example, we transfer a character string and a small integer through
the SQLDA from the client application to the stored procedure. First, the stored procedure is declared,
with the declaration accepting pointers to the SQLDA and SQLCA structures:
.....
SQL_API_RC SQL_API_FN cc22sbo1(void *reserved1,
void *reserved2,
struct sqlda *io_da,
struct sqlca *ca)
.....

We also have to declare working variables to facilitate the handling of information in the SQLDA in the
stored procedure. For our example we use:
.....
/* Declare Miscellaneous Variables */
.....
char *data_items[1];
short data_items_length[1];
short *data_itemy;
.....

The first SQLVAR in the SQLDA points to a character string; we can, for example, transfer it to the
data_items pointer:
.....
data_items[0] = io_da->sqlvar[0].sqldata;
data_items_length[0] = io_da->sqlvar[0].sqllen;
.....

The second SQLVAR in the SQLDA points to a small integer, which we can assign, for example, to the
data_itemy pointer:
.....
data_itemy = io_da->sqlvar[1].sqldata;
.....

7.2.3.2 REXX Example: In the REXX stored procedure, the values passed through the SQLDA are
received in the SQLRIDA stem variable. Output variables are sent back in the SQLRODA stem
variable. In the following list, n is a numeric value indicating a specific SQLVAR element in the
SQLDA:
sqlrida.sqld The number of variables in the SQLDA
sqlrida.n.sqldata Contains the data of the variable
sqlrida.n.sqltype The type of the variable
sqlrida.n.sqllen Contains the length of the variable
sqlrida.1.sqlind Contains the indicator variable

In the example below, a REXX stored procedure is called from a client application, receiving, as in our
C example, a character string and a small integer through the SQLDA. The database manager
retrieves the values from the SQLDA and adds them to the REXX variable pool. Adding the SQLDA
values to the REXX variable pool makes coding quite simple as the variables are immediately available
in the SQLRIDA stem variable:

108 Getting Started with DB2 Stored Procedures


.....
Received_number_of_vars = sqlrida.sqld
My_character_var = sqlrida.1.sqldata
My_integer_var = sqlrida.2.sqldata
.....

7.2.3.3 SQLZ_DISCONNECT_PROC and SQLZ_HOLD_PROC: When a stored procedure


ends, a return value is passed to the database manager to indicate whether the stored procedure′ s
library should be deleted or remain in memory upon exit.

If you want the stored procedure′s library to be deleted from memory, specify the following return
code:
SQLZ_DISCONNECT_PROC
Figure 70 shows this process.

Figure 70. Return with SQLZ_DISCONNECT_PROC

If the stored procedure is invoked only once, SQLZ_DISCONNECT_PROC should be returned to free
main memory.

If you want to implement a stored procedure to remain in memory after its execution, code the
following as the return statement in your stored procedure program (example for a C stored
procedure):
.....
return(SQLZ_HOLD_PROC);
}

Chapter 7. Coding Stored Procedures for DB2 Common Servers and DB2 UDB 109
Here is the example for a COBOL program:
.....
move SQLZ_HOLD_PROC to return-code
goback.
In this case, the database manager keeps the stored procedure′s library in memory, so the library
does not have to be loaded when the stored procedure is invoked. This option may lead to better
performance. Figure 71 shows this process.

Figure 71. Return with SQLZ_HOLD_PROC

If the client application issues multiple calls to invoke the same stored procedure, it is better to code
SQLZ_HOLD_PROC as the return value of the stored procedure. If you code SQLZ_HOLD_PROC, the
stored procedure′s library is not deleted from memory, and subsequent calls to this procedure result in
better performance. The last invocation of the stored procedure should return with
SQLZ_DISCONNECT_PROC to free main memory from the server. Otherwise, the library remains in
memory until the database manager is stopped. We recommend that, in the last call to the stored
procedure, the client application send a parameter indicating the final call, at which the stored
procedure ends with an SQLZ_DISCONNECT_PROC.

If you have an application that is infrequently used but consists of several programs executed
sequentially that invoke the same stored procedure, pass a parameter to the stored procedure so that
it can specify SQLZ_HOLD_PROC for all programs except the last.

Refer to Chapter 14, “DB2 Common Server Performance Considerations” on page 299.

110 Getting Started with DB2 Stored Procedures


7.2.4 Nulls to Reduce Network Traffic
If you have defined long variables that are used only for input or only for output or have no use for a
specific execution of the stored procedure, consider not transferring them between the client and the
server, to reduce network traffic. The client program should avoid transferring output-only host
variables, and the stored procedure should avoid transferring input-only host variables back to the
client. The value of the indicator variable associated with the host variable should be set to a negative
value. The client program should set the value of the indicator variable for output-only SQLVARs to
− 1. The stored procedure should set the value of the indicator variable for input-only SQLVARs to
− 128 to enable the database manager to choose which SQLVARs are passed.

The values of the indicator variables are not reset after the transfer. If, for example, the client program
sets the value of the indicator variable of an output-only host variable to a negative value, the stored
procedure must set the value to zero or a positive value if the parameter is to be passed back to the
client program.

If the stored procedure sets the value of the SQLVAR indicator variable of an input-only variable to a
negative value, the next time the client program invokes the stored procedure it should reset the value
to zero or a positive value for the parameter to be passed to the stored procedure.

For example, consider a stored procedure that calculates the highest salary and returns that value to
the client. In the client application that calls the stored procedure, the maximum salary host variable
(maxsal) has no value before the call. To avoid network traffic, its indicator variable value should be
set to a negative value. The indicator variable value and the client CALL statement would be:
maxsalind = -1;
EXEC SQL CALL storproc(:maxsal:maxsalind);
When the stored procedure calculates and sets the maxsal value, it should also reset the value of the
maxsalind indicator variable to a nonnegative value so that the result in maxsal is transferred back to
the client.

7.3 Stored Procedure Preparation

Stored procedures are stored either as functions inside a dynamic link library (DLL) on OS/2 or as a
library on AIX. REXX stored procedures are stored as a command file (extension .CMD). Remember
you cannot create REXX stored procedures on a DB2 for AIX server. For DB2 for OS/2, you can place
your DLLs in any directory that is in the LIBPATH of the server operating system. The convention,
however, is to place DLLs in the \sqllib\function directory of the server. You can add a COPY
statement at the end of the makefile to automatically place them in that directory after you have built
the stored procedure.

Unfenced stored procedures should be placed in the \sqllib\function\unfenced directory. Unfenced


stored procedures must be precompiled with the WCHARTYPE NOCONVERT option. Fenced stored
procedures may be precompiled with either the CONVERT or NOCONVERT options, which affects the
format of GRAPHIC data type manipulated by SQL statements in the stored procedure. Refer to the
PRECOMPILE command in the DB2 UDB Command Reference for more details.

As REXX stored procedures are command files, not libraries, they must be stored in a directory that is
in the PATH environment variable of the server operating system. The \sqllib\function directory is not
in the PATH environment variable, so you have to add the \sqllib\function directory to your PATH
environment variable or place the REXX stored procedures in another directory that is specified in the
PATH environment variable. Another approach is to qualify the path where the stored procedure is in
the CALL statement. Instead of coding, for example, INPSRV.CMD as the procedure name, you would
code D:\SQLLIB\FUNCTION\INPSRV.CMD as your procedure name in the CALL statement.

Chapter 7. Coding Stored Procedures for DB2 Common Servers and DB2 UDB 111
In the OS/2 environment, the PATH and LIBPATH statements are in your CONFIG.SYS file. If you
change something in that file, you must reboot your OS/2 to activate the changes. In AIX the LIBPATH
statement can be found in the .profile of the user who starts the database manager on the server.

If you have several copies of the same stored procedure in different directories, the copy found first in
the LIBPATH (PATH for REXX) sequence is executed.

You should place the sqllib/function/unfenced subdirectory in the LIBPATH to enable execution of
unfenced stored procedures, unless you will always call them by specifying the full path. If you have
two copies of a stored procedure, one unfenced, and the other fenced, the copy that is executed is the
copy found first after the LIBPATH sequence.

7.3.1 Uppercase and Lowercase


In this section, a reference to the stored procedure name is a reference to the function in the library
that contains the stored procedure.

For AIX the name of a stored procedure is always case-sensitive. For OS/2, if the procedure name is
in uppercase, the client program can invoke it using uppercase or lowercase. If the function is
exported in lowercase, it can only be accessed by using lowercase. However, if you want to map
uppercase to lowercase, add the following statement in the EXPORTS section of the module definition
file when linking your stored procedure:
EXPORTS
functioname
FUNCTIONAME=functioname
This statement declares the internal function as functioname, with two entry names: FUNCTIONAME
and functioname.

If the case is not correct, you get one of the following SQL error codes:
• SQL1106N The specified DLL dll_name module was loaded, but the stor_prc function could not be
executed.
• SQL1109 The specified DLL dll_name could not be loaded.

We recommend deciding whether you want your stored procedure names to be in uppercase or in
lowercase and then always follow your rule.

7.3.2 Makefiles
To build your stored procedures, you can either add them to the makefile or create separate, small
makefiles for each stored procedure. Here is the pr2c2s.mak file used to build the pr2c2s OS/2 stored
procedure:
DATASOURCE=sampos2
TESTUID=userid
TESTPWD=password

DB2INSTANCE=db2
CC=icc
LINK=link386
CFLAGS=-Ti+ -c+ -Ge- -Gm+ -W2
LINKFLAGS=/ST:64000 /NOI /PM:VIO
COPY=copy

# Library directories
DB2LIB=$(DB2PATH)\lib\db2api

112 Getting Started with DB2 Stored Procedures


pr2c2s.dll : pr2c2s.obj;
$(LINK) $(LINKFLAGS) pr2c2s.obj,pr2c2s.dll,,$(DB2LIB),pr2c2s.def;
$(COPY) pr2c2s.dll $(DB2PATH)\function

pr2c2s.obj : pr2c2s.c;
$(CC) $(CFLAGS) pr2c2s.c

pr2c2s.c : pr2c2s.sqc;
embprep pr2c2s $(DATASOURCE) $(TESTUID) $(TESTPWD)

The building of the stored procedure is invoked by entering this command:


nmake /f pr2c2s.mak

The compiler options used are:


• -c+: Compile only; do not link. (Linking is called later during build.)
• -Ge-: Build a .DLL file
• -Gm+: Link with the multithread version of the library
• -W2: Generate message group 2: Produce and count severe errors, errors, and warnings.

The -Ti+ option, found in some of the makefiles, generates debugger information and can be omitted.

7.3.3 Module Definition File


One of the input files for LINK386 is the module definition file. It provides information to LINK386 about
the DLL (or executable in other cases) it is creating. The module definition file usually has an
extension of .DEF; it contains one or more module statements that:
• Define various attributes of the executable file
• Define attributes of code and data segments
• Identify functions that are imported or exported
Note that VisualAge C and C++ use ILINK instead of LINK386.

Here is the inpsrv.def file, a sample module definition file that has six module statements:
LIBRARY INPSRV INITINSTANCE TERMINSTANCE
DESCRIPTION ′ Library for DB2 Stored Procedure INPSRV′
PROTMODE
DATA
MULTIPLE
NONSHARED
CODE
LOADONCALL
SHARED
EXPORTS
inpsrv

The LIBRARY statement assigns the name INPSRV to the DLL and specifies that the library be
initialized each time a new process gains access (INITINSTANCE) or relinquishes access
(TERMINSTANCE).

The DESCRIPTION statement inserts the text after the DESCRIPTION keyword in the library. If you
browse the library, you can find this description embedded at the end of the file.

Chapter 7. Coding Stored Procedures for DB2 Common Servers and DB2 UDB 113
The PROTMODE statement is specific for OS/2. It specifies that the module run only in protected mode
and not in Windows or dual mode.

The DATA statement defines the default attributes for data segments within the library. MULTIPLE
indicates that the automatic data segment is to be copied for each instance of the module.
NONSHARED indicates that the READWRITE data segment cannot be shared and must be loaded
separately for each process.

The CODE statement defines the default attributes for code segments in the library. LOADONCALL
indicates that a code segment is not to be loaded until accessed. SHARED indicates that it can be
shared.

The EXPORTS statement defines the name of the functions exported to other modules. The term
export refers to the process of making a function available to other run-time modules. You could also
add the following to this statement:
INPSRV=inpsrv
to ensure that the SQL CALL statement can specify the function name in uppercase or lowercase.

7.4 Stored Procedure Debugging

As a stored procedure cannot write output to a display, it is useful to know how to write some of the
stored procedure′s information to a file.

If you are debugging a stored procedure written in CLI, you should consider using the CLI application
trace. On AIX, you may consider using xldb to debug your stored procedure.

7.4.1 REXX Example


The following REXX code block can be embedded in your stored procedures. It first parses the source,
date, and time and writes them to an output file. Then it writes information from the SQLDATA and
SQLTYPE values to a file:
.....
/* Write some variables to file */
fn = ′ D:\SQLLIB\SAMPLES\REXX\REXX.dat′
parse source this_source
call lineout fn, ′ ------------------------------------------′
call lineout fn, this_source
call lineout fn, ′ Date : ′ date()′ Time : ′ time()

call lineout fn, ′ sqld : ′ | | sqlrida.sqld

call lineout fn, ′ value 1 : ′ | | sqlrida.1.sqldata


call lineout fn, ′ value 2 : ′ | | sqlrida.2.sqldata

call lineout fn, ′ type 1 : ′ | | sqlrida.1.sqltype


call lineout fn, ′ type 2 : ′ | | sqlrida.2.sqltype

call lineout fn, ′ len 1 : ′ | | sqlrida.1.sqllen


call lineout fn, ′ len 2 : ′ | | sqlrida.2.sqllen

call lineout fn, ′ ind 1 : ′ | | sqlrida.1.sqlind


call lineout fn, ′ ind 2 : ′ | | sqlrida.2.sqlind

call lineout fn /* Close the file */

114 Getting Started with DB2 Stored Procedures


.....

If you do not specify the path for the file name, the file is written in the root directory of your DB2 for
OS/2 drive.

7.4.2 C Example 1
In this example, we write data received in the SQLDA to a file. First we have to add one more include
file that will contain the information being traced:
.....
#include <stdio.h> /* Added for writing to file Bo.1 */
.....

We also have to declare one more variable containing the file name of our output file:
.....
/* Declare Miscellaneous Variables */
.....
FILE *stream; /* Added for writing to file Bo.2*/
.....

Now we can open the file and write a first record:


.....
stream = fopen(″stproc.dat″, ″w″ ) ; / * Open the file Bo.3 */
fprintf(stream,″Hello world \n″ ) ; /* Write a first record */
.....

Now let us take the character and small integer variables passed through the SQLDA from our
example in 7.2.3.1, “C Example” on page 108. First we take SQLTYPE and SQLDATA from the
character string:
.....
data_items[0] = io_da->sqlvar[0].sqldata;
data_items_length[0] = io_da->sqlvar[0].sqllen;
fprintf(stream,″Type of sqlvar0 ′%i′ \n″ , io_da->sqlvar[0].sqltype);
fprintf(stream,″Value of sqlvar0 ′%s′ \n″ , data_items[0]);
.....

Then we can write the second SQLVAR, the small integer:


.....
fprintf(stream,″Type of sqlvar1 ′%i′ \n″ , io_da->sqlvar[1].sqltype);
data_itemy = io_da->sqlvar[1].sqldata;
fprintf(stream,″Value of sqlvar1 ′%i′ \n″ , *data_itemy);
.....

After all information has been written, we close the file:


.....
fprintf(stream,″The end \n″ ) ;
fclose (stream); /* Close the file Bo.4 */
.....

When you run a stored procedure, a file named stproc.dat is created in the root directory of your
server containing the SQLLIB directory. The stproc.dat file contains the output created by the stored
procedure.

Chapter 7. Coding Stored Procedures for DB2 Common Servers and DB2 UDB 115
7.4.3 C Example 2
In this example, we write some of the data in the SQLCA to a file if an error occurs. Again we must
include the stdio.h file as in Example 1. We declare two variables: the stream variable, exactly as in
Example 1, and a new variable, my_errmsg:
.....
/* Declare Miscellaneous Variables */
.....
FILE *stream;
char my_errmsg[71];
.....

In our program we include the following statement:


.....
EXEC SQL WHENEVER SQLERROR GOTO error_exit;
.....
This statement causes the program to call the error_exit function whenever an SQLERROR occurs.

We add some statements to the error_exit function to write the SQLCODE, SQLERRMC, and SQLSTATE
to file:

error_exit:
/* An Error has occurred - ROLLBACK and return to Calling Program */
memcpy( ca, &sqlca, sizeof( struct sqlca ) );

EXEC SQL ROLLBACK;

/* Filewrite for debug */


stream = fopen(″stproc.dat″, ″w″ ) ; /* Open file */
fprintf(stream,″Hello world, I have a msg \n″ ) ; / * Write a record */

fprintf(stream,″SQLCODE : ′%i′ \n″ , ca->sqlcode);


/* Copy the message from the sqlca */
strncpy(my_errmsg, ca->sqlerrmc, ca->sqlerrml);
fprintf(stream,″SQLERRMC : ′%s′ \n″ , my_errmsg);
fprintf(stream,″SQLSTATE : ′%s′ \n″ , ca->sqlstate);

fprintf(stream,″The end \n″ ) ;


fclose (stream); /* Close file */

return(SQLZ_DISCONNECT_PROC);
}

7.4.4 The SENDDA and SHOWDA Samples


When working with stored procedures, it is important to have exact information about the SQLTYPE in
the SQLDA. Most problems with stored procedures occur when you assume a certain data type rather
than confirming it.

It is good programming practice to always interpret the SQLDA and verify that it is what you expected.
The SENDDA client program and SHOWDA stored procedure that come with the CLI samples enable
you to display and verify the SQLDA. You can reuse both code examples in your own programs.

116 Getting Started with DB2 Stored Procedures


Chapter 8. Coding Client Applications

In this chapter, we describe coding techniques and the program preparation process to create client
applications that call stored procedures on workstation and on MVS platforms.

8.1 Calling Stored Procedures

You can code a client application that invokes a stored procedure in the same way you code any other
application that uses SQL statements. The SQL CALL statement is used to invoke stored procedures
from local or remote client applications.

8.1.1 The SQL CALL Statement


The SQL CALL statement is part of the ISO/ANSI standard for SQL3. It is an open solution to invoke
stored procedures between relational database manager systems.

Figure 72 shows the client application functions for invoking a stored procedure with the SQL CALL
statement.

Figure 72. Basic Client Application Functions

The client application must connect to the DB2 server before issuing the SQL CALL statement. The
SQL CALL statement cannot be used dynamically, although in a CLI or ODBC application you can use
the SQLPrepare for a CALL statement.

The SQL CALL statement must include the stored procedure name and, optionally, the parameters to
be passed to the stored procedure through the SQLDA, host variables, or constants (for DB2 on the
MVS platform clients only). See 8.3, “SQL CALL Statement in DB2 on the Workstation” on page 123,
and 8.2, “SQL CALL Statement in DB2 on the MVS Platform” on page 119 for an explanation of the
SQL CALL syntax.

The SQL CALL statement enables the client application to pass parameters to the stored procedure
and receive parameters from the stored procedure. Therefore, the client application must declare,

 Copyright IBM Corp. 1996 1998 117


allocate, and initialize the variables to be used as parameters. These variables must have data types
compatible with the parameters expected by the stored procedure.

Parameters can be used to exchange data in both directions. Indicator variables can be used to nullify
parameters. When a parameter is null, only the indicator variable is sent through the network. The
client application can nullify parameters that are used only for output, and the stored procedure can
nullify parameters that are used only for input, thus reducing the sending and receiving of unnecessary
data.

For DB2 on the MVS platform, the specification of whether a parameter is used only for input, only for
output, or for both is dependent on the information registered in the SYSIBM.SYSPROCEDURES table.
Refer to 2.3.1.1, “SYSIBM.SYSPROCEDURES Table Columns” on page 14.

For DB2 on the workstation, all parameters are considered to be used for input and output, except
when using ODBC and CLI. When using ODBC and CLI you can specify which parameters are used for
input, for output, or for both.

8.1.2 Commit and Rollback


The SQL operations of a stored procedure are executed within the client′s unit of work. Therefore, the
client application has explicit control over the scope of the unit of work and is responsible for commit
or rollback processing.

Because stored procedures in DB2 on the MVS platform cannot execute commit or rollback processing,
the processing must be performed in the client application. For DB2 Version 5, if you specify
COMMIT_ON_RETURN=YES, the unit of work is committed when control returns to the client
application.

Stored procedures in DB2 on the workstation can execute commit or rollback processing if the client
application is precompiled with CONNECT TYPE 1. In this case, commit and rollback processing can
be performed from either the client application or the stored procedure. If a COMMIT is issued from
the stored procedure, the current unit of work is terminated and a new unit of work is initiated.

8.1.3 Using an SQLDA to Pass Parameters


The SQL CALL statement must be embedded in the client application; it cannot be dynamically
prepared. However, in the SQL CALL statement, you can use a host variable to specify the name of
the stored procedure and an SQLDA structure to pass parameters. Using this technique, it is possible
to define the stored procedure to be called and the parameters to be passed during the execution of
the client application, in a way similar to dynamic SQL (see Figure 73 on page 119).

118 Getting Started with DB2 Stored Procedures


Figure 73. Passing Stored Procedure Name (Host Variable) and Parameters (SQLDA)

In Figure 73 STOPROCA and STOPROCB are two stored procedures that are to be invoked by a client
application. STOPROCA uses three parameters: A1, A2, and A3. STOPROCB uses two parameters: B1
and B2.

The client application moves STOPROCA to a variable called procname , moves parameters A1, A2, and
A3 to an SQLDA structure called sqlda , and then executes the CALL statement. This CALL statement
invokes stored procedure STOPROCA and sends parameters A1, A2, and A3 to it.

The client application could also move STOPROCB to a variable called procname , move parameters B1
and B2 to an SQLDA structure called sqlda , and then execute the CALL statement. In this case, the
CALL statement invokes stored procedure STOPROCB, sending parameters B1 and B2 to it.

In the example, the CALL statement is coded twice, but both statements are exactly the same. The
CALL statement could be coded only once in a routine. By changing the content of the procname
variable and the SQLDA structure before performing the routine, you could invoke the appropriate
stored procedure.

Note: Using an SQLDA to pass parameters requires that the client application provide information
about the number of parameters, data type, data length, and indicator of each parameter.

8.2 SQL CALL Statement in DB2 on the MVS Platform

Figure 74 on page 120 shows the syntax of the SQL CALL statement in DB2 for MVS/ESA.

Chapter 8. Coding Client Applications 119


Figure 74. SQL CALL Statement Syntax in DB2 on the MVS Platform

8.2.1 Specifying the Procedure Name


The procedure name can be specified through a constant, represented as procedure name in
Figure 74, or within a host variable .

8.2.1.1 Using Procedure Name: The procedure name is a qualified or unqualified name. You
can specify the procedure name in any of the following ways:
• A fully qualified procedure name with three parts: the first part is a location name. The second
part depends on the application server. In the current releases of DB2, the second part must
contain the value SYSPROC. The third part identifies the stored procedure.
• A two-part name. The location name of the current server is implicitly used to qualify the
procedure name. In the current releases of DB2, the first part must be SYSPROC, and the second
part identifies the stored procedure.
• An unqualified name identifying the stored procedure. The name is implicitly qualified by the
location name of the current server and by the value SYSPROC.

If the server is DB2 on MVS, the last part of the procedure name must match an entry in the
PROCEDURE column of the SYSIBM.SYSPROCEDURES table.

Currently, if the stored procedure is located in DB2 on MVS, you can use qualified or unqualified
procedure names. If using fully qualified names, you must connect to the DB2 on MVS where the
stored procedure is located before issuing the SQL CALL statement. If the stored procedure is located
in a DB2 on the workstation, you can only use unqualified names.

8.2.1.2 Using a Host Variable: The name of the stored procedure is passed through a host
variable, which must be a character-string variable with a length attribute that is not greater than 254
bytes, and it must not include an indicator variable. The actual value of the host variable can include
special characters.

When calling stored procedures in DB2 on the workstation, you may want to specify the full path where
the stored procedure resides. In this case, you must use a host variable and move the stored
procedure name with the full path to that variable. If you try to specify a full path as a constant, the
DB2 on MVS precompiler sends an error message.

8.2.2 Specifying the Arguments


Client applications running in a DB2 on MVS platform can specify the parameters for the stored
procedure as a list, or as a single structure using an SQLDA. When using a list of parameters, you can
use host variables, constants, or the NULL keyword.

120 Getting Started with DB2 Stored Procedures


8.2.2.1 Parameters as a List When specifying the arguments as a list of parameters, the
parameter can be a host variable, a constant, or the NULL string.

Host Variable: You can use host variables, separated by commas, as parameters for the stored
procedure. The assignment of these values to the stored procedure parameters is positional, so the
first host variable is assigned to the first stored procedure parameter, the second host variable to the
second parameter, and so on. You must ensure that you are passing the number of parameters that
the stored procedure is expecting.

The host variable being used as a parameter cannot be defined as a structure or an array, and it must
be defined with a data type compatible with the data type of the corresponding stored procedure
parameter.

You can use indicator variables. However, if the server is DB2 for MVS, you must ensure that the
stored procedure is defined to accept nulls in the SYSIBM.SYSPROCEDURES table or the parameter is
defined as an output parameter.

Constant: You can use constant values as parameters. The constant value must be compatible with
the data type of the stored procedure parameter. If the server is DB2 on MVS, to be able to pass
constants as parameters, the corresponding stored procedure parameter must be defined as input
only.

NULL: You can use the NULL string as a parameter in the SQL CALL statement. In this case, a null
value is passed to the stored procedure. If the server is DB2 on MVS, the corresponding stored
procedure parameter must be defined as input only, and the stored procedure must be defined to
accept nulls, in the SYSIBM.SYSPROCEDURES table.

8.2.2.2 Parameters Using an SQLDA: You can use an SQLDA structure to pass the
parameters to the stored procedure by specifying:
USING DESCRIPTOR descriptor-name
The descriptor-name is the name of the structure containing the SQLDA definition.

Before the SQL CALL statement is processed, the application must set the following fields in the
SQLDA:
• SQLD to indicate the number of variables used in the SQLDA when processing the statement. This
number must be the same as the number of parameters of the stored procedure.
• SQLN to indicate the number of SQLVAR occurrences provided in the SQLDA. This value must not
be less than the value of SQLD.
• SQLDABC to indicate the number of bytes of storage allocated for the SQLDA. This value must be
SQLN*44+16.
• SQLVAR is a structural array. Each SQLVAR element is associated with a stored procedure
parameter. The assignment is positional, so the first SQLVAR element is assigned to the first
stored procedure parameter, and so on. The following fields of each base SQLVAR element
passed must be initialized:
− SQLTYPE
− SQLLEN
− SQLDATA
− SQLIND

Chapter 8. Coding Client Applications 121


In 8.2.3, “Examples of SQL CALL Statements to Send Parameters” on page 122 we provide examples
of coding the SQL CALL statement to send parameters by using host variables or explicitly by using
the SQLDA structure.

8.2.3 Examples of SQL CALL Statements to Send Parameters


Regardless of the DB2 server being accessed, you can use host variables or an SQLDA structure to
send parameters. DB2 on MVS stored procedures receive the parameters in program variables, and
DB2 on the workstation stored procedures receive the parameters in an SQLDA structure. How the
parameters are received in the stored procedure is transparent to the client program.

Below we show two samples of coding the SQL CALL statement.

8.2.3.1 Passing Parameters with Host Variables: Here is an example of a COBOL program
using an SQL CALL statement with host variables to pass parameters.
Identification Division.
Program-ID. ″TS0BMCBM″ .
Data Division.
Working-Storage Section.
EXEC SQL INCLUDE SQLCA END-EXEC.
01 PROG-NAME PIC X(12) VALUE ″BB22STS0″ .
01 PARM1 PIC X(10) VALUE ″ ″.
01 PARM2 PIC S9(9) COMP VALUE 0.
Procedure Division.
accept parm1.
EXEC SQL CONNECT TO SJ2SMPL END-EXEC.
EXEC SQL CALL :prog-name (:PARM1,:PARM2) END-EXEC.
.
.
.

8.2.3.2 Passing Parameters with an SQLDA: Here is an example of a COBOL program using
an SQL CALL statement with an SQLDA to pass parameters:
Identification Division.
Program-ID. ″TS2BMCB2″ .
Data Division.
Working-Storage Section.
EXEC SQL INCLUDE SQLCA END-EXEC.
01 PROG PIC X(10) VALUE ″TS0BMS″ .
01 IO-SQLDA.
05 IO-SQLDAID PIC X(8) VALUE ″SQLDA ″ .
05 IO-SQLDABC PIC S9(9) COMP.
05 IO-SQLN PIC S9(4) COMP.
05 IO-SQLD PIC S9(4) COMP.
05 IO-SQLVAR-ENTRIES OCCURS 0 TO 1489 TIMES
DEPENDING ON IO-SQLD.
10 IO-SQLVAR.
15 IO-SQLTYPE PIC S9(4) COMP.
15 IO-SQLLEN PIC S9(4) COMP.
15 IO-SQLDATA USAGE IS POINTER.
15 IO-SQLIND USAGE IS POINTER.
15 IO-SQLNAME.
20 IO-SQLNAMEL PIC S9(4) COMP.
20 IO-SQLNAMEC PIC X(30).
Linkage Section.
01 PARM-STRUCT.

122 Getting Started with DB2 Stored Procedures


05 PARM1 PIC X(10).
05 PARM2 PIC S9(9) COMP.
05 INDVAR1 PIC S9(4) COMP.
05 INDVAR2 PIC S9(4) COMP.
Procedure Division using parm-struct.
ACCEPT PARM1.
move 0 to indvar1.
move 0 to indvar2.
* Initialize SQLDA
move 2 to io-sqln.
move 2 to io-sqld.
move 104 to io-sqldabc.
*
move 452 to io-sqltype(1).
set io-sqldata(1) to address of parm1.
set io-sqlind(1) to address of indvar1.
move 10 to io-sqllen(1).
*
move 496 to io-sqltype(2).
set io-sqldata(2) to address of parm2.
set io-sqlind(2) to address of indvar2.
move 4 to io-sqllen(2).
* Call stored procedure using SQLDA
EXEC SQL CONNECT TO CENTDB2 END-EXEC.
EXEC SQL CALL :PROG
USING DESCRIPTOR :IO-SQLDA end-exec.
.
.
.

8.3 SQL CALL Statement in DB2 on the Workstation

DB2 on the workstation provides two syntax specifications for the SQL CALL statement to support
different coding techniques. One specification is for embedded SQL and REXX applications, and one is
for DB2 CLI and ODBC applications. See 8.3.1, “Embedded SQL Applications” and 8.4, “CLI and ODBC
Applications” on page 127 for a description of the syntax of the two specifications of the SQL CALL
statement.

Even though it is possible to invoke stored procedures in DB2 on the workstation by using the DARI
SQLeproc function call, we focus on using the SQL CALL statement as a common way of invoking
stored procedures in DB2 on the workstation. See 8.3.4, “Invoking Stored Procedures with DARI” on
page 127 for further explanation of the SQLeproc function call.

8.3.1 Embedded SQL Applications


Figure 75 shows the syntax of the SQL CALL statement used in embedded SQL applications.

Figure 75. The SQL CALL Statement for Embedded SQL

Chapter 8. Coding Client Applications 123


The call statement allows a client application to pass data to and receive data from a stored
procedure.

In the sections that follow, we explain the parameters associated with the SQL CALL statement.

8.3.1.1 Specifying the Stored Procedure Name: The procedure name can be specified
through a constant, represented as procedure name in Figure 75 on page 123, or within a host
variable .

Using Procedure Name: The name of the stored procedure is passed as a constant, which cannot
contain blanks or special characters.

Using a Host Variable: The name of the stored procedure is passed through a host variable, which
must be a character-string variable with a length attribute that is not greater than 254 bytes, and it
must not include an indicator variable. The actual value of the host variable can include special
characters.

The procedure name can take one of several forms, as explained in 8.5, “Stored Procedure Name
Considerations” on page 128. These forms may include special characters, which can be specified
only by using a host variable.

8.3.1.2 Specifying the Arguments: Embedded SQL applications have two options for passing
parameters to a stored procedure. They can use host variables (constants or the NULL specification
are not valid arguments) or explicitly use the SQLDA by specifying the USING DESCRIPTOR clause.

(host variable,,,): Each specification of a host variable is a parameter of the CALL statement, where
the nth parameter of the CALL corresponds to the nth parameter of the server′s stored procedure.

Each host variable is assumed to be used for exchanging data in both directions between the client
and the server, that is, each host variable is considered to be used for input and for output.

To avoid sending unnecessary data between the client and the server, the client application should
provide an indicator variable with each parameter and set the indicator to -1 if the parameter is not
used to transmit data to the stored procedure.

The stored procedure should set the indicator variable to -128 for any parameter that is not used to
return data to the client application.

If the server is a DB2 on the workstation, the parameters can have compatible data types in both the
client and server program, although we strongly recommend using matching data types in both
programs.

Both the DB2 on MVS and DB2 for OS/400 servers support conversion between compatible data types
when their stored procedures are invoked by any client. For example, if the client program uses the
INTEGER data type and the stored procedure expects FLOAT, the server converts the INTEGER value to
FLOAT before invoking the procedure.

USING DESCRIPTOR descriptor-name: Identifies an SQLDA that must contain a valid description of
host variables. The nth SQLVAR element corresponds to the nth parameter of the server′s stored
procedure.

Before the SQL CALL statement is processed, the application must set the following fields in the
SQLDA:
• SQLN to indicate the number of SQLVAR occurrences provided in the SQLDA
• SQLDABC to indicate the number of bytes of storage allocated for the SQLDA

124 Getting Started with DB2 Stored Procedures


• SQLD to indicate the number of variables used in the SQLDA when processing the statement
• SQLVAR occurrences to indicate the attributes of the variables. The following fields of each base
SQLVAR element passed must be initialized:
− SQLTYPE
− SQLLEN
− SQLDATA
− SQLIND
The following fields of each secondary SQLVAR element passed must be initialized:
− LEN.SQLLONGLEN
− SQLDATALEN
− SQLDATATYPE_NAME

As with host variables, the SQLDA is assumed to be used for exchanging data in both directions
between the client and the server. To avoid sending unnecessary data between the client and the
server, the client application should set the SQLIND field to − 1 if the parameter is not used to transmit
data to the stored procedure. The stored procedure should set the SQLIND field − 128 for any
parameter that is not used to return data to the client application.

In 8.3.2, “Examples of Coding the CALL Statement” we provide examples of how to code the CALL
statement to send parameters by using host variables or by explicitly using the SQLDA structure.

8.3.2 Examples of Coding the CALL Statement


Host variables are always passed to DB2 on the workstation stored procedures through an SQLDA
data structure generated by the database manager when the SQL CALL statement is executed. The
stored procedure always receives an SQLDA, regardless of whether you use an SQLDA or specify host
variables in the SQL CALL statement.

We show two examples of coding the SQL CALL statement.

8.3.2.1 Passing Parameters with Host Variables: Here is an example of a REXX OS/2 SQL
CALL statement using host variables:
procname = ′ SM0PMS′
dataitem.1 = ′ -DISPLAY THREAD(*)′
dataitem.2 = 0
dataitem.3 = 0
dataitem.4 = 0
dataitem.5 = substr(′ ′ , 1 , 8 3 2 0 , ′ ′ )
dataitem.5.ind = 0

call SQLEXEC ′ CALL :procname (′ ,


′ : dataitem.1,′ ,
′ : dataitem.2,′ ,
′ : dataitem.3,′ ,
′ : dataitem.4,′ ,
′ : dataitem.5 :dataitem.5.ind)′

8.3.2.2 Passing Parameters with SQLDA: Here is an example of a REXX OS/2 SQL CALL
statement using SQLDA to pass the parameters:

Chapter 8. Coding Client Applications 125


procname = ′ SM0PMS′
dataitem.1 = ′ -DISPLAY THREAD(*)′
dataitem.1.ind = 0
dataitem.2 = 0
dataitem.2.ind = 0
dataitem.3 = 0
dataitem.3.ind = 0
dataitem.4 = 0
dataitem.4.ind = 0
dataitem.5 = substr(′ ′ , 1 , 8 3 2 0 , ′ ′ )
dataitem.5.ind = 0

io_sqlda.sqld = 5

io_sqlda.1.sqltype = 453
io_sqlda.1.sqldata = dataitem.1
io_sqlda.1.sqllen = 20
io_sqlda.1.sqlind = dataitem.1.ind

io_sqlda.2.sqltype = 497
io_sqlda.2.sqldata = dataitem.2
io_sqlda.2.sqllen = 20
io_sqlda.2.sqlind = dataitem.2.ind

io_sqlda.3.sqltype = 497
io_sqlda.3.sqldata = dataitem.3
io_sqlda.3.sqllen = 20
io_sqlda.3.sqlind = dataitem.3.ind

io_sqlda.4.sqltype = 497
io_sqlda.4.sqldata = dataitem.4
io_sqlda.4.sqllen = 20
io_sqlda.4.sqlind = dataitem.4.ind

io_sqlda.5.sqltype = 453
io_sqlda.5.sqldata = dataitem.5
io_sqlda.5.sqllen = 8320
io_sqlda.5.sqlind = dataitem.5.ind

call SQLEXEC ′ CALL :procname USING DESCRIPTOR :io_sqlda′

8.3.3 Searching for Stored Procedures in DB2 on the Workstation


If you do not use the absolute-path!function-name to invoke a stored procedure, the stored procedure
is searched for through your server directories in the following way:

For DB2 for OS/2 servers, the stored procedure is searched for in the directories specified by the
LIBPATH environment variable of the CONFIG.SYS file. If you are invoking a stored procedure locally,
it is searched for first in the current directory. If not found in the current directory, it is searched for in
the directories specified in the LIBPATH environment variable.

For DB2 for AIX servers, fenced stored procedures are searched for in the sqllib/function directory, and
unfenced stored procedures are searched in the sqllib/function/unfenced directory.

126 Getting Started with DB2 Stored Procedures


8.3.4 Invoking Stored Procedures with DARI
The DARI API offers another way of invoking stored procedures, because the stored procedure
supports the SQLeproc() parameter convention in addition to the SQL CALL statement. Figure 76 on
page 127 shows the differences between the SQL CALL statement and the SQLeproc() statement.

Figure 76. SQLeproc() and the SQL CALL Statement

New client applications should be written using the SQL CALL statement to invoke stored procedures,
as applications using DARI can access stored procedures only on DB2 on the workstation. Other
DRDA database servers cannot be accessed by using DARI as DARI is not portable to other platforms.
DARI is not a part of System Application Architecture (SAA), and the DARI API is primarily kept for
backward compatibility with older applications.

8.4 CLI and ODBC Applications


You can call a stored procedure from a CLI or ODBC application running in DB2 on the workstation
platform or DB2 for OS/390 Version 5.

Figure 77 shows the syntax of the SQL CALL statement used in CLI and ODBC applications. This
syntax is applicable to DB2 Common Server V2, DB2 Universal Database V5 and DB2 for OS/390 V5.

Figure 77. CALL Statement Syntax Used in CLI and ODBC

The name of the stored procedure is passed as a constant. The constant can contain special
characters to support the different forms adopted by the stored procedure name, as explained in 8.5,
“Stored Procedure Name Considerations” on page 128.

The question mark represents a parameter marker. Each question mark in an SQL CALL statement
denotes an argument to be passed to the stored procedure. The parameter markers in the SQL CALL
statement are bound to application variables by means of the SQLBindParameter function. If you have
parameters that are input only or output only, specifying the type of parameter in an
SQLBindParameter() call (SQL_PARAM_INPUT and SQL_PARAM_OUTPUT) can avoid unnecessary
data transfer. See 10.3.7, “Calling the Stored Procedure” on page 196 for a description of this function.

Chapter 8. Coding Client Applications 127


Literals are supported only with an escape clause specification. Note that the stored procedure name
cannot be a literal. Only the arguments can be literals and you use the ODBC call syntax (that is, curly
braces {}) in order to get this support. Also, all types of literals are supported including numbers and
character strings along with any mismatch of parameter markers. For example,
{call sp(′ arg1′ , ? , 3 . 1 4 1 5 , ′ arg4′ , ? , ? ) }
is supported where the application bind uses SQLBindParameter 3 arguments but the stored procedure
gets the arguments passed in the correct order, which is the argument list of the stored procedure.

There are two ways to pass the CALL statement to CLI:


SQLExecDirect()

SQLPrepare()
SQLExecute()
Although the CALL statement itself cannot be prepared dynamically, DB2 CLI accepts the CALL
statement as if it could be dynamically prepared.

8.5 Stored Procedure Name Considerations

The procedure name can take one of several forms. The forms supported vary according to the server
where the procedure is stored.

8.5.1 DB2 on the Workstation


If the stored procedure is in DB2 on the workstation, it is supported by:
• Procedure-name
The name (with no extension) of the procedure to execute. Procedure-name is used both as the
name of the stored procedure library and the function name within that library. For example, if
procedure-name is proclib, the DB2 server loads the stored procedure proclib library and executes
the proclib() function routine within that library.
See 8.3.3, “Searching for Stored Procedures in DB2 on the Workstation” on page 126 for detailed
information about searching stored procedures.
• Procedure-library!function-name
The exclamation character (!) acts as a delimiter between the library name and the function name
of the stored procedure. For example, if proclib!func is specified, proclib is loaded into memory
and the func function from that library is executed. Thus multiple functions can be placed in the
same stored procedure library.
See 8.3.3, “Searching for Stored Procedures in DB2 on the Workstation” on page 126 for detailed
information about searching stored procedures.
• Absolute-path!function-name
The absolute-path specifies the complete path to the stored procedure library. In a UNIX-based
system, for example, if /u/terry/proclib!func is specified, the stored procedure proclib library is
obtained from the /u/terry directory and the func function from that library is executed. In OS/2, if
d:\terry\proclib!func is specified, the database manager loads the func.dll file from the
d:\terry\proclib directory.
In all cases, the total length of the procedure name including its implicit or explicit full path must not
be longer than 254 bytes.

128 Getting Started with DB2 Stored Procedures


Note: To invoke REXX stored procedures you must consider the following:
• Use the stored procedure name plus extension .cmd.
• The name of a REXX stored procedure can be provided only through a host variable.
• If using the absolute-path!function-name option, function-name is the REXX stored procedure name
plus extension .cmd.

8.5.2 DB2 on MVS


The procedure-name can be an implicit or explicit three part-name, consisting of the following parts:
location.middle.procedure-name
• location - The location of the server where the procedure is stored. This value is optional. If
location is not specified, the location name of the current connection is the default.
• middle - For the current releases of DB2 on MVS, the only acceptable value is SYSPROC. The
SYSPROC value is provided for compatibility with eventual support for a SET PATH statement,
where you can specify a search order for SCHEMA names used in UDFs. The specification of a
value for this part is optional.
• procedure-name - The name of a stored procedure. This value is compulsory and must match a
value of the PROCEDURE column of the SYSIBM.SYSPROCEDURES table.

Note that even if you specify the location in the procedure name, you must issue a connect to that
location before the SQL CALL statement. In the current DB2 implementation of DRDA, system-directed
access is not supported.

8.5.3 DB2 for OS/400 Server (V3.1 or Later)


The external program name is assumed to be the same as the procedure-name.

For portability, procedure-name should be specified as a single token no longer than 8 bytes.

8.6 Case Sensitivity and Stored Procedure Name Folding

There are some considerations regarding the use of lowercase and uppercase for the name of a stored
procedure in a CALL statement. These considerations depend on the platform where the stored
procedure is located and the fact that the CALL statement may fold the name of the stored procedure if
provided as a constant.

8.6.1 Case Sensitivity by Platform


It is possible to have lowercase procedure names in SYSPROCEDURES.

Table 8. How DB2 for MVS V4 and DB2 for OS/390 V5 Treat Lowercase Names
Call Method Behavior
C A L L < l i t e r a l > w h e r e < l i t e r a l > i s d e l i m i t e d ( ″″) Can find the lowercase procedure names.
CALL <literal> where <literal> is not delimited Causes <literal> to be folded to uppercase.
and has lowercase characters
CALL :hv where :hv is a host variable whose value is Fails with SQLCODE -113.
in lowercase

For CLI (DB2 for OS/390 V5) this implies that the stored procedure name on OS/390 must be in
uppercase. In practice we tend to stick to using uppercase for stored procedure on MVS and OS/390.

Chapter 8. Coding Client Applications 129


For DB2 for AIX both the name of the stored procedure function and the name of the library where the
function is located are case sensitive.

If you are using the same name for both the library and the function, but the library name is in
uppercase, you have to explicitly specify the name of the library and the function in the SQL CALL
statement.

For example, if the name of the function is proc1 and the name of the library is PROC1, the name of the
stored procedure, as used in the SQL CALL statement should look like this: PROC1!proc1.

In DB2 for OS/2 the name of the stored procedure function is case sensitive if it was exported in
lowercase. If the function was exported in uppercase, both lowercase and uppercase can be used to
invoke the stored procedure.

8.6.2 Stored Procedure Name Folding


There are two ways of providing the stored procedure name in the SQL CALL statement: through a
host variable or through a constant. The stored procedure name can be specified in lowercase or
uppercase, and, when you specify it through a host variable, the stored procedure name is sent without
conversion. When you specify it using an undelimited constant, the stored procedure name is
converted to uppercase as shown in Table 9.

Table 9. Stored Procedure Name Folding


Client Platform DB2 on MVS Stored Procedure DB2 on the workstation Stored
Procedure
DB2 on MVS Name is folded to uppercase Name is folded to uppercase
DB2 on the workstation Name is folded to uppercase Name is not folded to uppercase

Note that DB2 on MVS does not do any name folding if you pass an SQL delimited identifier. If, for
example, you code:
CALL ″my_proc″ ( : hv);
the procedure name my_proc is not folded to uppercase.

8.7 Client Program Preparation

The program preparation requirements for a client application that invokes a stored procedure are
identical to those of other DB2 applications. Therefore, besides compiling and linking, you must
precompile and create a package for your client application. The package for the client application
must be bound to the database server location where the stored procedure executes.

As with other DB2 applications, if the client application accesses more than one database server, the
package must be bound to every database server being accessed.

The program preparation process applies to client applications written in a compiled host language
such as COBOL, C, or PL/I and is valid for both DB2 on the workstation and DB2 on MVS.

In the DB2 on the workstation environment, the SQL CALL statement can be used in languages such
as REXX and SQL interfaces such as CLI and ODBC, which generally do not support static SQL. This
is possible because REXX, CLI, and ODBC recognize the SQL CALL, implement it as static, but give it
an appearance of dynamic SQL as explained in 8.1, “Calling Stored Procedures” on page 117. REXX,
CLI, and ODBC packages are bound when you create the DB2 on the workstation database or when

130 Getting Started with DB2 Stored Procedures


you bind the DDCSMVS.LST to the DRDA host DB2 on MVS location. Applications using REXX, ODBC,
and CLI are not compiled, so a specific package for these applications is not required.

8.7.1 DB2 on MVS


You must prepare the client program in the same way you prepare DB2 for MVS/ESA programs. Here
is a sample JCL for preparing a client program for DB2 Version 4:
//STDRD2AB JOB (999,POK),NOTIFY=&SYSUID,
// CLASS=A,MSGCLASS=T,MSGLEVEL=(1,1),TIME=1440
//PREPARE EXEC DSNHCOB2,MEM=TS0BMCBM,
// PARM.PC=(′ HOST(COB2)′ , QUOTE,APOSTSQL,SOURCE,XREF)
//PC.SYSIN DD DSN=STDRD2A.LIB.SOURCE(TS0BMCBM),
// DISP=SHR
//LKED.SYSLMOD DD DSN=DSN410.RUNLIB.LOAD(TS0BMCBM),
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNELI)
MODE AMODE(31) RMODE(ANY)
//BIND EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//DBRMLIB DD DSN=DSN410.DBRMLIB.DATA,DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DB41)

BIND PACKAGE(SJ2SMPL.TS0BMCBM) MEMBER(TS0BMCBM) -


LIBRARY(′ DSN410.DBRMLIB.DATA′ ) -
ACT(REP) ISOLATION(CS) VALIDATE(BIND)

BIND PLAN(TS0BMCBM) PKLIST(SJ2SMPL.TS0BMCBM.TS0BMCBM) -


ACT(REP) ISOLATION(CS) VALIDATE(BIND)

END
//

Client programs do not have to use LE/370 libraries, and they can be written in any language DB2 on
MVS supports.

8.7.1.1 Package and Plan: To call a stored procedure, the client program must have a package
on the DB2 system where the stored procedure executes. As seen in the preparation JCL sample, you
can use the remote bind capability of DRDA to bind the package on the remote system. You only have
to specify the location name in your bind command. In our example, SJ2SMPL is the location name of
the remote system.

The client program must have a plan. The plan resides only on the client system and must include the
remote package for the client program. When the client program and the stored procedure execute in
different DB2 locations, the plan for the client program does not have to include the stored procedure
package.

When the client program executes at the same location as the stored procedure, the plan for the client
program must also include the stored procedure′s package and all the packages associated with the
stored procedure. For example, if the stored procedure calls another program that also accesses DB2
tables, the called program has a separate package, and that package must also be included in the
client program plan.

Chapter 8. Coding Client Applications 131


8.7.1.2 Authorization: Refer to 6.3.3, “Privileges Required” on page 101 for the privileges
required to execute a DB2 on MVS client program containing a call to a stored procedure.

8.7.2 DB2 on the Workstation


DB2 on the workstation provide four options for coding an application:
• Embedded SQL in host programming languages
• Programs using the REXX interpreter
• CLI and ODBC
• IBM VisualGen and IBM VisualAge for Basic

You can develop client applications using any of the above techniques. The program preparation
process differs among the techniques.

8.7.2.1 Embedded SQL in Host Programming Languages: Embedded SQL applications


must be precompiled, compiled, linked, and bound to a database server.

The precompilation step is performed to change the SQL statements into language recognized by the
host language compiler. The development environment of DB2 on the workstation provides
precompilers for the following host languages: C, C++, COBOL, and FORTRAN.

Compilation and link steps are performed to create an executable file for your application. This
executable file contains the appropriate links to enable your application to interface with the host
language APIs and with the database manager APIs required for your operating environment.

The binding step is performed to create an executable control structure called package required to run
the SQL statements in your program. The package is bound to the database where the SQL
statements will be executed. A connection to one of the databases that the application uses is
required to execute this step.

8.7.2.2 Programs Using the REXX Interpreter: REXX is an interpretive language. It uses the
following two APIS:
SQLEXEC This API supports the SQL language.
SQLDBS This API supports DB2 commands.
SQL statements in a REXX application are processed by a dynamic SQL handler; therefore, a REXX
application does not require precompilation. No program preparation process is required for a REXX
application.

8.7.2.3 CLI and ODBC: CLI is a C or a C + + API for relational database access that uses
function calls to pass dynamic SQL statements as arguments.

CLI does not require host variables or a precompiler, so program preparation requires only compiling
and linking as with a regular C or C++ program.

CLI is based on the Microsoft ODBC and X/Open specifications. DB2 Common Server V2 supports all
core and level 1 functions of ODBC. Currently, it supports all level 2 functions of ODBC with the
exception of SQLBrowseConnect(), SQLDescribeParam(), and SQLSetPos().

DB2 Universal Database V5 supports the majority of ODBC 3.0 functions. Refer to DB2 UDB V5 Call
Level Interface Guide and Reference for a detailed list and description.

132 Getting Started with DB2 Stored Procedures


From an application coding point of view, the CLI and ODBC are equivalent. CLI functions are linked
together with the application. ODBC functions are not linked with the application but use a DLL during
execution. The ODBC component of DB2 on the workstation enables applications coded according to
the ODBC specification to access IBM DB2 database servers. The IBM ODBC driver is functionally
equivalent to the ODBC-specific portions of CLI.

Figure 78 illustrates the relationship between the IBM ODBC driver and the ODBC Driver Manager and
compares DB2 CLI and the IBM ODBC driver.

Figure 78. DB2 CLI and ODBC

To develop ODBC applications that access DB2 database servers, you must have the IBM ODBC driver
and an ODBC Software Development Kit. ODBC applications pass dynamic SQL as function arguments,
so they do not have to be precompiled.

8.7.2.4 Precompiled and Nonprecompiled Applications: Not all applications developed in


the DB2 on the workstation environment require a package to execute. Therefore, you may have a
situation where both the client application and the stored procedure do not use packages. Use
Table 10 on page 134 as a reference for defining which packages must be bound. The development
choices used to create both the client and the stored procedure applications determine whether a
package must be bound.

Chapter 8. Coding Client Applications 133


Table 10. Package Creation Requirements
Client Application Stored Procedure - Compiled Stored Procedure - REXX, CLI (2)
Host Languages (1)
Compiled host language Package for both applications: the Package only for the client
client and the stored procedure application
REXX, CLI, ODBC (3) Package only for the stored No packages
procedure application
Note:
(1) Stored procedures on the following platforms: DB2 on MVS, DB2 for OS/2, and DB2 for AIX
(2) DB2 for OS/2 and DB2 for AIX (DB2 for AIX does not support stored procedures written in REXX).
(3) AIX clients do not support ODBC.

8.7.2.5 Authorizations: The authorization issues covered in this section are related to the
privileges required by an authorization ID to run a stored procedure.

Executing a stored procedure implies running a client application, which in turn invokes the stored
procedure application. When the client program runs on DB2 on the workstation, privileges to execute
the packages of both the stored procedure application and the client application are required.

If the SQL CALL statement is the only SQL statement in the client application, you are not required to
have the execute privilege on the client package; you need the execute privilege only on the stored
procedure package. However, it is possible that neither your client application nor your stored
procedure requires a package to run. Therefore, the user running the application must have the
privileges needed to issue each SQL request.

If the stored procedure application contains dynamic SQL, the authorization rules depend on the
database server. For DB2 on the workstation and DB2 on MVS, the authorization ID of the user
running the client application must be granted the required privileges on the objects specified in each
dynamic SQL statement. For DB2 on MVS, if you bind the stored procedure with the
DYNAMICRULES(BIND) option, the authorization ID of the user who bound the stored procedure is
checked against the dynamic SQL statement executed by the stored procedure.

8.8 IBM VisualGen and VisualAge for Basic

VisualGen is an application generator that provides you with a graphic interface to interactively
develop and test applications. VisualGen can generate C applications for the AIX environment or
COBOL applications for the MVS and OS/2 environment.

The interactive test facility of VisualGen is a useful debugging tool that dynamically prepares the SQL
statements embedded in the body of your application.

You can use VisualGen to generate client applications on the OS/2, AIX, and MVS platforms.

You can develop client applications with VisualGen, but you cannot test them with the VisualGen
interactive test facility because the SQL CALL statement cannot be dynamically prepared.
Nevertheless the advantage of developing one application and being able to port it to three different
platforms should not be ignored.

You can generate stored procedures for DB2 on MVS, using VisualGen. You cannot generate DB2 on
the workstation stored procedures through VisualGen because VisualGen-generated code does not use
the SQLDA to receive parameters. A development tool called IBM VisualAge for Basic enables you to
build, run, debug, test, register, and distribute stored procedures for the DB2 for AIX and DB2 for OS/2

134 Getting Started with DB2 Stored Procedures


platforms. Refer to Chapter 16, “IBM VisualAge for Basic” on page 331 for more information about
using VisualAge for Basic.

8.9 Invoking Stored Procedures with ODBC Escape Clause

An escape clause is a syntactic mechanism for implementing vendor-specific SQL extensions in the
framework of standardized SQL. Both DB2 CLI and ODBC support vendor escape clauses as defined by
X/Open. For details please refer to the Call Level Interface Guide and Reference for Common Servers .

Chapter 8. Coding Client Applications 135


136 Getting Started with DB2 Stored Procedures
Chapter 9. Transferring Multiple Result Sets with Stored Procedures

Whenever a client program invokes a stored procedure, the stored procedure can return the results
through host variables (DB2 for MVS/ESA and DB2 for OS/390) or information in the SQLDA (DB2 UDB,
DB2 Common Servers, DB2 for MVS/ESA, and DB2 for OS/390). If you use a cursor in the stored
procedure, the result of the FETCH statement, which is one row, can be passed back to the client
program. If the client program requires more than one row to be returned, you can use one of two
methods to transfer the rows by blocking them or using the support available for multiple result sets
(MRSP).

Note that MRSP is not available for DB2 for MVS/ESA, and is not supported by DDCS. MRSP is
supported by:
• DB2 Common Servers if DRDA is not being used
• DB2 for OS/390
• DB2 Connect
If you are using DB2 CLI as the interface for your client in the workstatsion, or if you are using DB2 for
OS/390, use MRSP. Using MRSP functions enables you to use stored procedures to return one or
more result sets in a simpler way. For the client workstation environment, you can also have a client
application that uses mostly embedded SQL, except for the SQL CALL statement and the SQL FETCH,
which are coded in DB2 CLI. In the next sections we illustrate both methods with some examples.

9.1 DB2 CLI/ODBC for DB2 on the Workstation

If you code the client program with CLI or ODBC, DB2 on the workstation can return result sets directly
to the client program (see Figure 79).

Figure 79. Multiple Result Sets with CLI. Renamed client to MR3C2CC2 / server MR3C2S

To transfer one or more result sets to a client application, the following requirements must be met:

 Copyright IBM Corp. 1996 1998 137


• The client application must be written using DB2 CLI, or at least the part of the application that
issues the SQL CALL and obtains the results.
• The stored procedure indicates that a result set is to be returned by declaring a cursor on the
result set, opening a cursor on the result set (triggers the execution of the query), and leaving the
cursor open when exiting the stored procedure.
• For every cursor that is left open, a result set is returned to the application.
• If more than one cursor is left open, the result sets are returned in the order in which their cursors
were opened in the stored procedure. You obtain the result set for the next cursor by invoking the
SQLMoreResults function.
• Only unread rows are passed back to the client application. For example, if the result set of a
cursor has 300 rows, and the stored procedure fetches 100 of those rows, then at the time the
stored procedure terminates, rows 101 through 300 will be returned to the client application. You
can use this technique if the client program requires only the last rows of the result set. We
explain this aspect of DB2 for completeness, but we don′t think you will have any reason to exploit
this feature. In most applications, you will not want to fetch any of the rows prior to returning the
result set to the stored procedure caller.
• The stored procedure must run in fenced mode. If the stored procedure runs in unfenced mode, no
result sets are returned, and no error message is generated.
• The stored procedure must run on a remote server. Thus a network or named pipe connection
must be used for the communication between the client program and the stored procedure. To
implement MRSP on a single machine, it is possible to set up a “loopback” connection to a server
on the same machine, as explained in 9.1.2, “Setting Up a Loopback Connection” on page 149.
• An SQLFreeStmt() call issued by the client program with either SQL_DROP or SQL_CLOSE closes
the cursor for the current result set and flushes the rows. Note that this is also the case for all
other cursors associated with other result sets generated by this same stored procedure call.
The DDCS for OS/2 and DDCS for AIX do not support MRSP. If you need to access result sets from
DB2 on MVS you must use DB2 Connect and DB2 for OS/390.

For additional information refer to the Application Programming Guide for Common Servers and the
Call Level Interface Guide and Reference for Common Servers .

9.1.1 Examples Using CLI


The following examples illustrating MRSP come with SDK for Common Servers Version 2.1.1. You can
find them in the sqllib\samples\cli subdirectory (sqllib/samples/cli for the AIX platform) and the
documentation in the README file of that subdirectory.
************************************************************************
* New examples for Version 2.1.1
************************************************************************
mrspsrv.c - Modified version of outsrv2.c
- A stored procedure that returns a multi-row result set.
- mrspsrv.c must be built on the server.
- Uses CLI

mrspsrv2.sqc - Modified version of mrspsrv.c


- A stored procedure that returns a multi-row result set,
using embedded SQL.
- mrspsrv2.sqc must be built on the server.

mrspcli.c - Modified version of outcli.c


- Calls mrspsrv and displays the returned result set.
- Requires mrspsrv.c to be built on the server.

138 Getting Started with DB2 Stored Procedures


mrspcli2.c - Example mrspcli.c modified to call mrspsrv2.c on the
server.
- Calls mrspsrv2 library and displays the returned
result set.
- Requires mrspsrv2.sqc to be built on the server.

mrspcli3.sqc - This is an example of mixing embedded SQL and CLI.


This embeded SQL program calls the CLI program
clicall.c on the client which in turn calls
mrspsrv2.sqc on the server.
- Requires mrspsrv2.sqc to be built on the server.
- Note: mrspcli3.sqc is NOT built in the makefile
using the ALL command. To build this example
you must copy util.c and util.h from the .../SAMPLES/C
subdirectory. Once this is done you can make mrspcli3.

clicall.c - Defines a CLI function which is used in the embedded


SQL sample mrspcli3.sqc. This function calls
mrspsrv2.sqc on the server.

9.1.1.1 Retrieving One Result Set: This example illustrates how to code a stored procedure
with MRSP. The client program reads an SQL statement from the terminal and passes it to be
executed by the stored procedure. The stored procedure opens a cursor for the received SELECT
statement and ends, returning control to the client program. The client issues a FETCH statement for
each resulting row and displays it on the screen. The flow is displayed in Figure 80.

Figure 80. Retrieving One Result Set with CLI

We analyze this process below, dividing it into three parts: the client part, the stored procedure, and
the print_results function with the FETCH processing used by the client program. The client program
(MR3C2CO2.C) must be written with the CLI. The stored procedure (MR3C2S.SQC) is written in C with
embedded dynamic SQL, but it can be written with any supported language.

To execute the example, type:


mr3c2co2 loopsamp userid password

Chapter 9. Transferring Multiple Result Sets with Stored Procedures 139


This program prompts for a SELECT statement, so type an SQL SELECT statement and press Enter:
>Enter Select stmt:
select name, id, salary from userid.staff order by salary desc

The screen displays a connect message, a message indicating that the stored procedure has ended,
and the requested information. The program ends with a disconnect message:
>Connected to loopsamp
Server Procedure Complete.
NAME ID SALARY
Molinare 160 22959.20
Jones 260 21234.00
Fraye 140 21150.00
Graham 310 21000.00
Hanes 50 20659.80
Lu 210 20010.00
Quill 290 19818.00
.....
.....
Gafney 350 13030.50
Naughton 120 12954.75
Ngan 110 12508.20
Kermisch 170 12258.50
Abrahams 180 12009.75
Scoutten 200 11508.60
Burke 330 10988.00
Yamaguchi 130 10505.90
Disconnecting .....

9.1.1.2 Client Program MR3C2CO2.C: After initializing and declaring the variables, the
program obtains the server name, user ID, and password from the arguments entered when invoking
the program. The program uses the INIT_UID_PWD macro defined in the samputil.h header file of the
samples\cli directory. Next, the program prompts the user for a SELECT statement and stores it in a
variable called string :
....
....
int
main( int argc, char * argv[] )
{
SQLHENV henv;
SQLHDBC hdbc;
SQLRETURN rc;
SQLHSTMT hstmt;
SQLCHAR stmt[] = ″CALL mr3c2s( ? )″ ;

/* Declare String variable */


SQLCHAR string[254]; /* Will contain the sqlstring */
SQLINTEGER stringind = 0; /* Indicator variable for string */

/* macro to initalize server, uid and pwd */


INIT_UID_PWD;

/* Get the SQL statement */


printf(″>Enter Select stmt:\n″ ) ; gets((char *) string);
....
....

140 Getting Started with DB2 Stored Procedures


The SQLAllocEnv statement allocates an environment handle and associated resources. Each
application can have only one environment handle active at a time. This statement must precede all
other DB2 CLI statements.

The program then calls the DBconnect function coded in samputil.c, grouping together the statements
required for the connection. The DBconnect function issues:
1. SQLAllocConnect: Allocates a connection handle and associated resources within the environment
identified by the previously allocated environment handle.
2. SQLSetConnectOption: Enables you to set a range of connection attributes for a particular
connection. In the DBconnect function only one option is used; the default, AUTOCOMMIT, is set to
OFF. Refer to Chapter 5, “Functions,” of the Call Level Interface Guide and Reference for Common
Servers for a detailed description of the different options.
3. SQLConnect: The program establishes a connection to the target database with the supplied user
ID and password.

After the DBconnect, an SQLAllocStmt call is issued. This call allocates a statement handle and
associates it with the connection specified by the connection handle. DB2 CLI uses each statement
handle to relate SQL statements to the current database connection (referred by hdbc). There is no
defined limit on the number of statement handles active at any one time.

To summarize these steps:


1. The program allocates an environment handle.
2. It allocates a connection handle for the environment handle and connect.
3. It allocates a statement handle for the connection handle.
....
....
rc = SQLAllocEnv(&henv);
if (rc == SQL_ERROR)
return (terminate(henv, rc));

/* Connect to Remote Database */


rc = DBconnect(henv, &hdbc);
if (rc == SQL_ERROR)
return (terminate(henv, rc));

rc = SQLAllocStmt(hdbc, &hstmt);
CHECK_DBC(hdbc, rc);
....
....

SQLPrepare associates the SQL CALL statement in the stmt variable with the previously allocated
statement handle, hstmt, and sends it to the database management system to be prepared.

Next, we associate the parameter marker “?” in our SQL CALL statement
stmt[ ] = ″CALL mr3c2s( ? )″ ,
with the application variable “string,” using the SQLBindParameter function. SQLExecute executes the
prepared statement and calls the MR3C2S stored procedure, transferring the SELECT statement to the
server:

Chapter 9. Transferring Multiple Result Sets with Stored Procedures 141


....
....
/* Prepare the call statement */
rc = SQLPrepare(hstmt, stmt, SQL_NTS);
CHECK_STMT(hstmt, rc);

/* Bind the parameter to application variables */


rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,
254, 0, &string, 255, NULL);
CHECK_STMT(hstmt, rc);

SQLExecute(hstmt);
/* Ignore Warnings */
if (rc != SQL_SUCCESS & rc != SQL_SUCCESS_WITH_INFO)
CHECK_STMT(hstmt, rc);
....
....

When the stored procedure returns control, the client program fetches and displays the result set,
using the print_results function. This function is discussed in 9.1.1.4, “The Print_results Function” on
page 144.

On return from the print_results function, the client program ends by issuing the following DB2 CLI
calls:
1. SQLFreeStmt: Used with the SQL_DROP option, ends the processing on the referenced statement
handle. The SQL_DROP option frees all resources associated with the statement handle,
invalidates the handle, closes an open cursor (if any), and discards pending results.
2. SQLTransact: In our example with SQL_COMMIT as the argument, a commit is issued for the
current transaction in the specified connection.
3. SQLDisconnect: Closes the connection associated with the database connection handle.
4. SQLFreeConnect: Invalidates and frees the connection handle. All DB2 CLI resources associated
with the connection handle are freed.
5. SQLFreeEnv: Invalidates and frees the environment handle. All DB2 CLI resources associated with
this handle are freed:
....
....
/* Display result set */
rc = print_results(hstmt);
CHECK_STMT(hstmt, rc);

rc = SQLFreeStmt(hstmt, SQL_DROP);
CHECK_STMT(hstmt, rc);

rc = SQLTransact(henv, hdbc, SQL_COMMIT);


CHECK_DBC(hdbc, rc);

printf(″Disconnecting .....\n″ ) ;
rc = SQLDisconnect(hdbc);
CHECK_DBC(hdbc, rc);

rc = SQLFreeConnect(hdbc);
CHECK_DBC(hdbc, rc);

rc = SQLFreeEnv(henv);
if (rc != SQL_SUCCESS)

142 Getting Started with DB2 Stored Procedures


terminate(henv, rc);
....
....

9.1.1.3 Stored Procedure MR3C2S.SQC: The stored procedure accepts the SQLDA and
SQLCA structures passed by the client application, and declares the host and other required variables:
....
....
SQL_API_RC SQL_API_FN mr3c2s (
void *reserved1,
void *reserved2,
struct sqlda *inout_sqlda,
struct sqlca *ca) {

/* Declare a local SQLCA */


EXEC SQL INCLUDE SQLCA;

/* Declare Host Variables */


EXEC SQL BEGIN DECLARE SECTION;
char stmt[255];
EXEC SQL END DECLARE SECTION;

/* Declare Miscellaneous Variables */


FILE *stream; /* Added for writing to file Bo.2 */
char my_errmsg[71];
....
....

The stored procedure declares a cursor, C1. The WITH HOLD option is required for MRSP. Next, the
stored procedure copies the SQL SELECT statement, transferred by the client program, from the
SQLDA in the stmt variable. We coded the stored procedure assuming that the structure of the SQLDA
is as the stored procedure expected. In a production application, you should check the structure of the
SQLDA. The statement is prepared and the cursor is opened:
....
....
EXEC SQL DECLARE c1 CURSOR WITH HOLD FOR s1;

/* Copy the SQL statement from the sqlda */


strncpy(stmt, inout_sqlda->sqlvar[0].sqldata,
inout_sqlda->sqlvar[0].sqllen);

/* Prepare the Statement */


EXEC SQL PREPARE s1 FROM :stmt;

/* Open the cursor */


EXEC SQL OPEN c1;
....
....

Basically, this is it. After the OPEN CURSOR, the stored procedure copies the sqlca information into
the SQLCA structure and ends, returning control to the client program:

Chapter 9. Transferring Multiple Result Sets with Stored Procedures 143


....
....
/* Return the SQLCA to the Calling Program */
memcpy( ca, &sqlca, sizeof( struct sqlca ) );

return(SQLZ_DISCONNECT_PROC);
....
....

9.1.1.4 The Print_results Function: When the stored procedure returns, the client calls the
print_results function. This function is coded in the samputil.c file, which contains useful functions used
by most CLI samples. You can find the samputil.c file in the sqllib\samples\cli subdirectory
(sqllib/samples/cli for the AIX platform). We found the print_results function extremely useful when
coding with MRSP.

The print_results function does the following:


1. For each column, gets the column name and binds the column.
2. Displays the column headings.
3. Fetches each row.
4. Converts nulls to character string NULL.
5. Displays rows on the screen.
6. Frees local storage.

In the paragraphs that follow, we analyze the code. First, the program declares the different working
variables. Next, it issues the DB2 CLI SQLNumResultCols statement. This statement returns the
number of columns in the result set associated with the input statement handle in the nresultcols
variable:
print_results(SQLHSTMT hstmt)
{
SQLCHAR colname[32];
SQLSMALLINT coltype;
SQLSMALLINT colnamelen;
SQLSMALLINT nullable;
SQLUINTEGER collen[MAXCOLS];
SQLSMALLINT scale;
SQLINTEGER outlen[MAXCOLS];
SQLCHAR *data[MAXCOLS];
SQLCHAR errmsg[256];
SQLRETURN rc;
SQLSMALLINT nresultcols;
int i;
SQLINTEGER displaysize;

rc = SQLNumResultCols(hstmt, &nresultcols);
CHECK_STMT(hstmt, rc);
....
....

Next, the program starts a loop, going through the different columns. SQLDescribeCol returns the
following information about each column:
• Column name
• Column name length
• Column SQL data type

144 Getting Started with DB2 Stored Procedures


• Column precision
• Nulls allowed indicator

SQLColAttributes is used to get column attributes. In our example it is used with the
SQL_COLUMN_DISPLAY_SIZE argument to retrieve the maximum number of bytes needed to display
the data in character form.
....
....
for (i = 0; i < nresultcols; i++) {
SQLDescribeCol(hstmt, i + 1, colname, sizeof(colname),
&colnamelen, &coltype, &collen[i], &scale, NULL);

/* get display length for column */


SQLColAttributes(hstmt, i + 1, SQL_COLUMN_DISPLAY_SIZE, NULL, 0,
NULL, &displaysize);
....
....

Next, the program displays the column name on the screen, through the printf command, and allocates
memory to bind the column. The column is bound to application variables through the SQLBindCol
statement. This ends the loop for each column:
....
....
/*
* set column length to max of display length, and column name
* length. Plus one byte for null terminator
*/
collen[i] = max(displaysize, strlen((char *) colname)) + 1;

printf(″%-*.*s″ , ( int)collen[i], (int)collen[i], colname);

/* allocate memory to bind column */


data[i] = (SQLCHAR *) malloc((int)collen[i]);

/* bind columns to program vars, converting all types to CHAR */


rc = SQLBindCol(hstmt, i + 1, SQL_C_CHAR, data[i], collen[i],
&outlen[i]);
}
....
....

Now the program can fetch the rows in a “while” loop until it gets the SQL_NO_DATA_FOUND return
code. Note that the SQLFetch function specifies the statement handle related to the SQL CALL
statement.

For each row fetched, the program checks whether there is NULL data. If there is NULL data, the
program prints the character string NULL. If there is data, the program verifies that the length of the
data fits in the previously defined column width. If the data does not fit, it is truncated, and a message
is displayed. If the data fits, it is displayed on the screen through the printf function:
....
....
printf(″\n″ ) ;
/* display result rows */
while ((rc = SQLFetch(hstmt)) != SQL_NO_DATA_FOUND) {
errmsg[0] = ′ \0′ ;
for (i = 0; i < nresultcols; i++) {
/* Check for NULL data */

Chapter 9. Transferring Multiple Result Sets with Stored Procedures 145


if (outlen[i] == SQL_NULL_DATA)
printf(″%-*.*s″ , ( int)collen[i], (int)collen[i], ″NULL″ ) ;
else
{ /* Build a truncation message for any columns truncated */
if (outlen[i] >= collen[i]) {
sprintf((char *) errmsg + strlen((char *) errmsg),
″%d chars truncated, col %d\n″ ,
(int)outlen[i] - collen[i] + 1, i + 1);
}
/* Print column */
printf(″%-*.*s″ , ( int)collen[i], (int)collen[i], data[i]);
}
} /* for all columns in this row */

printf(″\n%s″, errmsg); /* print any truncation messages */


} /* while rows to fetch */
....
....

To end the print_results function, the program frees the data buffers and returns control to the client
application:
....
....
/* free data buffers */
for (i = 0; i < nresultcols; i++) {
free(data[i]);
}

return(SQL_SUCCESS);

} /* end print_results */
....
....

9.1.1.5 Retrieving Multiple Result Sets: This example with DB2 CLI and MRSP retrieves three
result sets. Programs mr4c2co2 and mr4c2s are modifications of the mr3c2co2 and mr3c2s. To invoke
the client program, enter the following:
mr4c2co2 loopsamp userid password
This displays the three result sets in succession on your screen.

Client Program MR4C2CO2.C: In this example, we have three string variables to hold the SQL SELECT
statements. For this application, the user is not prompted to enter the SELECT statements. Instead,
the SELECT statements are hard-coded in the client program:
int
main( int argc, char * argv[] )
{
SQLHENV henv;
SQLHDBC hdbc;
SQLRETURN rc;
SQLHSTMT hstmt;
SQLCHAR stmt[] = ″CALL mr4c2s( ? ? ? )″ ;

/* Declare String variable */


SQLCHAR string1[254]; /* Will contain the sqlstring1 */
SQLINTEGER string1ind = 0; /* Indicator variable for string1 */
SQLCHAR string2[254]; /* Will contain the sqlstring2 */

146 Getting Started with DB2 Stored Procedures


SQLINTEGER string2ind = 0; /* Indicator variable for string2 */
SQLCHAR string3[254]; /* Will contain the sqlstring3 */
SQLINTEGER string3ind = 0; /* Indicator variable for string3 */
short result_set_no = 0;

/* macro to initialize server, uid and pwd */


INIT_UID_PWD;

/* Get the SQL statement */


/* printf(″>Enter Select stmt1 :\n″ ) ; gets((char *) string1); */
/* Get the SQL statement */
/* printf(″>Enter Select stmt2 :\n″ ) ; gets((char *) string2); */
/* Get the SQL statement */
/* printf(″>Enter Select stmt3 :\n″ ) ; gets((char *) string3); */

strcpy( string1, ″SELECT dept FROM STAFF″ ) ;


strcpy( string2, ″SELECT id FROM STAFF″ ) ;
strcpy( string3, ″SELECT * FROM STAFF″ ) ;
....
....

After connecting to the database and binding the parameters, the client program calls the stored
procedure:
....
....
rc = SQLAllocEnv(&henv);
if (rc == SQL_ERROR)
return (terminate(henv, rc));

/* Connect to Remote Database */


rc = DBconnect(henv, &hdbc);
if (rc == SQL_ERROR)
return (terminate(henv, rc));

/* Allocate a statement handle */


rc = SQLAllocStmt(hdbc, &hstmt);
CHECK_DBC(hdbc, rc);

/* Prepare the call statement */


rc = SQLPrepare(hstmt, stmt, SQL_NTS);
CHECK_STMT(hstmt, rc);

/* Bind the parameter to application variables */


rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR,
SQL_CHAR, 254, 0, &string1, 255, NULL);
rc = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR,
SQL_CHAR, 254, 0, &string2, 255, NULL);
rc = SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR,
SQL_CHAR, 254, 0, &string3, 255, NULL);

CHECK_STMT(hstmt, rc);

SQLExecute(hstmt);
/* Ignore Warnings */
if (rc != SQL_SUCCESS & rc != SQL_SUCCESS_WITH_INFO)
CHECK_STMT(hstmt, rc);
....
....

Chapter 9. Transferring Multiple Result Sets with Stored Procedures 147


When the stored procedure returns control to the client program, the client program fetches and
displays the results from a result set until the SQLFetch function call returns SQL_NO_DATA_FOUND,
indicating that there are no more results for this result set. To get the next result set, the client
program issues an SQLMoreResults function call. When there are no more result sets,
SQL_NO_DATA_FOUND is returned to the SQLMoreResults function call:
....
....
do
{
result_set_no = result_set_no + 1;
printf(″Displaying result set number %i \n\n″ , result_set_no);
/* Display result set */
rc = print_results(hstmt);
CHECK_STMT(hstmt, rc);

} while ((rc = SQLMoreResults(hstmt)) != SQL_NO_DATA_FOUND);


....
....

The client program ends:


....
....
rc = SQLFreeStmt(hstmt, SQL_DROP);
CHECK_STMT(hstmt, rc);

rc = SQLTransact(henv, hdbc, SQL_COMMIT);


CHECK_DBC(hdbc, rc);

printf(″Disconnecting .....\n″ ) ;
rc = SQLDisconnect(hdbc);
CHECK_DBC(hdbc, rc);

rc = SQLFreeConnect(hdbc);
CHECK_DBC(hdbc, rc);

rc = SQLFreeEnv(henv);
if (rc != SQL_SUCCESS)
terminate(henv, rc);

return (SQL_SUCCESS);
}; /* end main */

Stored Procedure MR4C2S.SQC: This stored procedure is similar to mr3c2s except that we have three
host variables instead of one:
SQL_API_RC SQL_API_FN mr4c2s (
void *reserved1,
void *reserved2,
struct sqlda *inout_sqlda,
struct sqlca *ca) {

/* Declare a local SQLCA */


EXEC SQL INCLUDE SQLCA;

/* Declare Host Variables */


EXEC SQL BEGIN DECLARE SECTION;
char stmt1[255];
char stmt2[255];

148 Getting Started with DB2 Stored Procedures


char stmt3[255];
EXEC SQL END DECLARE SECTION;

/* Declare Miscellaneous Variables */


FILE *stream; /* Added for writing to file Bo.2 */
char my_errmsg[71];

EXEC SQL WHENEVER SQLERROR GOTO error_exit;


EXEC SQL WHENEVER SQLWARNING CONTINUE;
....
....

We copy the three SELECT statements from the SQLDA, declare the cursors WITH HOLD, prepare the
statements, open the three cursors, and return:
....
....
/* Copy the SQL statement from the sqlda */
strncpy(stmt1, inout_sqlda->sqlvar[0].sqldata,
inout_sqlda->sqlvar[0].sqllen);
strncpy(stmt2, inout_sqlda->sqlvar[1].sqldata,
inout_sqlda->sqlvar[1].sqllen);
strncpy(stmt3, inout_sqlda->sqlvar[2].sqldata,
inout_sqlda->sqlvar[2].sqllen);

EXEC SQL DECLARE c1 CURSOR WITH HOLD FOR s1;


EXEC SQL DECLARE c2 CURSOR WITH HOLD FOR s2;
EXEC SQL DECLARE c3 CURSOR WITH HOLD FOR s3;

/* Prepare the Statement */


EXEC SQL PREPARE s1 FROM :stmt1;
EXEC SQL PREPARE s2 FROM :stmt2;
EXEC SQL PREPARE s3 FROM :stmt3;

/* Open the cursor */


EXEC SQL OPEN c1;
EXEC SQL OPEN c2;
EXEC SQL OPEN c3;

/* Return the SQLCA to the Calling Program */


memcpy( ca, &sqlca, sizeof( struct sqlca ) );

return(SQLZ_DISCONNECT_PROC);

9.1.2 Setting Up a Loopback Connection


DB2 CLI MRSP requires a remote server. To simulate a remote server on a local machine, use a
so-called loopback connection. To create such a connection, catalog a node with your local server as
REMOTE and then catalog your local database, using the new node.

For example, to catalog a loopback connection using TCP/IP:


CATALOG TCPIP NODE loopback REMOTE thismachine SERVER svcename
CATALOG DATABASE sample AS loopsamp AT NODE loopback

If you connect to sample, it is a local connection; if you connect to loopsamp, it is a remote connection
and you can use DB2 CLI MRSP.

Chapter 9. Transferring Multiple Result Sets with Stored Procedures 149


9.2 Multiple Result Sets in DB2 for OS/390

DB2 for OS/390 has implemented support to MRSP as a client and as a server.

If your stored procedure is executing on DB2 for OS/390, your stored procedure can return MRSP to a
local or remote client application. If the client is a remote DRDA, the client must support the DRDA
code points used to return MRSP. DB2 Connect supports these code points, but DDCS Common
Server does not support these code points.

If the stored procedure is executing on a remote DRDA application server, the remote DRDA
application server must support the DRDA code points used to return MRSP.

DB2 Common Servers and the current release of DB2 UDB do not support these DRDA code points.
Note also that DB2 for MVS/ESA does not support MRSP, as a client or as server.

9.2.1 Multiple Result Set Stored Procedure


To implement MRSP for each result set you want returned, your stored procedure must:
• Declare a cursor with the WITH RETURN option.
• Open the cursor.
• Leave the cursor open.

When the stored procedure ends, DB2 returns the rows in the query result when the the client issues a
FETCH statement.

The RESULT_SETS column of the row associated with your stored procedure in the catalog table
SYSIBM.SYSPROCEDURES must contain the number of result sets that the stored procedure passes to
the client application. If the RESULT_SETS column value is less than the number of cursors left open
in the stored procedure, only the number specified in the RESULT_SETS column are passed to the
client application. In this case, you get a +464 SQLCODE. If the RESUL_SETS column value is greater
than the number of cursors left open in the stored procedure, all result sets are passed to the client
application.

For example, if you want to return a result set that contains entries for all employees in department
D11, you should code your stored procedure as follows:
1. The stored procedure declares a cursor that describes this subset of employees:
EXEC SQL DECLARE CURSOR-EMP CURSOR WITH RETURN FOR
SELECT EMPNO, FIRSTNAME, MIDINT, LASTNAME, PHONENO
FROM DSN8510.EMP
WHERE WORKDEPT=′ D11′ ;
END-EXEC.
2. The stored procedure opens the cursor:
EXEC SQL OPEN CURSOR-EMP END-EXEC.
3. The procedure ends without closing the cursor or fetching rows from this cursor,
You should use meaningful cursor names for returning result sets because the name of the cursor that
is used to return result sets is available to the client application through extensions to the DESCRIBE
statement explained in 9.2.4, “DESCRIBE CURSOR Statement” on page 163. See “Writing DB2 for
OS/390 Client Program to Receive Result Sets” in DB2 for OS/390 Version 5 Application Programming
and SQL Guide for more information.

150 Getting Started with DB2 Stored Procedures


DB2 does not return result sets for cursors that are closed before the stored procedure terminates.
The stored procedure must execute the CLOSE cursor statement for each cursor associated with a
result set that should not be returned to the DRDA client.

9.2.1.1 Objects from Which You Can Return Result Sets You can use any of these objects in
the SELECT statement associated with the cursor for a result set:
• Tables, synonyms, views, temporary tables, and aliases defined at local DB2 system
• Tables, synonyms, views, temporary tables, and aliases defined at remote DB2 on MVS systems
that are accessible through DB2 private protocol access

9.2.1.2 Returning a Subset of Rows to the Client: If you execute FETCH statements with a
result set cursor within the stored procedure, DB2 does not return the fetched rows to the client
program. For example, if you declare a cursor WITH RETURN and execute the statements OPEN,
FETCH, FETCH, the client receives data beginning with the third row in the result set. As with DB2 for
the workstation we explain this aspect of DB2 for completeness, but we don′t think you will have any
reason to exploit this feature. In most applications, you will not want to fetch any of the rows prior to
returning the result set to the stored procedure caller.

9.2.1.3 Using a Temporary Table to Return Result Sets: You can use a temporary table to
return result sets from a stored procedure. This capability can be used to return nonrelational data
such as IMS, VSAM, or QSAM, to a DRDA client. For example, you can access IMS data from a stored
procedure as follows:
• Use the ways described in 13.3, “Accessing IMS Databases” on page 272 to access IMS
databases.
• Receive the IMS reply message, which contains data that should be returned to the client.
• Insert the data from the reply message into a global temporary table.
• Open a cursor against the temporary table. When the stored procedure ends, the rows from the
temporary table are available to the client.
Using this approach you can join information contained in the global temporary table obtained from a
nonrelational database to your DB2 data and return it to the client.

9.2.1.4 Supported Environment: You can code your MRSP stored procedure in any of the
languages supported to code stored procedures. In addition, the stored procedure can be written
using the DB2 for OS/390 ODBC/CLI interface. As a normal stored procedure, it must use LE/370.

MRSP stored procedures are supported in the DB2-established address space and in the
WLM-established address spaces.

Although result sets are available to the client application when the stored procedure ends, the locking
considerations are the same as if the client application connects to the server, declares and opens a
cursor at the server. If the COMMIT_ON_RETURN column of SYSIBM.SYSPROCEDURE is set to YES,
you have to declare the cursor with the WITH HOLD option. In this case, locks are held on the base
table when the stored procedure ends.

Besides returning MRSP, the stored procedure can also return parameters passed in the SQL CALL
statement.

Chapter 9. Transferring Multiple Result Sets with Stored Procedures 151


9.2.2 Writing the DB2 for OS/390 Client to Receive Result Sets
If your application program calls a stored procedure that returns result sets, you must include code in
your application to receive each of the result sets.

In addition, your client application can determine how many result sets are returned by using the
DESCRIBE PROCEDURE statement, and determine the contents of each result set by using the new
DESCRIBE CURSOR statement. If you know the number and contents of the result sets that a stored
procedure returns, you can simplify your program. However, if you write code for the more general
case, in which the number and contents of result sets can vary, you do not have to make major
modifications to your client program if the stored procedure changes.

Result sets are available only for read-only client applications. You cannot use the UPDATE or DELETE
for MRSP in your client application. Stored procedure result sets are always marked ″read only,″ so
update or delete operations fail if you issue them. This implies that UPDATE or DELETE WHERE
CURRENT is not allowed in the stored procedure or in the client application.

When result sets are returned to the client program, you get a +466 SQLCODE for the SQL CALL
statement.

9.2.3 SQL Extensions


Unlike with DB2 UDB and DB2 Common Servers, your DB2 for OS/390 client application can be written
in any supported language and can use the DB2 for OS/390 ODBC/CLI interface.

If the client application is not using ODBC/CLI, there are these extensions in the SQL language:
• A new result set locator SQL data type
• A new ASSOCIATE LOCATORS SQL statement
• A new ALLOCATE CURSOR SQL statement
• A new DESCRIBE PROCEDURE SQL statement
• A new DESCRIBE CURSOR SQL statement
These extensions are compliant with the SQL92 Entry Level.

If you know how many result sets and the characteristics of each result set, you need to:
1. Declare as many result-set locator variables as the number of result sets returned by the stored
procedure.
2. Invoke the stored procedure using the SQL CALL statement.
3. Issue the ASSOCIATE LOCATORS statement once.
4. Issue one ALLOCATE CURSOR statement for each result set returned by the stored procedure.
Figure 81 on page 153 shows the relationship among the new SQL statements and the new data type.

152 Getting Started with DB2 Stored Procedures


Figure 81. Relationship A m o n g the New SQL Statements and the New Data Type

After the SQL CALL statement is executed, you issue the ASSOCIATE LOCATORS statement. The
ASSOCIATE LOCATORS statement associates the result sets returned by the stored procedure with the
result-set locator variables declared previously and specified in the ASSOCIATE LOCATORS statement.
For each result set returned, issue the ALLOCATE CURSOR statement to assign a local cursor name to
the result set locator variable. You can then process the rows of each result set by using the FETCH
statement specifying the local cursor name.

Note that the order of the association of result sets and result set locator variables is the order that the
stored procedure used in opening the cursor; the first open cursor issued by the stored procedure is
associated with the first result set locator variable, the second open cursor issued by the stored
procedure is associated with the second result set locator variable, and so on.

Unlike with DB2 UDB and DB2 Common Servers, you can process the result sets in parallel. For
example, you can process the first row of the first result set, process the first row of the second result
set, then process the second row of the first result set.

The following is the format of the ASSOCIATE LOCATORS statement:


ASSOCIATE LOCATORS (rs1,rs2, ...) WITH PROCEDURE proc
where
rs1 is the result set locator variable 1
rs2 is the result set locator variable 1
proc is the procedure name expressed as a literal or host variable
The format of the ALLOCATE CURSOR statement is the following:

Chapter 9. Transferring Multiple Result Sets with Stored Procedures 153


ALLOCATE cursor-name CURSOR FOR RESULT SET rs1
where
cursor-name is the local cursor name
rs1 is one of the result set locator variable specified in the
ASSOCIATE LOCATOR statement
After your client program issues an SQL CALL statement, you can use the DESCRIBE PROCEDURE
statement to obtain information about the result sets returned by the stored procedure. Figure 82
shows the DESCRIBE PROCEDURE statement.

Figure 82. DESCRIBE PROCEDURE Statement

The DESCRIBE PROCEDURE statement should be used when you do not know how many result sets
the stored procedure is returning. The DESCRIBE PROCEDURE returns the number of result sets
returned from the stored procedure and places information about the result sets in an SQLDA. Make
this SQLDA large enough to hold the maximum number of result sets that the stored procedure may
return. When the DESCRIBE PROCEDURE statement completes, the fields in the SQLDA contain the
following values:
• SQLD contains the number of result sets returned by the stored procedure.
• Each SQLVAR entry gives information about a result set. In an SQLVAR entry:
− The SQLNAME field contains the name of the SQL cursor used in the stored procedure to
return the result set.
− The SQLIND field contains the value -1. This indicates that no estimate of the number of rows
in the result set is available.

154 Getting Started with DB2 Stored Procedures


− The SQLDATA field contains the value of the result set locator, which is the address of the
result set. You can move this value to a result set locator variable, in which case you do not
need to code the ASSOCIATE LOCATORS statement.
The following is the format of the DESCRIBE PROCEDURE statement:
DESCRIBE PROCEDURE procname INTO descriptor
where
procname is a host variable or the literal that contains the
stored procedure name

descriptor is the SQLDA

To use the SQLDATA field from the DESCRIBE PROCEDURE statement, you need to set up a result set
locator variable. A subscript variable is not valid in an SQL ALLOCATE cursor statement. The
following is what is required to use the SQLDATA variable for a COBOL program:
* Redefine the SQLDATA pointer as PIC S9(8) comp.
03 SQLDATA POINTER.
03 SQLDATANUM REDEFINES SQLDATA PIC S9(8) COMP.

* Declare a result set locator variable to move the SQLDATA


* POINTER field too, to be used in the ALLOCATE CURSOR statement.
* You need to redefine this variable as PIC S9(8) comp.
01 LOCPTR USAGE SQL TYPE IS
RESULT-SET-LOCATOR VARYING.
01 LOCNUM REDEFINES LOCPTR PIC S9(8) COMP.

* After the DESCRIBE PROCEDURE statement you can


* move the SQLDATANUM variable to the LOCNUM variable
MOVE SQLDATANUM(IDX) TO LOCNUM.

* You can now allocate the cursor for the result set.
EXEC SQL ALLOCATE CURSOR1 CURSOR FOR RESULT SET
:LOCPTR
END-EXEC,

Provided for you are two sample programs that use the SQL statement DESCRIBE PROCEDURE. The
first program uses the SQL statement ASSOCIATE CURSOR to allocate the result set locator variable.
The second program uses the SQLDATA variable from SQLDA. Both are coded to handle five known
result sets from a stored procedure. The client program assumes that any result set or sets can be
returned in any order or any number from one to five cursors.

Sample program MR1BMCBM uses the SQL statement ASSOCIATE CURSOR to allocate the result set
locator variables after the DESCRIBE PROCEDURE statement:
WORKING-STORAGE SECTION.
***********************
* SQL INCLUDE FOR SQLCA
***********************
EXEC SQL INCLUDE SQLCA END-EXEC.
***********************
* SQL DESCRIPTION AREA IN COBOL SQLDA
* SEE ″APPLICATION PROGRAMMING AND SQL GUIDE″ SC26-8958
* APPENDIX C. PROGRAMMING EXAMPLES, PAGE X-23
***********************
01 SQLDA.
02 SQLDAID PIC X(8) VALUE ′ SQLDA ′ .
02 SQLDABC PIC S9(8) COMP VALUE 236.
02 SQLN PIC S9(4) COMP VALUE 5.

Chapter 9. Transferring Multiple Result Sets with Stored Procedures 155


02 SQLD PIC S9(4) COMP VALUE 0.
02 SQLDVAR OCCURS 1 TO 5 TIMES
DEPENDING ON SQLN.
03 SQLTYPE PIC S9(4) COMP.
03 SQLLEN PIC S9(4) COMP.
03 SQLDATA POINTER.
03 SQLIND POINTER.
03 SQLNAME.
49 SQLNAMEL PIC S9(4) COMP.
49 SQLNAMEC PIC X(30).
01 I PIC S9(4) COMP.
01 F PIC S9(4) COMP.
01 J PIC S9(4) COMP.
01 Q10 PIC X(10) VALUE ′ ?′ .
01 Q20 PIC X(20) VALUE ′ ?′ .
01 CURSOR-NM PIC X(8).
01 IDX PIC S9(4) COMP.
*
* 1 DECLARE A RESULT SET LOCATOR VARIABLE FOR EACH RESULT
* SET THAT MIGHT BE RETURNED.
*
01 LOC-1 USAGE SQL TYPE IS
RESULT-SET-LOCATOR VARYING.
01 LOC-2 USAGE SQL TYPE IS
RESULT-SET-LOCATOR VARYING.
01 LOC-3 USAGE SQL TYPE IS
RESULT-SET-LOCATOR VARYING.
01 LOC-4 USAGE SQL TYPE IS
RESULT-SET-LOCATOR VARYING.
01 LOC-5 USAGE SQL TYPE IS
RESULT-SET-LOCATOR VARYING.
01 TESTE-ROW.
02 TESTE-COL1 PIC X(10).
02 TESTE-COL2 PIC X(20).
01 TESTE-INDARRAY.
02 ICOL1E PIC S9(4) COMP.
02 ICOL2E PIC S9(4) COMP.
01 TEST-TB-ROW.
02 TEST-TB-COL1 PIC X(20).
02 TEST-TB-COL2 PIC X(30).
02 TEST-TB-COL3 PIC X(19).
01 TEST-TB-INDARRAY.
02 ICOL2T PIC S9(4) COMP.
02 ICOL3T PIC S9(4) COMP.
* PARM TO RECEIVE THE SQLCODE ERROR MESSAGES
01 ERROR-MESSAGE.
02 ERROR-LEN PIC S9(4) COMP VALUE +960.
02 ERROR-TEXT PIC X(120) OCCURS 8 TIMES
INDEXED BY ERROR-INDEX.
77 ERROR-TEXT-LEN PIC S9(8) COMP VALUE +120.

77 ERR-CODE PIC 9(8) VALUE 0.


77 ERR-MINUS PIC X VALUE SPACE.
77 LINE-EXEC PIC X(20) VALUE SPACE.
77 STOREPROC PIC X(8) VALUE ′ MR5BMS ′ .
77 CURSOR-E PIC X(30) VALUE ′ TESTE-CURSOR′ .
77 CURSOR-TB PIC X(30) VALUE ′ TEST-TB-CURSOR′ .
77 CURSOR-E-NF PIC X(30) VALUE ′ TESTE-NF-CURSOR′ .
77 CURSOR-TB-NF PIC X(30) VALUE ′ TEST-TB-NF-CURSOR′ .

156 Getting Started with DB2 Stored Procedures


77 CURSOR-TB-WH PIC X(30) VALUE ′ TEST-TB-WH-CURSOR′ .
*
* PASSED BY MR0BMCBM
PROCEDURE DIVISION.
**************************
*
* SQL RETURN CODE HANDLING
*
**************************
EXEC SQL WHENEVER SQLERROR GOTO DBERROR END-EXEC.
CALL-STORED-PROCEDURE.
**************************
*
* 2 CALL THE STORED PROCEDURE MR1BMS AND CHECK THE SQL
* RETURN CODE FOR +466
*
**************************
MOVE ″CALL 1 ″ TO LINE-EXEC.
EXEC SQL CALL :STOREPROC END-EXEC. 2A
IF SQLCODE = +466
PERFORM PROCESS-OUTPUT
ELSE
DISPLAY ″NO RESULT SETS RETURNED CALL 1 ″ SQLCODE.
PROG-END.
GOBACK.

PROCESS-OUTPUT.
**************************
*
* 3 DETERMINE HOW MANY RESULT SETS THE STORED PROCEDURE IS
* RETURNING.
*
* SQLD WILL HAVE THE NUMBER OF RESULT SETS.
* SQLNAMEC() WILL HAVE THE STORED PROCEDURE CURSOR NAMES.
*
**************************
MOVE ″DESCRIBE″ TO LINE-EXEC.
EXEC SQL DESCRIBE PROCEDURE :STOREPROC INTO :SQLDA
END-EXEC.

**************************
*
* 4 LINK RESULT SET LOCATORS TO RESULT SETS
*
**************************
EXEC SQL ASSOCIATE LOCATORS
(:LOC-1, :LOC-2, :LOC-3, :LOC-4, :LOC-5)
WITH PROCEDURE :STOREPROC
END-EXEC.
**************************
*
* CHECK TO SEE IF PROCEDURE RETURNED MORE RESULT SETS THAN YOU
* HAD LOCATORS FOR. IF SO YOU WILL GET A +494 SQLCODE FROM THE
* SQL ASSOCIATE LOCATOR STATEMENT.
*
* 494, WARNING: PROCEDURE MR1BMS RETURNED 00000006 QUERY RESULT
* SETS
* THE OTHER LOCATORS WILL HAVE VALID ADDRESSES THAT YOU CAN
* PROCESS.

Chapter 9. Transferring Multiple Result Sets with Stored Procedures 157


*
**************************
IF SQLCODE > 0 PERFORM DBERROR.

PERFORM PROCESS-CURSORS VARYING IDX


FROM 1 BY 1 UNTIL IDX GREATER THAN SQLD.
**************************
*
* 5 ALLOCATE CURSORS FOR EACH RESULT SET RETURNED FOR
* FETCHING ROWS.
*
**************************
PROCESS-CURSORS.
EVALUATE SQLNAMEC(IDX)
WHEN CURSOR-E
PERFORM PROCESS-E,
WHEN CURSOR-TB
PERFORM PROCESS-TB,
WHEN CURSOR-E-NF
PERFORM PROCESS-E-NF,
WHEN CURSOR-TB-NF
PERFORM PROCESS-TB-NF,
WHEN CURSOR-TB-WH
PERFORM PROCESS-TB-WH,
WHEN OTHER
PERFORM UNRECOGNIZED-ERROR,
END-EVALUATE.

ALLOCATE-CURSOR.
EVALUATE IDX
WHEN 1
EXEC SQL ALLOCATE CURSOR1 CURSOR FOR RESULT SET
:LOC-1
END-EXEC,
WHEN 2
EXEC SQL ALLOCATE CURSOR1 CURSOR FOR RESULT SET
:LOC-2
END-EXEC,
WHEN 3
EXEC SQL ALLOCATE CURSOR1 CURSOR FOR RESULT SET
:LOC-3
END-EXEC,
WHEN 4
EXEC SQL ALLOCATE CURSOR1 CURSOR FOR RESULT SET
:LOC-4
END-EXEC,
WHEN OTHER
EXEC SQL ALLOCATE CURSOR1 CURSOR FOR RESULT SET
:LOC-5
END-EXEC,
END-EVALUATE.
PROCESS-E.
PERFORM ALLOCATE-CURSOR.
PERFORM FETCH-ROWS-1 VARYING F FROM 1 BY 1 UNTIL
SQLCODE = +100.
EXEC SQL CLOSE CURSOR1 END-EXEC.

PROCESS-TB.
PERFORM ALLOCATE-CURSOR.

158 Getting Started with DB2 Stored Procedures


PERFORM FETCH-ROWS-2 VARYING F FROM 1 BY 1 UNTIL
SQLCODE = +100.
EXEC SQL CLOSE CURSOR1 END-EXEC.

PROCESS-E-NF.
PERFORM ALLOCATE-CURSOR.
PERFORM FETCH-ROWS-3 VARYING F FROM 1 BY 1 UNTIL
SQLCODE = +100 .
EXEC SQL CLOSE CURSOR1 END-EXEC.

PROCESS-TB-NF.
PERFORM ALLOCATE-CURSOR.
PERFORM FETCH-ROWS-4 VARYING F FROM 1 BY 1 UNTIL
SQLCODE = +100.
EXEC SQL CLOSE CURSOR1 END-EXEC.

PROCESS-TB-WH.
PERFORM ALLOCATE-CURSOR.
PERFORM FETCH-ROWS-5 VARYING F FROM 1 BY 1 UNTIL
SQLCODE = +100.
EXEC SQL CLOSE CURSOR1 END-EXEC.
FETCH-ROWS-1.
EXEC SQL FETCH CURSOR1 INTO
:TESTE-COL1 :ICOL1E,
:TESTE-COL2 :ICOL2E
END-EXEC.
IF SQLCODE = 0
.... process row
END-IF.
FETCH-ROWS-2.
MOVE ″FETCH CUR 2″ TO LINE-EXEC.
EXEC SQL FETCH CURSOR1 INTO
:TEST-TB-COL1,
:TEST-TB-COL2 :ICOL2T,
:TEST-TB-COL3 :ICOL3T
END-EXEC.
IF SQLCODE = 0
.... process row
END-IF.
FETCH-ROWS-3.
EXEC SQL FETCH CURSOR1 INTO
:TESTE-COL1 :ICOL1E,
:TESTE-COL2 :ICOL2E
END-EXEC.
IF SQLCODE = 0
.... process row
END-IF.
FETCH-ROWS-4.
EXEC SQL FETCH CURSOR1 INTO
:TEST-TB-COL1,
:TEST-TB-COL2 :ICOL2T
END-EXEC.
IF SQLCODE = 0
.... process row
END-IF.
FETCH-ROWS-5.
EXEC SQL FETCH CURSOR1 INTO
:TEST-TB-COL1,
:TEST-TB-COL3 :ICOL3T

Chapter 9. Transferring Multiple Result Sets with Stored Procedures 159


END-EXEC.
IF SQLCODE = 0
.... process row
END-IF.

Sample program MR2BMCBM uses the SQLDA variable SQLDATA to allocate the cursors to the result
sets after the DESCRIBE PROCEDURE statement:
***********************
* SQL DESCRIPTION AREA IN COBOL SQLDA
* SEE ″APPLICATION PROGRAMMING AND SQL GUIDE″ SC26-8958
* APPENDIX C. PROGRAMMING EXAMPLES, PAGE X-23
***********************
01 SQLDA.
02 SQLDAID PIC X(8) VALUE ′ SQLDA ′ .
02 SQLDABC PIC S9(8) COMP VALUE 236.
02 SQLN PIC S9(4) COMP VALUE 5.
02 SQLD PIC S9(4) COMP VALUE 0.
02 SQLDVAR OCCURS 1 TO 5 TIMES
DEPENDING ON SQLN.
03 SQLTYPE PIC S9(4) COMP.
03 SQLLEN PIC S9(4) COMP.
03 SQLDATA POINTER.
03 SQLDATANUM REDEFINES SQLDATA PIC S9(8) COMP.
03 SQLIND POINTER.
03 SQLNAME.
49 SQLNAMEL PIC S9(4) COMP.
49 SQLNAMEC PIC X(30).

01 LOCPTR USAGE SQL TYPE IS


RESULT-SET-LOCATOR VARYING.
01 LOCNUM REDEFINES LOCPTR PIC S9(8) COMP.
* Cursor names from stored procedure
77 STOREPROC PIC X(8) VALUE ′ MR5BMS ′ .
77 CURSOR-E PIC X(30) VALUE ′ TESTE-CURSOR′ .
77 CURSOR-TB PIC X(30) VALUE ′ TEST-TB-CURSOR′ .
77 CURSOR-E-NF PIC X(30) VALUE ′ TESTE-NF-CURSOR′ .
77 CURSOR-TB-NF PIC X(30) VALUE ′ TEST-TB-NF-CURSOR′ .
77 CURSOR-TB-WH PIC X(30) VALUE ′ TEST-TB-WH-CURSOR′ .

PROCEDURE DIVISION.
CALL-STORED-PROCEDURE.
**************************
*
* 2 CALL THE STORED PROCEDURE MR2BMS AND CHECK THE SQL
* RETURN CODE FOR +466
*
**************************
EXEC SQL CALL :STOREPROC END-EXEC. 2A
IF SQLCODE = +466
PERFORM PROCESS-OUTPUT
ELSE
DISPLAY ″NO RESULT SETS RETURNED CALL 1 ″ SQLCODE.
PROG-END.
GOBACK.

PROCESS-OUTPUT.
**************************
*
* 3 DETERMINE HOW MANY RESULT SETS THE STORED PROCEDURE IS

160 Getting Started with DB2 Stored Procedures


* RETURNING.
*
* SQLD WILL HAVE THE NUMBER OF RESULT SETS.
* SQLNAMEC() WILL HAVE THE STORED PROCEDURE CURSOR NAMES.
*
**************************
EXEC SQL DESCRIBE PROCEDURE :STOREPROC INTO :SQLDA
END-EXEC.

PERFORM PROCESS-CURSORS VARYING IDX


FROM 1 BY 1 UNTIL IDX GREATER THAN SQLD.
**************************
*
* 5 ALLOCATE CURSORS FOR EACH RESULT SET RETURNED FOR
* FETCHING ROWS.
*
**************************
PROCESS-CURSORS.
EVALUATE SQLNAMEC(IDX)
WHEN CURSOR-E
PERFORM PROCESS-E,
WHEN CURSOR-TB
PERFORM PROCESS-TB,
WHEN CURSOR-E-NF
PERFORM PROCESS-E-NF,
WHEN CURSOR-TB-NF
PERFORM PROCESS-TB-NF,
WHEN CURSOR-TB-WH
PERFORM PROCESS-TB-WH,
WHEN OTHER
PERFORM UNRECOGNIZED-ERROR,
END-EVALUATE.

PROCESS-E.
MOVE SQLDATANUM(IDX) TO LOCNUM.
EXEC SQL ALLOCATE CURSOR1 CURSOR FOR RESULT SET
:LOCPTR
END-EXEC,
PERFORM FETCH-ROWS-1 VARYING F FROM 1 BY 1 UNTIL
SQLCODE = +100.
EXEC SQL CLOSE CURSOR1 END-EXEC.

PROCESS-TB.
MOVE SQLDATANUM(IDX) TO LOCNUM.
EXEC SQL ALLOCATE CURSOR2 CURSOR FOR RESULT SET
:LOCPTR
END-EXEC,
PERFORM FETCH-ROWS-2 VARYING F FROM 1 BY 1 UNTIL
SQLCODE = +100.
EXEC SQL CLOSE CURSOR2 END-EXEC.

PROCESS-E-NF.
MOVE SQLDATANUM(IDX) TO LOCNUM.
EXEC SQL ALLOCATE CURSOR3 CURSOR FOR RESULT SET
:LOCPTR
END-EXEC,
PERFORM FETCH-ROWS-3 VARYING F FROM 1 BY 1 UNTIL
SQLCODE = +100 .
EXEC SQL CLOSE CURSOR3 END-EXEC.

Chapter 9. Transferring Multiple Result Sets with Stored Procedures 161


PROCESS-TB-NF.
MOVE SQLDATANUM(IDX) TO LOCNUM.
EXEC SQL ALLOCATE CURSOR4 CURSOR FOR RESULT SET
:LOCPTR
END-EXEC,
PERFORM FETCH-ROWS-4 VARYING F FROM 1 BY 1 UNTIL
SQLCODE = +100.
EXEC SQL CLOSE CURSOR4 END-EXEC.

PROCESS-TB-WH.
MOVE SQLDATANUM(IDX) TO LOCNUM.
EXEC SQL ALLOCATE CURSOR5 CURSOR FOR RESULT SET
:LOCPTR
END-EXEC,
PERFORM FETCH-ROWS-5 VARYING F FROM 1 BY 1 UNTIL
SQLCODE = +100.
EXEC SQL CLOSE CURSOR5 END-EXEC.
FETCH-ROWS-1.
EXEC SQL FETCH CURSOR1 INTO
:TESTE-COL1 :ICOL1E,
:TESTE-COL2 :ICOL2E
END-EXEC.
IF SQLCODE = 0
.... process row
END-IF.
FETCH-ROWS-2.
EXEC SQL FETCH CURSOR2 INTO
:TEST-TB-COL1,
:TEST-TB-COL2 :ICOL2T,
:TEST-TB-COL3 :ICOL3T
END-EXEC.
IF SQLCODE = 0
.... process row
END-IF.
MOVE ″FETCH CUR 3″ TO LINE-EXEC.
EXEC SQL FETCH CURSOR3 INTO
:TESTE-COL1 :ICOL1E,
:TESTE-COL2 :ICOL2E
END-EXEC.
IF SQLCODE = 0
.... process row
END-IF.
FETCH-ROWS-4.
EXEC SQL FETCH CURSOR4 INTO
:TEST-TB-COL1,
:TEST-TB-COL2 :ICOL2T
END-EXEC.
IF SQLCODE = 0
.... process row
END-IF.
FETCH-ROWS-5.
EXEC SQL FETCH CURSOR5 INTO
:TEST-TB-COL1,
:TEST-TB-COL3 :ICOL3T
END-EXEC.
IF SQLCODE = 0
.... process row
END-IF.

162 Getting Started with DB2 Stored Procedures


9.2.4 DESCRIBE CURSOR Statement
After your client program issued an SQL CALL statement, you can use the DESCRIBE CURSOR
statement to obtain information about a specific result set returned by the stored procedure if you don′ t
know the column names. Figure 83 on page 163 shows the DESCRIBE CURSOR statement.

Figure 83. DESCRIBE Cursor Statement

The DESCRIBE CURSOR statement should be used when you do not know the column names and data
types of a particular result set. After execution of the DESCRIBE CURSOR statement, the contents of
the SQLDA are similar to the execution of a SELECT statement:
• The first 5 bytes of the SQLDAID are set to ′SQLRS′.
• SQLD contains the number of columns for this result set.
• Each SQLVAR entry gives information about a column.
In an SQLVAR entry:
• The SQLTYPE field contains the data type of the column.
• The SQLLEN field contains the length attribute of the column.
• The SQLNAME field contains the name of the column.
The following is the format of the DESCRIBE CURSOR statement:
DESCRIBE CURSOR cursorname INTO descriptor

Chapter 9. Transferring Multiple Result Sets with Stored Procedures 163


where
cursorname is a host variable or the literal that contains the
local cursor name

descriptor is the SQLDA


The cursor name in the statement must have been previously allocated through the ALLOCATE
CURSOR statement.

Note that information about the columns is placed in the SQLDA when the statement that generated
the result set is dynamic. For static statements coded in the stored procedure, the SQLDA information
is returned if you specified the DESCSTAT(YES) bind option when binding the package for the stored
procedure.

9.2.5 Summary of Coding


The following summarizes the steps to code the client application:
1. Declare a result set locator variable for each result set that is returned.
2. Call the stored procedure and check the SQL return code for a + 4 6 6 . A 466 SQLCODE indicates
that the stored procedure returned one or more result sets.
3. Determine how many result sets the stored procedure is returning.
If you already know how many result sets the stored procedure returns, you may skip this step.
Use the SQL statement DESCRIBE PROCEDURE to determine the number of result sets reurned
and their names. DESCRIBE PROCEDURE places information about the result sets in the SQLDA.
4. Associate result set locators to result sets.
5. Allocate cursors for fetching rows from the result sets.
6. Determine the contents of the result sets.
If you already know the format of the result set, you can skip this step.
Use the SQL statement DESCRIBE CURSOR to determine the format of a result set and put this
information in an SQLDA. For each result set, you need an SQLDA big enough to hold descriptions
of all columns in the result set.
7. Fetch rows from the result sets into host variables by using the cursors you allocate with the
ALLOCATE CURSOR statements.

For a detailed explanation of theses steps see “Writing a DB2 for OS/390 Client Program to Receive
Result Sets” in DB2 for OS/390 Version 5 Application Programming and SQL Guide .

9.2.6 Example of Client Program Processing a Single Result Set


The following example shows a COBOL client program that processes a single result set. This
example uses linkage convention SIMPLE WITH NULLS. It uses five of the seven steps outlined above.

Here is an example of how you receive a single result set in sample COBOL client program
SRSBMCBM (no parameters are passed to or received from the stored procedure):
*
* PARMS TO FETCH ROWS INTO WITH NULL INDICATORS
*
01 COL1 PIC X(10).
01 COL2 PIC X(20).
01 INDARRAY.
02 ICOL1 PIC S9(4) COMP.

164 Getting Started with DB2 Stored Procedures


02 ICOL2 PIC S9(4) COMP.
*
* 1. DECLARE A RESULT SET LOCATOR FOR THE RESULT SET THAT
* IS RETURNED.
*
01 LOC-TESTE USAGE SQL TYPE IS
RESULT-SET-LOCATOR VARYING.

PROCEDURE DIVISION.

*
* 2. CALL THE STORED PROCEDURE AND CHECK THE SQL RETURN CODE.
* RETURN CODE FROM CALLED STORED PROCEDURE IS SET TO +466
* IF A RESULT SET IS RETURNED.
*
EXEC SQL CALL SRSBMS END-EXEC.
IF SQLCODE = +466
PERFORM PROCESS-OUTPUT
ELSE
DISPLAY ″NO RESULT SETS RETURNED″ .
PROG-END.
STOP RUN.
EXIT.

PROCESS-OUTPUT.
*
* 4. LINK RESULT SET LOCATORS TO RESULT SETS.
* ASSOCIATE LOCATOR WITH PROCEDURE
*
EXEC SQL ASSOCIATE LOCATORS (:LOC-TESTE)
WITH PROCEDURE SRSBMS
END-EXEC.

*
* 5. ALLOCATE CURSORS FOR FETCHING ROWS FROM THE RESULT SETS
*
EXEC SQL ALLOCATE TESTE-CURSOR CURSOR FOR RESULT SET
:LOC-TESTE
END-EXEC.

PERFORM GET-ROWS VARYING I FROM 1 BY 1 UNTIL


SQLCODE = +100.

GET-ROWS.
*
* 7. FETCH ROWS FROM THE RESULT SET INTO HOST VARIABLES.
* ALLOW FOR NULLS.
*
EXEC SQL FETCH TESTE-CURSOR INTO :COL1 :ICOL1,
:CCL2 :ICOL2
END-EXEC.
IF SQLCODE = 0

.... process row logic here

END-IF.

Here is an example of the COBOL stored procedure SRSBMS called by sample COBOL client program
SRSBMCBM:

Chapter 9. Transferring Multiple Result Sets with Stored Procedures 165


WORKING-STORAGE SECTION.
EXEC SQL INCLUDE SQLCA END-EXEC.

LINKAGE SECTION.

PROCEDURE DIVISION.

*
* 1 Declare a cursor with the option WITH RETURN
*
EXEC SQL DECLARE TESTE-CURSOR CURSOR WITH RETURN FOR
SELECT COL1, COL2 FROM TESTE
END-EXEC.

*
* 2 Open the cursor
*
EXEC SQL OPEN TESTE-CURSOR END-EXEC.

*
* 3 Leave the cursor open
*
ERROR-EXIT.
GOBACK.

In the SYSPROCEDURES table, the column RESULT_SETS is set to 1.

9.2.7 Example of Client Program Processing Multiple Result Sets


The following is an example of a COBOL client program that processes multiple result sets. This
example shows how the client program in OS/390 can process each result set separately or process
multiple result sets at the same time.

Here is an example of how you receive multiple result sets in the sample COBOL client program
MRSBMCBM:
* SQL INCLUDE FOR SQLCA
EXEC SQL INCLUDE SQLCA END-EXEC.
* PARMS FETCH ROWS INTO FROM TESTE
01 COL1 PIC X(10).
01 COL2 PIC X(20).
01 INDARRAY.
02 ICOL1 PIC S9(4) COMP.
02 ICOL2 PIC S9(4) COMP.

* PARMS FETCH ROWS INTO FROM TEST_TB


01 FLD1 PIC X(20).

*
* 1. DECLARE A RESULT SET LOCATOR FOR THE RESULT SETS THAT
* ARE RETURNED.
*
01 LOC-TESTE USAGE SQL TYPE IS
RESULT-SET-LOCATOR VARYING.

01 LOC-TEST-TB USAGE SQL TYPE IS


RESULT-SET-LOCATOR VARYING.

166 Getting Started with DB2 Stored Procedures


77 I PIC 9(5) VALUE 0.
77 FETCH-END PIC S9(8) COMP VALUE +0.
77 CUR-END1 PIC S9(8) COMP VALUE +0.
77 CUR-END2 PIC S9(8) COMP VALUE +0.

PROCEDURE DIVISION.

CALL-STORED-PROCEDURE.
*
* PROCESS CURSOR 1 FIRST AND THEN PROCESS CURSOR 2
*
*
* 2. CALL THE STORED PROCEDURE AND CHECK THE SQL RETURN CODE.
*
EXEC SQL CALL MRSBMS END-EXEC.
IF SQLCODE = +466
PERFORM PROCESS-OUTPUT
ELSE
DISPLAY ″NO RESULT SETS RETURNED CALL 1 ″ .
*
* PROCESS CURSOR 1 AND CURSOR 2 AT THE SAME TIME.
*
*
* 2. CALL THE STORED PROCEDURE AND CHECK THE SQL RETURN CODE.
*
EXEC SQL CALL MRSBMS (:SQLC) END-EXEC.
IF SQLCODE = +466
PERFORM PROCESS-BOTH
ELSE
DISPLAY ″NO RESULT SETS RETURNED CALL 2 ″ .
PROG-END.
STOP RUN.
EXIT.

PROCESS-BOTH.
PERFORM ASSOCIATE-LINK.
*
* PROCESS DATA FROM TABLE TESTE
*
PERFORM GET-ROWS-B VARYING I FROM 1 BY 1 UNTIL
FETCH-END = +2.

EXEC SQL CLOSE TESTE-CURSOR END-EXEC.


EXEC SQL CLOSE TEST-TB-CURSOR END-EXEC.

PROCESS-OUTPUT.
PERFORM ASSOCIATE-LINK.
*
* PROCESS DATA FROM TABLE TESTE
*
PERFORM GET-ROWS-E VARYING I FROM 1 BY 1 UNTIL
SQLCODE = +100.

EXEC SQL CLOSE TESTE-CURSOR END-EXEC.


*
* PROCESS DATA FROM TABLE TEST_TB
*
PERFORM GET-ROWS-TAB VARYING I FROM 1 BY 1 UNTIL
SQLCODE = +100.

Chapter 9. Transferring Multiple Result Sets with Stored Procedures 167


EXEC SQL CLOSE TEST-TB-CURSOR END-EXEC.

GET-ROWS-TAB.
*
* 7. FETCH ROWS FROM THE RESULT SET INTO HOST VARIABLES.
*
EXEC SQL FETCH TEST-TB-CURSOR INTO :FLD1 END-EXEC.
IF SQLCODE = 0
...... process row logic here
END-IF

GET-ROWS-E.
*
* 7. FETCH ROWS FROM THE RESULT SET INTO HOST VARIABLES.
* ALLOW FOR NULLS
*
EXEC SQL FETCH TESTE-CURSOR INTO :COL1 :ICOL1,
:COL2 :ICOL2
END-EXEC.
IF SQLCODE = 0
...... process row logic here
END-IF

FETCH-TEST-E.
*
* 7. FETCH ROWS FROM THE RESULT SET INTO HOST VARIABLES.
* ALLOW FOR NULLS
*
EXEC SQL FETCH TESTE-CURSOR INTO :COL1 :ICOL1,
:COL2 :ICOL2
END-EXEC.
FETCH-TEST-TB.
*
* 7. FETCH ROWS FROM THE RESULT SET INTO HOST VARIABLES.
*
EXEC SQL FETCH TEST-TB-CURSOR INTO :FLD1 END-EXEC .

GET-ROWS-B.
IF FETCH-END < 2 THEN
IF CUR-END1 < 100 THEN
PERFORM FETCH-TEST-TB
IF SQLCODE = 100 THEN
MOVE SQLCODE TO CUR-END1
ADD 1 TO FETCH-END
MOVE SPACE TO FLD1
END-IF
ELSE
MOVE SPACE TO FLD1
END-IF
IF CUR-END2 < 100 THEN
PERFORM FETCH-TEST-E
IF SQLCODE = 100 THEN
MOVE SQLCODE TO CUR-END2
ADD 1 TO FETCH-END
MOVE SPACES TO COL1
MOVE SPACES TO COL2
ELSE
.... insert null logic for columns

168 Getting Started with DB2 Stored Procedures


END-IF
ELSE
MOVE SPACES TO COL1
MOVE SPACES TO COL2
END-IF
IF FETCH-END < 2
..... insert process logic to process both rows
END-IF.

ASSOCIATE-LINK.
*
* 4. LINK RESULT SET LOCATORS TO RESULT SETS.
*
* ASSOCIATE LOCATORS WITH PROCEDURE MRSBMS
EXEC SQL ASSOCIATE LOCATORS (:LOC-TESTE, :LOC-TEST-TB)
WITH PROCEDURE MRSBMS
END-EXEC.
*
* 5. ALLOCATE CURSORS FOR FETCHING ROWS FROM THE RESULT SETS
*
* LINK THE RESULT SET TO THE LOCATOR
EXEC SQL ALLOCATE TESTE-CURSOR CURSOR FOR RESULT SET
:LOC-TESTE
END-EXEC.
* LINK THE RESULT SET TO THE LOCATOR
EXEC SQL ALLOCATE TEST-TB-CURSOR CURSOR FOR RESULT SET
:LOC-TEST-TB
END-EXEC.

Here is an example of the COBOL stored procedure MRSBMS called by the sample COBOL client
program MRSBMCBM:
WORKING-STORAGE SECTION.
EXEC SQL INCLUDE SQLCA END-EXEC.

LINKAGE SECTION.

PROCEDURE DIVISION.

*
* 1 Declare a cursor with the option WITH RETURN
*
EXEC SQL DECLARE TESTE-CURSOR CURSOR WITH RETURN FOR
SELECT COL1, COL2 FROM TESTE
END-EXEC.

*
* 2 Open the cursor
*
EXEC SQL OPEN TESTE-CURSOR END-EXEC.

*
* 1 Declare a cursor with the option WITH RETURN
*
EXEC SQL DECLARE TEST-TB-CURSOR CURSOR WITH RETURN FOR
SELECT COL1 FROM TEST_TB
END-EXEC.

*
* 2 Open the cursor

Chapter 9. Transferring Multiple Result Sets with Stored Procedures 169


*
EXEC SQL OPEN TEST-TB-CURSOR END-EXEC.

*
* 3 Leave the cursors open.
*
ERROR-EXIT.
GOBACK.

In the SYSPROCEDURES table, the column RESULT_SETS is set to 2.

9.2.8 Reasons Why Cursors May Not Be Returned to Client


If an open cursor statement has no rows that satisfied its WHERE clause, a cursor is still passed back
to the client. You must code your client program to handle this not-found condition.

There are two reasons why a cursor will not be passed back to a client program:
• The stored procedure closes the cursor before it terminates.
• The OPEN CURSOR statement fails.

9.2.9 Example of Client Program Using the DESCRIBE CURSOR SQL


Statement
Here is an example of a COBOL client program MR5BMCBM, which uses the SQL statements
DESCRIBE CURSOR and DESCRIBE PROCEDURE. This program is coded to determine the contents of
the result sets with the SQL statement DESCRIBE CURSOR. It uses a COBOL program (MR0BMCBM)
that allocates the memory for the maximum SQLDA and passes this to MR5BMCBM. This is not
required if you are going to use only the SQL statement DESCRIBE PROCEDURE, see sample program
MR2BMCM. This program uses DISPLAY statements to show you how values are returned in the
SQLDA area. It prints out the first 127 bytes of the rows returned by the fetches that use the SQLDA
area:
WORKING-STORAGE SECTION.
***********************
* SQL INCLUDE FOR SQLCA
***********************
EXEC SQL INCLUDE SQLCA END-EXEC.
***********************
* SQL DESCRIPTION AREA IN COBOL SQLDA
* SEE ″APPLICATION PROGRAMMING AND SQL GUIDE″ SC26-8958
* APPENDIX C. PROGRAMMING EXAMPLES, PAGE X-23
* This SQLDA is set up for the maximum size allowable
***********************
01 SQLDA.
02 SQLDAID PIC X(8) VALUE ′ SQLDA ′ .
02 SQLDABC PIC S9(8) COMP VALUE 33016.
02 SQLN PIC S9(4) COMP VALUE 750.
02 SQLD PIC S9(4) COMP VALUE 0.
02 SQLDVAR OCCURS 1 TO 750 TIMES
DEPENDING ON SQLN.
03 SQLTYPE PIC S9(4) COMP.
03 SQLLEN PIC S9(4) COMP.
03 SQLDATA POINTER.
03 SQLIND POINTER.
03 SQLNAME.
49 SQLNAMEL PIC S9(4) COMP.
49 SQLNAMEC PIC X(30).

170 Getting Started with DB2 Stored Procedures


***********************
* DATA TYPES FOUND IN SQLTYPE, AFTER REMOVING THE NULL BIT
***********************
77 DATETYP PIC S9(4) COMP VALUE +384.
77 TIMETYP PIC S9(4) COMP VALUE +388.
77 TIMESTMP PIC S9(4) COMP VALUE +392.
77 VARCTYPE PIC S9(4) COMP VALUE +448.
77 CHARTYPE PIC S9(4) COMP VALUE +452.
77 VARLTYPE PIC S9(4) COMP VALUE +456.
77 VARGTYPE PIC S9(4) COMP VALUE +464.
77 GTYPE PIC S9(4) COMP VALUE +468.
77 LVARGTYP PIC S9(4) COMP VALUE +472.
77 FLOATYPE PIC S9(4) COMP VALUE +480.
77 DECTYPE PIC S9(4) COMP VALUE +484.
77 INTTYPE PIC S9(4) COMP VALUE +496.
77 HWTYPE PIC S9(4) COMP VALUE +500.

01 RECPTR POINTER.
01 RECNUM REDEFINES RECPTR PIC S9(8) COMP.
01 IRECPTR POINTER.
01 IRECNUM REDEFINES IRECPTR PIC S9(8) COMP.
01 I PIC S9(4) COMP.
01 F PIC S9(4) COMP.
01 J PIC S9(4) COMP.
01 DUMMY PIC S9(4) COMP.
01 MYTYPE PIC S9(4) COMP.
01 COLUMN-IND PIC S9(4) COMP.
01 COLUMN-LEN PIC S9(4) COMP.
01 COLUMN-PREC PIC S9(4) COMP.
01 COLUMN-SCALE PIC S9(4) COMP.
01 INDCOUNT PIC S9(4) COMP.
01 ROWCOUNT PIC S9(4) COMP.
01 WORKAREA2.
02 WORKINDPTR POINTER OCCURS 750 TIMES.
77 ONE PIC S9(4) COMP VALUE +1.
77 TWO PIC S9(4) COMP VALUE +2.
77 FOUR PIC S9(4) COMP VALUE +4.
77 QMARK PIC X(1) VALUE ′ ? ′ .
* PARM TO RECEIVE THE SQLCODE FROM STORED PROCEDURE
01 SQLC PIC S9(9) COMP.
01 CURSOR-NM PIC X(8).
01 CURSOR-N PIC S9(4) COMP.
01 IDX-1 PIC S9(4) COMP.
01 IDX-2 PIC S9(4) COMP.
01 CURSOR-NAMEX.
02 CURSOR-NAMES OCCURS 5 TIMES.
04 CURNAMEL PIC S9(4) COMP.
04 CURNAMEC PIC X(30).
01 CURNAME1 PIC X(30).
01 CURNAME2 REDEFINES CURNAME1.
02 CURNAME3 OCCURS 30 TIMES.
04 CURNAME0 PIC X(1).

*
* 1 DECLARE A RESULT SET LOCATOR VARIABLE FOR EACH RESULT
* SET THAT MIGHT BE RETURNED.
*
01 LOC-1 USAGE SQL TYPE IS

Chapter 9. Transferring Multiple Result Sets with Stored Procedures 171


RESULT-SET-LOCATOR VARYING.
01 LOC-2 USAGE SQL TYPE IS
RESULT-SET-LOCATOR VARYING.
01 LOC-3 USAGE SQL TYPE IS
RESULT-SET-LOCATOR VARYING.
01 LOC-4 USAGE SQL TYPE IS
RESULT-SET-LOCATOR VARYING.
01 LOC-5 USAGE SQL TYPE IS
RESULT-SET-LOCATOR VARYING.

* PARM TO RECEIVE THE SQLCODE ERROR MESSAGES


01 ERROR-MESSAGE.
02 ERROR-LEN PIC S9(4) COMP VALUE +960.
02 ERROR-TEXT PIC X(120) OCCURS 8 TIMES
INDEXED BY ERROR-INDEX.
77 ERROR-TEXT-LEN PIC S9(8) COMP VALUE +120.

77 ERR-CODE PIC 9(8) VALUE 0.


77 ERR-MINUS PIC X VALUE SPACE.
77 LINE-EXEC PIC X(20) VALUE SPACE.
77 FETCH-END PIC S9(8) COMP VALUE +0.
77 CUR-END1 PIC S9(8) COMP VALUE +0.
77 CUR-END2 PIC S9(8) COMP VALUE +0.

77 STOREPROC PIC X(8) VALUE ′ MR5BMS ′ .

*
* PASSED BY MR0BMCBM
LINKAGE SECTION.
01 LINKAREA-IND.
02 IND PIC S9(4) COMP OCCURS 750 TIMES.
01 LINKAREA-REC.
02 REC1-LEN PIC S9(8) COMP.
02 REC1-CHAR PIC X(1) OCCURS 1 TO 32700 TIMES
DEPENDING ON REC1-LEN.
01 LINKAREA-QMARK.
02 INDREC PIC X(1).

PROCEDURE DIVISION USING LINKAREA-IND LINKAREA-REC.


**************************
*
* SQL RETURN CODE HANDLING
*
**************************
EXEC SQL WHENEVER SQLERROR GOTO DBERROR END-EXEC.
OPEN OUTPUT REPORT-OUT.
**************************
*
* SET ADDRESS TO PASSED STORAGE FROM BBMMCMR0
*
**************************
SET IRECPTR TO ADDRESS OF REC1-CHAR(1).

CALL-STORED-PROCEDURE.
**************************
*
* 2 CALL THE STORED PROCEDURE MR5BMS AND CHECK THE SQL
* RETURN CODE FOR +466
*

172 Getting Started with DB2 Stored Procedures


**************************
EXEC SQL CALL :STOREPROC (:SQLC) END-EXEC.
DISPLAY ′ SQLC = ′ SQLC ′ ********′
IF SQLCODE = +466
PERFORM PROCESS-OUTPUT
ELSE
DISPLAY ″NO RESULT SETS RETURNED CALL 1 ″ .
PROG-END.
CLOSE REPORT-OUT.
GOBACK.

PROCESS-OUTPUT.
**************************
*
* 3 DETERMINE HOW MANY RESULT SETS THE STORED PROCEDURE IS
* RETURNING.
*
* SQLD WILL HAVE THE NUMBER OF RESULT SETS.
* SQLNAMEC() WILL HAVE THE STORED PROCEDURE CURSOR NAMES.
*
**************************
EXEC SQL DESCRIBE PROCEDURE :sTOREPROC INTO :SQLDA
END-EXEC.

**************************
*
* Loop through the cursor names so you can see what was
* passed back from the DESCRIBE PROCEDURE SQL statement.
*
**************************
MOVE SQLD TO CURSOR-N.
PERFORM SAVE-CUR-NAMES VARYING IDX-1
FROM 1 BY 1 UNTIL IDX-1 GREATER THAN SQLD
**************************
*
* 4 LINK RESULT SET LOCATORS TO RESULT SETS
*
**************************
EXEC SQL ASSOCIATE LOCATORS
(:LOC-1, :LOC-2, :LOC-3, :LOC-4, :LOC-5)
WITH PROCEDURE :STOREPROC
END-EXEC.
**************************
*
* CHECK TO SEE IF PROCEDURE RETURNED MORE RESULT SETS THAN YOU
* HAD LOCATORS FOR. IF SO YOU WILL GET A +494.
* 494, WARNING: PROCEDURE MR5BMS RETURNED 00000006 QUERY RESULT
* SETS
* THE OTHER LOCATORS WILL HAVE VALID ADDRESSES THAT YOU CAN
* PROCESS.
*
**************************
IF SQLCODE > 0 PERFORM DBERROR.

**************************
*
* 5 ALLOCATE CURSORS FOR EACH RESULT SET RETURNED FOR
* FETCHING ROWS.
*

Chapter 9. Transferring Multiple Result Sets with Stored Procedures 173


**************************
IF CURSOR-N >= 1
EXEC SQL ALLOCATE CURSOR1 CURSOR FOR RESULT SET
:LOC-1
END-EXEC
MOVE ′ CURSOR1′ TO CURSOR-NM
PERFORM DESCRIBE-CURSOR
MOVE 1 TO IDX-2
DISPLAY CURNAMEL(IDX-2) CURSOR-NM ″+++++″
MOVE CURNAMEC(IDX-2) TO CURNAME1
PERFORM PRINT-CUR-NAME
DISPLAY ″FETCH ROWS 1″ ″+++++″
PERFORM FETCH-ROWS-1 VARYING F FROM 1 BY 1 UNTIL
SQLCODE = +100
EXEC SQL CLOSE CURSOR1 END-EXEC
END-IF.
IF CURSOR-N >= 2
EXEC SQL ALLOCATE CURSOR2 CURSOR FOR RESULT SET
:LOC-2
END-EXEC
MOVE ′ CURSOR2′ TO CURSOR-NM
PERFORM DESCRIBE-CURSOR
MOVE 2 TO IDX-2
DISPLAY CURNAMEL(IDX-2) CURSOR-NM ″+++++″
MOVE CURNAMEC(IDX-2) TO CURNAME1
PERFORM PRINT-CUR-NAME
DISPLAY ″FETCH ROWS 2″ ″+++++″
PERFORM FETCH-ROWS-2 VARYING F FROM 1 BY 1 UNTIL
SQLCODE = +100
EXEC SQL CLOSE CURSOR2 END-EXEC
END-IF.
IF CURSOR-N >= 3
EXEC SQL ALLOCATE CURSOR3 CURSOR FOR RESULT SET
:LOC-3
END-EXEC
DISPLAY SQLNAMEC(3)
MOVE ′ CURSOR3′ TO CURSOR-NM
PERFORM DESCRIBE-CURSOR
MOVE 3 TO IDX-2
DISPLAY CURNAMEL(IDX-2) CURSOR-NM ″+++++″
MOVE CURNAMEC(IDX-2) TO CURNAME1
PERFORM PRINT-CUR-NAME
PERFORM FETCH-ROWS-3 VARYING F FROM 1 BY 1 UNTIL
SQLCODE = +100
EXEC SQL CLOSE CURSOR3 END-EXEC
END-IF.
IF CURSOR-N >= 4
EXEC SQL ALLOCATE CURSOR4 CURSOR FOR RESULT SET
:LOC-4
END-EXEC
MOVE ′ CURSOR4′ TO CURSOR-NM
PERFORM DESCRIBE-CURSOR
MOVE 4 TO IDX-2
DISPLAY CURNAMEL(IDX-2) CURSOR-NM ″+++++″
MOVE CURNAMEC(IDX-2) TO CURNAME1
PERFORM PRINT-CUR-NAME
PERFORM FETCH-ROWS-4 VARYING F FROM 1 BY 1 UNTIL
SQLCODE = +100
EXEC SQL CLOSE CURSOR4 END-EXEC

174 Getting Started with DB2 Stored Procedures


END-IF.
IF CURSOR-N >= 5
EXEC SQL ALLOCATE CURSOR5 CURSOR FOR RESULT SET
:LOC-5
END-EXEC
MOVE ′ CURSOR5′ TO CURSOR-NM
PERFORM DESCRIBE-CURSOR
MOVE 5 TO IDX-2
DISPLAY CURNAMEL(IDX-2) CURSOR-NM ″+++++″
MOVE CURNAMEC(IDX-2) TO CURNAME1
PERFORM PRINT-CUR-NAME
PERFORM FETCH-ROWS-5 VARYING F FROM 1 BY 1 UNTIL
SQLCODE = +100
EXEC SQL CLOSE CURSOR5 END-EXEC
END-IF.
IF CURSOR-N > 5
DISPLAY ″MORE THEN 5 RESULT SET RETURNED″ .

**************************
*
* 7 PERFORM PARAGRAPH TO FETCH THE ROWS FOR CURSOR ONE
*
**************************
FETCH-ROWS-1.
EXEC SQL FETCH CURSOR1 USING DESCRIPTOR :SQLDA END-EXEC.
IF SQLCODE = 0
PERFORM DISPLAY-RECORD.

FETCH-ROWS-2.
EXEC SQL FETCH CURSOR2 USING DESCRIPTOR :SQLDA END-EXEC.
DISPLAY ″END FETCH ROWS 2″ ″+++++″
IF SQLCODE = 0
PERFORM DISPLAY-RECORD.

FETCH-ROWS-3.
EXEC SQL FETCH CURSOR3 USING DESCRIPTOR :SQLDA END-EXEC.
IF SQLCODE = 0
PERFORM DISPLAY-RECORD.

FETCH-ROWS-4.
EXEC SQL FETCH CURSOR4 USING DESCRIPTOR :SQLDA END-EXEC.
IF SQLCODE = 0
PERFORM DISPLAY-RECORD.

FETCH-ROWS-5.
EXEC SQL FETCH CURSOR5 USING DESCRIPTOR :SQLDA END-EXEC.
IF SQLCODE = 0
PERFORM DISPLAY-RECORD.

**************************
* PERFORM PARAGRAPH TO DISPLAY THE RECORD RETURNED.
**************************
DISPLAY-RECORD.
* ADD IN MARKERS TO DENOTE NULLS.
MOVE ONE TO INDCOUNT.
DISPLAY ″PERFORM NULLCHK″ ″+++++″ SQLD
PERFORM NULLCHK UNTIL INDCOUNT > SQLD.
MOVE REC1-LEN TO REC01-LEN.

Chapter 9. Transferring Multiple Result Sets with Stored Procedures 175


PERFORM MOVE-REC1
VARYING J FROM 1 BY 1 UNTIL J > REC1-LEN.
WRITE REC01
AFTER ADVANCING 1 LINE.
ADD ONE TO ROWCOUNT.
DISPLAY ″PERFORM BLANK RECORD″ ″+++++″
PERFORM BLANK-REC.

**************************
* PERFORM PARAGRAPH TO DENOTE NULLS
**************************
NULLCHK.
IF IND(INDCOUNT) < 0 THEN
SET ADDRESS OF LINKAREA-QMARK TO WORKINDPTR(INDCOUNT)
MOVE QMARK TO INDREC.
ADD ONE TO INDCOUNT.

**************************
* PERFORM PARAGRAPH TO BLANK LINES
**************************
BLANK-REC.
MOVE ONE TO J.
PERFORM BLANK-MORE UNTIL J > REC1-LEN.
BLANK-MORE.
MOVE SPACE TO REC1-CHAR(J).
ADD 1 TO J.
* ONLY PRINT THE FIRST 127 CHARS.
MOVE-REC1.
MOVE REC1-CHAR(J) TO REC01-CHAR(J)
IF J = 127
MOVE REC1-LEN TO J.
**************************
* PERFORM PARAGRAPH TO MOVE CURSOR NAME TO REC1.
**************************
PRINT-CUR-NAME.
MOVE SPACE TO REC01.
MOVE ONE TO J.
PERFORM PRINT-CUR-NAME-MOVE UNTIL J > CURNAMEL(IDX-2).
MOVE CURNAMEL(IDX-2) TO REC01-LEN.
WRITE REC01 AFTER ADVANCING 1 LINE.
MOVE SPACE TO REC01.

PRINT-CUR-NAME-MOVE.
DISPLAY ′+++++ J′ CURNAME0(J) J.
MOVE CURNAME0(J) TO REC01-CHAR(J).
ADD 1 TO J.

**************************
*
* PERFORM PARAGRAPH TO DESCRIBE THE CURSOR FOR RESULT SET,
* AND SET UP THE ADDRESSES IN THE SQLDA FOR DATA.
*
**************************
DESCRIBE-CURSOR.
**************************
*
* 6 DETERMINE THE CONTENTS OF THE RESULT SETS.
* USE THE DESCRIBE CURSOR TO GET INFORMATION ON THE
* NUMBER OF COLUMNS, DATA TYPE.

176 Getting Started with DB2 Stored Procedures


*
**************************
EXEC SQL DESCRIBE CURSOR :CURSOR-NM INTO :SQLDA
END-EXEC.
DISPLAY ′ SQLD ′ SQLD ′ SQLN ′ SQLN .
PERFORM DIS-SQLDA-FIELDS VARYING IDX-1
FROM 1 BY 1 UNTIL IDX-1 GREATER THAN SQLD.

**************************
*
* SET UP THE ADDRESSES IN THE SQLDA FOR DATA.
*
**************************
MOVE ZERO TO ROWCOUNT.
MOVE ZERO TO REC1-LEN.
SET RECPTR TO IRECPTR.
MOVE ONE TO I.
PERFORM COLADDR UNTIL I > SQLD.

**************************
*
* PERFORM PARAGRAPH TO CALCULATE COLUMN LENGTH
*
* DETERMINE THE LENGTH OF THIS COLUMN (COLUMN-LEN)
* THIS DEPENDS UPON THE DATA TYPE. MOST DATA TYPES HAVE
* THE LENGTH SET; BY VARCHAR, GRAPHIC, VARGRAPHIC, AND
* DECIMAL DATA NEED TO HAVE THE BYTES CALCULATED.
* THE NULL ATTRIBUTE MUST BE SEPARATED TO SIMPLIFY MATTERS.
*
**************************
COLADDR.
SET SQLDATA(I) TO RECPTR.
MOVE SQLLEN(I) TO COLUMN-LEN.
* COLUMN-IND IS 0 FOR NO NULLS AND 1 FOR NULLS
DIVIDE SQLTYPE(I) BY TWO GIVING DUMMY REMAINDER COLUMN-IND.
* MYTYPE IS JUST THE SQLTYPE WITHOUT THE NULL BIT
MOVE SQLTYPE(I) TO MYTYPE.
SUBTRACT COLUMN-IND FROM MYTYPE.
* SET THE COLUMN LENGTH, DEPENDENT UPON DATA TYPE
EVALUATE MYTYPE
WHEN CHARTYPE CONTINUE,
WHEN DATETYP CONTINUE,
WHEN TIMETYP CONTINUE,
WHEN TIMESTMP CONTINUE,
WHEN FLOATYPE CONTINUE,
WHEN VARCTYPE
ADD TWO TO COLUMN-LEN,
WHEN VARLTYPE
ADD TWO TO COLUMN-LEN,
WHEN GTYPE
MULTIPLY COLUMN-LEN BY TWO GIVING COLUMN-LEN,
WHEN VARGTYPE
PERFORM CALC-VARG-LEN,
WHEN LVARGTYP
PERFORM CALC-VARG-LEN,
WHEN HWTYPE
MOVE TWO TO COLUMN-LEN,
WHEN INTTYPE
MOVE FOUR TO COLUMN-LEN,

Chapter 9. Transferring Multiple Result Sets with Stored Procedures 177


WHEN DECTYPE
PERFORM CALC-DECIMAL-LEN,
WHEN OTHER
PERFORM UNRECOGNIZED-ERROR,
END-EVALUATE.
ADD COLUMN-LEN TO RECNUM.
ADD COLUMN-LEN TO REC1-LEN.
**************************
*
* IF THIS COLUMN CAN BE NULL, AND INDICATOR VARIABLE IS
* NEEDED. WE ALSO RESERVE SPACE IN THE OUTPUT RECORD
* TO NOTE THAT THE VALUE IS NULL.
*
**************************
MOVE ZERO TO IND(1).
IF COLUMN-IND = ONE THEN
SET SQLIND(I) TO ADDRESS OF IND(I)
SET WORKINDPTR(I) TO RECPTR
ADD ONE TO RECNUM
ADD ONE TO REC1-LEN.
* INCREMENT INDEX I BY ONE
ADD ONE TO I.

**************************
* PERFORM PARAGRAPH TO CALCULATE COLUMN LENGTH
* FOR A DECIMAL DATA TYPE COLUMN
**************************
CALC-DECIMAL-LEN.
DIVIDE COLUMN-LEN BY 256 GIVING COLUMN-PREC
REMAINDER COLUMN-SCALE.
MOVE COLUMN-PREC TO COLUMN-LEN.
ADD ONE TO COLUMN-LEN.
DIVIDE COLUMN-LEN BY TWO GIVING COLUMN-LEN.

**************************
* PERFORM PARAGRAPH TO CALCULATE COLUMN LENGTH
* FOR A VARGRAPHIC DATA TYPE COLUMN
**************************
CALC-VARG-LEN.
MULTIPLY COLUMN-LEN BY TWO GIVING COLUMN-LEN.
ADD TWO TO COLUMN-LEN.

**************************
* PERFORM PARAGRAPH TO NOTE AN UNRECOGNIZED
* DATA TYPE COLUMN
**************************
DISPLAY ′ UNRECOGNIZED DATA TYPE FOR COLUMN ′
DISPLAY ′ SQLTYPE ′ SQLTYPE(I).
DISPLAY ′ SQLLEN ′ SQLLEN(I).
GO TO PROG-END.

9.2.10 SQLCODEs
In this section, we provide some of the SQLCODES that you may get. Some are specific to MRSP, and
some can also be received even if you are not using MRSP.
+494 The number of result set locators specified on the ASSOCIATE LOCATORS statement is less
than the number of result sets returned by the stored procedure. The first ″n″ result set
locator values are returned, where ″n″ is the number of result set locator variables specified
on the SQL statement.

178 Getting Started with DB2 Stored Procedures


-114 A three-part procedure name was provided for one of the following SQL statements:
• ASSOCIATE LOCATORS
• CALL
• DESCRIBE PROCEDURE
The first part of the SQL procedure name, which specifies the location where the stored
procedure resides, did not match the value of the SQL CURRENT SERVER special register.
Although you can use a three-part name for the stored procedure, you have to be connected
to the location where the stored procedure must be executed.
-204 No row was found in the SYSIBM.SYSPROCEDURES catalog table for this stored procedure.
You must add a row to the SYSIBM.SYSPROCEDURES catalog table to define the stored
procedure and issue the -START PROCEDURE command to activate the new definition.
-440 DB2 received an SQL CALL statement for a stored procedure. DB2 found the row in the
SYSIBM.SYSPROCEDURES catalog table associated with the requested procedure name.
However, the number of parameters supplied on the CALL statement does not match the
number of parameters defined in the PARMLIST column of the SYSIBM.SYSPROCEDURES
table. The definition of a stored procedure may be cached. If you suspect that this
message is being issued because the cached definition of a procedure does not match the
definition of a procedure in the SYSIBM.SYSPROCEDURES table, issue the -START
PROCEDURE command to refresh the cache.
-444 DB2 received an SQL CALL statement for a stored procedure and found the row in the
SYSIBM.SYSPROCEDURES catalog table associated with the requested procedure name.
However, the MVS load module identified in the LOADMOD column of the
SYSIBM.SYSPROCEDURES row could not be found.
-471 This SQLCODE is accompanied by a reason code. Check the reason code.
-496 The SQL statement cannot be executed because the current server is different from the
server that called a stored procedure. To correct the problem, you must connect to the
server that called the stored procedure which created the result set before running the SQL
statement that failed.
-499 An attempt was made to assign a cursor to a result set using the SQL statement ALLOCATE
CURSOR and one of the following applies:
• The result set locator variable specified in the ALLOCATE CURSOR statement has been
previously assigned to this cursor.
• The cursor name specified in the ALLOCATE CURSOR statement has been previously
assigned to a result set from the stored procedure.
-504 The cursor name was referenced in an SQL statement, and one of the following is true:
• The cursor name was not declared (using the DECLARE CURSOR statement) or
allocated (using the ALLOCATE CURSOR statement) in the application program before it
was referenced.
• The cursor name was referenced in a positioned UPDATE or DELETE statement which is
not a supported operation for an allocated cursor.
• The cursor name was allocated, but a CLOSE cursor statement naming this cursor was
issued and deallocated the cursor before this cursor reference.
• The cursor name was allocated, but a ROLLBACK operation occurred and deallocated
the cursor before this cursor reference.
• The cursor name was allocated, but its associated cursor declared in a stored
procedure was not declared WITH HOLD, and a COMMIT operation occurred and
deallocated the cursor before this cursor reference. The COMMIT operation can be

Chapter 9. Transferring Multiple Result Sets with Stored Procedures 179


either explicit (the COMMIT statement) or implicit (that is, a stored procedure defined as
COMMIT_ON_RETURN = ′ Y′ was called before this cursor reference).
• The cursor name was allocated, but its associated stored procedure was called again
since the cursor was allocated, new result sets were returned, and cursor cursor-name
was deallocated.
-751 A stored procedure issued an SQL operation that forced the DB2 thread to roll back the unit
of work. The SQL statement is not executed

9.3 Blocking Rows

In this section, we explain how to transfer multiple rows to the calling program by blocking them (see
Figure 84).

Figure 84. Blocking Rows. Renamed Client to TR0C2CC2 / Server TROC2S

Blocking rows involves complex coding, which can be summarized as follows:


1. The client allocates an SQLDA large enough to hold all expected results.
2. The stored procedure fetches the rows.
3. For each row, the stored procedure packs the fetched columns as one parameter, so that each
parameter corresponds to one row.
4. The stored procedure sends back to the client program as many parameters as the number of
rows it fetched.
There are variations of this method. For example, instead of setting up the SQLDA for the maximum
number of rows, you can set it up for batches of a specific number of rows. You can also use host
variables in the SQL CALL statement instead of setting up an SQLDA, although DB2 on the workstation
always presents an SQLDA to the stored procedure.

This method has several disadvantages:


• When writing your program, you have to know the maximum amount of data to be transferred from
the stored procedure to the client. For a SELECT statement, you have to know how many rows will

180 Getting Started with DB2 Stored Procedures


be returned. It is not always possible to estimate the maximum amount of data to be transferred
or the number of rows to be returned.
• As you size your SQLDA or host variables for the maximum amount of data expected, memory for
the structures is allocated each time you execute the programs. Memory is also allocated when
your stored procedure returns less than the maximum possible amount of data. Because this can
happen frequently, memory space is wasted.
• The grouping of data in the stored procedure and the eventual unpacking of the data blocks on the
client cause overhead in your programs.
• Coding of the client program and the stored procedure may be complex.
Although it is possible to return an undefined number of rows with this method, it is not appropriate for
stored procedures, so you may consider using the cursor in the main program.

Although we show here examples for the workstation, the concept is also valid for DB2 for MVS/ESA
and DB2 for OS/390.

The programs developed during this project to transfer mulitple rows are TR0C2CC2 and TR0C2S. Our
sample program calls the stored procedure by using an SQLDA. The stored procedure fetches 10 rows
from the STAFF table. Columns NAME, ID, and SALARY are fetched. To avoid having to transfer 30
different items (10 rows x 3 columns), for each row the three columns are grouped as a single
parameter. Thus only 10 parameters are sent back to the client program and are displayed on screen.

To execute the sample TR0C2CC2 client program, type:


tr0c2cc2 db_alias userid password

Ten rows from the staff table are displayed:


Name : Sanders Id : 10 Salary : 18357.50
Name : Pernal Id : 20 Salary : 18171.25
Name : Marenghi Id : 30 Salary : 17506.75
Name : O′ Brien Id : 40 Salary : 18006.00
Name : Hanes Id : 50 Salary : 20659.80
Name : Quigley Id : 60 Salary : 16808.30
Name : Rothman Id : 70 Salary : 16502.83
Name : James Id : 80 Salary : 13504.60
Name : Koonitz Id : 90 Salary : 18001.75
Name : Plotz Id : 100 Salary : 18352.80

9.3.1 The TR0C2CC2 Client


In the beginning of our client program we declare the host variables, the SQLCA and the SQLDA:
....
....
EXEC SQL BEGIN DECLARE SECTION;
char database[9];
char userid[9];
char passwd[19];
char procname[10] = ″tr0c2s″ ;
char data_item0[100] = ″ ″;
char data_item1[100] = ″ ″;
char data_item2[100] = ″ ″;
char data_item3[100] = ″ ″;
char data_item4[100] = ″ ″;
char data_item5[100] = ″ ″;
char data_item6[100] = ″ ″;

Chapter 9. Transferring Multiple Result Sets with Stored Procedures 181


char data_item7[100] = ″ ″;
char data_item8[100] = ″ ″;
char data_item9[100] = ″ ″;
short dataind0, dataind1, dataind2, dataind3, dataind4;
short dataind5, dataind6, dataind7, dataind8, dataind9;
EXEC SQL END DECLARE SECTION;

/* Declare Variables */
struct sqlca sqlca;
struct sqlda *inout_sqlda = NULL;
int cntr;
....
....

After obtaining the database alias, user ID, and password, the program connects to the database
server. Next, the program prepares the SQLDA to receive 10 rows, each with a data length of 100
characters. The data length of 100 was chosen arbitrarily; it would be enough to define a data length
sufficient to hold the three columns. The preparation proceeds as follows:
....
....
/* Allocate and Initialize Output SQLDA */
inout_sqlda = (struct sqlda *)malloc( SQLDASIZE(10) );
inout_sqlda->sqln = 10;
inout_sqlda->sqld = 10;

dataind0 = dataind1 = dataind2 = dataind3 = dataind4 = 0;


dataind5 = dataind6 = dataind7 = dataind8 = dataind9 = 0;

inout_sqlda->sqlvar[0].sqltype = SQL_TYP_NCSTR;
inout_sqlda->sqlvar[0].sqldata = data_item0;
inout_sqlda->sqlvar[0].sqllen = 101;
inout_sqlda->sqlvar[0].sqlind = &dataind0;

inout_sqlda->sqlvar[1].sqltype = SQL_TYP_NCSTR;
inout_sqlda->sqlvar[1].sqldata = data_item1;
inout_sqlda->sqlvar[1].sqllen = 101;
inout_sqlda->sqlvar[1].sqlind = &dataind1;
....
....
inout_sqlda->sqlvar[9].sqltype = SQL_TYP_NCSTR;
inout_sqlda->sqlvar[9].sqldata = data_item9;
inout_sqlda->sqlvar[9].sqllen = 101;
inout_sqlda->sqlvar[9].sqlind = &dataind9;
....
....

Once the SQLDA is initialized, the client program can call the TR0C2S stored procedure. When the
stored procedure ends, the 10 rows are transferred from the stored procedure to the client in the
SQLDA. To see the results on the screen, use the printf command:
....
....
EXEC SQL CALL :procname USING DESCRIPTOR :*inout_sqlda;
CHECKERR (″CALL WITH SQLDA″ ) ;

for (cntr = 0; cntr < 10; cntr++)


{
printf(″%s \n″ , inout_sqlda->sqlvar[cntr].sqldata);
}

182 Getting Started with DB2 Stored Procedures


....
....

After displaying the results, the client program ends.

9.3.2 The TR0C2S Stored Procedure


The TR0C2S stored procedure accepts the SQLDA and SQLCA structures passed by the client
application and declares the host and some other temporary variables required by the stored
procedure:
....
....
SQL_API_RC SQL_API_FN tr0c2s(void *reserved1,
void *reserved2,
struct sqlda *inout_sqlda,
struct sqlca *ca)
{
/* Declare a local SQLCA */
EXEC SQL INCLUDE SQLCA;

/* Declare Host Variables */


EXEC SQL BEGIN DECLARE SECTION;
char NAME[21] = { 0 };
short ID = 0;
double SALARY = 0;
short nameind = 0;
short idind = 0;
short salaryind = 0;
EXEC SQL END DECLARE SECTION;

/* Declare Miscellaneous Variables */


char sname[21] = { 0 };
int sid = 0;
float ssalary = 0;
int cntr;
char outline[80];
....
....

The stored procedure declares and opens a cursor. Next, it starts fetching data into the host variables:
....
....
EXEC SQL DECLARE C1 CURSOR FOR select name, id, salary from staff;

EXEC SQL OPEN C1;

for (cntr = 0; cntr < 10; cntr++)


{
/*******************************************************************/
/* First we make sure that all variables are cleared */
/*******************************************************************/
memset(sname, 0, sizeof(sname));
sid = 0;
ssalary = 0;
memset(outline, 0, sizeof(outline));

/*******************************************************************/
/* Fetch the data */

Chapter 9. Transferring Multiple Result Sets with Stored Procedures 183


/*******************************************************************/
EXEC SQL FETCH C1 INTO :NAME :nameind
, :ID :idind
, :SALARY :salaryind;
....
....

For each fetched row, the stored procedure does the following:
1. Checks whether the SQLCODE is 0.
2. Checks whether the received data is NULLS.
3. Copies the host variables to working variables.
4. Groups the three columns in a single character string in the outline variable.
5. Copies the outline variable to the SQLDA.

The process proceeds as follows:


....
....
switch (SQLCODE)
{
/******************************************************************/
/* SQLCODE == 0 means OK */
/* Next, we look at the sqlind values. If -1 the host variable has */
/* a NULL value and we just put a ′ -′ or ′ 0 ′ in the final string */
/******************************************************************/
case 0:
if (nameind < 0) strcpy(sname, ″-″ ) ;
else sprintf(sname, ″%s″, NAME);

if (idind < 0) sid = 0;


else sid = ID;

if (salaryind < 0) ssalary = 0;


else ssalary = SALARY;

sprintf(outline,
″Name : %-10s Id : %-5i Salary : %-10.2f ″ ,
sname, sid, ssalary);

break;
} /* End switch */

strcpy(inout_sqlda->sqlvar[cntr].sqldata,&outline);/* Copy to sqlda */

} /* End For */
....
....

To end, the stored procedure closes the cursor and copies the SQLCA information to the SQLCA
structure. Control is returned to the client program:
....
....
EXEC SQL CLOSE C1;

/* Return the SQLCA to the Calling Program */


memcpy( ca, &sqlca, sizeof( struct sqlca ) );

184 Getting Started with DB2 Stored Procedures


return(SQLZ_DISCONNECT_PROC);
....
....
If you know in advance how many columns and how many rows are expected from the stored
procedure, you can code the SQLDA to return as many parameters as the product of the number of
rows and the number of columns.

Chapter 9. Transferring Multiple Result Sets with Stored Procedures 185


186 Getting Started with DB2 Stored Procedures
Chapter 10. Coding Considerations for Windows

There are a number of choices for developing Windows applications that access DB2 database servers:
• Embedded SQL - Using this choice you can develop applications in the following programming
languages:
− C or C++
- Microsoft Visual C++ Version 1,5
- Borland C++ 4.0 or Version 4.5
− COBOL
- Micro Focus COBOL Version 3.1 or later.
• DB2 CLI
• IBM ODBC driver - Through the IBM ODBC driver, you can use applications that support the ODBC
specifications to access DB2 database servers. For example, you can develop Visual Basic
applications to access DB2 databases.
You can also use the following products, among others:
• IBM VisualAge C++ for Windows (Version 3 Release 5 is the current release)
• IBM VisualAge for COBOL for OS/2 and Windows (Version 2.0 and later)
• IBM JDBC driver (for Java applications).

10.1 ODBC Applications: Setting the Environment

Before an ODBC application can access a DB2 database server, you must perform the following steps:
1. Install the IBM ODBC driver.
Start a Windows session and run the following command:
x:\sqllib\win\bin\db2odbc
where x is the drive where CAE for Windows is installed.
In native Windows, this command accomplishes the following tasks:
• Installs the IBM ODBC driver
• Installs an icon to trigger the ODBC Administrator functions from the control panel of Windows.
(The Control Panel icon is on the Windows main panel.)
In Windows under OS/2 (WIN-OS/2), this command installs only the IBM ODBC driver. Select the
ODBC Installer icon from the IBM DATABASE 2 panel to install an icon that triggers the ODBC
administrator functions from the OS/2 desktop.
2. Catalog databases and nodes, employing one of the following methods:
• Use the DB2 client setup tool.
• Issue catalog commands from the command line processor.
3. Bind the ODBC driver files for each database you want to access. We recommend using the
DB2CLI.LST list file to bind the ODBC driver to each database you want to access through ODBC.
4. Register the database as a data source , employing one of the following methods:
• Use the DB2 client setup tool.
• Use the ODBC administration tool.

 Copyright IBM Corp. 1996 1998 187


• Edit the ODBC.INI file (Figure 85 on page 188).

[ODBC Data Sources]


SAMP2COZ=IBM DB2 ODBC DRIVER
DB41POK=IBM DB2 ODBC DRIVER
SAMP6000=IBM DB2 ODBC DRIVER

[SAMP2COZ]
Driver=C:\WINDOWS\SYSTEM\db2cliw.dll
Description=

[DB41POK]
Driver=C:\WINDOWS\SYSTEM\db2cliw.dll
Description=

[SAMP6000]
Driver=C:\WINDOWS\SYSTEM\db2cliw.dll
Description=

Figure 85. ODBC.INI File

Refer to Installing and Using DB2 Client for Windows for more information.

We used Visual Basic to develop our ODBC client application samples. Our Visual Basic sample
applications issue calls to ODBC APIs, which are routed by the ODBC driver manager to the IBM
ODBC driver, and then through CAE for Windows to a DB2 database server. If the DB2 database
server is a DRDA server, DDCS is required. See Figure 86 on page 189 for a description of our ODBC
working environment.

188 Getting Started with DB2 Stored Procedures


Figure 86. ODBC Working Environment

10.2 Visual Basic Considerations


You can call a DB2 on MVS stored procedure from a Windows workstation using an ODBC interface
product. Visual Basic interfaces with IBM′s ODBC software, which is called CLI , using a variety of
methods. One method is the direct API approach, in which the user codes all of the ODBC function
calls inside of the Visual Basic application. Another approach that works with Visual Basic Version 4 is
called Remote Data Objects (RDO), in which most of the ODBC function calls are issued under the
covers by Visual Basic. There are benefits and drawbacks to each approach.

The benefits for using the direct API approach are that the user has complete control over which ODBC
functions get called. This allows greater flexibility and maximizes the performance of the application.
The drawbacks are that the user has to code the ODBC calls and, with this approach, the user is
forced to handle Unicode conversions.

The main benefits of using RDO are that the ODBC function calls are not hard coded in the application,
are performed by Visual Basic, and Unicode conversions are performed automatically by Visual Basic.
While this may seem like the way to go, the drawback is that RDO issues a large number of ODBC
calls over which you have no control. Many of these calls can be unnecessary and their sheer
numbers can degrade application performance. To see all of the ODBC calls that Visual Basic issues
during an RDO session, turn on the CLI trace before running the program.

For diagnosing distributed data problems in applications that use IBM′s ODBC/CLI driver, turn on the
CLI trace just prior to running the application. This trace is highly readable. It shows the sequence of

Chapter 10. Coding Considerations for Windows 189


ODBC calls, the values passed in the arguments, and the return codes from each call. To turn on the
CLI trace, add the following to your \sqllib\db2cli.ini file:
[Common]
Trace=1
TraceFileName=x:\pathname\filename.ext
TraceFlush=1
You do not need to allocate the trace file ahead of time. If running under Microsoft Visual Basic, you
must close Visual Basic completely before trying to access the trace file. Each time you run a CLI
application, the new trace data gets appended to the bottom of the file. Set Trace=0 to turn the trace
off.

10.2.1 String Data Truncation


There can be many reasons for string data truncation. Several of the more common problems are
discussed here:
• Microsoft Visual Basic V4 introduced a new internal data format called Unicode, which can be
described as a double-byte representation of data. If you are using the RDO coding method,
Unicode conversion between platforms is handled automatically. However, if you are using a
direct API approach and you are not communicating with a Unicode-compatible server (most
database products return ASCII data, not Unicode) you will experience problems passing string
data out of (and retrieving it back into) the Visual Basic program. The string data will be corrupted
or not returned at all. There are coding techniques to deal with the problem.
• When you assign a literal string value to the rgbValue column of SQLBindParameter, make sure
that the literal string is no larger than the size of the column defined in the procedure definition on
the host. If the string is too large, the SQLExecute statement will fail and CLI will issue a
″CLI0109E String data right truncation″ message. If you are passing more than one string
parameter, you can turn on the CLI trace to see which parameter value is actually causing the
error.
• When binding string data-type parameters, do the following to avoid data truncation in
INPUT_OUTPUT values. Specify the cbColDef to be the length of the field as defined in the catalog
of the DB2 server. Specify cbValueMax to be one byte larger than cbColDef. Declare a variable
the size of cbValueMax to hold the rgbValue (string input/output data). This is necessary to
accommodate the null terminator at the end of the string data. For example, to pass a 4-byte
CHAR variable (called chardata ) as a parameter:
1. Declare chardata as character with a length of 5.
2. Move no more than 4 bytes of character data to chardata.
3. Declare pcbv as integer to hold the length value of pcbValue.
4. Set pcbv = SQL_NTS.
5. Call the SQLBindParameter function as follows:
ret = SQLBindParameter(sphndl, 1, SQL_PARAM_INPUT_OUTPUT,
SQL_C_CHAR, SQL_CHAR, 4, 0, chardata, 5, pcbv)

190 Getting Started with DB2 Stored Procedures


10.2.2 How Microsoft Visual Basic Unicode Affects the Client/Server
Unicode, introduced in Microsoft Visual Basic V4, causes string-data conversion problems when a
Visual Basic application issues certain ODBC calls to a server that returns ASCII data (such as DB2) to
the Visual Basic client. Visual Basic automatically converts ASCII to Unicode for applications that use
the RDO method of remote data access. However, if you are using a direct API coding method, you
must perform some data conversions in your Visual Basic application prior to invoking certain ODBC
function calls. For example:
• In the SQLBindParameter function:
When rgbValue contains string data, the data must be converted from ″String to Byte″ prior to
issuing the SQLBindParameter call. After the SQLExecute of the SQL statement that uses the
parameters, you must convert these same (now output) fields from ″Byte to String″ before you can
display them.
The following example demonstrates the input data conversion:
′ the following two byte variables are used to store the ASCII
′ representation of the string data

Dim message(21) As Byte


Dim sqlerrm(75) As Byte
Dim procret As Long
Dim query as String
Dim pcb1 as Long
Dim pcb2 as Long
Dim pcb3 as Long

query = ″CALL STORPROC(?,?,?)″

′ the following call statements convert the Unicode literals


′ to ASCII byte arrays
Call StringByte(″initialize message″, 21, message())
Call StringByte(″initialize sqlerrm″, 75, sqlerrm())

pcb1 = 4
pcb2 = SQL_NTS
pcb3 = SQL_NTS

ret = SQLBindParameter(spr03, 1, SQL_PARAM_INPUT_OUTPUT, SQL_C_LONG,


SQL_INTEGER, 0, 0, procret, 4, pcb1)
ret = SQLBindParameter(spr03, 2, SQL_PARAM_INPUT_OUTPUT, SQL_C_CHAR,
SQL_CHAR, 20, 0, message(0), 21, pcb2)
ret = SQLBindParameter(spr03, 3, SQL_PARAM_INPUT_OUTPUT, SQL_C_CHAR,
SQL_CHAR, 74, 0, sqlerrm(0), 75, pcb3)

Sub
StringByte(Data As String, ByteLen As Integer, return_buffer() As Byte)
Dim StrLen As Integer, Count As Integer
For Count = 0 To Len(Data) - 1
return_buffer(Count) = Asc(Mid(Data, Count + 1, 1))
Next Count
For Count = Len(Data) To ByteLen
return_buffer(Count) = 0
Next Count
End Sub
• After issuing an SQLPrepare and SQLExecute to execute the SQL call stored procedure statement,
you may want to display the output values in those same parameters. Before displaying these

Chapter 10. Coding Considerations for Windows 191


values, you must convert the CHAR parameters from byte back to string. This can be
accomplished with a built-in Visual Basic function (StrConv) as shown in the following example:
MsgBox (″procret parm = ″ & procret)
MsgBox (″message = ″ & StrConv(message(), vbUnicode))
MsgBox (″sqlerrm = ″ & StrConv(sqlerrm(), vbUnicode))

10.2.3 RDO Program and SQL_NO_DATA_FOUND Error on the ODBC


SQL_SETConnect
The rdoDefaultLoginTimeout property defaults to 15 seconds. It must be set to 0 for the IBM CLI/ODBC
driver or you will get an SQL_NO_DATA_FOUND error on the SQLSetConnect function call.

10.2.4 Result Sets Column Names


If the SELECT statements inside the stored procedure are static, then you must turn on the DESCSTAT
subsystem parameter to retrieve column names from your stored procedure results sets. Set the
subsystem parameter on the host DB2 where the procedure was compiled. You must rebind your SP
application packages after setting this subsystem parameter to pick up the changes.

If the SELECT statements inside of the stored procedure are dynamic, the result-set column names
should be returned automatically.

Note that string-data conversion does not apply to Visual Basic Version 3.

For more information about Visual Basic and stored procedure, check the following Web page:
http://www.software.ibm.com/data/db2/os390/cstips.html
You can download working examples for Visual Basic Version 4 and Version 5 from this Web page.

10.3 Sample ODBC Applications

In this section, we do not explain all of the commands that we coded in our Visual Basic applications.
Instead, we describe the commands and functions related to invoking a stored procedure in DB2
servers.

Table 11 shows the characteristics of our Visual Basic sample applications.

Table 11. Visual Basic Sample Applications


Client Application Name Database Server Stored Procedure Name Number of Parameters
VBWMSTS0 DB2 for MVS/ESA TS0BMS 2
VBW2STS0 DB2 for OS/2 BB22STS0 2

On the diskette, the code for VBWMSTS0 and VBW2STS0 are at Version 3 of Visual Basic and will not
work with Visual Basic Version 4 and Version 5.

The stored procedures and the parameters required to invoke the stored procedures on MVS and on
OS/2 are similar. Table 12 on page 193 shows the characteristics of the parameters used for both
client applications, for Visual Basic Version 4 and Version 5.

192 Getting Started with DB2 Stored Procedures


Table 12. Parameter Characteristics
Parameter SQL Data Type Data Length (bytes) Use
P1 Character 11 Send to stored
procedure
P2 Integer 4 Receive from stored
procedure

For Visual Basic Version 3, the data length of the parameter P1 is 10.

Our client applications prompt users to enter the name of the database server to which they want to
connect. The only difference between the applications is the procedure name specified in the SQL
CALL statement.

In the paragraphs that follow, we describe the structure of our ODBC program coded with Visual Basic.
In this example, we are using the direct API coding method.

10.3.1 Setting Variables


We declared, allocated, and initialized variables used in the program. Our program required variables
for the following purposes:
• Parameters passed to the stored procedure and sent back to the client program
• Return codes from ODBC
• ODBC requires variables to allocate the handles. Handles are pointers that address the data
objects where the application status information of connections, attributes, and statements is
located. You can obtain either detailed or basic diagnostic information by referencing handles. We
allocated the following handles:
− Environment handle
− Connection handle
− Statement handle
We defined three variables for this information.
• We chose to pass the SQL CALL statement as a string, instead of a constant in the SQLPrepare
function. We had to declare and intitialize a string variable for the SQL CALL statement.
• As we chose to pass the database name (in ODBC terms, the data source), user ID, and password
required in the CONNECT statement as variables. We needed three variables for this information.

10.3.2 Connecting to the Database Server


Before the preparation of the CALL statement, the application must be connected to a database server.
To connect to the server, we had to:
• Allocate the following handles using the handle variables we defined:
− Environment handle
− Connection handle
• Use the SQLConnect function to establish the connection.

Chapter 10. Coding Considerations for Windows 193


10.3.3 Calling the Stored Procedure
To invoke the SQL CALL statement through the SQLExecute function we had to:
• Allocate a statement handle for the SQL CALL statement.
• Use the SQLPrepare function to dynamically prepare our SQL CALL statement.
• Use the SQLBindParameter function to bind each of the parameters used by the stored procedure.
• Use the SQLExecute function to execute our prepared SQL CALL statement.

10.3.4 Other Functions


Although not directly related to invoking a stored procedure, our Visual Basic program performed
these other functions:
1. Checked return codes from ODBC calls. If there were errors, we invoked a routine to handle them.
2. We wanted the program to have control of the transaction, so we coded the program to explicitly
invoke the COMMIT and ROLLBACK statements, instead of opting for ODBC to auto commit after
the execution of each SQL statement.
3. Upon termination, freed the allocated resources.
Next, we describe the most relevant commands we coded in our Visual Basic applications.

10.3.5 Setting Variables


By setting variables we refer to the process required to declare, allocate, and initialize the variables
required for our Visual Basic applications. Below we describe how we set the most relevant variables
used by our applications, as explained in 10.3.1, “Setting Variables” on page 193.

10.3.5.1 Parameters Used by the Stored Procedure: We defined and initialized parameters
P1 and P2 as shown in Figure 87.

Dim P1 As String
Dim P2 As Long
P1 = ″W000D1C000″
P2 = 0

Figure 87. Define and Initialize Parameters Used by the Stored Procedure

10.3.5.2 Handle Variables: A typical ODBC application uses a set of handle variables to control
the execution of the ODBC functions invoked by the application. Using these variables, the application
can request the completion status information of each ODBC call as it is executed. These variables
were defined as shown in Figure 88.

Dim a_henv As Long


Dim a_hdbc As Long
Dim s_storedproc As Long

Figure 88. Defining Variables for Handles

10.3.5.3 Return Code Variable: Every ODBC function returns basic diagnostic information by
using a return code that can be received in a variable defined in your application. Figure 89 on
page 195 shows the return code variable we defined in our Visual Basic applications.

194 Getting Started with DB2 Stored Procedures


Dim ret As Integer

Figure 89. Defining a Return Code Variable

10.3.5.4 CONNECT Statement Variables: The CONNECT statement issued from our
application requires three parameters: database name, user ID, and password. We defined three
variables for the values of these parameters as shown in Figure 90.

Note: Our Visual Basic applications prompt the user to enter data for these parameters.

Dim DataSource As String


Dim User As String
Dim Password As String

Figure 90. Connection Variables

10.3.5.5 Setting a Variable for the CALL Statement: The CALL statement issued in our
Visual Basic applications is passed to the SQLPrepare function by means of a variable we named
Query . This variable was defined as follows:
Dim Query as String

See 10.3.7, “Calling the Stored Procedure” on page 196 for an explanation of the SQLPrepare function.

The content of the Query variable is initialized according to the stored procedure that the application
invokes and should follow certain rules according to the platform where the stored procedure is
located:

Calling the DB2 for MVS/ESA Stored Procedure: Application VBWMSTS0 invokes a DB2 for MVS/ESA
stored procedure named TS0BMS. The initialization of the Query variable is the following:
Query = ″CALL TS0BMS(?,?)″

Note that the stored procedure name must be in uppercase; otherwise DB2 for MVS/ESA returns an
SQLCODE -113.

Calling the DB2 for OS/2 Stored Procedure: Application VBW2STS0 invokes a DB2 for OS/2 stored
procedure named BB22STS0. The initialization of the Query variable is:
Query = ″CALL bb22sts0(?,?)″

Note that the stored procedure name is in lowercase. It can also be specified in uppercase, because
the name of the function that executes this stored procedure was exported to a DLL in uppercase. See
7.3, “Stored Procedure Preparation” on page 111 for more information about preparing a stored
procedure in DB2 for OS/2.

Each question mark represents a parameter marker, that is, an argument to be passed to the stored
procedure. Our Visual Basic applications pass two parameters to the stored procedure they invoke.

Refer to 8.4, “CLI and ODBC Applications” on page 127 for details on the SQL CALL statement.

Chapter 10. Coding Considerations for Windows 195


10.3.6 Connecting to a Database Server
Before preparing the SQL CALL statement, our Visual Basic applications had to connect to the DB2
database server. To connect to the database server, you must:
• Allocate the environment handle and the connection handle to control the execution of the ODBC
functions invoked in the application.
• Issue the SQLConnect function

To allocate these handles and then perform the CONNECT statement, our Visual Basic applications
invoked the ODBC functions shown in Figure 91.

ret=SQLAllocEnv(a_henv)
ret=SQLAllocConnect(a_henv, a_hdbc)
ret=SQLConnect(a_hdbc,DataSource,SQL_NTS,User,SQL_NTS,Password,SQL_NTS)

Figure 91. Allocating Handles and Connecting

• SQLAllocEnv allocates memory for the environment handle. This handle is used to control the
valid connection handles and the current active connection handles. This handle must be
requested before connecting to a data source.
In our Visual Basic applications, the name of this handle is a_henv.
• SQLAllocConnect allocates memory to control a particular connection. A connection handle must
be related to one environment handle. However, an environment handle can control multiple
connection handles. This handle must be requested before connecting to a data source.
In our Visual Basic applications, the name of this handle is a_hdbc.
• SQLConnect loads the driver required to pass ODBC calls to a specific database manager system
and establishes the connection to the data source. A reference to a connection handle is required
to keep track of the status, transaction state, and error information of this connection.
Database alias name, user ID, and password values are required to establish the connection.
These values are provided through the DataSource, User, and Password variables, respectively.

With the support for ODBC 3.0 APIs in DB2 Universal Database V5, some of the ODBC 2.0 APIs have
been removed. For a comprehensive list, refer to Appendix B “Migrating Applications” in DB2 UDB V5
Call Level Interface Guide and Reference . It has a table of CLI functions that should not be used for
UDB Version 5.

10.3.7 Calling the Stored Procedure


To issue the SQL CALL statement, our Visual Basic applications must:
• Allocate a statement handle that contains the information related to the execution status of the SQL
statement.
• Prepare the CALL statement before sending it to the database server for execution.
• Associate the parameter markers of the CALL statement with the parameter variables used to
exchange data with the stored procedure.
• Issue the SQLExecute function to send the CALL statement to the database server for execution.

Figure 92 on page 197 shows the statements we coded for these tasks.

196 Getting Started with DB2 Stored Procedures


Dim cbn As Long
Dim cb4 As Long

cbn=SQL_NTS
cb4=4

ret=SQLAllocStmt(a_hdbc,s_storedproc)

ret=SQLPrepare(s_storedproc,Query,SQL_NTS)

ret=SQLBindParameter(s_storedproc,1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,
10,0,P1,11,cbn)

ret=SQLBindParameter(s_storedproc,2,SQL_PARAM_OUTPUT,SQL_C_LONG,
SQL_INTEGER,0,0,P2,4,cb4)

ret=SQLExecute(s_storedproc)

Figure 92. Issuing the CALL Statement

These statements are described as follows:


• SQLAllocStmt allocates memory to control a particular SQL statement and associates a statement
with a connection. This handle is required to keep track of network information, error messages,
and specifics for the data source, cursor name, number of result columns or rows affected,
SQLSTATE values, and status information for SQL statement processing.
A statement handle must be related to one connection handle; however, a connection handle can
control multiple statement handles. In our Visual Basic applications, the name of the statement
handle is s_storedproc.
• SQLPrepare associates an SQL statement with a statement handle and sends the statement to the
server to be dynamically prepared for execution. In our Visual Basic applications, the SQL
statement is allocated in the Query variable.
• Bind parameter statement - The SQLBindParameter call is used to associate the parameter
markers in an SQL statement with either application variables or arrays, LOB locators, or the
parameters of a stored procedure CALL statement. This function must be related to a statement
handle.
Because our stored procedure has two parameters, we issued the SQLBindParameter call twice,
one for each parameter marker, as shown in Figure 92. An explanation of the SQLBindParameter
functions we called from our Visual Basic applications follows:
− Binding Parameter P1
ret=SQLBindParameter(s_storedproc,1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,
10,0,P1,11,cbn)
- Variable s_storedproc associates this SQLBindParameter with the s_storedproc statement
handle.
- 1 indicates that this is the bind parameter call for the first parameter marker of the SQL
CALL statement.
- SQL_PARAM_INPUT indicates that the actual data value for this parameter should be sent
to the server at execution time.
- SQL_C_CHAR indicates the C data type of this parameter.

Chapter 10. Coding Considerations for Windows 197


- SQL_CHAR indicates the SQL data type of this parameter.
- 10 is the parameter length defined at the server. Usually it is a column size. For stored
procedures, it is the expected parameter length.
- 0 is the scale of the parameter. Not applicable for a character variable.
- P1 indicates the name of the variable where the data value for this parameter is allocated.
For Visual Basic Versions 4 and 5, this is the Unicode converted data value as explained in
10.2.2, “How Microsoft Visual Basic Unicode Affects the Client/Server” on page 191.
- 11 is the length of the string being sent. For Visual Basic Version 3, the length is 10.
- cbn is a pointer indicating that the variable being sent is null terminated.
− Binding Parameter P2
ret=SQLBindParameter(s_storedproc,2,SQL_PARAM_OUTPUT,SQL_C_LONG,
SQL_INTEGER,0,0,P2,4,cb4)
- Variable s_storedproc associates this SQLBindParameter with the s_storedproc statement
handle.
- 2 indicates that this is the bind parameter call for the second parameter marker of the SQL
CALL statement.
- SQL_PARAM_OUTPUT indicates that this parameter receives data after the execution of the
stored procedure.
- SQL_C_LONG indicates the C data type of this parameter.
- SQL_INTEGER indicates the SQL data type of this parameter.
- 0 is the maximum length of the parameter. Ignored when SQL data type is SQL_INTEGER.
- 0 is the scale of the parameter. Not applicable.
- P2 indicates the name of the variable where the return value for this parameter is
allocated.
- 4 indicates the maximum number of bytes to hold when receiving data back from the stored
procedure.
- cb4 is a pointer indicating that the variable being sent is null terminated.
Refer to Call Level Interface Guide and Reference for Common Servers for further details on this
statement.
• SQLExecute executes a prepared statement, using the current values of the parameter marker
variables, if any parameter markers exist in the statement. The values of parameter markers must
be bound to variables before executing this statement. The statement must be associated with a
statement handle, which in our Visual Basic applications is s_storedproc.

10.3.8 Error Handling and Status Checking of ODBC Functions


The calls to ODBC functions we coded in our applications are preceded by ret=, where ret is the
variable we defined to receive the return code of the calls to ODBC functions.

Every call to ODBC has specific return code values that you should always check to control the
execution of your application. An error during execution time can be caused by an error at bind time,
which is difficult to debug if you do not check the return code during bind time. For example, to check
the return code of the SQLExecute call, we coded the Visual Basic instruction shown in Figure 93 on
page 199.

198 Getting Started with DB2 Stored Procedures


if (ret = SQL_ERROR) Then
Call giveerrmsg(a_storedproc, ″Error on SQLExec of Stored Proc″ )
End if

Figure 93. Checking ODBC Return Codes

This conditional instruction checks whether the completion code of the SQLExecute returned a
function-failed state. In this case, the program calls the error routine shown in Figure 94.

Sub giveerrmsg (s_hstmt As Long, ErrMsg As String)


Dim ErrText1 As String
Dim ErrText2 As String
Dim ErrNum1 As Long
Dim rc As Integer
ErrText1 = Space$(SQL_MAX_MESSAGE_LENGTH)
ErrText1 = Space$(10)
rc=SQLError(a_henv,a_hdbc,s_hstmt, ErrText2, ErrNum1, ErrText1,
SQL_MAX_MESSAGE_LENGTH, ErrNum2) ′ No splitting in Visual Basic
MsgBox (ErrMsg)
MsgBox (ErrText2)
MsgBox (ErrText2)
MsgBox (″Native Error Code:″ & ErrNum1)
MsgBox (ErrText1)

Figure 94. Sample Visual Basic Error Routine

SQLError is a function to return the diagnostic information about both errors and warnings associated
with the most recently invoked ODBC function for a particular statement, connection, or environment
handle.

10.3.9 Transaction Control


A transaction is a group of SQL statements that can be treated as one atomic operation. All SQL
operations within the group are guaranteed to be completed (committed) or undone (rolled back) as if
they were a single operation.

Every connection in an ODBC application can be set to perform commit processing manually or
automatically. Manual processing implies that the scope of a transaction must be controlled by the
application; that is, the application must explicitly issue commit or rollback operations required.

Automatic commit processing treats each SQL statement as a single, complete transaction. Thus, the
scope of a transaction is a single SQL statement automatically committed after its completion.
Automatic commit is recommended for read applications.

Because our stored procedures perform write operations, we decided to use manual commit in order
to have explicit control over the transaction.

We used the SQLSetConnecOption to set the commit mode of our connection. This function was coded
as follows:

ret=SQLSetConnectOption(a_hdbc, SQL_AUTOCOMMIT, 0)
where
• a_hdbc is the name of the connection handle.
• SQL_AUTOCOMMIT is the name of the commit mode attribute.

Chapter 10. Coding Considerations for Windows 199


• 0 sets the commit mode to off, indicating that explicit coding of the commit and rollback operations
is performed.

Having set the commit mode to off, we were able to explicitly commit or roll back. We coded the
commit operation in the following way:
ret=SQLTransact(a_henv,a_hdbc, SQL_COMMIT)

This call executes commit processing for all the changes to the database since connect time or the
previous call to SQLTransact, whichever is the most recent event. Here, a_henv is the environment
handle for this statement, and a_hdbc is its connection handle. It associates the commit operation with
the connection where commit processing should occur.

We coded the rollback operation in the following way:


ret=SQLTransact(a_henv,a_hdbc, SQL_ROLLBACK)

This call executes rollback processing for all changes to the database since connect time or the
previous call to SQLTransact, whichever is the most recent event. Again, a_henv is the environment
handle for this statement, and a_hdbc is its connection handle. It associates the rollback operation
with the connection where rollback processing should occur.

10.3.10 Program Termination


It is good practice to free allocated resources and disconnect from the database server when the
program terminates or after an error has been detected. The allocated resources usually consist of
data areas identified by unique handles.

Figure 95 shows the functions we used to free our allocated handles and disconnect from the database
server.

ret=SQLFreeStmt(s_storedproc, SQL_DROP)
ret=SQLDisconnect(a_hdbc)
ret=SQLFreeConnect(a_hdbc)
ret=SQLFreeEnv(a_henv)

Figure 95. Freeing Handles

SQLFreeStmt stops processing associated with a specific statement, closes any open cursors, discards
pending results, and optionally frees all resources associated with the statement handle. In this
example, we free the s_storedproc statement handle. SQL_DROP indicates that all resources
associated with s_storedproc should be freed.

SQLDisconnect closes the connection associated with a specific connection handle. In this example,
we close the connection associated with the a_hdbc connection handle.

SQLFreeConnect releases a connection handle and frees all memory associated with the handle. In
this example, we release the a_hdbc connection handle.

SQLFreeEnv frees the environment handle and releases all memory associated with the handle. You
should issue SQLDisconnect with error checking to close all active connections before issuing
SQLFreeEnv. If there is an active connection, SQLFreeEnv fails. In this example, we free the a_henv
environment handle.

With the support for ODBC 3.0 APIs in DB2 Universal Database V5, some of the ODBC 2.0 APIs have
been removed. For a comprehensive list, refer to Appendix B “Migrating Applications” in DB2 UDB V5

200 Getting Started with DB2 Stored Procedures


Call Level Interface Guide and Reference . It has a table of CLI functions that should not be used for
UDB Version 5.

10.4 CLI Applications

Figure 96 on page 202 shows the C source code of our sample CLI application.

Chapter 10. Coding Considerations for Windows 201


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include ″sqlcli.h″
#include ″sqlcli1.h″
#include ″samputil.h″
#define MAX_STMT_LEN 255
/* Setting Variables */ 1
SQLCHAR server[SQL_MAX_DSN_LENGTH + 1];
SQLCHAR uid[MAX_UID_LENGTH + 1];
SQLCHAR pwd[MAX_PWD_LENGTH + 1];
int
main( int argc, char * argv[] )
{
SQLHENV henv;
SQLHDBC hdbc;
SQLRETURN rc;
SQLHSTMT hstmt;
/*--> SQLL1X42.SCRIPT */
SQLCHAR stmt[] = ″CALL CCMMNOR0(?,?,?,?,?,?,?,?,?,?,?)″ ;
/*<-- */

SQLCHAR P1[] = {″W000D1C000″ } ;


SQLCHAR P2[] = {″W000I0000120″ };
SQLCHAR P3[72];
SQLCHAR P4[360];
SQLCHAR P5[45];
SQLCHAR P6[15];
SQLCHAR P7[90];
SQLCHAR P8[105];
SQLSMALLINT P9;
SQLCHAR PA[24];
SQLCHAR PB[78];
/* macro to initalize server, uid and pwd */
INIT_UID_PWD;
rc = SQLAllocEnv(&henv); 2
if (rc == SQL_ERROR) 10
return (terminate(henv, rc));
rc = DBconnect(henv, &hdbc); 3
if (rc == SQL_ERROR)
return (terminate(henv, rc));
rc = SQLAllocStmt(hdbc, &hstmt); 4
CHECK_DBC(hdbc, rc);
rc = SQLPrepare(hstmt, stmt, SQL_NTS); 5
CHECK_STMT(hstmt, rc);
/* Associating variables with parameters */ 6

rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,


10, 0, P1, 10, NULL);
CHECK_STMT(hstmt, rc);
rc = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,
180, 0, P2, 180, NULL);
CHECK_STMT(hstmt, rc);
rc = SQLBindParameter(hstmt, 3, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_CHAR,
72, 0, P3, 72, NULL);

Figure 96 (Part 1 of 2). CLI Sample Application

202 Getting Started with DB2 Stored Procedures


CHECK_STMT(hstmt, rc);
rc = SQLBindParameter(hstmt, 4, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_CHAR,
360, 0, P4, 360, NULL);
CHECK_STMT(hstmt, rc);
rc = SQLBindParameter(hstmt, 5, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_CHAR,
45, 0, P5, 45, NULL);
CHECK_STMT(hstmt, rc);
rc = SQLBindParameter(hstmt, 6, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_CHAR,
15, 0, P6, 15, NULL);
CHECK_STMT(hstmt, rc);
rc = SQLBindParameter(hstmt, 7, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_CHAR,
90, 0, P7, 90, NULL);
CHECK_STMT(hstmt, rc);
rc = SQLBindParameter(hstmt, 8, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_CHAR,
105, 0, P8, 105, NULL);
CHECK_STMT(hstmt, rc);
rc = SQLBindParameter(hstmt, 9, SQL_PARAM_OUTPUT, SQL_C_SHORT,
SQL_SMALLINT, 2, 0, &P9, 2, NULL);
CHECK_STMT(hstmt, rc);
rc = SQLBindParameter(hstmt,10,SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_CHAR,
24, 0, PA, 24, NULL);
CHECK_STMT(hstmt, rc);
rc = SQLBindParameter(hstmt, 11, SQL_PARAM_OUTPUT, SQL_C_CHAR,SQL_CHAR,
78, 0, PB, 78, NULL);
CHECK_STMT(hstmt, rc);
rc = SQLExecute(hstmt); 7
/* Ignore Warnings */
if (rc != SQL_SUCCESS_WITH_INFO) 10
CHECK_STMT(hstmt, rc);
rc = SQLTransact(henv, hdbc, SQL_COMMIT); 8
CHECK_DBC(hdbc, rc);
/* Deallocate handles and disconnect */ 9
rc = SQLFreeStmt(hstmt, SQL_DROP);
CHECK_STMT(hstmt, rc);
printf(″Disconnecting .....\n″ ) ;
rc = SQLDisconnect(hdbc);
CHECK_DBC(hdbc, rc);
rc = SQLFreeConnect(hdbc);
CHECK_DBC(hdbc, rc);
rc = SQLFreeEnv(henv);
if (rc != SQL_SUCCESS)
terminate(henv, rc);
return (SQL_SUCCESS);
}; /* end main */

Figure 96 (Part 2 of 2). CLI Sample Application

Below we describe the statements coded in the application.


• Setting variables 1
Declare, allocate, and initialize variables for the stored procedure parameters, handles, return
code, SQL CALL statement string, and the CONNECT statement arguments.
• Connecting to a database server - Before preparing the CALL statement, the application performs
the following tasks:
− Allocates the environment handle. 2.
− Allocates the connection handle and connects to a database server. 3
Note that DBconnect is a sample utility function that performs both the SQLAllocConnect and
the SQLConnect. This function is in the samputil.c file included in the sample application.
• Calling the stored procedure - In preparation for calling the stored procedure, the application
performs the following tasks:

Chapter 10. Coding Considerations for Windows 203


− Allocates a statement handle for the SQL CALL statement. 4.
− Sends the SQL CALL statement to the database server for preparation. 5.
− Associates the parameter variables with the arguments of the stored procedure. 6.
The SQLBindParameter function used in this application uses the argument NULL as opposed to
SQL_NTS used in the Visual Basic applications, as explained in 10.3.7, “Calling the Stored
Procedure” on page 196.
NULL indicates that the value provided through the variable associated with this parameter (P1,
for example) is always provided as null-terminated.
− Executes the SQLExecute function to send the CALL statement to the database server for
execution. 7.
• Other functions
− The application issues a COMMIT statement to explicitly control the current transaction. 8.
In our Visual Basic applications, we had to set the commit mode to zero to explicitly control the
scope of our transaction. Refer to 10.3.9, “Transaction Control” on page 199 for further
information.
The DBConnect function sets the commit mode to zero.
Instead of setting the commit mode to zero in our CLI application, we modified the
AUTOCOMMIT keyword of the DB2CLI.INI file to set it to zero, although you should not rely on
the DB2CLI.INI file, and instead you should specify your requirements explicitly.
Note that AUTOCOMMIT 1 is the default and that the commit mode is related to the data
source, which is DB41POK in our case. Figure 97 on page 205 shows a sample DB2CLI.INI file.
− The application deallocates the handles and disconnects from the database server. 9.
− The application is coded with error handling statements to control its execution. 10.

204 Getting Started with DB2 Stored Procedures


; Comment lines start with a semi-colon.

[TSTCLI1X]
uid=userid
pwd=password
autocommit=0
TableType=″ ′ TABLE′ , ′ VIEW′ , ′ SYSTEM TABLE′ ″

[TSTCLI2X]
; Assuming dbalias2 is a database in DB2 for MVS.
SchemaList=″ ′ OWNER1′ , ′ OWNER2′ , CURRENT SQLID″

[MYVERYLONGDBALIASNAME]
dbalias=dbalias3
SysSchema=MYSCHEMA

[SAMP6000]
SYSSCHEMA=SYSIBM
Description=

[SAMP2COZ]
Description=

[DB41POK}
AUTOCOMMIT=0

Figure 97. The DB2CLI.INI File

10.5 PowerBuilder

Different types of DB2 stored procedures call for different techniques from a PowerBuilder client. We
describe three different approaches for three different scenarios:
• No result sets (using output parameters, available in DB2 V4 and later)
• Single result sets (DB2 for OS/390 V5 or later)
• Multiple result sets (DB2 for OS/390 V5 or later)

Our application requester (AR) runs DB2 Connect Personal Edition on Windows 95. We did the
following:
1. Installed PowerBuilder Enterprise 5.0 using the Custom setup option to request ODBC drivers:
a. From the setup options, click on the Custom check box.
b. On the Products Available window, select PowerBuilder and click on the Detail button.
c. Click on the ODBC drivers check box to select it as shown in Figure 98 on page 206

Chapter 10. Coding Considerations for Windows 205


Figure 98. Specify ODBC Drivers During PowerBuilder Install

2. Rebooted after successful install.


3. Applied Maintenance Release 5.0.02 for Intel.

Our application server (AS) runs DB2 for OS/390 V5 on OS/390 R4. Communication is using TCP/IP.

We first write our stored procedure on OS/390 running DB2 for OS/390 V5. We insert a row in
SYSIBM.SYSPROCEDURES for each stored procedure with COMMIT_ON_RETURN set to ′ Y′.

We then code the client programs, allowing for the COMMIT_ON_RETURN settings of the stored
procedure. Familiarity with creating an application using PowerBuilder is assumed.

10.5.1 Configuring CLI/ODBC


There are fixes for some known problems with ODBC applications. Follow these instructions to check
if any of these fixes are applicable. You can also use the Client Configuration Assistant (CCA) to
specify CLI/ODBC services such as traces. We assume that the target databases have already been
defined. If they have not yet been defined, add them using CCA and then configure CLI/ODBC. The
steps are these:
1. Invoke Client Configuration Assistant (CCA) from DB2 for Windows 95.
2. Highlight the target database as shown in Figure 99 on page 207 (DSGCT in our case).

206 Getting Started with DB2 Stored Procedures


Figure 99. Update Database Properties Using CCA

3. Click on the Properties... push button.


4. Select the check box for Register this database for ODBC. The radio button for As a system data
source is selected by default as shown in Figure 100.

Figure 100. Select CLI/ODBC Settings for a Database

5. Click on Settings.
6. Click on No to connect (we are updating the local CLI/ODBC configuration file and therefore do not
need a connection for this).
7. Click on the Advanced push button in CLI/ODBC Settings as shown in Figure 101 on page 208.

Chapter 10. Coding Considerations for Windows 207


Figure 101. Invoke CLI/ODBC Advanced Settings

8. Select the Service tab in the CLI/ODBC Settings - Advanced Settings window
9. From here you can choose the different tabs (such as Service where you can specify CLI/ODBC
trace options). Refer to Chapter 4 “DB2 CLI/ODBC Configuration Keyword Listing” in the IBM DB2
UDB Call Level Interface Guide and Reference .
If a CLI/ODBC application is accessing DB2, these changes will not be in effect in that application
until it is restarted.
If you work with more than one DB2 database (in PowerBuilder terms) / data source, you will need
to perform the same actions for each one.
10. Click on the OK push button to get back to the CLI/ODBC Settings window.
11. Click on the OK push button to return to Database Properties.
12. You should get a message box saying that the database list has been successfully updated. Click
on the OK push button.
Your db2cli.ini file has now been updated.
13. Edit the pbibm050.ini file. Change PBSupportDBBind=′ YES′ .
14. Edit the db2cli.ini file to add the following line for the DB2 data source:
[DSGCT]
..
.
PATCH2=1
PATCH2 specifies using work-arounds for known problems with CLI/ODBC applications.

10.5.2 PowerBuilder Client Using Parameters - No Result Sets


For stored procedures that do not return result sets, here is a step-by-step guide to define the stored
procedure for your application:
1. Click on Appl on the PowerBar.
2. Click on User Obj on the PowerBar.
3. Click on the New push button in the Select User Object window as shown in Figure 102 on
page 209.

208 Getting Started with DB2 Stored Procedures


Figure 102. Select User Object

4. Select Standard for Class in the New User Object window and click on the OK push button as
shown in Figure 103.

Figure 103. Create New User Object: Standard Class

5. Select transaction in the Types list box on the Select Standard Class Type window and click on the
OK push button as shown in Figure 104 on page 210.

Chapter 10. Coding Considerations for Windows 209


Figure 104. Select Standard Class Type: Transaction

6. Click on the Declare pull-down menu on the action bar.


7. Select Local External Functions as shown in Figure 105.

Figure 105. Declare Local External Function

8. You are prompted to log on if a connection to your database (location) is not already established.
9. Click on the Procedures push button in the Declare Local External Functions window.
10. Select the stored procedure of your choice from the scroll down and click on OK on the Remote
Stored Procedure(s) window as shown in Figure 106 on page 211.

210 Getting Started with DB2 Stored Procedures


Figure 106. Select Stored Procedure from List Box

11. PowerBuilder shows you how the transaction is declared. You will see something like:
subroutine ORDSTATX (string P1,ref string P2,ref string P3,ref long P4,
ref string P5) RPCFUNC ALIAS FOR ″ORDSTATX″
12. Click on File and save this User Object. For example we save it as irww_procedures. The
message “User Object - irww_procedures inherited from transaction” appears in the title of the
User Object Painter.
13. To use this User Object, associate it with the Variable Type SQLCA:
a. Click on Appl on the PowerBar.
b. Position mouse pointer on the Appl object and click mouse button 2.
c. Select Properties.
d. Select the Variable Types tab.
e. Currently “transaction” is associated with SQLCA..
f. Overtype the entry field with irww_procedures to associate it with SQLCA.
Your program can now call irww_procedures.
Check it!
In previous releases of PowerBuilder, it was necessary to modify the declaration by adding
alias proc-name for proc-name
where proc-name is the name of the stored procedure you selected.

The script shown in Figure 107 on page 212 is for the clicked event tied to a CommandButton which
we labeled RUN.

Chapter 10. Coding Considerations for Windows 211


 
string P1
string P2
string P3
long P4
string P5

P2 = SPACE(79)
P3 = SPACE(435)
P4 = 0
P5 = SPACE(78)

P1 = sle_warehouse.text+sle_district.text+sle_cid.text+sle_clast.text 1

SQLCA.ORDSTATX(P1, P2, P3, P4, P5) 2

IF (SQLCA.sqlcode < 0) THEN 3


mle_errormsg.text = SQLCA.sqlerrtext
ROLLBACK;
RETURN
END IF;

If P4 >= 0 THEN
// Process Parameter P2 4
sle_cid.text=mid(P2,1,4)
sle_cfirst.text=mid(P2,5,16)
sle_cmiddle.text=mid(P2,21,2)
sle_clast.text=mid(P2,23,16)
sle_balance.text=mid(P2,39,12)
sle_date.text=mid(P2,51,19)
sle_orderid.text=mid(P2,70,8)
sle_carid.text=mid(P2,78,2)

// Process Parameter P3
sle_ordid1.text=mid(P3,1,6)
sle_swid1.text=mid(P3,7,4)
sle_quantity1.text=mid(P3,11,2)
sle_amount1.text=mid(P3,13,7)
sle_delivery1.text=mid(P3,20,10)
..
.
sle_ordid15.text=mid(P3,407,6)
sle_swid15.text=mid(P3,413,4)
sle_quantity15.text=mid(P3,417,2)
sle_amount15.text=mid(P3,419,7)
sle_delivery15.text=mid(P3,426,10)

mle_errormsg.text=P5
ELSE
mle_errormsg.text=P5
ROLLBACK;
END IF
RETURN
 
Figure 107. PowerScript Sample: Process Stored Procedures Using Parameters

212 Getting Started with DB2 Stored Procedures


1 The input from different SingleLineEdit controls is concatenated into P1. Our stored procedure
parameters are as follows:
P1 : Input parameters - 26 bytes
W_ID Char(4) Warehouse id
D_ID Char(2) District id
C_ID Char(4) Customer id (may be blank)
C_LAST Char(16) Cust. last name (if id blank)
P2 : Customer/order information - 79 bytes
C_ID Char(4)
C_FIRST Char(16)
C_MIDDLE Char(2)
C_LAST Char(16)
C_BALANCE Char(12) (nnnnnnnnn.nn)
out_date Char(19) (yyyy-mm-dd-hh.mm.ss)
O_ID Char(8)
O_CARRIER_ID Char(2)
P3 : Order line information - 29 bytes (up to 15 times)
OL_I_ID Char(6)
OL_SUPPLY_W_ID Char(4)
OL_QUANTITY Char(2)
OL_AMOUNT Char(7)
OL_DELIVERY_D Char(10)
P4 : RC Procedure return code
P5 : ERRMSG Status/error message

Other parameters (P2 to P5) are for output and are initialized just before this line.

2 The stored procedure ORDSTATX is called with parameters passed.

3 and 4 For SQLCODE indicating success, the returned parameters are “unpacked” into the various
SingleLineEdit and MultiLineEdit controls. We pick a nonnegative SQLCODE because stored
procedures with results sets will come back with SQLCODE=+466. We do not code any commit in the
client code because the stored procedure is set up to COMMIT_ON_RETURN.

If we did not have COMMIT_ON_RETURN we would have to code a COMMIT for a successful CALL.
IF (SQLCA.sqlcode < 0) THEN
mle_errormsg.text = SQLCA.sqlerrtext
ROLLBACK;
RETURN
ELSE
COMMIT;
END IF;

10.5.3 PowerBuilder Client for Single Result Set


Single and multiple result sets require different techniques. For a single result set, PowerBuilder
automatically handles data scrolling in the DataWindow control. This redbook includes two working
samples of PowerBuilder applications. Although you will not be able to execute them (because the
host part is not included), it should give you an idea of how the stored procedures are called from
PowerBuilder.

To code for a single result set client, we create a DataWindow control for our stored procedure:
1. Create a new DataWindow Object.
2. Choose Stored Procedures as data source.
3. Choose a Presentation Style (for example, tabular).
4. Select the appropriate stored procedure.

Chapter 10. Coding Considerations for Windows 213


Next, create a new DataWindow control in the application window and associate our new DataWindow
Object with it:
1. On the application window, click on Controls.
2. Select DataWindow.
3. Place the mouse pointer where you want the DataWindow positioned in the application window and
click mouse button 1. A new DataWindow control is created.
4. With the mouse pointer still on the DataWindow, click mouse button 2.
5. Select Properties.
6. Click on the Browse button to list the DataWindow Object that you have just created. This
associates the DataWindow control with the DataWindow Object.

Our example in query3.pbl is actually inherited from another window, as shown in Figure 108

Figure 108. How a DataWindow Object Is Related to a DataWindow Control

Figure 109 on page 215 shows the fields of the DataWindow for the execute_query12.

214 Getting Started with DB2 Stored Procedures


Figure 109. Design of w_main_window_1

To see how a PowerBuilder Script is used (for example, for the Execute command button of the
“execute_query12” of our application window), follow these steps:
1. Click on the Application Painter button on the PowerBar.
2. Click on File on the menu bar.
3. Select Open and open our sample file, query3.pbl.
4. In the Select Application dialog box, choose query3 and click on OK.
5. Click the Window button on the PowerBar.
6. From the Select Window dialog, scroll down the list box and select w_main_window_1 (because
w_qry12 is inherited from w_main_window_1) and click on OK. w_main_window_1 appears in the
Workspace.
7. Place the cursor over the Execute button in the Workspace and click on mouse button 2
8. Select Script to look at the PowerScript that drives this application. Figure 110 shows our
PowerScript.

 
string input_values
int numrows
input_values = mle_input1.text
dw_1.SetTransObject(SQLCA) // 1
sle_numrows.text = string(dw_1.Retrieve(input_values)) // 2
IF (SQLCA.sqlcode < 0) THEN
mle_errormsg.text = SQLCA.sqlerrtext
sle_sqlcode.text = string(SQLCA.SQLDBCode) + ″ / ″ + string(SQLCA.sqlcode)
ROLLBACK;
RETURN
END IF;
sle_sqlcode.text = string(SQLCA.SQLDBCode) + ″ / ″ + string(SQLCA.sqlcode)
 
Figure 110. Code Fragment for Single Result Set

Chapter 10. Coding Considerations for Windows 215


1 Tells the dw_1 DataWindows to look in the SQLCA transaction object for the values of the database
variables. Each transaction object has associated properties related to the application and the data
source to which it connects.

2 Use the Retrieve function in PowerScript to obtain the number of rows retrieved.

To see how DataWindow d_qry12 relates to the stored procedure, we look at the sample provided in
the accompanying diskette:
1. Select DataWindow d_qry12.
2. Click on Design from the menu bar.
3. Select Data Source.
4. Click on the More > > button. Figure 111 shows this DataWindow using stored procedure
USRT001.QRY12.

Figure 111. Modify Result Set Description for qry12

5. Click on Arguments to specify retrieve arguments.

10.5.4 PowerBuilder Client for Multiple Result Set


We can examine how the single result set example is modified into a client calling a stored procedure
to retrieve two result sets. Figure 112 on page 217 shows how the window is put together. Most of
the controls are inherited from w_main_window_1 except for DataWindow dw_2. Both of them are tied
to the same DataWindow object. Figure 112 on page 217 shows the fields of the DataWindow for the
execute_query22.

216 Getting Started with DB2 Stored Procedures


Figure 112. Design of w_qry22

Before opening any new file, make sure all files are closed). Then,
1. Click on the Application Painter button on the PowerBar.
2. Click on File on the menu bar.
3. Select Open and open our sample file, query3.pbl.
4. In the Select Application dialog box, choose query3 and click on OK.
5. Click on the Window button on the PowerBar.
6. From the Select Window dialog, scroll down the list box and select w_qry22 and click on OK.
w_qry22 appears in the Workspace.
7. Place the cursor over the Execute button in the Workspace and click on mouse button 2.
8. Select Script to look at the PowerScript that drives this application. Figure 113 on page 218 shows
our PowerScript.

Chapter 10. Coding Considerations for Windows 217


 
string input_values
string MSG
string ERRMSG
string firstname
string lastname
string P3
int numrows
int RC
int retcode
int count1=0
int count2=0
int P2

RC = 0
mle_errormsg.text = ″″
sle_sqlcode.text = ″″
ERRMSG = space(78)

input_values = mle_input1.text

DECLARE QRY22 PROCEDURE FOR QRY22


P1 = :input_values,
P2 = :RC,
P3 = :ERRMSG ; // 1

execute QRY22;

sle_sqlcode.text = string(SQLCA.SQLDBCode) + ″ / ″ + string(SQLCA.sqlcode)

IF (SQLCA.sqlcode < 0) THEN


mle_errormsg.text = SQLCA.sqlerrtext
sle_sqlcode.text = string(SQLCA.SQLDBCode) + ″ / ″ + string(SQLCA.sqlcode)
ROLLBACK;
close QRY22;
END IF;

fetch QRY22 into :firstname, :lastname;


do while sqlca.sqlcode=0
count1 = count1 + 1
dw_1.Object.compute_0001[count1] = firstname // 2
dw_1.Object.compute_0002[count1] = lastname
fetch QRY22 into :firstname, :lastname;
loop

fetch QRY22 into :firstname, :lastname;


do while sqlca.sqlcode=0
count2 = count2 + 1
dw_2.Object.compute_0001[count2] = firstname
dw_2.Object.compute_0002[count2] = lastname
fetch QRY22 into :firstname, :lastname;
loop

sle_numrows.text = string(count1 + count2)


close QRY22;
 
Figure 113. Code Fragment for Multiple Result Sets

218 Getting Started with DB2 Stored Procedures


1 Declaring the stored procedure

2 Assigning results to output areas in a DataWindow. With a single result set, PowerBuilder handles
the scrolling of data. With multiple result sets, the scrolling has to be done in the code. Both
DataWindows are using the same DataWindow object, so the field names (compute_0001 and
compute_0002) are identical.

To see how DataWindow d_qry22 relates to the stored procedure, follow these steps:
1. Select DataWindow d_qry22.
2. Click on Design from the menu bar.
3. Select Data Source.
4. Click on the More > > button.
5. Figure 114 shows this DataWindow is using stored procedure USRT001.QRY22.

Figure 114. Modify Result Set Description for qry22

6. Click on Arguments to specify retrieve arguments and the window shown in Figure 115 is shown.

Figure 115. Specify Retrieve Arguments

Chapter 10. Coding Considerations for Windows 219


10.6 C Applications

Developing a client application with C does not differ from the development of other database C
applications.

In this section, we describe some considerations related to the platform where the stored procedures
are located:
• DB2 for MVS/ESA
− The length of the string variable used to hold the stored procedure name must be 254
characters or less; otherwise the precompilation step fails with a -312 SQLCODE.
− If the client application is going to send a null indicator, the stored procedure linkage
characteristic in the LINKAGE column of SYSIBM.SYSPROCEDURE must be set to N to indicate
that the stored procedure can accept nulls. Otherwise the stored procedure fails with a -470
SQLCODE.
See 2.3.1.1, “SYSIBM.SYSPROCEDURES Table Columns” on page 14 for a description of the
SYSIBM.SYSPROCEDURES catalog table.
• DB2 Common Servers
− The length of the string variable used to hold the stored procedure can be longer than 254
characters.
− No special action is required to receive nulls in the stored procedures of DB2 Common
Servers.

220 Getting Started with DB2 Stored Procedures


Chapter 11. CLI on DB2 Version 5

In this chapter, we show you how to implement a CLI application and present some techniques for
problem determination. For the sample presented in this chapter, we use OS/390 C/C++ V2R4. The
JCL samples provided by the DB2 for OS/390 V5 Call Level Interface Guide and Reference contain
detailed descriptions and instructions regarding DB2 CLI. The JCL examples in this chapter relate to
OS/390 and C/C++ Optional Features V2R4. They differ from those in current DB2 publications, which
document IBM C/C++ for MVS/ESA Version 3 Release 1.

11.1 Introduction to CLI

Application ODBC programs written for DB2 Common Server V2, DB2 Universal Database V5, or other
RDBMS that support ODBC can be ported to the OS/390 platform. You can write and execute
applications across different platforms, accessing the various members of the DB2 family with fewer
coding differences. You can also port existing ODBC applications written for the workstation to OS/390
and exploit the many powerful features which can only be found on OS/390 such as its robustness and
its security.

To use CLI, you have to write your application in C or C++ program languages, which support DLLs.

11.2 Implementing CLI

To use CLI, make sure the following APARS/PTFs are applied in your DB2 for OS/390 V5 environment:
• PQ02582 fixes missing SDSNSAMP member DSNTIJCL
• PQ07001/UQ08548
• PQ06894/UQ11231 enables stored procedures to read CLI INI file
Before using CLI, you have to bind the CLI packages at the server (DB2 for OS/390 V5 in our case).
During the bind process of CLI on DB2 for OS/390 V5, you can ignore the BIND PACKAGE warnings for
DSNCLINC related to ISOLATION(NC). DB2 for OS/390 V5 provides this package because some DBMS
support isolation NC. Similarly, if you are binding to a DB2 for OS/390 V5 subsystem, warnings related
to SYSIBM.SYSLOCATIONS can be ignored because this table has been renamed to
SYSIBM.LOCATIONS in Version 5. The SYSIBM.SYSLOCATION table is referred in the CLI pacakges
because a remote DB2 Version 4 can act as a DRDA application server. “Configuring CLI and Running
Sample Applications” in the DB2 for OS/390 V5 Call Level Interface Guide and Reference lists in detail
each step required to set up CLI.

11.3 How to Invoke a Stored Procedure

To invoke a stored procedure using CLI, we prepared the CALL statement with parameter markers and
bind the markers with SQLBindParameter(). 8.4, “CLI and ODBC Applications” on page 127 describes
the syntax for the CALL statement.

 Copyright IBM Corp. 1996 1998 221


11.3.1 Multiple Result Sets
Unlike a COBOL, PLI, Assembler, or FORTRAN client application you don′t have to code the new
ASSOCIATE LOCATORS or ALLOCATE CURSOR statements. You could use ASSOCIATE LOCATORS
statements in a C program using embedded SQL. However, you don′t need to, because CLI has a
built-in set of callable functions that can be used instead

For reference, a copy of mrspcli.c from the DB2 UDB CLI samples is included on the diskette to
illustrate how to obtain rows from a result set.

Use SQLMoreResults() to examine if there are more result sets associated with a handle.

11.3.2 Executing the Client Program


When executing a client program, you must use a physical sequential (DSORG=PS) file or a member
in a partition data set (DSORG=PO) to store the CLI initialization file. The use of SYSIN DD * for the
CLI initialization file DSNAOINI is not supported. If you use in-stream data for the DSNAOINI file, as
follows:
//GO.DSNAOINI DD *
you may encounter the following memory overlay problems during the SQLFreeEnv:
EDC6006E The raise() function was issued for the signal SIGABRT.
From entry point CLI_memFree(void**,CLI_LISTINFO*) at compile
unit offset +0000017E at address 09DB84D6

This does not apply to stored procedures because you cannot use in-stream data in the JCL procedure
to start the stored procedures address space.

11.4 Coding the Stored Procedure


To code the stored procedure, you must consider the following factors:
• Null Connection
The null connection is implemented specifically for CLI stored procedures as a way to get the
database connection handle. This is not strictly a CONNECT statement, which is not allowed in
stored procedures. The following is an example of a null connection:
SQLConnect(hdbc, NULL, 0, NULL, 0, NULL, 0);
• Do not COMMIT or ROLLBACK from a stored procedure
We cannot COMMIT or ROLLBACK from a stored procedure and therefore cannot code
SQLTransact(). Turn autocommit off using the SQLSetConnectOption() API. This prevents an
implicit COMMIT.

11.4.1 Receiving Parameters


CLI programs are written in C or C++ because these languages can use DLLs. CLI programs receive
parameters just like their embedded SQL counterparts in C and C++:
• For a main program, CLI uses the argc and argv passed to main().
• A subprogram will be the same as a C/C++ subprogram as shown in DB2 for OS/390 Version 5
Application Programming and SQL Guide , except for an addition of:

#include <sqlcli1.h>
to pick up the CLI header file

222 Getting Started with DB2 Stored Procedures


− instead of an EXEC SQL INCLUDE SQLCA you can use
#include <sqlca.h>

Refer to 11.12.3, “CLI Stored Procedure Coding Considerations” on page 240 for a detailed description
of a main CLI stored procedure that returns a single result set and passes a parameter with indicator.

11.4.2 Result Sets


Refer to 11.12.3, “CLI Stored Procedure Coding Considerations” on page 240 for a detailed description
of a main CLI stored procedure that returns a single result set and passes a parameter with indicator.

11.5 Precompile/Bind Requirements


CLI programs issue SQL by calling the CLI driver, which issues the SQL on your behalf If you only
issue CLI calls, you don′t have to precompile and bind your program. If you issue embedded SQL calls
in addition to CLI calls, then you do have to precompile and bind your application.

11.6 Compiling

CLI programs need to:


• Include the CLI header file sqlcli.h which resides in DSN510.SDSNC.H.
• Use the DLL compile option, which instructs the compiler to produce DLL code.
• Be written and link-edited to execute with AMODE(31)

You need to use the DB2 precompiler only if your CLI program uses embedded SQL.

The DLL code can EXPORT or IMPORT functions and external variables. Specifying DLL defaults to
DLL(NOCBA) requires compile options of RENT and LONGNAME. The OS/390 C/C++ compiler
enables RENT and LONGNAME automatically when you specify DLL. Table 13 shows the C and C++
compiler options.

T a b l e 1 3 . C / C + + Compiler Options
Option C C++
Default NODLL(NOCBA) DLL(NOCBA)

Unlike C++, C compilations default to compile option NODLL(NOCBA). So you have to explicitly
specify the DLL compile option for C programs in to IMPORT the CLI DLLs.

You can either use the existing C and C++ compile JCL procedures using overrides and symbolics,
or customze your own JCL procedure based on the JCL procedure shipped with the C and C++
compilers. These JCLs are found in member EDCC (for C) and CBCC (for C++) of the CBC.SCBCPRC
library.

An example of using EDCC for C compile follows:


// JCLLIB ORDER=CBC.SCBCPRC
// SET SOURCE=SG244693.SAMPLES.SOURCE * Source
// SET OBJLIB=SG244693.SAMPLES.OBJ * Object
// SET MEM=SR1OMS
//DOCB EXEC PROC=EDCC,INFILE=&SOURCE.(&MEM),
// CPARM=′ OPTFILE(DD:CCOPT)′ 1
//COMPILE.SYSLIN DD DISP=SHR,DSN=&OBJLIB.(&MEM.)
//COMPILE.CCOPT DD * 2

Chapter 11. CLI on DB2 Version 5 223


DLL 3
RENT
LONGNAME
NOMARGINS
SOURCE
SE(′ CEE.SCEEH.+′ , ′ CBC.SCLBH.+′ , ′ DSN510.SDSNC.+′ ) 4
LSE(′ SG244693.SAMPLES.+′ ) 5
//

In the above example, we direct the C compiler to read the CCOPT DD statement 2 using the
OPTFILE option 1. This file can be in-stream or it can refer to a data set.

In the CCOPT file, we specify DLL, RENT, and LONGNAME 3.

The SEARCH option 4 directs the preprocessor to look for system-include files in the specified
libraries. System-include files are those file associated with the #include <filename> format of the
#include C/C++ preprocessor directive. We include the DB2 header file library.

The LSEARCH option 5 directs the preprocessor to look for the user-include files (#include
″filename″) in the specified libraries.

For more information on C/C++ compile options, refer to OS/390: C/C++ User ′ s Guide , SC09-2361.

CLI programs need to be prelinked because they are compiled with the DLL, RENT and LONGNAME
options.

In Figure 116 we made a copy of the procedure EDCC to pass the desired parameters for the compiler.
We put the options file into a data set, simplifying the invoking JCL significantly because there is no
need to specify overrides.

 .. 
.
// CREGSIZ=′ 4M′ , < COMPILER REGION SIZE
// CRUN=, < compiler run-time options
// CPARM=′ OPTFILE(DD:CCOPT)′ 1
// CPARM2=′ NOMARGINS SOURCE′ , < compiler options
// CPARM3=, < COMPILER OPTIONS
..
.
//C EXEC PGM=CBCDRVR,COND=(4,LT,PC),REGION=&CREGSIZ.,
// PARM=(′&CRUN/&CPARM &CPARM2 &CPARM3′ )
//CCOPT DD DISP=SHR,DSN=MY.OWN.OPTIONS 2
..
.
 
Figure 116. C/CLI Compile: JCL Fragment Showing Parameters

You can also avoid using OPTFILE by specifying the USERLIB (replacing LSEARCH) and SYSLIB
(replacing SEARCH) DD statements. Figure 117 on page 225 is an example of a JCL procedure that
can be used to compile a CLI program:

224 Getting Started with DB2 Stored Procedures


//********************************************************************
//* COMPILE A C / CLI PROGRAM *
//* OS/390 C/C++ *
//* RELEASE LEVEL: 02.04.00 (VERSION.RELEASE.MODIFICATION LEVEL) *
//********************************************************************
//*
//CLIC PROC MEM=, < Member name 1
// CREGSIZ=′ 4M′ , < COMPILER REGION SIZE
// CRUN=, < COMPILER RUNTIME OPTIONS
// CPARM=′ DLL RENT LONGNAME′ , < Required for CLI 2
// CPARM2=′ NOMARGINS SOURCE′ , < COMPILER OPTIONS 3
// CPARM3=, < COMPILER OPTIONS
// LIBPRFX=′ CEE′ , < PREFIX FOR LIBRARY DSN
// LNGPRFX=′ CBC′ , < PREFIX FOR LANGUAGE DSN
// CLANG=′ EDCMSGE′, < NOT USED IN THIS RELEASE. KEPT FOR COMPATIBILITY
// DCB80=′ ( RECFM=FB,LRECL=80,BLKSIZE=3200)′ , <DCB FOR LRECL 80
// DCB3200=′ ( RECFM=FB,LRECL=3200,BLKSIZE=12800)′, <DCB FOR LRECL 3200
// TUNIT=′ VIO′ , < UNIT FOR TEMPORARY FILES
//*
// APPLHDR=SG244693.SAMPLES.H, * Appl C header
// DB2CH=DSN510.SDSNC.H, * DB2 C header files
// OBJLIB=SG244693.SAMPLES.OBJ, * Object
// SOURCE=SG244693.SAMPLES.SOURCE * Source
//*
//* COMPILE STEP:
//*-------------------------------------------------------------------
//COMPILE EXEC PGM=CBCDRVR,REGION=&CREGSIZ, 4
// PARM=(′&CRUN/&CPARM &CPARM2 &CPARM3′ ) 5
//STEPLIB DD DSNAME=&LIBPRFX..SCEERUN,DISP=SHR
// DD DSNAME=&LNGPRFX..SCBCCMP,DISP=SHR
//SYSMSGS DD DUMMY,DSN=&LNGPRFX..SCBC3MSG(&CLANG),DISP=SHR
//SYSIN DD DISP=SHR,DSN=&SOURCE.(&MEM.) 6
//USERLIB DD DISP=SHR,DSN=&APPLHDR. 7
//SYSLIB DD DSN=&LIBPRFX..SCEEH.H,DISP=SHR
// DD DSN=&LIBPRFX..SCEEH.SYS.H,DISP=SHR
// DD DISP=SHR,DSN=&DB2CH. 8
//SYSLIN DD DISP=SHR,DSN=&OBJLIB.(&MEM.) 9
//SYSPRINT DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//SYSCPRT DD SYSOUT=*
//SYSUT1 DD UNIT=&TUNIT.,SPACE=(32000,(30,30)),DCB=&DCB80
//SYSUT4 DD UNIT=&TUNIT.,SPACE=(32000,(30,30)),DCB=&DCB80
//SYSUT5 DD UNIT=&TUNIT.,SPACE=(32000,(30,30)),DCB=&DCB3200
//SYSUT6 DD UNIT=&TUNIT.,SPACE=(32000,(30,30)),DCB=&DCB3200
//SYSUT7 DD UNIT=&TUNIT.,SPACE=(32000,(30,30)),DCB=&DCB3200
//SYSUT9 DD UNIT=&TUNIT.,SPACE=(32000,(30,30)),
// DCB=(RECFM=VB,LRECL=137,BLKSIZE=882)
//SYSUT10 DD SYSOUT=*
//SYSUT14 DD UNIT=&TUNIT.,SPACE=(32000,(30,30)),
// DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800)

Figure 117. JCL Procedure to Compile a CLI Program

Notes for Figure 117:


• 1 and 6 specify the program source.
• 1 and 9 specify the output of the compilation: the object module.

Chapter 11. CLI on DB2 Version 5 225


• The compiler options required by CLI 2 and those requested by user 3 are set once and for all
and passed to the compiler 5.
• The name for the compiler for OS/390 R4 4 differs from the one in C/C++ for MVS V3R1 (which
is in the DB2 for OS/390 V5 Call Level Interface Guide and Reference ).
• 7 USERLIB and 8 SYSLIB specify where the user and system header files are located.

The diskette provides a sample JCL procedure DB2HCCLI for compiling C using CLI. This procedure
invokes the DB2 precompiler, but because there is no embedded SQL it returns a condition code of 4
and continues.

11.7 Prelinking and Link-editing

Prelink is required for:


• C++ code.
• C code that is compiled with the RENT, LONGNAME, DLL, or IPA compiler options.
• Applications compiled to run under OpenEdition.

Therefore, you need to prelink CLI applications.

For object modules containing DLL code (C++ code, or C code compiled with the DLL compiler
option), the prelinker:
• Generates a function descriptor (linkage section) in writable static for each DLL-referenced
function.
• Generates a variable descriptor (linkage section) for each unresolved DLL-referenced variable.
• Generates an IMPORT control statement in the SYSDEFSD data set for each exported function and
variable.
• Generates internal information for the load module that describes which symbols are exported and
which symbols are imported from other load modules.
• Combines static DLL initialization information.

Refer to O S / 3 9 0 : C / C + + U s e r ′ s Guide for more details. For prelink and link-edit, we customized the
JCL procedure based on the member CBCL of the CBC.SCBCPRC library as shown below:
//********************************************************************
//* *
//* PRELINK AND LINK A C CLI PROGRAM, BASED ON CBC.SCBCPRC(CBCL) *
//* *
//* OS/390 C/C++ *
//* *
//* RELEASE LEVEL: 02.04.00 (VERSION.RELEASE.MODIFICATION LEVEL) *
//* *
//********************************************************************
//*
//CLIL PROC MEM=, 1
// LIBPRFX=′ CEE′ , < PREFIX FOR LIBRARY DSN
// CLBPRFX=′ CBC′ , < PREFIX FOR CLASS LIBRARIES
// PLANG=′ EDCPMSGE′ , < PRE-LINKER MESSAGE NAME
// PREGSIZ=′2048K′ , < PRE-LINKER REGION SIZE
// PPARM=′ MAP,NOER′ , < PRE-LINKER OPTIONS
// LPARM=′ AMODE=31,MAP,RENT′ , < LINKAGE EDITOR OPTIONS
// TUNIT=′ VIO′ , < UNIT FOR TEMPORARY FILES
//* 2
// DB2MACS=DSN510.SDSNMACS, * DB2 macros etc
// LOADLIB=SG244693.SAMPLES.LOAD.SPAS, Appl load lib - SPAS
// OBJLIB=SG244693.SAMPLES.OBJ * Object

226 Getting Started with DB2 Stored Procedures


//*
//*-------------------------------------------------------------
//* PRE-LINKEDIT STEP:
//*-------------------------------------------------------------
//PLKED EXEC PGM=EDCPRLK,REGION=&PREGSIZ,
// PARM=′&PPARM′
//STEPLIB DD DSN=&LIBPRFX..SCEERUN,DISP=SHR
//SYSMSGS DD DSN=&LIBPRFX..SCEEMSGP(&PLANG),DISP=SHR
//SYSLIB DD DSN=&LIBPRFX..SCEECPP,DISP=SHR
//SYSIN DD DISP=SHR,DSN=&OBJLIB.(&MEM.) 3
// DD DSN=&CLBPRFX..SCLBSID(ASCCOLL),DISP=SHR 4
// DD DSN=&CLBPRFX..SCLBSID(IOSTREAM),DISP=SHR
// DD DSN=&CLBPRFX..SCLBSID(COMPLEX),DISP=SHR
//* DD DSN=&CLBPRFX..SCLBSID(APPSUPP),DISP=SHR before OS390 R3
//* DD DSN=&CLBPRFX..SCLBSID(COLLECT),DISP=SHR before OS390 R3
// DD DSN=&DB2MACS.(DSNAOCLI),DISP=SHR * IMPORT CLI 5
// DD DDNAME=SYSIN2 6
//SYSMOD DD DSN=&&PLKSET,UNIT=&TUNIT.,DISP=(NEW,PASS),
// SPACE=(32000,(30,30)),
// DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200)
//SYSDEFSD DD DUMMY 7
//SYSOUT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSIN2 DD DUMMY 8
//*
//*-------------------------------------------------------------------
//* LINKEDIT STEP:
//*-------------------------------------------------------------------
//LKED EXEC PGM=HEWL,REGION=1024K,COND=(8,LE,PLKED),
// PARM=′&LPARM′
//SYSLIB DD DSN=&LIBPRFX..SCEELKED,DISP=SHR
//SYSLIN DD DSN=*.PLKED.SYSMOD,DISP=(OLD,DELETE)
// DD DDNAME=SYSIN
//SYSLMOD DD DISP=SHR,DSN=&LOADLIB.(&MEM.) 9
//SYSUT1 DD UNIT=&TUNIT.,SPACE=(32000,(30,30))
//SYSPRINT DD SYSOUT=*
//SYSIN DD DUMMY

Notice that AMODE(31) is specified.

Notes: 1 and 2 are symbolics we have added to simplify the invoking JCL. The object 3 is the
input to prelink. Notice that as of OS/390 R3 ASCCOLL 4 replaces APPSUPP and COLLECT. The four
class libraries were:
• The I/O stream class library
• The complex mathematics class library
• The application support class library (replaced by ASCCOLL)
• The collection class library (replaced by ASCCOLL)
Refer to OS/390: C/C++ IBM Open Class Library User ′ s Guide , SC09-2363 for more information.

For a CLI program, the prelink step needs DSN510.SDSNMACS(DSNAOCLI) 5 to IMPORT statements
used for CLI during prelinking. If the application uses other DLLs (such as our sample SR1OMS), you
can use the SYSIN2 6 / 8. DD statement to specify where the IMPORT statements are kept.

9 points to where the output of the link should go.

7 is a DUMMY for the definition side-deck (SYSDEFSD). The prelinker generates a definition
side-deck if you are prelinking an application that exports external symbols for functions and variables

Chapter 11. CLI on DB2 Version 5 227


(a DLL). You must provide this side-deck to any user of your DLL. The user of the DLL must prelink
the side-deck of the DLL with their other object modules.

Our sample utility V2SUTIL exports symbols and we kept the side-deck for SR1OMS which uses
V2SUTIL. These IMPORTs are required because we ported the sample from AIX to the S/390 platform.

We used the following JCL to invoke the compiler and the prelink/link:
// JCLLIB ORDER=SG244693.SAMPLES.JCL
//*
//COMPILE EXEC CLIC,MEM=SR1OMS
//PRELINK EXEC CLIL,MEM=SR1OMS,COND=(4,LT)
//PLKED.SYSIN2 DD *
IMPORT CODE ′ V2SUTIL′ check_error
IMPORT CODE ′ V2SUTIL′ print_connect_info
IMPORT CODE ′ V2SUTIL′ print_error
IMPORT CODE ′ V2SUTIL′ print_results
IMPORT CODE ′ V2SUTIL′ terminate
IMPORT DATA ′ V2SUTIL′ DSNCNM
IMPORT DATA ′ V2SUTIL′ DSNPNM
IMPORT DATA ′ V2SUTIL′ SQLTEMP
//
Note that the prelink/link is executed only if the compiler returns a condition code less than 4.

11.8 SYSIBM.SYSPROCEDURES

For the stored procedure to use the correct CLI packages, the COLLID column in the
SYSIBM.SYSPROCEDURES table must be the same as the collection ID of the CLI packages.
Otherwise, DB2 returns a -805 SQLCODE. The default collection ID is DSNAOCLI. Note also, that as
for other local client applications, the CLI package must be included in the plan of the client
application.

Since a CLI stored procedure is written in either C or C++, the LANGUAGE column in
SYSPROCEDURES must be C.

The rest of the columns obey the same rules as for non-CLI stored procedures described in 2.3.1.1,
“SYSIBM.SYSPROCEDURES Table Columns” on page 14.

11.9 Stored Procedure Address Space Requirements

Besides the usual stored procedure address space requirements, we need to include the CLI
initialization (INI) file. Figure 118 on page 229 is a JCL example for a DB2-established stored
procedure address space.

228 Getting Started with DB2 Stored Procedures


 
//DBC1SPAS PROC RGN=0K,TME=1440,SUBSYS=DBC1,NUMTCB=1 1
//IEFPROC EXEC PGM=DSNX9STP,REGION=&RGN,TIME=&TME, 2
// PARM=′&SUBSYS,&NUMTCB′
//STEPLIB DD DISP=SHR,DSN=DSN510.SDSNLOAD 3
// DD DISP=SHR,DSN=CEE.SCEERUN 4
// DD DSN=CBC.SCLBDLL,DISP=SHR 5
// DD DISP=SHR,DSN=SG244693.SAMPLES.LOAD.SPAS 6
//DSNAOINI DD DISP=SHR,DSN=SG244693.SAMPLES.SOURCE(CLIINI) 7
//CLITRACE DD SYSOUT=* 8
//DSNAOTRC DD DISP=SHR,DSN=SG244693.FB80 9
 
Figure 118. Example of JCL Procedure for Stored Procedures Address Space

1 To test our application, we limit the number of TCBs to 1. This eliminates the danger of multiple
stored procedures running concurrently within the same address space and writing to the same file.
2.2.3, “Serializing Access to Non-DB2 Resources” on page 12 explains this in more detail.

2 For WLM-established stored procedure address space we replace the program name with
PGM=DSNX9WLM. CLI stored procedures that require the same INI file can be grouped into one
application environment. In other words, you should define an application environment for each
variation of the INI file.

For stored procedures using CLI, we need to update the stored procedure address space JCL to
include:
3 The library where the CLI DLL code resides. This code is contained in the DB2 system library
SDSNLOAD which should already be in the STEPLIB DD statement. so there is nothing to add.
4 As with any stored procedure address space, the LE runtime is needed.
6 The library where the application modules reside.
7 DSNAOINI DD statement for the DB2 CLI initialization (INI) file. See Figure 119 on page 230 for
a sample.

Optionally, the JCL can include:


5 DD statement for class libraries if required.
6 CLI user application trace output file. See Figure 121 on page 232 for an example.
8 DD statement for the CLI application trace (required if you set CLITRACE=1 in the CLI INI file).
The file name should match the TRACEFILENAME statement in the CLI INI file. If this file name is
not set, there is no output from the CLI application trace.
9 DSNAOTRC DD statement for the CLI diagnosis trace (required if you set TRACE=1 in the CLI
INI file). It must be a sequential data set of fixed block 80.

11.10 Problem Determination Tracing

We can obtain additional information on how a CLI stored procedure is behaving using:
• The CLI application trace, which traces every DB2 CLI call from the application. It also displays the
invoking parameters.
• The CLI diagnosis trace - IBM Support Center uses information in this trace for service support. It
is sometimes known as the CLI serviceability trace . It is not intended to assist in debugging
application code.

Chapter 11. CLI on DB2 Version 5 229


• LE run-time options - Use run-time options such as RPTSTG and RPTOPTS to display the amount of
storage and the run-time options used. This may suggest different LE run-time settings, which may
help with performance issues. You can set the LE run-time options using the RUNOPTS column of
SYSIBM.SYSPROCEDURES.
• The debugger - Refer to Chapter 15, “Debugging DB2 on MVS Stored Procedures” on page 305.

This information can assist in problem determination or performance tuning.

11.10.1 Using the CLI Application Trace


The CLI application trace is a very useful tool. It displays the parameters the application passes to
DB2 CLI APIs, and the results of the CLI calls. This saves you from having to write code to display
what is happening at the CLI interface. We update the CLI INI file (Figure 119) using CLITRACE=1 4
and specify the DD name for the trace output 5.

 
; See also sample DSN510.SDSNSAMP(DSNAOINI) for CLI ini file
; COMMON stanza
[COMMON]
MVSDEFAULTSSID=DSGC
;be sure trace is not started before the ini is read, else this is
; missed
;be sure that you put this ini out just before the job you want to
; trace, that is, if you have a setup insert job. run that before.
; turn diagnosis trace on and increase trace buffer size
; no wrapping around and increase trace buffer size from 32KB
TRACE=1 1
TRACE_NO_WRAP=1 2
TRACE_BUFFER_SIZE=2000000 3
; turn user application trace on and direct to DD name CLITRACE
CLITRACE=1 4
TRACEFILENAME=DD:CLITRACE 5
 
Figure 119. Using CLI INI File to Enable Diagnosis and Application Trace

11.10.2 Using the CLI Diagnosis Trace


If IBM requests a CLI diagnosis trace, you have to update the CLI INI file (Figure 119) using TRACE=1
1, specifying no wrapping 2, and increasing the trace buffer size 3.

You must also include a DD statement for the trace output file, which has to be allocated as fixed block
80 sequential file.
//DSNAOTRC DD DISP=OLD,DSN=SG244693.FB80
Figure 120 on page 231 shows how to produce the Formatted Detail Report (FMT) and Formatted Flow
Report (FLW).

230 Getting Started with DB2 Stored Procedures


 
// SET CLBPRFX=CBC * for class lib
// SET DB2EXIT=DSN510.SDSNEXIT * DB2 exits
// SET DB2LOAD=DSN510.SDSNLOAD * DB2
// SET LIBPRFX=CEE * LE prefix
//*
//DSNAOTRC EXEC PGM=IKJEFT01,COND=(04,LT),
// REGION=0M
//STEPLIB DD DSN=&DB2EXIT.,DISP=SHR * DB2 EXIT
// DD DSN=&DB2LOAD.,DISP=SHR * DB2 SYSTEM LIBRARY
// DD DSN=&LIBPRFX..SCEERUN,DISP=SHR * LE RUN-TIME
// DD DSN=&CLBPRFX..SCLBDLL,DISP=SHR * CLASS
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//CEEDUMP DD SYSOUT=*
//FMT DD SYSOUT=*
//FLW DD SYSOUT=*
//TRACECLI DD DISP=SHR,DSN=SG244693.FB80 * TRACE FILE
//SYSTSIN DD *
DSNAOTRC OFF
DSNAOTRC FMT DD:TRACECLI DD:FMT
DSNAOTRC FLW DD:TRACECLI DD:FLW
/*
 
Figure 120. Execute DSNAOTRC to Produce FMT and FLW Reports

The DD name specified by DSNAOTRC is TRACECLI, and it is defined in the JCL.

11.10.3 Running with Traces


The following are the steps to run the CLI sample application with traces:
1. If you use DB2-established address spaces and you have modified the JCL procedure to include
the trace files, you need to refresh the stored procedure address space so that the new JCL is
picked up. One way is to stop and start all procedures. This can be quite disruptive. Again,
however, if you are using WLM-established address space, you can modify the JCL and issue the
VARY command with the REFRESH option. You should set aside an application environment for
testing and debugging purposes for C/CLI stored procedures.
2. Invoke apd29 which CALLs the stored procedure spd29. Figure 121 on page 232 is an excerpt of
the CLI application trace output from the stored procedure address space.
To show how the information from each trace report differs, we use a + to mark the same
statement on each report. Figure 121 on page 232 is an example of the CLI application trace
output.

Chapter 11. CLI on DB2 Version 5 231


 .. 
.
SQLSetConnectOption( hDbc=1, fOption=SQL_AUTOCOMMIT, vParam=0 )
SQLSetConnectOption( )
---> SQL_SUCCESS
SQLConnect( hDbc=1, szDSN=Null Pointer, cbDSN=0, szUID=″db2v5″ ,
cbUID=-3, szAuthStr=″*****″, cbAuthStr=-3 )
SQLConnect( )
---> SQL_SUCCESS
SQLAllocStmt( hDbc=1, phStmt=&9e900b8 )
SQLAllocStmt( phStmt=1 )
---> SQL_SUCCESS
SQLPrepare( hStmt=1, pszSqlStr=″insert into TABLE2A(int4) values(?)″ ,
cbSqlStr=-3 )
SQLPrepare( )
---> SQL_SUCCESS
SQLNumParams( hStmt=1, pcPar=&9e90040 )
SQLBindParameter( hStmt=1, iPar=1, fParamType=SQL_PARAM_INPUT,
fCType=SQL_C_LONG, fSQLType=SQL_INTEGER, cbColDef=0, ibScale=0, rgbVa
lue=&9e900d4, cbValueMax=0, pcbValue=&9e900dc )
SQLBindParameter( )
---> SQL_SUCCESS
SQLExecute( hStmt=1 ) +
( iPar=1, fCType=SQL_C_LONG, rgbValue=200, pcbValue=4 )
SQLExecute( )
---> SQL_SUCCESS
..
.
 
Figure 121. CLI Application Trace Output Example

3. Free the trace file by bringing down the stored procedure address space with DB2 -STOP PROC(*)
command. If using WLM-established address spaces, you must issue the VARY WLM command
with the QUIESCE or REFRESH option instead of STO PROC(*).
4. Process the CLI diagnosis trace file using DSNAOTRC to obtain a format detail report and a format
flow report. Note that the CLI application trace in the dataset is formatted when written to the
output dataset. The CLI diagnosis trace needs you to format it using DSNAOTRC FMT or FLW.

Figure 122 on page 233 is an example of the formatted flow report for the diagnosis trace.

232 Getting Started with DB2 Stored Procedures


 .. 
.
803 SQLExecute fnc_entry +
804 |CLI_dstGetInfo fnc_entry
805 |CLI_dstGetInfo fnc_retcode 0
..
.
808 |SQLExecute2 fnc_entry
809 | |CLI_sdaInitSqldaParm fnc_entry
810 | | |CLI_sdaTermSqldaParm fnc_entry
811 | | |CLI_sdaTermSqldaParm fnc_retcode 0
..
.
847 | |CLI_sqlExecute fnc_retcode 0
848 |SQLExecute2 fnc_retcode 0
849 SQLExecute fnc_retcode 0
..
.
 
Figure 122. Formatted Flow Report (FLW) for CLI Diagnosis Trace Example

Figure 123 is an example of the formatted detail report for diagnosis trace.

 .. 
.
803 DB2 fnc_entry call_level_interface SQLExecute (1.30.42.12) +
pid 0x007d7be0; tid 1; cpid 0; sec 0; nsec 0; tpoint 0
804 DB2 fnc_entry call_level_interface CLI_dstGetInfo (1.30.42.70)
pid 0x007d7be0; tid 1; cpid 0; sec 0; nsec 0; tpoint 0
805 DB2 fnc_retcode call_level_interface CLI_dstGetInfo (1.33.42.70)
pid 0x007d7be0; tid 1; cpid 0; sec 0; nsec 0; tpoint 254
return_code = 0x00000000 = 0
..
.
 
Figure 123. Formatted Detail Report (FMT) for CLI Diagnosis Trace Example

11.10.4 Specifying LE Run-Time Options


Figure 124 on page 234 shows an example of specifying some common LE run-time parameters for a
stored procedure using the DB2 Administration Tool. You can update SYSIBM.SYSPROCEDURES in a
variety of ways.

Chapter 11. CLI on DB2 Version 5 233


 
DB2 Admin --------------- DBC1 Update Stored Procedure ------------------ 15:40
Command ===>

DB2 System: DBC1


Enter/verify: DB2 SQL ID: DB2RES1
Procedure name ===> SPD29
Authid ===>
LU name ===>
Load module ===> SPD29
Linkage ===> (blank: SIMPLE, N: SIMPLE WITH NULLS
Collection ID ===> DSNAOCLI
Service units ===> 0 (0: no limit, 1-N: max service units
Language ===> C (ASSEMBLE, PLI, COBOL, or C)
Stay resident ===> (Y: yes, blank: no)
Run-time options ===> MSGFILE(OUTDUMP2),RPTSTG(ON),RPTOPTS(ON),HEAPCHK(ON),HEA
P(600K),TRACE(ON,12M,DUMP,LE=2)

Parameter list ===> INTEGER INOUT

Result sets ===> 2 (0: no result sets, 1-N: result sets


WLM environment ===> (name of WLM environment to be used)
Program type ===> M (M: main routine, S: subroutine)
Ext security ===> N (N: No, Y: RACF env. needed)
Commit on return===> N (N: No, Y: UOW is to be commited)
Press Enter to Update, or PF3 to cancel. Cmd EPARM to EDIT parm
 
Figure 124. Specifying LE Run-Time Options Using DB2 Administration Tool

Notice that the collection ID DSNAOCLI matches the collection ID where you bound CLI packages.

We use MSGFILE to redirect dump output to a different DD name, OUTDUMP2. RPTSTG(ON) requests
report on storage usage which can help you decide on an appropriate LE run-time parameter.
Figure 125 is a sample output from the RPTSTG option.

RPTOPTS(ON) lets you know which run-time options are used. You can also request HEAP size and
trace.

 
HEAP statistics:
Initial size: 614400
Increment size: 32768
Total heap storage used (sugg. initial size): 838896
Successful Get Heap requests: 214
Successful Free Heap requests: 90
Number of segments allocated: 9
Number of segments freed: 0
 
Figure 125. Excerpt from Specifying LE Run-Time Option RPTSTG(ON)

234 Getting Started with DB2 Stored Procedures


11.11 Running the CLI Sample Stored Procedure

Now we go through setting up a sample CLI stored procedure and demonstrate how to use these
techniques. The base for this sample is contained in Appendix F of the DB2 for OS/390 V5 Call Level
Interface Guide and Reference . In this redbook, we provide a modified version of the stored procedure
and the client program.

Table 14 summarizes the steps to implement the sample client program written in CLI that invokes a
stored procedure written in CLI.

Table 14. Jobs for CLI Sample Stored Procedure


Member Notes
apddl CREATE the two target tables: TABLE2A and TABLE2B and their unique indexes. Each
table has columns with different data types. TABLE2B is identical to TABLE2A except
every column is defined as NOT NULL WITH DEFAULT.
defspd29 INSERT a row into SYSIBM.SYSPROCEDURES
spd29 Precompile, prelink, and link stored procedure spd29
apdin INSERT rows into target tables. Must be run before each invocation of apd29 (which in
turn CALLs spd29)
apd29 Precompile, prelink, link, and execute the apd29 client program

We have included the members listed in Table 14 in the JCL library of the sample diskette.

To implement this sample perform the following steps:


1. Make sure the CLI environment is already set up.
2. Update the SOURCE me mb e r apddl with your data source, user ID, and password.
3. Run the apddl JCL m e m b e r to compile, prelink, link, and execute.
4. Update the SOURCE m e m b e r apdin with your data source, user ID, and password.
5. Run the defspd29 me mb e r to define the stored procedure to SYSIBM.SYSPROCEDURES table.
6. Run the spd29 JCL me mb e r to compile, prelink, and link.
7. Run the apdin JCL me mb e r to compile, prelink, link, and execute SQL statements within apdin.
8. Update the SOURCE me mb e r apd29 with your data source, user ID, and password.
9. Manually drop the index TABLE2AX from TABLE2A.
10. Run the apd29 JCL member to compile, prelink, link, and execute the client program, calling spd29.

These sample programs use printf() to write output. If we do not define SYSPRINT in the stored
procedure during execution, SYSOUT data sets are dynamically allocated with DD names such as
SYS00001, SYS0002, and SYS00003. You will see these DD names in the stored procedure address
space output as follows:
DDNAME STEPNAME
JESMSGLG JES2
JESJCL JES2
JESYSMSG JES2
CLITRACE DBC1SPAS
SYS00001 DBC1SPAS
SYS00002 DBC1SPAS
SYS00003 DBC1SPAS

Chapter 11. CLI on DB2 Version 5 235


11.12 Porting CLI Applications

In this section, we illustrate some of the considerations we came across while porting existing
CLI/ODBC code from AIX to OS/390. Although what we came across is by no means a comprehensive
list of tasks, it is a starting point for porting code.

There are differences in how stored procedures are supported between the workstation DB2 products
and the host DB2 products. Understanding these differences gives you an idea of the effort involved in
porting existing applications between platforms. It also helps you design more portable code if you are
writing applications using DB2 stored procedures. Table 15 outlines some of these similarities and
differences.

Table 15. Overview of Support Related to Stored Procedures


Description DB2 for MVS/ESA DB2 for OS/390 V5 DB2 Common DB2 Universal
V4 Server V2 Database V5
DRDA AR using Yes Yes Yes Yes
parameters
DRDA AS using Yes Yes Yes Yes
parameters
DRDA AR for Yes Yes(CLI)
result sets
DRDA AS for Yes
result sets
CLI ODBC 2.0 Yes Yes Yes
level 2
CLI ODBC 3.0 Yes
level 1
stored procedure must be in uppercase for CLI. See 8.6, case sensitive. On OS/2, we can use the
name “Case Sensitivity and Stored Procedure EXPORTS section in the module definition
Name Folding” on page 129 file to allow uppercase. See 7.3.1,
“Uppercase and Lowercase” on
page 112
keep program in update STAYRESIDENT = ′ Y′ in return(SQLZ_HOLD_PROC) in source
memory SYSPROCEDURES table code
remove program update STAYRESIDENT = ′ ′ in return(SQLZ_DISCONNECT_PROC) in
fro m m e m o r y SYSPROCEDURES table source code

Note that DB2 Common Server V2 and DB2 Universal Database V5 support result sets only when using
CLI.

Result sets are supported both as a client and server by DB2 Universal Database V5 and DB2 Common
Server V2 using the private protocol called DB2RA. Using the DRDA protocol, only the application
requester is supported: DRDA application server on DB2 for the workstation does not currently
support result sets.

11.12.1 Porting a Sample Result Set CLI Application from AIX to OS/390
To demonstrate the similarities and differences between stored procedures on AIX (or other
workstation platforms) and OS/390, we chose the sample stored procedure mrspsrv from DB2
Universal Database V5. This exercise illustrates:
• Restrictions on stored procedures returning result sets
• How to pass a parameter with indicator to and from a stored procedure

236 Getting Started with DB2 Stored Procedures


• How to use a single result set (where only part of the result set is returned to the caller)
• Data conversion (decimal to double in this case)
• Migration from an ODBC 3.0 application to ODBC 2.0

11.12.2 Differences in Handling Result Sets


Refer to Chapter 6, “Using Advanced Features” in DB2 for OS/390 V5 Call Level Interface Guide and
Reference for detailed information about using stored procedures and restrictions. For porting CLI
applications to OS/390, we highlight visible differences in how result sets behave. This may have
implications for application design.

We created an AIX client CLI program on UDB based on mrspcli so that we can specify which stored
procedure to CALL at invocation. This program, sr1, is provided as part of the samples. (See
Figure 126.) We ran it with the CLI application trace on at the client so that we can examine each CLI
call. We updated the CLI INI file as follows:
trace=1
; do a physical write after each trace call
traceflush=1
; ------------------------------------------
; use a full subdirectory name
; ------------------------------------------
tracepathname=/home/svtdbm4/sqllib/clitrace

Figure 126. Using Sample mrspcli.c and sr1.c as Clients

Table 16 summarizes the various scenarios.

Table 16 (Page 1 of 2). Visible Differences in Result Sets Behavior.


Scenario (client to stored Parameters / indicators Result Sets
procedure)
11.12.2.1, “UDB to UDB Result OK OK
Sets Using Private Protocol” on
page 238

Chapter 11. CLI on DB2 Version 5 237


Table 16 (Page 2 of 2). Visible Differences in Result Sets Behavior.
Scenario (client to stored Parameters / indicators Result Sets
procedure)
11.12.2.2, “UDB to UDB Result OK Fails: not supported
Sets Using DRDA Protocol” on
page 238
11.12.2.3, “UDB to OS/390 Result OK OK, but column names are not
Sets Using DRDA Protocol” on returned. The ordinal position of
page 239 (CLI or embedded SQL) the column is returned instead.
UDB to OS/390 (stored procedure OK OK, but column names are not
using embedded SQL), DRDA returned. The ordinal position of
protocol the column is returned instead.

Note that for the column name to be returned, you must specify DESCSTAT=YES in the ZPARM
module. If your stored procedure already exists, you have to rebind it after changing the ZPARM
module.

11.12.2.1 UDB to UDB Result Sets Using Private Protocol: We catalog a remote database
on the workstation platform and run our version sr1 of the sample result sets program mrspcli
between an AIX client and an OS/2 server. Figure 127 shows the results:

 
$ sr1 sample2 db2v5 db2v5
>Enter stored procedure name
mrspsrv
>Connected to sample2
Use CALL with Host Variable to invoke the Server Procedure named >mrspsrv<
Server Procedure Complete.
Median Salary = 17654.50 A

ID NAME SALARY B


340 Edwards 17844.00
90 Koonitz 18001.75
40 O′ Brien 18006.00
..
.
160 Molinare 22959.20
>Disconnecting .....
 
Figure 127. UDB to UDB over Private Protocol

Going from AIX to OS/2 using the DB2 UDB private protocol (DB2RA), the parameters/indicators A
and the column names B are passed back to the client program with the result set.

11.12.2.2 UDB to UDB Result Sets Using DRDA Protocol: Going from AIX to OS/2 using
DRDA, the median salary comes back because the stored procedure passes it as a parameter. The
result set does not work because on the workstation platform, DRDA AS does not support result sets.
We see an error in our client program (invalid cursor state). Figure 128 on page 239 shows the
results.

238 Getting Started with DB2 Stored Procedures


 
capefear:/home/svtdbm4/gavcli >mrspcli sample2d db2v5 db2v5
>Connected to sample2d
Use CALL with Host Variable to invoke the Server Procedure named mrspsrv
Server Procedure Complete.
Median Salary = 17654.50

>--- ERROR -- RC = -1 Reported from samputil.c, line 324 ------------


SQLSTATE: 24000
Native Error Code: -99999
[IBM][CLI Driver] CLI0115E Invalid cursor state. SQLSTATE=24000
>--------------------------------------------------
..
.
 
Figure 128. UDB to UDB over DRDA Protocol

11.12.2.3 UDB to OS/390 Result Sets Using DRDA Protocol: We rewrote the UDB sample
program mrspsrv with minor modifications and renamed it sr1oms. We invoked it using the modified
AIX client sr1.

The different tasks and considerations in porting the CLI source code from AIX to OS/390 are described
in 11.12.3, “CLI Stored Procedure Coding Considerations” on page 240. Figure 129 shows the results.

 
$ sr1 dsgct db2v5 db2v5
>Enter stored procedure name
SR1OMS
>Connected to dsgct
Use CALL with Host Variable to invoke the Server Procedure named >SR1OMS<
Server Procedure Complete.
Median Salary = 17654.50 A

1 2 3 B
340 Edwards 17844.00
90 Koonitz 18001.75
40 O′ Brien 18006.00
20 Pernal 18171.25
100 Plotz 18352.80
..
.
 
Figure 129. UDB to OS/390 (CLI) Using DRDA Protocol

The parameter/indicator A is passed back, as is the result set. However, the column names B are
not passed back from the stored procedure. Instead, the ordinal position of the column is passed.

We also rewrote the UDB sample program mrspsrv using embedded SQL and other host languages.
The results are identical to those of the OS/390 CLI stored procedure.

Although the column names for the result sets are not passed back to the client that called the stored
procedure, the stored procedure can obtain each column name using SQLDescribeCol(). The result
can then be passed back to the client program either using parameters, or as another result set using
a global temporary table.

Chapter 11. CLI on DB2 Version 5 239


11.12.3 CLI Stored Procedure Coding Considerations
The majority of differences between the original AIX CLI stored procedure and the OS/390 CLI stored
procedure can be categorized as:
• Those specific to the OS/390 implementation of CLI
• Modifications due to porting from ODBC 3.0 to ODBC 2.0
• Features specific to writing stored procedures

Let us examine the example shown in Figure 130.

#pragma options (rent) /* 01 */


#pragma runopts(plist(os)) /* 02 */
/*********************************************************************
**
** The STAFF table:
** Column Name Col No Col Type Length Scale Null
** ------------------ ------ -------- ------ ------ -----
** ID 1 SMALLINT 2 0 N
** NAME 2 VARCHAR 9 0 Y
** DEPT 3 SMALLINT 2 0 Y
** JOB 4 CHAR 5 0 Y
** YEARS 5 SMALLINT 2 0 Y
** SALARY 6 DECIMAL 7 2 Y
** COMM 7 DECIMAL 7 2 Y
**
** Source File Name = mrspsrv.c 1.4
**
** Licensed Materials - Property of IBM
**
** (C) COPYRIGHT International Business Machines Corp. 1995, 1997

Figure 130 (Part 1 of 8). SR1OMS Source Code: CLI Stored Procedure in C

240 Getting Started with DB2 Stored Procedures


** All Rights Reserved.
**
** US Government Users Restricted Rights - Use, duplication or
** disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
**
**
** PURPOSE :
** This sample program demonstrates a CLI ′ output′ stored
** procedure that returns a result set.
**
** There are two parts to this program:
** - the mrspcli executable (placed on the client)
** - the mrspsrv library (placed on the server)
**
** Refer to the mrspcli.c program for more details on how
** this program is invoked as the mrspsrv routine
** in the mrspsrv library by the SQL CALL statement.
**
** The mrspsrv routine will do two things:
** 1) Obtain the median salary of employees in the ″staff″ table
** of the ″sample″ database. This value will be placed in the
** input/output SQLDA and returned to the mrspcli routine.
** 2) It will also leave open a cursor in the ″staff″ table
** positioned to return all the employees with salaries
** greater than the median.
** The mrspcli sample will then print out the median salary, and
** the list of employees with salaries greater than the median.
**
**
*********************************************************************/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* #include <sqlda.h> */ /* 03 */
#include <sqlca.h>
#include <sqlcli1.h> /* 04 */
#include <decimal.h>
/* #include ″samputil.h″ */ /* Header file for CLI sample code */
#include ″v2sutil.h″ /* ODBC 2.0 CLI sample utilities 05 */

Figure 130 (Part 2 of 8). SR1OMS Source Code: CLI Stored Procedure in C

Chapter 11. CLI on DB2 Version 5 241


/* ml */
#define MAXCOLS 255 /* 06 */

/*--> SQLL1X58.SCRIPT */
/*
int SQL_API_FN mrspsrv(
void *reserved1,
void *reserved2,
struct sqlda *output_sqlda,
struct sqlca *sqlca)
*/
/*here */
/* local variables */
SQLSMALLINT num_records; /* 07 */
SQLINTEGER indicator; /* 08 */

struct sqlca sqlca; /* 09 */


/*---------------------------------------------------------------*/
/* variables used for SQLNumResultCols() 10 */
/* SQLDescribeCol() */
/* SQLColAttributes() */
/*---------------------------------------------------------------*/
SQLCHAR colname[32];
SQLSMALLINT coltype;
SQLSMALLINT colnamelen;
SQLSMALLINT nullable;
SQLUINTEGER collen[MAXCOLS];
SQLSMALLINT scale;
SQLINTEGER outlen[MAXCOLS];
SQLCHAR *data[MAXCOLS];
SQLCHAR errmsg[256];
SQLRETURN rc;
SQLSMALLINT nresultcols;
SQLINTEGER i;
SQLINTEGER displaysize;
/*---------------------------------------------------------------*/
/* variables used for SQLError() 11 */
/*---------------------------------------------------------------*/
SQLCHAR buffer[SQL_MAX_MESSAGE_LENGTH + 1];
SQLCHAR cli_sqlstate[SQL_SQLSTATE_SIZE + 1];

Figure 130 (Part 3 of 8). SR1OMS Source Code: CLI Stored Procedure in C

242 Getting Started with DB2 Stored Procedures


SQLINTEGER cli_sqlcode;
SQLSMALLINT length;

/* 12 */
int
main(SQLINTEGER argc, SQLCHAR *argv[] )
/*<-- */
{
/* Declare CLI Variables */ /* 13 */
/* SQLHANDLE henv, hdbc, hstmt1, hstmt2 ; */
SQLHENV henv ;
SQLHDBC hdbc ;
SQLHSTMT hstmt1, hstmt2 ;
SQLRETURN rc ;

/*--> */

SQLCHAR * stmt2 = ″SELECT count(*) FROM DB2RES1.STAFF″ ;


SQLCHAR stmt1[80] ;

SQLDOUBLE salary; /* 14 */

SQLINTEGER counter = 0;

/*strcpy((char *)stmt1, ″SELECT ID, JOB , SALARY″ ) ; */ /* CHAR */


/*strcpy((char *)stmt1, ″SELECT ID, NAME, SALARY″ ) ; */ /* VARCHAR */
strcpy((char *)stmt1, ″SELECT ID, DEPT, SALARY″ ) ;
strcat((char *)stmt1, ″ FROM DB2RES1.STAFF ORDER BY SALARY″ ) ;

/*-----------------------------------------------------------------*/
/* Setup CLI required environment */
/* */
/*ODBC3.0 Split SQLAllocHandle into SQLAllocEnv, SQLAllocConnect */
/*ODBC3.0 and SQLAllocStmt for OS/390 which is mainly ODBC 2/0 */
/*-----------------------------------------------------------------*/

/* 15 */
/*rc = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv ) ; */
rc = SQLAllocEnv( &henv ) ;
if ( rc != SQL_SUCCESS ) return( terminate( henv, rc ) ) ;

Figure 130 (Part 4 of 8). SR1OMS Source Code: CLI Stored Procedure in C

Chapter 11. CLI on DB2 Version 5 243


/* 16 */
/*rc = SQLAllocHandle( SQL_HANDLE_DBC, henv, &hdbc ) ; */
rc = SQLAllocConnect( henv, &hdbc ) ;
if ( rc != SQL_SUCCESS ) return( terminate( henv, rc ) ) ;

/* 17 */
rc = SQLSetConnectOption(hdbc,SQL_AUTOCOMMIT,SQL_AUTOCOMMIT_OFF);
if( rc != SQL_SUCCESS ) goto ext;

/*-----------------------------------------------------------------*/
/* Issue NULL Connect, since in CLI we need a statement handle */
/* and thus a connection handle and environment handle. */
/* A connection is not established, rather the current */
/* connection from the calling application is used */
/*-----------------------------------------------------------------*/

/*
SQLConnect( hdbc, NULL, SQL_NTS, NULL, SQL_NTS, NULL, SQL_NTS ) ;
*/
rc=SQLConnect(hdbc,
NULL,
0,
NULL,
0,
NULL,
0); /* 18 */

/*SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt1 ) ; */


SQLAllocStmt( hdbc, &hstmt1 ) ; /* 19 */
/*SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &hstmt2 ) ; */
SQLAllocStmt( hdbc, &hstmt2 ) ;
/* Execute a Statement to Obtain and Order all Salaries */
rc = SQLExecDirect(hstmt1, stmt1, SQL_NTS);
if (rc != SQL_SUCCESS) goto ext;

/*---------------------------------------------------------------*/
/* Examine the columns related to the SQL statement 20 */
/*---------------------------------------------------------------*/
rc = SQLNumResultCols(hstmt1, &nresultcols);

Figure 130 (Part 5 of 8). SR1OMS Source Code: CLI Stored Procedure in C

244 Getting Started with DB2 Stored Procedures


CHECK_STMT(hstmt1, rc);
printf(″number of result columns: %d\n″ , nresultcols) ;

for (i = 0; i < nresultcols; i++) {


SQLDescribeCol(hstmt1, i + 1, colname, sizeof(colname),
&colnamelen, &coltype,
&collen[i], &scale, NULL);
SQLError(henv, hdbc, hstmt1, cli_sqlstate, &cli_sqlcode,
buffer,SQL_MAX_MESSAGE_LENGTH + 1, &length) ;

/* get display length for column */


SQLColAttributes(hstmt1, i + 1, SQL_COLUMN_DISPLAY_SIZE, NULL,
0, NULL, &displaysize);
SQLError(henv, hdbc, hstmt1, cli_sqlstate, &cli_sqlcode,
buffer,SQL_MAX_MESSAGE_LENGTH + 1, &length) ;

/* Execute a Statement to */
/* determine the Total Number of Records */
rc = SQLExecDirect(hstmt2, stmt2, SQL_NTS);
if (rc != SQL_SUCCESS) goto ext;

rc = SQLFetch(hstmt2);
if (rc != SQL_SUCCESS) goto ext;

rc = SQLGetData(hstmt2, 1, SQL_C_SHORT, &num_records,


0, NULL);
if (rc != SQL_SUCCESS) goto ext;

printf(″number of rows in table: %d\n″ , num_records);

/* Fetch Salaries until the Median Salary is Obtained */


while ( counter++ < num_records/2 + 1 )
{ rc = SQLFetch(hstmt1);
if (rc == SQL_ERROR) goto ext;
}

/* Return the median salary */ /* 21 */


/*

Figure 130 (Part 6 of 8). SR1OMS Source Code: CLI Stored Procedure in C

Chapter 11. CLI on DB2 Version 5 245


rc = SQLGetData(hstmt1, 3, SQL_C_DOUBLE, \
output_sqlda->sqlvar[0].sqldata, \
0, &indicator);
*(output_sqlda->sqlvar[0].sqlind) = indicator;
*/
rc = SQLGetData(hstmt1,
3,
SQL_C_DOUBLE,
&salary,
sizeof(salary),
&indicator);
memcpy(argv[1],&salary, sizeof(salary)) ; /* 22 */
*(argv[2]) = 0 ; /* 23 */

if (rc != SQL_SUCCESS) goto ext;

/*-----------------------------------------------------------------*/
/* Return to caller */
/*-----------------------------------------------------------------*/

ext:
/* ml */

while ((rc=SQLError(henv, hdbc, hstmt1, cli_sqlstate, &cli_sqlcode,


buffer,SQL_MAX_MESSAGE_LENGTH + 1, &length)) == SQL_SUCCESS) {
printf(″ SQLSTATE: %s″, cli_sqlstate);
printf(″Native Error Code: %ld″, cli_sqlcode);
printf(″%s ″, buffer);
};

/* SQLGetSQLCA(henv, hdbc, hstmt1, sqlca); */


SQLGetSQLCA(henv, hdbc, hstmt1, &sqlca);

/* Leave hstmt1 allocated, with cursor open to return all rows


with salaries greater than the median, unless rc == SQL_ERORR
*/
if( rc == SQL_ERROR)
{
/*startODBC 3.0*/
/* rc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt1 ) ; */

Figure 130 (Part 7 of 8). SR1OMS Source Code: CLI Stored Procedure in C

246 Getting Started with DB2 Stored Procedures


/* CHECK_HANDLE( SQL_HANDLE_STMT, hstmt1, rc ) ; */
/*endODBC 3.0*/
/*
SQLFreeStmt(hstmt1, SQL_DROP);
CHECK_STMT(hstmt1, rc);
*/
}
/*startODBC 3.0*/
/*rc = SQLFreeHandle( SQL_HANDLE_STMT, hstmt2 ) ; */
/*CHECK_HANDLE( SQL_HANDLE_STMT, hstmt2, rc ) ; */
/*endODBC 3.0*/
/*
SQLFreeStmt(hstmt2, SQL_DROP);
CHECK_STMT(hstmt2, rc);
*/

/*rc = SQLEndTran( SQL_HANDLE_DBC, hdbc, SQL_COMMIT ) ; */


/* CHECK_HANDLE( SQL_HANDLE_DBC, hdbc, rc ) ; */

/*rc = SQLTransact(henv, hdbc, SQL_COMMIT); */ /* 24 */


/*CHECK_DBC(hdbc, rc); */

printf( ″>Disconnecting .....\n″ ) ;


rc = SQLDisconnect( hdbc ) ;

/*CHECK_HANDLE( SQL_HANDLE_DBC, hdbc, rc ) ; */ /* 25 */


CHECK_DBC(hdbc, rc);

/*rc = SQLFreeHandle( SQL_HANDLE_DBC, hdbc ) ; */


rc = SQLFreeConnect(hdbc); /* 26 */
/*CHECK_HANDLE( SQL_HANDLE_DBC, hdbc, rc ) ; */
CHECK_DBC(hdbc, rc);

/*rc = SQLFreeHandle( SQL_HANDLE_ENV, henv ) ; */


rc = SQLFreeEnv(henv); /* 27 */
if ( rc != SQL_SUCCESS )
return( terminate( henv, rc ) ) ;

/* return(1); */ /* Return SQLZ_DISCONNECT_PROC */


return; /* 28 */
}
/*<-- */

Figure 130 (Part 8 of 8). SR1OMS Source Code: CLI Stored Procedure in C

11.12.3.1 Code Specific to the OS/390 Implementation of CLI: 01 This pragma tells the
compiler that the code is to be reentrant. In our case this is not necessary, since we have decided to
rewrite this stored procedure as a main() program and we do not request that the module be kept
resident (specified in the SYSIBM.SYSPROCEDURES table).

04 We must include the CLI header file (# include<sqlcli1.h>). This is the same as for DB2 in the
workstation environments.

We have decided to use data conversion in this example. Instead of using decimal, the SALARY
column is defined on the STAFF table using SQLDOUBLE ( 14 and 21), which is easier to manipulate
in C. Refer to “Data Types and Data Conversion” in Chapter 3 of DB2 for OS/390 V5 Call Level
Interface Guide and Reference for more details.

Chapter 11. CLI on DB2 Version 5 247


11.12.3.2 Code Related to Differences Between ODBC 2.0 and ODBC 3.0: The level of
ODBC supported by DB2 CLI is different across different releases and different platforms. For more
details, refer to the CLI references for each product.

DB2 Universal Database V5 provides a sample utility that incorporates a number of routines to handle
standard tasks such as error checking. There is also a version written for ODBC 2.0. Unlike the
original UDB version of mrspsrv.c, we are using the DB2 Common Server V2 routines because
OS/390′s implementation of CLI conforms mostly to ODBC 2.0, and v2sutil.c is written in ODBC 2.0 (the
DB2 Universal Database V5 version uses ODBC 3.0). Therefore, we include the v2sutil.h header 05.

When porting from AIX to OS/390, we need to revert back to some of the ODBC 2.0 functions:
ODBC 3.0: SQLFreeHandle( SQL_HANDLE_STMT, hstmt ) ;
ODBC 2.0: SQLFreeStmt(hstmt, SQL_DROP);

ODBC 3.0: SQLEndTran()


ODBC 2.0: SQLTransact()

For a comprehensive list, refer to Appendix B “Migrating Applications” in DB2 UDB V5 Call Level
Interface Guide and Reference . It has a table of CLI functions that should not be used for UDB Version
5.

We revert to the ODBC 2.0 version of samputil.c routines (v2sutil.c) in a similar fashion, for example,
ODBC 3.0: CHECK_HANDLE( SQL_HANDLE_STMT, hstmt, rc ) ;
ODBC 2.0: CHECK_STMT(hstmt, rc);

ODBC 3.0: CHECK_HANDLE( SQL_HANDLE_DBC, hdbc, rc ) ;


ODBC 2.0: CHECK_DBC(hdbc, rc);

These requirements account for the modifications in 13, 15, 16, 19, 24, 25, 26 and 27.

11.12.3.3 Code Related to Stored Procedures: 02 This pragma is specific to OS/390 for C
stored procedures so that the correct linkage is used when the stored procedure is invoked. On the
workstation, stored procedures are implemented as DLLs. For our example, we have decided to use a
main program (not a subprogram).

When we exit the stored procedure, DB2 for OS/390 V5 decides whether to remove the module from
memory or not by referencing the STAYRESIDENT column of the SYSIBM.SYSPROCEDURES table.
This decision lies outside the stored procedure itself.

The workstation implementation differs in that the stored procedure passes a return code back
indicating whether to disconnect the library or hold. 28

03 The header file for SQLDA is commented out here because unlike the UDB sample, we are
handling parameters as variables ( 07, 08 and 14) passed to a main() program 12.

Similarly we pass the parameter 22 and indicator 23 back without explicit reference to the SQLDA.

SQLCAs are used differently on OS/390 than in the UDB sample 09.

Among the SQL statements that are not allowed for stored procedures for DB2 for MVS/ESA V4 and
DB2 for OS/390 V5 are COMMIT and CONNECT.

A Null Connection: 18 is a null connection. NULL CONNECT is an ODBC term. It is a valid client or
stored procedure connect technique where the pointer to the data source is NULL. NULL CONNECT
means “default” connect.

248 Getting Started with DB2 Stored Procedures


Table 17. How NULL Connections Behave for DB2 for OS/390 V5
Client Application Stored Procedure
NULL CONNECT turns into EXEC SQL CONNECT DB2 requires a NULL CONNECT to be sure the user
RESET which gets you to the DB2 in which this knows we connect to the “default” data source (DB2
thread is “attached.” subsystem) which is the one to which the stored
procedure address space has threads connected.
In a client, a NULL CONNECT causes a CONNECT
RESET. In a stored procedure, a NULL CONNECT sets up CLI
internal structures about the connection.

Note that a NULL CONNECT does not establish the database connection handle. The connection
handle was established at SQLAllocConnect time.

Do Not COMMIT from a Stored Procedure: We cannot COMMIT from a stored procedure and therefore
the SQLTransact() 24 has to be taken out from the AIX code, or a -751 SQLCODE is returned as
follows:
DSNT408I SQLCODE = -751, ERROR: A STORED PROCEDURE HAS BEEN
PLACED IN MUST_ROLLBACK STATE DUE TO SQL OPERATION COMMIT
DSNT418I SQLSTATE = 42987 SQLSTATE RETURN CODE
DSNT415I SQLERRP = DSNXEEZ SQL PROCEDURE DETECTING ERROR

17 To turn autocommit off, use the SQLSetConnectOption() API. This prevents an implicit COMMIT,
which is invalid.

Notice also that result sets in CLI stored procedures do not require the WITH RETURN clause in a
SELECT statement.

11.12.4 Miscellaneous Programming Hints


While developing CLI application programs, use the CLI application trace facility to examine
parameters passed to and from CLI. It will save you from having to write many printf() statements.

11.12.4.1 Using SQLBindCol() instead of SQLGetData() for Better Performance: Using


SQLGetData() is the least efficient way to FETCH because it causes a double move: data to CLI
address, then CLI address to SQLGetData() address. Where possible, use SQLBindCol() instead before
a FETCH. It moves the data once directly into the user storage.

11.12.4.2 SQL Errors: At the early stages of application development (such as prototyping), in the
absence of an error handling routine, use SQLError() and SQLGetSQLCA() together with CLI
application trace to find out causes for errors. Variables related to SQLError() are declared in 11 and
SQLError() is called in 20

A better solution is to develop an error handling routine up front.

11.12.4.3 Invalid Conversions (SQLSTATE 07006): Ensure that you are using the correct
data types. By coding SQLDescribeCol() or SQLColAttributes() directly after an SQLExecDirect() or
SQLPrepare(), as in 20 you can obtain the data types and attributes for each column from the CLI
application trace data set:
0SQLDescribeCol( hStmt=1, iCol=1, pszColName=&9e8f318, cbColNameMax=32,
pcbColName=&9e8f04c, pfSQLType=&9e8f048, pcbColDef=&9e8f600,
pibScale=&9e8f054, pfNullable=NULL )

SQLDescribeCol( pszColName=″ID″, pcbColName=2, pfSQLType=SQL_SMALLINT,


pcbColDef=5, pibScale=0 )

Chapter 11. CLI on DB2 Version 5 249


---> SQL_SUCCESS

SQLDescribeCol() provides information on:


• Column name
• Base SQL data type
• Precision and scale

The variables used by SQLDescribeCol() are declared in 10.

Once you have identified the attributes, you can take these statements out of your source code. Refer
to “Data Types and Data Conversion” in Chapter 3 of DB2 for OS/390 V5 Call Level Interface Guide and
Reference for more details.

11.12.4.4 Code Page Translation Between Platforms: If you are porting C / C + + programs,
beware of code page translations. The C/C++ compiler requires coded character set (code page)
IBM-1047. The CLI initialization file also requires IBM-1047.

The iconv() and JCL procedure EDCICONV (usually found in the LE sample JCL procedure library
CEE.SCEEPROC) can convert the square brackets [ ] (x′B A′ and x′B B′) into the appropriate IBM-1047
representations (x′AD′ and x′BD′). Refer to O S / 3 9 0 : C / C + + U s e r ′ s Guide , SC09-2361, for information
about EDCICONV. Refer to OS/390: OpenEdition Command Reference , SC28-1892, for more information
about iconv().

If you upload a source program from some platform that has a different code page, you need to
convert to the local code page before compiling the application. For our OS/390 we use code page
IBM-037. Figure 131 is a sample JCL to convert the coded character sets from IBM-1047 to our coded
character set IBM-037

 
//... JOB ...
// JCLLIB ORDER=CEE.SCEEPROC 1
//ICONV EXEC PROC=EDCICONV,
// INFILE=, 2
// OUTFILE=, 3
// FROMC=′ IBM-037′ , 4
// TOC=′ IBM-1047′ 5
 
Figure 131. Sample JCL to Convert Coded Chracter Set

1 Optional statement to point to a JCL procedures library where EDCICONV is located.

2 and 3 are input and output data set names.

4 The name of the code set in which the input data is encoded. For example IBM-037
(En_US.IBM-037) for US, IBM-285 (En_GB.IBM-285) for the United Kingdom.

5 The name of the code set to which the output data is to be converted.

We can use utilities on OS/390 or AIX to translate the source code between code pages. Figure 132 on
page 251 shows how to invoke EDCICONV to tranlate code pages.

250 Getting Started with DB2 Stored Procedures


 
// JCLLIB ORDER=CEE.SCEEPROC
// SET MEM=APD29C
//*
//ICONV EXEC PROC=EDCICONV,
// INFILE=SG244693.SAMPLES.SOURCE(&MEM.),
// OUTFILE=SG244693.SAMPLES.SOURCE.UDBAIX(&MEM.),
// FROMC=′ IBM-1047′ ,
// TOC=′ ISO8859-1′
 
Figure 132. Translating Code Page

On AIX, we can also use:


iconv -f IBM-850 -t ISO8859-1 infile > outfile

If you need to find out what code page you are using on AIX, you can use smit to help you:
1. Find out the code page for AIX.
2. Find out the code page for OS/390.
3. Use iconv() or EDCICONV to translate code pages.
4. Use FTP to move source code.
To find out the code page for AIX using smit:
1. Invoke smit and the System Management panel shown in Figure 133 is displayed.

 
System Management

Move cursor to desired item and press Enter.

Software Installation and Maintenance


Software License Management
Devices
System Storage Management (Physical & Logical Storage)
Security & Users
Communications Applications and Services
Print Spooling
Problem Determination
Performance & Resource Scheduling
System Environments
Processes & Subsystems
Applications
Applicationsinformation only)
Using SMIT (information only)

F1=Help F2=Refresh F3=Cancel F8=Image


F9=Shell F10=Exit Enter=Do
 
Figure 133. System Management Panel

2. Place the cursor under System Environments, press Enter and the System Environments panel
shown in Figure 134 on page 252 is displayed.

Chapter 11. CLI on DB2 Version 5 251


 
System Environments
Move cursor to desired item and press Enter.
Stop the System
Assign the Console
Change / Show Date, Time, and Time Zone
Manage Language Environment
Change / Show Characteristics of Operating System
Change / Show Number of Licensed Users
Broadcast Message to all Users
Manage System Logs
Change / Show Characteristics of System Dump
Change System User Interface

F1=Help F2=Refresh F3=Cancel F8=Image


F9=Shell F10=Exit Enter=Do
 
Figure 134. System Environments Panel

3. Place the cursor under Manage Language Environment, press Enter and the Manage Language
Environment panel shown in Figure 135 is displayed.

 
Manage Language Environment
Move cursor to desired item and press Enter.
Change/Show Primary Language Environment
Add Additional Language Environments
Remove Language Environments
Change/Show Language Hierarchy
Set User Languages
Change/Show Applications for a Language
Convert System Messages and Flat Files

F1=Help F2=Refresh F3=Cancel F8=Image


F9=Shell F10=Exit Enter=Dond Keyboard
 
Figure 135. Select Change/Show Primary Language Environment

4. Place the cursor under Change/Show Primary Language Environment, press Enter and the
Change/Show Cultural Convention, Language, or Keyboard panel shown in Figure 136 on page 253
is displayed.

252 Getting Started with DB2 Stored Procedures


 
Change/Show Cultural Convention, Language, or Keyboard
Type or select values in entry fields.
Press Enter AFTER making all desired changes.
[Entry Fields]
Primary CULTURAL convention ISO8859-1 C (POSIX)
Primary LANGUAGE translation ISO8859-1 C
Primary KEYBOARD ISO8859-1 C (POSIX)
INPUT device/directory for software []
EXTEND file systems if space needed? yes

F1=Help F2=Refresh F3=Cancel F4=List


Esc+5=Reset F6=Command F7=Edit F8=Image
F9=Shell F10=Exit Enter=Do
 
Figure 136. Change/Show Cultural Convention, Language, or Keyboard Panel

5. The value for the code page is in the Primary LANGUAGE translation field.

Chapter 11. CLI on DB2 Version 5 253


254 Getting Started with DB2 Stored Procedures
Chapter 12. Recoverable Resource Manager Services Attachment
Facility

An application program can use the Recoverable Resource Manager Services attachment facility
(RRSAF) to connect to DB2 to process SQL statements, commands, or instrumentation facility interface
(IFI) calls. Programs that run in MVS batch, TSO foreground, and TSO background can use RRSAF.

RRSAF uses OS/390 Transaction Management and Recoverable Resource Manager Services (OS/390
RRS). With RRSAF, you can coordinate DB2 updates with updates made by all other resource
managers that also use OS/390 RRS in an MVS system.

12.1 Prerequisite Knowledge


To use RRSAF, you need some prerequisite knowledge. You must be familiar with the following MVS
topics:
• The CALL macro and standard module linkage conventions
• Program addressing and residence options (AMODE and RMODE)
• Creating and controlling tasks, multitasking
• Functional recovery facilities such as ESTAE, ESTAI, and FRRs
• Synchronization techniques such as WAIT/POST
• OS/390 RRS functions, such as SRRCMIT and SRRBACK

12.2 Capabilities of RRSAF Applications

An application program using RRSAF can:


• Use the MVS system authorization (SAF) facility and an external security product, such as RACF, to
sign on to DB2 with the authorization ID of an end user.
• Sign on to DB2 using a new authorization ID and use an existing connection and plan.
• Access DB2 from multiple MVS tasks in an address space.
• Switch a DB2 thread among MVS tasks.
• Access the DB2 IFI.
• Run with or without the TSO terminal monitor program (TMP).
• Run without being a subtask of the DSN command processor (or of any DB2 code).
• Run above or below the 16 MB line.
• Establish an explicit connection to DB2, through a call interface, with control over the exact state of
the connection.
• Supply event control blocks (ECBs) for DB2 to post, signaling start-up or termination.
• Intercept return codes, reason codes, and abend codes from DB2 and translate them into
messages as desired.

 Copyright IBM Corp. 1996 1998 255


12.3 Task Capabilities

Any task in an address space can establish a connection to DB2 through RRSAF. The following are
some considerations related to:
• Number of connections to DB2 — You can have multiple connections to DB2 from one TCB, but only
one can be actively used at any one time. You can switch the TCB between the connections any
way you require.
• Specifying a plan for a task - Each connected task can run a plan.
• Providing attention processing exits and recovery routines - RRSAF does not generate task
structures, and it does not provide attention processing exits or functional recovery routines. You
can provide whatever attention handling and functional recovery your application needs, but you
must use ESTAE/ESTAI type recovery routines only.

12.4 Programming Languages Supported

RRSAF applications can be written in assembler language, C, COBOL, FORTRAN, and PL/I. If you use
MVS macros (ATTACH, WAIT, POST, and so on) you must choose a programming language that
supports them. The RRSAF TRANSLATE function is not available from FORTRAN. To use the function,
code it in a routine written in another language, and then call that routine from FORTRAN.

12.5 Program Size

You have to plan on estimating 10 KB to 20 KB more for your RRSAF program size. The RRSAF code
requires about 10 KB of virtual storage for each address space and an additional 10 KB for each TCB
that uses RRSAF.

12.6 RRSAF Use of Load

RRSAF uses MVS SVC LOAD to load a module as part of the initialization following your first service
request. The module is loaded into fetch-protected storage that has the job-step protection key. If
your local environment intercepts and replaces the LOAD SVC, then you must ensure that your version
of LOAD manages the load list element (LLE) and contents directory entry (CDE) chains like the
standard MVS LOAD macro

12.7 Commit and Rollback Operations

To commit work in RRSAF applications, use the CPIC SRRCMIT function or the DB2 COMMIT
statement. If you use the DB2 COMMIT statement, DB2 calls RRS to drive the two-phase commit
processing. We recommend using the CPIC function to commit your work across all other resource
managers that also use OS/390 RRS in an MVS system. The following is an example of the SRRCMIT
call in a COBOL program:
CALL ′ SRRCMIT′ USING CM-RETCODE .
To roll back work, use the CPIC SRRBACK function or the DB2 ROLLBACK statement. We recommend
that you use the CPIC SRRCMIT and SRRBACK functions. Using the CPCI SRRCMIT and SRRBACK
functions will guarantee the synchronization of all work. The following is an example of the SRRBACK
call in a COBOL program:
CALL ′ SRRBACK′ USING CM-RETCODE .

256 Getting Started with DB2 Stored Procedures


12.8 Run Environment

Applications that request DB2 services must adhere to several run environment requirements. Those
requirements must be met regardless of the attachment facility you use. They are not unique to
RRSAF. For a detail explanation of the RRSAF run environment see 6.7.1.2.4. “Run Environment,” in
DB2 for OS/390 Version 5 Application Programming and SQL Guide .

12.9 RRSAF Language Interface

To use RRSAF, you must first make available the RRSAF language interface load module, DSNRLI.
Add the following statement to your link-edit step:
INCLUDE DB2LIB(DSNRLI)
For information on loading or link-editing this module see 6.7.2.1. “Accessing the RRSAF Language
Interface” in DB2 for OS/390 Version 5 Application Programming and SQL Guide .

12.10 How to Use RRSAF


Your program uses RRSAF by issuing CALL DSNRLI statements with the appropriate options. The first
element of each option list is a function, which describes the act you want RRSAF to take. You can
use the following functions with CALL DSNRLI:
• IDENTIFY
• SIGNON
• AUTH SIGNON
• CREATE THREAD
• TERMINATE THREAD
• TERMINATE IDENTIFY
• TRANSLATE

12.10.1 IDENTIFY Function


The IDENTIFY function establishes the task as a user of the named DB2 subsystem. When the first task
within an address space issues a connection request, the address space is initialized as a user of DB2.
See ″IDENTIFY: Syntax and Usage″ in DB2 for OS/390 Version 5 Application Programming and SQL
Guide . Here is a COBOL example of this command:
CALL ′ DSNRLI′ USING IDFYFN SSNM RIBPTR EIBPTR
TERMCB STARTECB
RETCODE RSNCODE.
• IDFYN is an 18-byte area containing IDENTIFY followed by 10 blanks.
• SSNM is a 4-byte DB2 subsystem name or group attachment name (if used in a data sharing
group) to which the connection is made. If SSNM is less than four characters long, pad it on the
right with blanks to a length of four characters.
• RIBPTR is a 4-byte area in which RRSAF places the address of the release information block (RIB)
after the call. This can be used to determine the release level of the DB2 subsystem to which the
application is connected. If the RIB is not available (for example, if the specified subsystem does
not exist), RRSAF sets the 4-byte area to zeros. The area to which RIBPTR points is below the
16-MB line. This parameter is required, although the application does not need to refer to the
returned information.
• EIBPTR is a 4-byte area in which RRSAF places the address of the environment information block
(EIB) after the call. The EIB contains environment information, such as the data sharing group and
member name for the DB2 to which the IDENTIFY request was issued. If the DB2 subsystem is not

Chapter 12. Recoverable Resource Manager Services Attachment Facility 257


in a data sharing group, RRSAF sets the data sharing group and member names to blanks. If the
EIB is not available (for example, if SSNM specifies a subsystem that does not exist), RRSAF sets
the 4-byte area to zeros. The area to which EIBPTR points is above the 16-MB line. This
parameter is required, although the application does not need to refer to the returned information.
• TERMCB is the address of the application′s event control block (ECB) used for DB2 termination.
DB2 posts this ECB when the system operator enters the command STOP DB2 or when DB2 is
terminating abnormally. Specify a value of 0 if you do not want to use a termination ECB. RRSAF
puts a POST code in the ECB to indicate the type of termination, as shown in Table 18.

Table 18. POST Codes for Types of DB2 Termination


POST code Termination type
8 QUIESCE
12 FORCE
16 ABTERM

• STARTECB is the address of the application′s startup ECB. If DB2 has not started when the
application issues the IDENTIFY call, DB2 posts the ECB when DB2 startup has completed. Enter a
value of zero if you do not want to use a startup ECB. DB2 posts a maximum of one startup ECB in
an address space. The ECB posted is associated with the most recent IDENTIFY call from that
address space. The application program must examine any nonzero RRSAF or DB2 reason codes
before issuing a WAIT on this ECB. If SSNM is a group attachment name, DB2 ignores the startup
ECB.
• RETCODE is a 4-byte area in which RRSAF places the return code. This parameter is optional. If
you do not specify this parameter, RRSAF places the return code in register 15 and the reason
code in register 0.
• RSNCODE is a 4-byte area in which RRSAF places a reason code. This parameter is optional. If
you do not specify this parameter, RRSAF places the reason code in register 0. If you specify this
parameter, you must also specify RETCODE.

12.10.2 SIGNON Function


The SIGNON function provides to DB2 a user ID and, optionally, one or more secondary authorization
IDs that are associated with the connection. See “SIGNON: Syntax and Usage” in DB2 for OS/390
Version 5 Application Programming and SQL Guide . Here is a COBOL example of this command:
CALL ′ DSNRLI′ USING SIGNONFN CORRID
ACCTTKN ACCTINT
RETCODE RSNCODE.
• SIGNONFN is an 18-byte area containing SIGNON followed by twelve blanks.
• CORRID is the correlation ID displayed in DB2 accounting and statistics trace records. You can
use the correlation ID to correlate units of work. This token appears in the output of the DB2
DISPLAY THREAD command. If you do not want to specify a correlation ID, fill the 12-byte area
with blanks.
• ACCTTKN is a 22-byte area in which you can put a value for a DB2 accounting token. This value is
displayed in the DB2 accounting and statistics trace records. If you do not want to specify an
accounting token, fill the 22-byte area with blanks.
• ACCTINT is a 6-byte area with which you can control when DB2 writes an accounting record. If you
specify COMMIT in that area, DB2 writes an accounting record each time the application issues
SRRCMIT. If you specify any other value, DB2 writes an accounting record when the application
terminates or when you call SIGNON with a new authorization ID.

258 Getting Started with DB2 Stored Procedures


12.10.3 AUTH SIGNON Function
The AUTH SIGNON function provides to DB2 a user ID, an accessor environment element (ACEE) and,
optionally, one or more secondary authorization IDs that are associated with the connection. See
“AUTH SIGNON: Syntax and Usage” in DB2 for OS/390 Version 5 Application Programming and SQL
Guide . Here is a COBOL example of this command:
CALL ′ DSNRLI′ USING ASGNONFN CORRID ACCTTKN ACCTINT PAUTHID
ACEEPTR SAUTHID
RETCODE RSNCODE.
• ASGNONFN is an 18-byte area containing AUTH SIGNON followed by seven blanks.
• PAUTHID is an 8-byte area in which you can put a primary authorization ID. If you are not passing
the authorization ID to DB2 explicitly, put X′00′ or a blank in the first byte of the area.
• ACEEPTR is the 4-byte address of an ACEE that you pass to DB2. If you do not want to provide an
ACEE, specify 0 in this field.
• SAUTHID is an 8-byte area in which you can specify a secondary authorization ID. If you do not
pass the authorization ID to DB2 explicitly, put X′00′ or a blank in the first byte of the area. If you
enter a secondary authorization ID, you must also enter a primary authorization ID.

12.10.4 CREATE THREAD Function


The CREATE THREAD function allocates a DB2 plan or package. The CREATE THREAD function must
complete before the application can execute SQL statements. See “CREATE THREAD: Syntax and
Usage” in DB2 for OS/390 Version 5 Application Programming and SQL Guide . Here is a COBOL
example of this command:
CALL ′ DSNRLI′ USING CRTHRDFN PLAN COLLID REUSE
RETCODE RSNCODE.
• CRTHRDFN is an 18-byte area containing CREATE THREAD followed by five blanks.
• PLAN is an 8-byte area where you specify the DB2 plan name. If you provide a collection name
instead of a plan name, specify the character ? in the first byte of this field. DB2 then allocates a
special plan named ?RRSAF and uses the collection parameter. If you do not provide a collection
name in the collection field, you must enter a valid plan name in this field.
• REUSE is an 8-byte area that controls the action DB2 takes if a SIGNON call is issued after a
CREATE THREAD call. Specify either of these values in this field:
− RESET - to release any held cursors and reinitialize the special registers
− INITIAL - to disallow the SIGNON
This parameter is required. If the 8-byte area does not contain either RESET or INITIAL, then the
default value is INITIAL.

12.10.5 TERMINATE THREAD Function


The TERMINATE THREAD function deallocates the plan. See “TERMINATE THREAD: Syntax and Usage”
in DB2 for OS/390 Version 5 Application Programming and SQL Guide . Here is a COBOL example of
this command:
CALL ′ DSNRLI′ USING TRMTHDFN
RETCODE RSNCODE.
• TRMTHDFN is an 18-byte area containing TERMINATE THREAD followed by two blanks.

Chapter 12. Recoverable Resource Manager Services Attachment Facility 259


12.10.6 TERMINATE IDENTIFY Function
The TERMINATE IDENTIFY function removes the task as a user of DB2 and, if this is the last or only
task in the address space that has a DB2 connection, terminates the address space connection to DB2.
See “TERMINATE IDENTIFY: Syntax and Usage” in DB2 for OS/390 Version 5 Application Programming
and SQL Guide . Here is a COBOL example of this command:
CALL ′ DSNRLI′ USING TMIDFYFN
RETCODE RSNCODE.
• TMIDFYFN is an 18-byte area containing TERMINATE IDENTIFY.

12.10.7 TRANSLATE Function


The TRANSLATE function returns an SQL code and printable text in the SQLCA, describing a DB2 error
reason code. You cannot call the TRANSLATE function from the FORTRAN language. See
“TRANSLATE: Syntax and Usage” in DB2 for OS/390 Version 5 Application Programming and SQL
Guide . Here is a COBOL example of this command:
CALL ′ DSNRLI′ USING XLATFN SQLCA
RETCODE RSNCODE.
• XLATFN is an 18-byte area containing the word TRANSLATE followed by nine blanks.
• SQLCA is the program′s SQLCA.

12.11 Sample JCL to Use RRSAF


Use the sample JCL that follows as a model for using RRSAF in a batch environment. The DD
statement for DSNRRSAF starts the RRSAF trace. Use that DD statement only if you are diagnosing a
problem. The sample is as follows:
//jobname JOB MVS_jobcard_information
//RRSJCL EXEC PGM=RRS_application_program
//STEPLIB DD DSN=application_load_library
DD DSN=DB2_load_library
.
.
//SYSPRINT DD SYSOUT=*
//DSNRRSAF DD DUMMY
//SYSUDUMP DD SYSOUT=*

12.12 Sample Program RRSAFCOB

Included in the sample programs is RRSAFCOB. RRSAFCOB uses RRSAF to coordinate the updates
between DB2 Version 5 and IMS Version 6. It uses APPC to start a conversation with an IMS Version 6
IVP transaction. It updates a DB2 Version 5 table. The logic is provided in the documentation on how
to call a DB2 Version 5 WLM DB2 stored procedure.

Working storage information related to RRSAF is as follows:


• A switch, RRSAF-SWITCH, is set up to coordinate the successful completions of each update to a
RRS data resource. Before the updates, this switch is set to commit.
• After each update, this switch is set to rollback if there were any errors during this process.
• After all the RRS data resources are updated, this switch is checked to see if all of the work should
be committed or rolled back.
• Variables are defined to be used when calling DSNRLI. The RRS-INPUT variables are set up to hold
the RRSAF services constants, variables set by DB2, and variables set by the application.

260 Getting Started with DB2 Stored Procedures


The following is the program logic:
1. The program logic calls DSNRLI with the IDENTIFY function to identify to RRS that the program is a
user of the DB2 subsystem DBC1. The DB2 subsystem name is passed in the SSNM variable.
IDENTIFY establishes the caller′s task as a user of DB2 services. IDENTIFY also initializes the
address space to communicate with the DB2 address spaces. During IDENTIFY processing, DB2
determines whether the user address space is authorized to connect to DB2. DB2 invokes the MVS
SAF and passes a primary authorization ID to SAF. That authorization ID is the 7-byte user ID
associated with the address space.
2. DSNRLI is called with the SIGNON function. SIGNON causes a new primary authorization ID and
optional secondary authorization IDs to be assigned to a connection. Since CORRID is set to
spaces, the 7-byte user ID associated with the address space is used. If you need to change the
primary authorization ID you must issue the external security interface macro RACROUTE
REQUEST=VERIFY to do the following:
• Define and populate an ACEE to identify the user of the program.
• Associate the ACEE with the user′s TCB.
• Verify that the user is defined to RACF and authorized to use the application.
3. DSNRLI is called with the CREATE THREAD function. CREATE THREAD allocates the DB2
resources required to issue SQL or IFI requests. Since the program passes to RRSAF a PLAN
name in variable PLAN, RRSAF allocates the RRSAFCOB plan.
4. You can now issue SQL commands to the DBC1 subsystem.
5. To commit the work in RRSAF the program uses the CPIC SRRCMIT function. To roll back the
work, the program uses the CPIC SRRBACK function.

At task termination DB2 deallocates the plan, terminates the application′s connection to DBC1, and
OS/390 RRS commits any changes made after the last commit point. This is because RRSAFCOB ends
with no TERMINATE THREAD or TERMINATE IDENTIFY functions to deallocate the plan during the
execution of the program.

The following is a sample RRSAFCOB program:


***************************************************************
* INCLUDE THE APPC CPI-COMMUNICATIONS PSEUDONYM FILE. *
***************************************************************
COPY CMCOBOL.
COPY SRRCOBOL.

01 SWITCHES.
05 RRSAF-SWITCH PIC X.
88 RRSAF-COMMIT VALUE SPACE.
88 RRSAF-ROLLBACK VALUE ′ R′ .
*
* INPUT FOR THE RRS/AF CALL
*
01 RRS-INPUT.
* RRSAF services constants
05 IDFYFN PIC X(18) VALUE ′ IDENTIFY ′.
05 SIGNONFN PIC X(18) VALUE ′ SIGNON ′.
05 CRTHRDFN PIC X(18) VALUE ′ CREATE THREAD ′.
05 TRMTHDFN PIC X(18) VALUE ′ TERMINATE THREAD ′ .
05 TMIDFYFN PIC X(18) VALUE ′ TERMINATE IDENTIFY′ .

* RRSAF Variables set by Application


05 SSNM PIC X(4) VALUE ′ DBC1′ .
05 PLAN PIC X(8) VALUE ′ RRSAFCOB′ .

Chapter 12. Recoverable Resource Manager Services Attachment Facility 261


05 CORRID PIC X(12) VALUE SPACES.
05 COLLID PIC X(18) VALUE SPACES.
05 ACCTTKN PIC X(22) VALUE SPACES.
05 ACCTINT PIC X(6) VALUE SPACES.
05 REUSE PIC X(8) VALUE SPACES.

* RRSAF Variables set by DB2


05 RIBPTR PIC X(4) VALUE SPACES.
05 EIBPTR PIC X(4) VALUE SPACES.
05 TERMCB PIC X(4) VALUE ′0′.
05 STARTECB PIC X(4) VALUE ′0′.
05 RETCODE PIC 9(8) COMP.
05 RSNCODE PIC 9(8) COMP.

PROCEDURE DIVISION.
*************
* CALL RRS/AF FOR IDENTIFY FUNCTION
*************
DISPLAY ′ *** RRS/AF IDENTIFY′ .
CALL ′ DSNRLI′ USING IDFYFN SSNM RIBPTR EIBPTR
TERMCB STARTECB
RETCODE RSNCODE.
PERFORM RRSAF-RETCODE-CHK THRU RRSAF-RETCODE-CHK-EXIT.
************
* CALL RRS/AF FOR SIGNON FUNCTION
************
DISPLAY ′ *** RRS/AF SIGNON ′ .
CALL ′ DSNRLI′ USING SIGNONFN CORRID
ACCTTKN ACCTINT
RETCODE RSNCODE.
PERFORM RRSAF-RETCODE-CHK THRU RRSAF-RETCODE-CHK-EXIT.
************
* CALL RRS/AF FOR CREATE THREAD FUNCTION
************
DISPLAY ′ *** RRS/AF CREATE THREAD′ .
CALL ′ DSNRLI′ USING CRTHRDFN PLAN
COLLID REUSE
RETCODE RSNCODE.
PERFORM RRSAF-RETCODE-CHK THRU RRSAF-RETCODE-CHK-EXIT.
************
* PROCESS TRANSACTIONS
************
SET RRSAF-COMMIT TO TRUE.
............
............ update any resource managers that can use
............ the OS/390 RRS.
............
............ Update a DB2 V5 table.
............
............ EXEC SQL INSERT INTO TRAN_LOG
............ (IMSTRAN, IMSDATA)
............ VALUES(:IMSTRAN, :IMSDATA)
............ end-exec.
............
............ call a DB2 V5 WLM Stored Procedure
............
............ EXEC SQL CALL :STORED-PROCEDURE
............ (:IMS-TRAN, :IMSDATA, :STPC-RC)
............ END-EXEC.

262 Getting Started with DB2 Stored Procedures


............
............ Use APPC to start a conversation with a
............ IMS V6 transaction.
............
* IF ALL UPDATES OK COMMIT WORK ELSE ROLLBACK
* THE OTHER UPDATES.
*
IF RRSAF-ROLLBACK
PERFORM RRSAF-ROLLBACK-RT
ELSE
PERFORM RRSAF-COMMIT-RT.
PROG-END.
STOP RUN.

*******************
* Rollback all resource managers′ data
*******************
RRSAF-ROLLBACK.
CALL ′ SRRBACK′ USING CM-RETCODE .
*******************
* Commit all resource managers′ data
*******************
RRSAF-COMMIT.
CALL ′ SRRCMIT′ USING CM-RETCODE .
DELIMITED BY SIZE INTO MSG-LINE-1.

12.13 Common RRSAF Errors

The following are some common RRSAF error return codes. The error codes cover not having the
RRS address space running, having an invalid DB2 subsystem name, and an invalid plan name.

12.13.1 IDENTIFY Return Code 8 Reason Code 15925393


When the RRS address space is not running, you get a return code 8 from the IDENTIFY function. The
reason code returned is 15925393.
-JOBNAME STEPNAME PROCSTEP RC EXCP CPU SRB CLOCK SERV P
-RRSBMEX STEP01 08 67 .00 .00 .0 2201

PROGRAM ***RRSAFCOB*** STARTED


*** RRS/AF IDENTIFY
RRSAF ERROR, RETCODE = 00000008 RSNCODE = 15925393

12.13.2 IDENTIFY Return Code 8 Reason Code 15925250


When the DB2 subsystem address space is not running, you get a return code 8 from the IDENTIFY
function. The reason code returned is 15925250.
-JOBNAME STEPNAME PROCSTEP RC EXCP CPU SRB CLOCK SERV P
-RRSBMEX STEP01 08 67 .00 .00 .0 2201

PROGRAM ***RRSAFCOB*** STARTED


*** RRS/AF IDENTIFY
RRSAF ERROR, RETCODE = 00000008 RSNCODE = 15925250

Chapter 12. Recoverable Resource Manager Services Attachment Facility 263


12.13.3 IDENTIFY Return Code 12
When the SSNM variable has an invalid DB2 subsystem name, a return code 12 is returned from the
IDENTIFY function. The reason code returned is 1592554.

-JOBNAME STEPNAME PROCSTEP RC EXCP CPU SRB CLOCK SERV


-RRSBMEX STEP01 12 67 .00 .00 .0 1993

PROGRAM ***RRSAFCOB*** STARTED


*** RRS/AF IDENTIFY
RRSAF ERROR, RETCODE = 00000012 RSNCODE = 15925254

12.13.4 CREATE THREAD Return Code 12


When the PLAN variable has an invalid DB2 plan name, a return code 12 is returned from the CREATE
THREAD function. The reason code returned is 1592312.

-JOBNAME STEPNAME PROCSTEP RC EXCP CPU SRB CLOCK SERV PG


-RRSBMEX STEP01 12 67 .00 .00 .0 2417 0

PROGRAM ***RRSAFCOB*** STARTED


*** RRS/AF IDENTIFY
*** RRS/AF SIGNON
*** RRS/AF CREATE THREAD
RRSAF ERROR, RETCODE = 00000012 RSNCODE = 15925312

264 Getting Started with DB2 Stored Procedures


Chapter 13. Accessing Non-DB2 Resources

You can access non-DB2 resources, such as VSAM files, flat files, and CICS transactions, from a stored
procedure. The non-DB2 resource must be available to the stored procedures address space. Thus if
you are accessing VSAM files or flat files, you need a JCL DD statement in the stored procedures
address space JCL procedure for every file that the stored procedure accesses.

Not all non-DB2 resources can be accessed concurrently by multiple tasks in the same address space.
Thus you may have to serialize the access to the non-DB2 resource in the stored procedure. You can
use a WLM-established stored procedures address space just for this purpose by setting the
NUMTCB=1 in the JCL to start the stored procedure and specifying to WLM to start only one address
space.

For the DB2-established address space, when accessing non-DB2 resources that are RACF protected,
the user ID associated with the stored procedures address space is used to check authorizations. The
user ID associated with the client program is not used to check authorizations because the MVS
system is not aware that the stored procedures address space is processing work on behalf of the
client program.

For WLM-established address space, when accessing non-DB2 resources that are RACF protected, the
user ID associated with the stored procedures address space or the user ID associated with the client
application is used to check authorizations, depending on what you specify for the
EXTERNAL_SECURITY column of SYSIBM.SYSPROCEDURES.

13.1 Accessing CICS Systems

Stored procedures can access CICS systems by using one of these methods:
• Message Queue Interface (MQI)
• External CICS Interface (EXCI)
• APPC

MQI calls are used for asynchronous execution of CICS transactions, and EXCI calls are used for
synchronous execution of CICS transactions.

When accessing CICS transactions, DB2 Version 4 does not coordinate commit and rollback activity.
The CICS transaction runs as a separate unit of work. For example, if the CICS transaction rolls back
its unit of work, the stored procedure unit of work is not automatically rolled back and can be
committed without problems.

The current release of CICS does not support RRS. DB2 Version 5 supports RRS, so you can get
coordination between a DB2 WLM-established stored procedure and CICS by using CICS′s LU 6.2
support. This can be done using an APPC transaction to invoke the CICS transaction. CICS supports
SYNCLVL=SYNCPT conversations, so when the outbound APPC transaction does the SRRCMIT, an LU
6.2 network flows to the inbound CICS transaction to commit the transaction. So while there are two
commit coordinators (RRS and CICS), it was still a coordinated two-phase commit transaction, because
APPC is the distributed synch point manager. You must use APPC as the distributed synch point
manager because CICS doesn′t register with RRS.

During our project, we tested only the EXCI calls. Below we briefly describe how to code EXCI calls
within a stored procedure.

 Copyright IBM Corp. 1996 1998 265


13.2 Using EXCI in a Stored Procedure

The EXCI is a programming interface that enables a non-CICS program (including stored procedures)
to call a program running in a CICS/ESA Version 4.1 region and pass and receive data by means of a
communication area (COMMAREA). The EXCI provides two types of programming interfaces: the EXCI
CALL interface and the EXEC CICS interface.

The EXCI CALL interface consists of six commands that are used to allocate and open sessions to a
CICS system, issue requests on these sessions, close, and deallocate the sessions.

The EXEC CICS interface provides a single command, the EXEC CICS LINK PROGRAM command, that
performs all six commands of the EXCI CALL interface in one invocation. You can choose both the
EXEC CICS interface and the EXCI CALL interface to call CICS programs from a stored procedure.

For more information about EXCI, refer to the External CICS Interface Manual .

13.2.1 Sample Stored Procedure


The following is a COBOL example stored procedure that calls a CICS program through the EXEC CICS
interface:
CBL XOPTS(EXCI,COBOL2)
Identification Division.
Program-ID. ″XC0BMS″ .
*****************************************************
* This stored procedure shows how to invoke *
* an CICS program using the External Call Interface.*
*****************************************************
Data Division.
Working-Storage Section.
exec sql include sqlca end-exec.
*==============================================================*
* Declare Call level,DPL, and EXEC level Return Code areas. *
*==============================================================*
COPY DFHXCPLO.
*==============================================================*
* Initialize Target information variables. *
*==============================================================*
01 TARGET-PROGRAM PIC X(8) VALUE ′ BOUNCE ′ .
01 TARGET-TRANSID PIC X(4) VALUE ′ EXCI′ .
01 TARGET-SYSTEM.
05 TARGET-SYS-ELEM PIC X OCCURS 8 TIMES.
*==============================================================*
* Define Commarea struct. *
*==============================================================*
01 COMMAREA.
05 FILE-NAME PIC X(6) VALUE SPACES.
*==============================================================*
* Initialize Commarea length and Data length(in bytes). *
*==============================================================*
01 COMM-LENGTH PIC S9(8) COMP VALUE 6.
01 DATA-LENGTH PIC S9(8) COMP VALUE 6.
01 LINK-COM-LEN PIC S9(4) COMP VALUE 6.
01 LINK-DAT-LEN PIC S9(4) COMP VALUE 6.
*==============================================================*
LINKAGE SECTION.
01 PARM1 PIC X(8).
01 PARM2 PIC X(6).

266 Getting Started with DB2 Stored Procedures


01 EXEC-LEVEL-MSG.
05 EXEC-LEVEL-MSG-TEXT PIC X OCCURS 128 TIMES.

Procedure Division USING PARM1, PARM2.


*==============================================================*
* The PARM1 stored procedure parameter contains the CICS system ID
* where the called CICS program resides
*==============================================================*
MOVE PARM1 TO TARGET-SYSTEM.
*==============================================================*
* *
* This section will use an EXEC level EXCI call *
* to invoke the program BOUNCE on the target *
* CICS system. *
* *
*==============================================================*
* Perform the Link Request;
EXEC CICS LINK PROGRAM(TARGET-PROGRAM)
TRANSID(TARGET-TRANSID)
APPLID(TARGET-SYSTEM)
COMMAREA(COMMAREA)
LENGTH(LINK-COM-LEN)
DATALENGTH(LINK-DAT-LEN)
RETCODE(EXCI-EXEC-RETURN-CODE)
SYNCONRETURN
END-EXEC.
IF EXEC-RESP IS EQUAL TO ZERO THEN
MOVE COMMAREA TO PARM2
EXEC SQL INSERT INTO STDRD2A.TESTE VALUES(:PARM2)
END-EXEC
ELSE
SET ADDRESS OF EXEC-LEVEL-MSG TO EXEC-MSG-PTR.
Error-Exit.
goback.

The called CICS program is named BOUNCE. It is a simple test program that receives the
COMMAREA sent by the stored procedure and returns the value BOUNCE to the stored procedure.

13.2.2 Program Preparation for EXCI


The following is the JCL used to prepare the stored procedure in DB2 Version 4.
//XCITCL JOB (999,POK),′ CICSUSR′ , NOTIFY=&SYSUID,
// CLASS=A,MSGCLASS=T,REGION=6M,MSGLEVEL=(1,1)
//PC EXEC PGM=DSNHPC,PARM=′ HOST(COB2)′ , REGION=4096K
//DBRMLIB DD DISP=OLD,DSN=DSN410.DBRMLIB.DATA(XC0BMS)
//STEPLIB DD DISP=SHR,DSN=DSN410.SDSNEXIT
// DD DISP=SHR,DSN=DSN410.SDSNLOAD
//SYSIN DD DSN=HUGHSMT.COBOL.SOURCE(XC0BMS),
// DISP=SHR
//SYSCIN DD DSN=&&DSNHOUT,DISP=(MOD,PASS),UNIT=SYSDA,
// SPACE=(800,(500,500))
//SYSLIB DD DISP=SHR,DSN=DSN410.SRCLIB.DATA
// DD DISP=SHR,DSN=SYS1.CEE.V1R5M0.SCEERUN
//SYSPRINT DD SYSOUT=*
//SYSTERM DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSUT1 DD SPACE=(800,(500,500),,,ROUND),UNIT=SYSDA

Chapter 13. Accessing Non-DB2 Resources 267


//SYSUT2 DD SPACE=(800,(500,500),,,ROUND),UNIT=SYSDA
//STLYXTVL PROC SUFFIX=1$, SUFFIX FOR TRANSLATOR MODULE
// INDEX=′ CICS.V4R1M0′ , Qualifier(s) for CICS libraries
// PROGLIB=′ CICS.V4R1M0.EXCI.LOADLIB′ , Name of output library
// DSCTLIB=′ CICS.V4R1M0.SDFHCOB′ , Name of private macro/DSECT lib
// AD370HLQ=′ IGY.V1R2M0′ , Qualifier(s) for AD/Cycle compiler
// LE370HLQ=′ CEE.V1R5M0′ , Qualifier(s) for LE/370 libraries
// OUTC=A, Class for print output
// REG=2M, Region size for all steps
// LNKPARM=′ AMODE(31),RMODE(ANY),LIST,XREF′ ,
//* Link edit parameters
// TRNPARM=′ COBOL2′ ,
//* Link edit parameters
// WORK=SYSDA Unit for work datasets
//*
//* This procedure is used to translate,compile and link-edit
//* batch application programs using the external CICS
//* interface (EXCI).
//TRN EXEC PGM=DFHECP&SUFFIX,
// PARM=&TRNPARM,
// REGION=&REG
//STEPLIB DD DSN=&INDEX..SDFHLOAD,DISP=SHR
//SYSPRINT DD SYSOUT=&OUTC
//SYSPUNCH DD DSN=&&SYSCIN,
// DISP=(,PASS),UNIT=&WORK,
// DCB=BLKSIZE=400,
// SPACE=(400,(400,100))
//*
//COB EXEC PGM=IGYCRCTL,REGION=&REG,
// PARM=′ NODYNAM,LIB,OBJECT,RENT,RES,APOST,MAP,XREF′
//STEPLIB DD DSN=&AD370HLQ..SIGYCOMP,DISP=SHR
//SYSLIB DD DSN=&DSCTLIB,DISP=SHR
// DD DSN=&INDEX..SDFHCOB,DISP=SHR
// DD DSN=&INDEX..SDFHMAC,DISP=SHR
// DD DSN=&INDEX..SDFHSAMP,DISP=SHR
//SYSPRINT DD SYSOUT=&OUTC
//SYSIN DD DSN=&&SYSCIN,DISP=(OLD,DELETE)
//SYSLIN DD DSN=&&LOADSET,DISP=(MOD,PASS),
// UNIT=&WORK,SPACE=(80,(250,100))
//SYSUT1 DD UNIT=&WORK,SPACE=(460,(350,100))
//SYSUT2 DD UNIT=&WORK,SPACE=(460,(350,100))
//SYSUT3 DD UNIT=&WORK,SPACE=(460,(350,100))
//SYSUT4 DD UNIT=&WORK,SPACE=(460,(350,100))
//SYSUT5 DD UNIT=&WORK,SPACE=(460,(350,100))
//SYSUT6 DD UNIT=&WORK,SPACE=(460,(350,100))
//SYSUT7 DD UNIT=&WORK,SPACE=(460,(350,100))
//*
//COPYLINK EXEC PGM=IEBGENER,COND=(7,LT,COB)
//SYSUT1 DD DSN=&INDEX..SDFHMAC(DFHEXLI),DISP=SHR
//SYSUT2 DD DSN=&&COPYLINK,DISP=(NEW,PASS),
// DCB=(LRECL=80,BLKSIZE=400,RECFM=FB),
// UNIT=&WORK,SPACE=(400,(20,20))
//SYSPRINT DD SYSOUT=&OUTC
//SYSIN DD DUMMY
//*
//LKED EXEC PGM=IEWL,REGION=&REG,
// PARM=&LNKPARM,COND=(5,LT,COB)
//SYSLIB DD DSN=&INDEX..SDFHEXCI,DISP=SHR
// DD DSN=&LE370HLQ..SCEELKED,DISP=SHR

268 Getting Started with DB2 Stored Procedures


//SYSLMOD DD DSN=&PROGLIB,DISP=SHR
//SYSUT1 DD UNIT=&WORK,DCB=BLKSIZE=1024,
// SPACE=(1024,(200,20))
//SYSPRINT DD SYSOUT=&OUTC
//SYSLIN DD DSN=&&COPYLINK,DISP=(OLD,DELETE)
// DD DSN=&&LOADSET,DISP=(OLD,DELETE)
// DD DDNAME=SYSIN
// PEND
//*
//APPLPROG EXEC STLYXTVL,TRNPARM=(EXCI,COBOL2),
// PARM.COB=(QUOTE,LIST,RENT,TEST,LIB),
// LNKPARM=(′ XREF,LIST,MAP,LET,AMODE=31,RMODE=ANY′ ) ,
// PROGLIB=′ DSN410.RUNLIB.LOAD′ ,
// INDEX=′ CICS.V4R1M0′
//COB.SYSPRINT DD DSN=DSN410.CODE.LISTING,DISP=SHR
//TRN.SYSIN DD DSN=&&DSNHOUT,DISP=(OLD,DELETE)
//LKED.SYSLIB DD
// DD
// DD DSN=DSN410.SDSNLOAD,DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNALI)
NAME XC0BMS(R)
//*
//STEP3 EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)
//STEPLIB DD DISP=SHR,DSN=DSN410.SDSNEXIT
// DD DISP=SHR,DSN=DSN410.SDSNLOAD
//DBRMLIB DD DSN=DSN410.DBRMLIB.DATA,DISP=SHR
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//REPORT DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DB41)
BIND PACKAGE(CENTDB2.XC0BMS) MEMBER(XC0BMS) -
LIBRARY(′ DSN410.DBRMLIB.DATA′ ) -
ACT(REP) ISOLATION(CS) VALIDATE(BIND)
END
//

We used the sample STLYXTVL procedure to prepare the batch program with EXCI calls. We included
steps for the DB2 precompiler and bind. For this JCL sample we used STLYXTVL as an in-stream
procedure.

You also have to include the CICS load library, CICS.V4R1M0.SDFHEXCI, in the STEPLIB DD statement
of the stored procedures address space JCL procedure.

13.2.3 CICS Table Definitions


Some definitions on CICS tables are required to issue EXCI calls. Refer to the External CICS Interface
Manual and the Resource Definition Guide for information about how to customize your environment for
EXCI. Some EXCI samples are provided with CICS V4.1, and you can use them to ensure that your
EXCI environment is working.

We used these definitions for the connection, sessions, program, and transaction:

Connection

Chapter 13. Accessing Non-DB2 Resources 269


Connection : XCIG
Group : EXCI
DEscription :
CONNECTION IDENTIFIERS
Netname :
INDsys :
REMOTE ATTRIBUTES
REMOTESYSTem :
REMOTEName :
REMOTESYSNet :
CONNECTION PROPERTIES
ACcessmethod : IRc Vtam | IRc | INdirect | Xm
PRotocol : Exci Appc | Lu61 | Exci
Conntype : Generic Generic | Specific
SInglesess : No No | Yes
DAtastream : User User | 3270 | SCs | STrfield | Lms
RECordformat : U U | Vb
Queuelimit : No No | 0-9999
Maxqtime : No No | 0-9999
OPERATIONAL PROPERTIES
AUtoconnect : No No | Yes | All
INService : Yes Yes | No
SECURITY
SEcurityname :
ATtachsec : Local Local | Identify | Verify | Persist
| Mixidpe
BINDPassword : PASSWORD NOT SPECIFIED
BINDSecurity : No No | Yes
Usedfltuser : No No | Yes
RECOVERY
PSrecovery : Sysdefault | None

Sessions
Sessions : XCIGSESS
Group : EXCI
DEscription :
SESSION IDENTIFIERS
Connection : XCIG
SESSName :
NETnameq :
MOdename :
SESSION PROPERTIES
Protocol : Exci Appc | Lu61 | Exci
MAximum : 000 , 000 0-999
RECEIVEPfx : XG
RECEIVECount : 005 1-999
SENDPfx :
SENDCount : 1-999
SENDSize : 04096 1-30720
RECEIVESize : 04096 1-30720
SESSPriority : 000 0-255
Transaction :
OPERATOR DEFAULTS
OPERId :
OPERPriority : 000 0-255
OPERRsl : 0
OPERSecurity : 1
PRESET SECURITY
USERId :

270 Getting Started with DB2 Stored Procedures


OPERATIONAL PROPERTIES
Autoconnect : No No | Yes | All
INservice : Yes
Buildchain : Yes Yes | No
USERArealen : 000 0-255
IOarealen : 04096 , 04096 0-32767
RELreq : No No | Yes
DIscreq : No No | Yes
NEPclass : 000 0-255
RECOVERY
RECOVOption : Sysdefault Sysdefault | Clearconv | Releaseses
| Uncondrel | None
RECOVNotify : None None | Message | Transaction

Program
PROGram : BOUNCE
Group : HUGHPRG
DEscription :
Language : CObol | Assembler | Le370 | C | Pli
| Rpg
RELoad : No No | Yes
RESident : No No | Yes
USAge : Normal Normal | Transient
USElpacopy : No No | Yes
Status : Enabled Enabled | Disabled
RSl : 00 0-24 | Public
Cedf : Yes Yes | No
DAtalocation : Below Below | Any
EXECKey : User User | Cics
REMOTE ATTRIBUTES
REMOTESystem :
REMOTEName :
Transid :
EXECUtionset : Fullapi Fullapi | Dplsubset

Transaction
TRANSaction : EXCI
Group : DFH$EXCI
DEscription :
PROGram : DFHMIRS
TWasize : 00000 0-32767
PROFile : DFHCICSA
PArtitionset :
STAtus : Enabled Enabled | Disabled
PRIMedsize : 00000 0-65520
TASKDATALoc : Below Below | Any
TASKDATAKey : User User | Cics
STOrageclear : No No | Yes
RUnaway : System System | 0-2700000
SHutdown : Disabled Disabled | Enabled
ISolate : Yes Yes | No
REMOTE ATTRIBUTES
DYnamic : No No | Yes
REMOTESystem :
REMOTEName :
TRProf :
Localq : No | Yes
SCHEDULING

Chapter 13. Accessing Non-DB2 Resources 271


PRIOrity : 001 0-255
TClass : No No | 1-10
TRANClass : DFHTCL00
ALIASES
Alias :
TASKReq :
XTRanid :
TPName :
:
XTPname :
:
:
RECOVERY
DTimout : 0010 No | 1-6800
INdoubt : Backout Backout | Commit | Wait
RESTart : No No | Yes
SPurge : Yes No | Yes
TPUrge : Yes No | Yes
DUmp : Yes Yes | No
TRACe : Yes Yes | No
COnfdata : No No | Yes
SECURITY
RESSec : No No | Yes
CMdsec : No No | Yes
Extsec : No
TRANSec : 01 1-64
RSl : 00 0-24 | Public

13.3 Accessing IMS Databases

Because IMS does not support multiple TCBs for batch processing and requires that the IMS region
controller be the module in control, you cannot access IMS databases directly from the stored
procedures address spaces using the batch region facility.

There are several ways that you can access IMS databases:
• Using the new database resource adapter (DRA) callable interface.
• Including APPC code in the stored procedure. An IMS or CICS transaction can be invoked by
APPC.
• Using the MQI interface to access CICS transaction.
• Using the EXCI interface as described in 13.2, “Using EXCI in a Stored Procedure” on page 266
• Using the MQI interface to place a transaction on the IMS message queue.
Depending on the method and the level of product you use you have different flavors of:
• Commitment control
• Complexity of the code
• Performance

Once you have accessed IMS databases, you can pass IMS information through output parameters, or
you can insert information obtained from IMS databases in a global temporary table, and pass this
information to the client application using multiple result sets.

In this section, we describe some of these methods.

272 Getting Started with DB2 Stored Procedures


13.3.1 Using Database Resource Adapter Callable Interface
The IMS-supplied DRA-callable interface is a facility available in IMS Version 6 as an APAR. The
DRA-callable interface allows an OS/390 application execution environment (AEE), such as a stored
procedures address space, access to IMS database through the IMS database control system (DBCTL).
A stored procedure has access to the IMS database using DRA connecting to DBCTL in a CICS
environment, and connecting to the IMS control region in an IMS TM environment. Because in an IMS
TM environment, DBCTL services are provided in the IMS control region, any reference in this redbook
to DBCTL applies to stand-alone DBCTL, or to the DBCTL services available in the IMS control region

As illustrated in Figure 137, the architecture of DRA, the callable interface resides in the DB2 stored
procedures address space, and is recognized by IMS as an application execution region (AER).

Figure 137. DRA Architecture

Using the DRA-callable interface the stored procedure can access to full-function DL/I data bases and
Fast Path data entry databases (DEDB). The DRA-callable interface allows DBCTL and OS/390
application programs, such as stored procedures, to be developed, installed, and maintained
independent of each other.

The IMS DRA-callable interface provides new modules packaged with the existing IMS Version 6 DRA
modules to support the new callable interface to DBCTL.

Although DRA uses a TCB in the stored procedures address space, you don′t have to account for this
TCB when specifying the NUMTCB parameters passed to the stored procedures address space during
initialization.

Chapter 13. Accessing Non-DB2 Resources 273


Because the interface requires OS/390 RRS, you can use the interface only in the WLM-established
address space. Note that OS/390 R3 or later is required, due to RRS. As a consequence, the
minimum level of DB2 that allows you to use the new DRA-callable interface is DB2 Version 5.
Because DB2 Version 4 supports only the DB2-established address space, you cannot access an IMS
database using the DRA-callable interface with DB2 Version 4.

You cannot execute a stored procedure as an IMS batch application, because the IMS batch does not
connect to DBCTL.

13.3.1.1 IMS Function Calls: You can code the stored procedure in any language supported by
stored procedure.

You access IMS databases using the language CALL statement.

The CALLs that are available are the CALLs to the AERTDLI interface or the AIBTDLI interface. The
formats of the CALL are the following:
CALL AERTDLI parmcount,function.AIB,...
CALL AIBTDLI parmcount,function.AIB,...
wher:
• parmcount specifies the address of a 4-byte field in the user-defined storage that contains the
number of parameters in the parameter list that follows parmcount.
• function specifies the address of a 4-byte field in the user-defined storage that contains the
function call. The function call must be left justified and padded with blanks, such as GUbb.
• AIB specifies the address of the application interface block.
The following function calls are supported by the DRA-callable interface:
APSB
CIMS
DEQ
DLET
DPSB
FLD
GU
GHU
GN
GHN
GMSG
ICMD
INIT
INQY
ISRT
LOG
POS
RCMD
REPL
ROLS
SETS
SETU
SNAP
STAT
OPEN
CLSE

274 Getting Started with DB2 Stored Procedures


For the INQY function call, the PROGRAM subfunction is not supported. ROLL and ROLLB are not
supported because RRS is used as the synch point manager. Although RRSBACK and ATRBACK are
supported with RRS, you cannot issue them from a stored procedure.

The I/O PCB is used only for DL/I system service calls. The GU, GN, or ISRT calls to the I/O PCB are
not supported because no access is provided to the IMS message queue.

Table 19 maps the AIB used by the DRA-callable interface for processing DL/I.

Table 19. AIB Mapping


AIB Field Description
AIBID 8 byte character field eyecatcher (′DFSAIB ′)
AILEN 8 byte binary field length of AIB (264)
AIBSFUNC 8 byte character field subfunction
AIBRSNM1 8 byte character field resource name 1
AIBRSNM2 8 byte character field resource name 2
AIBRSV1 8 bytes reserved
AIBOLEN 4 byte binary field
AIRSV2 12 bytes reserved
AIBRTRN 4 byte binary field return code
AIBREASN 4 byte binary field reason code
AIBRESV3 4 bytes reserved
AIRSA1 4 byte address field
AIBRSA2 4 bytes reserved
AIBESA3 4 bytes reserved
AIBSAVE 72 bytes reserved
AIBTOKN 56 bytes reserved

For DRA, the AIB must be 264 bytes.

13.3.1.2 Link-Edit Requirements: The only requirement is to link the stored procedure with the
DSNARLI module. A program other than stored procedures that intends to use DRA must be
link-edited with the DFSCDL10 module (or load it to use the AERTDLI call interface entry point).

This new module provides the AERTDLI and AIBTDLI application interface block for an OS/390 AEE
application region.

13.3.1.3 The CIMS Call: The CIMS call is a new DL/I function call introduced by the DRA-callable
interface. It is available only for the IMS AER environment. It is used by the stored procedures
address space when it is initializing or terminating the environment.

The following subfunctions are supported:


• INIT, which establishes the DRA-callable interface
• TERM, which terminates the DRS callable interface environment
The CIMS INIT is done by DB2 during initialization of the stored procedures address space and not by
the stored procedure. Therefore, you don′t have to code it in your stored procedure. The CIMS INIT
done during initialization covers all TCBs that can run in that address space. DB2 will also do the
CIMS TERM when shutting down the SPAS.

Chapter 13. Accessing Non-DB2 Resources 275


13.3.1.4 Scheduling a PSB: During its execution, an IMS program has to be associated with a
program specification block (PSB). A stored procedure can be associated with a PSB through the
APSB call. The format of the APSB call is the following:
CALL AERTCDLI|AIBTDLI parmcount,APSB,AIB
where
• parmcount is a 4-byte binary field with the value of 2.
• APSB is the function call.
• AIB is the application interface block.
You must set the following fields in the AIB:
− AIBRSNM1 to the PSB name
− AIBRSNM2, to the ID of the DBCTL that you wish to connect
After the call is executed, the AIB contains the fields shown in Table 20.

Table 20. AIB Mapping


AIB Field Description
AIBID 8 byte character field eyecatcher (′DFSAIB ′)
AILEN 8 byte binary field length of AIB (264)
AIBSFUNC 8 byte character field with blanks
AIBRSNM1 jobname - 6 bytes, ASID - 2 bytes
AIBRSNM2 DBCTL name
AIRSA1 chain pointer for connection AIBs
AIBRSA2 ECB
AIBSAVE address of IDENTIFY TCB for this DBCTL
AIBTOKN Name/token work area

A stored procedure can allocate (schedule) more than one PSB during its execution, although only one
PSB can be allocated at a time. To allocate a new PSB, the stored procedure must first deallocate the
current PSB through the DPSB call explained in 13.3.1.5, “DPSB Call.”

When you use a new APSB call, you can also change the DBCTL ID in the AIB, by specifying a different
DBCTL ID as the resource name. This way you can process different sets of IMS databases if you have
different DBCTLs control regions.

13.3.1.5 DPSB Call: The DPSB call deallocates a PSB and terminates the connection from a
stored procedure to DBCTL. The format of the DPSB call is the following:
CALL AERTDLI|AIBTDLI parmcount,DPSB,AIB
where
• parmcount is a 4-byte binary field with the value of 2.
• DPSB is the function call.
• AIB is the application interface block.
You must set the following fields in the AIB:
− AIBRSNM1 to the PSB name.
− AIBSFUNC is the subfunction and should be set to the string PREP.

276 Getting Started with DB2 Stored Procedures


The DPSB releases the PSB, terminates the thread to DBCTL, and completes signoff processing. If the
stored procedure does not update IMS databases, no locks held on IMS databases. If the store
procedure updates an IMS database, the DPSB call sets the work done in IMS from IN-FLIGHT to
IN-DOUBT state. When the client application commits, DB2 initiates synch point processing on behalf
of the stored procedure.

13.3.1.6 Synch Point Processing: The IMS DBCTL Version 6.1 utilizes OS/390 Registration
Services, RRS, and Context Services when the services are available. Since DBCTL is a participant in
synch point processing, it uses a two-phase commit to record a synch point. In general an AEE
application program uses the RRS to process commit or roll back using the following interfaces:
• ATRCMT/ATRBACK
• SRRCMIT/SRRBACK
• OTS-COMMIT/OTS-ROLLBACK
For a stored procedure environment, these interfaces are not available. When the client application
commits, or when control is returned to the client application and the COMMIT_ON_RETURN is in
effect, DB2 initiates commit processing as a coordinator to RRS.

13.3.1.7 Security Considerations: IMS resources accessed from an AEE and an unauthorized
AEE connections to the DBCTL environment are controlled by using the existing ISIS execution
parameter as follows:
• ISIS=0, no check is performed
• ISIS=1 the connection and the PSB are checked. The USERID and application group name (AGN)
from the startup table must be authorized to access DBCTL. You must build RACF tables that
define valid USERID and AGN combination. If the startup table values do not correspond to an
entry in RACF tables, the stored procedure cannot connect to DBCTL.
Note that connection to different DBCTL systems from the same stored procedures address space,
can have different USERID and AGN security because the DBCTL ID specifies a different startup
table module.
• ISIS=2 the connection and the PSB are checked. You have to create the resource access security
exit routine DFSISIS0. The routine must determine whether the AGN passed to it is valid for the
attempted connection

13.3.1.8 Example of Stored Procedure Coding The following is an example of a JCL to


compile and link-edit a stored procedure using DRA:
//WLMCOB JOB CLASS=K,
// MSGCLASS=A,MSGLEVEL=(1,1),
// REGION=4096K
//********************************************************************
//* THIS COMPILES AND LINKS A PROGRAM
//********************************************************************
//STEPPROC EXEC PROC=DSNHCOBA,DB2LEV=DB2A,MEM=DFSTDB2P
//PC.SYSIN DD *
CBL APOST,LIST,RENT
IDENTIFICATION DIVISION.
PROGRAM-ID. DFSTDB2P
*
********************************************************@SCPYRT**
* *
* Licensed Materials - Property of IBM *
* *
* ″Restricted Materials of IBM″ *
* *

Chapter 13. Accessing Non-DB2 Resources 277


* 5655-158 (C) Copyright IBM Corp. 1991 *
* *
********************************************************@ECPYRT**
* DFSTDB2P IS USED TO TEST CALLABLE INTERFACE TO DBCTL
* FROM A DB2 STORED PROCEDURES ENVIRONMENT
* APPLICATION : DB2 STORED PROCEDURE
* TRANSACTION : NONE
* PSB : DFSIVP64
* DATABASE : DFSIVD1
* INPUT:
*
* TELEPHONE DIRECTORY SYSTEM
* PROCESS CODE : CCCCCCCC
* LAST NAME : XXXXXXXXXX
* FIRST NAME : XXXXXXXXXX
* EXTENSION# : N-NNN-NNNN
* INTERNAL ZIP : XXX/XXX
*
* CCCCCCCC = COMMAND
* ADD = INSERT ENTRY IN DB
* DELETE = DELETE ENTRY FROM DB
* UPDATE = UPDATE ENTRY FROM DB
* DISPLAY = DISPLAY ENTRY
* TADD = SAME AS ADD, BUT WRITE TO OPERATOR
*
* CHANGES: THIS MODULE IS NEW IN IMS/ESA 6.1
*
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBM-370.
OBJECT-COMPUTER. IBM-370.
*
DATA DIVISION.
WORKING-STORAGE SECTION.

* DL/I FUNCTION CODES

77 GET-UNIQUE PIC X(4) VALUE ′ GU ′ .


77 GET-HOLD-UNIQUE PIC X(4) VALUE ′ GHU ′ .
77 GET-NEXT PIC X(4) VALUE ′ GN ′ .
77 ISRT PIC X(4) VALUE ′ ISRT′ .
77 DLET PIC X(4) VALUE ′ DLET′ .
77 REPL PIC X(4) VALUE ′ REPL′ .
77 CIMS PIC X(4) VALUE ′ CIMS′ .
77 APSB PIC X(4) VALUE ′ APSB′ .
77 DPSB PIC X(4) VALUE ′ DPSB′ .
77 APPERR PIC X(3) VALUE ′264′.
77 INVCMD PIC X(3) VALUE ′440′.
77 NOKEY PIC X(3) VALUE ′218′.

* DL/I CALL STATUS CODE

77 END-OF-DATABASE PIC X(4) VALUE ′ GB′ .

* MESSAGES

77 MDEL PIC X(40)


VALUE ′ ENTRY WAS DELETED ′.
77 MADD PIC X(40)

278 Getting Started with DB2 Stored Procedures


VALUE ′ ENTRY WAS ADDED ′.
77 MDIS PIC X(40)
VALUE ′ ENTRY WAS DISPLAYED ′.
77 MUPD1 PIC X(40)
VALUE ′ ENTRY WAS UPDATED ′.
77 MTEST PIC X(40)
VALUE ′ TEST REQUEST WAS ENDED ′.
77 MMORE PIC X(40)
VALUE ′ DATA IS NOT ENOUGH ′.
77 MINV PIC X(40)
VALUE ′ PROCESS CODE IS NOT VALID ′.
77 MUPD0 PIC X(40)
VALUE ′ PLEASE UPDATE ENTRY ′.
77 MNODATA PIC X(40)
VALUE ′ NO DATA WAS ENTERED ′.
77 MNONAME PIC X(40)
VALUE ′ LAST NAME WAS NOT SPECIFIED ′.
77 MNOENT PIC X(40)
VALUE ′ SPECIFIED PERSON WAS NOT FOUND ′.
77 MISRTE PIC X(40)
VALUE ′ ADDITION OF ENTRY HAS FAILED ′.
77 MDLETE PIC X(40)
VALUE ′ DELETION OF ENTRY HAS FAILED ′.
77 MREPLE PIC X(40)
VALUE ′ UPDATE OF ENTRY HAS FAILED ′.

* VARIABLES

77 TEMP-ONE PICTURE X(8) VALUE SPACES.


77 TEMP-TWO PICTURE X(8) VALUE SPACES.
77 REPLY PICTURE X(16).
77 DBCTLID PICTURE X(8).

* CONSTANTS

77 SSA1 PIC X(9) VALUE ′ A1111111 ′ .


77 APSBNME PIC X(8) VALUE ′ DFSIVP34′ .
77 DPCBNME PIC X(8) VALUE ′ TELEPCB1′ .
77 GSAMIN PIC X(8) VALUE ′ TELEPCB2′ .
77 GSAMOUT PIC X(8) VALUE ′ TELEPCB3′ .
77 APPLNME2 PIC X(8) VALUE ′ DFSTDB2P′ .
77 VAIBID PIC X(8) VALUE ′ DFSAIB ′ .
77 TDBCTLID PIC X(8) VALUE ′ SYS3 ′.
77 TDBCTLALL PIC X(8) VALUE ′ ALL ′.
77 SFINIT PIC X(4) VALUE ′ INIT′ .
77 SFTERM PIC X(4) VALUE ′ TERM′ .
77 SFPREP PIC X(4) VALUE ′ PREP′ .

* FLAGS

01 FLAGS.
02 SET-DATA-FLAG PIC X VALUE ′ 0 ′ .
88 NO-SET-DATA VALUE ′ 1 ′ .
02 TADD-FLAG PIC X VALUE ′ 0 ′ .
88 PROCESS-TADD VALUE ′ 1 ′ .

* COUNTERS

Chapter 13. Accessing Non-DB2 Resources 279


01 COUNTERS.
02 L-SPACE-CTR PIC 9(2) COMP VALUE 0.

* Application Interface Block(AIB) mapping

01 AIB.
02 AIBID PIC X(8).
02 AIBLEN PIC 9(9) USAGE BINARY.
02 AIBSFUNC PIC X(8).
02 AIBRSNM1 PIC X(8).
02 AIBRSNM2 PIC X(8).
02 AIBRESV1 PIC X(8).
02 AIBOALEN PIC 9(9) USAGE BINARY.
02 AIBOAUSE PIC 9(9) USAGE BINARY.
02 AIBRESV2 PIC X(12).
02 AIBRETRN PIC 9(9) USAGE BINARY.
02 AIBREASN PIC 9(9) USAGE BINARY.
02 AIBRESV3 PIC X(4).
02 AIBRESA1 USAGE POINTER.
02 AIBRESA2 USAGE POINTER.
02 AIBRESA3 USAGE POINTER.
02 AIBRESV4 PIC X(40).
02 AIBSAVE OCCURS 18 TIMES
USAGE POINTER.
02 AIBTOKN OCCURS 6 TIMES
USAGE POINTER.
02 AIBTOKC PIC X(16).
02 AIBTOKV PIC X(16).
02 AIBTOKA OCCURS 2 TIMES
PIC 9(9) USAGE BINARY.

* I/O AREA FOR DATACASE HANDLING

01 IOAREA.
02 IO-BLANK PIC X(37) VALUE SPACES.
02 IO-DATA REDEFINES IO-BLANK.
03 IO-LAST-NAME PIC X(10).
03 IO-FIRST-NAME PIC X(10).
03 IO-EXTENSION PIC X(10).
03 IO-ZIP-CODE PIC X(7).
02 IO-FILLER PIC X(3) VALUE SPACES.
02 IO-COMMAND PIC X(8) VALUE SPACES.

01 DB2IN-COMMAND.
02 DB2IW-COMMAND PIC X(8).
02 DB2TEMP-COMMAND REDEFINES DB2IW-COMMAND.
03 DB2TEMP-IOCMD PIC X(3).
03 FILLER PIC X(5).

* SEGMENT SEARCH ARGUMENT

01 SSA.
02 SEGMENT-NAME PIC X(8) VALUE ′ A1111111′ .
02 SEG-KEY-NAME PIC X(11) VALUE ′ ( A1111111 =′ .
02 SSA-KEY PIC X(10).
02 FILLER PIC X VALUE ′ ) ′ .

LINKAGE SECTION.

280 Getting Started with DB2 Stored Procedures


01 IOPCB.
02 LTERM-NAME PIC X(8).
02 IO-RESERVE-IMS PIC X(2).
02 IO-STATUS PIC X(2).
02 CURR-DATE PIC X(4).
02 CURR-TIME PIC X(4).
02 IN-MSN PIC X(4).
02 MODNAME PIC X(8).
02 USERID PIC X(8).
*01 DBPCB.
* 02 DBD-NAME PIC X(8).
* 02 SEG-LEVEL PIC X(2).
* 02 DBSTATUS PIC X(2).
* 02 PROC-OPTIONS PIC X(4).
* 02 RESERVE-DLI PIC X(4).
* 02 SEG-NAME-FB PIC X(8).
* 02 LENGTH-FB-KEY PIC 9(4).
* 02 NUMB-SENS-SEGS PIC 9(4).
* 02 KEY-FB-AREA PIC X(17).

* DATA AREA FOR DB2 STORED PROCEDURES INPUT/OUTPUT

01 DB2IO-COMMAND PIC X(8).


01 DB2IO-LAST-NAME PIC X(10).
01 DB2IO-FIRST-NAME PIC X(10).
01 DB2IO-EXTENSION PIC X(10).
01 DB2IO-ZIP-CODE PIC X(7).

* DATA AREA FOR DB2 STORED PROCEDURES OUTPUT

01 DB2OUT-SEGMENT-NO PIC 9(4).


01 DB2OUT-AIBRETRN PIC 9(9) USAGE BINARY.
01 DB2OUT-AIBREASN PIC 9(9) USAGE BINARY.
01 DC-ERROR-CALL PIC X(4).
01 DC-ERROR-STATCDE PIC X(2).

PROCEDURE DIVISION USING DB2IO-COMMAND,


DB2IO-LAST-NAME, DB2IO-FIRST-NAME, DB2IO-EXTENSION,
DB2IO-ZIP-CODE, DB2OUT-SEGMENT-NO,
DB2OUT-AIBRETRN, DB2OUT-AIBREASN,
DC-ERROR-CALL, DC-ERROR-STATCDE.

* ON ENTRY DB2 PASSES COMMAND REQUEST AND KEY VALUE

MAIN-RTN.

INITIALIZE AIB.
SET AIBRESA1 TO NULLS.
SET AIBRESA2 TO NULLS.
SET AIBRESA3 TO NULLS.
MOVE ZEROES to AIBRETRN.
MOVE ZEROES to AIBREASN.
MOVE VAIBID to AIBID.
MOVE LENGTH OF AIB to AIBLEN.
MOVE SPACES to IOAREA.
* MOVE SPACES TO DBPCB.
MOVE LENGTH OF IOAREA to AIBOALEN.
MOVE SPACES TO AIBSFUNC.

Chapter 13. Accessing Non-DB2 Resources 281


MOVE APSBNME to AIBRSNM1.
MOVE TDBCTLID to AIBRSNM2.
DISPLAY ′ AIBRSNM1=′ AIBRSNM1.
DISPLAY ′ AIBRSNM2=′ AIBRSNM2.
DISPLAY ′ AIBSFUNC=′ AIBSFUNC.
DISPLAY ′ AIBLEN =′ AIBLEN.
CALL ′ AERTDLI′ USING APSB, AIB.
* CALL ′ CEETDLI′ USING APSB, AIB.
DISPLAY ′ AIBRETRN=′ AIBRETRN.
DISPLAY ′ AIBREASN=′ AIBREASN.
DISPLAY ′ AIBRESA1=′ AIBRESA1.
DISPLAY ′ AIBRESA2=′ AIBRESA2.
DISPLAY ′ AIBRESA3=′ AIBRESA3.
IF AIBRETRN NOT EQUAL ZEROES
THEN
MOVE AIBRETRN TO DB2OUT-AIBRETRN
MOVE AIBREASN TO DB2OUT-AIBREASN
GOBACK
ELSE
MOVE 0 TO SET-DATA-FLAG
MOVE 0 TO TADD-FLAG.
READ-INPUT.
PERFORM PROCESS-INPUT THRU PROCESS-INPUT-END.
MOVE APSBNME to AIBRSNM1.
MOVE SFPREP to AIBSFUNC.
DISPLAY ′ AIBRSNM1=′ AIBRSNM1.
DISPLAY ′ AIBRSNM2=′ AIBRSNM2.
DISPLAY ′ AIBSFUNC=′ AIBSFUNC.
DISPLAY ′ AIBLEN =′ AIBLEN.
CALL ′ AERTDLI′ USING DPSB, AIB.
* CALL ′ CEETDLI′ USING DPSB, AIB.
DISPLAY ′ AIBRETRN=′ AIBRETRN.
DISPLAY ′ AIBREASN=′ AIBREASN.
DISPLAY ′ AIBRESA1=′ AIBRESA1.
DISPLAY ′ AIBRESA2=′ AIBRESA2.
DISPLAY ′ AIBRESA3=′ AIBRESA3.
MOVE AIBRETRN TO DB2OUT-AIBRETRN.
MOVE AIBREASN TO DB2OUT-AIBREASN.
GOBACK.

* PROCEDURE PROCESS-INPUT

PROCESS-INPUT.

MOVE ZEROES TO DB2OUT-SEGMENT-NO.

* CHECK THE LEADING SPACE IN INPUT COMMAND AND TRIM IT OFF

INSPECT DB2IO-COMMAND TALLYING L-SPACE-CTR FOR LEADING SPACE


REPLACING LEADING SPACE BY ′ *′ .
IF L-SPACE-CTR > 0
UNSTRING DB2IO-COMMAND DELIMITED BY ALL ′ *′ INTO TEMP-ONE
TEMP-TWO
MOVE TEMP-TWO TO DB2IO-COMMAND
MOVE 0 TO L-SPACE-CTR
MOVE SPACES TO TEMP-TWO.

* CHECK THE LEADING SPACE IN INPUT LAST NAME AND TRIM IT OFF

282 Getting Started with DB2 Stored Procedures


INSPECT DB2IO-LAST-NAME TALLYING L-SPACE-CTR FOR LEADING
SPACE REPLACING LEADING SPACE BY ′ *′ .
IF L-SPACE-CTR > 0
UNSTRING DB2IO-LAST-NAME DELIMITED BY ALL ′ *′ INTO TEMP-ONE
TEMP-TWO
MOVE TEMP-TWO TO DB2IO-LAST-NAME
MOVE 0 TO L-SPACE-CTR
MOVE SPACES TO TEMP-TWO.

* CHECK THE LEADING SPACE IN INPUT FIRST NAME AND TRIM IT OFF

INSPECT DB2IO-FIRST-NAME TALLYING L-SPACE-CTR FOR LEADING


SPACE REPLACING LEADING SPACE BY ′ *′ .
IF L-SPACE-CTR > 0
UNSTRING DB2IO-FIRST-NAME DELIMITED BY ALL ′ *′ INTO TEMP-ONE
TEMP-TWO
MOVE TEMP-TWO TO DB2IO-FIRST-NAME
MOVE 0 TO L-SPACE-CTR
MOVE SPACES TO TEMP-TWO.

* CHECK THE LEADING SPACE IN INPUT EXTENSION AND TRIM IT OFF

INSPECT DB2IO-EXTENSION TALLYING L-SPACE-CTR FOR LEADING


SPACE REPLACING LEADING SPACE BY ′ *′ .
IF L-SPACE-CTR > 0
UNSTRING DB2IO-EXTENSION DELIMITED BY ALL ′ *′ INTO TEMP-ONE
TEMP-TWO
MOVE TEMP-TWO TO DB2IO-EXTENSION
MOVE 0 TO L-SPACE-CTR
MOVE SPACES TO TEMP-TWO.

* CHECK THE LEADING SPACE IN INPUT ZIP CODE AND TRIM IT OFF

INSPECT DB2IO-ZIP-CODE TALLYING L-SPACE-CTR FOR LEADING SPACE


REPLACING LEADING SPACE BY ′ *′ .
IF L-SPACE-CTR > 0
UNSTRING DB2IO-ZIP-CODE DELIMITED BY ALL ′ *′ INTO TEMP-ONE
TEMP-TWO
MOVE TEMP-TWO TO DB2IO-ZIP-CODE
MOVE 0 TO L-SPACE-CTR
MOVE SPACES TO TEMP-TWO.

*
MOVE DB2IO-LAST-NAME TO IO-LAST-NAME.
MOVE DB2IO-COMMAND TO IO-COMMAND.
MOVE DB2IO-COMMAND TO DB2IN-COMMAND.

IF IO-COMMAND EQUAL SPACES


THEN MOVE APPERR TO DB2OUT-AIBRETRN
MOVE INVCMD TO DB2OUT-AIBREASN
ELSE IF IO-LAST-NAME EQUAL SPACES
THEN MOVE APPERR TO DB2OUT-AIBRETRN
MOVE NOKEY TO DB2OUT-AIBREASN
ELSE IF DB2TEMP-IOCMD EQUAL ′ ADD′
THEN PERFORM TO-ADD THRU TO-ADD-END
ELSE IF DB2TEMP-IOCMD EQUAL ′ TAD′
THEN MOVE 1 TO TADD-FLAG
PERFORM TO-ADD THRU TO-ADD-END
ELSE IF DB2TEMP-IOCMD EQUAL ′ UPD′

Chapter 13. Accessing Non-DB2 Resources 283


THEN PERFORM TO-UPD THRU TO-UPD-END
ELSE IF DB2TEMP-IOCMD EQUAL ′ DEL′
THEN PERFORM TO-DEL THRU TO-DEL-END
ELSE IF DB2TEMP-IOCMD EQUAL ′ DIS′
THEN PERFORM TO-DIS THRU TO-DIS-END
ELSE
MOVE APPERR TO DB2OUT-AIBRETRN
MOVE INVCMD TO DB2OUT-AIBREASN.
PROCESS-INPUT-END.
EXIT.

* PROCEDURE TO-ADD : ADDITION REQUEST HANDLER

TO-ADD.
MOVE DB2IO-FIRST-NAME TO IO-FIRST-NAME.
MOVE DB2IO-EXTENSION TO IO-EXTENSION.
MOVE DB2IO-ZIP-CODE TO IO-ZIP-CODE.
* MOVE IO-DATA TO DB2OUT-DATA.
MOVE IO-COMMAND TO DB2IO-COMMAND.
IF DB2IO-FIRST-NAME EQUAL SPACES OR
DB2IO-EXTENSION EQUAL SPACES OR
DB2IO-ZIP-CODE EQUAL SPACES
THEN
MOVE APPERR TO DB2OUT-AIBRETRN
MOVE INVCMD TO DB2OUT-AIBREASN
ELSE
PERFORM ISRT-DB THRU ISRT-DB-END.
TO-ADD-END.
EXIT.

* PROCEDURE TO-UPD : UPDATE REQUEST HANDLER

TO-UPD.
MOVE 0 TO SET-DATA-FLAG.
MOVE IO-LAST-NAME TO SSA-KEY.
PERFORM GET-HOLD-UNIQUE-DB THRU GET-HOLD-UNIQUE-DB-END.
IF AIBRETRN = ZEROES
THEN
IF DB2IO-FIRST-NAME NOT = SPACES
MOVE 1 TO SET-DATA-FLAG
MOVE DB2IO-FIRST-NAME TO IO-FIRST-NAME
END-IF
IF DB2IO-EXTENSION NOT = SPACES
MOVE 1 TO SET-DATA-FLAG
MOVE DB2IO-EXTENSION TO IO-EXTENSION
END-IF
IF DB2IO-ZIP-CODE NOT = SPACES
MOVE 1 TO SET-DATA-FLAG
MOVE DB2IO-ZIP-CODE TO IO-ZIP-CODE
END-IF
* MOVE IO-DATA TO DB2OUT-DATA.
MOVE IO-COMMAND TO DB2IO-COMMAND.
IF NO-SET-DATA
THEN
PERFORM REPL-DB THRU REPL-DB-END
ELSE
MOVE APPERR TO DB2OUT-AIBRETRN
MOVE INVCMD TO DB2OUT-AIBREASN.

284 Getting Started with DB2 Stored Procedures


TO-UPD-END.
EXIT.

* PROCEDURE TO-DEL : DELETE REQUEST HANDLER

TO-DEL.
MOVE IO-LAST-NAME TO SSA-KEY.
PERFORM GET-HOLD-UNIQUE-DB THRU GET-HOLD-UNIQUE-DB-END.
IF AIBRETRN = ZEROES
THEN
* MOVE IO-DATA TO DB2OUT-DATA
MOVE IO-COMMAND TO DB2IO-COMMAND
PERFORM DLET-DB THRU DLET-DB-END.
TO-DEL-END.
EXIT.

* PROCEDURE TO-DIS : DISPLAY REQUEST HANDLER

TO-DIS.
MOVE IO-LAST-NAME TO SSA-KEY.
PERFORM GET-UNIQUE-DB THRU GET-UNIQUE-DB-END.
IF AIBRETRN = ZEROES
THEN
* MOVE IO-DATA TO DB2OUT-DATA
MOVE IO-COMMAND TO DB2IO-COMMAND.
TO-DIS-END.
EXIT.

* PROCEDURE ISRT-DB : DATA BASE SEGMENT INSERT REQUEST HANDLER

ISRT-DB.
MOVE DPCBNME to AIBRSNM1.
CALL ′ AERTDLI′ USING ISRT, AIB, IOAREA, SSA1.
* CALL ′ CEETDLI′ USING ISRT, AIB, IOAREA, SSA1.
IF AIBRETRN = ZEROES
THEN
IF PROCESS-TADD
DISPLAY ′ INSERT IS DONE, REPLY′ UPON CONSOLE
ACCEPT REPLY FROM CONSOLE
MOVE 0 TO TADD-FLAG
END-IF
ELSE
MOVE APPERR TO DB2OUT-AIBRETRN
MOVE INVCMD TO DB2OUT-AIBREASN
MOVE ISRT TO DC-ERROR-CALL.
* SET ADDRESS OF DBPCB TO AIBRESA1
* MOVE DBSTATUS TO DC-ERROR-STATCDE.
ISRT-DB-END.
EXIT.

* PROCEDURE GET-UNIQUE-DB
* DATA BASE SEGMENT GET-UNIQUE-DB REQUEST HANDLER

GET-UNIQUE-DB.
MOVE DPCBNME to AIBRSNM1.
CALL ′ AERTDLI′ USING GET-UNIQUE, AIB, IOAREA, SSA.
* CALL ′ CEETDLI′ USING GET-UNIQUE, AIB, IOAREA, SSA.
IF AIBRETRN NOT EQUAL ZEROES
THEN

Chapter 13. Accessing Non-DB2 Resources 285


MOVE APPERR TO DB2OUT-AIBRETRN
MOVE INVCMD TO DB2OUT-AIBREASN
* SET ADDRESS OF DBPCB TO AIBRESA1
MOVE GET-UNIQUE TO DC-ERROR-CALL.
* MOVE DBSTATUS TO DC-ERROR-STATCDE.
GET-UNIQUE-DB-END.
EXIT.

* PROCEDURE GET-HOLD-UNIQUE-DB
* DATA BASE SEGMENT GET-HOLD-UNIQUE-DB REQUEST HANDLER

GET-HOLD-UNIQUE-DB.
MOVE DPCBNME to AIBRSNM1.
CALL ′ AERTDLI′ USING GET-HOLD-UNIQUE, AIB, IOAREA, SSA.
* CALL ′ CEETDLI′ USING GET-HOLD-UNIQUE, AIB, IOAREA, SSA.
IF AIBRETRN NOT EQUAL ZEROES
THEN
MOVE APPERR TO DB2OUT-AIBRETRN
MOVE INVCMD TO DB2OUT-AIBREASN
* SET ADDRESS OF DBPCB TO AIBRESA1
MOVE GET-HOLD-UNIQUE TO DC-ERROR-CALL.
* MOVE DBSTATUS TO DC-ERROR-STATCDE.
GET-HOLD-UNIQUE-DB-END.
EXIT.

* PROCEDURE REPL-DB : DATA BASE SEGMENT REPLACE REQUEST HANDLER

REPL-DB.
MOVE DPCBNME to AIBRSNM1.
CALL ′ AERTDLI′ USING REPL, AIB, IOAREA.
* CALL ′ CEETDLI′ USING REPL, AIB, IOAREA.
IF AIBRETRN NOT EQUAL ZEROES
MOVE APPERR TO DB2OUT-AIBRETRN
MOVE INVCMD TO DB2OUT-AIBREASN
* SET ADDRESS OF DBPCB TO AIBRESA1
MOVE REPL TO DC-ERROR-CALL.
* MOVE DBSTATUS TO DC-ERROR-STATCDE.
REPL-DB-END.
EXIT.

* PROCEDURE DLET-DB : DATA BASE SEGMENT DELETE REQUEST HANDLER

DLET-DB.
MOVE DPCBNME to AIBRSNM1.
CALL ′ AERTDLI′ USING DLET, AIB, IOAREA.
* CALL ′ CEETDLI′ USING DLET, AIB, IOAREA.
IF AIBRETRN NOT EQUAL ZEROES
MOVE APPERR TO DB2OUT-AIBRETRN
MOVE INVCMD TO DB2OUT-AIBREASN
* SET ADDRESS OF DBPCB TO AIBRESA1
MOVE DLET TO DC-ERROR-CALL.
* MOVE DBSTATUS TO DC-ERROR-STATCDE.
DLET-DB-END.
EXIT.

//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNRLI)
INCLUDE SYSLIB(DSNTIAR)

286 Getting Started with DB2 Stored Procedures


NAME DFSTDB2P(R)
The following is an example of a JCL to:
1. Insert a row into the SYSIBM.SYSPROCEDURES.
2. Compile and link-edit the client program.
3. Bind the plan for the client program.
4. Execute the client program.

The example is:


//DFSTDB2P JOB MSGCLASS=A,
// MSGLEVEL=(1,1),
// REGION=4096K
//********************************************************************
//*
//* set up catalog entry
//*
//********************************************************************
//STEP8 EXEC TSOBATCH,DB2LEV=DB2A
//SYSTSIN DD *
DSN SYSTEM(V51A)
RUN PROGRAM(DSNTEP3)
//SYSIN DD *

DELETE FROM SYSIBM.SYSPROCEDURES


WHERE PROCEDURE = ′ DFSTDB2P′ ;

INSERT INTO SYSIBM.SYSPROCEDURES


VALUES(′ DFSTDB2P′ ,
′ ′,
′ ′,
′ DFSTDB2P′ ,
′ ′,
′ L302COL1′ ,
′ COBOL′ ,
0,
′ ′,
′ N′ ,
′ TRAP(ON),RPTOPTS(ON),TERMTHDAC(UADUMP)′ ,
′ CHAR(8) INOUT, CHAR(10) INOUT, CHAR(10) INOUT,
CHAR(10) INOUT, CHAR(7) INOUT, SMALLINT OUT, INT OUT,
INT OUT, CHAR(4) OUT, CHAR(2) OUT′ ,
0,
′ WLMENV1′ , ′ S′ , ′ N′ , ′ N′ ) ;

SELECT * FROM SYSIBM.SYSPROCEDURES;

//********************************************************************
//* DFSTDB2P TEXT DECK ALREADY IN USER.CIMS.PGMLIB
//* FOLLOWING JUST FORCES A LINK (ALREADY DONE WITH IMSCOB2)
//********************************************************************
//*STEPPROC EXEC PROC=DSNHCOBM,DB2LEV=DB2A,MEM=DFSTDB2P
//*LKED.SYSIN DD *
//* NAME DFSTDB2P(R)
//********************************************************************
//* CALLING PROGRAM!
//********************************************************************

Chapter 13. Accessing Non-DB2 Resources 287


//STEPPROC EXEC PROC=DSNHPLIA,DB2LEV=DB2A,MEM=APPLDIS2
//PC.SYSIN DD *
APPLDIS2: PROCEDURE OPTIONS(MAIN );
/************************************************************/
/* Include SQLCA, SQLDA, and global variables declaration. */
/************************************************************/

EXEC SQL INCLUDE SQLCA;


EXEC SQL INCLUDE SQLDA;
/******************************************************************/
/* EXEC SQL INCLUDE PLIVAR; */
/******************************************************************/

DECLARE 1 DB2IO_COMMAND CHAR(8);


DECLARE 1 DB2IO_LAST_NAME CHAR(10);
DECLARE 1 DB2IO_FIRST_NAME CHAR(10);
DECLARE 1 DB2IO_EXTENSION CHAR(10);
DECLARE 1 DB2IO_ZIP_CODE CHAR(7);
DECLARE 1 DB2OUT_SEGMENT_NO BIN FIXED(15);
DECLARE 1 DB2OUT_AIBRETRN BIN FIXED(31);
DECLARE 1 DB2OUT_AIBREASN BIN FIXED(31);
DECLARE 1 DC_ERROR_CALL CHAR(4);
DECLARE 1 DC_ERROR_STATCDE CHAR(2);

DECLARE 1 CNT BIN FIXED(31);


DECLARE 1 RETCODE BIN FIXED(31);

DISPLAY (′ ** APPLDIS2 INITIALIZATION **′ ) ;

IF SQLCODE¬=0 THEN /* If SQL CALL failed, */


DO;
PUT SKIP EDIT(′ CONNECT failed due to SQLCODE = ′ ,
SQLCODE) (A(34),A(14));
PUT SKIP EDIT(′ SQLERRM = ′ ,
SQLERRM) (A(10),A(70));
END;

/* EXEC SQL */
/* SET CURRENT PACKAGESET = ′ COL1′ ; */

DB2IO_COMMAND = ′ DIS ′; /* ADD & WTO */


DB2IO_LAST_NAME = ′ LAST1 ′;
DB2IO_FIRST_NAME = ′ FIRST1 ′;
DB2IO_EXTENSION = ′ X-XXX-XXXX′ ;
DB2IO_ZIP_CODE = ′ XXX/XXX′ ;

DISPLAY(′ DB2IO_COMMAND = ′ || DB2IO_COMMAND );


DISPLAY(′ DB2IO_LAST_NAME = ′ || DB2IO_LAST_NAME );
DISPLAY(′ DB2IO_FIRST_NAME = ′ || DB2IO_FIRST_NAME );
DISPLAY(′ DB2IO_EXTENSION = ′ || DB2IO_EXTENSION );
DISPLAY(′ DB2IO_ZIP_CODE = ′ || DB2IO_ZIP_CODE );
DISPLAY(′ DB2OUT_SEGMENT_NO = ′ || DB2OUT_SEGMENT_NO);
DISPLAY(′ DB2OUT_AIBRETRN = ′ || DB2OUT_AIBRETRN );
DISPLAY(′ DB2OUT_AIBREASN = ′ || DB2OUT_AIBREASN );
DISPLAY(′ DC_ERROR_CALL = ′ || DC_ERROR_CALL );
DISPLAY(′ DC_ERROR_STATCDE = ′ || DC_ERROR_STATCDE );

DISPLAY (′ ** CALLING TELEPHONE STORED PROCEDURE DFSTDB2P **′ ) ;


EXEC SQL

288 Getting Started with DB2 Stored Procedures


CALL DFSTDB2P( :DB2IO_COMMAND, :DB2IO_LAST_NAME, :DB2IO_FIRST_NAME,
:DB2IO_EXTENSION, :DB2IO_ZIP_CODE, :DB2OUT_SEGMENT_NO,
:DB2OUT_AIBRETRN, :DB2OUT_AIBREASN, :DC_ERROR_CALL,
:DC_ERROR_STATCDE)
;

DISPLAY (′ ** APPLDIS2 CALL RETURN FROM DFSTDB2P **′ ) ;

DISPLAY(′ DB2IO_COMMAND = ′ || DB2IO_COMMAND );


DISPLAY(′ DB2IO_LAST_NAME = ′ || DB2IO_LAST_NAME );
DISPLAY(′ DB2IO_FIRST_NAME = ′ || DB2IO_FIRST_NAME );
DISPLAY(′ DB2IO_EXTENSION = ′ || DB2IO_EXTENSION );
DISPLAY(′ DB2IO_ZIP_CODE = ′ || DB2IO_ZIP_CODE );
DISPLAY(′ DB2OUT_SEGMENT_NO = ′ || DB2OUT_SEGMENT_NO);
DISPLAY(′ DB2OUT_AIBRETRN = ′ || DB2OUT_AIBRETRN );
DISPLAY(′ DB2OUT_AIBREASN = ′ || DB2OUT_AIBREASN );
DISPLAY(′ DC_ERROR_CALL = ′ || DC_ERROR_CALL );
DISPLAY(′ DC_ERROR_STATCDE = ′ || DC_ERROR_STATCDE );

/*IF SQLCODE¬=0 THEN IF SQL CALL FAILED, */


DO;
PUT SKIP EDIT(′ SQL CALL failed due to SQLCODE = ′ ,
SQLCODE) (A(34),A(14));
PUT SKIP EDIT(′ SQLERRM = ′ ,
SQLERRM) (A(10),A(70));
END;

/************************************************************/
/* Include Standard Language Procedures. */
/************************************************************/
/* EXEC SQL INCLUDE PLISUB; */
/******************************************************************/
END APPLDIS2;
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNELI)
INCLUDE SYSLIB(DSNTIAR)
NAME APPLDIS2(R)
//********************************************************************
//********************************************************************
//********************************************************************
//********************************************************************
//********************************************************************
//STEP14 EXEC TSOBATCH,DB2LEV=DB2A
//SYSTSIN DD *
DSN SYSTEM(V51A)

FREE PLAN(PLANADI2)

BIND PLAN(PLANADI2) MEMBER(APPLDIS2)

//**********************************************************************
//* DSNCMD STEP
//**********************************************************************
//STEP16 EXEC TSOBATCH,DB2LEV=DB2A
//SYSTSIN DD *
DSN SYSTEM(V51A)

RUN PROGRAM(APPLDIS2) PLAN(PLANADI2)

Chapter 13. Accessing Non-DB2 Resources 289


Note that other than having IMS RESLIB in STEPLIB (or DFSRESLB pointing to IMS RESLIB) in the
stored procedures address space, there are no extra requiremnets. Note that the IMS RESLIB data set
must be APF authorized.

13.3.1.9 Problem Determination: You should always check the IMS status code, the reason
code, and the return code. The reason code is contained in the AIBREASN field, and the return code is
contained in the AIBRETRN field. You should check for nonzero values for reason and return codes,
and unexpected nonblank spaces for status code (for example, GE and GB can be expected as status
code indicating no more segment found, or end of database reached).

Table 21 shows some new AIB reason and return codes with possible causes.

Table 21. New Reason and Return Codes


Return Reason Possible Cause
Code Code
0104 200 incorrect parameter in the startup table
204 No values specified for DBCTL id in AIBRSNM2
208 AIBRSNM1 not set to PCBNAME
218 Invalid subfunction code
460 AIBLEN not 164 bytes
464 DL/I call issued before environment initialization
0108 010 GETMAIN failure trying to obtain storage
420 No active communication with DBCTL
448 LOAD of required DRA module or startup table failed
452 Dynamic allocation or open of DRA RESLIB failed
462 RRS is not active and APSB cannot be issued
0110 72 DRA RESLIB is not authorized

Table 22 shows the existing AIB return codes and reason codes for the APSB and DPSB function calls
applicable to AERTDLI.

Table 22 (Page 1 of 2). Existing Reason and Return Codes


Return Reason Possible Cause
Code Code
0104 0404 Invalid function code
048C APSB issued without a previous DPSB
0490 DPSB with no CPI-RR commit
0494 PSB was not found
054C Invalid output destination
0108 0304 PSB was not found
0308 PSB authorization failure
030C PSB permanently bad
0310 Fast Path database locked or stopped
0314 PSB already scheduled
0318 PSB locked or stopped
031C I/O error reading PSB or DMB

290 Getting Started with DB2 Stored Procedures


Table 22 (Page 2 of 2). Existing Reason and Return Codes
Return Reason Possible Cause
Code Code
0320 PSBW/DMB/PSB pool too small
0324 Invalid ′ L′ or ′LS′ option
0328 Fast Path buffer fix error
032C Invalid processing intent
0110 000C Resource specified was not authorized

13.3.2 Including APPC Code in the Stored Procedure


The stored procedure can include an APPC code to invoke an IMS transaction. You must have IMS TM
Version 3 or higher. You can use the implicit or explicit APPC support provided by IMS.

You can use the APPC code in the DB2-established address space or in the WLM-established address
space.

If you use the DB2-established address space you should specify SYNCLEVEL NONE or CONFIRM. For
DB2-established address space, you don′t have two-phase commit support for updates done in IMS
database. If the client application signals to ROLLBACK, or if one of the participants of the two-phase
commit processing cannot commit, updates done by the IMS transaction are not rolled back. In this
case, the application is responsible for removing the updates. Note that this is an exposure, because
by the time DB2 rolls back, the IMS applications may already have used the updated information.

If you use the WLM-established address space you should specify SYNCLEVEL NONE or CONFIRM if
the IMS transaction does not perform any updates on IMS databases. If the IMS transaction performs
updates to IMS databases you must specify SYNCLEVEL SYNCPOINT to ensure that IMS is a participant
in the two-phase commit process. In this case, you need IMS Version 6, which is RRS enabled. You
have to make sure you also have OS/390 R3 APPC to achieve a full two-phase commit processing.

For an example of how to use APPC to invoke IMS transactions from a stored procedure refer to 13.5,
“APPC to Access Transactions from a Stored Procedure” on page 292.

13.4 Using MQSeries for Enqueued Messages


You can code your stored procedure to enqueue a message destined to IMS or CICS using MQSeries.
MQSeries also supports other environments that your stored procedure can request information from.

IMS has access to messages enqueued on MQSeries through a BMP or using the IMS Open
Transaction Manager Access (OTMA). Please refer to IMS publications for more information about
OTMA.

You can use this method using DB2-established stored procedures or WLM-established stored
procedures. If you need two-phase commit processing, then you have to use WLM-established
address spaces and the correct level of MQSeries, CICS, IMS, or the product that your stored
procedure is requesting information from.

Chapter 13. Accessing Non-DB2 Resources 291


13.5 APPC to Access Transactions from a Stored Procedure

Advanced Program-to-Program Communication (APPC), using the Common Programming Interface


Communications (CPIC) application programming interface can be used to access IMS and CICS
transaction from a stored procedure. For considerations of using APPC to access non-DB2 resources
refer to “Accessing Non-DB2 Resources” in the DB2 for OS/390 Version 5 Application Programming and
SQL Guide .

We provide three COBOL samples stored procedure using CPIC to invoke the IMS installation
verification procedure (IVP) transactions:
• IMSBMS stored procedure is called by client IMSBMCBM and executes the IMS IVP PART
transaction. It places information about PARTs received from IMS in a DB2 global temporary table,
which is returned to the client application in a result set.
• IMUBMS stored procedure is called by client IMUBMCBM and shows how to dynamically change
the transaction program name (TPN). It can invoke any of the IMS IVP transactions. It stores the
IMS data into a DB2 global temporary table and returns a result set back to the client.
• IMDBMS stored procedure is called by clients IMDBMCBM, IMDBMCBN, and IMDBMCB2. It has
the same function as IMUBMS except the IMS output is returned in a parameter. It does not use a
DB2 global temporary table.

13.5.1 Preparing IMS for APPC


Two SYS1.PARMLIB members are required to define the APPC and ASCH characteristics. All
APPC/MVS LUs must be defined in MVS in the member APPCPMxx, where xx are two characters
defined by the systems programmer. The other SYS1.PARMLIB member is for the ASCH address
space, defined in member ASCHPMxx. Here is an example of APPC/MVS and IMS parameters for the
SYS1.PARMLIB (APPCPMxx) member that we used:
LUADD ACBNAME(SC47APPC) /* ADD LOCAL LU TO THE */
/* APPC/MVS CONFIGURATION */
SCHED(ASCH) /* SPECIFY THAT THE APPC/MVS */
/* TRANSACTION SCHEDULER IS ASSOCIATED */
/* WITH THIS LU NAME */
BASE /* DESIGNATE THIS LU AS THE BASE LU */
TPDATA(SYS1.APPCTP) /* SPECIFY THAT VSAM DATA SET */
/* SYS2.APPCTP IS THE PERMANENT */
/* REPOSITORY FOR THE TP PROFILES */
/* FOR THIS LU */
TPLEVEL(SYSTEM) /* SPECIFY THE SEARCH ORDER FOR TP */
/* PROFILES AS : */
/* 1. TP PROFILES ASSOCIATED WITH */
/* A SPECIFIC USER */
/* 2. TP PROFILES ASSOCIATED WITH */
/* A GROUP OF USERS */
/* 3. TP PROFILES ASSOCIATED WITH */
/* ALL USERS OF THE LU NAME */
LUADD ACBNAME(SC47IMSA)
SCHED(IMSA)
TPDATA(SYS1.APPCTP)
BASE
SIDEINFO DATASET(SYS1.APPCSI)
Note that in the LUADDD for IMS:
• The ACBNAME specification must match the LU name assigned to IMS
• The SCHED specification must match the IMS system ID.

292 Getting Started with DB2 Stored Procedures


The TP profile data set contains all the information to successfully schedule the execution of a TP. The
side information data set can contain all the information required for processing an outbound request
that specifies a symbolic destination name. In our example, we only needed to set up the side
information data set, because if there is no TPN entry for some ALLOCATE to this IMS, IMS tries for a
transaction code of the first 8 characters of the TPN. This means, if the program that initiates
communication with IMS specifies the IMS transaction code for TPN, no TP profile entry is required.

Here is the example of the side information file we used to set up the symbolic destination name:
//STEP01 EXEC PGM=ATBSDFMU
//SYSPRINT DD SYSOUT=*
//SYSSDLIB DD DSN=SYS1.APPCSI,DISP=SHR
//SYSSDOUT DD SYSOUT=*
//SYSIN DD *
SIADD
DESTNAME(IMSA)
TPNAME(PART)
MODENAME(LU62APPC)
PARTNER_LU(SC47IMSA)
/*
Note that:
• The DESTNAME specification can be any name. When you code your application, if you want to
use this side information, you pass it on the CPIC call.
• The TPNAME specifcation matches the IMS transaction code.
• The MODENAME specifcation must match a VTAM log mode available for IMS.
• The PARTNER_LU specifcation must match the IMS LU name.

Instead of using the ATBSDFMU utility, you can update the information in the data sets interactively,
using ISPF panels.

13.5.1.1 Program Preparation: APPC/MVS provides interface definition files (IDFs), also called
pseudonym files, which define variables and values for parameters of APPC/MVS services. IDFs are
available for different languages, and can be included or copied from a central library into programs
that invoke APPC/MVS callable services. The following IDFs are available on MVS:
for PL/I include SYS1.SAMPLIB(ATBCMPLI)
CICS.V5R1M0.SDFHPL1(CMPLI) *

for COBOL copybook SYS1.SAMPLIB(ATBCMCOB)


CICS.V5R1M0.SDFHCOB(CMCOBOL) *

for C headers SYS1.SAMPLIB(ATBCMC)


CICS.V5R1M0.SDFHC370(CMC) *

* denotes those that we used.

The ATBPBI module, from SYS1.CSSLIB must be link-edited with any program that issues APPC/MVS
services CPIC calls or TP conversation services.

For our samples, we used CPIC calls to MVS TP services because CPIC is more portable. Like CPIC,
APPC/MVS′s MVS-specific services let your programs communicate with other programs on the same
MVS system, other MVS systems, or other operating systems in an SNA network. Unlike CPIC,
programs using the MVS-specific services are not portable to other systems. MVS-specific services
make use of the MVS/ESA architecture, including data spaces and asynchronous processing, and
provide TP scheduling options, server functions, and test services.

Chapter 13. Accessing Non-DB2 Resources 293


13.5.2 IMSBMCBM, IMSBMS, and PART
Before the program is executed, a DB2 global temporary table is defined to DB2. This is the setup to
hold the returned messages from IMS. In this case, a cursor for the global temporary table can be
defined to return a result set back to IMSBMCBM:
SET CURRENT SQLID=′ DB2V5′ ;
CREATE GLOBAL TEMPORARY TABLE TEMPIMS
(COL1 CHAR(100));
Next, the IMSBMS stored procedure must be defined to the SYSIBM.SYSPROCEDURE table:
INSERT INTO SYSIBM.SYSPROCEDURES
(PROCEDURE, AUTHID, LUNAME, LOADMOD,
LINKAGE, COLLID, LANGUAGE, ASUTIME,
STAYRESIDENT, IBMREQD, RUNOPTS,
PARMLIST,
RESULT_SETS, WLM_ENV, PGM_TYPE, EXTERNAL_SECURITY,
COMMIT_ON_RETURN )
VALUES(′ IMSBMS′ , ′ ′, ′ ′, ′ IMSBMs′ ,
′ ′, ′ SAMPLESP′ , ′ COBOL′ , 0,
′ ′, ′ N′ , ′ ′,
′ CHAR(8) IN′ ,
1, ′ WLMENV2′ , ′ M′ , ′ N′ ,
′ N′ ) ;
COMMIT;

The following is a summary of the IMSBMCBM client program and the IMSBMS stored procedure:
1. IMSBMCBM declares a result set locator for the result set that is returned from IMSBMS.
2. A working storage field is defined to hold the 100 characters returned from the result set.
3. IMSBMCBM calls the stored procedure IMSBMS and passes to it a part number using the SIMPLE
linkage convention.
4. IMSBMS initializes and allocates the conversation to the IMS transaction PART.
5. IMSBMS sends and flushes the data, which is the part number.
6. The partner transaction PART is scheduled by the IMS control region in a message processing
region (MPP).
7. The PART transaction reads information about a part number and sends the reply back. In the
case of an existing part number, the part-related information is returned. Otherwise, an error
message is returned.
8. IMSBMS loops to receive data and stores this data in a DB2 global temporary table, and continues
to loop until all data has been received.
9. When a deallocated normal message is received from IMS, IMSBMS ends the conversation.
10. IMSBMS declares a cursor WITH RETURN selecting all the rows from the DB2 global temporary
table:
EXEC SQL DECLARE TESTE-CURSOR CURSOR WITH RETURN FOR
SELECT COL1
FROM TEMPIMS
END-EXEC.
11. The cursor is opened and control is returned to the client program IMSBMCBM.
12. IMSBMCBM checks for an SQLCODE of +466, to see if a result set was returned. If a result is
returned IMSBMCBM associates the result locator variable to the result set with the ASSOCIATE
LOCATORS SQL statement.

294 Getting Started with DB2 Stored Procedures


13. A cursor is allocated to the result set with the ALLOCATE SQL statement.
14. IMSBMCBM loops until all rows from the result set are fetched with the FETCH SQL command.

13.5.3 IMUBMCBM, IMUBMS and IMS IVP Transactions


Before the program is executed, a DB2 global temporary table is defined to DB2. This is the same
table used by IMSDBCDB. A second DB2 table is defined to log the IMS transaction as the
transactions are processed:
**************
* CREATE TABLE LOG FOR IMS TRANSACTIONS
**************
SET CURRENT SQLID=′ DB2V5′ ;
DROP TABLE TRAN_LOG;
COMMIT ;
CREATE TABLE TRAN_LOG (IMSTIME TIMESTAMP DEFAULT,
IMSTRAN CHAR (8) NOT NULL,
IMSDATA VARCHAR(71) NOT NULL);
COMMIT ;

Next, the IMUBMS stored procedure must be defined to the SYSIBM.SYSPROCEDURE table. This
stored procedure is defined with COMMIT-ON-RETURN to show you how to return a result set when
using COMMIT_ON_RETURN and how COMMIT_ON_RETURN affects a global temporary table.
INSERT INTO SYSIBM.SYSPROCEDURES
(PROCEDURE, AUTHID, LUNAME, LOADMOD,
LINKAGE, COLLID, LANGUAGE, ASUTIME,
STAYRESIDENT, IBMREQD, RUNOPTS,
PARMLIST,
RESULT_SETS, WLM_ENV, PGM_TYPE, EXTERNAL_SECURITY,
COMMIT_ON_RETURN )
VALUES(′ IBUBMS′ , ′ ′, ′ ′, ′ IBUBMs′ ,
′ ′, ′ SAMPLESP′ , ′ COBOL′ , 0,
′ ′, ′ N′ , ′ ′,
′ CHAR(8) IN, CHAR(71) IN
1, ′ WLMENV2′ , ′ M′ , ′ N′ ,
′ Y′ ) ;
COMMIT;

The following is a summary of the IMUBMCBM client program and the IMUBMS stored procedure:
1. IMUBMCBM declares a result locator for the result set that will be returned from IMUBMS.
2. A working storage field is defined to hold the 100 characters returned from the result set.
3. Two fields are defined to be passed to IMUBMS:
• An 8-character field to hold the IMS IVP transaction
• A 71-character field to hold the IMS IVP transaction data
4. IMUBMCBM reads an IMS IVP transaction, calls the stored procedure IMUBMS, passing to it the
IMS IVP transaction code and its data. It uses the SIMPLE linkage.
5. IMUBMS first deletes any rows in the global temporary table. Although we have defined this
stored procedure to use COMMIT_ON_RETURN, the rows are not deleted when we return to the
client. This is because the application process has an open cursor WITH HOLD option on this table
to pass the IMS rows back to IMUBMCBM. With COMMIT_ON_RETURN, any cursor that is opened
without the WITH HOLD option is closed when control is returned to the client application, and no
data is passed back to the client application. Because the client application can invoke the stored
procedure again using the same thread, the stored procedure must delete the rows inserted when
the stored procedure was invoked previously.

Chapter 13. Accessing Non-DB2 Resources 295


6. IMUBMS initializes the conversation to the IMS region.
7. IMUBMS sets the TPN to the IMS IVP transaction that was passed to it. To perform this, IMUBMS
uses the CPI CMSTPN function.
8. IMUBMS allocates a conversation with this IMS IVP transaction.
9. The IVP transaction and its data are inserted into the DB2 transaction log table.
10. IMUBMS sends and flushes the data containing the transaction.
11. The partner IVP transaction is scheduled by the IMS control region.
12. The IVP transaction gets the data and sends the reply back. In the case of an existing transaction
and good data, the related information is returned. Otherwise, an error message is returned.
13. IMUBMS loops to receive data and stores this data in the DB2 global temporary table. It continues
to loop until all data has been received.
14. When a deallocated normal message is received from IMS, IMUBMS ends the conversation.
15. IMUBMS declares a cursor WITH HOLD WITH RETURN options that selects all the rows from the
DB2 global temporary table:
EXEC SQL DECLARE TESTE-CURSOR CURSOR
WITH HOLD WITH RETURN FOR
SELECT COL1
FROM TEMPIMS
END-EXEC.
16. The TESTE-CURSOR cursor is opened and control is returned to the client program IMUBMCBM.
17. IMUBMCBM checks for an SQLCODE of +466, to see if a result set was returned.
18. If a result is returned, IMUBMCBM associates the result set locator variable with the result set
using the ASSOCIATE LOCATORS SQL command.
19. A cursor is allocated to the result set with the ALLOCATE SQL command.
20. IMUBMCBM loops until all rows from the result set are fetched with the FETCH SQL command.
21. IMUBMCBM then reads the next IMS IVP transactions.

13.5.4 IMDBMCBM, IMDBMS and IMS IVP Transactions


This program uses a VARCHAR parameter IMS-OUTPUT1 to get the IMS transaction output back from
IMDBMS. A second area, XXX_OUTPUT, is defined in working storage with an OCCURS clause so the
data can be looped through for display:
**********************************************************
01 IMS-TRANSACTIONS.
05 IMS-TRAN PIC X(8).
05 FILLER PIC X.
05 IMS-DATA PIC X(71).
01 IMS-LINES PIC S9(4) COMP.
01 IMS-OUTPUT1.
49 IMS-OUTPUTL PIC S9(4) COMP.
49 IMS-OUTPUTS PIC X(400).
**********************************************************
* DEFINE INDICATOR VARIABLES FOR STORED PROCEDURE PARMS *
**********************************************************
01 IMS-ARRARY.
03 IMS-TRANI PIC S9(4) COMP.
03 IMS-DATAI PIC S9(4) COMP.
03 IMS-LINESI PIC S9(4) COMP.
03 IMS-OUTPUT1I PIC S9(4) COMP.

296 Getting Started with DB2 Stored Procedures


**********************************************************
* DEFINE NEW OUTPUT VARIABLES TO BE REDEFINED TO *
* PIC X(80) OCCURS 5 TIMES. THIS WILL ALLOW YOU *
* TO LOOP THROUGH THE OUTPUT WHEN PROCESSING IT. *
**********************************************************
01 XXX-OUTPUT.
03 XXX-OUTPUTS PIC X(80) OCCURS 5 TIMES.

Next, the IMDBMS stored procedure must be defined to the SYSIBM.SYSPROCEDURE table. This
stored procedure is defined with SIMPLE WITH NULLS:
DELETE FROM SYSIBM.SYSPROCEDURES
WHERE PROCEDURE=′ IBUBMS′ ;
commit;
INSERT INTO SYSIBM.SYSPROCEDURES
(PROCEDURE, AUTHID, LUNAME, LOADMOD,
LINKAGE, COLLID, LANGUAGE, ASUTIME,
STAYRESIDENT, IBMREQD, RUNOPTS,
PARMLIST,
RESULT_SETS, WLM_ENV, PGM_TYPE, EXTERNAL_SECURITY,
COMMIT_ON_RETURN )
VALUES(′ IBDBMS′ , ′ ′, ′ ′, ′ IBDBMs′ ,
′ N′ , ′ SAMPLESP′ , ′ COBOL′ , 0,
′ ′, ′ N′ , ′ ′,
′ CHAR(8) IN, CHAR(71) IN
0, ′ WLMENV2′ , ′ M′ , ′ N′ ,
′ N′ ) ;
COMMIT;

The following is a summary of the IMDBMCBM client program and the IMDBMS stored procedure:
1. IMDBMCBM sets the indicator variables for IMS-LINES and IMS-OUTPUT1 to a negative one. This
will stop the sending of these two fields to the stored procedure on the CALL. Two fields are
passed to IMDBMS.
• An 8-character field that contains the IMS IVP transaction
• A 71-character field that contains the IMS IVP transaction data
2. IMDBMCBM reads an IMS IVP transaction and calls the stored procedure IMDBMS passing the IMS
IVP transaction. It uses the SIMPLE WITH NULL linkage.
3. IMDBMS initializes the conversation to the IMS region
4. IMDBMS sets the TPN to the IMS IVP transaction code passed to it, using the CPIC CMSTPN
function.
5. IMDBMS allocates a conversation with this IMS IVP transaction.
6. The IVP transaction and its data are inserted into the transaction log table.
7. IMDBMS sends and flushes the data that contains the transaction code.
8. The partner IVP transaction is scheduled by the IMS control region, and the IVP transaction gets
the data, and sends the reply back. In the case of an existing transaction and good data, the
related information is returned. Otherwise, an error message is returned.
9. IMDBMS loops to receive data and stores this data into the field defined with an OCCURS clause.
10. When a deallocated normal message is received from IMS, IMDBMS ends the conversation.
11. IMDBMS then sets the length of the VARCHAR field with the number of lines returned from IMS
times the length of the lines.

Chapter 13. Accessing Non-DB2 Resources 297


12. The OCCURS field is moved to the VARCHAR text.
13. The indicator variables for the IMS-TRAN and IMS-DATA are set to a negative 1 so they are not
returned to the client.
14. The IMS-LINES and IMS-OUTPUT indicator variables are set to zero, so they are returned to the
client. IMDBMS is then returned to IMDBMCBM.
15. IMDBMCBM checks to see if IMS-LINES is greater then zero. If it is, the IMS-OUTPUT1 field is
moved to the XXX-OUTPUT OCCURS field.
16. IMDBMCBM loops, using the IMS-LINES, until all rows from the XXX-OUTPUT are displayed.
17. IMDBMCBM then reads the next IMS IVP transactions.
For more information on writing TPs for APPC, see OS/390 MVS Writing TPs for APPC/MVS and
MVS/ESA SP V5 Planning: APPC Management .

For more information on the IMS IVP transactions PART, ADDPART and DLETPART, which come with
IMS installation verification, refer to IMS/ESA: Installation Volume 1: Installation and Verification ,
SC26-8023.

298 Getting Started with DB2 Stored Procedures


Chapter 14. DB2 Common Server Performance Considerations

In this chapter, we discuss several issues related to the performance of an application using stored
procedures. We used stored procedures based on the samples that come with DB2 Common Servers.
We encourage you to reproduce some of our tests in your own environment to verify the performance
improvements for each scenario.

Although the performance aspects of stored procedures are certainly important, we suggest that you
consider the other advantages of using stored procedures. Performance is one, but probably not the
only, reason to implement stored procedures. Refer to Chapter 1, “Stored Procedures Overview” on
page 1 for information about the advantages of stored procedures.

Here is a summary of some of the programs we use in this chapter.

Table 23. Sample Programs Used for Performance Measurement


PR0 PR1 PR2 PR3 PR4
Client pr0c2cr2 pr1c2cr2 pr2c2cr2 pr3c2cr2 pr4c2cr2
Server pr0c2s pr1c2s pr2c2s pr3c2s pr4c2s
Type dynamic SQL static SQL static static
compound SQL unfenced SQL

14.1 Traditional Coding and Stored Procedures

In this section, we compare using stored procedures with using traditional coding where each SQL
statement must be shipped to the server in order to be executed on the server. For the comparisons
we created two scenarios.

In the first scenario, we coded a traditional SQL program that did not use stored procedures. The
traditional application was written in REXX and executed on an OS/2 client connected to a DB2 for
OS/2 server database.

In the second scenario, a stored procedure issued 10 SQL PREPARE and 10 SQL INSERT statements.
These 20 statements were repeated a number of times according to a LOOP parameter defined in the
client program. The client program was written in REXX and ran on an OS/2 client. The stored
procedure was written in REXX and ran on an OS/2 server.

Table 24 shows the results of the comparison.

Table 24 (Page 1 of 2). Stored Procedures and Traditional Coding


Number of INSERTs Stored Procedures (seconds) Traditional (seconds)
10 0.54 0.48
20 0.82 0.84
30 1.10 1.19
40 1.41 1.54
50 1.69 1.92
100 3.18 3.72
500 14.67 18.05

 Copyright IBM Corp. 1996 1998 299


Table 24 (Page 2 of 2). Stored Procedures and Traditional Coding
Number of INSERTs Stored Procedures (seconds) Traditional (seconds)
1000 29.09 35.94
Note: Seconds are elapsed execution time.

The execution of these programs was relatively slow for the following reasons:
• All three programs (the client, the stored procedure, and the traditional program) were coded in
REXX, which is an interpreted language.
• For each INSERT statement, the program issued an SQL PREPARE statement to simulate execution
of a command different from the SQL INSERT statement. In this test, the PREPARE statement was
not necessary because the program executed the same INSERT statement multiple times, but we
included it to measure the results if different SQL statements were executed.

This test was executed between two dedicated OS/2 PCs connected through a 16 MB LAN. As the
connection between the client and the server machine became slower, or as network traffic increased,
the performance advantage of stored procedures became more obvious, even with only a few SQL
statements. As with all performance tests, we recommend reproducing them in your own environment
to determine the potential benefits.

You can find the following programs from this test on the diskette that accompanies this book: sp0r2s
for the stored procedure, sp0r2cr2 for the client program, and rr22xsp0 for the traditional program.

14.2 Dynamic and Static SQL

In most cases, static SQL performs better than dynamic SQL. To verify the effects of using static and
dynamic SQL in a stored procedure, we developed two C OS/2 stored procedures: one used static
SQL, and the other used dynamic SQL. When the stored procedure was invoked, it issued 10 SQL
INSERT statements. We measured the time that elapsed when the client program invoked the stored
procedure 10 times and 50 times. Table 25 shows the results.

Table 25. Static and Dynamic SQL


Loops Static (seconds) Dynamic (seconds)
10 1.41 1.61
50 6.94 7.82
Note:
1. Loops are the number of times the stored procedure was called. For example, during 10 loops there was
a total of 100 inserts.
2. Seconds are elapsed execution time.

As the dynamic SQL had to issue an SQL PREPARE and an SQL EXECUTE statement for each INSERT,
it is no surprise that the static SQL with just a single SQL statement executed faster.

In our case, 10 PREPARE statements were not needed for the 10 INSERT statements as explained in
14.1, “Traditional Coding and Stored Procedures” on page 299. The client program was written in
REXX and ran on an OS/2 client; the stored procedure ran on the OS/2 server.

You can find the following programs from this test on the diskette that accompanies this book: pr1c2s
for the stored procedure and pr1c2cr2 for the client program when dynamic SQL is used, and pr2c2s
for the stored procedure and pr2c2cr2 for the client program when static SQL is used.

300 Getting Started with DB2 Stored Procedures


14.3 Using Compound SQL

Using compound SQL is a way of reducing network traffic by grouping multiple SQL statements into a
single executable block.

As stored procedures reside on the server, network traffic is already reduced. Because stored
procedures usually run fenced, there is still interprocess communication overhead between the DB2
kernel processes and the process running the stored procedure. Compound SQL improves the overall
performance by reducing this interprocess communication. To measure the effect of using compound
SQL statements, we changed the static SQL statements described in 14.2, “Dynamic and Static SQL”
on page 300 to use compound SQL statements. Table 26 shows the results for compound static SQL.

Table 26. Compound, Static, and Dynamic SQL Comparison


Loops Compound (seconds) Static (seconds) Dynamic (seconds)
10 1.30 1.41 1.61
50 6.32 6.94 7.82
Note:
1. Loops are the number of times the stored procedure was called.
2. Seconds are elapsed execution time.

You can find the following programs from this test on the diskette that accompanies this book: pr3c2s
for the stored procedure and pr3c2cr2 for the client program.

Note the following about compound SQL:


• Compound SQL statements are always executed as static SQL; dynamic SQL is not supported.
• Host language code is not allowed in a compound SQL statement. Therefore, you cannot code:

EXEC SQL BEGIN COMPOUND NOT ATOMIC STATIC


for (cntr = 0; cntr < num_of_data; cntr++)
{
strcpy (president, data_items[cntr]);
EXEC SQL INSERT INTO PRESIDENTS (NAME) VALUES (:president);
}
END COMPOUND;
/* This won′ t work ! */
Instead, to insert 10 names in the PRESIDENTS table, you have to code:
EXEC SQL BEGIN COMPOUND NOT ATOMIC STATIC

INSERT INTO PRESIDENTS (NAME) VALUES (:president1);


INSERT INTO PRESIDENTS (NAME) VALUES (:president2);
INSERT INTO PRESIDENTS (NAME) VALUES (:president3);
INSERT INTO PRESIDENTS (NAME) VALUES (:president4);
INSERT INTO PRESIDENTS (NAME) VALUES (:president5);
INSERT INTO PRESIDENTS (NAME) VALUES (:president6);
INSERT INTO PRESIDENTS (NAME) VALUES (:president7);
INSERT INTO PRESIDENTS (NAME) VALUES (:president8);
INSERT INTO PRESIDENTS (NAME) VALUES (:president9);
INSERT INTO PRESIDENTS (NAME) VALUES (:president10);

END COMPOUND;

Chapter 14. DB2 Common Server Performance Considerations 301


For more information about compound SQL, see Chapter 6, “Statements,” in the SQL Reference for
Common Servers .

14.4 Using Unfenced Stored Procedures

Although we do not recommend that you run stored procedures unfenced for reasons discussed in 4.5,
“Fenced and Unfenced Stored Procedures” on page 76, we measured the effect of using unfenced
stored procedures. Table 27 shows the results for unfenced stored procedures. For this test, we used
the same program we used for the static, noncompound SQL tests (program pr2c2s, here renamed to
pr4c2s).

Table 27. Unfenced Stored Procedures


Loops Unfenced Compound Static (seconds) Dynamic (seconds)
(seconds) (seconds)
10 0.91 1.30 1.41 1.61
50 4.42 6.32 6.94 7.82
Note:
1. Loops are the number of times the stored procedure was called.
2. Seconds are elapsed execution time.

You can find the following programs from this test on the diskette that accompanies this book: pr4c2s
for the stored procedure and pr4c2cr2 for the client program.

14.5 Embedded SQL and CLI

To compare embedded dynamic SQL with CLI, we wrote test programs where we had one PREPARE
statement followed by 10 inserts. We ran the programs with 10 calls and 50 calls to the stored
procedure. Table 28 shows the results.

Table 28. Embedded Dynamic SQL and CLI


Loops CLI (seconds) Embedded Dynamic (seconds)
10 1.43 1.42
50 6.80 6.71
Note:
1. Loops are the number of times the stored procedure is called.
2. Seconds are elapsed execution time.

You can find the following programs from this test on the diskette that accompanies this book: cl2o2s
for the stored procedure and cl2o2cr2 for the client program using CLI, and dd1c2s for the stored
procedure and dd1c2cr2 for the client program using embedded dynamic SQL.

You cannot compare this test with the previous tests because in this test we ran one statement 10
times. In the previous tests, we basically ran 10 different statements, each requiring its own PREPARE
statement.

We also tested CLI with a PREPARE statement for each insert, but we found that the CLI SQLPrepare
statement was more time consuming than the embedded dynamic SQL PREPARE statement. In a case
with many prepare statements, performance might be better if you code the stored procedure in
embedded SQL and use CLI for the client only.

302 Getting Started with DB2 Stored Procedures


14.6 The KEEPDARI Indicator

The KEEPDARI indicator has an important impact on the performance of stored procedures. If
KEEPDARI is set to YES, the process required for running a stored procedure remains active after the
stored procedure has ended. If KEEPDARI is set to NO, the db2dari process must be rebuilt each time
a stored procedure is called.

We ran some tests with a stored procedure that issued 10 inserts. Subsequently we called this stored
procedure several times, comparing the elapsed time with KEEPDARI=YES and KEEPDARI=NO. As
expected, with KEEPDARI=YES the subsequent calls were processed much faster (see Table 29).

Table 29. KEEPDARI Measurements


Loops TIME(KEEPDARI=YES) (seconds) TIME(KEEPDARI=NO) (seconds)
1 0.25 0.54
2 0.37 1.10
5 0.81 3.65
10 1.50 7.10
15 2.22 10.60
20 2.85 13.80
50 7.10 45.00
Note:
1. Loops are the number of times the stored procedure was called. For example, during 10 loops there were
100 inserts.
2. Seconds are elapsed executiom time.

This test was done with a REXX OS/2 program running on an OS/2 client workstation and calling a C
OS/2 stored procedure written with embedded dynamic SQL statements running on an OS/2 server.

14.7 Keeping Stored Procedures in Memory

As discussed in 7.2.3.3, “SQLZ_DISCONNECT_PROC and SQLZ_HOLD_PROC” on page 109, it is


possible to keep a stored procedure in main memory after its first invocation. In this way, subsequent
calls to the same stored procedure execute faster, enhancing performance. To measure the benefit,
we executed the client program calling the same stored procedure 20 times. Table 30 shows the
results.

Table 30. Keeping a Stored Procedure in M e m o r y


Number of Times Procedure Was In Memory (SQLZ_HOLD_PROC) Not in Memory
Called (SQLZ_DISCONNECT_PROC)
20 2.10 seconds 3.03 seconds
Note: Seconds are elapsed execution time.

You can find the following programs from this test on the diskette that accompanies this book: pr1c2s
for the stored procedure and pr1c2cr2 for the client program.

Chapter 14. DB2 Common Server Performance Considerations 303


14.8 Performance Summary

The following are our recommendations for achieving performance gains:


• Set KEEPDARI to YES.
• Code stored procedures in embedded static SQL.
• Use compound SQL where possible.
• Use SQLZ_HOLD_PROC for the stored procedures most frequently called.

We also recommend setting MAXDARI to the MAXAGENTS value and running unfenced stored
procedures on dedicated test machines, or only after they have been thoroughly tested.

For other performance measurements and capacity planning information, refer to Appendix B,
“Performance Benchmark and Capacity Planning” on page 377 and Appendix C, “DB2 Connect Result
Set Study” on page 415.

304 Getting Started with DB2 Stored Procedures


Chapter 15. Debugging DB2 on MVS Stored Procedures

In this chapter, we describe how to debug DB2 on MVS stored procedures with the CoOperative
Development Environment/370 (CODE/370). We discuss installation considerations, preparations for
debugging your stored procedure for testing, and use of the CODE/370 debug tool.

15.1 CODE/370 Overview

DB2 on MVS stored procedures run in an environment where some commonly used debugging tools,
such as TSO TEST, are not available. CODE/370 provides a powerful alternative for testing and
debugging DB2 for MVS/ESA stored procedures.

CODE/370 is an integrated edit, compile, and debug tool for high-level languages application
development and maintenance across different platforms. CODE/370 functions are available in the
OS/2 environment, operating cooperatively with the host. CODE/370 works with COBOL/370, C/370, or
PL/I compilers and with the LE/370 run-time environment to create the applications. Figure 138 is an
overview of the CODE/370 cooperative environment.

Figure 138. CODE/370 Overview

CODE/370 provides the following functions:


• Language-sensitive editor

 Copyright IBM Corp. 1996 1998 305


• Host compiler invocation interface
• Advanced cooperative debugger, programmable workstation (PWS) debug tool
• Mainframe interactive debug tool (MFI), and batch debug tool
• Comprehensive online help and documentation

In this chapter, we focus on the debugging functions of CODE/370. For more information on other
CODE/370 functions, refer to the CODE/370 General Information Manual .

The CODE/370 debug tool is an interactive debugger with both a mainframe and an OS/2 interface. It
provides a very powerful set of debugging functions that can be used in CMS, CICS, IMS, TSO, and
MVS batch environments. CODE/370 supports DB2 for MVS/ESA stored procedures as an MVS batch
environment.

The CODE/370 debug tool enables you to:


• Debug your program even if it was link-edited with modules written in different languages.
• Monitor the frequency of statement execution for performance purposes.
• Replay all logged debug commands.
• Perform step mode debugging and set dynamic breakpoints:
− You can monitor and interrupt the execution of a program to easily identify errors and correct
them quickly.
− The tool animates execution of the program in visual form so that you can step through the
execution of the program.
− You can use “step” and “go” control to focus on a problem area or resume execution of the
application program.
− You can dynamically add, remove, enable, or disable breakpoints.
− The tool can execute commands at a breakpoint with or without user interaction.
− You can display and change variables at breakpoints.
− You can monitor program variable changes during program execution.
− You can simulate exception conditions to test error handling.
• Follow the execution of a program in the compiler listing view to quickly and effectively identify and
correct errors in the source code.

The functions above are available in both the mainframe and PWS debug tools.

The mainframe debug tool runs in interactive or batch mode. In interactive mode (MFI) you use panels
to issue debug commands and monitor the execution of the program. In batch mode, you must create
a data set with the debug commands to be used and a data set to receive the debug information.

The PWS debug tool (Figure 139 on page 307) runs on an OS/2 workstation in interactive mode. You
use OS/2 windows to issue debug commands and monitor the execution of the program. The PWS
must be connected to the mainframe through APPC.

306 Getting Started with DB2 Stored Procedures


Figure 139. CODE/370 PWS Debug Tool

To debug DB2 for MVS/ESA stored procedures you can use either the PWS debug tool or the
mainframe batch debug tool. Because stored procedures run in a separate address space, you cannot
use the MFI debug tool to debug them. To debug MVS client programs, you can use either the PWS
debug tool, the MFI, or the batch debug tool.

15.2 CODE/370 Installation Considerations

15.2.1 Prerequisites for Installation


To debug DB2 for MVS/ESA stored procedures, we recommend that you use the PWS debug tool. To
install the PWS debug tool in your workstation, you must already have installed the CODE/370 product
on the host system.

The workstation components of CODE/370 are downloaded from the host system during the process of
installing CODE/370 on the workstation. You must have a 3270 terminal emulation defined in your
workstation to install CODE/370 in your workstation.

To debug DB2 for MVS/ESA stored procedures, you must ensure that you have the following PTFs
applied in your system:
• LE/370 Version 1.5

Chapter 15. Debugging DB2 on MVS Stored Procedures 307


− UN86441 (CEEPIPI fix for workstation ID)
• CODE/370 Version 1.2
− UN86398 (header file support)
− UN87131 (CEEPIPI fix for multiple calls)

For a complete description of the installations steps, refer to Chapter 2, “Installing CODE/370 on Your
Workstation,” in the CODE/370 Installation Manual .

15.2.2 Communications Configuration for CODE/370


To use CODE/370 cooperative functions, such as the PWS debug tool, between your workstation and
the host, you must configure some communication parameters on your workstation and on the host
system. You must use Communications Manager/2 (CM/2) functions for the configuration on your
workstation.

15.2.2.1 Configuring the Workstation: The CODE/370 PWS debug tool requires an APPC
connection between your workstation and the host system. The configuration required for CODE/370
connection is similar to the configuration required for DRDA connection. If your workstation is already
configured for DRDA connection, most of the definitions for CODE/370 probably exist.

In this section, we describe only those definitions required by the CODE/370 PWS debug tool that are
not defined when you create an APPC connection for DRDA. Refer to Chapter 3, “Configuring
Communications for CODE/370,” of the CODE/370 Installation Manual , for a complete list of the
definitions required for CODE/370.

When running CODE/370 interactively to debug a DB2 for MVS/ESA stored procedure, the PWS debug
tool runs as a server to the CODE/370 debug functions on the host. Defining your workstation as a
PWS debug tool server requires that you create a transaction program name (TPN) definition in CM/2.
This TPN definition is similar to the TPN definitions you create when configuring DB2 for OS/2 as a
DRDA server. Follow these steps:
1. To configure the TPN for the PWS debug tool, select Transaction program definition in the SNA
Features List window and click on the Create push button, as shown in Figure 140 on page 309.

308 Getting Started with DB2 Stored Procedures


Figure 140. SNA Features List Window

The Transaction Program Definition window (Figure 141) is displayed.

Figure 141. Transaction Program Definition Window

2. Fill in the following information:


• Type CODE370DT in the Transaction program (TP) name field
• In the OS/2 program path and file name field, type:
D:\CODE\BIN\EQACEL62.EXE
where D is the drive where CODE/370 is installed.
3. Click on the Continue push button. The Additional TP Parameters window is displayed, as shown
in Figure 142 on page 310.

Chapter 15. Debugging DB2 on MVS Stored Procedures 309


Figure 142. Additional TP Parameters

4. Select Presentation Manager for Presentation type and Non-queued, Attach Manager started for
Operation type.
5. Click on the OK push button.

15.2.2.2 Configuring the Host: CODE/370 requires some definitions on the host system. We
assume that your host system has been prepared for APPC connection with your workstation. In this
section, we discuss only the configuration of the APPC/MVS subsystem required by CODE/370.

APPC/MVS Definitions: APPC/MVS uses PARMLIB members APPCPMxx and ASCHPMxx to store its
definitions. You must update these members with CODE/370 information. The debug tools requires an
entry only in the APPCPMxx member. The CODE/370 edit and compile tools require an entry in the
ASCHPMxx member. If you plan to use CODE/370 edit and compile tools, refer to the CODE/370
Installation Manual for configuration requirements.

Here is an example of an entry in the APPCPMxx member:


LUADD ACBNAME(SCC370)
SCHED(ASCH)
TPLEVEL(USER)
TPDATA(SYS1.APPCTP)
BASE
.
.
.
SIDEINFO DATASET(SYS1.APPCSI)

The SIDEINFO DATASET is a VSAM data set used to store the CPI-C side information. The CODE/370
debug tool uses information stored in this data set to establish the APPC connection to your
workstation. Refer to “CPI-C Side Information” on page 311 for information on how to load this data
set with CODE/370 information.

You must define the CODE/370 LU to VTAM. Here is an example of the VTAM definition required by
CODE/370:
VBUILD TYPE=APPL
*
SCC370 APPL ACBNAME=SCC370,
APPC=YES,
AUTOSES=10,
DDRAINL=NALLOW,
DMINWNL=16,
DMINWNR=16,

310 Getting Started with DB2 Stored Procedures


DRESPL=NALLOW,
DSESLIM=64,
EAS=64,
MODETAB=AGWTAB,
SECACPT=CONV,
SRBEXIT=YES,
VPACING=2,
VERIFY=NONE

Note that the LUNAME in the VTAM definition must match the ACBNAME in the APPCPMxx member.

CPI-C Side Information: To configure the CODE/370 PWS debug tool as a client in the host system,
you must add an entry in the CPI-C side information data set. This data set is defined to APPC/MVS in
the APPCPMxx member.

The CPI-C side information defines a symbolic destination name for your workstation. When you
invoke your stored procedure by using the TEST run-time option, this name indicates the name of the
workstation used to debug the stored procedure. You must have an entry in this data set for every
workstation that is going to be used as a CODE/370 PWS debug tool server. Here is the sample JCL to
create an entry in the CPI-C side information data set:
//SIADD0 JOB (999,POK),NOTIFY=&SYSUID,
// CLASS=A,MSGCLASS=T,MSGLEVEL=(1,1),TIME=1440
//STEP EXEC PGM=ATBSDFMU
//SYSPRINT DD SYSOUT=*
//SYSSDLIB DD DSN=SYS1.APPCSI,DISP=SHR
//SYSSDOUT DD SYSOUT=*
//SYSIN DD *
SIADD
DESTNAME(SC02130I)
TPNAME(CODE370DT)
MODENAME(IBMRDB)
PARTNER_LU(SC02130I)
/*

In this example, the TPNAME must match the transaction program name defined in the CM/2 profile.
(See Figure 141 on page 309 for an example of the CM/2 transaction program definition.) We used the
log mode IBMRDB. This log mode is the same as that used by the DRDA connection, and there is no
need to define a new log mode for the CODE/370 connection. The PARTNER_LU is the LUNAME of
your workstation.

Updating the Stored Procedures Address Space JCL Procedure: After you have completed the
CODE/370 installation and customization, to debug DB2 on MVS stored procedures you must update
the stored procedures address space JCL procedure. You must concatenate the CODE/370 load library
to the STEPLIB list. Here is an example of the stored procedures address space JCL procedure with
the CODE/370 library for DB2 Version 4:
//DB41SPAS PROC RGN=0K,TME=1440,SUBSYS=DB41,NUMTCB=8
//IEFPROC EXEC PGM=DSNX9STP,REGION=&RGN,TIME=&TME,
// PARM=′&SUBSYS,&NUMTCB′
//STEPLIB DD DISP=SHR,DSN=DSN410.RUNLIB.LOAD
// DD DISP=SHR,DSN=SYS1.CEE.V1R5M0.SCEERUN
// DD DISP=SHR,DSN=DSN410.SDSNLOAD
// DD DISP=SHR,DSN=EQAW.V1R2M0.SEQAMOD <--------
// DD DISP=SHR,DSN=STDRD2A.STPROC.LOAD

Chapter 15. Debugging DB2 on MVS Stored Procedures 311


15.3 Preparing to Debug Your Stored Procedure

To provide the CODE/370 debug tools with necessary debugging information, you must compile your
stored procedure with the TEST compiler option. This option causes the compiler to create the
dictionary tables that the debug tool uses to obtain information about program variables.

In addition, the compiler inserts program hooks at selected points in your program. Your source is not
modified. These points can be at entrances and exits of blocks, at statements, and at points in the
program where program flow may change between statement boundaries (called path points ), such as
before and after a CALL statement. Using these hooks, you can set breakpoints that enable you to
gain control when you are debugging the stored procedure and issue CODE/370 debug tool commands.

15.3.1 TEST Compiler Option Syntax


The syntax of the TEST compiler option for the C compiler differs from the syntax of the TEST compiler
option for COBOL and PL/I. Figure 143 shows the syntax of the C compiler TEST option.

Figure 143. TEST Option Syntax: C Compiler

Figure 144 shows the syntax of the TEST option for the COBOL and PL/I compilers.

Figure 144. TEST Option Syntax: COBOL and PL/I Compilers

For C compilers, the TEST option can have any number of suboptions, even if they are contradictory.
In this case, the last suboption specified in the list is used. For example,
TEST(BLOCK,NOBLOCK,SYM) is equivalent to TEST(NOBLOCK,SYM).

For COBOL and PL/I compilers, the TEST option can have a maximum of two suboptions specified.
The first suboption refers to the program hooks that are created in your stored procedure; the second
suboption refers to the creation of dictionary tables that enable the debug tool to access variables.

Here is a summary of the TEST suboptions: (For more detailed information about the TEST suboptions,
refer to the CODE/370 Debug Tool Manual .)

312 Getting Started with DB2 Stored Procedures


ALL Generates all program hooks, which includes all statement, path, and program entry
and exit hooks. For the C compiler, this option also generates a symbol table.
BLOCK Program hooks are inserted at all block entry and exit points.
NONE Hooks are not inserted in the program.
PATH Program hooks are inserted at all path points.
STMT Hooks are inserted at every statement and label, and at all entry and exit points. This
option does not apply to the C compiler.
SYM Generates symbol tables that enable the debug tool to access variables and other
symbol information.
NOSYM Suppresses the generation of symbol tables.

The following suboptions apply only to the C compiler:


NOBLOCK Prevents program hooks from being generated for nested blocks.
LINE Hooks are generated at most executable statements.
NOLINE Suppresses the generation of statement hooks.
NOPATH Suppresses the generation of path hooks.

For COBOL programs, specifying the TEST option with no suboption is equivalent to specifying
TEST(ALL,SYM).

For PL/I programs, specifying the TEST option with no suboption is equivalent to specifying
TEST(NONE,SYM).

15.3.2 Viewing the Source Code


While debugging in interactive mode with the PWS debug tool, you can view the stored procedure
source code.

For C stored procedures, the data set containing the source code is used to display the source code in
the PWS debug tool. When you prepare stored procedures, usually the source data set used by the C
compiler is a temporary data set generated by the DB2 precompiler. To view the C source code, you
must ensure that you direct the output of the DB2 precompiler to a nontemporary data set. Here is an
example of the JCL DD statements required when you prepare a stored procedure in C:
//PC EXEC PGM=DSNHPC,PARM=′ HOST(C),MARGINS(1,80)′ , REGION=4096K
//SYSCIN DD DSN=DSN410.CODE.SOURCE,DISP=(NEW,CATLG),
// UNIT=SYSDA,SPACE=(TRK,(10,10))
.
.
//C EXEC PGM=EDCDC120,COND=(4,LT,PC),REGION=4096K,
// PARM=(′ RENT,NOMARGINS,SOURCE,NOSEQ,LIST,TEST(ALL)′ )
//SYSIN DD DSN=DSN410.CODE.SOURCE,DISP=SHR
.
.
.

For COBOL and PL/I stored procedures, the compiler listing is used to display the source code in the
PWS debug tool. You must ensure that your compiler listing is directed to a nontemporary file that is
available during the debugging session. Here is an example of the JCL DD statements required when
you prepare a stored procedure in COBOL:

Chapter 15. Debugging DB2 on MVS Stored Procedures 313


.
.
.
//COB EXEC PGM=IGYCRCTL,PARM=′ QUOTE,LIST,RENT,TEST′
//SYSPRINT DD DSN=DSN410.CODE.LISTING(PA0BMS),DISP=SHR
.
.
.

You can use both sequential and partitioned data sets to store the source code used by the CODE/370
debug tools.

Because the data set name is stored in the load module, you do not have to specify it when you invoke
the debug tool.

15.4 Using the CODE/370 Debug Tool


To debug DB2 for MVS/ESA stored procedures, you can use the CODE/370 PWS debug tool
interactively or the mainframe batch debug tool.

There are two ways of invoking the CODE/370 debug tool:


• Use the TEST run-time option
• Issue calls to CEETEST inside the stored procedure code.

In this section, we explain the use of the TEST run-time option. For information on the use of calls to
CEETEST, refer to the CODE/370 Debug Tool Manual .

15.4.1 TEST Run-Time Option


Use the TEST run-time option to invoke the CODE/370 debug tool and begin testing your stored
procedure. You must specify the TEST run-time option for stored procedures in the RUNOPTS column
of the SYSIBM.SYSPROCEDURES table. Figure 145 shows the syntax of the TEST run-time option.

Figure 145. TEST Run-time Option Syntax

The TEST run-time option has four suboptions, which are summarized below. For detailed information
about the suboptions refer to the CODE/370 Debug Tool Manual .

314 Getting Started with DB2 Stored Procedures


The first suboption is the test level and determines which conditions raised by the stored procedure
cause the debug tool to gain control. The possible values for this suboption are:
ALL or blank Specifies that the occurrence of an interrupt, termination of your program (either
normally or through an abend), or any program or LE/370 condition causes the debug
tool to gain control, even if no breakpoints are defined. The debug tool also gains
control at the defined breakpoints.
ERROR Specifies that the debug tool gains control only under certain error conditions.
NONE Specifies that the debug tool gains control from a condition only if a breakpoint is
defined for that condition.

The second suboption is the commands file suboption and determines the commands data set to be
used as a source of debug commands when you are running the debug tool in batch mode. This
option can also be used as an initial source of commands if you are running in interactive mode. The
possible values for this suboption are:
* or blank A commands file is not used, and the workstation is used to input debug tool
commands.
commands_file Specifies the ddname of the data set that contains the debug tool commands. If you
are using a command file, the ddname must be allocated in the stored procedures
address space JCL procedure.

The third suboption is the prompt level and can be used to send an initial set of debug commands to
be executed during program initialization. This suboption can also specify whether the debug tool
should gain control after LE/370 initialization. The possible values for this suboption are:
PROMPT or ; or blank Indicates that you want the debug tool to be invoked immediately after LE/370
initialization.
NOPROMPT or * Specifies that you do not want the debug tool to be invoked immediately after
the LE/370 initialization.
command Specifies that one or more debug tools is to be executed immediately after the
stored procedure initialization.

The fourth suboption consists of the session parameter and the preferences file, separated by a colon.
The session parameter provides information to the debug tool about the session characteristics
necessary to establish an MFI session or an APPC session. The preferences file indicates a file you
can use to specify default settings for your debugging environment. The possible values for this
suboption are:
MFI: or blank Specifies that the MFI debug tool should be invoked.
workstation_id Specifies your workstation APPC symbolic destination name. This value must match
the DESTNAME parameter formed when creating the CPI-C side information for your
workstation. Refer to “CPI-C Side Information” on page 311. An APPC session with
your workstation is automatically created and the PWS debug tool is automatically
started if you specify this option.
%session_id Specifies a unique identifier for each session, if multiple concurrent APPC debug
sessions are being conducted on your workstation. The default value is CODEDT.
INSPPREF or blank
The debug tool default preferences file ddname.
preferences_file
A ddname specifying the preferences file to be used. This file must be allocated in the
stored procedures address space JCL procedure if you plan to use a preferences file.
* A preferences file is not supplied.

Chapter 15. Debugging DB2 on MVS Stored Procedures 315


In our tests, when working with the PWS debug tool, we used the following TEST run-time option:
TEST(ALL,*,PROMPT,SC02130I:*)
ALL enables the debug tool to gain control at breakpoints and when predefined conditions occur. The
* indicates that a command file is not used. PROMPT indicates that the debug tool is invoked as soon
as the LE/370 environment for the stored procedure is initialized. SC02130I is the DESTNAME that
directs the host part of the debug tool to initiate a session with our workstation and start the PWS
debug tool at our workstation. The * indicates that a preference file is not used, so the default settings
are used.

When working with the MFI debug tool in batch mode, we used the following TEST run-time option:
TEST(ALL,TESTIN,PROMPT,MFI:*)
The basic difference between this TEST run-time option and the previous TEST run-time option is that a
command data set with ddname TESTIN is used and the MFI debug tool is invoked.

15.4.2 Debug Tool Session Example


Using the PWS debug tool enables you to test your stored procedure in a powerful, yet easy-to-use,
graphical environment. Most of the debug tool functions are available through menus and windows.
Figure 139 on page 307 shows an example of the PWS debug tool environment. In this section, we
present a PWS debug tool example, where we monitor the execution of a stored procedure modifying
the value of a parameter.

Once you have compiled your stored procedure with the TEST compiler option and updated the
SYSIBM.SYSPROCEDURES table with the TEST run-time option indicating the PWS debug tool to be
activated, when the stored procedure is invoked, the debug tool on the host initiates a session with the
workstation. The windows shown in Figure 146 on page 317 are automatically displayed on the
workstation.

316 Getting Started with DB2 Stored Procedures


Figure 146. PWS Debug Tool Windows

The details of the windows are explained in 15.4.3, “PWS Debug Tool Windows” on page 323 and are
summarized below:

• The CODE-LISTING window displays the stored procedure source code. The data set where the
source code is located is automatically obtained because it is stored in the load module. You can
use this window to generate debug tool commands by clicking on specific areas.
• The Debug Tool Command Log window is divided into two areas: the bottom is for commands
entered manually, and the top is a history log of the commands manually entered or automatically
generated and the results of the commands.
• The Global Monitor List window is used to monitor and change the values of variables during
execution of the stored procedure.
• In the Step/Run window, you control the execution of the stored procedure by indicating when the
stored procedure should proceed.

To begin testing your stored procedure, click on the Step button on the Step/Run window, so that the
first statement of the stored procedure is highlighted, as shown in Figure 147 on page 318.

Chapter 15. Debugging DB2 on MVS Stored Procedures 317


Figure 147. Beginning the Debug Session

Note that the Debug Tool Command Log window shows the STEP debug command associated with the
Step push button.

To set breakpoints, use your mouse to scroll the CODE-LISTING window until you get to the statement
where you want the debug tool to gain control during execution. In our example, we want the
execution to stop at statement 85. Double-click on the prefix area of statement 85 in the CODE-LISTING
window. The prefix area for the statement is highlighted, as shown in Figure 148 on page 319.

318 Getting Started with DB2 Stored Procedures


Figure 148. Setting a Breakpoint in the PWS Debug Tool

Note that the Debug Tool Command Log window shows the AT debug command associated with
setting a breakpoint.

Now click on the Run push button in the Step/Run window to execute the stored procedure. The stored
procedure is executed until statement 85 where we set a breakpoint. At this breakpoint, control is
returned to the PWS debug tool, the statement is highlighted, and you can enter debug tool commands.

At this point, we want to display the values of the PARM1 variable. Type the LIST PARM1 command in
the Debug Tool Command Log window, as shown in Figure 149 on page 320.

Chapter 15. Debugging DB2 on MVS Stored Procedures 319


Figure 149. Checking the Value of a Variable (Part 1)

Click on the Process push button to execute the command. Figure 150 shows the result of the LIST
PARM1 command.

Figure 150. Checking the Value of a Variable (Part 2)

Note that the value of the PARM1 variable is volta1.

320 Getting Started with DB2 Stored Procedures


If you want to change the value of the PARM1 variable, use the MOVE debug command. Then click on
the Process push button as shown in Figure 151 on page 321.

Figure 151. Changing the Value of a Variable

Now you can check the new value of PARM1 by issuing the LIST command again. The LIST PARM1
command is logged in the Debug Tool Command Log window, so you do not have to type it again.
Just use your mouse to select the command, and press Alt+Ins. The LIST PARM1 command is copied
automatically to the command area, as shown in Figure 152.

Figure 152. Copying a Command from the Log Area

Click on the Process push button, and check the new value of PARM1, as shown in Figure 153 on
page 322.

Chapter 15. Debugging DB2 on MVS Stored Procedures 321


Figure 153. Checking the New Value of a Variable

To resume execution of the stored procedure, click on the Run push button in the Step/Run window.
Because no other breakpoints were set and we compiled the stored procedure with the TEST compiler
suboption ALL, the stored procedure is executed and then terminates. At this point, you can enter
debug commands. Click on the Run push button again. The stored procedure finishes, and the PWS
debug tool enters a wait state, waiting for the next debug session, as shown in Figure 154.

Figure 154. Entering the Wait State

322 Getting Started with DB2 Stored Procedures


Click on the Cancel push button to end the PWS debug tool or start a new debugging session.

15.4.3 PWS Debug Tool Windows


In this section, we explain some of the PWS debug tool windows.

15.4.3.1 CODE-LISTING Window: The CODE-LISTING window (Figure 155) shows the source
code of your stored procedure. As explained in 15.3.2, “Viewing the Source Code” on page 313, when
preparing your stored procedure you must ensure that the source code data set (for C language) or the
listing data set (for COBOL and PL/I languages) are not temporary data sets, so that you can access
the source code while using the debug tool.

Figure 155. CODE-LISTING Window

In the CODE-LISTING window, you can monitor the execution of your stored procedures. The next
statement to be executed is highlighted in the source code. Using the CODE-LISTING window you can
also set breakpoints in your stored procedures, list the values of variables, add variables to the debug
tool monitors, run your stored procedure, and get help.

Setting Breakpoints: If you compile your stored procedure with the option TEST(ALL), you can set
breakpoints at most statements in your stored procedure. At these breakpoints, the execution of your
stored procedure is interrupted and the debug tool gains control. When the execution is interrupted,
you can issue debug commands, such as LIST, or change the values of variables.

In the CODE-LISTING window, you can set a breakpoint by double-clicking in the prefix area of the
source code. The prefix areas for statements with breakpoints are highlighted, as shown in Figure 156
on page 324. You can also set breakpoints by selecting Breakpoints from the source window action
bar.

Chapter 15. Debugging DB2 on MVS Stored Procedures 323


Figure 156. CODE-LISTING Window: Setting Breakpoints

Displaying the Value of a Variable: You can use the CODE-LISTING window to display and change the
values of variables. To display the value of a variable, double-click on any reference to the variable in
the source code. The variable value is then shown in a window as in Figure 157.

Figure 157. Displaying the Value of a Variable

To change the value of the variable, type the new value in the variable value window and press Enter.
The new value is assigned to the variable.

By selecting Variables from the source window action bar, you can specify the variables to be
monitored. The variables are added to the Local or Global Monitor List windows, and you can monitor
the values of these variables during execution of the stored procedure.

15.4.3.2 Step/Run Window: The Step/Run window, shown in Figure 158 on page 325, enables
you to control the execution of your stored procedure. It contains four push buttons that issue different
STEP and RUN debug commands.

324 Getting Started with DB2 Stored Procedures


Figure 158. Step/Run Window

Use the Step push button to execute the program one statement at time. When you click on the Step
button, the current statement is executed, and execution of the stored procedure is interrupted before
the next statement.

Use the Step over push button to step through the execution of the current statement, without stepping
through called programs, procedures, or functions. All statements of the program, procedure, or
function you want to step over are executed, and you are returned to the next statement after the call.
For example, Figure 159 shows that your stored procedure invokes another routine, PROG B, but you
do not want to monitor any of the statements of that routine.

Figure 159. Step Over Push Button Actions

Use the Step return push button when you are stepping through a called program, procedure, or
function and want to return to the point where the current program, procedure, or function was invoked
without stepping through the remaining statements. Clicking on Step return executes the remaining
statements of the current program, procedure, or function and returns to the next statement after the
call. For example, Figure 160 on page 326 shows that your stored procedure invokes a routine, PROG
B, and you are monitoring each statement of the routine. Then you decide that you do not want to
further monitor the statements of the routine. Instead, you want the routine to complete processing
without monitoring and get back to monitoring the stored procedure.

Chapter 15. Debugging DB2 on MVS Stored Procedures 325


Figure 160. Step Return Push Button Actions

Use the Run push button to execute the stored procedure statements up to the next breakpoint or the
end of the procedure.

15.4.3.3 Local and Global Monitor List Windows: Use the Local and Global Monitor List
windows to monitor the changing values of variables or change the values of variables. The Global
Monitor List window (Figure 161) appears when you invoke the debug tool. You can use it to monitor
the variables of all programs invoked during one debug session. The Local Monitor List window is a
secondary window. Each Local Monitor List window is associated with a specific CODE-LISTING
window, and you can use it only to monitor the variables of the program in that window.

Figure 161. Global Monitor List Window

To specify the variables you want to monitor, select Variables from the source code window action bar
or issue the debug tool MONITOR command.

326 Getting Started with DB2 Stored Procedures


15.4.3.4 Debug Tool Command Log Window: The Debug Tool Command Log window
(Figure 162 on page 327) contains a command input area for entering debug commands and a log
output area displaying a history of your debugging session. You can issue debug tool commands in
the command input area or use the action bar pull-down menus.

Figure 162. Debug Tool Command Log Window

The upper section is the log output area. The lower section is the command input area. To issue
debug tool commands, type the command in the command input area and click on the Process push
button.

Here is a list of some useful debug commands. For a complete list of debug commands, refer to the
CODE/370 Debug Tool Manual .
LIST variable Displays a variable value.
MONITOR GLOBAL LIST variable
Adds a variable to the Global Monitor List window.
MONITOR LOCAL LIST variable
Adds a variable to the Local Monitor List window.
CLEAR MONITOR n
Removes the variable number, n , from the monitor list.
MOVE value TO variable
Changes the value of a variable (COBOL stored procedures only).
variable = value
Changes the value of a variable (PL/I and C stored procedures).
AT LINE xx Sets a breakpoint at a specific line.
SET SOURCE ON(spname) DSN410.CODE.LISTING(spname)
Displays the stored procedure source code. The process of displaying the source
code should be automatic if you use a nontemporary file for the source code or
compiler listing when preparing the stored procedure.
COMMENT text Adds a comment to the log output area.
STEP n Steps through n statements in the source code.
RUN Runs the stored procedure up to the next breakpoint or to the end of the stored
procedure.
QUIT Ends the debug session.

Chapter 15. Debugging DB2 on MVS Stored Procedures 327


15.4.4 Using the Batch Debug Tool
To use the batch debug tool, you must create a data set with the debug commands you want to
execute. This data set must be allocated in the stored procedures address space JCL procedure, and
its ddname must be specified in the TEST run-time option. For example, if you use the following TEST
run-time option:
TEST(ALL,TESTIN,PROMPT,MFI:*)
You must have a JCL DD statement in your stored procedures address space to define the TESTIN
ddname as follows:
//TESTIN DD DSN=STDRD2A.CODE370.CMDS,DISP=SHR

Here is an example of the contents of a CODE/370 command file for debugging a stored procedure
written in COBOL:
COMMENT SIMPLE TEST OF STORED PROCEDURE;
AT 82
LIST ( ″AT THE BREAKPOINT FOR LINE″, %LINE ) ;
GO ;
STEP 1 ;
LIST PARM1;
MOVE ″RICARDO″ TO PARM1;
77 TEMP PIC X(10);
MOVE PARM1 TO TEMP ;
LIST TEMP ;
AT EXIT *
LIST ( ″EXITING ″, %CU ) ;
GO ;
QUIT ;

The output of the commands in the commands file is directed to a log data set. The default ddname
for the log data set is INSPLOG. You must have a JCL DD statement defined for this log data set in
your stored procedures address space JCL procedure as follows:
//INSPLOG DD DSN=DSN410.CODE370.LOG,DISP=SHR

To direct your output to a different ddname, you must include in your command file the following
command:
SET LOG ON FILE ddname;

The ddname specified in this command must be allocated to the stored procedures address space JCL
procedure.

Here is an example of the CODE/370 output log:


* IBM Debug Tool Version 1 Release 2 Mod 0
* 03/06/96 5:27:41 PM
* 5688-194 (C) Copyright IBM Corp. 1992, 1995
COMMENT SIMPLE TEST OF STORED PROCEDURE ;
AT 82
LIST ( ″AT THE BREAKPOINT FOR LINE″, %LINE ) ;
GO ;
* AT THE BREAKPOINT FOR LINE
* %LINE = 82.1
STEP 1 ;
LIST PARM1 ;
* PARM1 = ′ ALINE ′
MOVE ″RICARDO″ TO PARM1 ;
77 TEMP PIC X(10) ;

328 Getting Started with DB2 Stored Procedures


MOVE PARM1 TO TEMP ;
LIST TEMP ;
* TEMP = ′ RICARDO ′
AT EXIT *
LIST ( ″EXITING ″, %CU ) ;
GO ;
* EXITING
* %CU = PA0BMS
* QUIT ;

Chapter 15. Debugging DB2 on MVS Stored Procedures 329


330 Getting Started with DB2 Stored Procedures
Chapter 16. IBM VisualAge for Basic

IBM′s IBM VisualAge for Basic (VAB) enables you to develop, test, and maintain stored procedures
and UDFs. With VAB you can build, run, debug, test, register, and distribute server procedures by
using the client/server facilities of the VAB development environment.

16.1 Functions and Features

VAB provides the following functions and features:


• A project manager, which enables you to group related stored procedures and client programs as
one project
• A code editor, which displays your source code in an easy-to-read format with different colors and
fonts
• A BASIC interpreter, which supports a version of the BASIC language similar to Microsoft Visual
Basic Version 3.0
• A debugger, which enables you to set breakpoints, step through your code, inspect values, and
access the call stack
• Tools for building and registering server procedures on different server machines
• A set of dialogs called QuickTest dialogs to test server procedures
• The QuickTest SmartGuide, a feature that helps you generate test applications that use QuickTest
dialogs

Once you create the server procedures, they can be called from different client platforms just like other
stored procedures or UDFs. Any client program developed in any language that can access your
database server can access VAB server procedures. For clients written in Visual Basic, VAB provides
a Visual Basic custom control (VBX) that simplifies calling your stored procedure.

16.1.1 Environments and Platforms


In this section, we describe the platforms that VAB supports in the development, server, and client
environments.

16.1.1.1 Development Environment: VAB supports the following platforms where you can
develop, test, and maintain stored procedures and UDFs:
• OS/2
• AIX
• Windows NT
• HP-UX
• Solaris

 Copyright IBM Corp. 1996 1998 331


16.1.1.2 Client Environment: The client portions of your production applications can run on any
operating system that can access your database server. Client programs can be written in any
language that provides a relational database interface; for example you can use COBOL, C, C + + ,
DB2 CLI, or REXX to invoke stored procedures developed with VAB.

VAB comes with a Visual Basic custom control (VBX) that facilitates the integration of VAB stored
procedures with Visual Basic client applications. In addition, you can develop client applications using
VAB on the following platforms:
• Windows 95
• Windows NT
• OS/2

16.1.2 Advantages of Using VAB


Using VAB to code stored procedures provides the following advantages:
• Your stored procedures are portable.
• BASIC is easier to use than languages such as C or C++.
• You can manage your code in an integrated development and test environment, using advanced
debugging facilities.
• You can pass arrays to stored procedures.
• You do not have to declare host variables or an SQLDA.
• Precompile and bind are not required.

16.2 Creating Stored Procedures with VAB


In this section, we describe the steps you would follow to develop a stored procedure application. The
steps and sequence will vary according to your organization′s development methods and environment.

16.2.1 Preparing the Environment


Before using VAB to create stored procedures, you have to create the DB2 stored procedures
pseudo-catalog table. VAB adds an entry to the DB2CLI.PROCEDURES table for the stored procedure
during the build and register stored procedure step described in 16.2.4.2, “Building and Registering
Stored Procedures” on page 336. Refer to 4.6, “Registering Stored Procedures” on page 77 for
information about how to create the DB2CLI.PROCEDURES table.

After creating the DB2CLI.PROCEDURES table, you must grant to each user who builds stored
procedures privileges to insert, update, and delete entries in the DB2CLI.PROCEDURES table of each
target database.

To browse the DB2CLI.PROCEDURES table, select Stored procedure catalog from the Window
pull-down menu of the IBM VAB window as shown in Figure 163 on page 333.

332 Getting Started with DB2 Stored Procedures


Figure 163. Selecting the Stored Procedures Catalog Table

Figure 164 shows the resulting Stored Procedure Catalog window for the SAMPLE database.

Figure 164. Stored Procedure Catalog Window

16.2.2 The VAB Language


The VAB language is a powerful implementation of BASIC with some useful extensions.

In a VAB project, you create code modules, or .bas files , which contain the VAB language source code
for the stored procedures and UDFs. A small application may contain only a single code module, and
larger applications may contain several code modules. In the code modules, VAB instructions are
grouped into procedures. A code module may contain multiple procedures. A given code module can
be reused in multiple projects. By placing procedures in code modules, you can make your frequently
used code reusable.

VAB instructions are grouped into two kinds of procedures: subprocedures and function procedures.
Both accept parameters, but only function procedures have a return code value, enabling them to be
used in such expressions as
return_code = my_function(parm1, parm2)

Chapter 16. IBM VisualAge for Basic 333


During the build process (see 16.2.4.2, “Building and Registering Stored Procedures” on page 336),
VAB creates the stored procedures and UDFs from the .bas files, using the specifications in the
definition files. The definition files have an extension of .sp for stored procedures and .udf for UDFs.

16.2.3 Editing a Project


Application code in VAB is managed through projects. A project consists of code modules (.bas files)
and build files (.sp and .udf files). Some modules are commonly used libraries of functions and
constants. In the build files, we find the definitions required to build stored procedures and UDFs.
Figure 165 shows an example of the sample salary project shipped with VAB. The sample uses a
stored procedure to retrieve the maximum salary and the name of the employee who draws that
salary. The project has four modules:
constant.bas The global constant declarations. This file is automatically included in each new project.
salary.bas The client program
spsalary.bas The stored procedure
sqlca.bas The SQLCA and SQLDA global declarations, which are also automatically included in each
new project.

Figure 165. IBM VAB Window: Salary Project

By double-clicking on any of the modules in the project window, you open the code editor. For
example, double-click on the spsalary.bas stored procedure code to edit it. The code editor window
shown in Figure 166 on page 335 displays your code in different colors and fonts in an easy-to-read
format.

334 Getting Started with DB2 Stored Procedures


Figure 166. The VAB Code Editor Window

16.2.4 Developing the Stored Procedure


When you develop stored procedures using VAB, be aware of some differences between VAB and
other languages such as C, REXX, and COBOL.

A stored procedure written in VAB does not declare input and output parameters as SQLDA structures.
Optionally, the parameters can be followed by an array of integers to hold corresponding null
indicators and by an instance of the SQLCA structure (sqlca_type). The following is an example of
declaring the sqlsproc entry point and the parameters passed to the stored procedure:
Sub sqlsproc (sqlstmt As String, _
empname As String, _
result As Double, _
nullArray() As Integer, _
sqlca As sqlca_type)

With VAB you can pass single or multiple arrays to a stored procedure; the parameters passed can be
of any type, including a UDT.

Chapter 16. IBM VisualAge for Basic 335


16.2.4.1 Sample Stored Procedure: The sample stored procedure in Figure 166 performs the
following tasks:
1. Declares the procedure, spsalary , specifying the parameters accepted from the calling program.
The parameters are Salary and EmployeeName .
2. Declares the Employee variable as string.
3. Declares the Maxsal variable as double.
4. Selects the ma x i mu m salary from STAFF into Maxsal .
5. Selects the name for the maximum salary into Employee .
6. Assigns the value of Maxsal to Salary .
7. Assigns the value of Employee to EmployeeName .
8. Returns to the client.
The following is the content of the spsalary.bas file:
′ ****************************************************************
′ File: spsalary.bas
′ ****************************************************************
Sub spsalary (Salary As Double, EmployeeName As String)
Dim Employee as string * 50
Dim Maxsal as double

EXEC SQL
SELECT MAX(SALARY) INTO :Maxsal FROM USERID.STAFF
END EXEC
EXEC SQL
SELECT NAME INTO :Employee FROM USERID.STAFF
WHERE SALARY = :Maxsal
END EXEC

Salary = Maxsal
EmployeeName = Employee
End sub

16.2.4.2 Building and Registering Stored Procedures: Building is the process of creating
the library for the stored procedure at the database server. The build process uses as input the .bas
file and the stored procedure definition file (.sp file).

A stored procedure definition file is similar to a makefile. It contains:


• Name and entry point of the stored procedure
• Names of the VAB code modules (.bas files)
• Targets for builds (database aliases and server paths)
• Time stamp of the modules (.bas files) in an internal format
• Status of the last build for each target server
The VAB graphical user interface (GUI) is used to create and update the definition file.

VAB creates a new stored procedure definition file (also referred to as a stored procedure history file )
when you select New stored procedure from the File pull-down menu of the IBM VAB window shown in
Figure 165 on page 334 and save the definition.

To update the definition file, double-click on the spsalary.sp file shown in Figure 165 on page 334.

336 Getting Started with DB2 Stored Procedures


To create a new definition file or update an existing definition file, use the Stored Procedure Definition
window shown in Figure 167 on page 337.

Figure 167. Stored Procedure Definition Window

During the build process, you can request that the stored procedure be registered on the selected
servers by checking the Register stored procedure option on the Stored Procedure Definition window.
Registering a stored procedure is the process of updating the DB2CLI.PROCEDURES table with
information about the stored procedure. Any previously registered stored procedure using the same
schema and executable name is replaced by the new procedure.

After you have completed the Stored Procedure Definition window, click on the Build push button to
build the stored procedure at the selected servers. VAB transfers the BASIC modules specified in the
stored procedure definition and sends it to the server to be used to build the library.

16.2.5 Developing the Client Program


VAB provides the following methods to call a VAB stored procedure:
• Embedded SQL CALL statement
• CLI CALL verb
• DB2 DARI protocol using the SQLeproc function
• VAB SP.VBX for Microsoft Visual Basic clients
• VAB SQLarrayCALL API for C and C++ for passing arrays
The embedded SQL CALL (for VAB clients), SP.VBX (for Visual Basic clients), and SQLarrayCALL API
(for C and C++ clients) are recommended for passing arrays.

Chapter 16. IBM VisualAge for Basic 337


To decide which method to use, consider your client application development, run-time, and target
server environments as well as the skills and preferences of your programmers.

16.2.5.1 Local and Remote Calls: When you use VAB to develop a client program, you have
the option of executing a call to the VAB procedure as local or remote. Before you execute a local or
remote call, your client application must connect to the database server.

A local call to the VAB procedure means invoking the VAB subprocedure as a normal procedure call,
that is, the SQL CALL statement is not used. Instead, the subprocedure is executed locally, but the
SQL statements contained in the subprocedure are executed at the database server as shown in
Figure 168.

Figure 168. Local Call Using a Subprocedure

An example of a local call to the spsalary subprocedure with two parameters is:
spsalary salary, EmployeeName

A remote call to the VAB procedure means invoking the VAB subprocedure remotely as a stored
procedure, that is, the SQL CALL statement is used, as illustrated in Figure 169 on page 339.

338 Getting Started with DB2 Stored Procedures


Figure 169. Remote Call Using a Stored Procedure

An example of a remote call to the spsalary stored procedure with two parameters is:
EXEC SQL CALL userid.spsalary (:salary, :EmployeeName) END EXEC

16.2.5.2 Sample Client Program: We use the salary.bas client program from the sample salary
project as an example. This client program was developed with VAB. The embedded SQL CALL
statement is used to invoke the stored procedure.

Double-clicking on the salary.bas module in the IBM VAB salary project window (Figure 165 on
page 334) opens the code editor with the client code. The client program performs the following tasks:
1. Defines the variables.
2. Opens a window asking if the call is local or remote.
3. Connects to the database.
4. Calls the local subprocedure if the call is local.
5. Calls the stored procedure with the SQL CALL statement if the call is remote.
6. Displays the result in a message box after the subprocedure or the stored procedure has returned.
7. Disconnects from the database and ends.
Here is the salary.bas file:
′ ****************************************************************
′ File: salary.bas
′ ****************************************************************
Sub Main()
Dim prompt As String ′ Input prompt
Dim LRcall As String * 1 ′ Local or Remote
Dim sppath As String * 70 ′ Stored procedure path
Dim salary As Double ′ salary and EmployeeName are
Dim EmployeeName As String * 50 ′ returned from stored procedure

prompt = ″Type L for LOCAL subproc, R for REMOTE stored procedure:″


LRcall = InputBox$(prompt)

Chapter 16. IBM VisualAge for Basic 339


Select Case UCase$(LRcall)

Case ″L″
EXEC SQL CONNECT TO SAMPLE END EXEC ′ connect to sample database
′ Next : call local subprocedure spsalary
spsalary salary, EmployeeName
MsgBox ″The Employee ″ & RTrim$(EmployeeName) & ″ has
highest salary of $″ & salary, 0, ″Local Call″
EXEC SQL CONNECT RESET END EXEC ′ reset connection to database

Case ″R″
EXEC SQL CONNECT TO SAMPLE END EXEC ′ connect to sample database
sppath=″spsalary!spsalary″ ′ sppath = stored proc name
salary=0
EmployeeName = ″″
′ Next : call the stored procedure
EXEC SQL CALL userid.spsalary (:salary, :EmployeeName) END EXEC

MsgBox ″The Employee ″ & RTrim$(EmployeeName) & ″ has


highest salary of $″ & salary, 0, ″Remote Call″
EXEC SQL CONNECT RESET END EXEC
End Select

End
End Sub

16.3 Debugging and Testing with VAB

VAB offers you an advanced debugging facility that enables you to set breakpoints, view and edit the
values of variables, and debug stored procedures running on the server platform.

You can enter debug mode when the execution of your project is suspended by a run-time error or by
a breakpoint you have set.

If execution has stopped because of a breakpoint, you can step through your code in the Code Editor
window and examine the values of variables and expressions through the Inspector window. If
execution has stopped because of a run-time error, you cannot continue to step through your code, but
you can use the Inspector window to examine your data. In debug mode, you cannot edit your code in
the Code Editor Window.

16.3.1 Setting Breakpoints


To set breakpoints in a stored procedure, first position the cursor on the line in the Code Editor
Window where you want the breakpoint. Then select Add breakpoints from the Debug pull-down menu.
You must repeat this procedure for each breakpoint you want to set. After a breakpoint is set, the
Breakpoints window displays the breakpoints, two in our case, as shown in Figure 170 on page 341.

340 Getting Started with DB2 Stored Procedures


Figure 170. Setting Breakpoints

When you run your application, VAB stops executing the code at the breakpoint, enabling you to step
through your code to inspect it and the values of your variables. Your source code is displayed, and a
little hand points to the line of code where the debugger is actually waiting. Once VAB encounters a
breakpoint, you can:
• Continue to the next breakpoint.
• Step to the next statement.
• Step over to the next subprocedure.

16.3.2 The Inspector Window


When you are in debug mode, you can view and edit the values of variables and expressions in your
program through the Inspector window (Figure 171 on page 342). It provides three ways to examine
the behavior of your code:
• A call stack for tracing subprocedure calls
• A watch area for watching the values of expressions or variables
• An immediate window for evaluating expressions

Chapter 16. IBM VisualAge for Basic 341


16.3.2.1 Call Stack: You can see the procedure calls on the call stack. When VAB executes the
VAB code in your procedures, each procedure is added to the call stack. A procedure is removed
from the stack after it has completed execution. If a procedure call in your program contains calls to
other procedures, the subprocedure is said to be nested. In the call stack you see the sequence of
calls and the nested subprocedures.

16.3.2.2 Watch: A watchpoint is a variable or expression that you want the system to monitor. To
add a watchpoint to the Watch area, click on the variable in your Code Editor window. Then click on
Add Watch on the Debug pull-down menu. Figure 171 shows that we added the Employee variable to
the watch area.

Figure 171. The Inspector Window

When the application enters a break mode, the system displays the values of the watchpoints in the
Value column of the Inspector window. At every debugging step, the values of the watchpoints are
refreshed. You can also use the Quickwatch window to examine the values of variables that are not
listed in the watch area. To do so, place your cursor on a variable in the Code Editor Window and
select Immediate Watch from the Debug pull-down menu.

16.3.2.3 Immediate Window: The Immediate window provides direct access to the VAB
interpreter. Thus you can enter commands and execute statements directly while the execution of
your code is suspended. You also have access to all of the variables in your current program. For
example, Figure 172 on page 343 shows how we used the Immediate window to assign values to the
Salary and EmployeeName variables by entering the following BASIC statements:

342 Getting Started with DB2 Stored Procedures


Salary = 50000
EmployeeName = ″Marcella″

Figure 172. Using the Immediate Window

16.3.3 The Remote Debugger


VAB′s remote debugger enables you to debug stored procedures running on the server in the same
way you debug local code.

To enable the remote debugger, check the Enable remote debug option on the Stored Procedure
Definition window shown in Figure 167 on page 337 when you are building the stored procedure.
Once the stored procedure is built with this option, the call to the stored procedure displays a Project
window and a Code Editor window to show the stored procedure code at the server. You can then
debug your server code as described in the previous sections. When your server code is bug free,
build it again without checking the Enable remote debug option, so the remote debugger is not invoked
the next time the server procedure is called.

16.4 Testing Code Using QuickTest Dialogs

To test your code with a GUI client application, use the VAB QuickTest dialogs. Figure 173 on
page 344 shows an example of a QuickTest dialog.

Chapter 16. IBM VisualAge for Basic 343


Figure 173. The qtText2 QuickTest Dialog

You can initialize QuickTest dialogs with your own parameters and modify them through your VAB
code. For each dialog you can specify:
• The number of buttons on the dialog (up to four)
• Which button is the default
• Code executed when a user clicks on a specific button
• Which bitmap, if any, to display
• A background bitmap
• The title, size, and position of the form
• Labels for each text box, grid, and button
• Whether the form is modal or nonmodal
Four QuickTest dialogs are available; the dialog shown in Figure 174 enables you to specify a fixed
number (from one to the limit your screen can hold) of input and output fields.

Figure 174. The qtArray QuickTest Dialog

To facilitate your use of the QuickTest dialogs, VAB provides the QuickTest SmartGuide as shown in
Figure 175 on page 345. This tool generates a test application that uses QuickTest dialogs to guide
you through the steps required to generate this application.

344 Getting Started with DB2 Stored Procedures


Figure 175. The QuickTest SmartGuide

You can test your stored procedures without QuickTest dialogs by using the remote debugger,
temporarily inserting statements into the code to print values to a file, or using input boxes to gather
input and message boxes to display results. You can also test the stored procedures from your own
client application. However, the QuickTest dialogs offer the simplest method of testing your code with
a GUI.

16.5 VAB on the World Wide Web

For the latest news about VAB, go to the VAB home page on the Internet:
http://www.software.ibm.com/data/db2/databasic

Chapter 16. IBM VisualAge for Basic 345


346 Getting Started with DB2 Stored Procedures
Appendix A. Sample Programs

This redbook ships with a diskette containing sample programs developed during this project. The
sample programs illustrate the theory discussed in this redbook and are useful for getting started with
stored procedures in your own environment and gaining some hands-on experience.

The diskette was created under OS/2 using


ez2zip sg244693.exe s:\sg244693\samples97\*.* /toexe /p
It contains a self-extracting executable file which can be run on OS/2 and DOS. When unzipped, the
samples take up 4 MB. We tested unzipping it on OS/2, Win95 and Windows NT 4.

To unzip the samples:


1. Create a working directory on your hard drive, for example d:\stproc.
2. Copy the sg244693.exe file which is on the diskette into your working directory.
3. Unzip with the command:
sg244693.exe d:\stproc /d
It will create relative subdirectories and unzip the file contents into the appropriate subdirectories
under d:\stproc

The diskette directory structure is as follows:


• AIX
In this directory you find AIX programs. This directory is further subdivided into the following
subdirectories:
− C
− CLI
− REXX
• MVS
In this directory, you find samples written for OS/390 (MVS).
There are five files with the *.unl suffix:
file name on diskette original data set name on OS/390
---------------------------------------------------------
h.unl SG244693.SAMPLES.H
jcl.unl SG244693.SAMPLES.JCL
link.unl SG244693.SAMPLES.LINK
source.unl SG244693.SAMPLES.SOURCE
sql.unl SG244693.SAMPLES.SQL
These five sequential files were created from partitioned data sets using the TSO TRANSMIT
OUTDA() command. To recreate the partitioned data sets on OS/390 from the diskette, you need
to:
1. Transfer the files from PC to MVS as binary, with the following attributes for the output data
set:
DSORG=PS
RECFM=FB
LRECL=80
BLKSIZE=3200
2. Use the TSO RECEIVE INDA( ) command to create the partitioned data sets (PDSs) from the
sequential data sets you just transferred. You can use the TSO HELP RECEIVE command to
find out about the optional parameters for the RECEIVE command.

 Copyright IBM Corp. 1996 1998 347


There is a file called sampbld.jcl in the same subdirectory which will transfer the fives files by FTP,
then RECEIVE them all. If you are using FTP, this may be a more convenient method.
• NT
In this directory, you find sample programs developed using Windows NT Version 4. This directory
is further subdivided into the following subdirectories:
− C
− COBOL
• OS/2
In this directory you find OS/2 programs. This directory is further subdivided into the following
subdirectories:
− C
− CLI
− COBOL
− VAB
− REXX
• Windows
In this directory you find Windows 3.1 programs. This directory is further subdivided into the
following subdirectories:
− C (for the second edition of this redbook, we did not verify the Windows 3.11 samples)
− VBasic (for Version 5 of Visual Basic)
− VBasic3 (for Version 3 of Visual Basic)
• Win95
In this directory you find Windows 95 programs. This directory contains a subdirectory for the
PowerBuilder samples, PB.

A.1 Naming Convention

In the samples that we have provided with this redbook, we have created a naming convention for
client programs, and another naming convention for the stored procedures. Both are defined below.

For the client program, the convention is:


xxxLEPLE
Figure 176 on page 349 shows the values for the client program naming convention.

348 Getting Started with DB2 Stored Procedures


Figure 176. Client Program Naming Convention

For the stored procedure, the convention is:


xxxLEP
Figure 177 shows the values for the stored procedure naming convention.

Figure 177. Stored Procedure Naming Convention

where

xxx uniquely identifies the stored procedure and client pair.

L is the Language:

Appendix A. Sample P r o g r a m s 349


B - COBOL
C - C
D - Databasic
J - Java
O - ODBC/CLI
P - PL/I
R - PowerBuilder
R - REXX
V - VisualBasic
X - C++

When interpreting the naming convention with a client program, the first L represents the language of
the stored procedure that the client program calls and the second L identifies the language in which
the client program was written. For the stored procedure, there is only one L, and it represents the
language in which the stored procedure was coded.

E is the environment:
M - MVS and/or OS/390
N - Windows NT
W - WLM-established stored procedure address space
X - AIX
2 - OS/2
9 - Win95

The client program also has two environment identifiers. The first represents the environment of the
stored procedure that this client calls. The second E represents the environment in which this client
was coded. Samples written for the stored procedures have one E associated with them, which
represents the environment that the stored procedures should execute.

P is the purpose of the program:


C - Client
S - Server (= stored procedure)

For example, PR0C2CCN is a client uniquely identified as PR0 calling a stored procedure written in C
on OS/2 and called PR0C2S, while the client is written in C on a Windows NT environment.

350 Getting Started with DB2 Stored Procedures


A.2 AIX Samples

The following instructions are based on:


• Building Applications for UNIX Environments
• The README files that come with DB2 Universal Database V5 in each of the subdirectories in
sqllib/samples

A.2.1 C Samples on AIX


To build and execute AIX C clients and stored procedures, you need to:
1. Execute sqllib/db2profile to set up your environment.
2. Run db2start.
3. FTP or copy all the files from \aix\c directory on the diskette provided with this book to a working
directory local to your machine.
4. Copy the files util.h and util.c from the sqllib/samples/c directory of your DB2 instance to the
working directory. These provide common utilities such as error checking and printing SQLDA.

To use the debugger, xldb, specify compiler option -g. If you are using the makefile from DB2
Universal Database V5 samples, you can update:
# the required compiler flags
CFLAGS= -I$(DB2INSTANCEPATH)/sqllib/include -g

A.2.1.1 C Sample Clients on AIX: To use the sample programs from this redbook, first you
need to make sure bldxlc is available, or copy it to the working directory.

To build the client program for database sample2, use the following build script:
bldxlc pr0c2ccx sample2 userid password

A.2.1.2 C Sample Stored Procedures on AIX: Copy the file bldxlcsrv from the
sqllib/samples/c directory of your DB2 instance

A.2.2 CLI Samples on AIX


The CLI samples from this redbook work only with DB2 Universal Database V5 since it uses ODBC 3.0
APIs.

A.2.2.1 CLI Sample Clients on AIX: These are the steps:


1. Create a working directory on AIX.
2. Go to working directory.
3. Copy sqllib/samples/cli/samputil.c to working directory.
4. Copy sqllib/samples/cli/samputil.h to working directory.
5. FTP the redbook samples from diskette \AIX\CLI\*.
6. Make bldcli executable using
chmod +x bldcli

To build the client (for example sr1.c), run:


bldcli sr1
bldcli is based on clibld script file and the makefile that comes with DB2 Universal Database V5:

Appendix A. Sample P r o g r a m s 351


#! /bin/ksh
# bldcli script file - AIX
# Compile the program
xlc -I/usr/lpp/db2_05_00/include -c samputil.c
xlc -I/usr/lpp/db2_05_00/include -qsource -c $1.c
# Link the program
xlc -o $1 $1.o samputil.o -L/usr/lpp/db2_05_00/lib -ldb2

To execute the client, make sure the server is started and that you can connect to the server.

A.2.2.2 CLI Sample Stored Procedures on AIX: The AIX CLI sample clients call existing
stored procedure from this redbook. We do not provide any additional sample stored procedures on
AIX. Figure 126 on page 237 shows how client sr1 interacts with other stored procedures.

To build mrspsrv.c, follow these steps:


1. Create a working directory on AIX.
2. Go to working directory.
3. Copy sqllib/samples/cli/mrspsrv.*.
4. Copy sqllib/samples/cli/makefile.
5. Run the following command:
make mrspsrv

For more information, consult the README file in sqllib/samples/cli that comes with DB2 Universal
Database V5.

A.2.3 REXX Samples on AIX


You do not precompile or bind REXX programs. To run DB2 REXX/SQL programs on AIX, you must set
the LIBPATH environment variable to include sqllib/lib under the DB2 install directory.

If LIBPATH has not been set yet, enter:


export LIBPATH=/lib:/usr/lib:/usr/lpp/db2_05_00/sqllib/lib

If LIBPATH has been set already, enter:


export LIBPATH=$LIBPATH:/usr/lpp/db2_05_00/sqllib/lib

On AIX, your application file can have any file extension. You can run your application using either of
the following two methods:
1. At the shell command prompt, enter rexx name where name is the name of your REXX program.
2. If the first line of your REXX program contains a “ m a g i c number,” (#!), and identifies the directory
where the REXX/6000 interpreter resides, you can run your REXX program by entering its name at
the shell command prompt. For example, if the REXX/6000 interpreter file is in the /usr/bin
directory, include the following as the very first line of your REXX program:
#! /usr/bin/rexx
Then, make the program executable by entering the following command at the shell command
prompt:
chmod +x name
Run your REXX program by entering its file name at the shell command prompt.

REXX sample programs are in the directory sqllib/samples/rexx. To run the sample REXX program
updat.cmd, do one of the following:

352 Getting Started with DB2 Stored Procedures


• Run the program directly. Type:
updat.cmd
• Specify the REXX interpreter and the program. Type:
rexx updat.cmd

For further information on REXX and DB2, refer to the Embedded SQL Programming Guide , Chapter 13,
“Programming in REXX.”

Table 31. Description of the Programs Used in the AIX Environment.


Legend: N=Simple with NULLS, S=Simple, D=SQLDA, H=Host Variables, R(n)=With n Result Sets
Sample Name Features Description Possible
partners
imsbmcox.c SHR(1) Performs similar function to the MVS client IMSBMCBM. IMSBMCBM
Modeled on mrspcli.c, it calls IMSBMS which uses APPC
to invoke the standard IMS IVP transaction PART with Part
Number AN960C10. See 13.5, “APPC to Access
Transactions from a Stored Procedure” on page 292.
imubmcox.c SHR(1) Performs similar function to the MVS client IMUBMCBM. IMUBMCBM
Modeled on mrspcli.c, it calls IMUBMS which invokes the
standard IMS IVP transaction PART using APPC, passing it
two parameters, the IMS IVP transaction and its data.
The data is returned in a result set that was stored in a
DB2 Global Temporary Table. The IMUBMS stored
procedure initiates an IMS transaction through APPC. See
13.5, “APPC to Access Transactions from a Stored
Procedure” on page 292.
pr0cxs DH This is inpsrv.sqc, identical to the OS/2 version pr0c2s. It pr0cxcc2.sqc
loops through the parameters passed by the caller to
insert rows into a table.
pr0c2ccx DH Renamed from sample inpcli shipped with DB2 Common pr0c2s
Server V2 and DB2 Universal Database V5. This client
calls pr0c2s to insert three presidents′ names twice. The
first time it passes the names using host variables; the
second time, it uses the SQLDA.
pr0c2crx.cmd DH Renamed from sample inpcli shipped with DB2 Common pr0c2s
Server V2 and DB2 Universal Database V5. This client
calls pr0c2s to insert three presidents′ names twice. The
first time it passes the names using host variables, the
second it uses the SQLDA.
pr0r2crx.cmd DH Variation on inpcli, going to OS/2. pr0r2s.cmd
sm0pmcrx.cmd HN Passes DB2 commands to stored procedure on OS/390 SM0PMS
(MVS) and retrieves results.
sr1 NHR(1) Modified version of mrspcli.c shipped with DB2 Common SR1CMS
Server V2 and DB2 Universal Database V5. It can go to SR1OMS
any of the mrspsrv.c equivalents on any platform. SR1PMS
Figure 126 on page 237 shows how client sr1 interacts SR1XMS
with other stored procedures. mrspcli.c

A.3 OS/2 Samples

The OS/2 samples that come with this redbook mostly derive from the DB2 Common Server samples.
Please consult Building Applications for Windows and OS/2 Environments for further information.

Appendix A. Sample P r o g r a m s 353


A.3.1 C Samples on OS/2
This redbook provides samples for C programs using embedded SQL. These programs were tested
using CSet++ and DB2 Common Server V2. They have been retested using IBM VisualAge C++ for
OS/2 Version 3.0 and DB2 Universal Database V5.

The *.mak files that come with this redbook were written for CSet++. You can use nmake against
these *.mak files. For UDB we used the bld*.cmd files that come with the product instead of the *.mak
files.

To use the sample programs from this redbook, first you need to:
1. Copy all the files from \os2\c directory on the diskette provided with this book to a working
directory local to your machine. For example,
copy a:\os2\c\*.* c:\working
2. Copy the files util.h and util.c from the samples\c directory of your DB2 instance (typically
\sqllib\samples\c) to the working directory. These provide common utilities such as error
checking and printing SQLDA.

A.3.1.1 C Sample Clients on OS/2: To have a client program call a stored procedure, please
ensure that the following items have been reviewed:
1. Copy the file bldvaemb.cmd from the %DB2PATH%\samples\c directory.
2. Catalog the database where the stored procedure resides.

To create the client, enter the following:


bldvaemb cl0c2cc2 sample userid password

A.3.1.2 C Sample Stored Procedures on OS/2: To define a sample stored procedure on an


OS/2 system, ensure that the following steps have been performed:
1. Copy the file bldvastp.cmd from the %DB2PATH%\samples\c directory.
2. Create the sample database.

Next, create the stored procedure dynamically linked library, for example:
bldvastp pr0c2s sample db2v5 db2v5

A.3.2 CLI Programs on OS/2


Caution !
Our samples were originally written using DB2 Common Server V2. It uses samputil.c which has
changed in DB2 Universal Database V5 since UDB is ODBC 3.0 (level 1) compliant. You need
samputil.c and samputil.h from our diskette in order to make these samples work. These are
modified versions of UDB′s v2sutil which is in effect samputil from Version 2.

Do not confuse our samputil.c and samputil.h with the UDB samputil.c and samputil.h. If you are
using the UDB version of samputil.c, you will get two unresolved externals: CHECK_DBC,
CHECK_STMT.

Our CLI samples derive from DB2 Common Server V2. We tested the samples using DB2 Universal
Database V5. To use the samples provided with this redbook, copy all the files from \os2\cli directory
on the diskette provided with this book to a working directory local to your machine. For example:

354 Getting Started with DB2 Stored Procedures


copy a:\os2\cli\*.* c:\working

These samples are designed to show how to do certain tasks. For example, error handling in mr3*
and mr4* needs to be strengthened; giving an invalid SQL statement causes looping. If you are to put
these into a production environment, more work needs to be done on making these programs robust.
Note: For further information, please consult Building Applications for Windows and OS/2
Environments .

A.3.2.1 CLI Sample Clients on OS/2: If you are starting over from scratch and are reading the
book Building Applications for Windows and OS/2 Environments , ensure that you are using the example
in the book for VisualAge C/C++ and not the sample in the samples directory. The sample file
clibld.cmd in the samples directory is not for VisualAge C/C++.

Each of the sample clients come with a *.mak file. To build the client program, update the *.mak file as
necessary to choose between ilink /NOFREE (for VisualAge C/C++) and link386 (C/Set). Use:
nmake /a /f program.mak
to create the client program.

As an alternative, we also added a new cmd file, bldvacli.cmd, to build CLI applications using
V i s u a l A g e C / C + + . The source for this is:
/* rexx */
parse arg pgmname .
address cmd
″icc -c -Ls+ samputil.c″
″icc -C+ -O- -Ti+ -Ls+″ pgmname″ . c″
″ilink /NOFREE /NOI /DEBUG /ST:128000 /PM:VIO″ ,
pgmname″ . obj samputil.obj,,,db2cli;″
exit rc

A.3.2.2 CLI Sample Stored Procedures on OS/2: Each of the sample stored procedures
comes with a *.mak file. To build the stored procedure, update the *.mak file as necessary to choose
between ilink /NOFREE (for VisualAge C/C++) and link386 (C/Set). Use nmake /a /f program.mak to
create the stored procedure.

A.3.3 COBOL Programs


In our testing, we installed IBM VisualAge for COBOL Standard, Version 2.1. For further information,
please consult the Building Applications for Windows and OS/2 Environments , S10J-8160-0.

A.3.3.1 COBOL Sample Client Program on OS/2: To have a client program call a stored
procedure, please ensure that the following items have been reviewed:
1. Copy all the files from \os2\cobol directory on the diskette provided with this book to a working
directory local to your machine.
For example,
copy a:\os2\cobol\*.* c:\working
2. Copy the files bldvaemb.cmd and checkerr.cbl from the samples\cobol directory of your DB2
instance to the working directory.
3. Catalog the database where the stored procedure resides.

To create the client imdbmcb2, enter the following:


bldibmcb imdbmcb2 sample userid password

Appendix A. Sample P r o g r a m s 355


A.3.3.2 COBOL Sample Stored Procedures on OS/2: To define a sample stored procedure
on an OS/2 system please ensure that the following steps have been performed:
1. Copy all the files from \os2\cobol directory on the diskette provided with this book to a working
directory local to your machine.
For example,
copy a:\os2\cobol\*.* c:\working
2. Copy the file bldicobs.cmd from the samples\cobol directory of your DB2 instance to the working
directory.
3. Create the sample database

Two files, *.sqp and *.def, are required for a stored procedure. To create the stored procedure
dynamically linked library, enter the following:
bldicobs pr0b2s sample db2v5 db2v5

A.3.4 REXX Programs


To execute REXX programs from this redbook, copy all the samples to your own directory and execute
them. No other preparation is necessary.

A.3.5 VAB Programs


We have one sample code SPBO1.bas but the corresponding SPBO1.sp is missing. It is included here
for reference. Refer to Chapter 16, “IBM VisualAge for Basic” on page 331.

Table 32 (Page 1 of 3). Description of the Programs Used in the OS/2 Environment.
Legend: N=Simple with NULLS, S=Simple, D=SQLDA, H=Host Variables, R(n)=With n Result Sets
Sample Name Features Description Possible
partners
dd1c2cr2 HN Used as a simple test for measuring performance. See dd1c2s
Table 28 on page 302. Each loop inserts 10 presidents
into the PRESIDENTS table. Invoke this client program
using:
dd1c2cr2 dbname uid pwd #_of_loops
dd1c2s HN Used as a simple test for measuring performance. See dd1c2cr2
Table 28 on page 302. Each invocation inserts 10 rows
into a table. DLL is removed from memory after each
invocation. It also writes a small debug file, stproc.dat.
imdbmcb2 SH This is a sample MVS batch client program that invokes IMSBMS
the IMDBMS stored procedure, passing it two parameters,
the IMS IVP transaction and its data. The data is returned
in two parameters, a counter for the number of lines
returned and a varchar field with the lines. The IMSBMS
stored procedure initiates an IMS transaction through
APPC.
pr0cxcc2 DH Renamed from sample inpcli. shipped with DB2 pr0cxs
Common Server V2 and DB2 Universal Database V5. This
client calls pr0cxs to insert three presidents′ names twice.
The first time it passes the names using host variables;
the second time, it uses the SQLDA.

356 Getting Started with DB2 Stored Procedures


Table 32 (Page 2 of 3). Description of the Programs Used in the OS/2 Environment.
Legend: N=Simple with NULLS, S=Simple, D=SQLDA, H=Host Variables, R(n)=With n Result Sets
Sample Name Features Description Possible
partners
pr0c2s DH Renamed from sample inpsrv. shipped with DB2 PR0C2CCN
Common Server V2 and DB2 Universal Database V5. This pr0c2crx.cmd
is a stored procedure that accepts calls from clients. It pr0c2ccx.sqc
creates the PRESIDENTS table in the sample database
and inserts three presidents′ names twice. The first time
it accepts the names using host variables; the second
time it uses the SQLDA.
pr1c2s DH Modified from pr0c2s (inpsrv), this stored procedure is PR0C2CCN
used in performance test (see Chapter 14, “DB2 Common
Server Performance Considerations” on page 299). It
assumes the PRESIDENTS table has already been created
and inserts rows into it. On completion, the library is kept
in memory by return with SQLZ_HOLD_PROC.
pr2c2s DH Modified from pr0c2s (inpsrv), this stored procedure is PR0C2CCN
used in performance test (see Chapter 14, “DB2 Common
Server Performance Considerations” on page 299). It
assumes the PRESIDENTS table has already been created
and inserts 10 rows into it using static SQL. On
completion, the library is removed from memory by
returning with SQLZ_DISCONNECT_PROC.
pr3c2s DH Modified from pr0c2s (inpsrv), this stored procedure is PR0C3CCN
used in performance test (see Chapter 14, “DB2 Common
Server Performance Considerations” on page 299).
Similar to pr2c2s, it assumes the PRESIDENTS table has
already been created and inserts 10 rows into it using
compound static SQL. On completion, the library is
removed from memory by returning with
SQLZ_DISCONNECT_PROC.
pr4c2s DH Identical to pr2c2s except this stored procedure is PR0C3CCN
unfenced (see Chapter 14, “DB2 Common Server
Performance Considerations” on page 299 and 4.5,
“Fenced and Unfenced Stored Procedures” on page 76).
Similar to pr2c2s, it assumes the PRESIDENTS table has
already been created and inserts 10 rows into it using
compound static SQL. On completion, the library is
removed from memory by returning with
SQLZ_DISCONNECT_PROC.
pr0b2cc2 DHN Invokes pr0b2s to update news in color. pr0b2s
tr0c2cc2 D Calls the tr0c2s stored procedure. See 9.3, “Blocking tr0c2s
Rows” on page 180
tr0c2s D A example of transferring multiple rows of data by tr0c2cc2
blocking. Ten rows of salary information from STAFF is
read and values reformatted, then passed back to the
caller via the SQLDA. See 9.3, “Blocking Rows” on
page 180
mr3c2co2 SD CLI client program processing a result set based on a mr3c2s
SELECT statement entered by the user. Refer to 9.1.1.1,
“Retrieving One Result Set” on page 139. The stored
procedure also writes a small debug file stproc.dat.

Appendix A. Sample P r o g r a m s 357


Table 32 (Page 3 of 3). Description of the Programs Used in the OS/2 Environment.
Legend: N=Simple with NULLS, S=Simple, D=SQLDA, H=Host Variables, R(n)=With n Result Sets
Sample Name Features Description Possible
partners
mr3c2s SD C program with embedded SQL. Accepts an SQL mr3c2co2
statement passed from the client program, prepares it,
opens it and returns the SQLCA. Refer to 9.1.1.1,
“Retrieving One Result Set” on page 139. This stored
procedure also writes a small debug file stproc.dat.
mr4c2co2 SD CLI client program processing three result sets based on mr4c2s
three SELECT statements. We trivialize it by putting three
identical statements in this sample. Modify it to suit your
needs. If the program seems to loop, it is probably
having trouble with SQL statements that cause errors.
Refer to 9.1.1.5, “Retrieving Multiple Result Sets” on
page 146. A quick look at the small debug file stproc.dat
written by the stored procedure may provide some clues.
mr4c2s SD C program with embedded SQL. Accepts three SQL mr4c2co2
statements passed from the client program, prepares
them, opens them, and returns the SQLCA. Refer to
9.1.1.5, “Retrieving Multiple Result Sets” on page 146.
This stored procedure also writes a small debug file
stproc.dat.
st0c2x.sqc - This sample does not use stored procedures, but provides -
elapsed time to compare with sp0r2cr2.cmd/sp2r2s.cmd ?
cc22cst0.cmd. It inserts 10 presidents in the PRESIDENTS
sample table and can loop any number of times. Build it
using
bldvaemb st0c2x dbname uid pwd
cd22cbb0.sqc Refer to 16.2.4.2, “Building and Registering Stored spbo1.bas
Procedures” on page 336. spbo1.sp is missing.
pr0r2cr2.cmd NHD Modified from inpcli. pr0r2s.cmd
pr0cxcr2.cmd NHD This is a REXX OS/2 client calling an AIX C stored pr0cxs
procedure that creates the PRESIDENTS table in the
sample database. Three presidents′ names are entered
twice. The first sends the data using host variables; the
second set of data is sent using SQLDA.
sm0pmcr2.cmd NHD This is a REXX OS/2 client calling an MVS PL/I stored SM0PMS
procedure that issues the DB2 on MVS -DISPLAY PROC(*)
command. You can modify the data.item1 variable to
issue a DB2 on MVS command of your choice. The stored
procedure is called twice. The first sends the data using
host variables; the second set of data is sent using
SQLDA.
sr2o2s.c NHR(1) This is renamed from the V2 CLI result set sample, sr2o2co2.c
mrspsrv.c.
sr2o2co2.c NHR(1) This is renamed from the V2 CLI result set sample, sr2o2s.c
mrspcli.c.

A.4 Windows Samples

Samples are provided for C, VisualAge for Basic, and COBOL.

358 Getting Started with DB2 Stored Procedures


A.4.1 C Programs
Client: To have a client program call a stored procedure, please ensure that the following items have
been reviewed:
1. Copy all the files from \windows\c directory on the diskette provided with this book to a working
directory local to your machine.
For example,
copy a:\windows\c\*.* c:\working
2. Copy the files bldvaemb.bat,util.h, and util.c. from the samples\c directory of your DB2 instance
to the working directory.
3. Catalog the database where the stored procedure resides.

To create the client, type the following:


bldvaemb pr0c2ccn sample2 db2v5 db2v5

Stored Procedure: To define a sample stored procedure on a Windows system, please ensure that the
following steps have been performed:
1. Copy all the files from \windows\c directory on the diskette provided with this book to a working
directory local to your machine.
For example,
copy a:\windows\c\*.* c:\working
2. Copy the file bldvastp.bat from the samples\c directory of your DB2 instance to the working
directory.
3. Create the sample database.

To create the stored procedure dynamically linked library, enter the following:
bldvastp XXXXXXX sample db2v5 db2v5
Note: Place a valid sample name in example above. There are two files, .sqc, and .def file, required
for a stored procedure. Both are on s:\sg244693\samples97\os2\c.These samples are untested.

For further information, please consult the Building Applications for Windows and OS/2 Environments ,
S10J-8160-0. In our testing we installed IBM VisualAge C++ for Windows Version 3.0.

A.4.2 Visual Basic Programs


For a stored procedure in Visual Basic to work, a C dynamically linked library must be copied to the
%DB2PATH%\function directory. The purpose of this is to act as a DB2 OLE Automation Stored
Procedure controller. An example of this has been provided in the DB2 samples for you to use. The
file can be found in the \windows\vbasic\ole directory on the diskette provided with this redbook, or it
is located in samples\old\stpcntr of your DB2 instance. In future releases of DB2, this controller will be
integrated into the product.

For further information, please consult Building Applications for Windows and OS/2 Environments. The
readme.txt file located in the DB2 instance ′sqllib\samples\ole′ is another source of information for
building applications and stored procedures with Visual Basic.

In our testing we installed Microsoft Visual Basic Version 5.0. We used the DB2 OLE Automation
Stored Procedure provided with the DB2 Software Developers Kit.

Appendix A. Sample P r o g r a m s 359


Note
The three samples that came with a previous version of this redbook cannot be upgraded from
MicroSoft Visual Basic V3.0 to V5.0. We could not verify that they still work:
• STORPROC
• VBW6STS0
• VCWMTST

They reside in \windows\vbasic3\ and are included for reference only.

A.4.2.1 Visual Basic Sample Clients on Windows: When creating a client application using
Visual Basic, the following will assist you in building the modules required:
1. Copy all the files from \windows\vbasic directory on the diskette provided with this book to a
working directory local to your machine.
For example,
copy a:\windows\vbasic\*.* c:\working
2. Copy the file ′ODBC32.BAS′ from the samples\ole\msvb directory of your DB2 instance to the
working directory.
3. Catalog the database where the stored procedure resides.
4. Make the Visual Basic program. The result is an executable of the same filename (s02vncvn.exe).
For example,
vb5 /make s02vncvn.vbp

A.4.2.2 PowerBuilder Sample Clients: Two PowerBuilder Version 5 sample clients are
included for reference only:
• irww.pbl demonstrates how a client calls a stored procedure using parameters.
• query3.pbl demonstrates using single and multiple result sets.

Both are from working applications. The server portion (the stored procedures) is not included. Refer
to 10.5, “PowerBuilder” on page 205.

A.4.2.3 Visual Basic Sample Stored Procedures on Windows: When creating a stored
procedure, using the Visual Basic language will assist you in building the modules required:
1. Copy all the files from \windows\vbasic directory on the diskette provided with this book to a
working directory local to your machine. For example,
copy a:\windows\vbasic\*.* c:\working
2. Copy the file ′ODBC32.BAS′ from the samples\ole\msvb directory of your DB2 instance to the
working directory
3. If you have Microsoft C + + compiler 4.2 or higher, then you can build the DB2 OLE Automation
Stored Procedure controller. If not, the .dll been supplied with the samples in the Software
Developers Kit for DB2. Copy the resulting file db2oastp.dll to the function directory in your db2
instance. For example,
copy %db2path%\samples\ole\stpcntr\db2oastp.dll %db2path%\function
4. Create the sample database.
5. Connect to sample database and create the STAFF2 table using DDL from
\sqllib\samples\ole\msvb\staff2.ddl:

360 Getting Started with DB2 Stored Procedures


db2 -t -v -f staff2.ddl
6. Compile the Visual Basic program to create the dynamically linked library. For example,
vb5 /l s02vns.vbp
7. Our sample creates salsrv.dll. Register the dynamically linked library with the OLE server. For
example,
regsvr32 salsrv.dll
Note: To unregister the stored procedure, use the following command:
regsvr32 /u salsrv.dll

A.4.3 COBOL Programs


Client: To have a client program call a stored procedure please ensure that the following items have
been reviewed:
1. Copy all the files from \nt\cobol directory on the diskette provided with this book to a working
directory local to your machine.
For example,
copy a:\nt\cobol\*.* c:\working
2. Copy the files bldvacob.cmd and checkerr.cbl from the samples\cobol directory of your DB2 instance
to the working directory.
3. Catalog the database where the stored procedure resides.

To create the client type the following:


bldvacob XXXXXXXX sample db2v5 db2v5
Note: Place a valid sample name in example above.

Stored Procedure: To define a sample stored procedure on a Windows system, ensure that the
following steps have been performed:
1. Copy all the files from \windows\cobol directory on the diskette provided with this book to a
working directory local to your machine.
For example,
copy a:\nt\cobol\*.* c:\working
2. Copy the file bldvacbs.cmd from the samples\cobol directory of your DB2 instance to the working
directory.
3. Create the sample database.

To create an example of the stored procedure dynamically linked library, enter the following:
bldicobs XXXXXXXX sample db2v5 db2v5
Note: Place a valid sample name in example above. A sample untested file is located on
s:\sg244693\samples97\windows\cobol.

For further information, please consult the Building Applications for Windows and OS/2 Environments ,
S10J-8160-0. In our testing we installed IBM VisualAge for COBOL Standard, version 2.1

Appendix A. Sample P r o g r a m s 361


Table 33. Description of the Programs Used in the Windows Environment.
Legend: N=Simple with NULLS, S=Simple, D=SQLDA, H=Host Variables, R(n)=With n Result Sets
Sample Name Features Description Possible
partners
IMDBMCBN SH This is a sample MVS batch client program that invokes IMDBMS
the IMDBMS stored procedure passing it two parameters,
the IMS IVP transaction and its data. The data is returned
in two parameters, a counter for the number of lines
returned and a varchar field with the lines. The IMDBMS
stored procedure initiates an IMS transaction through
APPC.
PR0C2CCN DH This is a client call to a stored procedure that creates the pr0c2s
PRESIDENTS table in the sample database. Three
presidents′ names are entered twice. The first sends the
data using host variables; the second set of data is sent
using SQLDA.
S02VNCVN D This client calls a stored procedure and determines the S02VNS
median salary of all the employees listed in the staff table
of the sample database. Renamed from the UDB sample
salcltvb.
S02VNS D This stored procedure accepts calls from a client that is S02VNCVN
written to determine the median value of the employees′
salaries found in the staff2 table of the sample database.
The sample database is created by typing db2sampl from
a command line on OS/2, NT and AIX environments. The
staff2 DDL is found in \sqllib\samples\ole\msvb\.
Renamed from the UDB sample salsrv.
For this stored procedure to work, the DB2 OLE
automation stored procedure must be copied to the
%DB2PATH%\FUNCTION directory (db2oastp.dll).
SM0PWCCN DH This client calls the stored procedure SM0PWS and SM0PWS
requests that a display thread command be issued on the
MVS system. The resulting information from the
command is passed back to the client.
cl2o2s.c NH Modified from inpsrv2.c except for: cl2o2cr2.cmd
• There is no CREATE for the PRESIDENTS table.
• Accepting 10 (instead of 3) parameters from caller to
insert into table.
• The bind and prepare functions are outside the loop.
This is used for performance testing between embedded
SQL and CLI. The client decides on the number of
invocations for this stored procedure. Refer to 14.5,
“Embedded SQL and CLI” on page 302.
cl2o2cr2.cmd NH Modified from inpsrv.cmd except for: cl2o2s
• Passing 10 presidents′ names instead of three to the
stored procedure cl2o2s.c
This is used for performance testing between embedded
SQL and CLI. The client decides on the number of
invocations for stored procedure cl2o2s.c. The elapsed
time is reported at the end of this client program. Refer
to 14.5, “Embedded SQL and CLI” on page 302.

362 Getting Started with DB2 Stored Procedures


A.5 MVS Samples
To use the samples provided with this redbook, you must perform the following steps:
1. Execute the self-extracting file (comes with the sample diskette) which contains the samples:
sg244693.exe d:\stproc /d
2. Transfer (upload) in binary the following five files:
h.unl
jcl.unl
link.unl
source.unl
sql.unl
from the MVS subdirectory on your PC to your OS/390 (MVS) environment, with the following
attributes for the output data set:
DSORG=PS
RECFM=FB
LRECL=80
BLKSIZE 3200
These files were created using the TSO TRANSMIT command.
Shortcut
You can upload the file sampbld.jcl (as ASCII) in the MVS subdirectory to the host. This job will
FTP and receive in one go. Saves you the next step. See Figure 178 on page 365 for the JCL.

3. Use the TSO RECEIVE INDA( ) command to create the PDSs. You can do it interactively or using
JCL. Here is sample JCL:
//SAMPBLD2 JOB (999,POK),′ FTP′ , NOTIFY=&SYSUID.,
// CLASS=A,MSGCLASS=T,REGION=5000K,
// MSGLEVEL=(1,1)
//*-------------------------------------------------------------------
//*$ Sample JCL RECEIVE the SG24-4693 stored procedures samples
//*
//* Make a backup copy of the samples files on the PC, then tailor
//* this JCL and submit it.
//*
//* 1/ Transfer all the unzip files as binary, sequential (dsorg=ps)
//* recfm(fb) lrecl(80) blksize(3200) using FTP or PComm (for
//* example) to the Host from your PC or FTP. In this example, they
//* are uploaded to the host as ′ DB2RES3.*.UNLBIN′ files
//*
//* PComm will use
//* IND$FILE PUT JCL.UNLBIN RECFM(F) LRECL(80) BLKSIZE(3200)
//*
//* 2/ The PDSs that will be rebuilt are all prefixed with
//* userid.SAMPLES.OUT.*
//*-------------------------------------------------------------------
//REBUILD EXEC PGM=IKJEFT01,
//* COND=(00,NE).
// DYNAMNBR=25
//SYSTSPRT DD SYSOUT=*,DCB=(RECFM=VBA,LRECL=255,BLKSIZE=259)
//SYSTSIN DD *

RECEIVE INDA(′ DB2RES3.SQL.UNLBIN′ )


DSNAME(SAMPLES.OUT.SQL)

Appendix A. Sample P r o g r a m s 363


RECEIVE INDA(′ DB2RES3.JCL.UNLBIN′ )
DSNAME(SAMPLES.OUT.JCL

RECEIVE INDA(′ DB2RES3.LINK.UNLBIN′ )


DSNAME(SAMPLES.OUT.LINK

RECEIVE INDA(′ DB2RES3.SOURCE.UNLBIN′ )


DSNAME(SAMPLES.OUT.SOURCE

/*
4. Recreate other necessary data sets. We used the following data sets in our test environment,
which you need to replicate:
our name Dsorg Recfm Lrecl Blksz
-------------------------------------------------------------
SG244693.SAMPLES.DBRMLIB PO-E FB 80 32720
SG244693.SAMPLES.H PO FB 80 27920 S
SG244693.SAMPLES.JCL PO FB 80 27920 S
SG244693.SAMPLES.LINK PO FB 80 27920 S
SG244693.SAMPLES.LOAD.SPAS PO U 0 6144
SG244693.SAMPLES.LOAD.WLM PO U 0 6144
SG244693.SAMPLES.OBJ PO-E FB 80 32720
SG244693.SAMPLES.SOURCE PO FB 80 27920 S
SG244693.SAMPLES.SQL PO FB 80 27920 S
S denotes PDSs that are delivered with this redbook.
5. Update JCL for stored procedure address spaces
For our project we had three stored procedure address spaces:
DBC1SPAS - DB2-established stored procedure address space
DBC1WLMM - WLM-established stored procedure address space
DBC1WLM2 - WLM-established stored procedure address space
The WLM-established stored procedure address spaces have the same JCL: they were set up for
convenience to isolate testers/programs. You may or may not want to follow how we set it up.
6. Tailor sample JCL.
Update SG244693.SAMPLES.JCL(@DEFAULT) with your installation defaults. A.6, “Using Sample
JCL Procedures” on page 368 describes this in greater detail.
Warning
If you recreate the JCL library with a name other than SG244693.SAMPLES.JCL, you will have to
update the JCLLIB statement for each run JCL
// JCLLIB ORDER=SG244693.SAMPLES.JCL
to point to your new JCL library.

7. Update SG244693.SAMPLES.SOURCE(@DSNTIAD) with your plan name for DSNTIAD


8. Create DB2 objects required by sample programs. The SG244693.SAMPLES.SQL library you
unloaded and rebuilt contains some members to create the necessary DB2 objects such as tables.
And you may need to obtain the appropriate privileges in order to perform these tasks. For
example, the collection IDs we use are mainly SAMPLESP and SAMPLECL. And you may need to
create your own database, tablespace, and so on, for these DB2 objects. You will need to run the
following members:

364 Getting Started with DB2 Stored Procedures


CTEST
IMSTEMP
STAFF
TESTE
TRANLOG
We assume you already have DB2 for OS/390 V5 installed.
9. Build programs using the JCL members provided. SG244693.SAMPLES.JCL(*BL) builds the
corresponding programs. The JCL member name and the source member name have an obvious
similarity.
10. Update SYSIBM.SYSPROCEDURES to register the stored procedures. You will find a member in
SG244693.SAMPLES.SQL with the same member name as the sample program. Run the SQL
statements (for example using SPUFI).
We actually used the stored procedure option (Z.PM) in DB2 Administration Tool to update
SYSIBM.SYSPROCEDURES interactively. However, we also provide the SQL statements for your
convenience.
11. Execute sample programs.
Each program has a corresponding member in SG244693.SAMPLES.JCL with an *EX suffix. This is
the member name which contains the JCL to execute the sample program. The sample JCL is
shown in Figure 178.

//SAMPBLD JOB (999,POK),′ FTP′ , NOTIFY=&SYSUID.,


// CLASS=A,MSGCLASS=T,REGION=5000K,
//* RESTART=REBUILD,
// MSGLEVEL=(1,1)
//*-------------------------------------------------------------------
//*$ Sample JCL to FTP GET the SG24-4693 stored procedures samples
//* and RECEIVE them.
//*
//* Make a backup copy of the samples files on the PC, then tailor
//* this JCL and submit it
//*
//* 1/ All temporary data sets used for FTP are prefixed with
//* DB2RES3.SAMPLES.OUT.*
//* 2/ The PDSEs that will be rebuilt are all prefixed with
//* userid.OUT.*
//* 3/ For FTP, tailor: yourFtpSite
//* yourUserid
//* yourPwd
//* yourDir
//* 4/ On successful completion, you can execute the DELETE step
Figure 178 (Part 1 of 4). Sample JCL sampbld.jcl to Rebuild Sample Data Sets

Appendix A. Sample P r o g r a m s 365


//* at the bottom of the job
//*-------------------------------------------------------------------
//*
//*-------------------------------------------------------------------
//* PREALLOCATE RECFM=FB LRECL=80 BLKSIZE=3200 DSORG=PS DATA SETS
//*-------------------------------------------------------------------
//ALLOC EXEC PGM=IEFBR14
//DD01 DD DSN=DB2RES3.SAMPLES.OUT.H,
// LRECL=80,RECFM=FB,BLKSIZE=3200,DSORG=PS,
// SPACE=(TRK,(90,15)),DISP=(NEW,CATLG)
//DD02 DD DSN=DB2RES3.SAMPLES.OUT.JCL,
// LRECL=80,RECFM=FB,BLKSIZE=3200,DSORG=PS,
// SPACE=(TRK,(90,15)),DISP=(NEW,CATLG)
//DD03 DD DSN=DB2RES3.SAMPLES.OUT.LINK,
// LRECL=80,RECFM=FB,BLKSIZE=3200,DSORG=PS,
// SPACE=(TRK,(90,15)),DISP=(NEW,CATLG)
//DD04 DD DSN=DB2RES3.SAMPLES.OUT.SOURCE,
// LRECL=80,RECFM=FB,BLKSIZE=3200,DSORG=PS,
// SPACE=(TRK,(90,15)),DISP=(NEW,CATLG)
//DD05 DD DSN=DB2RES3.SAMPLES.OUT.SQL,
// LRECL=80,RECFM=FB,BLKSIZE=3200,DSORG=PS,
// SPACE=(TRK,(90,15)),DISP=(NEW,CATLG)
//*-------------------------------------------------------------------
//* GET FILES FROM FTP SITE
//*-------------------------------------------------------------------
//FTP EXEC PGM=FTP,PARM=′ ( EXIT′
//SYSTCPD DD DSN=SYS1.TCPPARMS(TCPDATA),DISP=SHR
//SYSPRINT DD SYSOUT=*
//OUTPUT DD SYSOUT=*
//INPUT DD *
yourFtpSite
yourUserid
yourPwd
cd yourDir
pwd
binary
get h.unl ′ db2res3.samples.out.h′ (REPLACE
get JCL.unl ′ db2res3.samples.out.JCL′ (REPLACE
get LINK.unl ′ db2res3.samples.out.LINK′ (REPLACE
get SOURCE.unl ′ db2res3.samples.out.SOURCE′ ( REPLACE
Figure 178 (Part 2 of 4). Sample JCL sampbld.jcl to Rebuild Sample Data Sets

366 Getting Started with DB2 Stored Procedures


get SQL.unl ′ db2res3.samples.out.SQL′ (REPLACE
quit
/*
//*-------------------------------------------------------------------
//* USE RECEIVE INDA() COMMAND TO RECREATE PDSE′ S WITH NEW NAMES
//*-------------------------------------------------------------------
//REBUILD EXEC PGM=IKJEFT01,
// DYNAMNBR=25,
// COND=(00,NE)
//SYSTSPRT DD SYSOUT=*,DCB=(RECFM=VBA,LRECL=255,BLKSIZE=259)
//SYSTSIN DD *
RECEIVE INDA(′ DB2RES3.SAMPLES.OUT.H′ )
DSNAME(OUT.H

RECEIVE INDA(′ DB2RES3.SAMPLES.OUT.JCL′ )


DSNAME(OUT.JCL

RECEIVE INDA(′ DB2RES3.SAMPLES.OUT.LINK′ )


DSNAME(OUT.LINK

RECEIVE INDA(′ DB2RES3.SAMPLES.OUT.SOURCE′ )


DSNAME(OUT.SOURCE

RECEIVE INDA(′ DB2RES3.SAMPLES.OUT.SQL′ )


DSNAME(OUT.SQL

/*
//

//*-------------------------------------------------------------------
//*$ REMOVE TEMPORARY FILES FROM PREVIOUS FTP/RECEIVE
//*-------------------------------------------------------------------
//DELETE EXEC PGM=IDCAMS,COND=(00,NE)
//AMSDUMP DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//LISTING DD SYSOUT=*
//SYSIN DD *
DELETE DB2RES3.SAMPLES.OUT.H
DELETE DB2RES3.SAMPLES.OUT.JCL
DELETE DB2RES3.SAMPLES.OUT.LINK
Figure 178 (Part 3 of 4). Sample JCL sampbld.jcl to Rebuild Sample Data Sets

Appendix A. Sample P r o g r a m s 367


DELETE DB2RES3.SAMPLES.OUT.SOURCE
DELETE DB2RES3.SAMPLES.OUT.SQL
Figure 178 (Part 4 of 4). Sample JCL sampbld.jcl to Rebuild Sample Data Sets

A.6 Using Sample JCL Procedures

We used sample JCL procedures from each of the products, such as DB2, C/C++, PL/I and COBOL.
The following JCL procedures are supplied as a starting point: (Their names are different from those
of the IBM-supplied sample JCL procedure to avoid clashes.)
1. We use JCLLIB to identify which JCL procedure libraries to search.
2. We use SET statements to set symbolic parameters used in sample JCL procedures.
3. Where symbolic parameters are related to the setup of the environment (such as data set
qualifiers) as opposed to the conditions (such as compile options), these parameters will be put
into a centralized defaults data set member. This is to simplify implementation.

To use the JCL samples, follow the instructions presented here.

368 Getting Started with DB2 Stored Procedures


 
//********************************************************************
//* Set symbolic parameters for SG24-4693 samples
//********************************************************************
//*
//*-------------------------------------------------------------------
//* DB2 related symbolics 1
//*-------------------------------------------------------------------
// SET DB2EXIT=DSN510.SDSNEXIT * DB2 exits
// SET DB2LOAD=DSN510.SDSNLOAD * DB2
// SET DB2RUN=DSN510.RUNLIB.LOAD * where DSNTIAD is
// SET DB2CH=DSN510.SDSNC.H * DB2 C header files
// SET DB2MACS=DSN510.SDSNMACS * DB2 macros etc
// SET SSID=DBC1 * DB2 subsystem ID
//*-------------------------------------------------------------------
//* Symbolics related to sample applications 2
//*-------------------------------------------------------------------
//*
//* SET DB2ATTCH=DSNELI * TO CREATE A TSO-CAF
// SET DB2ATTCH=DSNALI * TO CREATE A SPAS SP
//* SET LINKWINC=DUMMY * Do not create WLM-SP
// SET LINKWINC=DB2LINKW * Create SP for WLM AS
//*
// SET DBRMLIB=SG244693.SAMPLES.DBRMLIB * Application DBRM lib
// SET LINK=SG244693.SAMPLES.LINK * Link-edit control stm
// SET LOADLIB=SG244693.SAMPLES.LOAD.SPAS Appl load lib - SPAS
// SET LOADWLM=SG244693.SAMPLES.LOAD.WLM Appl load lib - WLM
// SET SOURCE=SG244693.SAMPLES.SOURCE * Source
// SET OBJLIB=SG244693.SAMPLES.OBJ * Object
// SET PLINCL=DSN510.SRCLIB.DATA * PL/I include
// SET COBCPY=DSN510.SRCLIB.DATA * COBOL copybook
// SET APPLHDR=SG244693.SAMPLES.H * Appl C header
// SET UTILLIB=SG244693.SAMPLES.JCL * Utility control stmts
//* SET MEM=
//*-------------------------------------------------------------------
//* Language Environment (LE) 3
//* For a description of LE related data sets, refer to
//* OS/390: Language Environment for OS/390 & VM Programming Guide
//*-------------------------------------------------------------------
// SET SCEERUN=CEE.SCEERUN * LE run time
// SET SCEELKED=CEE.SCEELKED
//* SET SCEELKEX= * from OS/390 C++ V2R4
// SET LIBPRFX=CEE * LE prefix
//*-------------------------------------------------------------------
//* PL/I for MVS 4
//*-------------------------------------------------------------------
// SET PLICOMP=IEL.V1R1M0.SIELCOMP * PL/I compiler
//*-------------------------------------------------------------------
//* C/C++ for OS/390 5
//* Use CBC.SCBCPRC(CBCCLG) as a sample for the symbolics
//*-------------------------------------------------------------------
// SET LNGPRFX=CBC * C/C++ prefix
// SET CLBPRFX=CBC * for class lib CLI
//*-------------------------------------------------------------------
//* COBOL for MVS 6
//*-------------------------------------------------------------------
// SET COBCOMP=IGY.V2R1M0.SIGYCOMP * COBOL compiler
//*
 

Appendix A. Sample P r o g r a m s 369


Before using the samples, you must tailor the JCL INCLUDE member @DEFAULT for your environment.
(Procedures CLIC and CLIL do not use the @DEFAULT member to set the JCL symbolics.)

1 You must tailor the symbolics for the DB2 section. If you are not using CLI, you will not be running
the CLI-related JCL procedures and can therefore leave them out. The same applies to data set
names related to C.

2 Tailor this section to reflect the data set names for your application.

3 This section is compulsory since stored procedures must run under LE. We assume all languages
run under the same release of LE. If this is not true, you will probably be using a variety of stored
procedure address space to separate the different environments.

4 This section is needed only if you have PL/I installed and you are going to use it.

5 This section is needed only if you have C/C++ installed and you are going to use it.

6 This section is needed only if you have COBOL installed and you are going to use it.

Table 34 shows the JCL procedures used from the samples in this redbook.

Table 34. JCL Procedures Used for Our Samples


Name Description
CLIC Compile a C/CLI program. Based on EDCC supplied with the C/C++ compiler
product.
CLIL Prelink/Link a C/CLI program. Based on CBCL supplied with the C/C++ compiler
product.
DB2HCCLI Prepare embedded C programs using CLI.
We didn′t actually have any programs using a mix of embedded SQL and CLI
programs.
DB2LINKW This is actually a JCL INCLUDE to link-edit using RRASF for WLM-established
stored procedure address space. We adopted the use of INCLUDEs so that the
same block of JCL can be embedded into different JCL jobs and procedures.
DSNHC We tailored the C compile JCL procedure by merging it with the JCL provided by
C/C++ in CBC.SCBCPRC. The compiler name has also changed.
DSNHCPP We tailored the C++ compile JCL procedure, including changing the C++
compiler name for OS/390.
If you get CBC1090(S) or CBC1104(E) messages from the C/C++ for OS/390
compiler, it is likely you need to run through the coded character set conversion
utility iconv().
DSNHICOB COBOL for MVS compilation with minor changes.
DSNHPLI Modified to match IEL1CLG, which comes with PL/I for MVS.

A.7 C / C + + Programs

OS/390 Version 2 Release 4 has introduced intermediate process architecture (IPA) links. If you plan
to use IPA links, you will need the SCEELKEX data set in your link step.

The samples are classified into different “features” for ease of reference:

370 Getting Started with DB2 Stored Procedures


N - SIMPLE WITH NULLS linkage convention
S - SIMPLE linkage convention
H - using host variables to pass parameters
D - using SQLDA to pass parameters
R - using result sets

Table 35 presents the C programs used in the OS/390 evironment

Table 35. Description of the C Programs Used in the OS/390 Environment.


Legend: N=Simple with NULLS, S=Simple, D=SQLDA, H=Host Variables, R(n)=With n Result Sets
Sample Name Features Description Possible
partners
CS0CMS NH C stored procedure, inserts a row in CTEST. cs0cmcr2.cmd
SR1CMS NHR(1) C version of UDB CLI samples mrspsrv.c against the (AIX)mrspcli.c
STAFF table. Similar to PL/I version SR1PMS. See (AIX)sr1.c
11.12.2, “Differences in Handling Result Sets” on
page 237

A.8 CLI Programs

Refer to 11.11, “Running the CLI Sample Stored Procedure” on page 235 for a detailed description of
how to prepare and run the APD29/SPD29 sample.

Table 36 presents CLI samples in the OS/390 environments.

Table 36 (Page 1 of 2). CLI Samples on OS/390.


Legend: N=Simple with NULLS, S=Simple, D=SQLDA, H=Host Variables, R(n)=With n Result Sets
Sample Name Features Description Possible
partners
APD29 SHR(2) Sample client from DB2 for OS/390 V5 Call Level Interface SPD29
Guide and Reference
SPD29 SHR(2) Sample stored procedure from DB2 for OS/390 V5 Call APD29
Level Interface Guide and Reference
SRSOMS SR(1) Sample stored procedure demonstrating single result set. SRSBMCBM
This is the CLI version of SRSBMS (COBOL) and SRSPMS
(PL/I). It is delivered to use the name SRSBMS so that
we only keep one client. You may want to clone the
COBOL client SRSBMCBM and call it SRSOMCBM so that
the source code calls SRSOMS instead of SRSBMS. To
build it:
1. Compile and prelink V2SUTIL by running JCL m e m b e r
V2SUTIL. V2SUTIL is used by SRSOMS.
2. Update the SRSOMS source code to point to the
TESTE table with your table qualifier.
3. Compile and prelink SRSOMS itself using JCL
m e m b e r SRSOMSBL.

Appendix A. Sample P r o g r a m s 371


Table 36 (Page 2 of 2). CLI Samples on OS/390.
Legend: N=Simple with NULLS, S=Simple, D=SQLDA, H=Host Variables, R(n)=With n Result Sets
Sample Name Features Description Possible
partners
SR1OMS NHR(1) CLI version of UDB CLI samples mrspsrv.c against the (AIX)sr1.c
STAFF table. See 11.12.3, “CLI Stored Procedure Coding
Considerations” on page 240 for a detailed description of
the source code. To execute it:
1. Create the STAFF table. The sample SQL library
contains member STAFF to create this table. This is
modified from the NT sample STAFF2 (the INSERT
statements on DB2 Universal Database V5 differ from
DB2 for OS/390 V5).
2. Compile and prelink V2SUTIL which is used by
SR1OMS. JCL member V2SUTIL will do it for you, as
well as creating a side-deck output to be used
whenever V2SUTIL is called.
3. Update the SR1OMS source code to point to the
STAFF table with your table qualifier.
4. Compile and prelink SR1OMS itself using JCL m e m b e r
SR1OMSBL.

A.9 COBOL Programs

Table 37 presents the COBOL samples used in the OS/390 environment.

Table 37 (Page 1 of 4). COBOL Samples on OS/390.


Legend: N=Simple with NULLS, S=Simple, D=SQLDA, H=Host Variables, R(n)=With n Result Sets
Name Features Description Possible
partners
BOUNCE This program is a test link of the user key program to
CICS.
CA0BMCBM SH This is a sample MVS batch client program that invokes CA0BMS
the CA0BMS MVS stored procedure using a constant as
the stored procedure name. It used the stored procedure
linkage convention SIMPLE.
CA0BMS SH This stored procedure calls an external program, CA0BMCBM
EXTPROG, that does not access DB2 data.
CA1BMCBM SH This is a sample MVS batch client program that invokes CA1BMS
the CA1BMS MVS stored procedure using a constant as
the stored procedure name. It used the stored procedure
linkage convention SIMPLE.
CA1BMS SH This stored procedure calls an external program,
EXTPROG1, that accesses DB2 data. The collection for
the external program package is different from the
collection for the stored procedure package. Note the SET
CURRENT PACKAGESET statement used to set the
collection.
EXTPROG This is the external program called by the CA0BMCBM CA0BMCBM
stored procedure.
EXTPROG1 This is the external program called by the CA1BMCBM CA1BMCBM
stored procedure. It contains SQL code to update a DB2
Table.

372 Getting Started with DB2 Stored Procedures


Table 37 (Page 2 of 4). COBOL Samples on OS/390.
Legend: N=Simple with NULLS, S=Simple, D=SQLDA, H=Host Variables, R(n)=With n Result Sets
Name Features Description Possible
partners
IMDBMCBM SH This is a sample MVS batch client program that invokes IMSBMS
the IMDBMS stored procedure passing it two parameters,
the IMS IVP transaction and its data. The data is returned
in two parameters, a counter for the number of lines
returned and a varchar field with the lines. The IMSBMS
stored procedure initiates an IMS transaction through
APPC.
IMDBMS SH This stored procedure shows how to activate an IMS IMS IVP
transaction through APPC. IMDBMS does a transactions
get-conversation to establish a conversation with the IMDBMCBM
requesting TP PARTNER : PART (implicit API, existing IMS imdbmcb2
transaction). It uses the SAA CPI Communications call, imdbmcbn
CMSTPN (Set_TP_Name) sets the TP name characteristic
for the conversation, to change the IMS transaction with
the transaction passed by the client. It then sends data to
the partner IVP transaction in IMS and receives the
output. The received IMS data is stored into a VARCHAR
parameter and returned to the client with the number of
lines received.
IMUBMCBM SHR This is a sample MVS batch client program that invokes IMUBMS
the IMUBMS stored procedure passing it two parameters,
the IMS IVP transaction and its data. The data is returned
in a result set that was stored in a DB2 Global Temporary
Table. The IMUBMS stored procedure initiates an IMS
transaction through APPC.
IMUBMS SHR This stored procedure shows how to activate an IMS IMS IVP
transaction through APPC. IMDBMS does a transactions
get-conversation to establish a conversation with the
requesting TP PARTNER : PART (implicit API, existing IMS
transaction). It uses the SAA CPI Communications call,
CMSTPN (Set_TP_Name) sets the TP name characteristic
for the conversation, to change the IMS transaction with
the transaction passed by the client. It then sends data to
the partner IVP transaction in IMS and receives the output
into a Global Temporary Table. The received IMS data is
then returned to the client as a result set.
IMSBMCBM SHR This is a sample MVS batch client program that invokes IMSBMS
the IMSBMS stored procedure passing it a single
parameter. The data is returned in a single result set.
The IMSBMS stored procedure initiates an IMS
transaction through APPC.
IMSBMS SHR This stored procedure shows how to activate an IMS IMS transaction
transaction through APPC. IMSBMS does a PART
get-conversation to establish a conversation with the
requesting TP PARTNER : PART (implicit API, existing IMS
transaction). It then sends data to the partner PART
transaction and receives the output. The received IMS
data is stored in a Global temporary table and returned to
the client as a result set.

Appendix A. Sample P r o g r a m s 373


Table 37 (Page 3 of 4). COBOL Samples on OS/390.
Legend: N=Simple with NULLS, S=Simple, D=SQLDA, H=Host Variables, R(n)=With n Result Sets
Name Features Description Possible
partners
MRSBMCBM NR This is a sample MVS BATCH client program that invokes MRSBMS
the MRSBMS MVS stored procedure and retrieves two
result sets. First, the result sets are processed one set at
a time. Second, the result sets are processed both at the
same time.
MRSBMS R This stored procedure returns two result sets back with MRSBMCBM
NULL columns.
MR0BMCBM This DB2 sample application COBOL provides a means to MR5BMCBM
allocate main storage to MR5BMCBM. This is required for
program MR5BMCBM to do pointer manipulation in using
this storage for the SQLDA.
MR5BMCBM NDR This is a sample MVS BATCH client program that invokes MR5BMS
the MR5BMS MVS stored procedure and retrieves result
sets back. It is coded to determine how many result sets
the stored procedure is returning. It is also coded to
determine the contents of the result sets.
MR5BMS NR This stored procedure shows how to receive multiple MR5BMCBM
result sets with and without null columns. This program
sets up five cursors and returns rows in only three of
them. It closes the cursor so no result set is returned for
it.
PA0BMCBM NH This is a sample MVS BATCH client program that invokes XC0BMCBM
the PA0BMS MVS stored procedure using a constant as
the stored procedure name. It uses the SIMPLE WITH
NULLS linkage.
PA0BMS NH This stored procedure shows how to receive NULL values
using indicator variables structures. This program is used
in CODE/370 debugging samples.
RRSAFCOB This is a sample MVS batch COBOL RRSAF program that IMS IVP
invokes the IMS V6 IVP transactions and updates a DB2 transactions
table. It uses RRSAF to coordinate the updates between
DB2 and IMS V6, and to attach them to DB2.
S10BMCPM NHR(1) This is a sample COBOL MVS BATCH client program MRSPSRV
similar to DB2 Universal Database V5 sample mrspcli.c.
It invokes the MRSPSRV MVS stored procedure, which we
have substituted for modules SR1CMS, SR1PMS, and
SR1XMS. But SR1OMS has been modified so the columns
do not match. Also, unlike the others, SR1OMS actually
has two results sets. So we get +464 with SR1OMS, and
a -303 due to columns not matching.
S01BMCC2 NH This is a sample MVS batch client program that invokes pr0c2s
the ″pr0c2s″ a OS2 stored procedure.
SD0BMCBM NH This is a sample MVS batch client program that invokes SD0BMS
the SD0BMS MVS stored procedure using a host variable
as the stored procedure name. It uses the stored
procedure linkage convention SIMPLE WITH NULLS to
pass two parameters.

374 Getting Started with DB2 Stored Procedures


Table 37 (Page 4 of 4). COBOL Samples on OS/390.
Legend: N=Simple with NULLS, S=Simple, D=SQLDA, H=Host Variables, R(n)=With n Result Sets
Name Features Description Possible
partners
SD0BMS NH This stored procedure shows how to use system-directed SD0BMCBM
access from a stored procedure using a three-part name
and private protocol. Location must have a LU defined in
SYSIBM.LUNAMES (SYSIBM.SYSLUNAMES) . It uses the
stored procedure linkage convention SIMPLE with NULLS.
SRSBMCBM R This is a sample MVS batch client program that invokes SRSBMS
the SRSBMS MVS stored procedure, using a single result SRSOMS
set. By changing SYSPROCEDURES to point to different SRSPMS
modules and collections, this client can execute the PL/I
version (SRSPMS) or the CLI version (SRSOMS) of the
stored procedure.
SRSBMS R This MVS stored procedure shows how to return a single SRSBMCBM
result set with NULL columns.
TS2BMCB2 SH This is a sample MVS batch client program that invokes ts2b2s
the ″ts2b2s″ OS/2 stored procedure using a constant as
the stored procedure name. Note that we used the stored
procedure name between quotes to avoid translation to
uppercase.
TS0BMCBM D This is a sample MVS batch client program that invokes TS0BMS
the TS0BMS MVS stored procedure using an SQLDA to
pass parameters.
TS0BMS SH This stored procedure is a sample of how to receive TS0BMCBM
parameters without indicator variables.
XC0BMCBM SH This is a sample MVS batch client program that invokes XC0VMS
the XC0BMS MVS stored procedure using SIMPLE
parameters.
XC0BMS SH This stored procedure shows how to invoke an CICS
program using the External Call Interface.

A.10 PL/I Programs


Table 38 presents the PL/I samples on OS/390.

Table 38 (Page 1 of 2). PL/I Samples on OS/390.


Legend: N=Simple with NULLS, S=Simple, D=SQLDA, H=Host Variables, R(n)=With n Result Sets
Name Features Description Possible
partners
MRSPMS NR(2) PL/I version of COBOL MRSBMS: multiple result set MRSBMCBM
stored procedure. We modified
SYSIBM.SYSPROCEDURES to pick up the PL/I module
MRSPMS instead of the COBOL module MRSBMS, and
run client MRSBMCBM.
SM0PMCPM NH Copy of sample SDSNSAMP(DSN8EP1), JCL from SM0PMS
SDSNSAMP(DSNTEJ6P). Client calling SM0PMS.

Appendix A. Sample P r o g r a m s 375


Table 38 (Page 2 of 2). PL/I Samples on OS/390.
Legend: N=Simple with NULLS, S=Simple, D=SQLDA, H=Host Variables, R(n)=With n Result Sets
Name Features Description Possible
partners
SM0PMS NH Copy of sample SDSNSAMP(DSN8EP2), JCL in sm0pmcr2.cmd
SDSNSAMP(DSNTEJ6S). Stored procedure using IFI to sm0pmcrx.cmd
run DB2 commands. It processes the display thread DB2 SM0PMCPM
command on MVS and passes the information back to the
client.
We added a DISPLAY PL/I statement to identify when it
has executed. A date/time string will be sent to the
stored procedures address space.
Code to call a REXX procedure is also added but will not
be executed unless you uncomment the code. See 6.2.5,
“Calling a REXX Procedure from a Stored Procedure” on
page 98.
Also a DISPLAY/REPLY is added to force operator
intervention. We use this technique to simulate
long-running stored procedures when testing how often
WLM starts up new stored procedures. See 3.13.3.1,
“Test WLM Management of Multiple Address Spaces” on
page 57.
SRSPWCPM R(1) PL/I version of COBOL program SRSBMCBM; accepts a SRSPMS
positional run-time parameter to specify location and
stored procedure name.
SRSPMS R(1) PL/I version of COBOL sample SRSBMS: single result set SRSPWCPM
stored procedure. The stored procedure address space
needs to allocate a SYSPRINT statement when running
SRSPMS.
SR1PMS NHR(1) PL/I version of UDB CLI samples mrspsrv.c against the (AIX)mrspcli.c
STAFF table. (AIX)sr1.c

Table 39 describes the REXX programs used for APPC/IMS verification.

Table 39. Description of the REXX Programs Used for APPC/IMS Verification.
Sample Name Features Description Possible
partners
SJXPART1 n/a APPC/IMS sample from Client/Server Computing with n/a
IMS/ESA Using APPC , which forms the basis for our APPC
work. Refer to 13.5, “APPC to Access Transactions from a
Stored Procedure” on page 292.
SJXPART2 n/a APPC/IMS sample from Client/Server Computing with n/a
IMS/ESA Using APPC , which forms the basis for our APPC
work. Refer to 13.5, “APPC to Access Transactions from a
Stored Procedure” on page 292.

376 Getting Started with DB2 Stored Procedures


Appendix B. Performance Benchmark and Capacity Planning

This appendix is based on one of a series of technical reports dealing with performance prediction and
capacity planning issues for the DB2 family of products operating in a client/server configuration. The
goal of these technical reports is to help the customer:
• Assess proposed configurations for acceptable performance.
• Assess performance of current configurations.
• Choose proper hardware capacity for a proposed configuration.
• Choose the proper software programs for a proposed configuration.
• Tune a new or current configuration.

We present measurements taken in a DRDA environment where the application server is DB2 for
MVS/ESA and the gateway products used are DDCS for OS/2 and DDCS for AIX. This report is not
intended and should not be used to compare the results of gateway products. Also, the hardware used
for DDCS for OS/2 and the hardware used for DDCS for AIX are not comparable and are not equivalent.

We provide two configurations as examples. A level of analysis must be performed when using
configurations different from the configuration used in this report.

We also include some general considerations that you can use to help plan, tune, and analyze your
configuration.

The information in this appendix is also available in a slightly different format in the following sources:
• IBM personnel can request the following packages by using the DB2INFO EXEC or through
MKTTOOLS:
− DD2MVS, the report using DDCS for OS/2 as the gateway product
− DD6MVS, the report using DDCS for AIX as the gateway product
A report using DDCS for OS/2 as the gateway and DB2 for OS/400 as the application server is also
available in the DD2400 package.
• Home page on the World Wide Web:
http://www.csc.ibm.com/advisor/library/
Performance measurement and capacity planning are ongoing projects of the authors of this appendix,
so you can expect new reports in the sources cited above.

B.1 Configurations and Specifications

Figure 179 on page 378 shows the configuration for the measurements when DDCS for OS/2 was used
as the gateway.

 Copyright IBM Corp. 1996 1998 377


Figure 179. Configuration with DB2 for MVS/ESA and DDCS for OS/2

Figure 180 on page 379 shows the configuration for the measurements when DDCS for AIX was used
as the gateway.

378 Getting Started with DB2 Stored Procedures


Figure 180. Configuration with DB2 for MVS/ESA and DDCS for AIX

The specifications for the benchmarking setup are as follows:


• DB2 for MVS/ESA Version 4.1 running on MVS Version 5.2 with VTAM Version 4.2. The processor
is a 9121-742 (4-way) with 1 GB of main storage and 1 GB of expanded storage. The processor is
partitioned into four logical partitions, with any one partition having the ability to use the other
processors, if needed. The partition running DB2 has 576 MB of storage available to it. The
processor is attached to a 3745 Model 210 with 8 MB of storage on a 4.5 MB block multiplex
channel. The 3745 is attached to the 16 Mb LAN through a TIC type 2.
• DDCS for OS/2 Version 2.3.1 running on a PC500 server with a 90 MHz Pentium processor and 128
MB of memory. The PC500 is attached to the 16 Mb LAN through the LANStreamer adapter card.
• DDCS for AIX Version 2.3.1 running on a C10 PowerPC 601 with an 80 MHz processor and 256 MB
of memory.
• Six PowerBuilder Version 4.0.2 with DB2 CAE for Windows Version 2.1 clients running on 9595 OPT
PS/2s with 60 MHz Pentium processors and 80 MB of memory. The LAN adapter cards are
configured to use early token release.
• Two 9595 OPT PS/2s with 60 MHz Pentium processors running OS/2 Version 3.0 (WARP). These
PS/2s are used to increase the workload in the configuration.
• 16 Mb token-ring LAN

These network protocols are used between the components:


• TCP/IP between the PowerBuilder clients and DDCS for OS/2
• TCP/IP between the PowerBuilder clients and DDCS for AIX
• LU 6.2 between the OS/2 clients and DDCS for OS/2
• LU 6.2 between DDCS for OS/2 and DB2 for MVS/ESA

Appendix B. Performance Benchmark and Capacity Planning 379


• LU 6.2 between DDCS for AIX and DB2 for MVS/ESA

The components in this configuration are monitored by means of the following programs:
• For the MVS platform
− MVS: Resource Measurement Facility (RMF)
− DB2 for MVS/ESA: DB2 Accounting and Statistics traces
• 3745: NetView Performance Monitor (NPM)
• OS/2: System Performance Monitor/2 (SPM/2)
• AIX: vmstat
• Clients: Internal tools to measure elapsed time and transactions per second
• LAN: DatagLANce Network Analyzer for Ethernet and Token-Ring for OS/2

B.2 Workload Description

The IBM Relational Warehouse Workload (IRWW) is used for the measurements. IRWW is a simulated
product warehouse, customer order, and order delivery system.

A series of measurements are performed, with each subsequent measurement providing an increased
workload to the configuration. All measurements include six PowerBuilder clients running a
predefined set of transactions in random order without modification for the entire series of
measurements. The PowerBuilder clients provide the end-user perspective of the effects of increasing
the workload in the configuration. The workload is increased each run by increasing the number of
sessions on the two OS/2 workload generators. The OS/2 workload generators run the exact same
transaction mix as the six PowerBuilder clients. The only difference is the management of screen I/O
at the client. The PowerBuilder clients simulate a real application, whereas the OS/2 workload
generators do not perform screen I/O.

B.2.1 Transaction Characteristics


The workload consists of seven transactions. Each transaction consists of a stored procedure call
followed by a commit or rollback. This results in two round-trip network flows between the client and
the server. The stored procedures are written in C, and they perform seven distinct functions in a
predefined mix:
• Transaction Tx1
Performs various selects, fetches, updates, and inserts in support of the receipt of new customer
orders. Transaction Tx1 runs as 22% of the total transaction mix and is the most complicated
transaction.
• Transaction Tx2
Performs various selects and fetches in support of reporting the status of an order. Transaction
Tx2 runs as 24% of the total transaction mix.
• Transaction Tx3
Performs various selects, fetches, updates, and inserts to record received customer payments.
Transaction Tx3 runs as 22% of the total transaction mix.
• Transaction Tx4
Performs an update in support of changing the price of an item. Transaction Tx4 runs as 1% of the
total transaction mix.
• Transaction Tx5

380 Getting Started with DB2 Stored Procedures


Performs various selects in support of reporting the price of a set of items. Transaction Tx5 runs
as 25% of the total transaction mix.
• Transaction Tx6
Performs various selects in support of providing the current stock level of an item. Transaction Tx6
runs as 4% of the total transaction mix.
• Transaction Tx7
Performs a join and various selects, updates, and deletes in support of the delivery of a group of
orders. Transaction Tx7 runs as 2% of the total transaction mix.

These transactions are described in greater detail in B.3.5, “Transactions” on page 389.

B.2.2 Table Characteristics


Before each measurement run, the tables on DB2 for MVS/ESA are put into a consistent state as
defined in Table 40. The table shows the initial number of rows at the start of a measurement run, the
number of columns, the number of indexes, the preload percentage, whether the number of rows is
fixed or will grow throughout the measurement run, and whether the table is partitioned into multiple
parts so the table can be spread out to multiple physical disk drives. The preload value is the
percentage of the table that is preloaded into memory before the measurement run. The transactions
manipulate these tables in various ways, and they are designed to have a high degree of contention on
some of the tables, such as the T2 table.

Table 40. Table Characteristics for DB2 for MVS/ESA


Table Initial Rows Columns Indexes Preload ( % ) Variable/ Partitioned
(Length in Fixed
Bytes)
T1 0 (62) 8 0 0 Variable No
T2 8 (103) 9 1 100 Fixed No
T3 80 (110) 11 1 100 Fixed No
T4 72,000 3 1 12 Variable No
(22)
T5 100,000 (91) 4 1 100 Fixed No
T6 240,000 (42) 8 2 12 Variable No
T7 240,000 21 2 12 Fixed Yes
(679)
T8 800,000 17 1 20 Fixed Yes
(322)
T9 2,399,791 10 1 12 Variable Yes
(75)

B.2.3 Locking Definitions


Type 2 indexes are used for all indexes. Row level locking is used for Table T4, and page level locking
for all other tables. Tables T2 and T3 have one row in a page, with the net equivalence of row level
locking for those two tables. All packages are bound with an isolation level of cursor stability. Table
space locks are set for use or commit.

Appendix B. Performance Benchmark and Capacity Planning 381


B.2.4 Physical Location
The configuration is tuned by spreading out the data and indexes to multiple unique disk drives. Also,
Tables T7, T8, and T9 and indexes are additionally spread out by partitioning and spreading out the
partitions to unique drives (see Table 41 on page 382). Fictitious labels are used to illustrate the
relationships between the physical locations of the tables and indexes. For example, if two tables are
on DISK1, they share the same disk drive.

For general consideration


It is best to spread out the tables and indexes to unique drives and controllers to reduce I/O
contention to the drives.

For the configurations in this report, there is some overlap of tables and indexes. In some cases, such
as Tables T2 and T3, the tables are 100% preloaded into memory, so the I/O contention to these drives
is reduced.

Table 41. Physical Storage Characteristics


Drive Controller Drive Type Tables and Indexes
DISK1-8 CNTRL1 3390-3 Table T7 (partitions
1-8)
Table T9 (partitions
1-8)
DISK9-16 CNTRL2 3390-2 All indexes
DISK17-24 CNTRL3 9394-1 Table T8 (partitions
1-8)
DISK25-32 CNTRL4 9394-1 Table T8 (partitions
9-16)
DISK33 CNTRL5 3380-E Table T1
Table T2
Table T6
DISK34 CNTRL5 3380-E Table T6
DISK35 CNTRL5 3380-E Table T4
DISK36 CNTRL6 3380-E Table T5
DISK37-44 CNTRL6 3380-E Table T7 (partitions
9-16)
Table T9 (partitions
9-16)

B.2.5 Buffer Pool Allocation


The tables and indexes are also spread out to multiple buffer pools as described in Table 42.
Spreading out the tables and indexes to multiple buffer pools allows for buffer pool tuning based on the
access characteristics of the tables and indexes. See the DB2 for MVS/ESA Administration Guide for a
discussion of buffer pools.

Table 42 (Page 1 of 2). Buffer Pool Characteristics


Buffer Pool Size (KB) Table and Index
BP0 2000 System defaults
BP1 2000 Table T1

382 Getting Started with DB2 Stored Procedures


Table 42 (Page 2 of 2). Buffer Pool Characteristics
Buffer Pool Size (KB) Table and Index
BP2 3000 Table T2 and index
Table T3 and index
Table T5 and index
BP3 6000 T7 Index 1
T7 Index 2
T8 Index
BP4 7000 T4 Index
T9 Index
T6 Index 1
T6 Index 2
BP5 4000 Table T4
Table T6
BP6 20000 Table T9
BP7 12500 Table T7
BP8 20000 Table T8
Total 76500

B.3 Results for DDCS for OS/2

This section describes the results of the measurements. The effects on each component in the
configuration are described as well as the performance of each transaction. The component results
can help you understand hardware capacity issues. The transaction results can help you understand
the perceived performance prediction issues.

The results are presented in relation to the overall throughput achieved at each workload level. This is
described as transactions per second (TPS). As the workload increases, the throughput increases.
The resultant effects on each component are then presented based on the current achieved
throughput. For example, when achieving 80 TPS:
• The 3745 running the network control program (NCP) is 81% utilized.
• The transfer rate through the 3745 running the NCP is 71,380 bytes per second.
• The PC500 running DDCS for OS/2 is 79% utilized.

The process of tuning the application and database is ongoing. These measurements achieved a
throughput rate of 89.34 TPS. At this point, several factors begin to show signs of stress. Primarily,
high levels of locking and latching occur. Also the device activity rate and the average response time
accessing disks 36-43 increase. These disks are 3380-E, and they contain 8 of the 16 partitions for
Table T7 and Table T9. The other 8 partitions are on 3390-3 disks, which are faster, and the device
rate and average response time reflect this.

Multiple iterations with tuning occurred before these results were achieved. The results are probably
not the absolute best, but to continue tuning and pushing for the absolute limits is not the goal of this
project. Other benchmarking projects deal with those goals. The goal of this project is to provide a
reasonably tuned environment. An important point to note is that the tuning of DB2 for MVS/ESA in
this client/server configuration should be the same as tuning DB2 for MVS/ESA in a local configuration.
This is true because of the use of stored procedures.

Appendix B. Performance Benchmark and Capacity Planning 383


B.3.1 Client Equivalence
The configuration includes six PowerBuilder clients and a variable number of OS/2 clients. All clients
run the same transaction mix, but the PowerBuilder clients present the output data on the computer
screen. This adds to the response time, which decreases the throughput for the PowerBuilder clients.
This section estimates a rough number of total PowerBuilder clients that can be served, based on the
throughput obtained by the OS/2 clients and the throughput of the actual PowerBuilder clients.

Table 43 shows the number of clients activated to achieve the throughput defined in column 1.
Column 2 shows the number of PowerBuilder clients (always 6). Column 3 shows the number of OS/2
clients. This number is increased by 10 for each measurement run. Column 4 shows the actual
number of clients, which is the sum of columns 2 and 3. Column 5 shows the estimated number of
PowerBuilder clients. This column is derived by evaluating the number of equivalent PowerBuilder
clients that each OS/2 client represents in terms of throughput:

---- ----
| |
| OS/2 client tps |
Estimated PowerBuilder Clients = |-------------------------- * (# OS/2 clients)| + (# PowerBuilder clients)
| PowerBuilder client tps |
| |
---- ----

If
OS/2 client tps = 1.476 tps
PowerBuilder client tps = .128 tps
# OS/2 clients = 60
# PowerBuilder clients = 6
then

---- ----
| |
| 1.476 tps |
Estimated PowerBuilder Clients = |----------- * 60 clients | + (6 clients)
| .128 tps |
| |
---- ----

= 698 clients

Table 43. Number of Clients in Relation to Aggregate Throughput: Transactions per Second (DDCS for OS/2)
Throughput PowerBuilder OS/2 Clients Actual Clients Est. PowerBuilder
Clients Clients
34.67 6 10 16 293
66.57 6 20 26 563
79.74 6 30 36 646
86.54 6 40 46 657
88.55 6 50 56 697
89.34 6 60 66 698

The values obtained in these measurements are based on the actual number of clients as reflected in
column 4 of Table 43. When evaluating the estimated number of PowerBuilder clients, other capacity
planning factors must be addressed. For example, DB2 for MVS/ESA V4.1 can handle up to 25,000
connections, with up to 1,999 active threads, and each client that passes through DDCS for OS/2 should
be allowed approximately 300 KB of RAM on DDCS for OS/2. These factors must be taken in
consideration when designing a configuration. One last point on the number of clients: the numbers
are based on the clients running without think time or keystroke time. So, if you factor in these
aspects, you could increase the actual number of clients to fill the capacity left available due to think
time and keystroke time.

384 Getting Started with DB2 Stored Procedures


B.3.2 CPU Utilization
This section describes CPU utilization and RAM utilization as the workload increases for each
measurement. Table 44 on page 385 and Figure 181 on page 385 show the CPU utilization, and
Table 45 on page 386 shows the RAM utilization for the PC500 running DDCS for OS/2.

The PC500 running DDCS for OS/2 reaches CPU utilization of 90.04% at a throughput rate of 89.34 TPS.
The measurements that support this report do not support any conclusions about the upper bounds of
CPU utilization for a PC500 or at what point degradation becomes noticeable.

At a throughput rate of 89.34 TPS, the 9121-742 running DB2 for MVS/ESA processor reaches 77.33 CPU
utilization. The 9121-742 is capable of scaling up to 98% CPU utilization; therefore, excess processor
power is available.

Table 44. CPU Utilization in Relation to Throughput: DDCS for OS/2


Throughput (TPS) PC500 Running DDCS for OS/2 9121-742 Running DB2 for
MVS/ESA
34.67 34.59% 30.89%
66.57 62.06% 56.86%
79.74 78.53% 70.07%
86.54 84.58% 73.93%
88.55 88.12% 75.88%
89.34 90.04% 77.33%

Figure 181. CPU Utilization in Relation to Throughput: DDCS for OS/2

Table 45 on page 386 shows the increase in RAM utilization for the PC500 as the number of clients
increases. The initial value of 33.126 MB for 16 clients should not be used as an indication of RAM
usage. This number is a factor of the types and numbers of applications activated on the PC500. Treat
33.126 as the base number, which increases as clients are added. The average amount of RAM used
by a client is approximately 200 KB. Conservatively, plan for 300 KB for each additional client.

Appendix B. Performance Benchmark and Capacity Planning 385


Table 45. RAM Utilization on PC500
Number of Clients MB of RAM
16 33.126
26 34.971
36 36.864
46 38.841
56 41.505
66 43.556

For general consideration


• DDCS for OS/2 should run on a fast processor with enough memory to handle the number of
expected clients. Plan for 300 KB for each client passing through DDCS for OS/2. The base
level of RAM for the PC500 should be based on the number of applications and RAM
requirements for those applications.
• Hard disk capacity is not an issue for DDCS for OS/2 because the processing requirements do
not require large amounts of disk capacity.

B.3.3 Network
The network plays a big part in how well the client/server application performs and how big an effect
the client/server applications have on the performance of the database. Delay is the biggest enemy.
How big a role delay plays depends on the application. Every time a trip across the network is
required, if locks are held, they are held for the time it takes for the messages to move between the
client and the database. For these measurements, stored procedures are used, which has the benefit
of decreasing the number of SQL calls that must flow across the network as messages. Locks are held
only for the time to process the stored procedure and for one network roundtrip to issue a commit or
rollback. So, although delay does play a role in these measurements, it could play a larger role in
other environments.

The next two sections describe the effects on the NCP and LAN during the measurements. For this mix
of transactions, the message lengths are never greater than 1,200 bytes, so the following values are
set:
• 4 KB RUSIZEs in VTAM
• 4 KB RQRIOBLK definition in DDCS for OS/2
• 4 KB RQRIOBLK definitions in the OS/2 clients
• 4 KB DOS_RQRIOBLK definitions in the DOS clients

B.3.3.1 Network Control Program: Table 46 on page 387 shows the effects of the workload on
the 3745 running the NCP. The 3745 reached 89% utilization at a throughput rate of 89.34 TPS. The
data throughput in the NCP reached 79,873 bytes per second.

The DELAY parameters in the NCP play an important role in the performance of the NCP as well as the
response time observed at the clients. The greater the DELAY parameter value on the PCCU, HOST,
or GROUP LNCTL=CA parameters, the lower the CCU utilization, but the greater the response time at
the clients, especially at lower throughput.

For these measurements, the GROUP LNCTL=CA DELAY parameter is set to 0.1, and the PCCU and
HOST DELAY parameters are set to zero. This has the beneficial effect of controlling the CCU
utilization with little effect on response time at the clients with the higher levels of throughput. The

386 Getting Started with DB2 Stored Procedures


lower levels of throughput experience mildly higher levels of delay than when the GROUP LNCTL=CA
DELAY parameter is set to 0.

The NCP for the measurements was dedicated to the IRWW workload activity. Typically, an NCP is
doing other work, and this work should be factored into the capacity requirements for the NCP.

Table 46. 3745 Utilization in Relation to Throughput: DDCS for OS/2


Throughput (TPS) Bytes per Second 3745 Utilization (%)
34.67 31,565 38
66.57 57,992 67
79.74 71,380 81
86.54 76,626 86
88.55 78,446 88
89.34 79,873 89

These results can be used to analyze the line capacity requirements between the LAN and the DB2 for
MVS/ESA host system. For these measurements, the connection is through a 4.5 MB channel, which is
underutilized. If this is replaced by a line with a speed of 56 Kb per second or 256 Kb per second, the
throughput is limited.

Additional measurements using a 3174-61R attached to the LAN with a 56 Kb per second connection to
the 3745 achieved a data throughput rate of approximately 4847 bytes per second (see Figure 182 on
page 388). This is a 69% utilization of the line. At this utilization, the throughput rate reached
approximately 5 TPS. Although the line has more capacity, the increase in transactions per second
begins to level off. For this report, there is not enough information to identify why 69% is the
threshold. It could be due to such factors as message size, hardware constraints, or protocol
constraints. Additional research or measurements are needed to identify the cause.

Appendix B. Performance Benchmark and Capacity Planning 387


Figure 182. Configuration with 3174: DDCS for OS/2

For general consideration


• Assess the line speeds between the LAN and DB2 for MVS/ESA. The throughput is only as
good as the slowest line. Overutilization of any line results in delays.
• Introducing multiple communications devices (for example, 3745s, bridges, routers) on the
communication path between the LAN and the database introduces delays.
• Tune the NCP definition DELAY parameters. If response time at the client is most important,
set all DELAY values to zero. If CCU is constrained, set the GROUP LNCTL=CA to 0.1 or 0.2;
0.2 will create a greater response time delay than 0.1. The following NCP statements have
DELAY parameters:
PCCU
HOST
GROUP LNCTL=CA

B.3.3.2 LAN: Table 47 on page 389 shows the percentage of LAN utilization and byte rate as the
workload is increased. For these measurements, the LAN capacity does not factor in. The 16 Mb LAN
is lightly utilized. Typically, a production environment has more activity on the LAN. Use these
numbers to analyze the additional load introduced on the LAN due to the mix of transactions used in
this configuration.

For general consideration

Monitor your LAN to make sure it is not being overutilized. Overutilization of the LAN could
introduce delays with resultant bad effects on database performance.

388 Getting Started with DB2 Stored Procedures


Table 47. LAN Utilization in Relation to Throughput: DDCS for OS/2
Throughput (TPS) Bytes per Second LAN Utilization (%)
34.67 115,493 5.77
66.57 210,132 10.51
79.74 257,767 12.89
86.54 276,741 13.84
88.55 284,118 14.21
89.34 286,491 14.32

B.3.4 DB2 Utilization


The following rate and mix of SQL statements occur when achieving a transaction throughput rate of
89.34 TPS:
• 314 SELECT statements per second
• 252 INSERT statements per second
• 326 UPDATE statements per second
• 18 DELETE statements per second
• 395 OPEN statements per second
• 229 CLOSE statements per second
• 782 FETCH statements per second

Two network flows are involved in each transaction. The first flow calls the stored procedure. The
second flow commits or rolls back the transaction. Locks acquired during stored procedure processing
are held until the commit or rollback is received. These locks are held for the amount of time it takes
to send the stored procedure response back to the client and for the client to process the response
and issue the commit or rollback. This delay results in locking contention at DB2 for MVS/ESA. This
contention becomes a major factor at higher levels of utilization, such as 89.34 TPS.

Secondarily, the average response time accessing 8 of the 16 partitions for Table T7 and Table T9 is
reaching levels that cause a delay because those partitions reside on slower disk drives (3380-E).

For general consideration


• When using stored procedures in a client/server environment, tune the database as if the
access is local.

B.3.5 Transactions
This section describes the transactions and the achieved response time at the PowerBuilder clients in
relation to the aggregate throughput. The response time duration starts when the end user submits
the transaction request—after the network connection is established and the end user has entered the
input data. The duration ends after the commit or rollback has been issued and all response data is
available to the end user (visible on the computer monitor).

In this section, graphs depict the point where 90% of the transactions complete within the identified
response time for the identified throughput. Figure 183 on page 390 shows the aggregate response
time of the transactions for the identified throughput.

Appendix B. Performance Benchmark and Capacity Planning 389


Figure 183. Aggregate Response Time: DB2 for MVS/ESA and DDCS for OS/2

Each procedure described in the subsections that follow performs different operations, which creates
various degrees of contention on the tables. The SQL calls are described in the order they are called
for each procedure. Locking contention is the primary factor for response time degradation, with
access to slower disk drives also becoming a factor.

B.3.5.1 Transaction Tx1: Transaction Tx1 is the most involved of the seven transactions. The
transaction calls a stored procedure that performs write operations against Tables T3, T4, T6, T8, and
T9. The stored procedure performs read operations against Tables T2, T3, T5, T7, and T8.
Index-matching predicates in the WHERE clauses optimize access to all tables. The stored procedure
has two input parameters with a byte count between 22 and 190. There are nine output parameters
with a maximum byte count of 713.

Here is a summary of the SQL calls in the stored procedure and the order in which they occur:
Select
T7
T2
Fetch and Update
T3
Insert
T4
T6
Fetch
T5
Loop up to 15 times
Fetch and Update
T8
Insert
T9
End loop

Figure 184 on page 391 shows the achieved response time for transaction Tx1. The vertical axis
represents the response time as seen by the PowerBuilder clients. The horizontal axis represents the

390 Getting Started with DB2 Stored Procedures


overall throughput rate for the aggregate of transactions. The solid line represents the point where
90% of the Tx1 transactions achieved this response time or better.

Figure 184. Response Time for Transaction Tx1: DDCS for OS/2

Most Tx1 transactions complete between 1.4 and 2.6 seconds. Transaction Tx1 shows a response time
degradation at 80 TPS, which is attributed to lock contention on Table T3. Both the Tx3 and Tx6
transactions update Table T3. Transaction Tx1 also inserts Table T9, and one-half of those rows are
resident on slower disk drives.

Table 48 shows the transactions that have potential lock contention with transaction Tx1 on the defined
tables.

Table 48. Potential Lock Contention for Transaction Tx1: DDCS for OS/2
Table Tx1 Tx2 Tx3 Tx4 Tx5 Tx6 Tx7
T2 Yes
T3 Yes Yes
T4 Yes Yes
T5 Yes
T6 Yes Yes
T7 Yes Yes
T8 Yes
T9 Yes Yes

B.3.5.2 Transaction Tx2: Transaction Tx2 calls a stored procedure that performs read operations
against Tables T6, T7, and T9. Index-matching predicates in the WHERE clause optimize access to
these tables. The stored procedure has one input parameter with a byte count of 26 and four output
parameters with a maximum byte count of 516.

Here is a summary of the SQL calls in the stored procedure and the order in which they occur:

Appendix B. Performance Benchmark and Capacity Planning 391


For 60% of the time:
Select
T7
Loop up to 4 times
Fetch from
T7
End loop
End 60% of the time
Select
T7
T6
Loop up to 15 times
Fetch
T9
End loop

Figure 185 shows the achieved response time for transaction Tx2. The vertical axis represents the
response time as seen by the PowerBuilder clients. The horizontal axis represents the overall
throughput rate for the aggregate of transactions. The solid line represents the point where 90% of the
Tx2 transactions achieved this response time or better.

Figure 185. Response Time for Transaction Tx2: DDCS for OS/2

Most Tx2 transactions complete between 1.0 and 1.2 seconds. Transaction Tx2 shows the beginning of
response time degradation at 89 TPS, which can be attributed to the fetch from Table T9, which is 50%
contained on slower disk drives. These drives are beginning to show higher response time due to
higher utilization rates.

Table 49 shows the transactions that have potential lock contention with transaction Tx2 on the defined
tables.

Table 49. Potential Lock Contention for Transaction Tx2: DDCS for OS/2
Table Tx1 Tx2 Tx3 Tx4 Tx5 Tx6 Tx7
T6 Yes Yes
T7 Yes Yes
T9 Yes Yes

392 Getting Started with DB2 Stored Procedures


B.3.5.3 Transaction Tx3: Transaction Tx3 calls a stored procedure that performs write operations
against Tables T1, T2, T3, and T7. The stored procedure performs read operations against Tables T2,
T3, and T7. Index-matching predicates in the WHERE clauses optimize access to all tables except T1.
The stored procedure has one input parameter for a byte count of 39 and six output parameters with a
maximum byte count of 551.

Here is a summary of the SQL calls in the stored procedure and the order in which they occur:
For 60% of the time
Select
T7
Loop up to 4 times
Fetch from
T7
End loop
End 60% of the time
Fetch and Update
T7
Conditionally Fetch and Update
T2
T3
Insert
T1

Figure 186 shows the achieved response time for transaction Tx3. The vertical axis represents the
response time as seen by the PowerBuilder clients. The horizontal axis represents the overall
throughput rate for the aggregate of transactions. The solid line represents the point where 90% of the
Tx3 transactions achieved this response time or better.

Figure 186. Response Time for Transaction Tx3: DDCS for OS/2

Most Tx3 transactions complete between 1 and 2.75 seconds. Transaction Tx3 shows a gradual
response time degradation at 70 TPS and a greater degradation at 89 TPS. This is attributed to
requiring exclusive locks on Tables T2, T3, and T7. Both Tables T2 and T3 are small. The Tx7
transaction updates Table T7. The Tx1 transaction updates Table T3 and reads Tables T2 and T7. The
Tx2 transaction reads Table T7.

Table 50 on page 394 shows the transactions that have potential lock contention with transaction Tx3
on the defined tables. Both Tables T2 and T3 are small, so the contention potential is great.

Appendix B. Performance Benchmark and Capacity Planning 393


Table 50. Potential Lock Contention for Transaction Tx3: DDCS for OS/2
Table Tx1 Tx2 Tx3 Tx4 Tx5 Tx6 Tx7
T1 Yes
T2 Yes
T3 Yes Yes
T7 Yes Yes

B.3.5.4 Transaction Tx4: Transaction Tx4 calls a stored procedure that performs a write
operation against T5. Index-matching predicates in the WHERE clause optimize access to this table.
The stored procedure has one input parameter with a byte count of 8 and three output parameters with
a maximum byte count of 99.

Here is the SQL call in the stored procedure:


Update
T5

Figure 187 shows the achieved response time for this transaction. The vertical axis represents the
response time as seen by the PowerBuilder clients. The horizontal axis represents the overall
throughput rate for the aggregate of transactions. The solid line represents the point where 90% of the
Tx4 transactions achieved this response time or better.

Figure 187. Response Time for Transaction Tx4: DDCS for OS/2

Most Tx4 transactions complete in less than 0.8 second. The response time degradation is minimal for
the scope of the measurements. Tx4 updates Table T5, which is 100% preloaded into memory. The
disk drive that contains the log shows some high-level utilization, but the average access time is still
low because of the speed of the disk drive. The high level of utilization at the greater throughput rates
can account for the slight degradation in response time. Transaction Tx4 runs 1% of the time;
therefore, the sampling is low, which can result in sampling anomalies.

Table 51 on page 395 shows the transaction that has potential lock contention with transaction Tx4 on
the defined tables.

394 Getting Started with DB2 Stored Procedures


Table 51. Potential Lock Contention for Transaction Tx4: DDCS for OS/2
Table Tx1 Tx2 Tx3 Tx4 Tx5 Tx6 Tx7
T5 Yes

B.3.5.5 Transaction Tx5: Transaction Tx5 calls a stored procedure that performs read operations
against Table T5. Index-matching predicates in the WHERE clause optimize access to this table. The
stored procedure has one input parameter with a byte count between 8 and 120. It has seven output
parameters with a maximum byte count of 590.

Here is a summary of the SQL calls in the stored procedure and the order in which they occur:
Loop up to 15 times
Select
T5
End loop

Figure 188 shows the achieved response time for this transaction. The vertical axis represents the
response time as seen by the PowerBuilder clients. The horizontal axis represents the overall
throughput rate for the aggregate of transactions. The solid line represents the point where 90% of the
Tx5 transactions achieved this response time or better.

Figure 188. Response Time for Transaction Tx5: DDCS for OS/2

The Tx5 transactions complete in less than 1.0 second. Tx5 shows a little change in response time.
Table T5 is the only table that Tx5 accesses. There is neither lock contention nor I/O contention
against this table because it is large and 100% loaded into memory.

Table 52 shows the transaction that has potential lock contention with transaction Tx5 on the defined
table.

Table 52. Potential Lock Contention for Transaction Tx5: DDCS for OS/2
Table Tx1 Tx2 Tx3 Tx4 Tx5 Tx6 Tx7
T5 Yes

Appendix B. Performance Benchmark and Capacity Planning 395


B.3.5.6 Transaction Tx6: Transaction Tx6 calls a stored procedure that performs read operations
against Tables T3, T8, and T9. Index-matching predicates in the WHERE clause optimize access to the
rows. The stored procedure has one input parameter with a byte count of 8 and three output
parameters with a maximum byte count of 78.

Here is a summary of the SQL calls in the stored procedure and the order in which they occur:
Select
T3
Select
T8 joined with T9

Figure 189 shows the achieved response time for this transaction. The vertical axis represents the
response time as seen by the PowerBuilder clients. The horizontal axis represents the overall
throughput rate for the aggregate of transactions. The solid line represents the point where 90% of the
Tx6 transactions achieved this response time or better.

Figure 189. Response Time for Transaction Tx6: DDCS for OS/2

The Tx6 transactions complete between 0.65 and 1.5 seconds. Tx6 shows an increase in response time
at about 80 TPS. This can be attributed to locking contention on Table T3 and increased disk utilization
on 50% of Table T9. Transactions Tx1 and Tx7 perform updates on Table T3.

Table 53 shows the transactions that have potential lock contention with transaction Tx6 on the defined
tables.

Table 53. Potential Lock Contention for Transaction Tx6: DDCS for OS/2
Table Tx1 Tx2 Tx3 Tx4 Tx5 Tx6 Tx7
T3 Yes Yes
T8 Yes
T9 Yes Yes

396 Getting Started with DB2 Stored Procedures


B.3.5.7 Transaction Tx7: Transaction Tx7 calls a stored procedure that performs write operations
against Tables T4, T6, T7, and T9. The stored procedure performs read operations against Tables T4,
T6, and T9. Index-matching predicates in the WHERE clauses optimize access to these large tables.
The stored procedure has one input parameter for a byte count of 6 and three output parameters with
a maximum byte count of 78.

Here is a summary of the SQL calls in the stored procedure and the order in which they occur:
Loop up to 10 times
Fetch and Delete
T4
Fetch and Update
T6
Update
T9
Select
T9
Update
T7
End loop

Figure 190 shows the achieved response time for this transaction. The vertical axis represents the
response time as seen by the PowerBuilder clients. The horizontal axis represents the overall
throughput rate for the aggregate of transactions. The solid line represents the point where 90% of the
Tx7 transactions achieved this response time or better.

Figure 190. Response Time for Transaction Tx7: DDCS for OS/2

The Tx7 transactions complete between 0.7 and 1.5 seconds. Tx7 shows a gradual response time
degradation throughout the scope of the measurements. Since transaction Tx7 needs exclusive locks
to Tables T4, T6, T7, and T9, as the throughput increases, the response time should degrade. These
are all large tables, so the contention should not be drastic.

Table 54 on page 398 shows the transactions that have potential lock contention with transaction Tx7
on the defined tables.

Appendix B. Performance Benchmark and Capacity Planning 397


Table 54. Potential Lock Contention for Transaction Tx7: DDCS for OS/2
Table Tx1 Tx2 Tx3 Tx4 Tx5 Tx6 Tx7
T4 Yes Yes
T6 Yes Yes
T7 Yes Yes
T9 Yes Yes

B.4 Results for DDCS for AIX

This section describes the results from the measurements. The effects on each component in the
configuration are described as well as the performance of each transaction. The component results
can help you understand hardware capacity issues. The transaction results can help you understand
the perceived performance prediction issues.

The results are presented in relation to the overall throughput achieved at each workload level. This is
described as TPS. As the workload increases, the throughput increases. The resultant effects on each
component are then presented based on the current achieved throughput. For example, when
achieving 57.1 TPS:
• The 3745 running the NCP is 74% utilized.
• The transfer rate through the 3745 running the NCP is 50,922 bytes per second.
• The C10 running DDCS for AIX is 97% utilized.

The process of tuning the application and database is ongoing. These measurements achieved a
throughput rate of 57.1 TPS. At this point, several factors are beginning to show signs of stress.
Primarily, there are CPU constraints on the C10 running DDCS for AIX. The CPU utilization on the C10
reaches 97%. Secondarily, high levels of locking and latching occurr. Also, the device activity rate
and the average response time accessing disks 36-43, both increase. These disks are 3380-E, and they
contain 8 of the 16 partitions for the Tables T7 and T9. The other 8 partitions are on 3390-3 disks,
which are faster, and the device rate and average response time reflect this.

Multiple iterations with tuning occurred before achieving these results. The results are probably not
the absolute best, but to continue tuning and pushing for the absolute limits is not the goal of this
project. Other benchmarking projects deal with those goals. The goal of this project is to provide a
reasonably tuned environment. An important point to note is that the tuning of DB2 for MVS/ESA in
this client/server configuration should be the same as tuning DB2 for MVS/ESA in a local configuration.
This is true because of the use of stored procedures.

B.4.1 Client Equivalence


The configuration includes six PowerBuilder clients and a varying number of OS/2 clients. All clients
run the same transaction mix, but the PowerBuilder clients present the output data on the computer
screen. This adds to the response time, which decreases the throughput for the PowerBuilder clients.
This section estimates a rough number of total PowerBuilder clients that can be served, based on the
throughput obtained by the OS/2 clients and the throughput of the actual PowerBuilder clients.

Table 55 on page 399 shows the number of clients activated to achieve the throughput defined in
column 1. Column 2 shows the number of PowerBuilder clients (always 6). Column 3 shows the
number of OS/2 clients. This number is increased by 10 for each measurement run. Column 4 shows
the actual number of clients, which is the sum of columns 2 and 3. Column 5 shows the estimated
number of PowerBuilder clients. This column is derived by evaluating the number of equivalent
PowerBuilder clients that each OS/2 client represents in terms of throughput:

398 Getting Started with DB2 Stored Procedures


---- ----
| |
| OS/2 client tps |
Estimated PowerBuilder Clients = |-------------------------- * (# OS/2 clients)| + (# PowerBuilder clients)
| PowerBuilder client tps |
| |
---- ----

If
OS/2 client tps = 1.41 tps
PowerBuilder client tps = .128 tps
# OS/2 clients = 40
# PowerBuilder clients = 6
then

---- ----
| |
| 1.41 tps |
Estimated PowerBuilder Clients = |----------- * 40 clients | + (6 clients)
| .128 tps |
| |
---- ----

= 447 clients

Table 55. Number of Clients in Relation to Aggregate Throughput: Transactions per Second (DDCS for AIX)
Throughput (TPS) PowerBuilder OS/2 Clients Actual Clients Est. PowerBuilder
Clients Clients
24.53 6 10 16 179
43.67 6 20 26 340
53.68 6 30 36 402
57.1 6 40 46 447

The values obtained in these measurements are based on the actual number of clients as reflected in
column 4. When evaluating the estimated number of PowerBuilder clients, other capacity planning
factors must be addressed. For example, DB2 for MVS/ESA V4.1 can handle up to 25,000 connections,
with up to 1,999 active threads, and each client that passes through DDCS for AIX should be allowed
approximately 500 KB of RAM on DDCS for AIX. These factors must be taken in consideration when
designing a configuration. One last point on the number of clients: the numbers are based on the
clients running without think time or keystroke time. So, if you factor in these aspects, you could
increase the actual number of clients to fill the capacity left available due to think time and keystroke
time.

B.4.2 CPU Utilization


This section describes CPU utilization and RAM utilization as the workload increases for each
measurement. Table 56 on page 400 and Figure 191 on page 400 show the CPU utilization and
Table 57 on page 400 shows the RAM utilization for the C10 running DDCS for AIX.

The C10 running DDCS for AIX reaches CPU utilization of 97% at a throughput rate of 57.1 TPS. The
C10 is identified as the primary bottleneck that prevents additional throughput.

At a throughput rate of 57.1 TPS, the 9121-742 processor reaches 48.57 CPU utilization. The 9121-742 is
capable of scaling up to 98% CPU utilization; therefore, excess processor power is available.

Appendix B. Performance Benchmark and Capacity Planning 399


Table 56. CPU Utilization in Relation to Throughput: DDCS for AIX
Throughput (TPS) C10 Running DDCS for C10 Running DDCS for 9121-742 Running DB2
AIX - User AIX - System for MVS/ESA
24.53 8% 37% 22.15%
43.68 14% 57% 38.07%
53.68 17% 72% 45.72%
57.1 17% 80% 48.57%

Figure 191. CPU Utilization in Relation to Throughput: DDCS for AIX

Table 57 shows the increase in RAM utilization for the C10 as the number of clients increases. The
initial value of 75.54 MB for 16 clients should not be used as an indication of RAM usage. This number
is a factor of the types and numbers of applications activated on the C10. Treat 75.54 as the base
number, which increases as clients are added. The average amount of RAM used per client is
approximately 450 KB. Conservatively, plan for 500 KB for additional clients.

Table 57. RAM Utilization on C10


Number of Clients MB of RAM
16 75.54
26 80.33
36 84.78
46 89.31

For general consideration


• DDCS for AIX should run on a fast processor with enough memory to handle the number of
expected clients. Plan for 500 KB for each client passing through DDCS for AIX. The base level
of RAM for the C10 should be based on the number of applications and RAM requirements for
those applications.
• Hard disk capacity is not an issue for DDCS for AIX because the processing requirements do
not require large amounts of disk capacity.

400 Getting Started with DB2 Stored Procedures


B.4.3 Network
The network plays a big part in how well the client/server application will perform and how big an
effect the client/server applications will have on the performance of the database. Delay is the biggest
enemy. How big a role delay plays depends on the application. Every time a trip across the network
is required, if locks are held, they are held for the time it takes for the messages to move between the
client and the database. For these measurements, stored procedures are used, which has the benefit
of decreasing the number of SQL calls that must flow across the network as messages. Locks are held
only for the time to process the stored procedure and for one network roundtrip to issue a commit or
rollback. So, although delay does play a role in these measurements, it could play a larger role in
other environments.

The next two sections describe the effects on the NCP and LAN during the measurements. For this mix
of transactions, the message lengths are never greater than 1,200 bytes, so the following values are
set:
• 4 KB RUSIZEs in VTAM
• 4 KB RQRIOBLK definition in DDCS for AIX
• 4 KB RQRIOBLK definitions in the OS/2 clients
• 4 KB DOS_RQRIOBLK definitions in the DOS clients

B.4.3.1 Network Control Program: Table 58 shows the effects of the workload on the 3745
running the NCP. The 3745 reached 74% utilization at a throughput rate of 57.1 TPS. The data
throughput in the NCP reached 50,922 bytes per second.

The DELAY parameters in the NCP play an important role in the performance of the NCP as well as the
response time observed at the clients. The greater the DELAY parameter values on the PCCU, HOST,
or GROUP LNCTL=CA parameters, the lower the CCU utilization, but the greater the response time at
the clients, especially at lower throughput.

For these measurements, the GROUP LNCTL=CA DELAY parameter is set to 0.1 and the PCCU and
HOST DELAY parameters are set to zero. This has the beneficial effect of controlling the CCU
utilization with little response time impact at the clients at the higher levels of throughput. The lower
levels of throughput experience mildly higher levels of delay than when the GROUP LNCTL=CA
DELAY parameter is set to 0.

The NCP for the measurements was dedicated to the measurement workload activity. Typically, an
NCP is doing other work, and this work should be factored into the capacity requirements for the NCP.

Table 58. 3745 Utilization in Relation to TPS: DDCS for AIX


Throughput (TPS) Bytes per Second 3745 Utilization (%)
24.53 24,105 35
43.67 39,379 58
53.68 47,935 70
57.1 50,922 74

These results can be used to analyze the line capacity requirements between the LAN and the DB2 for
MVS/ESA host system. For these measurements, the connection is through a 4.5 MB channel, which is
underutilized. If this is replaced by a line with a speed of 56 Kb per second or 256 Kb per second, the
throughput is limited.

Appendix B. Performance Benchmark and Capacity Planning 401


Additional measurements using a 3174-61R attached to the LAN with a 56 Kb per second connection to
the 3745 achieved a data throughput rate of approximately 4847 bytes per second (see Figure 192 on
page 402). This is a 69% utilization of the line. At this utilization, the throughput rate reached
approximately 5 TPS. Although the line has more capacity, the increase in transactions per second
begins to level off. For this report, there is not enough information to identify why 69% is the
threshold. It may be due to such factors as message size, hardware constraints, or protocol
constraints. Additional research or measurements are needed to identify the cause.
Note: The 3174 measurements use a DDCS for OS/2 on a PC/500. Although this is different from using
DDCS for AIX on a C10, the results are the same regardless of which type of component is
driving the throughput.

Figure 192. Configuration with 3174: DDCS for AIX

For general consideration


• Assess the line speeds between the LAN and DB2 for MVS/ESA. The throughput is only as
good as the slowest line. Overutilization of any line will result in delays.
• Introducing multiple communications devices (for example, 3745s, bridges, routers) on the
communication path between the LAN and the database introduces delays.
• Tune the NCP definition DELAY parameters. If response time at the client is most important,
set all DELAY values to zero. If CCU is constrained, set the GROUP LNCTL=CA to 0.1 or 0.2;
0.2 will create a greater response time delay than 0.1. The following NCP statements have
DELAY parameters:
PCCU
HOST
GROUP LNCTL=CA

402 Getting Started with DB2 Stored Procedures


B.4.3.2 LAN: Table 59 on page 403 shows the percentage of LAN utilization and byte rate as the
workload is increased. For these measurements, the LAN capacity does not factor in. The 16 Mb LAN
is lightly utilized. Typically, a production environment will have more activity on the LAN. Use these
numbers to analyze the additional load introduced on the LAN due to the mix of transactions used in
this configuration.

For general consideration

Monitor your LAN to make sure it is not being overutilized. Overutilization of the LAN could
introduce delays that degrade database performance.

Table 59. LAN Utilization in Relation to Throughput: DDCS for AIX


Throughput (TPS) Bytes per Second LAN Utilization (%)
24.53 86,985 4.35
43.67 148,656 7.43
53.68 178,345 8.92
57.1 190,265 9.51

B.4.4 DB2 Utilization


The following rate and mix of SQL statements occur when achieving a transaction throughput rate of
57.1 TPS:
• 203 SELECT statements per second
• 159 INSERT statements per second
• 205 UPDATE statements per second
• 11 DELETE statements per second
• 248 OPEN statements per second
• 143 CLOSE statements per second
• 495 FETCH statements per second

Two network flows are involved in each transaction. The first flow calls the stored procedure. The
second flow commits or rolls back the transaction. Locks acquired during stored procedure processing
are held until the commit or rollback is received. These locks are held for the amount of time it takes
to send the stored procedure response back to the client and for the client to process the response
and issue the commit or rollback. DDCS for AIX running at maximum CPU utilization increases this
delay. Delays result in locking contention at DB2 for MVS/ESA.

Secondarily, the average response time accessing 8 of the 16 partitions for Tables T7 and T9 is
reaching levels that have a delaying effect because those partitions reside on slower disk drives
(3380-E).

For general consideration


• When using stored procedures in a client/server environment, tune the database as if the
access is local.

Appendix B. Performance Benchmark and Capacity Planning 403


B.4.5 Transactions
This section describes the transactions and the achieved response time at the PowerBuilder clients in
relation to the aggregate throughput. The response time duration starts when the end user submits
the transaction request—after the network connection is established and the end user has entered the
input data. The duration ends after the commit or rollback command has been issued and all the
response data is available to the end user (visible on the computer monitor).

In this section, graphs depict the point where 90% of the transactions complete within the identified
response time for the identified throughput. Figure 193 shows the aggregate response time of the
transactions for the identified throughput.

Figure 193. Aggregate Response Time: DDCS for AIX

Each procedure described in the subsections that follow performs different operations, which creates
various degrees of contention on the tables. The SQL calls are described for each procedure in the
order they are called. Locking contention is the primary factor for response time degradation, with
access to slower disk drives also becoming a factor.

B.4.5.1 Transaction Tx1: Transaction Tx1 is the most involved of the seven transactions. The
transaction calls a stored procedure that performs write operations against Tables T3, T4, T6, T8, and
T9. The stored procedure performs read operations against Tables T2, T3, T5, T7, and T8.
Index-matching predicates in the WHERE clauses optimize access to all tables. The stored procedure
has two input parameters for a byte count between 22 and 190. There are nine output parameters with
a maximum byte count of 713.

Here is a summary of the SQL calls in the stored procedure and the order in which they occur:
Select
T7
T2
Fetch and Update
T3
Insert
T4
T6
Fetch
T5
Loop up to 15 times
Fetch and Update

404 Getting Started with DB2 Stored Procedures


T8
Insert
T9
End loop

Figure 194 shows the achieved response time for transaction Tx1. The vertical axis represents the
response time as seen by the PowerBuilder clients. The horizontal axis represents the overall
throughput rate for the aggregate of transactions. The solid line represents the point where 90% of the
Tx1 transactions achieved this response time or better.

Figure 194. Response Time for Transaction Tx1: DDCS for AIX

Most Tx1 transactions complete between 1.4 and 2.0 seconds. Transaction Tx1 shows a gradual
response time degradation as the workload increases. This can be attributed to lock contention on
Table T3. Both the Tx3 and Tx6 transactions update Table T3. Transaction Tx1 also inserts Table T9,
and one-half of those rows are resident on slower disk drives. A greater reponse-time degradation
begins at 54 TPS, and this is attributed to CPU constraints on the C10 running DDCS for AIX.

Table 60 shows the transactions that have potential lock contention with transaction Tx1 on the defined
tables.

Table 60. Potential Lock Contention for Transaction Tx1: DDCS for AIX
Table Tx1 Tx2 Tx3 Tx4 Tx5 Tx6 Tx7
T2 Yes
T3 Yes Yes
T4 Yes Yes
T5 Yes
T6 Yes Yes
T7 Yes Yes
T8 Yes
T9 Yes Yes

Appendix B. Performance Benchmark and Capacity Planning 405


B.4.5.2 Transaction Tx2: Transaction Tx2 calls a stored procedure that performs read operations
against Tables T6, T7, and T9. Index-matching predicates in the WHERE clause optimize access to
these tables. The stored procedure has one input parameter with a byte count of 26 and four output
parameters with a maximum byte count of 516.

Here is a summary of the SQL calls in the stored procedure and the order in which they occur:
For 60% of the time:
Select
T7
Loop up to 4 times
Fetch from
T7
End loop
End 60% of the time
Select
T7
T6
Loop up to 15 times
Fetch
T9
End loop

Figure 195 shows the achieved response time for transaction Tx2. The vertical axis represents the
response time as seen by the PowerBuilder clients. The horizontal axis represents the overall
throughput rate for the aggregate of transactions. The solid line represents the point where 90% of the
Tx2 transactions achieved this response time or better.

Figure 195. Response Time for Transaction Tx2: DDCS for AIX

Most Tx2 transactions complete between 1.0 and 1.5 seconds. The response time improvement can be
attributed to the data becoming available in the buffers because of the increased workload.

Table 61 shows the transactions that have potential lock contention with transaction Tx2 on the defined
tables.

Table 61 (Page 1 of 2). Potential Lock Contention for Transaction Tx2: DDCS for AIX
Table Tx1 Tx2 Tx3 Tx4 Tx5 Tx6 Tx7
T6 Yes Yes

406 Getting Started with DB2 Stored Procedures


Table 61 (Page 2 of 2). Potential Lock Contention for Transaction Tx2: DDCS for AIX
Table Tx1 Tx2 Tx3 Tx4 Tx5 Tx6 Tx7
T7 Yes Yes
T9 Yes Yes

B.4.5.3 Transaction Tx3: Transaction Tx3 calls a stored procedure that performs write operations
against Tables T1, T2, T3, and T7. The stored procedure performs read operations against Tables T2,
T3, and T7. Index-matching predicates in the WHERE clauses optimize access to all tables except T1.
The stored procedure has one input parameter for a byte count of 39 and six output parameters with a
maximum byte count of 551.

Here is a summary of the SQL calls in the stored procedure and the order in which they occur:
For 60% of the time
Select
T7
Loop up to 4 times
Fetch from
T7
End loop
End 60% of the time
Fetch and Update
T7
Conditionally Fetch and Update
T2
T3
Insert
T1

Figure 196 shows the achieved response time for transaction Tx3. The vertical axis represents the
response time as seen by the PowerBuilder clients. The horizontal axis represents the overall
throughput rate for the aggregate of transactions. The solid line represents the point where 90% of the
Tx3 transactions achieved this response time or better.

Figure 196. Response Time for Transaction Tx3: DDCS for AIX

Most Tx3 transactions complete between 1 and 1.75 seconds. Transaction Tx3 shows a response time
degradation at 54 TPS. This is attributable to delays introduced by CPU contraint on the C10 running

Appendix B. Performance Benchmark and Capacity Planning 407


DDCS for AIX, which causes delays acquiring exclusive locks on Tables T2, T3, and T7. Both Tables T2
and T3 are small. The Tx7 transaction updates Table T7. The Tx1 transaction updates Table T3 and
reads Tables T2 and T7. The Tx2 transaction reads Table T7.

Table 62 shows the transactions that have potential lock contention with transaction Tx3 on the defined
tables.

Table 62. Potential Lock Contention for Transaction Tx3: DDCS for AIX
Table Tx1 Tx2 Tx3 Tx4 Tx5 Tx6 Tx7
T1 Yes
T2 Yes
T3 Yes Yes
T7 Yes Yes

B.4.5.4 Transaction Tx4: Transaction Tx4 calls a stored procedure that performs a write
operation against T5. Index-matching predicates in the WHERE clause optimize access to this table.
The stored procedure has one input parameter with a byte count of 8 and three output parameters with
a maximum byte count of 99.

Here is the SQL call in the stored procedure:


Update
T5

Figure 197 shows the achieved response time for this transaction. The vertical axis represents the
response time as seen by the PowerBuilder clients. The horizontal axis represents the overall
throughput rate for the aggregate of transactions. The solid line represents the point where 90% of the
Tx4 transactions achieved this response time or better.

Figure 197. Response Time for Transaction Tx4: DDCS for AIX

Most Tx4 transactions complete in less than 1 second. The response time degradation is gradual for
the scope of the measurements. Tx4 updates Table T5, which is 100% preloaded into memory.
Transaction Tx4 runs 1% of the time; therefore, the sampling is low, which can result in sampling
anomalies.

Table 63 on page 409 shows the transaction that has potential lock contention with transaction Tx4 on
the defined tables.

408 Getting Started with DB2 Stored Procedures


Table 63. Potential Lock Contention for Transaction Tx4: DDCS for AIX
Table Tx1 Tx2 Tx3 Tx4 Tx5 Tx6 Tx7
T5 Yes

B.4.5.5 Transaction Tx5: Transaction Tx5 calls a stored procedure that performs read operations
against Table T5. Index-matching predicates in the WHERE clause optimize access to this table. The
stored procedure has one input parameter with a byte count between 8 and 120. It has seven output
parameters with a maximum byte count of 590.

Here is a summary of the SQL calls in the stored procedure and the order in which they occur:
Loop up to 15 times
Select
T5
End loop

Figure 198 shows the achieved response time for this transaction. The vertical axis represents the
response time as seen by the PowerBuilder clients. The horizontal axis represents the overall
throughput rate for the aggregate of transactions. The solid line represents the point where 90% of the
Tx5 transactions achieved this response time or better.

Figure 198. Response Time for Transaction Tx5: DDCS for AIX

The Tx5 transactions complete in less than 1.25 seconds. Tx5 shows a little change in response time.
Table T5 is the only table that Tx5 accesses. There is neither lock contention nor I/O contention
against this table because it is large and 100% loaded into memory.

Table 64 shows the transaction that has potential lock contention with transaction Tx5 on the defined
tables.

Table 64. Potential Lock Contention for Transaction Tx5: DDCS for AIX
Table Tx1 Tx2 Tx3 Tx4 Tx5 Tx6 Tx7
T5 Yes

Appendix B. Performance Benchmark and Capacity Planning 409


B.4.5.6 Transaction Tx6: Transaction Tx6 calls a stored procedure that performs read operations
against Tables T3, T8, and T9. Index-matching predicates in the WHERE clause optimize access to the
tables. The stored procedure has one input parameter with a byte count of 8 and three output
parameters with a maximum byte count of 78.

Here is a summary of the SQL calls in the stored procedure and the order in which they occur:
Select
T3
Select
T8 joined with T9

Figure 199 shows the achieved response time for this transaction. The vertical axis represents the
response time as seen by the PowerBuilder clients. The horizontal axis represents the overall
throughput rate for the aggregate of transactions. The solid line represents the point where 90% of the
Tx6 transactions achieved this response time or better.

Figure 199. Response Time for Transaction Tx6: DDCS for AIX

The Tx6 transactions complete between 0.5 and 1.0 second. Tx6 shows a gradual improvement in
response time until 54 TPS. This is attributable to data becoming available in the buffers as the
workload increases. At 54 TPS the response time degrades. This can be attributed to CPU contraint
on the C10 running DDCS for AIX, which causes locking contention on Table T3. The Tx1 and Tx7
transactions perform updates on Table T3.

Table 65 shows the transactions that have potential lock contention with transaction Tx6 on the defined
tables.

Table 65. Potential Lock Contention for Transaction Tx6: DDCS for AIX
Table Tx1 Tx2 Tx3 Tx4 Tx5 Tx6 Tx7
T3 Yes Yes
T8 Yes
T9 Yes Yes

410 Getting Started with DB2 Stored Procedures


B.4.5.7 Transaction Tx7: Transaction Tx7 calls a stored procedure that performs write operations
against Tables T4, T6, T7, and T9. The stored procedure performs read operations against Tables T4,
T6, and T9. Index-matching predicates in the WHERE clauses optimize access to these large tables.
The stored procedure has one input parameter for a byte count of 6 and three output parameters with
a maximum byte count of 78.

Here is a summary of the SQL calls in the stored procedure and the order in which they occur:
Loop up to 10 times
Fetch and Delete
T4
Fetch and Update
T6
Update
T9
Select
T9
Update
T7
End loop

Figure 200 shows the achieved response time for this transaction. The vertical axis represents the
response time as seen by the PowerBuilder clients. The horizontal axis represents the overall
throughput rate for the aggregate of transactions. The solid line represents the point where 90% of the
Tx7 transactions achieved this response time or better.

Figure 200. Response Time for Transaction Tx7: DDCS for AIX

The Tx7 transactions complete between 0.75 and 2.5 seconds. The spike in response time at 40 TPS
can be attributed to the random sampling that created a sample with lock contention. Because Tx7
runs only 2% of the time, a single sample with contention can have drastic effects on the final
numbers.
Note: Other measurements not included in this report show that the response time of transaction Tx7
gradually degrades as the workload increases. Spikes such as these are not uncommon for
small transaction samples such as those found with Tx7 and Tx4.

Table 66 on page 412 shows the transactions that have potential lock contention with transaction Tx7
on the defined tables.

Appendix B. Performance Benchmark and Capacity Planning 411


Table 66. Potential Lock Contention for Transaction Tx7: DDCS for AIX
Table Tx1 Tx2 Tx3 Tx4 Tx5 Tx6 Tx7
T4 Yes Yes
T6 Yes Yes
T7 Yes Yes
T9 Yes Yes

B.5 Conclusions

This technical report shows the results and analysis of some performance measurements for a
client/server relational database configuration that includes DB2 for MVS/ESA, DDCS for OS/2, DDCS
for AIX, and DB2 CAE for Windows with PowerBuilder. The goal of these measurements was to
provide a sample environment and analysis that will help a customer:
• Assess proposed configurations for acceptable performance.
• Assess performance of current configurations.
• Choose appropriate hardware capacity for a proposed configuration.
• Choose appropriate software programs for a proposed configuration.
• Tune a new or current configuration.

Throughout this appendix, we identify general considerations: information to consider for tuning and
capacity planning analysis. This does not imply that all information is summarized in these general
considerations, because we provide information throughout this appendix that can be of more or less
utility depending on your reference point.

We focus on the use of stored procedures for online transaction processing environments. Network
delays play an important role in how well the environment performs. The use of stored procedures
may reduce the importance of network delays, but does not eliminate them. For example, each
transaction consists of a stored procedure call and a commit (or rollback). This results in two
message roundtrips from the client to the database. After the stored procedure completes, any locks
created remain held until the commit or rollback flows across the wire. Without stored procedures,
locks may be held much longer because there are two roundtrip messages for every SQL statement.

The burden of providing good throughput in a client/server environment falls on several different
people:
• Network designers, to ensure that the network has capacity and that an efficient path exists
between the client and target database.
• Database administrators, to ensure that the target database and gateway operate within capacity
and are tuned for client/server access.
• Application programmers, to ensure that the program is manipulating the database efficiently (for
example, making efficient use of indexes).
• Any administrators of other software programs between the client and the target database (for
example, gateways).

This appendix provides a reasonably tuned client/server database configuration that achieves a certain
level of throughput using a combination of components. Some questions to ask when analyzing this
configuration in terms of your environment are as follows:
• How does the data throughput compare to my environment or proposed environment?
− On the LAN?
− Through DDCS?
− Through the NCP?

412 Getting Started with DB2 Stored Procedures


• How much processor capacity would I need for my environment considering the throughput and
transaction mix (DDCS, DB2 for MVS/ESA, and so on)?
• Is the response time at the clients reasonable, or can I allow worse response time to
accommodate additional clients?
• Considering throughput, how much network line capacity would I need?
• How many network devices are there between the clients and the database?

B.6 Other Sources of Information


• Distributed Relational Database Architecture Connectivity Guide
• DB2 for MVS/ESA Administration Guide
• Administration Guide for Common Servers

Appendix B. Performance Benchmark and Capacity Planning 413


414 Getting Started with DB2 Stored Procedures
Appendix C. DB2 Connect Result Set Study

This appendix is based on one of a series of technical reports dealing with performance prediction and
capacity planning issues for the DB2 family of products operating in a client/server configuration. The
goal of these technical reports is to help the customer:
• Assess proposed configurations for acceptable performance.
• Assess performance of current configurations.
• Choose proper hardware capacity for a proposed configuration.
• Choose the proper software programs for a proposed configuration.
• Tune a new or current configuration.

This appendix is unique because it describes the impacts on the numerous components involved in a
client/server environment as the workload increases in that environment. Use the configuration
reported here as an example that could be analyzed and potentially applied to other configurations.
We describe the throughput, CPU utilization, RAM utilization, LAN utilization and response times when
PowerBuilder clients and OS/2 clients call stored procedures on DB2 to perform Query type
transactions. Use the results from these measurements to predict performance and plan for capacity
in your environment. Particularly noteworthy items are highlighted as general considerations.

C.1 Configuration and Specifications

Figure 201 presents the configuration example discussed in the following sections.

Figure 201. Configuration with DB2 Connect for NT

The configuration is specified as follows:

 Copyright IBM Corp. 1996 1998 415


• DB2 for OS/390 Version 5 running on OS/390 Release 3 with VTAM Version 4.4. The processor is a
9672-R61 (six-way) with 512 MB of main storage and 512 MB of expanded storage. The processor
is attached to a 3172 Model 1 communications controller.
• DB2 Connect for NT Version 5.1 runs on NT Server Version 4.0 with SNA Server 2.11. Several
hardware server configurations are included for comparison. All server configurations contain 512
MB of RAM and have LANStreamer adapter cards. The following hardware server configurations
are included in this appendix:
− PC720 with 4x100 MHz Pentium processors
− PC704 with 4x166 MHz Pentium Pro processors with 512 KB cache
− PC704 with 2x166 MHz Pentium Pro processors with 512 KB cache
− PC704 with 1x166 MHz Pentium Pro processors with 512 KB cache
• 6 - PowerBuilder Version 5.0.2 with DB2 CAE for Windows 95 Version 5.1 clients running on PC350s
with 133 MHz Pentium Processors and 64 MB of memory. The clients contain LANStreamer
adapter cards and are configured to use early token release.
• 2 - 9595 OPT PS/2s with 60 MHz Pentium Processors running OS/2 Version 4.0. These PS/2s are
used to increase the workload in the configuration.
• 16 Mbps Token-Ring LAN

Network protocols in use between the components are as follows:


• TCP/IP is in use between the PowerBuilder clients and DB2 Connect for NT.
• TCP/IP is in use between the OS/2 clients and DB2 Connect for NT.
• LU 6.2 using SNA is in use between DB2 Connect for NT and DB2 for OS/390 Version 5.

The components in this configuration are monitored using the following programs:
• MVS: Resource Measurement Facility (RMF)
• DB2 for OS/390 Version 5: DB2 Accounting and Statistics traces
• NT-provided Performance Monitor program
• PowerBuilder clients: Mercury Winrunner and Loadrunner programs
• OS/2 clients: Internal tools
• LAN: DatagLANce Network Analyzer for Ethernet and Token-Ring for OS/2

C.2 Workload Description

The workload calls stored procedures that return query answer sets. These answer sets provide a
combination of various answer set characteristics, from a few rows to many rows, from a few columns
to many columns. The answer sets are designed to help understand the effects of various answer set
characteristics on DB2 Connect, the network, and the client.

A series of measurements are performed, with each subsequent measurement providing an increased
workload to the configuration. All measurements include six PowerBuilder clients running a
predefined set of transactions in random order without modification for the entire series of
measurements. The PowerBuilder clients provide the end-user perspective of the effects of increasing
the workload in the configuration. The workload is increased each run by increasing the number of
sessions on the two OS/2 workload generators. The OS/2 workload generators run the exact same
transaction mix as the six PowerBuilder clients. The only difference is the management of screen I/O
at the client. The PowerBuilder clients simulate a real application, where the OS/2 workload
generators do not perform screen I/O.

416 Getting Started with DB2 Stored Procedures


C.2.1 Transaction Characteristics
The workload consists of five query transactions that are called in a predefined mix. Each query
consists of a stored procedure that returns an answer set. The stored procedures are written in C and
are defined to commit on return when the stored procedure completes. The commit on return
eliminates the need for the client to issue a commit command at the end of the transaction. This saves
a network message. The five query transactions, a brief description, and the percentage of the mix are
as follows:
• Transaction Qry1_2
Transaction Qry1_2 returns 150 rows with two columns per row. There are 32 character bytes per
row for a total of 4,800 bytes per query. Qry1_2 runs as 24% of the total transaction mix. The SQL
logic in the stored procedure is as follows:

EXEC SQL DECLARE c1 CURSOR WITH RETURN WITH HOLD FOR


SELECT C1, C2 FROM T3
WHERE IX1a = Value1 AND IX1b = Value2
AND IX1c BETWEEN Value3 AND Value4;
EXEC SQL OPEN c1;

• Transaction Qry1_9
Transaction Qry1_9 returns 150 rows with nine columns per row. There are 105 character bytes
per row for a total of 15,750 bytes per query. Qry1_9 runs as 24% of the total transaction mix. The
SQL logic in the stored procedure is as follows:

EXEC SQL DECLARE c1 CURSOR WITH RETURN WITH HOLD FOR


SELECT C1, C2, C3, C4, C5, C6, C7, C8, C9 FROM T3
WHERE IX1a = Value1 AND IX1b = Value2
AND IX1c BETWEEN Value3 AND Value4;
EXEC SQL OPEN c1;
_
• Transaction Qry1_17
Transacton Qry1_17 returns 150 rows with 17 columns per row. There are 11 columns of character
data and 6 columns of numeric data for 167 bytes per row and a total of 25,050 bytes per query.
Qry1_17 runs as 24% of the total transaction mix. The SQL logic in the stored procedure is as
follows:

EXEC SQL DECLARE c1 CURSOR WITH RETURN WITH HOLD FOR


SELECT C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14,
C15, C16, C17 FROM T3
WHERE IX1a = Value1 AND IX1b = Value2
AND IX1c BETWEEN Value3 AND Value4;

EXEC SQL OPEN c1;


_
• Transaction FewRows
Transaction FewRows returns between 5 and 15 rows with one column of character data and 1
column of numeric data for 18 bytes per row and a total of 90 to 270 bytes per query. FewRows
also requires some client arithmetic logic for some of the fields displayed at the client. FewRows
runs as 27% of the total transaction mix. The SQL logic in the stored procedure is as follows:

Appendix C. DB2 Connect Result Set Study 417


EXEC SQL DECLARE c1 CURSOR WITH RETURN WITH HOLD FOR
SELECT C1, C2 FROM T1
WHERE IX1 IN (Values) FOR FETCH ONLY OPTIMIZE FOR 15 ROWS;

EXEC SQL OPEN c1;


_
• Transaction ManyRows
Transaction ManyRows returns 6400 rows with 11 columns of character data and 4 columns of
numeric data for 147 bytes per row and a total of 940,800 bytes per query. ManyRows runs as 1%
of the total transaction mix. The SQL logic in the stored procedure is as follows:

EXEC SQL DECLARE c1 CURSOR WITH RETURN WITH HOLD FOR


SELECT C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15
FROM T3, T2
WHERE IX1 = IX2 AND IX1=Value1 AND IX2 = Value2;
EXEC SQL OPEN c1;
_

C.2.2 Table Characteristics


Before each measurement run, the tables on DB2 for MVS/ESA are put into a consistent state as
defined in Table 67. The table shows the number of rows and length in parentheses, the number of
columns, the number of indexes, and the preload percentage. The preload value is the percentage of
the table that is preloaded into memory buffers prior to the measurement run.

Table 67. Table Characteristics


Table Number of Rows Columns Indexes Preload Value (%)
(Length in Bytes)
T1 100,000 4 1 100
(91)
T2 240,000 8 1 30
(42)
T3 240,000 21 2 30
(679)

C.2.3 Locking Definitions


Type 2 indexes are used for all indexes. Page-level locking is in use for the tables. All packages are
bound with an isolation level of uncommitted read (UR). Tablespace locks are set for use/commit.

C.2.4 Buffer Pool Allocation


The tables and indexes are also spread out to multiple buffer pools, as described in Table 68.
Spreading the tables and indexes out to multiple buffer pools allows for buffer pool tuning based on the
access characteristics of the tables and indexes. See the DB2 Administration Guide for a discussion of
buffer pools.

Table 68 (Page 1 of 2). Buffer Pool Characteristics


Buffer Pool Size Table/Index
BP0 2000 System catalogs and directories

418 Getting Started with DB2 Stored Procedures


Table 68 (Page 2 of 2). Buffer Pool Characteristics
Buffer Pool Size Table/Index
BP2 3000 T1 Table and Index
BP3 10000 T3 Index 1
T3 Index 2
BP4 7000 T2 Index
BP5 10000 T2 Table
BP7 12500 T3 Table
Total 44500

C.3 Results

The next sections describe the results from the measurements. The results are presented in relation
to the overall throughput achieved at each workload level. This is described as transactions per
second (TPS). As the workload increases, the throughput increases. The effects on each component
are then presented, based on the current achieved throughput. For example, when achieving 24
transactions per second:
• The PC704 4X166 running DB2 Connect for NT is 19.90% utilized.
• The 16 Mbps token-ring LAN is 61.83% utilized at a rate of 1,236,541 bytes per second.

C.3.1 Client Equivalence


The configuration includes six PowerBuilder clients and a variable number of OS/2 clients. All clients
run the same query transaction mix, but the PowerBuilder clients present the output data on the
computer screen. This adds to the response time, which in turn decreases the throughput for the
PowerBuilder clients. This section estimates a rough number of total PowerBuilder clients that can be
served, based on the throughput obtained by the OS/2 clients plus the throughput of the actual
PowerBuilder clients.

Table 69 on page 420 describes the number of clients activated to achieve the throughput defined in
column 1. Column 2 describes the number of PowerBuilder clients. This is always six. Column 3
describes the number of OS/2 clients. This is increased by five for each measurement run. Column 4
is the actual number of clients, which is the sum of columns 2 and 3. Column 5 is the estimated
number of PowerBuilder clients. This column is derived by evaluating the number of equivalent
PowerBuilder clients each OS/2 client represents in terms of throughput. The equation for evaluating
this is:

---- ----
| |
| OS/2 client tps |
Estimated PowerBuilder Clients = |-------------------------- * (# OS/2 clients)| + (# PowerBuilder clients)
| PowerBuilder client tps |
| |
---- ----

If
OS/2 client tps = 2.630 tps
PowerBuilder client tps = 0.146 tps
# OS/2 clients = 5
# PowerBuilder clients = 6
then

---- ----
| |

Appendix C. DB2 Connect Result Set Study 419


| 2.630 tps |
Estimated PowerBuilder Clients = |----------- * 5 clients | + (6 clients)
| 0.146 tps |
| |
---- ----

= 96 clients

Table 69. Number of Clients in Relation to Aggregate Throughput (TPS)


Throughput (TPS) PowerBuilder OS/2 Clients Actual Clients Est. PowerBuilder
Clients Clients
16.05 6 5 11 105
21.77 6 10 16 148
24.15 6 15 21 166

The values obtained in these measurements are obtained based on the actual number of clients as
reflected in column 4. When evaluating the estimated number of PowerBuilder clients, other capacity
planning factors need to be addressed. For example, DB2 for OS/390 Version 5 can handle up to
25,000 connected threads, with up to 1,999 simultaneously active threads, and each client that passes
through DB2 Connect for NT and OS/2 should be allowed approximately 200 KB of RAM on DB2
Connect. These factors need to be taken into consideration when designing a configuration. One last
point on the number of clients. These numbers are based on the clients running without a think time.
So if this aspect is factored in, the actual number of clients could be increased to fill the capacity left
available due to the think time.

C.3.2 CPU Utilization


This section describes CPU utilization comparisons between the different hardware configurations that
run DB2 Connect for NT. Table 70 and Figure 202 on page 421 describe the CPU utilization.

Table 70. CPU Utilization in Relation to TPS


Throughput PC704 (1X166) PC720 (4X100) PC704 (2X166) PC704 (4X166) 9672-R61
(TPS)
14.31 45.61% 24.49%
15.07 33.77% 26.29%
16.00 26.37% 27.23%
16.05 13.02% 27.52%
19.12 60.59% 33.21%
20.93 48.10% 36.78%
21.35 67.87% 37.57%
21.54 35.69% 37.39%
21.77 17.78% 37.30%
23.31 54.74% 41.38%
23.75 39.45% 41.01%
24.14 19.90% 41.72%

In Figure 202 on page 421, the solid line represents the CPU utilization of the PC704 four-processor
configuration. The dotted line represents the PC704 two-processor configuration. The dotted/dashed
line represents the PC704 single-processor configuration, and the dashed line represents the PC720
four-processor configuration. The 9672-R61 (not shown in Figure 202 on page 421) reached a 41.72%
utilization at the maximum throughput of 24.14 transactions per second.

420 Getting Started with DB2 Stored Procedures


Figure 202. CPU Utilization in Relation to Throughput - DB2 Connect for NT

Legend:
Solid line - PC704 4X166
Dot line - PC704 2X166
Dot/Dash line - PC704 1X166
Dash - PC720 4X100

For general consideration


• The more processors available on the hardware, the greater the capacity for DB2 Connect.
• DB2 Connect should run on a fast processor. A two-processor machine is significantly faster
than a one-processor machine of the same processor speed. A four-processor machine is
marginally faster than a two-processor machine. Consider upgrading from two to four
processors if capacity is the goal, not speed. For these measurements, the network
configuration (for example, 3172, 16 Mbps LAN) runs out of capacity before a four-processor
machine is fully utilized.
• DB2 Connect should run with enough memory to handle the number of expected clients. Plan
for 200 KB for each client passing through DB2 Connect for NT and OS/2. The base level of
RAM should be based on the number of applications and RAM requirements for those
applications. It is suggested that DB2 Connect is the only application running on the machine.
• Hard disk capacity is not an issue for DB2 Connect because the processing does not require
high disk capacity.

Appendix C. DB2 Connect Result Set Study 421


C.3.3 Network

The network plays a big part in how well the client/server application will perform, and how big an
effect the client/server applications will have on the performance of the database. Delay is the biggest
enemy. How big a role delay plays depends on the application. Every time a trip across the network
is required, locks (if locks are held) are held for the time it takes the messages to move between the
client and the database. If the transaction includes many SQL statements, then the client will wait for
every SQL statement to traverse the network, assuming this is not a stored procedure or compound
SQL. For these measurements, overall network bandwidth is very important because large amounts of
data are moving through the network. Bandwidth through the 3172 Model 1 is the factor that prevents
additional throughput.

This section describes the effects on the 3172 Model 1 and LAN during the measurements. For this
mix of transactions, the message lengths are large, so the following values are set:
• 4 KB RUSIZEs in VTAM
• 32 KB RQRIOBLK definition in DB2 Connect for NT
• 32 KB RQRIOBLK definitions in the OS/2 clients
• 32 KB RQRIOBLK definitions in the Win95 Clients

C.3.3.1 3172 Model 1: The 3172 Model 1 is fully utilized for these measurements. This model of
3172 uses older technology. Follow-on 3172 models will provide greater bandwidth and speed. The
3172 Model 1 has a delay parameter that must be turned off.

For general consideration


• Assess the line speeds between the LAN and DB2 for MVS. The throughput is only as good as
the slowest line. Over-utilizing any line will result in delays.
• Introducing multiple communications devices (such as 3745s, Bridges, Routers) on the
communication path between the client and the database introduces delays.

C.3.3.2 LAN: Table 71 shows the percentage of LAN utilization and byte rate as the workload is
increased. Notice that query answer set transactions impose a much greater demand on LAN capacity
than OLTP type transactions. The 16 Mbps LAN is over 50% utilized at the higher transaction rate.

Table 71. LAN Utilization in Relation to TPS


Throughput (TPS) Bytes per Second % LAN Utilization
16.05 831,054 41.55
21.77 1,105,883 55.29
24.14 1,236,541 61.83

For general consideration

Monitor your LAN to make sure it is not being overutilized. This is especially true for transactions
that return large answer sets. Overutilization of the LAN could introduce delays that degrade
database performance.

422 Getting Started with DB2 Stored Procedures


C.3.4 Transactions
We next describe the achieved response time at the PowerBuilder clients in relation to the aggregate
throughput. Response time starts when the end user submits the transaction request. This occurs
after the network connection is established and the end user has entered the input data. The response
time ends after all the response data is available to the end user (visible on the computer monitor).

In this section, graphs depict the point where 90% of the transactions complete within the identified
maximum response time for the identified throughput. Since this is the 90th percentile, this is an
indication of the greatest response time when sampling the fastest 90% of the transactions. Most
transactions achieve a better response time.

Figure 203 through Figure 208 on page 428 describe the achieved response time for the transactions.
The vertical axis represents the response time as seen by the PowerBuilder clients. The horizontal
axis represents the overall throughput rate for the aggregate of transactions. The solid line represents
the point where 90% of the specified transaction achieves this response time or better.

C.3.4.1 Transaction FEWROWS

Figure 203. Response Time for Transaction FEWROWS

Legend:
Solid line - PC704 4X166
Dot line - PC704 2X166
Dot/Dash line - PC704 1X166
Dash - PC720 4X100

The maximum response time for 90% of the FEWROWS transactions is between 0.61 and 0.88 second
on the four-processor PC704 as the workload increases. The standard deviation is between 0.06 and
0.10. The transaction response times for the other multiprocessor configurations are moderately

Appendix C. DB2 Connect Result Set Study 423


degraded, with the single-processor configuration achieving the longest response times (0.66 to 0.99
second, a standard deviation of 0.07 to 0.13).

C.3.4.2 Transaction MANYROWS

Figure 204. Response Time for Transaction MANYROWS

Legend:
Solid line - PC704 4X166
Dot line - PC704 2X166
Dot/Dash line - PC704 1X166
Dash - PC720 4X100

The maximum response time for 90% of the MANYROWS transactions is between 8.35 and 12.47
seconds on the four-processor PC704 as the workload increases. The standard deviation is between
0.28 and 0.95. The transaction response times for the other multiprocessor configurations are
moderately degraded, with the single-processor configuration achieving the longest response times
(9.45 to 13.29 seconds, a standard deviation of 0.34 to 1.32).

C.3.4.3 Transaction Qry1_2

424 Getting Started with DB2 Stored Procedures


Figure 205. Response Time for Transaction Qry1_2

Legend:
Solid line - PC704 4X166
Dot line - PC704 2X166
Dot/Dash line - PC704 1X166
Dash - PC720 4X100

The maximum response time for 90% of the Qry1_2 transactions is between 0.72 and 0.99 second on
the four-processor PC704 as the workload increases. The standard deviation is between 0.07 and 0.10.
The transaction response times for the other multiprocessor configurations are moderately degraded,
with the single-processor configuration achieving the longest response times (0.82 to 1.10 seconds, a
standard deviation of 0.08 to 0.13).

C.3.4.4 Transaction Qry1_9

Appendix C. DB2 Connect Result Set Study 425


Figure 206. Response Time for Transaction Qry1_9

Legend:
Solid line - PC704 4X166
Dot line - PC704 2X166
Dot/Dash line - PC704 1X166
Dash - PC720 4X100

The maximum response time for 90% of the Qry1_9 transactions is between 0.83 and 1.10 seconds on
the four-processor PC704 as the workload increases. The standard deviation is between 0.08 and 0.11.
The transaction response times for the other multiprocessor configurations are moderately degraded,
with the single-processor configuration achieving the longest response times (0.93 to 1.21 seconds, a
standard deviation of 0.09 to 0.12).

C.3.4.5 Transaction Qry1_17

426 Getting Started with DB2 Stored Procedures


Figure 207. Response Time for Transaction Qry1_17

Legend:
Solid line - PC704 4X166
Dot line - PC704 2X166
Dot/Dash line - PC704 1X166
Dash - PC720 4X100

The maximum response time for 90% of the Qry1_17 transactions is between 0.93 and 1.21 seconds on
the four-processor PC704 as the workload increases. The standard deviation is between 0.07 and 0.11.
The transaction response times for the other multiprocessor configurations are moderately degraded,
with the single-processor configuration achieving the longest response times (0.99 to 1.31 seconds, a
standard deviation of 0.09 to 0.12).

C.3.4.6 Transaction Comparison

Appendix C. DB2 Connect Result Set Study 427


Figure 208. Response Time Comparison (Qry1_2, Qry1_9, Qry1_17)

Legend:
Solid line - Qry1_2
Dot line - Qry1_9
Dash - Qry1_17

Figure 208 displays the response time differences between transactions Qry1_2, Qry1_9, and Qry1_17.
These transactions return the same number of rows from the same table. The only difference is the
number of columns. As expected, the response time increases as the number of columns increases.

C.4 DB2 Connect Environment Tuning

Many factors are involved in achieving a well-performing environment for your application. These
factors are:
• Client
• DB2 Connect
• Network
− LAN
− WAN
This section will describe these factors and what you can do to tune them. However, because the
potential variations in the environments are so numerous, not all the listed suggestions may be
appropriate for your environment, nor do we list all possible performance enhancements.

428 Getting Started with DB2 Stored Procedures


C.4.1 Client
The client machine plays a role in how well the application will perform. The following software
settings are a factor in performance:
• RQRIOBLK - The RQRIOBLK value for the DB2 CAE should be set to 32,767 bytes. This is most
important when retrieving large numbers of answer set rows.
• Maximum Transmission Unit (MTU) - The MTU value in TCP/IP should be set to the maximum
allowed by the installed TCP/IP. For Ethernet LANs, this is 1500 and for Token-Ring LANs it is 4400.
• DB2CLI.INI file - For ODBC/CLI applications, settings in the DB2CLI.INI can have an effect on
performance. Listed below are the recommended settings, although some of these may need to be
set differently for your application:
− DeferredPrepare=1
Offers major performance gain. Combines line flows.
− AutoCommit=0
If you turn autocommit off, your program is responsible for issuing commits. It is better to have
a few strategicically placed commits in your program than to commit every SQL call, as is the
case when autocommit is turned on. Turning off autocommit can bring a major performance
gain.
− EarlyClose=1
Offers a minor performance gain. Allows DDCS to close cursors at the end of result sets.
Offers most benefits for sets with many small queries.
− CursorHold=0
Provides minor to moderate performance gain. Between transactions, closes those cursors not
held.
− KeepConnect=1
Provides minor to moderate performance gain. Caches connection data for applications that
connect and disconnect often.
− DB2Degree=any
Provides minor to moderate performance gain. Lets the database decide what level of
parallelism should be used for queries.
− OptimizeForNRows=5000
Can provide a good performance gain as long as the value is greater than the number of rows
for most of your queries.
− TXNISOLATION=2
Provides moderate to major performance gain. This uses isolation-level cursor stability.
The following hardware is a factor in performance:
• Processor Power - The faster the processor, the faster the client machine will process application
code as well as sending and receiving data.
• Memory - Memory can be one of the biggest factors that can make or break performance. Use a
minimum of 32 MB, with 64 MB a better amount. This is not to say that a machine will run with
less, but with the number of applications and the capabilities today, memory demands are
constantly increasing. You do not want to get into the mode where frequent paging is needed due
to lack of memory.

Appendix C. DB2 Connect Result Set Study 429


• LAN Adapter Card - Getting the data on and off the LAN quickly is the goal. Look for fast LAN
adapter cards and make sure you set up the buffers in that card to handle a large amount of data.
You should consider setting these buffers up to the maximum.
• Video Card - The speed with which your application can paint your monitor screen is also a factor.

C.4.2 DB2 Connect


The following software settings affect performance:
• RQRIOBLK - The RQRIOBLK value for the DB2 Connect should be set to 32,767. This is most
important when retrieving large numbers of answer set rows.
• Mode Table Settings - Set the send and receive pacing values to 16.
Set the send and receive RU size to match the RU size at the host. Recommended value is 4096.
• SNA DLC Settings - The Send Frame value should be set at 7. The Receive Frame value should be
set at 2 for 3172s and at 4 for NCP and OSA.
The Max BTU value should be set at 16393.
• Maximum Transmission Unit (MTU) - The MTU value in TCP/IP should be set to the maximum
allowed by the installed TCP/IP. For Ethernet LANs, this is 1500 and for Token-Ring LANs it is 4400.

Hardware plays a large role in how well DB2 Connect will work. The following hardware features are
important:
• Processor Power and SPECint
Processor speed with high SPECint values is very important for DB2 Connect performance.
Consider an SMP system for the best performance. The greater the number of processors, the
greater the capacity. Enclosed below are some SPECint_base95 values obtained from the SPEC
Web page (http://www.specbench.org/osg/cpu95/results/cint95.html):

Intel Processors PC SPECint_base95

Pentium II Processor 300 MHz 11.60


Pentium II Processor 266 MHz 10.80
Pentium II Processor 266 MHz(w/ECC memory) 10.40
Pentium II Processor 233 MHz 9.49

Pentium Pro Processor 200 MHz 8.20


Pentium Pro Processor 180 MHz 7.28
Pentium Pro Processor 150 MHz 6.25

Pentium Processor 200 MHz MMX 6.41


Pentium Processor 166 MHz MMX 5.59

Pentium Processor 200 MHz 5.00


Pentium Processor 166 MHz 4.52
Pentium Processor 150 MHz 4.05
Pentium Processor 133 MHz 3.96
Pentium Processor 120 MHz 3.55
Pentium Processor 100 MHz 3.20
Pentium Processor 90 MHz 2.88
Pentium Processor 75 MHz 2.39

430 Getting Started with DB2 Stored Procedures


• Memory — Memory is very important for DB2 Connect performance. Paging must be avoided.
Allow for about 200 KB of RAM for each client that uses DB2 Connect. Consider 64 MB of RAM as
a minimum value for DB2 Connect on NT or OS/2. Increase the amount of RAM as the number of
clients increases, or if paging occurs.
• LAN Adapter card - Getting the data on and off the LAN quickly is the goal. Look for fast LAN
adapter cards and make sure you set up the buffers in those cards to handle a large amount of
data. You should consider setting these buffers up to the maximum.

C.4.3 Network
Ignoring the run-time characteristics of the transaction, network time is where the majority of the time
is spent in a transaction. The biggest performance gains can be here. In addition to network
parameter values suggested on the DB2 Connect and the client, the next sections describe additional
considerations.

C.4.3.1 LAN: The LAN portion of your network connectivity is generally faster than the WAN
portion. Overutilization of the LAN and the devices (Bridges/Routers) will have an effect.
Retransmissions as a result of LAN congestion or other causes are common. Retransmissions are
very expensive in regards to response time:
• Ethernet tends to have congestion problems when approaching 50% LAN utilization.
• Token-Ring can operate up to 75% to 100% LAN utilization, depending on the type of workload.
Bulk transfer transactions get the higher utilization. For best performance, enable early token
release.
• Bridges and Routers - Bridges generally operate at media speed and therefore create little latency
unless the bridge is overutilized. An overutilized bridge will result in delays. Routers provide
more logic, thus increasing the latency. If a client needs to cross many routers to access the
database, the latency will add up and increase the potential for retransmit conditions.

C.4.3.2 WAN: The WAN portion of the network is generally where the majority of time is spent.
Performance can be affected by the type of devices as well as how those devices are configured. The
following are some typical connectivity solutions:
• 3745 - LAN attached (TIC) provides medium to high throughput, depending on the TIC type and 3745
model. 3745s are also used for connections over long distance by connecting between two 3745s.
The line speed of the connection between the 3745s should be as fast as possible to provide the
best response time.
• OSA - The mainframe is directly connected to the LAN, which provides very high throughput.
• 3172 - This can provide LAN/channel-attached capabilities as well as ″3172 to 3172″ attached
capabilities for long distance. The LAN/channel-attached setup provides very high throughput,
while throughput of the 3172 to 3172 configuration depends on the line speed connecting the two.
• ESCON - This is a channel-attached solution where DB2 Connect is directly channel attached to the
mainframe. It does not require DB2 Connect traffic to traverse the LAN, as does an OSA, 3172, or
3745 solution. This solution provides very high throughput with multipath channel (MPC ) support
providing the best throughput.

The configuration parameters for these devices, VTAM, and TCP/IP have large to small effects on
response time, dependent on the parameter. Listed below are some of these parameters. They are
not all valid in all configurations. These are parameters to look at in terms of your configuration:
• DELAY - Most devices have one or more DELAY parameters that can be set. This parameter has
severe performance implications since the network message can be held up on route to and from
the client. This has a direct effect on response time, so it should be set to zero in all cases.

Appendix C. DB2 Connect Result Set Study 431


Watch out for defaults, as the default values tend to be other than zero. For 3745 connectivity,
there are two definitions that contain DELAY parameters: the PCCU and the LNCTL=CA. The
PCCU is most important. Note also that in some configurations, the PCCU macro is replaced by a
PU definition.
• MAXOUT (VTAM PU) - Should be set to 7.
• PASSLIM (VTAM PU) - Should be set to 7.
• MAXDATA (VTAM definition) - This value should be set large enough to contain the largest PIU. If
set to 33,100, it would be large enough to handle RUs up to 32 KB.
• VPACING (VTAM APPL) - Should be set to 16.
• MAXTSL (NCP LINE) - If connecting through a 3745 TIC, set MAXTSL to 16,732.
• MAXBFRU (VTAM definition) - Make sure this is large enough to avoid slowdown conditions.

C.5 Conclusions

This appendix shows the results and analysis of some performance measurements for a client/server
relational database configuration that includes DB2 for MVS/ESA, DB2 Connect for NT, and
DB2/CAE/Windows with PowerBuilder. The goal of these measurements is to provide an example
environment and analysis that will help a customer:

• Assess proposed configurations for acceptable performance.


• Assess performance of current configurations.
• Choose proper hardware capacity for a proposed configuration.
• Choose the proper software programs for a proposed configuration.
• Tune a new or current configuration.

Throughout this appendix, general considerations are identified. This information is especially
identified as for you to consider in tuning and capacity planning analyses. This does not imply that all
information is summarized in these general considerations, because information throughout this
appendix can be of use, depeinding upon the analyst′s reference point.

This report focuses on the use of stored procedures for query-transaction processing environments.
Network delays, network bandwidth, and gateway speed play an important role in how well such an
environment performs. This is because of the large amount of data that is typically returned for these
transactions. The use of stored procedures helps speed up this process by eliminating some of the
line flows back and forth between the client and server.

The burden of providing good throughput in a client/server environment falls on several different
people:
• Network designers, to make sure the network has capacity and an efficient path exists between the
client and target database.
• Database administrators, to make sure the target database and gateway (DB2 Connect) is
operating within capacity and tuned for client/server access.
• Application programmers, to make sure the program is manipulating the database efficiently (for
example, use of indexes).
• Any other administrators of software programs between the client and the target database (for
example, gateways).

432 Getting Started with DB2 Stored Procedures


The importance of this appendix is that it provides a reasonably tuned client/server database
configuration that achieves a useful level of throughput using a combination of components. Some
questions to ask applying the information in this appendix to your environment are the following:
• How does the data throughput compare to my environment or proposed environment?
− On the LAN?
− Through DB2 Connect?
• How much processor capacity would I need for my environment considering the throughput and
transaction mix? DB2 Connect? DB2? Other?
• Is the response time at the clients reasonable, or can I accept greater response time to
accommodate additional clients?
• How much network line capacity would I need considering throughput?
• How many network devices are between the clients and the database?

C.6 Other Sources of Information


• DRDA Connectivity Guide SC26-4783
• DB2 For OS/390 Version 5 Administration Guide
• DB2 Administration Guide For Common Server V5

Appendix C. DB2 Connect Result Set Study 433


434 Getting Started with DB2 Stored Procedures
Appendix D. Special Notices

This publication is intended to help database administrators implement DB2 stored procedures in a
client/server environment. The information in this publication is not intended as the specification of
any programming interfaces that are provided by the DB2 family of products. See the PUBLICATIONS
section of the IBM Programming Announcement for the current level of the products listed below for
more information on the formal product documentation:
• ACF/VTAM
• AIX
• AIX/6000
• CICS/ESA
• CODE/370
• DB2 for MVS/ESA
• DB2 Server for OS/390
• DB2 for OS/2
• DB2 for OS/400
• DB2 for AIX
• DDCS for OS/2
• DDCS for AIX
• DB2 Connect for OS/2
• DB2 Connect for AIX
• DB2 Connect for Windows NT
• DB2 Connect for Windows 95
• IMS/ESA
• LE/370
• MVS/ESA
• OS/390

References in this publication to IBM products, programs or services do not imply that IBM intends to
make these available in all countries in which IBM operates. Any reference to an IBM product,
program, or service is not intended to state or imply that only IBM′s product, program, or service may
be used. Any functionally equivalent program that does not infringe any of IBM′s intellectual property
rights may be used instead of the IBM product, program or service.

Information in this book was developed in conjunction with use of the equipment specified, and is
limited in application to those specific hardware and software products and levels.

IBM may have patents or pending patent applications covering subject matter in this document. The
furnishing of this document does not give you any license to these patents. You can send license
inquiries, in writing, to the IBM Director of Licensing, IBM Corporation, 500 Columbus Avenue,
Thornwood, NY 10594 USA.

Licensees of this program who wish to have information about it for the purpose of enabling: (i) the
exchange of information between independently created programs and other programs (including this
one) and (ii) the mutual use of the information which has been exchanged, should contact IBM
Corporation, Dept. 600A, Mail Drop 1329, Somers, NY 10589 USA.

Such information may be available, subject to appropriate terms and conditions, including in some
cases, payment of a fee.

The information contained in this document has not been submitted to any formal IBM test and is
distributed AS IS. The information about non-IBM (″vendor″) products in this manual has been
supplied by the vendor and IBM assumes no responsibility for its accuracy or completeness. The use
of this information or the implementation of any of these techniques is a customer responsibility and

 Copyright IBM Corp. 1996 1998 435


depends on the customer′s ability to evaluate and integrate them into the customer′s operational
environment. While each item may have been reviewed by IBM for accuracy in a specific situation,
there is no guarantee that the same or similar results will be obtained elsewhere. Customers
attempting to adapt these techniques to their own environments do so at their own risk.

Any performance data contained in this document was determined in a controlled environment, and
therefore, the results that may be obtained in other operating environments may vary significantly.
Users of this document should verify the applicable data for their specific environment.

The following document contains examples of data and reports used in daily business operations. To
illustrate them as completely as possible, the examples contain the names of individuals, companies,
brands, and products. All of these names are fictitious and any similarity to the names and addresses
used by an actual business enterprise is entirely coincidental.

Reference to PTF numbers that have not been released through the normal distribution process does
not imply general availability. The purpose of including these reference numbers is to alert IBM
customers to specific information relative to the implementation of the PTF when it becomes available
to each customer according to the normal IBM PTF distribution process.

The following terms are trademarks of the International Business Machines Corporation in the United
States and/or other countries:

DB2 MVS/ESA
OS/2 AIX
IBM Distributed Relational Database Architecture
DRDA ACF/VTAM
AIX/6000 CICS/ESA
OS/400 IMS/ESA
SAA AD/Cycle
C/370 Language Environment
RISC System/6000 ES/9000
PowerPC PS/2
CICS IMS
RACF SP
VisualGen SP1
400 VisualAge
DATABASE 2 AT
COBOL/370 Presentation Manager
VTAM LANStreamer
PowerPC 601 Resource Measurement Facility
RMF DatagLANce
PROFS

The following terms are trademarks of other companies:

C-bus is a trademark of Corollary, Inc.

Java and HotJava are trademarks of Sun Microsystems, Incorporated.

Microsoft, Windows, Windows NT, and the Windows 95 logo are trademarks
or registered trademarks of Microsoft Corporation.

PC Direct is a trademark of Ziff Communications Company and is used


by IBM Corporation under license.

Pentium, MMX, ProShare, LANDesk, and ActionMedia are trademarks or


registered trademarks of Intel Corporation in the U.S. and other
countries.

436 Getting Started with DB2 Stored Procedures


UNIX is a registered trademark in the United States and other
countries licensed exclusively through X/Open Company Limited.

Other company, product, and service names may be trademarks or


service marks of others.

Other trademarks are trademarks of their respective companies.

Appendix D. Special Notices 437


438 Getting Started with DB2 Stored Procedures
Appendix E. Related Publications

The publications listed in this section are considered particularly suitable for a more detailed
discussion of the topics covered in this redbook.

E.1 International Technical Support Organization Publications

For information on ordering these ITSO publications see “How to Get ITSO Redbooks” on page 443.
• Distributed Relational Database Architecture Connectivity Guide , SC26-4783
• DRDA Security Considerations , GG24-2500-00
• WOW! DRDA Supports TCP/IP: DB2 Server for OS/390 and DB2 Universal Database , SG24-2212-00

E.2 Redbooks on CD-ROMs

Redbooks are also available on CD-ROMs. Order a subscription and receive updates 2-4 times a year
at significant savings.

CD-ROM Title Subscription Collection Kit


Number Number
System/390 Redbooks Collection SBOF-7201 SK2T-2177
Networking and Systems Management Redbooks Collection SBOF-7370 SK2T-6022
Transaction Processing and Data Management Redbook SBOF-7240 SK2T-8038
Lotus Redbooks Collection SBOF-6899 SK2T-8039
Tivoli Redbooks Collection SBOF-6898 SK2T-8044
AS/400 Redbooks Collection SBOF-7270 SK2T-2849
RS/6000 Redbooks Collection (HTML, BkMgr) SBOF-7230 SK2T-8040
RS/6000 Redbooks Collection (PostScript) SBOF-7205 SK2T-8041
RS/6000 Redbooks Collection (PDF Format) SBOF-8700 SK2T-8043
Application Development Redbooks Collection SBOF-7290 SK2T-8037

E.3 Other Publications

These publications are also relevant as further information sources:


• DB2 UDB Administration Getting Started , S10J-8154-00
• Administration Guide for Common Servers , S20H-4580-01
• DB2 UDB Administration Guide Version 5 , S10J-8157-00
• DB2 UDB API Reference Version 5 , S10J-8167-00
• Application Programming Guide for Common Servers , S20H-4643-01
• Building Applications for UNIX Environments , S10J-8161-00
• Building Applications for Windows and OS/2 Environments , S10J-8160-00
• Call Level Interface Guide and Reference for Common Servers , S20H-4644-01
• CODE/370 Debug Tool Manual , SC09-1623-01
• CODE/370 General Information Manual , GC09-2048-00
• CODE/370 Installation Manual , SC09-1624-03
• Command Reference for Common Servers , S20H-4645-01
• DB2 UDB Command Reference Version 5 , S10J-8166-00

 Copyright IBM Corp. 1996 1998 439


• DB2 API Reference for Common Servers , S20H-4984-01
• DB2 Connect Enterprise Edition Quick Beginnings , S10J-7888-00
• DB2 Connect Personal Edition Quick Beginnings , S10J-8162-00
• DB2 Connect User ′ s Guide , S10J-8163-00
• DB2 Extended Enterprise Edition Quick Beginnings , S72H-9620-00
• DB2 for MVS/ESA Administration Guide , SC26-3265-00
• DB2 for MVS/ESA Application Programming and SQL Guide , SC26-3266-00
• DB2 for MVS/ESA Command Reference , SC26-3267-00
• DB2 for MVS/ESA Installation Guide , SC26-3456-00
• DB2 for MVS/ESA SQL Reference Manual , SC26-3270-00
• DB2 for OS/390 Version 5 Administration Guide , SC26-8957-00
• DB2 for OS/390 Version 5 Application Programming and SQL Guide , SC26-8958-00
• DB2 for OS/390 Version 5 Call Level Interface Guide and Reference , SC26-8959-00
• DB2 for OS/390 Version 5 Command Reference , SC26-8960-99
• DB2 for OS/390 Version 5 Data Sharing Planning and Administration , SC26-8961-00
• DB2 for OS/390 Version 5 Installation Guide , GC26-8970
• DB2 for OS/390 Version 5 Messages and Codes , SC26-8979
• DB2 for OS/390 Version 5 Release Guide , SC26-8965-01
• DB2 for OS/390 Version 5 SQL Reference , SC26-8966-00
• DB2 for OS/390 Version 5 Utility Guide and Reference , SC26-8967-00
• DB2 for OS/390 Version 5 What ′ s New? , GC26-8971-00
• DB2 Personal Edition Quick Beginnings , S10J-8150-00
• DB2 SDK for Macintosh Building Your Applications , S50H-0528-00
• DB2 SDK for SCO Open Server Building Your Applications , S89H-3242-00
• DB2 SDK for Silicon Graphics IRIX Building Your Applications ,S89H-4032-00
• DB2 SDK for SINIX Building Your Applications , S50H-0530-00
• DB2 UDB V5 Administration Guide , S10J-8157-00
• DB2 UDB V5 Call Level Interface Guide and Reference , S10J-8159-00
• Distributed Relational Database Architecture Connectivity Guide , SC26-4783
• DB2 UDB Embedded SQL Programming Guide , S10J-8158-00
• External CICS Interface Manual , SC33-1390-01
• IBM VisualAge for Basic Data Access Guide , SC26-8692-01
• IBM VisualAge for Basic Getting Started , GC26-8926-01
• IBM VisualAge for Basic Language Reference , SC26-8693-00
• IBM VisualAge for Basic Programming Guide , SC26-8833-01
• IMS/ESA: Installation Volume 1: Installation and Verification , SC26-8023-00
• Installing and Using DB2 Client for Windows , S33H-0313-01
• DB2 UDB Master Index , S10J-8170-00

440 Getting Started with DB2 Stored Procedures


• OS/390 V2R4 MVS System Messages , GC28-1784-03
• DB2 UDB Message Reference , S10J-8168-00
• DB2 UDB Microsoft ODBC specification , S10J-8159-00
• MVS/ESA SP V5 Planning: APPC Management , GC28-1503-01
• OS/390 MVS Programming: Assembler Services Reference , GC28-1910-00
• OS/390 MVS Programming: Resource Recovery , GC28-1739-01
• OS/390 MVS Setting Up a Sysplex , GC28-1779-03
• OS/390 MVS Workload Management Services , GC28-1773
• OS/390 MVS Writing TPs for APPC/MVS , GC28-1775-02
• OS/390 V1R3.0 MVS Planning: Workload Management , GC28-1761-03
• OS/390: C/C++ IBM Open Class Library User ′ s Guide , SC09-2363-02
• O S / 3 9 0 : C / C + + U s e r ′ s Guide , SC09-2361-02
• OS/390: OpenEdition Command Reference , SC28-1892-03
• OS/390: TSO/E REXX Reference , SC28-1975-01
• Quick Beginnings for OS/2 , S10J-8147-00
• Quick Beginnings for UNIX , S10J-8148-00
• Quick Beginnings for Windows NT , S10J-8149-00
• Replication Guide and Reference , S95H-0999-00
• Resource Definition Guide , SC33-1166-01
• DB2 UDB Road Map to DB2 Programming , S10J-8155-00
• DB2 UDB SQL Getting Started , S10J-8156-00
• SQL Reference for Common Servers , S20H-4665-01
• DB2 UDB SQL Reference , S10J-8165-00
• DB2 UDB System Monitor Guide and Reference , S10J-8164-00
• DB2 UDB Troubleshooting Guide , S10J-8169-00
• Visual PL/I for OS/2 , GC26-9180-00
• PowerBuilder Getting Started .

Appendix E. Related Publications 441


442 Getting Started with DB2 Stored Procedures
How to Get ITSO Redbooks
This section explains how both customers and IBM employees can find out about ITSO redbooks, CD-ROMs,
workshops, and residencies. A form for ordering books and CD-ROMs is also provided.

This information was current at the time of publication, but is continually subject to change. The latest
information may be found at http://www.redbooks.ibm.com.

How IBM Employees Can Get ITSO Redbooks


Employees may request ITSO deliverables (redbooks, BookManager BOOKs, and CD-ROMs) and information about
redbooks, workshops, and residencies in the following ways:
• PUBORDER — to order hardcopies in United States
• GOPHER link to the Internet - type GOPHER.WTSCPOK.ITSO.IBM.COM
• Tools disks
To get LIST3820s of redbooks, type one of the following commands:
TOOLS SENDTO EHONE4 TOOLS2 REDPRINT GET SG24xxxx PACKAGE
TOOLS SENDTO CANVM2 TOOLS REDPRINT GET SG24xxxx PACKAGE (Canadian users only)
To get BookManager BOOKs of redbooks, type the following command:
TOOLCAT REDBOOKS
To get lists of redbooks, type one of the following commands:
TOOLS SENDTO USDIST MKTTOOLS MKTTOOLS GET ITSOCAT TXT
TOOLS SENDTO USDIST MKTTOOLS MKTTOOLS GET LISTSERV PACKAGE
To register for information on workshops, residencies, and redbooks, type the following command:
TOOLS SENDTO WTSCPOK TOOLS ZDISK GET ITSOREGI 1998
For a list of product area specialists in the ITSO: type the following command:
TOOLS SENDTO WTSCPOK TOOLS ZDISK GET ORGCARD PACKAGE
• Redbooks Web Site on the World Wide Web
http://w3.itso.ibm.com/redbooks
• IBM Direct Publications Catalog on the World Wide Web
http://www.elink.ibmlink.ibm.com/pbl/pbl
IBM employees may obtain LIST3820s of redbooks from this page.
• REDBOOKS category on INEWS
• Online — send orders to: USIB6FPL at IBMMAIL or DKIBMBSH at IBMMAIL
• Internet Listserver
With an Internet e-mail address, anyone can subscribe to an IBM Announcement Listserver. To initiate the
service, send an e-mail note to announce@webster.ibmlink.ibm.com with the keyword subscribe in the body of
the note (leave the subject line blank). A category form and detailed instructions will be sent to you.

Redpieces

For information so current it is still in the process of being written, look at ″Redpieces″ on the Redbooks Web
Site ( http://www.redbooks.ibm.com/redpieces.htm). Redpieces are redbooks in progress; not all redbooks
become redpieces, and sometimes just a few chapters will be published this way. The intent is to get the
information out much quicker than the formal publishing process allows.

 Copyright IBM Corp. 1996 1998 443


How Customers Can Get ITSO Redbooks
Customers may request ITSO deliverables (redbooks, BookManager BOOKs, and CD-ROMs) and information about
redbooks, workshops, and residencies in the following ways:
• Online Orders — send orders to:

IBMMAIL Internet
In United States: usib6fpl at ibmmail usib6fpl@ibmmail.com
In Canada: caibmbkz at ibmmail lmannix@vnet.ibm.com
Outside North America: dkibmbsh at ibmmail bookshop@dk.ibm.com

• Telephone orders

United States (toll free) 1-800-879-2755


Canada (toll free) 1-800-IBM-4YOU

Outside North America (long distance charges apply)


(+45) 4810-1320 - Danish (+45) 4810-1020 - German
(+45) 4810-1420 - Dutch (+45) 4810-1620 - Italian
(+45) 4810-1540 - English (+45) 4810-1270 - Norwegian
(+45) 4810-1670 - Finnish (+45) 4810-1120 - Spanish
(+45) 4810-1220 - French (+45) 4810-1170 - Swedish

• Mail Orders — send orders to:

I B M Publications I B M Publications IBM Direct Services


Publications Customer Support 144-4th Avenue, S.W. Sortemosevej 21
P.O. Box 29570 Calgary, Alberta T2P 3N5 DK-3450 Allerød
Raleigh, NC 27626-0570 Canada D enmark
USA

• Fax — send orders to:

United States (toll free) 1-800-445-9269


Canada 1-403-267-4455
Outside North America (+45) 48 14 2207 (long distance charge)

• 1-800-IBM-4FAX (United States) or (+1)001-408-256-5422 (Outside USA) — ask for:


Index # 4421 Abstracts of new redbooks
Index # 4422 IBM redbooks
Index # 4420 Redbooks for last six months
• Direct Services - send note to softwareshop@vnet.ibm.com
• On the World Wide Web
Redbooks Web Site http://www.redbooks.ibm.com
IBM Direct Publications Catalog http://www.elink.ibmlink.ibm.com/pbl/pbl
• Internet Listserver
With an Internet e-mail address, anyone can subscribe to an IBM Announcement Listserver. To initiate the
service, send an e-mail note to announce@webster.ibmlink.ibm.com with the keyword subscribe in the body of
the note (leave the subject line blank).

Redpieces

For information so current it is still in the process of being written, look at ″Redpieces″ on the Redbooks Web
Site ( http://www.redbooks.ibm.com/redpieces.htm). Redpieces are redbooks in progress; not all redbooks
become redpieces, and sometimes just a few chapters will be published this way. The intent is to get the
information out much quicker than the formal publishing process allows.

444 Getting Started with DB2 Stored Procedures


IBM Redbook Order Form
Please send me the following:

Title Order Number Quantity

First name Last name

Company

Address

City Postal code Country

Telephone number Telefax number VAT number

• Invoice to customer number

• Credit card number

Credit card expiration date Card issued to Signature

We accept American Express, Diners, Eurocard, Master Card, and Visa. Payment by credit card not
available in all countries. Signature mandatory for credit card payment.

How to Get ITSO Redbooks 445


446 Getting Started with DB2 Stored Procedures
Index
APF authorized 290
Special Characters APPC
.bas file 334, 336 access CICS systems 265
&IWMSSNM symbolic parameter 32 connection 5
DB2 Connect 68
IMS 272, 292
Numerics including code in your stored procedure 291
3270 terminal emulation 307
MVS definitions 310
3745 379
preferences file 315
5648-A25 85
PWS debug tool 306, 308
9121-742 379
RRS 265
RRSAF 260
APPCPMxx member 311
A APPLENV parameter 53, 55
abend 315
application environment
absolute-path!function-name 128
CLI 229, 231
ACBNAME specification 292, 311
problem 54
ACCEPT SQL CALL parameter 9
QUIESCED state 58
access profile 71
WLM-established stored procedure 29
accounting 3, 7
APPSUPP option 227
ACTION(REJECT) specification 34
APSB function call 274, 276, 290
administration tasks (DB2 for MVS/ESA) 13
array
administration tool (ODBC) 187
host variable 121
Advanced Program-to-Program Communication
SQLarrayCALL 337
See APPC
VAB 332, 335
AERTDLI interface 274
ASA2013I message 65
AIB 274, 275, 276
ASA2016I message 65
AIBREASN field 290
ASCCOLL option 227
AIBTDLI interface 274
ASCHPMxx member 310
AIX
ASCII 191
DB2 Connect 68
Assembler
diskette 347, 351
COLLID column 14
prerequisites 3
DB2 on MVS 85
product overview 68
stored procedures overview 1
VAB 331
ASSOCIATE LOCATORS statement
aliases 86, 87, 151
CLI 222
ALL TEST suboption 313, 315
format 153
allied address space 11
relationship among new SQL statements 153
ALLOCATE CURSOR statement
SQL extension 152
CLI 222
ASUTIME column 14
format 153
AT debug command 319, 327
relationship among new SQL statements 153
ATBPBI module 293
SQL extension 152
ATBSDFMU utility 293
AMODE parameter 100
ATR130I message 65
APAR
ATRBACK 275, 277
PN78797 85
ATRCMT 277
PQ02582 221
ATRRRS procedure 63
PQ06894/UQ11231 221
AUTH SIGNON function call 257, 259
PQ07001 221
AUTHID column 14, 15
PQ11161 18
authorization
UN86398 308
client program 132, 265
UN86441 308
ID 13, 14
UN86554 85
required to run a stored procedure 134
UN87131 308
RRSAF 255, 259, 261
WLM-established address space 53

 Copyright IBM Corp. 1996 1998 447


auto c o mmi t 194 build (continued)
AUTOCOMMIT keyword 141, 204, 205 DB2CLI.PROCEDURES 332
automatic control 32, 33, 57, 58 files 334
AVAILABLE state 34 r e m o t e debug 343
samples 78
stored procedure 112, 336
B VAB 134, 331
backup 70 build files 334
BACKUP command 106
BASIC
extensions 333 C
language 79 C
statements 342 C/370 305
VAB 331, 332 CLI 82
batch client p r o g r a m 130, 132
debug tool 306, 314, 328 COLLID column 14
DSNTIAD program 103 data type 90, 197
EXCI call 269 DB2 for AIX 105
mode 315 DB2 for OS/2 105
multiple TCBs 272 DB2 on MVS 85
MVS 306 DB2 on the workstation 105
benchmark 377 DB2CLI.PROCEDURES 79
bind diskette 347, 348, 351, 354
CLI 221 example 94, 108, 115, 116
client program 147 performance 300, 303
column 144, 145 precompiler 132
DB2 on MVS 99, 100 prelink utility 102
DDCSMVS.LST file 131 RENT compiler option 102
DRDA 131 SQLarrayCALL 337
DYNAMICRULES 7 stored procedures overview 1
EXCI 269 TEST compiler option 312, 313
files 83 VAB 332, 335
ODBC 187 Visual Basic
parameter statement 197 VisualGen 134
REXX 132 Windows 187, 220
SQLBindParameter 194 C/370 95, 102, 305
stored procedure 100 C++
VAB 332 client program 132
validation 83 COLLID column 14
BLOCK TEST suboption 313 DB2 for AIX 105
blocking rows 180 DB2 for OS/2 105
BMP 291 DB2 on MVS 85
B o r l a n d C + + 187 DB2 on the workstation 105
bottleneck 399 DB2CLI.PROCEDURES 79
break mode 342 precompiler 132
breakpoints SQLarrayCALL 337
CODE-LISTING window 318, 323 stored procedures overview 1
CODE/370 306, 312, 315 VAB 332
debug tool 316 Windows 187
VAB 331, 340 CAE 69
bridges 431 CAE for Windows 188, 379, 412
buffer CAF
DB2 Connect result set study 418 DB2-established address space 87
START PROCEDURE command 19, 104 link-edit 100
SYSIBM.SYSPROCEDURES 14 performance goals 29
workload 406, 410 RACF 11
buffer pool 382, 383, 418 WLM-established address space 59
build call attachment facility
.bas files 334 See CAF

448 Getting Started with DB2 Stored Procedures


CALL DSNALI statement 87 CICS (continued)
CALL DSNRLI statement 257 COMMIT_ON_RETURN 18
call level interface DRA 273
See CLI 77 methods to access 265
call stack 331, 342 MQI 272
CALL statement MQSeries 291
authorizations 134 non-DB2 resources 265
CALL statement 117 performance goals 29
CLI and ODBC applications 127 RRS 265
connection to the DB2 server 117 tables 269
DB2 Common Servers V1 71 CIMS function call 274, 275
DB2 on MVS 86, 119 cl2o2cr2 302
DB2 on the workstation 123 cl2o2s 302
DDF 8 classification rules
DRA 274 associating with stored procedures 45
embedded SQL 123 definition menu 45
examples 122, 125 qualifier 28
flow 7 susbsystem type 32
in a stored procedure 106 CLEAR MONITOR debug command 327
location specification 129 CLI
MRSP 151 advantages 83
NULL 91, 121 application trace 230
number of parameters 18 CALL statement 127
performance goals 29 client program 130, 132
preparation 193 code page translation between platforms 250
privilege 101 code specific to the OS/390 implementation 247
qualify 111 coding the stored procedure 222
queuing 34 compiling 223
SET CURRENT PACKAGESET statement 97 DB2 Connect result set study 429
SIMPLE linkage convention 90 DB2 on MVS 85
SQL extension 153 DB2 on the workstation 82
SQLCODE 96 DB2 Version 5 221
SQLeproc 127 DB2CLI.PROCEDURES 77
SQLPrepare 141, 193 diagnosis trace 230
statement handle 145 diskette 347, 348, 351, 354
stored procedures overview 1 escape clause 135
Sysplex 32 executing the client program 222
VAB 337, 338 host variables 82
Visual Basic 195, 196 how to invoke a stored procedure 221
WLM-established stored procedure 30 implementing 221
calling other programs 97 MR3C2CO2.C client program 139
CANCEL command 33 MRSP 137, 151, 152
capacity planning 377, 384, 399, 412 MRSP for your client application in the workstation
case sensitivity 53, 112, 129, 236 or if you are 137
cbColDef 190 parameters 118
cbValueMax 190 performance 302
CCOPT statement 224 porting applications 235
CCU 386, 388, 401, 402 PowerBuilder 206
CEETEST 314 precompile 106
CFRM policy 59, 61 prelinking and link-editing 226
CGI 69 privilege 101
CHAR data type 96 problem determination tracing 229
character conversion 17 PROCCOLS sample 78
CHARACTER parameter 17 PROCS sample 78
CICS receiving parameters 222
access IMS databases 273 result sets 146, 223
APPC 292 sample 116, 203
CODE/370 306 stored procedures address space
commit coordination 11 requirements 228

Index 449
CLI (continued) CODE/370 (continued)
SYSIBM.SYSPROCEDURES 228 displaying variables 324
trace 189 edit tool 310
VAB 332, 337 installation 307
Visual Basic 189 LE/370 86
Windows 187 o v e r v i e w 305
CLI0109E message 190 PTF 308
clicall.c 139 source code 317
clicked event 211 step o v e r 325
client pro gra m step return 325
CODE/370 307 step through 325
coding 117 using the debug tool 314
DB2 on the workstation 132 coded character set 250
MRSP 137 COLLECT option 227
preparation 130 collection
VAB 332, 337, 339 calling other programs 97
VisualGen 134 classification rules 28
client/server 1, 331, 377 client program 100
close 200 COLLID column 14
CLSE function call 274 RRSAF 259
CM/2 308, 311 SET CURRENT PACKAGESET statement 98
CMD file 106 WLM-established stored procedure 28
CMS 306 COLLID column 14, 100, 228
COBOL command
batch debug tool 328 bind 131
calling other programs 97 building stored procedures 113
client program 130 DB2 on MVS 19
COBOL/370 305 db2start 75, 107
COLLID column 14 debug 306, 312, 317, 327
data type 90 DISPLAY PROCEDURE 21
DB2 for AIX 105 DISPLAY THREAD 23
DB2 for OS/2 105 EXCI call 266
DB2 on MVS 85 file 315, 328
DB2 on the workstation 105 in a stored procedure 86
DB2CLI.PROCEDURES 79 SET CURRENT PACKAGESET 97
diskette 348, 355, 361, 372 START DB2-established address space 11
example 93, 99, 122, 266 START PROCEDURE 19
MRSP 164, 166 STOP PROCEDURE 20
precompiler 132 terminate current process 107
RENT compiler option 102 unsupported 106
SQLDATA 155 VAB 342
stored procedures overview 1 Visual Basic 194
TEST compiler option 312, 313 Windows 187
VAB 332, 335 COMMAREA 266
varying-length character 17 COMMENT debug command 327
VisualGen 134 commit
Windows 187 client program 118
COBOL for OS/390 and VM 85 coordination 11
code editor 331, 334 DB2 Connect result set study 429
code module 333, 334, 336 DB2 on MVS 7
code page 106, 250 implicit 222, 249
code points 150 lock 381, 386, 412
code segment 114 mode 199, 204
CODE statement 114 network flow 389, 403
CODE-LISTING window 323 non-DB2 resources 11, 265
CODE/370 ODBC 199
batch debug tool 328 transaction characteristics 380
compile tool 310 COMMIT statement
debug tool session example 316 CLI 204

450 Getting Started with DB2 Stored Procedures


COMMIT statement (continued) CONNECT TYPE 1 18, 87, 89, 118
COMMIT_ON_RETURN 18 CONNECT TYPE 2 18, 87, 89, 107
CONNECT TYPE 2 88, 107 connection 7, 195
DB2 on MVS 8 connection handle
not supported statements 86 CLI 142
RRSAF 256 DBconnect function 141
Visual Basic 194 null connection 222
COMMIT_ON_RETURN ODBC 193, 200
accessing IMS databases 277 Visual Basic 196, 197
APPC 295 constants
column 15 CALL statement 117
considerations 18 DB2 on MVS 93
MRSP 151 specifying arguments 120, 124
commitment control 272 stored procedure name 124, 127
common gateway interface VAB 334
See CGI constraints 67
Communications Manager/2 contention
See CM/2 design 381
compatibility mode I/O 382, 395
application environment 30 locking
considerations 33 DB2 for MVS/ESA utilization 389
testing 58 response time 390
compile transaction Tx1 391, 405
accessing IMS databases 287 transaction Tx2 392, 406
CFRM policy 63 transaction Tx3 393, 408
CLI 131 transaction Tx4 394, 408
client program 130 transaction Tx5 395, 409
CODE/370 305, 310, 312 transaction Tx6 396, 410
DB2 on MVS 99 transaction Tx7 404, 411
embedded SQL 106, 132 Control Center 70
nonreentrant 102 control structures 76
ODBC 131 conversion
options 113 DB2 on MVS 124
PL/I 94 DRDA 17
reentrant 102 parameters assignment 96
REXX 131 undelimited constant 130
source code 327 Unicode 191
TEST(ALL) option 323 CONVERT option 111
varying-length character 17 CoOperative Development Environment/370
VS COBOL II 85 See CODE/370
compound SQL 67, 301 COPY statement 111
concurrency 67 core functions 132
condition handling 85 correlation ID 258
CONFIG.SYS file 112, 126 couple data sets 26, 34, 59
configuration coupling facility 59, 61
CODE/370 308 CPI-C side information 310, 311, 315
DB2 Connect result set study 415 CPU
host for CODE/370 310 DB2 Connect result set study 420
technical report 377 DDCS for AIX 398, 399, 405, 407, 410
used in the measurements 377 DDCS for OS/2 385
CONNECT RESET statement 106, 249 locking contention 403
CONNECT statement thread 7
CLI 203, 222 CREATE call 87
CONNECT TYPE 2 88 CREATE DATABASE command 106
thread 7, 89 CREATE THREAD function call 257, 259, 264
three-part names 87 cursor
unsupported 86, 106 blocking rows 183
variables 195 close 200
Visual Basic 196 COMMIT_ON_RETURN 18

Index 451
cursor (continued) DataJoiner 68, 69
MRSP 137, 139, 143, 150 DATE data type 96
names 150 DB2 accounting and statistics traces 380
order of result sets 153 DB2 Administration Tool 103
reasons why not returned to client 170 DB2 Client Application Enabler
statement handle 197 See CAE
used in stored procedure 137 DB2 Common Servers
C application for Windows 220
coding considerations 105
D MRSP 150
D WLM command 54 performance 299
DARI VisualGen 134
CALL statement 123 DB2 Connect
DB2 Common Servers V2 71 COMMIT_ON_RETURN 18
DB2CLI.PROCEDURES 79 MRSP 137, 150
using to invoke stored procedures 127 PowerBuilder 205
VAB 337 product overview 68
data areas 200 result set study 415
data control language DB2 for AIX
See DCL client program 89
data conversion 13, 237, 247, 249 DRDA stored procedure support 1
data definition language REXX 111
See DDL searching stored procedures 126
data integrity 67 stored procedure name 130
data length 119 VisualGen 134
data manipulation language DB2 for HP-UX 1, 67
See DML DB2 for MVS/ESA
data replication 68 C application for Windows 220
data segments 113 connections 384, 399
data sharing 19 DRDA stored procedure support 1
data source line capacity 387, 401
commit mode 204 measurement conclusions 412
handle 196 measurements taken 377
register 187 MRSP 150
SQLConnect 196 network protocol 379
statement handle 197 stored procedures architecture 7
data transformation 3 thread 384, 399
data type tuning 398
assignment rules 95 utilization 389, 403
C 197 DB2 for OS/2
client program 118, 121 client program 89
conversion 96 DRDA stored procedure support 1
object extenders 68 LIBPATH 111
PARMLIST column 89 searching stored procedures 126
print_results function 144 stored procedure name 130
specifying arguments 124 VisualGen 134
SQLDA 119 DB2 for OS/390
data warehouse 68 DB2 Connect 68
database agent process 76 DB2 Connect result set study 416
database application remote interface MRSP 137, 150
See DARI stored procedures architecture 7
database control system DB2 for OS/400 1, 68, 124, 129
See DBCTL DB2 for Sinix 67
database request module DB2 for Solaris 1
See DBRM DB2 for Sun/Solaris 67
database resource adapter DB2 for VM and VSE 68
See DRA DB2 for Windows NT 1, 67
DatagLANce Network Analyzer for Ethernet and DB2 kernel 301
Token-Ring for OS/2 380

452 Getting Started with DB2 Stored Procedures


DB2 on MVS DBADM 78
authorizations 134 DBconnect function 141, 203, 204
client program 88, 130, 131 DBCTL 273, 274, 276, 277
coding stored procedures 85 DBRM 100
commands related to stored procedure 19 DCE 67
constants 93 DCL 3, 86
conversion 124 dd1c2cr2 302
debugging 305 dd1c2s 302
host variables 93 DDCS
languages 85 COMMIT_ON_RETURN 18
SQLDA 93 follow-on product 68
stored procedure name 129 MRSP 150
Visual Basic 189 DDCS for AIX
VisualGen 134 capacity planning 377
DB2 on the workstation client equivalence 398
authorizations 134 configuration 378
CALL statement 123 CPU 398, 399, 405, 407, 410
client program 130, 132 disk capacity 400
coding considerations 106 measurement conclusions 412
MRSP 137 measurement results 398
parameters 118 MRSP 138
searching stored procedures 126 network 401
stored procedure name considerations 128 protocols 379
DB2 Parallel Edition 68 R A M 399, 400
DB2 UDB transactions 404
coding considerations 105 DDCS for OS/2
DRDA stored procedure support 1 capacity planning 377
MRSP 150 configuration 377
product overview 68 CPU 385
tools 70 disk capacity 386
DB2 Version 4 measurement conclusions 412
access IMS databases 274 measurement results 383
COMMIT statement 8 MRSP 138
DB2 Version 5 network 386
access IMS databases 274 protocols 379
CLI 221 R A M 384
COMMIT statement 8 DDCSMVS.LST 131
DB2 WWW Connection 69 DDF 8, 29, 46, 47
DB2-established stored procedures address space DDL 3, 86
APPC 291 debug
CLI traces 231 CLI 231
JCL to start 10 CODE/370 306, 314
load module 52 DB2 on MVS 305
MRSP 151 DB2 on the workstation 114
RACF 11 LE/370 86
RRSAF 59 mode 340
DB2CKPTR environment variable 107 r e m o t e 343, 345
db2cli.ini file 190, 204, 208, 429 tool session example 316
DB2CLI.LST file 187 VAB 340
DB2CLI.PROCEDURES VisualGen 134
columns 79 Debug Tool Command Log window 327
creation 77 DECIMAL data type 96
register 332 DECIMAL parameter 17
VAB 337 DEF file 113
db2dari process 303 DEFINER column 79
DB2INFO EXEC 377 definition file 334, 336
DB2SSN keyword 32 definition menu panel 38
db2start command 75, 107 delay
CPU 403, 407

Index 453
delay (continued) DOS 67
disk 389 DOS_RQRIOBLK 386, 401
line 402 DOUBLE parameter 17
network 412 DPSB call 274, 276, 290
role played 386, 401 DRA 272, 273
DELAY parameter 386, 388, 401, 402, 422, 431 DRDA
DELETE statement 13, 152 bind 131
delimited identifier 130 character conversion 17
DEQ function call 274 CODE/370 308
DESCRIBE CURSOR statement COMMIT_ON_RETURN 18
example 170 data type conversion 96
format 163 DB2 Connect 68
returned information 163 DB2 for MVS/ESA 8
SQL extension 152 DB2 for OS/390 8
DESCRIBE PROCEDURE statement DDCSMVS.LST 131
example 170 measurements taken 377
format 155 MRSP 150
MR2BMCBM sample program 160 SQLeproc 127
number of result sets 152 stored procedures overview 1, 3
returned information 154 system-directed access 87, 129
SQL extension 152 temporary table 151
DESCRIBE statement 150 Visual Basic 188
DESCRIPTION statement 113 DROP DATABASE command 106
DESCSTAT bind option 164, 192 DSN8EP2 member 57
DESTNAME parameter 293, 315 DSNALI module 52, 87, 100
DFSCDL10 module 275 DSNAOCLI collection 228
diagnostic information 189, 193, 199 DSNAOINI file 222
dictionary tables 312 DSNAOINI statement 229
differences between stored procedures and other DSNAOTRC statement 229
programs 106 DSNARLI module 275
directories search 126 DSNCLINC package 221
directory structure 347 DSNRLI module 52, 59, 100, 257, 260
discretionary goals 27 DSNRRSAF statement 260
DISPLAY privilege 21 DSNT408I message 249
DISPLAY PROCEDURE command 21 DSNTIAD 103
DISPLAY statement 57 DSNTIJUZ 12
DISPLAY THREAD command 23 DSNTINST CLIST 8, 12
DISPLAY WLM command 34, 57 DSNTIPG panel 10
Distributed Computing Environment DSNTIPX panel 8, 11, 21
See DCE DSNV429I message 23
distributed data facility DSNX968I message 58
See DDF DSNX981E message 53, 55
Distributed Database Connection Services DSNX982I message 53
See DDCS for Common Servers DSNX9WLM program 229
Distributed Relational Database Architecture dual mode 114
See DRDA dynamic breakpoints 306
distributed unit of work 67 dynamic SQL
see DUW authorizations 134
DLET function call 274 CALL statement 1, 118
DLL compound SQL 301
CLI 222, 229 considerations 81
compile option 223 DB2 on MVS 86
function name 195 DESCRIBE CURSOR statement 164
LINK386 113 performance 300, 303
OS/2 106, 111 privilege 7
prelink 224 system-directed access 87
side deck 228 VisualGen 134
DML 3, 86 DYNAMICRULES(BIND) 7, 134

454 Getting Started with DB2 Stored Procedures


EXE file 106
E executable file 113, 132, 337
ECB 255, 258 EXECUTE privilege 101
EDC6006E message 222 EXECUTE statement 81, 198
EDCICONV procedure 250 execution velocity goal 27
embedded SQL expanded storage 379
CALL statement 123 explicit APPC support 291
client application 132 EXPORT function 223
considerations 81 EXPORTS section 236
MRSP 139 EXPORTS statement 112, 114
performance 302, 303 External CICS Interface
precompile 106 See EXCI 265
static 83 external program name 129
Windows 187 EXTERNAL_SECURITY column 15, 53, 265
encapsulation 83
Encina 18
enclave 25 F
enqueue 12 F WLM command 33
entry point 336 Fast Path data entry databases 273
environment handle FENCED column 80
CLI 141, 142, 203 fenced stored procedure
ODBC 193, 200 concept 76
Visual Basic 196 LIBPATH 112
environment variables 107 MRSP 138
error performance 301
application environment 35 precompile 111
case sensitive 112 searching 126
CLI 249 FETCH statement
coding 35 measurements 389, 403
compiler options 113 MRSP 139, 151
full-path specification 120 result 137
handling statements 204 RESULT_SETS column 150
JCL 35, 55 FFFF2222 64
MRSP 138 flat files 12, 53, 265
ODBC 198 FLD function call 274
parm-name parameter 17 FLOAT data type 96, 124
ROLLBACK statement 87 FLOAT parameter 17
RRS 64 folding 129, 130
RRSAF 263 fopen() command 12
source code 306 FOR subtype DATA parameter 17
SQLConnect 196 FORTRAN
START PROCEDURE command 20 DB2 for AIX 105
statement handle 197 DB2 for OS/2 105
user program 11 DB2 on MVS 85
VAB 340 DB2 on the workstation 105
WLM 34 DB2CLI.PROCEDURES 79
ERROR TEST suboption 315 precompiler 132
ES/9000 4 stored procedures overview 1
escape clause 128, 135 FORWARD RECOVERY command 106
ESCON 431 function
Ethernet 380, 416, 429, 430, 431 calls 82
event control block case sensitive 112
See ECB coding considerations 106
EXCI multiple in the same library 128
access CICS systems 265 name 128, 130
access IMS databases 272 procedures (VAB) 333
CICS tables 269 stored procedure preparation 111
program preparation 267 VAB 334
using in a stored procedure 266

Index 455
function descriptor 226 host variables (continued)
FUNCTIONAME 112 stored procedure name 118, 120, 124
structure 121
VAB 332
G varying-length character 17
GHN function call 274 HP 68
GHU function call 274 HP-UX 331
global temporary table HTML 69
accessing IMS databases 151, 272
result sets 239
sample application 292, 294, 353, 373 I
GMSG function call 274 I/O PCB 275
GN function call 274 IBM AIX XL FORTRAN Version 2 Release 3 4
goal mode IBM AIX XL FORTRAN/6000 Version 2.3 105
application environment 30, 32 IBM C for AIX Version 3 Release 1 3
operation 33, 58 IBM C for AIX Version 3.1 105
Sysplex 26 IBM C Set++ Version 2 Release 1 4
testing 57 IBM C/C++ for MVS/ESA Version 3 Release 1 3
WLM-established stored procedure 25 IBM C/SET++ for AIX Version 2.1 or Version
GRAPHIC data type 96, 111 3.1 105
GRAPHIC parameter 17 IBM C/Set++ for OS/2 Version 2.1 105
GROUP parameter 386, 388, 401, 402 IBM COBOL for MVS and VM Version 1 Release 1 3
GU function call 274 IBM COBOL Set for AIX Version 1 Release 1 4
IBM COBOL Set for AIX Version 1.1 105
IBM COBOL VisualSet for OS/2 Version 1 Release
H 1 4
handler 132 IBM COBOL VisualSet for OS/2 Version 1.1 105
handles IBM High Level Assembler/MVS Version 1 Release
allocation 196 1 3
CLI sample 203 IBM Internet Connection Server 69
data areas 200 IBM PL/I for MVS and VM Version 1 Release 1 3
deallocation 204 IBM Procedures Language 2/REXX 4, 106
e r r o r 199 IBM SAA AD/Cycle C/370 Version 1 Release 2 3
program structure 193 IBM SAA AD/Cycle COBOL/370 85
SQLFreeEnv 200 IBM SAA AD/Cycle Language Environment/370
variables 194 Version 1 Release 1 3
header file 247 IBM VisualAge C++ for OS/2 Version 3 105
HEAP size 234 I B M V i s u a l A g e C + + f o r W i n d o w s 187
history file 336 IBM VisualAge for COBOL for OS/2 and
home page 345, 377 Windows 187
host language IBM XL C Compiler Version 1.2.1 or Version 1.3 105
client program 130 IBM XL C Version 1 Release 2.1 3
compound SQL 301 IBM XL FORTRAN for AIX Version 3.2 105
considerations 81 IBMREQD column 14
DB2 on the workstation 106 ICMD function call 274
package 134 IDENTIFY function call 87, 257, 261
HOST parameter 386, 388, 401, 402 IEASYSnn member 59
host variables IEFSSNxx member 63
array 121 IFI calls 86, 100, 255
CALL statement 117 ILINK 113
CLI 82, 132 IMDBMCB2 sample 292
DB2 on MVS 93 IMDBMCBM sample 292, 296
example 122 IMDBMCBN sample 292
full-path specification 120 IMDBMS sample 292, 296
MRSP 180 Immediate window 342
ODBC 132 implicit APPC support 291
passing parameters 125 IMPORT statement 223, 226
specifying arguments 120, 124 importance 27
SQLDA 107

456 Getting Started with DB2 Stored Procedures


IMS interface block 275
accessing databases 272 International Organization for
APPC 291, 292 Standardization/American National Standards
CODE/370 306 Institute
c o mmi t coordination 11 See ISO/ANSI
DataJoiner 68 Internet 68, 69, 345
DRA 272, 274 interpreter 342
MQSeries 291 interprocess communication 301
performance goals 29 IPA option 226
RRSAF 260 IPS 25
synch point processing 277 IPX 5
temporary table 151 IRXINIT routine 99
IMSBMCBM sample 292, 294 ISIS parameter 277
IMSBMS sample 292, 294 ISO/ANSI 1, 95, 96, 117
IMUBMCBM sample 292, 295 isolation level 221, 381, 418, 429
IMUBMS sample 292, 295 ISPF variables 99
IN parameter 17 ISRT function call 274
inbound translation 53 IWM001I message 54
include files 224 IWM007I message 33
index IWM008I message 33
DB2 Connect result set study 418, 432 IWM029I message 54, 57, 58
matching predicates 390 IWM032I message 54, 58
performance benchmark 381, 382 IWM034I message 55, 57
spreading 382 IWMAM052 message 37
indicator array 14, 91 IXCMIAPU utility 60
indicator variable IXG231I message 65
array 14, 91 IXGLOGR prefix 60
client program 118, 121
DB2 on the workstation 111
SIMPLE WITH NULLS linkage convention 91 J
specifying arguments 124 Java 68, 187
stored procedure name 120, 124 Java Database Connectivity
using nulls to reduce traffic 92 See JDBC
Informix 68 JCL
INIT function call 274 LE/370 library 10
INIT_UID_PWD macro 140 prepare stored procedure 99
initialization file 222, 250 stored procedures address space 9, 12
INITINSTANCE 113 JDBC 68, 187
INOUT parameter 17, 92 join 151, 381
INQY function call 274
INSERT statement 13
Inspector window 341
K
KEEPDARI 72, 75, 303, 304
installation
keystroke time 384
CODE/370 307
DB2 for MVS/ESA 8
DB2 for OS/390 8
updating parameters 12
L
LAN 5, 68, 388, 403
installation control specification
language
See ICS 25
BASIC 79
installation performance specification
CLI 221
See IPS 25
CODE/370 305
instrumentation facility interface
DB2 on MVS 85
See IFI call
DB2 on the workstation 105
INTEGER data type 96, 124
DRA 274
INTEGER parameter 16
MRSP 139, 151, 152
Intel 67, 68
RRSAF 256
interactive mode 306
stored procedures overview 1
interactive test facility 134
VAB 333

Index 457
LANGUAGE column 14, 79, 228 load module (continued)
language interface 52 DISPLAY PROCEDURE command 21
large objects DISPLAY THREAD command 23
See LOB LE/370 86
latching 383, 398 LOADMOD column 14
LE/370 nonreusable 102
calling other program 98 reentrant 102
client program 131 REFRESH option 35
CODE/370 305, 315 reusable 102
DB2 Version 4 85 STAYRESIDENT column 14
introduction 85 STOP PROCEDURE command 20, 21
library name 10 SYSIBM.SYSPROCEDURES 13
link-edit 100 test version 15
MRSP 151 WLM-established address space 52
PTF 307 LOAD utility 13
resident 102 LOADMOD column 14, 21, 52, 104
RUNOPTS 14 LOB 67, 197
RUNTIME parameter 10 Local and Global Monitor List windows 326
stored procedures address space 7 local application 8
SYSIBM.SYSPROCEDURES 13 local call 338
virtual storage 9 local client 1, 117
level functions 132 location 120, 129, 131
LIBPATH 111, 126 lock
library accessing IMS databases 277
case sensitive 112 CPU 403
DB2 on the workstation 106 DB2 Connect result set study 418
LE/370 86 DB2 on MVS 7
name 130 definitions for the measurements 381
path 128 delay 389, 401, 403
SQLZ_DISCONNECT_PROC 109 network 386, 401
SQLZ_HOLD_PROC 109 page level 381
STOPPING state 35 result sets 151
stored procedure name considerations 128 row level 381
stored procedure preparation 111 three-part names 89
VAB 334, 336 LOG function call 274
LIBRARY statement 113 log mode 293, 311
line 387, 388, 401 log streams 59, 60, 64
LINE TEST suboption 313 logical partitions 379
link-edit 52 LONG VARCHAR data type 17
accessing IMS databases 275, 287 LONGNAME option 223, 224
APPC 293 loopback connection 138, 149
CAF 87 lowercase
CFRM policy 63 DB2 for OS/2 130
CLI 223, 226 function name 195
CODE/370 306 stored procedure name 112, 129
DB2 on MVS 99 LSEARCH option 224
LE/370 100 LU 6.2 265, 379, 416
reentrant 102 LU name 13, 293, 310
RENT option 102 LUNAME column 14, 15, 311
REUS option 102
LINK386 113
LINKAGE column 14, 90 M
LIST debug command 319, 321, 327 Macintosh 67
load library 11, 100 mainframe interactive debug tool
load module See MFI
CALL flow 7 makefile
CLI 226 - T i + o p t i o n 113
CODE/370 314, 317 build stored procedure 112
DB2CLI.PROCEDURES 79 COPY statement 111

458 Getting Started with DB2 Stored Procedures


makefile (continued) MR4C2CO2.C client program 146
mrspcli3.sqc 139 MR4C2S.SQL stored procedure 148
VAB 336 MR5BMCBM sample 170
manual control 32 MRSBMCBM sample 166
massively parallel processing MRSBMS sample 169
See MPP MRSP 137
MAX ABEND COUNT parameter 9, 12 access IMS databases 272
MAXAGENTS 74, 304 COMMIT_ON_RETURN 18
MAXDARI 72, 74, 75, 304 DB2 for OS/390 150
measurements 419 example 164
DDCS for AIX gateway 378 porting CLI from AIX to OS/390 236
DDCS for OS/2 gateway 377 mrspcli sample 222
IRRW 380 mrspcli.c 138
KEEPDARI 303 mrspcli2.c 139
performance benchmark 377 mrspcli3.sqc 139
PowerBuilder 412 mrspsrv.c 138
sample program used 299 mrspsrv2.sqc 138
m e m b e r 19, 32 multimedia 68
memory multiple concurrent connections 83
blocking rows 181 multiple functions 128
handle allocation 196 multiple result sets 137
library 109 multiple result sets using stored procedures
performance 303 See MRSP
SQLAllocStmt 197 multiple rows 15, 21, 180
SQLFreeEnv 200 must rollback state 87
STAYRESIDENT column 14 MVS
stored procedures overview 3 DB2 PROC NAME parameter 10
message queue 275 diskette 347, 363
Message Queue Interface measurements 379
See MQI 265 prerequisites 3
MFI 306 PROC NAME parameter 9
Micro Focus COBOL Version 3.1 4, 105, 187
Microsoft Internet Server 69
M i c r o s o f t V i s u a l C + + 187 N
migration 8, 237 named pipe 138
mixed data 17 NCP 386, 401, 402, 412, 430
MKTTOOLS 377 nested 313, 342
MODENAME 293 Net.Data 68, 69
MODIFY command 33 NetBIOS 5
module definition file 112, 113 Netscape 69
monitor NetView Performance Monitor
CODE-LISTING window 323 See NPM
CODE/370 306, 316 network
components used in benchmark 380 client program 118
Control Center 71 compound SQL 301
DB2 Common Servers features 67 DB2 Connect result set study 422
LAN 388, 403 DB2 on the workstation 111
MONITOR GLOBAL LIST debug command 327 DDCS for AIX 401
MONITOR LOCAL LIST debug command 327 DDCS for OS/2 386
MOVE debug command 321, 327 delays 412
MPP 68 lock 386, 401
MQI 265, 272 MRSP 138
MQSeries 291 performance 300
MR0BMCBM sample program 170 protocols 379
MR1BMCBM sample program 155 statement handle 197
MR2BMCBM sample program 160 stored procedures overview 2
MR3C2CO2.C client program 139, 140 using nulls to reduce traffic 92
MR3C2S.SQC stored procedure 139, 143 Network Control Program
See NCP 386

Index 459
NOBLOCK TEST suboption 313 ODBC.INI file 188
NOCONVERT option 76, 111 OLTP 68
NOEXECOPS run-time option 94 OO COBOL
NOLINE TEST suboption 313 COLLID column 14
non-DB2 resources DB2 on MVS 85
accessing from a stored procedure 8, 265 stored procedures overview 1
change the JCL procedure 11 open 138, 200
RACF 12, 53 OPEN CURSOR statement 170
WLM-established address space 53 Open Database Connectivity
NONE TEST suboption 313, 315 See ODBC
NOPATH TEST suboption 313 OPEN function call 274
NOSYM TEST suboption 313 OpenEdition 12
Not-fenced stored procedures operator commands 58
See unfenced stored procedure OPTFILE option 224
NPM 380 optimizer 67
null Oracle 68
blocking rows 184 OS/2
CALL statement 121 client 299, 384, 398
character string 144, 145 COBOL 134
client program 118 CODE/370 305
DB2 on MVS 90 DB2 Connect 68
DB2 on the workstation 111 debug 306
LINKAGE column 14 desktop 187
pointer 107 diskette 347, 348, 353
specifying arguments 120, 124 DLL 106, 111
terminator 198 function 128
VAB 335 IBM Procedures Language 2/REXX 4
Visual Basic 204 LIBPATH 112
NULL CONNECT term 249 PATH 112
null connection 222, 248 prerequisites 4
NULL keyword 91, 120 product overview 68
NUMBER OF TCBS parameter 9 server 299
NUMTCB parameter 12, 13, 57, 273 SPM/2 380
test 303
VAB 331
O Warp 5
object-relational extenders 68 OS/390 25, 54, 206, 221, 274, 275
ODBC OTS-COMMIT 277
administration tool 187 OTS-ROLLBACK 277
bind 187 OUT parameter 17
CALL statement 127 overhead 181
CLI 82 OWNER 7, 101
client program 130
DB2 Common Servers features 67
DB2 Connect result set study 429 P
e r r o r 198 PACKADM authority 101
escape clause 135 package
handle allocation 196 calling other programs 97
migration 237 classification rules 28
MRSP 137, 151, 152 CLI 221
parameters 118 client program 130, 131
PowerBuilder 205, 206 COLLID column 14
privilege 101 DB2 on MVS 99, 100
program structure 193 DB2CLI.PROCEDURES 79
sample application 192 embedded SQL 83
setting the environment 187 isolation level 381
Software Development Kit 133 privilege 7, 101
Visual Basic 189 RRSAF 259
Windows 187 system-directed access 87

460 Getting Started with DB2 Stored Procedures


package (continued) performance (continued)
WLM-established stored procedure 28 technical report 377
parallel processing 68 unfenced stored procedure 76
parameter marker Visual Basic 189
question mark 127, 195 performance goals
SQLBindParameter 141, 197 assigning to a stored procedures 29
SQLExecute 198 classification rules 32
Visual Basic 196 defining 26
parameters relationship among WLM definitions 25
assignment rules 95, 96, 121 service class period 27
CLI 118, 203 testing 57
client program 118 unit of work 29
DB2 on MVS 89, 118 PGM_TYPE column 15
DB2 on the workstation 107, 118 PKGNAME column 79
input 91, 103, 124 PKGSCHEMA column 79
MRSP 151 PL/I
null 91 client program 130
number 119 CODE/370 305
ODBC 118 data type 90
output 91, 124 DB2 on MVS 85
passing to REXX procedure 99 diskette 375
passing using host variables 125 example to call a REXX procedure 98
receiving in DB2 on MVS 93 PROC OPTIONS(REENTRANT) 102
receiving in DB2 on the workstation 107 stored procedures overview 1
SQLDA 118 TEST compiler option 312
stored procedures overview 1 plan
VAB 335 accessing IMS databases 287
parm-name parameter 16 calling a stored procedure from a local client 98
PARM_LIST column (DB2CLI.PROCEDURES) 80 CLI 228
PARM_STYLE column 79 for a stored procedure 100
PARMLIB member 310 privilege 101
PARMLIST column RRSAF 256, 259, 261, 263
assignment rules 95 PLEXCFG parameter 59
data type 96 PLI value 14
syntax 16 PLIST(MVS) run-time option 95
SYSIBM.SYSPROCEDURES 14, 89 portability
PARTNER_LU specifcation 293, 311 application 221
path 128 CLI 83, 236
PATH environment variable 111 receiving parameters 93
PATH TEST suboption 313 stored procedure name 129
pbibm050.ini file 208 VAB 332
PCCU parameter 386, 388, 401, 402 VisualGen 134
Pentium 379 POS function call 274
performance PowerBuilder
access IMS databases 272 client equivalence 384
classification rules 28 DB2 Connect result set study 415, 416
CLI 249 diskette 348, 360
CODE/370 306 IRRW 380
considerations 299 multiple result sets 216
Control Center 71 no result sets 208
DB2 Common Servers features 67 performance benchmark 379
DB2 Connect result set study 429 single result set 213
goal 27 PowerPC 601 379
KEEPDARI parameter 72 pr1c2cr2 300, 303
query 68 pr1c2s 300, 303
reentrant 102 pr2c2cr2 300
SQL_HOLD_PROC 110 pr2c2s 300
static SQL 83 pr3c2cr2 301
stored procedures overview 2

Index 461
pr3c2s 301
pr4c2cr2 302 Q
pr4c2s 302 QSAM files 12, 53, 151
precision 145 qualified name 120
precompile querying 78
client pro gra m 130 queuing 56, 58
CODE/370 313 QuickTest 331, 343
DB2 on MVS 99 QUIESCE option 33, 34
embedded SQL statements 81 QUIESCED state 34, 58
precompiler 120 QUIESCING state 33, 34, 58
VAB 332 QUIT debug command 327
preferences file 315
prelink 102, 224, 226
preload 381, 382, 394, 408, 418
R
RACF
PREPARE statement 81, 197
accessing IMS databases 277
preprocessor 81
DB2-established address space 11, 265
primary authorization 101
RRSAF 255
print_results function 144, 146
WLM-established stored procedures address
priority
space 25, 53, 265
RRS 64
R A M 385, 386, 399, 400
WLM-established stored procedure 25, 56
RCMD function call 274
private protocol 1, 151
RDO 189, 190, 191, 192
privileges
rdoDefaultLoginTimeout property 192
DB2 on MVS 101
REAL data type 96
DB2CLI.PROCEDURES 332
REAL parameter 16
DISPLAY PROCEDURES command 21
reason code
embedded SQL 83
00E79002 55
execute a stored procedure 101, 134
00E79009 53
non-DB2 resources 12
1592312 reason code 264
START PROCEDURE command 19
15925250 reason code 263
STOP PROCEDURE command 20
15925393 263
SYSIBM.SYSPROCEDURES 104
1592554 reason code 264
PROC OPTIONS(REENTRANT) 102
receive operation 2
PROC_LOCATION column 79
Recoverable Resource Manager attachment facility
PROCCOLS sample 78
See RRSAF
PROCEDURE column 14, 120, 129
recoverable resource manager services attachment
procedure-library!function-name 128
facility
process
See RRSAF 253
db2dari 303
recovery 67, 70
fenced stored procedure 76
reentrant 99, 102, 247
KEEPDARI parameter 72
referential integrity 67
terminating 107
refresh 34
PROCNAME column 79
REFRESH option 35
PROCS sample 78
REFRESHING state 33, 35
PROCSCHEMA column 79
region controller 272
program hooks 312
REGION parameter 11
program specification block
registering stored procedures 77, 187, 332
See PSB
RELEASE statement 86, 88, 106
project manager 331
REMARKS column 80
prompt level 315
remote call 338
protected mode 114
remote client 117
protected resources 59
remote data objects
PROTMODE statement 114
See RDO 189
PS/2 4
remote data services 1
PSB 276
RENT compiler option 102, 224
pseudonym files 293
RENT link-edit option 102
PTF 85, 307
REPL function call 274

462 Getting Started with DB2 Stored Procedures


replication 70 ROLLB function call 275
resident 86, 102 rollback
Resource Measurement Facility client program 118
See RMF 416 DB2 on MVS 7
resources 200 RRSAF 256
response time goal 27 ROLLBACK statement
restarting DB2 11 COMMIT_ON_RETURN 18
RESTORE command 106 CONNECT TYPE 2 107
result set must rollback state 87
CLI 83 unsupported statement 86
cursor 137, 138 Visual Basic 194
DB2 Version 4 93 ROLS function call 274
DB2 Version 5 93 routers 431
MRSP 146 RPTOPTS option 230
number of columns 144 RPTSTG option 230, 234
sample 138 RQRIOBLK 386, 401, 422, 429, 430
result set locator rr22xsp0 300
DESCRIBE PROCEDURE statement 155 RRS
relationship among new SQL statements 153 adding the subsystem name 64
SQL extension 152 CFRM policy 63
RESULT_SETS column 14, 80, 150 CICS 265
RESUME option 34, 35 COMMIT_ON_RETURN 18
RESUMING state 34 coupling facility 61
return code DASD log streams 60
CLI 203 DRA 274
e r r o r 194 errors 64
function procedure 333 implementing 59
making a stored procedure resident JCL procedure 63
(workstation) 248 not active 53
ODBC 193 staging data sets 60
SQL_NO_DATA_FOUND 145 starting and stopping 64
variable 194, 198 synch point processing 277
REUS link-edit option 102 RRSAF
reusable 102, 333 coding stored procedures 87
REXX COMMIT_ON_RETURN 18
calling a procedure 98 DB2-established address space 52
calling from a stored procedure 86, 98 e r r o r 263
client program 130, 132 performance goals 29
command file 111 programming 253
DB2 for AIX 105, 111 RACF 53
DB2 for OS/2 106 RRS implementation 59
DB2 on the workstation 105 RRSAFCOB sample 260
DB2CLI.PROCEDURES 79 RRSBACK 275
diskette 347, 348, 352, 356 RUN debug command 327
example 108, 114, 125 RUNOPTS column
library 106 DB2CLI.PROCEDURES 80
PATH environment variable 111 LE/370 14, 230
performance 299, 303 TEST run-time option 314
precompile 106 virtual storage 9
stored procedure name considerations 129 RUNTIME parameter 10
stored procedures overview 1 RUSIZE 386, 401, 422
VAB 332, 335
variable pool 108
rgbValue column 190, 191 S
RISC System/6000 4 S5C4 abend code 64
RMF 380, 416 SAA 127
RMODE(ANY) 100 SAF 255, 261
ROLL function call 275 samputil.c 141, 144, 203

Index 463
samputil.h 140 SNA 293, 309, 416
SBCS 17 SNAP function call 274
scale 198 software prerequisites 3
SCHED specification 292 Solaris 331
scheduling 29 source code
SCHEMA 129, 337 .bas file (VAB) 333
SCO 68 CODE-LISTING window 317, 323
scripts 70 CODE/370 317
SDK for Common Servers 138 VAB 331
SEARCH option 224 viewing (CODE/370) 313
searching stored procedures 16, 126 sp file 334, 336
secondary authorization 101 sp0r2cr2 300
security 3, 7, 83, 277 sp0r2s 300
SELECT statement special characters 120, 124, 127
blocking rows technique 180 speed line 387, 401
CLI 141 SPM/2 380
DESCRIBE CURSOR statement 163 SQL_CLOSE 138
DESCSTAT bind option 192 SQL_COMMIT 142
mr3c2o2 sample program 140 SQL_DROP 138, 142, 200
MR4C2S.SQC program 149 SQL_NO_DATA_FOUND 145, 148, 192
MRSP 139, 143, 151 SQL_NTS 190, 204
WITH RETURN clause 249 SQL0969N message 55
WITH RETURN option 357 SQL1106N message 112
send operation 2 SQL1109 message 112
SENDDA sample 116 SQL3 1, 117
serialization 12, 32, 53, 265 SQL92 Entry Level 152
service class 26, 56, 57 SQLAllocConnect 141, 196, 203
service class period 27 SQLAllocEnv 140, 196
service definition 25, 30, 35 SQLAllocStmt 141, 197
WLM 26 SQLarrayCALL 337
service policy 26, 35, 38 SQLBindCol 145, 249
service units 14, 103 SQLBindParameter function call
serviceability trace 229 CLI 204, 221
SET CONNECTION statement 86, 106 parameter marker 141
SET CURRENT PACKAGESET statement 97 parameter markers 127, 197
SET CURRENT SQLID statement 86 rgbValue column 190
SET PATH statement 129 Visual Basic 190, 194
SET SOURCE ON debug command 327 SQLBrowseConnect 132
SETRRS CANCEL command 64 SQLCA
SETS function call 274 client program 89
setting variables 193, 203 DB2 on the workstation 107
SETU function call 274 MRSP 143
SETXCF command 63 porting CLI applications 248
SHOWDA sample 116 PowerBuilder 211, 216
side deck 227 RRSAF 260
side information 293 VAB 334, 335
SIDEINFO 310 sqlcli.h header file 223
sign on 7, 255 SQLCODE
SIGNON function call 87, 257, 258, 261 -113 129, 195
SIMPLE linkage convention 14, 90, 92 -1133 107
SIMPLE WITH NULLS linkage convention 14, 91, 92, -114 179
164 -204 179
simulate 149, 306 -30090 89
SINIX 68 -301 96
SMALLINT data type 96 -302 96
SMALLINT parameter 16 -303 374
SmartGuide 70, 331, 344 -312 220
SMS class 60 -406 96
-426 19

464 Getting Started with DB2 Stored Procedures


SQLCODE (continued) SQLExecute function call (continued)
-440 18, 179 Visual Basic 190, 191, 196, 198
-444 179 SQLFetch 145, 148
-470 220 SQLFreeConnect 142, 200
-471 21, 53, 55, 179 SQLFreeEnv 142, 200, 222
-496 179 SQLFreeStmt 138, 142, 200
-499 179 SQLGetData 249
-504 179 SQLGetSQLCA 249
-751 86, 180, 249 SQLIND field 121, 125, 154
-805 228 SQLLEN field 121, 125, 163
-842 88 SQLMoreResults 148, 222
-925 18 SQLN 121, 124
-926 18 SQLNAME field
464 150, 152 DESCRIBE CURSOR statement 163
466 164 DESCRIBE PROCEDURE statement 154
494 SQLCODE 178 SQLNumResultCols 144
blocking rows 184 SQLPrepare function call
client program 89 CALL statement 141, 191
SQLColAttributes 145, 249 passing a string 193
SQLConnect 141, 193, 196, 203 Visual Basic 194, 195, 197
SQLD field SQLProcedureColumns 77, 78
DESCRIBE CURSOR statement 163 SQLProcedures 77, 78
DESCRIBE PROCEDURE statement 154 SQLRIDA stem variable 108
setting before the SQL CALL statement 121, 125 SQLRODA stem variable 108
SQLDA SQLSetConnect function call 192
CALL statement 117, 125 SQLSetConnectOption function call 141, 199, 222,
DB2 Common Servers 107 249
DB2 on MVS 93 SQLSetPos 132
DESCRIBE CURSOR statement 163 SQLSTATE 197
DESCRIBE PROCEDURE statement 154, 155 SQLTransact 142, 200, 222, 249
example 122 SQLTYPE field 114, 116, 121, 125, 163
MRSP 143 SQLVAR field
multiple rows 180 assigning 108
parameters 118 client program 111
porting CLI applications 248 DESCRIBE CURSOR statement 163
REXX 125 DESCRIBE PROCEDURE statement 154
SENDDA 116 host variable 124
SHOWDA 116 stored procedure parameter 121
specifying arguments 120, 124 SQLZ_DISCONNECT_PROC 79, 109, 303
SQLD 107 SQLZ_HOLD_PROC 79, 109, 303, 304
SQLVAR field 108 SRB 25
USING DESCRIPTOR 121 SRRBACK function 255, 256, 261, 277
VAB 332, 334, 335 SRRCMIT function
VisualGen 134 ACCTINT field 258
SQLDABC 121, 124 CICS 265
SQLDAID field 163 DRA 277
SQLDATA field 125, 155 RRS 255, 256
SQLDBS 132 RRSAF 261
SQLDescribeCol 144, 239 SRSBMCBM sample 164
SQLDescribeParam 132 SRSBMS sample 165
SQLDisconnect 142, 200 START command 11, 32, 33
SQLeproc 123, 127, 337 START PROCEDURE command 14, 19, 104
SQLError 199, 249 START RRS command 64
SQLEXEC 132 started task 27, 33
SQLExecDirect 249 startup 21
SQLExecute function call STAT function call 274
CALL statement 191 statement handle
CLI 141 CLI 141, 204
ODBC 194 MRSP 144, 145

Index 465
statement handle (continued) STORPROC parameter 12
ODBC 193 STORPROC.DLL 77
Visual Basic 196, 197 STORPROC.LOG 77
static SQL STORPROC.XMP 78
compound SQL 301 STORTIME 55
considerations 81 StrConv function 192
DB2 on MVS 86 string variable 193
DESCRIBE CURSOR statement 164 structure 121
performance 300 subprocedures 333, 338, 341, 342
privilege 7 subprogram 85
status 196, 197, 198, 336 subscript variable 155
STATUS field of DISPLAY PROCEDURE command 22 subsystem identifier 32
STAYRESIDENT column 14, 79, 86, 102, 248 subtask 255
STCB 25 Sun 68
STEP debug command 327 Sybase 68
step mode 306 SYM TEST suboption 313
step over 325, 341 symbol table 313
step return 325 symbolic destination 311, 315
step through synch point manager 265
breakpoint 341 synch point processing 277
Code Editor window 340 synchronous execution 265
CODE/370 306, 325 SYNCLEVEL 291
VAB 331 SYNCLVL specification 265
Step/Run window 324 synonyms 151
STEPLIB 311 SYS1.MIGLIB library 60
STMT TEST suboption 313 SYS1.SAMPLIB library 63
STOP PROCEDURE command 20, 34 SYSADM authority 19, 20, 21, 101
STOPPED state 35, 53, 54 SYSCTRL authority 19, 20, 21
STOPPING state 35 SYSDEFSD data set 226, 227
storage SYSEXEC statement 99
link-edit 100 SYSIBM.SYSLOCATIONS 221
management 85 SYSIBM.SYSPROCEDURES
measurements 379 application environment 30
pointer 107 CALL flow 7
print_results function 144 CLI 228
store assignment rules 95 columns 14
stored procedure name entries required to run in DB2 and
case sensitivity 130 WLM-established address space 52
considerations 128 indicator variables 92
DB2 on MVS 129 INSERT statement 103
DB2 on the MVS platform 120 MRSP 150
embedded SQL 124 passing nulls 90
folding 129, 130 restricting access 104
load module 7 search precedence 16
supplied at execution time 1 START PROCEDURE command 19
Visual Basic 195 updating 13
stored procedures address space SYSOPR 19, 20, 21
architecture 7 SYSOUT statement 57
batch debug tool 328 Sysplex
bringing down 58 application environment 30, 32
CODE/370 311 checking WLM data sets 56
installation 9 couple data sets 26
language-specific libraries 86 DISPLAY command 34
load library 100 log streams 59
multiple 57 MODIFY command 33
non-DB2 resources 265 MONOPLEX 60
resident 102 OS/390 level 37
START PROCEDURE command 19 RRS CFRM policy 63
STOP PROCEDURE command 20 RRS implementation 59

466 Getting Started with DB2 Stored Procedures


Sysplex (continued) TIME data type 96
service policy 26 time stamp 336
STOPPING state 35 timeout 21, 55
VARY command 34 TIMEOUT VALUE parameter 9, 12, 23
VARY WLM command 34 TIMESTAMP data type 96
SYSPROC 120, 129 TP profile 293
System Application Architecture TPN 292, 293, 308
See SAA TPNAME 293, 311
system authorization facility TR0C2CC2 client 181
see SAF TR0C2S stored procedure 183
System Automation for OS/390 33 TRACEFILENAME statement 229
system logger 59 traditional coding 299
System Performance Monitor/2 transaction control 199
See SPM/2 transaction program name
system-directed access 87, 129 See TPN
SYSTEM(MVS) compile option 94 transaction Tx1
description 380
potential lock contention 391, 405
T SQL statements 390, 404
table space 70 transaction Tx2
task control block description 380
See TCB potential lock contention 392, 406
TCB SQL statements 391, 406
application environment 30 transaction Tx3
changing the number 13 description 380
DRA 273, 275 potential lock contention 393, 408
multiple 272 SQL statements 393, 407
number of 9 transaction Tx4
RRSAF 256 description 380
stored procedures address space 7 potential lock contention 394, 408
testing 57 SQL statements 394, 408
TCP/IP 5, 149, 379, 416 transaction Tx5
TERMINATE call 87 description 380
TERMINATE IDENTIFY function call 257, 260, 261 potential lock contention 395, 409
TERMINATE THREAD function call 257, 259, 261 SQL statements 395, 409
TERMINSTANCE 113 transaction Tx6
test description 381
user program 11 potential lock contention 396, 410
VAB 340, 343 SQL statements 396, 410
VisualGen 134 transaction Tx7
TEST compiler option 312 description 381
TEST run-time option 311, 314, 316 potential lock contention 397, 411
TEST suboptions 312 SQL statements 397, 411
think time 384 TRANSLATE function call 87, 256, 257, 260
thread triggers 67
CONNECT TYPE 2 89 TRUNC(BIN) option 17
creation 7 truncation 190
DB2 for MVS/ESA 22, 384 trusted stored procedure
must rollback state 86 See unfenced stored procedure
porting CLI applications 249 TSO 29, 305, 306
RRSAF 255 tuning
three-part names 18, 86, 87, 88, 129 buffer pool 382
threshold 387, 402 database 389
throughput DB2 Connect 428
aggregate 389, 404, 405 DB2 for MVS/ESA 398
client/server 412 two-phase commit
DDCS for AIX 398 accessing IMS databases 277
DDCS for OS/2 383, 384 APPC 291
NCP 387, 401 DRDA 3

Index 467
two-phase commit (continued) VAB (continued)
RRS 265 developing stored procedure 335
RRSAF 256 development environment 331
WLM-established stored procedure 25 diskette 348
type 2 indexes 381, 418 editing a project 334
functions and features 331
home page 345
U remote debugger 343
UDF 67, 129, 331, 333 testing using QuickTest 343
udf files 334 VARCHAR data type 96
UDT 67, 335 VARCHAR parameter 17, 296
undelimited constant 130 VARGRAPHIC data type 96
unfenced stored procedures VARGRAPHIC parameter 17
environment variables 107 variable descriptor 226
LIBPATH 112 variable pool 108
measurement 302 VARY WLM command 33, 34, 55, 58
MRSP 138 VBX 331, 332, 337
performance 302, 304 views 104, 151
placement 111 virtual storage 9, 11, 102
searching 126 Visual Basic
Unicode 189, 190, 191 coding considerations 189
unit of work coding the application 194
client program 118 diskette 359
COMMIT_ON_RETURN 18 ODBC driver 187
CONNECT TYPE 2 88, 89 VAB 331, 332, 337
DB2 for MVS/ESA 8 visual explain 67
DB2 for OS/390 8 VisualAge 113
DB2 on MVS 7 VisualAge for Basic
non-DB2 resources 265 See VAB 135
performance goals 29 VisualDebugger 86
rollback 87 VisualGen 85, 132, 134
RRSAF 258 v m s t a t 380
unit-of-recovery 59 VS COBOL II 85
UNIX 67, 128 VSAM
unqualified name 120 DataJoiner 68
UPDATE statement 13, 152 JCL requirement 265
uppercase RACF 12, 53
DB2 for AIX 130 RRS log streams 60
DB2 for OS/2 130 temporary table 151
delimited identifier 130 VTAM 310, 379, 386, 401, 416
function name 114, 195
porting applications 236
stored procedure name 112, 129, 195 W
undelimited constant 130 wait state 322
user-defined functions WARP 379
See UDF WATCOM FORTRAN 77 32 Version 9.5 4, 105
user-defined types WCHARTYPE option 76, 111
See UDT Web
USING DESCRIPTOR 121, 124 enablement 68
util.c 139 Net.Data 69
util.h 139 WIN-OS/2 187
Windows
client support 67
V coding considerations 187
V2SUTIL utility 228, 248 diskette 348
VAB protected mode 114
client 132, 337, 339 STORPROC.DLL 77
creating stored procedures 332 VAB 331
debugging and testing with VAB 340

468 Getting Started with DB2 Stored Procedures


Windows 3.11
DB2 Connect 68
Windows 95
DB2 Connect 68
diskette 348
product o v e r v i e w 68
Windows NT
DB2 Connect 68
diskette 348
product o v e r v i e w 68
WITH HOLD option 18, 143, 151
WITH RETURN option 18, 150, 151, 249
WLM
introduction 25
relationships 26
WLM PROC NAME parameter 10
WLM-established stored procedures address space
AMODE parameter 100
APPC 291
CAF 59
CLI traces 231
DB2 Version 5 25
DRA 274
MRSP 151
RACF 11, 53, 265
serialization 12
serialize access 265
WLM_ENV column 15, 31, 52
workload 26, 380, 383, 416
workload balancing 25
World Wide Web 345, 377

X
X/Open 82, 132, 135

Index 469
470 Getting Started with DB2 Stored Procedures
ITSO Redbook Evaluation
Getting Started with DB2 Stored Procedures: Give Them a Call through the Network
SG24-4693-01

Your feedback is very important to help us maintain the quality of ITSO redbooks. Please complete this
questionnaire and return it using one of the following methods:
• Use the online evaluation form found at http://www.redbooks.ibm.com
• Fax this form to: USA International Access Code + 1 914 432 8264
• Send your comments in an Internet note to redbook@vnet.ibm.com

Please rate your overall satisfaction with this book using the scale:
(1 = very good, 2 = good, 3 = average, 4 = poor, 5 = very poor)

Overall Satisfaction ____________

Please answer the following questions:

Was this redbook published in time for your needs? Yes____ No____

If no, please explain:


_____________________________________________________________________________________________________

_____________________________________________________________________________________________________

_____________________________________________________________________________________________________

_____________________________________________________________________________________________________

What other redbooks would you like to see published?


_____________________________________________________________________________________________________

_____________________________________________________________________________________________________

_____________________________________________________________________________________________________

Comments/Suggestions: ( THANK YOU FOR YOUR FEEDBACK! )


_____________________________________________________________________________________________________

_____________________________________________________________________________________________________

_____________________________________________________________________________________________________

_____________________________________________________________________________________________________

_____________________________________________________________________________________________________

 Copyright IBM Corp. 1996 1998 471


Getting Started with DB2 Stored Procedures: Give Them a Call through the Network SG24-4693-01

Printed in the U.S.A.

IBML
SG24-4693-01

Vous aimerez peut-être aussi