Db2

  • October 2019
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Db2 as PDF for free.

More details

  • Words: 167,494
  • Pages: 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

International Technical Support Organization Getting Started with DB2 Stored Procedures: Give Them a Call through the Network March 1998

SG24-4693-01

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

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Tables

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

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

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Chapter 1. Stored Procedures Overview . . . . . . . . . . . . . . 1.1 What Are Stored Procedures? . . . . . . . . . 1.2 Why Use Stored Procedures? 1.3 Software Prerequisites for Stored Procedures . . . . . . . . . . . . 1.4 The Project Environment

xvii xvii xix

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

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

 Copyright IBM Corp. 1996 1998

xv

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

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

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

xi

1 1 2 3 4 7 7 8 10 11 12 12 13 13 19 25 25 25 26 28 29 30 30 33 33 34 34 34 35 35 35 50 51 51 53 53 56 56 57 57 58

iii

3.14 Implementing OS/390 Resource Recovery Services (RRS) Support . . . . . . . . . . . . . . . . . . . . . . . . . . 3.14.1 RRS Log Streams . . . . . . . . . . 3.14.2 Activating the CFRM Policy to Support RRS . . . . . . . . . . . 3.14.3 Making the RRS JCL Procedure Available 3.14.4 Adding RRS Subsystem Name . . . . . . . . . . . . . . . . . . . 3.14.5 Starting and Stopping RRS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.14.6 RRS Error Samples Chapter 4. DB2 Common Servers and DB2 UDB . . . . . . . . . . . . . 4.1 What Are DB2 Common Servers? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2 Features of DB2 Common Servers . . . . . . . . . . . . . . . . . . . . . . . . . 4.3 DB2 Universal Database 4.3.1 DB2 Connect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.3.2 Two-Phase Commit Support . . . . . . . . . . . . . . . . . . . . . 4.3.3 Net.Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.3.4 DB2 Universal Database (UDB) Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.4 Configuring for Stored Procedures . . . . . . . . . 4.4.1 The Keep DARI Process Indicator (KEEPDARI) 4.4.2 The Maximum Number of DARI Processes Indicator (MAXDARI) . . . . . . . . 4.4.3 Viewing and Updating KEEPDARI and MAXDARI . . . . . . . . . . . . . . . 4.5 Fenced and Unfenced Stored Procedures . . . . . . . . . . . . . . . . . . . . . 4.6 Registering Stored Procedures 4.6.1 Creating and Updating DB2CLI.PROCEDURES . . . . . . . . . . 4.6.2 Querying DB2CLI.PROCEDURES . . . . . . . . . . . . . . . . . . 4.6.3 Columns of the DB2CLI.PROCEDURES Table . . . . . . . . . . . Chapter 5. Interfaces to Application Development 5.1 Embedded SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.1.1 Static SQL . . . . . . . . . . . . . . . . 5.1.2 Dynamic SQL 5.2 Call Level Interface . . . . . . . . . . . . . . . . 5.3 Deciding Which Interface to Use . . . . . . . . 5.3.1 Embedded SQL Advantages . . . . . . . . . . . . . . . . . . . . . . . 5.3.2 CLI Advantages 5.3.3 Using Both Interfaces . . . . . . . . . . . .

Getting Started with DB2 Stored Procedures

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Chapter 6. Coding Stored Procedures in DB2 on MVS . . . . . . . . 6.1 General Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.1.1 Languages 6.1.2 LE/370 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2 Rules for Coding Stored Procedures . . . . . . . . . . . . . . . 6.2.1 Statements in Stored Procedures 6.2.2 Using System-Directed Access with Stored Procedures . . . . . . . . . . . . . . . . . . . 6.2.3 Stored Procedure Parameters 6.2.4 Calling Other Programs from a Stored Procedure . . . . . . 6.2.5 Calling a REXX Procedure from a Stored Procedure . . . . 6.3 Stored Procedure Preparation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3.1 JCL for the Stored Procedure Preparation 6.3.2 Binding the Stored Procedure . . . . . . . . . . . . . . . . . . 6.3.3 Privileges Required . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3.4 Making Your Stored Procedure Reentrant . . . . . . . . . . . . . . . . . . 6.3.5 Resident Stored Procedures 6.3.6 Defining the Stored Procedure to DB2 . . . . . . . . . . . . . 6.3.7 Restricting Access to the SYSIBM.SYSPROCEDURES Table

iv

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

59 59 63 63 64 64 64 67 67 67 68 68 69 69 70 71 72 74 75 76 77 77 78 79 81 81 81 81 82 82 83 83 83 85 85 85 85 86 86 87 89 97 98 99 99 100 101 102 102 103 104

Chapter 7. Coding Stored Procedures for DB2 Common Servers and DB2 UDB 7.1 Languages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.1.1 Supported Languages for DB2 on the AIX Platform . . . . . . . . . . . . 7.1.2 Supported Languages for DB2 on the OS/2 Platform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.2 Coding Considerations 7.2.1 Rules for Coding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.2.2 Differences between Stored Procedures and Other Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.2.3 Receiving Parameters . . . . . . . . . . . . . . . . . . . . . . . 7.2.4 Nulls to Reduce Network Traffic 7.3 Stored Procedure Preparation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.3.1 Uppercase and Lowercase 7.3.2 Makefiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.3.3 Module Definition File 7.4 Stored Procedure Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.4.1 REXX Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.4.2 C Example 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.4.3 C Example 2 . . . . . . . . . . . . . . . . . . . . 7.4.4 The SENDDA and SHOWDA Samples Chapter 8. Coding Client Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.1 Calling Stored Procedures 8.1.1 The SQL CALL Statement . . . . . . . . . . . . . . . . . . . . 8.1.2 Commit and Rollback . . . . . . . . . . . . . . . . . . . . . . . 8.1.3 Using an SQLDA to Pass Parameters . . . . . . . . . . . . . 8.2 SQL CALL Statement in DB2 on the MVS Platform . . . . . . . . . . . . . . . . . . . . . . . . 8.2.1 Specifying the Procedure Name 8.2.2 Specifying the Arguments . . . . . . . . . . . . . . . . . . . . . 8.2.3 Examples of SQL CALL Statements to Send Parameters 8.3 SQL CALL Statement in DB2 on the Workstation . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.3.1 Embedded SQL Applications 8.3.2 Examples of Coding the CALL Statement . . . . . . . . . . . 8.3.3 Searching for Stored Procedures in DB2 on the Workstation . . . . . . . . . . . . 8.3.4 Invoking Stored Procedures with DARI 8.4 CLI and ODBC Applications . . . . . . . . . . . . . . . . . . . . . . 8.5 Stored Procedure Name Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.5.1 DB2 on the Workstation 8.5.2 DB2 on MVS . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.5.3 DB2 for OS/400 Server (V3.1 or Later) . . . . . . . . . . . . . 8.6 Case Sensitivity and Stored Procedure Name Folding . . . . . . 8.6.1 Case Sensitivity by Platform . . . . . . . . . . . . . . . . . . . 8.6.2 Stored Procedure Name Folding . . . . . . . . . . . . . . . . 8.7 Client Program Preparation . . . . . . . . . . . . . . . . . . . . . . 8.7.1 DB2 on MVS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.7.2 DB2 on the Workstation 8.8 IBM VisualGen and VisualAge for Basic . . . . . . . . . . . . . . 8.9 Invoking Stored Procedures with ODBC Escape Clause . . . . . Chapter 9. Transferring Multiple Result Sets with Stored Procedures . . . . . . . . . . . . 9.1 DB2 CLI/ODBC for DB2 on the Workstation 9.1.1 Examples Using CLI . . . . . . . . . . . . . . . . . . . . . . . . 9.1.2 Setting Up a Loopback Connection . . . . . . . . . . . . . . . 9.2 Multiple Result Sets in DB2 for OS/390 . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.2.1 Multiple Result Set Stored Procedure 9.2.2 Writing the DB2 for OS/390 Client to Receive Result Sets . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.2.3 SQL Extensions

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Contents

105 105 105 105 106 106 106 107 111 111 112 112 113 114 114 115 116 116 117 117 117 118 118 119 120 120 122 123 123 125 126 127 127 128 128 129 129 129 129 130 130 131 132 134 135 137 137 138 149 150 150 152 152

v

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

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Chapter 10. Coding Considerations for Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.1 ODBC Applications: Setting the Environment 10.2 Visual Basic Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.2.1 String Data Truncation . . . . . . . . . . . 10.2.2 How Microsoft Visual Basic Unicode Affects the Client/Server 10.2.3 RDO Program and SQL_NO_DATA_FOUND Error on the ODBC SQL_SETConnect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.2.4 Result Sets Column Names 10.3 Sample ODBC Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.3.1 Setting Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.3.2 Connecting to the Database Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.3.3 Calling the Stored Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.3.4 Other Functions 10.3.5 Setting Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.3.6 Connecting to a Database Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.3.7 Calling the Stored Procedure 10.3.8 Error Handling and Status Checking of ODBC Functions . . . . . . . . . . . . . . . 10.3.9 Transaction Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.3.10 Program Termination 10.4 CLI Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.5 PowerBuilder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.5.1 Configuring CLI/ODBC 10.5.2 PowerBuilder Client Using Parameters - No Result Sets . . . . . . . . . . . . . . . 10.5.3 PowerBuilder Client for Single Result Set . . . . . . . . . . . . . . . . . . . . . . . . 10.5.4 PowerBuilder Client for Multiple Result Set . . . . . . . . . . . . . . . . . . . . . . . 10.6 C Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 11. CLI on DB2 Version 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.1 Introduction to CLI 11.2 Implementing CLI . . . . . . . . . . . . . . . . . . 11.3 How to Invoke a Stored Procedure . . . . . . . . 11.3.1 Multiple Result Sets . . . . . . . . . . . . . . . . . . . . . . 11.3.2 Executing the Client Program 11.4 Coding the Stored Procedure . . . . . . . . . . . 11.4.1 Receiving Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.4.2 Result Sets 11.5 Precompile/Bind Requirements . . . . . . . . . . 11.6 Compiling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.7 Prelinking and Link-editing . . . . . . . . . . . . 11.8 SYSIBM.SYSPROCEDURES 11.9 Stored Procedure Address Space Requirements 11.10 Problem Determination Tracing . . . . . . . . . 11.10.1 Using the CLI Application Trace . . . . . . 11.10.2 Using the CLI Diagnosis Trace . . . . . . . 11.10.3 Running with Traces . . . . . . . . . . . . .

vi

Getting Started with DB2 Stored Procedures

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

163 164 164 166 170 170 178 180 181 183 187 187 189 190 191 192 192 192 193 193 194 194 194 196 196 198 199 200 201 205 206 208 213 216 220 221 221 221 221 222 222 222 222 223 223 223 226 228 228 229 230 230 231

11.10.4 Specifying LE Run-Time Options . . . . . . . . . . . . . . . . . . . 11.11 Running the CLI Sample Stored Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.12 Porting CLI Applications 11.12.1 Porting a Sample Result Set CLI Application from AIX to OS/390 11.12.2 Differences in Handling Result Sets . . . . . . . . . . . . . . . . . 11.12.3 CLI Stored Procedure Coding Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.12.4 Miscellaneous Programming Hints Chapter 12. Recoverable Resource Manager Services Attachment Facility 12.1 Prerequisite Knowledge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.2 Capabilities of RRSAF Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.3 Task Capabilities . . . . . . . . . . . . . . . . . . 12.4 Programming Languages Supported . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.5 Program Size 12.6 RRSAF Use of Load . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.7 Commit and Rollback Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.8 Run Environment . . . . . . . . . . . . . . . . . . . . . . . . 12.9 RRSAF Language Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.10 How to Use RRSAF . . . . . . . . . . . . . . . . . . . . . . . . . . 12.10.1 IDENTIFY Function 12.10.2 SIGNON Function . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.10.3 AUTH SIGNON Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.10.4 CREATE THREAD Function 12.10.5 TERMINATE THREAD Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.10.6 TERMINATE IDENTIFY Function . . . . . . . . . . . . . . . . . . . . . . . . 12.10.7 TRANSLATE Function 12.11 Sample JCL to Use RRSAF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.12 Sample Program RRSAFCOB 12.13 Common RRSAF Errors . . . . . . . . . . . . . . . . . . . . . . . . . . 12.13.1 IDENTIFY Return Code 8 Reason Code 15925393 . . . . . . . . 12.13.2 IDENTIFY Return Code 8 Reason Code 15925250 . . . . . . . . 12.13.3 IDENTIFY Return Code 12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.13.4 CREATE THREAD Return Code 12 Chapter 13. Accessing Non-DB2 Resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13.1 Accessing CICS Systems 13.2 Using EXCI in a Stored Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13.2.1 Sample Stored Procedure 13.2.2 Program Preparation for EXCI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13.2.3 CICS Table Definitions 13.3 Accessing IMS Databases . . . . . . . . . . . . . . . . . . . 13.3.1 Using Database Resource Adapter Callable Interface 13.3.2 Including APPC Code in the Stored Procedure . . . . 13.4 Using MQSeries for Enqueued Messages . . . . . . . . . . 13.5 APPC to Access Transactions from a Stored Procedure . . . . . . . . . . . . . . . . . . 13.5.1 Preparing IMS for APPC 13.5.2 IMSBMCBM, IMSBMS, and PART . . . . . . . . . . . . . . 13.5.3 IMUBMCBM, IMUBMS and IMS IVP Transactions . . 13.5.4 IMDBMCBM, IMDBMS and IMS IVP Transactions Chapter 14. DB2 Common Server Performance Considerations 14.1 Traditional Coding and Stored Procedures . . . . . . . . . 14.2 Dynamic and Static SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14.3 Using Compound SQL . . . . . . . . . . . . . 14.4 Using Unfenced Stored Procedures

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

233 235 236 236 237 240 249 255 255 255 256 256 256 256 256 257 257 257 257 258 259 259 259 260 260 260 260 263 263 263 264 264 265 265 266 266 267 269 272 273 291 291 292 292 294 295 296

. . . . . . . . . . . . . . . . . . . . . .

299 299 300 301 302

Contents

vii

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

14.5 14.6 14.7 14.8

Embedded SQL and CLI . . . . . . . . The KEEPDARI Indicator . . . . . . . . Keeping Stored Procedures in Memory Performance Summary . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Chapter 15. Debugging DB2 on MVS Stored Procedures . . . . . . . . . . . . . . . . . . 15.1 CODE/370 Overview 15.2 CODE/370 Installation Considerations . . . . . . . . 15.2.1 Prerequisites for Installation . . . . . . . . . . . 15.2.2 Communications Configuration for CODE/370 . . . . . 15.3 Preparing to Debug Your Stored Procedure 15.3.1 TEST Compiler Option Syntax . . . . . . . . . . 15.3.2 Viewing the Source Code . . . . . . . . . . . . . 15.4 Using the CODE/370 Debug Tool . . . . . . . . . . . . . . . . . . . . . . . . . 15.4.1 TEST Run-Time Option . . . . . . . . . . 15.4.2 Debug Tool Session Example 15.4.3 PWS Debug Tool Windows . . . . . . . . . . . . 15.4.4 Using the Batch Debug Tool . . . . . . . . . . . Chapter 16. IBM VisualAge for Basic . . . . . . . . . . . 16.1 Functions and Features 16.1.1 Environments and Platforms . . . . . . . 16.1.2 Advantages of Using VAB 16.2 Creating Stored Procedures with VAB 16.2.1 Preparing the Environment . . . . . . . . . . . . 16.2.2 The VAB Language 16.2.3 Editing a Project . . . . . . . . . . 16.2.4 Developing the Stored Procedure . 16.2.5 Developing the Client Program . . 16.3 Debugging and Testing with VAB . . . . . . . . 16.3.1 Setting Breakpoints 16.3.2 The Inspector Window . . . . . . . . . . . . . 16.3.3 The Remote Debugger 16.4 Testing Code Using QuickTest Dialogs . . . . . 16.5 VAB on the World Wide Web Appendix A. Sample Programs . . . . . . . . A.1 Naming Convention . . . . . . . . . . A.2 AIX Samples . . . . A.2.1 C Samples on AIX . . . A.2.2 CLI Samples on AIX A.2.3 REXX Samples on AIX . . . . . . . . . . . A.3 OS/2 Samples A.3.1 C Samples on OS/2 . . . . A.3.2 CLI Programs on OS/2 . . A.3.3 COBOL Programs . . . . . A.3.4 REXX Programs . . . . . . . . . . . . A.3.5 VAB Programs A.4 Windows Samples . . . . . . . . . . . . . . . A.4.1 C Programs A.4.2 Visual Basic Programs . . A.4.3 COBOL Programs . . . . . A.5 MVS Samples . . . . . . . . . . A.6 Using Sample JCL Procedures A.7 C / C + + Programs . . . . . . .

viii

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Getting Started with DB2 Stored Procedures

302 303 303 304 305 305 307 307 308 312 312 313 314 314 316 323 328 331 331 331 332 332 332 333 334 335 337 340 340 341 343 343 345 347 348 351 351 351 352 353 354 354 355 356 356 358 359 359 361 363 368 370

A.8 CLI Programs . . A.9 COBOL Programs A.10 PL/I Programs .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Appendix B. Performance Benchmark and Capacity Planning B.1 Configurations and Specifications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.2 Workload Description B.2.1 Transaction Characteristics . . . . . . . . . . . . . . . B.2.2 Table Characteristics . . . . . . . . . . . . . . . . . . . B.2.3 Locking Definitions . . . . . . . . . . . . . . . . . . . . B.2.4 Physical Location . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.2.5 Buffer Pool Allocation B.3 Results for DDCS for OS/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.3.1 Client Equivalence . . . . . . . . . . . . . . . . . . . . . . B.3.2 CPU Utilization B.3.3 Network . . . . . . . . . . . . . . . . . . . . . . . . . . . B.3.4 DB2 Utilization . . . . . . . . . . . . . . . . . . . . . . . B.3.5 Transactions . . . . . . . . . . . . . . . . . . . . . . . . B.4 Results for DDCS for AIX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.4.1 Client Equivalence . . . . . . . . . . . . . . . . . . . . . . B.4.2 CPU Utilization B.4.3 Network . . . . . . . . . . . . . . . . . . . . . . . . . . . B.4.4 DB2 Utilization . . . . . . . . . . . . . . . . . . . . . . . B.4.5 Transactions . . . . . . . . . . . . . . . . . . . . . . . . B.5 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.6 Other Sources of Information Appendix C. DB2 Connect Result Set Study . . . C.1 Configuration and Specifications . . . . . . . . . . C.2 Workload Description C.2.1 Transaction Characteristics . . . . C.2.2 Table Characteristics . . . . . . . . C.2.3 Locking Definitions . . . . . . . . . . . . . . . . C.2.4 Buffer Pool Allocation C.3 Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . C.3.1 Client Equivalence . . . . . . . . . . . C.3.2 CPU Utilization C.3.3 Network . . . . . . . . . . . . . . . . C.3.4 Transactions . . . . . . . . . . . . . C.4 DB2 Connect Environment Tuning . . . C.4.1 Client . . . . . . . . . . . . . . . . . C.4.2 DB2 Connect . . . . . . . . . . . . . C.4.3 Network . . . . . . . . . . . . . . . . C.5 Conclusions . . . . . . . . . . . . . . . . . . . . . C.6 Other Sources of Information Appendix D. Special Notices

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

371 372 375 377 377 380 380 381 381 382 382 383 384 385 386 389 389 398 398 399 401 403 404 412 413

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

415 415 416 417 418 418 418 419 419 420 422 423 428 429 430 431 432 433

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

435

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Appendix E. Related Publications . . . . . . . . . . . . . . . . E.1 International Technical Support Organization Publications E.2 Redbooks on CD-ROMs . . . . . . . . . . . . . . . . . . . . E.3 Other Publications . . . . . . . . . . . . . . . . . . . . . . . How to Get ITSO Redbooks . . . . . . . . . . How IBM Employees Can Get ITSO Redbooks

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

439 439 439 439

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

443 443

Contents

ix

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

How Customers Can Get ITSO Redbooks . . . . . . . . IBM Redbook Order Form Index

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

444 445

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

447

ITSO Redbook Evaluation

x

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Getting Started with DB2 Stored Procedures

449

Figures 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51.

Processing without Stored Procedures . . . . . . . . . . . . . . . . . . . . . Processing with Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . The Project Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . DB2 Stored Procedure Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . Stored Procedures Parameters Panel (DSNTIPX) - DB2 Version 4 . . . . . Stored Procedures Parameters Panel (DSNTIPX) - DB2 Version 5 . . . . . . . . DB2-Established Stored Procedures Address Space JCL Procedure Changing DSNTIJUZ Parameters . . . . . . . . . . . . . . . . . . . . . . . . . Changing the Number of Concurrent TCBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . PARMLIST Column String Syntax START PROCEDURE Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . STOP PROCEDURE Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . DISPLAY PROCEDURE Syntax Service Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Workload, Service Classes, and Service Class Periods Summary of the Performance Goals of a Service Class . . . . . . . . . . . Assigning Performance Goals to Stored Procedures . . . . . . . . . . . . . SYSIBM.SYSPROCEDURES, Application Environment, and JCL Procedure An Example of the Application-Environment Panel . . . . . . . . . . . . . . Relationship Among WLM Definitions . . . . . . . . . . . . . . . . . . . . . . WLM First Panel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Choose Service Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Definition Menu Panel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Create a Service Policy . . . . . . . . . . . . . . . . . . . . . . . . . . . Service Policy Selection List Selecting Workload . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Create a Workload . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Workload Selection List . . . . . . . . . . . . . . . . . . . Definition Menu - Create Service Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Create a Service Class Choose a Goal Type Pop-Up Window - Period 1 . . . . . . . . . . . . . . . . Average Response Time Goal Pop-Up Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Create a Service Class Panel - Period 1 . . . . . . . . . . . . . . Choose a Goal Type for Period 2 Pop-Up Window Average Response Time Goal Pop-Up Window - Period 2 . . . . . . . . . . Create a Service Class Panel - 2 Service Class Periods . . . . . . . . . . . Choose a Goal Type Pop-Up Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Definition Menu - Classification Rules Subsystem Type Selection List for Rules . . . . . . . . . . . . . . . . . . . . Create Rules for the Subsystem Type . . . . . . . . . . . . . . . . . . . . . . Modify Rules for the Subsystem Type . . . . . . . . . . . . . . . . . . . . . . Definition Menu - Application Environments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Create an Application Environment Application Environment Selection List Panel . . . . . . . . . . . . . . . . . Utility Pull-Down Menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Policy Selection List Panel Choose Service Definition Panel . . . . . . . . . . . . . . . . . . . . . . . . . SQL Template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Sample Scenario with DB2 Connect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Sample Scenario with Net.Data . . . . . . . . . . . . . . . . . . . . . . . . DB2 UDB Control Center Window

 Copyright IBM Corp. 1996 1998

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2 3 4 8 9 10 11 12 13 16 19 20 21 26 27 28 29 31 31 36 37 37 38 38 39 39 40 40 41 41 42 42 43 43 44 44 45 45 46 46 47 48 48 49 49 50 50 52 69 70 71

xi

52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106.

KEEPDARI Set to NO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . KEEPDARI Set to YES Configuring for Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . Fenced Stored Procedures (IPC=Interprocess Communication) . . . . . . . . . Unfenced Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Format of PARM_LIST Column . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Use of Three-Part Names in Stored Procedures . . . . . . . . . . . . . . . . . . . Client Program Restrictions (Scenario 1) . . . . . . . . . . . . . . . . . . . . . . . Client Program Restrictions (Scenario 2) . . . . . . . . . . . . . . . . . . . . . . . Client Program Restrictions (Scenario 3) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . SIMPLE Linkage Convention SIMPLE WITH NULLS Linkage Convention . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Assigning Values to Input Parameters . . . . . . . . . . . . . . . . . . . . . . . Assigning Values to Output Parameters Calling External Programs from Stored Procedures (Example 1) . . . . . . . . . Calling External Programs from Stored Procedures (Example 2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Stored Procedure Packages . . . . . . . Using the DB2 Administration Tool to Manage Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . Return with SQLZ_DISCONNECT_PROC Return with SQLZ_HOLD_PROC . . . . . . . . . . . . . . . . . . . . . . . . . . . . Basic Client Application Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . Passing Stored Procedure Name (Host Variable) and Parameters (SQLDA) . . . . . . . . . . . . . . SQL CALL Statement Syntax in DB2 on the MVS Platform The SQL CALL Statement for Embedded SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . SQLeproc() and the SQL CALL Statement CALL Statement Syntax Used in CLI and ODBC . . . . . . . . . . . . . . . . . . . DB2 CLI and ODBC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Multiple Result Sets with CLI. Renamed client to MR3C2CC2 / server MR3C2S . . . . . . . . . . . . . . . . . . . . . . . . . . Retrieving One Result Set with CLI . . . . Relationship Among the New SQL Statements and the New Data Type . . . . . . . . . . . . . . . . . . . . . . . . . . DESCRIBE PROCEDURE Statement DESCRIBE Cursor Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Blocking Rows. Renamed Client to TR0C2CC2 / Server TROC2S . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ODBC.INI File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ODBC Working Environment Define and Initialize Parameters Used by the Stored Procedure . . . . . . . . . Defining Variables for Handles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Defining a Return Code Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . Connection Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Allocating Handles and Connecting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Issuing the CALL Statement Checking ODBC Return Codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Sample Visual Basic Error Routine Freeing Handles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CLI Sample Application The DB2CLI.INI File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Specify ODBC Drivers During PowerBuilder Install . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Update Database Properties Using CCA . . . . . . . . . . . . . . . . . . . . . . Select CLI/ODBC Settings for a Database Invoke CLI/ODBC Advanced Settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Select User Object Create New User Object: Standard Class . . . . . . . . . . . . . . . . . . . . . . . Select Standard Class Type: Transaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Declare Local External Function Select Stored Procedure from List Box . . . . . . . . . . . . . . . . . . . . . . . .

xii

Getting Started with DB2 Stored Procedures

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

73 74 75 76 77 80 87 88 88 89 91 91 95 96 97 98 100 104 109 110 117 119 120 123 127 127 133 137 139 153 154 163 180 188 189 194 194 195 195 196 197 199 199 200 202 205 206 207 207 208 209 209 210 210 211

107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160.

PowerScript Sample: Process Stored Procedures Using Parameters How a DataWindow Object Is Related to a DataWindow Control . . Design of w_main_window_1 . . . . . . . . . . . . . . . . . . . . . . . Code Fragment for Single Result Set . . . . . . . . . . . . . . . . . . Modify Result Set Description for qry12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Design of w_qry22 . . . . . . . . . . . . . . . . Code Fragment for Multiple Result Sets Modify Result Set Description for qry22 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Specify Retrieve Arguments C/CLI Compile: JCL Fragment Showing Parameters . . . . . . . . . JCL Procedure to Compile a CLI Program . . . . . . . . . . . . . . . Example of JCL Procedure for Stored Procedures Address Space . . . Using CLI INI File to Enable Diagnosis and Application Trace Execute DSNAOTRC to Produce FMT and FLW Reports . . . . . . . . . . . . . . . . . . . . . . . . CLI Application Trace Output Example Formatted Flow Report (FLW) for CLI Diagnosis Trace Example . . . Formatted Detail Report (FMT) for CLI Diagnosis Trace Example Specifying LE Run-Time Options Using DB2 Administration Tool . . Excerpt from Specifying LE Run-Time Option RPTSTG(ON) . . . . . . . . . . . . . . . . . . Using Sample mrspcli.c and sr1.c as Clients UDB to UDB over Private Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . UDB to UDB over DRDA Protocol UDB to OS/390 (CLI) Using DRDA Protocol . . . . . . . . . . . . . . . SR1OMS Source Code: CLI Stored Procedure in C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Sample JCL to Invoke EDCICONV Sample JCL to Convert Coded Chracter Set . . . . . . . . . . . . . . Translating Code Page . . . . . . . . . . . . . . . . . . . . . . . . . . . System Management Panel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . System Environments Panel Select Change/Show Primary Language Environment . . . . . . . . Change/Show Cultural Convention, Language, or Keyboard Panel DRA Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CODE/370 Overview CODE/370 PWS Debug Tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . SNA Features List Window . . . . . . . . . . . . . . . . Transaction Program Definition Window Additional TP Parameters . . . . . . . . . . . . . . . . . . . . . . . . . TEST Option Syntax: C Compiler . . . . . . . . . . . . . . . . . . . . . TEST Option Syntax: COBOL and PL/I Compilers . . . . . . . . . . . TEST Run-time Option Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . PWS Debug Tool Windows . . . . . . . . . . . . . . . . . . . . . . Beginning the Debug Session . . . . . . . . . . . . . Setting a Breakpoint in the PWS Debug Tool . . . . . . . . . . . . . . . Checking the Value of a Variable (Part 1) . . . . . . . . . . . . . . . Checking the Value of a Variable (Part 2) . . . . . . . . . . . . . . . . . . . . Changing the Value of a Variable Copying a Command from the Log Area . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Checking the New Value of a Variable Entering the Wait State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CODE-LISTING Window . . . . . . . . . . . . . CODE-LISTING Window: Setting Breakpoints Displaying the Value of a Variable . . . . . . . . . . . . . . . . . . . . Step/Run Window . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Step Over Push Button Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Step Return Push Button Actions

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Figures

212 214 215 215 216 217 218 219 219 224 225 229 230 231 232 233 233 234 234 237 238 239 239 240 250 250 251 251 252 252 253 273 305 307 309 309 310 312 312 314 317 318 319 320 320 321 321 322 322 323 324 324 325 325 326

xiii

161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208.

Global Monitor List Window . . . . . . . . . . . . . . . . . . . . . . . Debug Tool Command Log Window . . . . . . . . . . . . . . . . . . Selecting the Stored Procedures Catalog Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Stored Procedure Catalog Window . . . . . . . . . . . . . . . . . . . IBM VAB Window: Salary Project . . . . . . . . . . . . . . . . . . . . . The VAB Code Editor Window . . . . . . . . . . . . . . . . . Stored Procedure Definition Window . . . . . . . . . . . . . . . . . . . Local Call Using a Subprocedure Remote Call Using a Stored Procedure . . . . . . . . . . . . . . . . Setting Breakpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . The Inspector Window . . . . . . . . . . . . . . . . . . . . . . . . . . Using the Immediate Window . . . . . . . . . . . . . . . . . . . . . . The qtText2 QuickTest Dialog . . . . . . . . . . . . . . . . . . . . . . The qtArray QuickTest Dialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . The QuickTest SmartGuide Client Program Naming Convention . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Stored Procedure Naming Convention Sample JCL sampbld.jcl to Rebuild Sample Data Sets . . . . . . . Configuration with DB2 for MVS/ESA and DDCS for OS/2 . . . . . Configuration with DB2 for MVS/ESA and DDCS for AIX . . . . . . . . . . CPU Utilization in Relation to Throughput: DDCS for OS/2 . . . . . . . . . . . . . . . Configuration with 3174: DDCS for OS/2 Aggregate Response Time: DB2 for MVS/ESA and DDCS for OS/2 Response Time for Transaction Tx1: DDCS for OS/2 . . . . . . . . Response Time for Transaction Tx2: DDCS for OS/2 . . . . . . . . Response Time for Transaction Tx3: DDCS for OS/2 . . . . . . . . Response Time for Transaction Tx4: DDCS for OS/2 . . . . . . . . Response Time for Transaction Tx5: DDCS for OS/2 . . . . . . . . Response Time for Transaction Tx6: DDCS for OS/2 . . . . . . . . Response Time for Transaction Tx7: DDCS for OS/2 . . . . . . . . . . . . . CPU Utilization in Relation to Throughput: DDCS for AIX . . . . . . . . . . . . . . . . Configuration with 3174: DDCS for AIX . . . . . . . . . . . . . . Aggregate Response Time: DDCS for AIX Response Time for Transaction Tx1: DDCS for AIX . . . . . . . . . Response Time for Transaction Tx2: DDCS for AIX . . . . . . . . . Response Time for Transaction Tx3: DDCS for AIX . . . . . . . . . Response Time for Transaction Tx4: DDCS for AIX . . . . . . . . . Response Time for Transaction Tx5: DDCS for AIX . . . . . . . . . Response Time for Transaction Tx6: DDCS for AIX . . . . . . . . . Response Time for Transaction Tx7: DDCS for AIX . . . . . . . . . Configuration with DB2 Connect for NT . . . . . . . . . . . . . . . . CPU Utilization in Relation to Throughput - DB2 Connect for NT . . . . . . . . . . . . . . Response Time for Transaction FEWROWS . . . . . . . . . . . . Response Time for Transaction MANYROWS Response Time for Transaction Qry1_2 . . . . . . . . . . . . . . . . Response Time for Transaction Qry1_9 . . . . . . . . . . . . . . . . Response Time for Transaction Qry1_17 . . . . . . . . . . . . . . . Response Time Comparison (Qry1_2, Qry1_9, Qry1_17) . . . . . .

xiv

Getting Started with DB2 Stored Procedures

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

326 327 333 333 334 335 337 338 339 341 342 343 344 344 345 349 349 365 378 379 385 388 390 391 392 393 394 395 396 397 400 402 404 405 406 407 408 409 410 411 415 421 423 424 425 426 427 428

Tables 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50.

Hardware and Software Used - First Edition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Hardware and Software Used - Second Edition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Sample SYSIBM.SYSPROCEDURES Table . . . . . . . . . . Sample Setup To Test Same Program in DB2- and WLM- Address Spaces . . . . . . . . . . . . . . Definitions of Stored Procedure Parameters in C, COBOL, and PL/I . . . . . . . . . . . . . . . . . . . . . . . . . Null Parameters and SIMPLE Linkage Convention Null Parameters and SIMPLE WITH NULLS Linkage Convention . . . . . . . . . . . . . . . . . How DB2 for MVS V4 and DB2 for OS/390 V5 Treat Lowercase Names . . . . . . . . . . . . . Stored Procedure Name Folding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Package Creation Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Visual Basic Sample Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Parameter Characteristics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C/C++ Compiler Options Jobs for CLI Sample Stored Procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Overview of Support Related to Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Visible Differences in Result Sets Behavior . . . . . . . . . . . . . . . . . . . . . . How NULL Connections Behave for DB2 for OS/390 V5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . POST Codes for Types of DB2 Termination AIB Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AIB Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . New Reason and Return Codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Existing Reason and Return Codes Sample Programs Used for Performance Measurement . . . . . . . . . . . . . . . . . . . . . . Stored Procedures and Traditional Coding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Static and Dynamic SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Compound, Static, and Dynamic SQL Comparison . . . . . . . . . . . . . . . . . . . . . . . . . Unfenced Stored Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Embedded Dynamic SQL and CLI KEEPDARI Measurements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Keeping a Stored Procedure in Memory . . . . . . . . . . . . . . . . . . . . Description of the Programs Used in the AIX Environment . . . . . . . . . . . . . . . . . . . Description of the Programs Used in the OS/2 Environment Description of the Programs Used in the Windows Environment . . . . . . . . . . . . . . . . . JCL Procedures Used for Our Samples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Description of the C Programs Used in the OS/390 Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CLI Samples on OS/390 COBOL Samples on OS/390 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . PL/I Samples on OS/390 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Description of the REXX Programs Used for APPC/IMS Verification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Table Characteristics for DB2 for MVS/ESA Physical Storage Characteristics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Buffer Pool Characteristics Number of Clients in Relation to Aggregate Throughput: Transactions per Second (DDCS for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . OS/2) . . . . . . . . . . . . . . . . . . . . CPU Utilization in Relation to Throughput: DDCS for OS/2 RAM Utilization on PC500 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3745 Utilization in Relation to Throughput: DDCS for OS/2 . . . . . . . . . . . . . . . . . . . . LAN Utilization in Relation to Throughput: DDCS for OS/2 Potential Lock Contention for Transaction Tx1: DDCS for OS/2 . . . . . . . . . . . . . . . . . . Potential Lock Contention for Transaction Tx2: DDCS for OS/2 . . . . . . . . . . . . . . . . . . Potential Lock Contention for Transaction Tx3: DDCS for OS/2 . . . . . . . . . . . . . . . . . .

 Copyright IBM Corp. 1996 1998

5 5 15 52 90 92 92 129 130 134 192 193 223 235 236 237 249 258 275 276 290 290 299 299 300 301 302 302 303 303 353 356 362 370 371 371 372 375 376 381 382 382

. .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . .

384 385 386 387 389 391 392 394

xv

51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71.

Potential Lock Contention for Transaction Tx4: DDCS for OS/2 . . . . . . . . . . . . . . . . . . Potential Lock Contention for Transaction Tx5: DDCS for OS/2 . . . . . . . . . . . . . . . . . . Potential Lock Contention for Transaction Tx6: DDCS for OS/2 . . . . . . . . . . . . . . . . . . Potential Lock Contention for Transaction Tx7: DDCS for OS/2 . . . . . . . . . . . . . . . . . . Number of Clients in Relation to Aggregate Throughput: Transactions per Second (DDCS for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . AIX) . . . . . . . . . . . . . . . . . . . . . CPU Utilization in Relation to Throughput: DDCS for AIX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . RAM Utilization on C10 3745 Utilization in Relation to TPS: DDCS for AIX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . LAN Utilization in Relation to Throughput: DDCS for AIX Potential Lock Contention for Transaction Tx1: DDCS for AIX . . . . . . . . . . . . . . . . . . . Potential Lock Contention for Transaction Tx2: DDCS for AIX . . . . . . . . . . . . . . . . . . . Potential Lock Contention for Transaction Tx3: DDCS for AIX . . . . . . . . . . . . . . . . . . . Potential Lock Contention for Transaction Tx4: DDCS for AIX . . . . . . . . . . . . . . . . . . . Potential Lock Contention for Transaction Tx5: DDCS for AIX . . . . . . . . . . . . . . . . . . . Potential Lock Contention for Transaction Tx6: DDCS for AIX . . . . . . . . . . . . . . . . . . . Potential Lock Contention for Transaction Tx7: DDCS for AIX . . . . . . . . . . . . . . . . . . . Table Characteristics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Buffer Pool Characteristics Number of Clients in Relation to Aggregate Throughput (TPS) . . . . . . . . . . . . . . . . . . CPU Utilization in Relation to TPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . LAN Utilization in Relation to TPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

xvi

Getting Started with DB2 Stored Procedures

. . . .

. . . . . . . . . . . . . . . . .

395 395 396 398 399 400 400 401 403 405 406 408 409 409 410 412 418 418 420 420 422

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 For IBM Intranet users



http://www.redbooks.ibm.com http://w3.itso.ibm.com

Send us a note at the following address:

[email protected]

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

AIX

4.1

DB2 for AIX

2.1.1

DDCS for AIX

2.3.1

SDK for AIX

2.1.1

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

OS/2 Warp

3.0

SDK for OS/2

2.1.1

Windows

3.11

SDK for Windows

2.1.1

RISC System/6000 PowerPC

PS/2 Model 95 (server)

PS/2 Model 95 (client)

PS/2 Model 80

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

AIX

4.2

DB2 Enterprise Edition for AIX

5.0

DB2 Connect for AIX

5.0

SDK for AIX

5.0

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

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

RISC System/6000 Model 360

PS/2 Model 95

PS/2 Model 95

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 * 2 3 4 5 6



===> YES

Accept SQL CALL statements (stored procedure requests)? YES or NO. MVS/ESA PROC NAME ===> DB41SPAS Stored procedure JCL PROC name NUMBER OF TCBS ===> 8 Number of concurrent TCBs (1-1000) MAX ABEND COUNT ===> 0 Allowable ABENDs for a procedure (0-255) TIMEOUT VALUE ===> 180 Seconds to wait before SQL CALL fails 5-1800 or NOLIMIT (no timeout occurs) 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

* 2 DB2 PROC NAME

===> DBC1SPAS

3 NUMBER OF TCBS ===> 8 4 MAX ABEND COUNT ===> 0 5 TIMEOUT VALUE ===> 180



PRESS: ENTER to continue

WLM-established stored procedure JCL PROC name DB2-established stored procedure JCL PROC name Number of concurrent TCBs (1-100) Allowable ABENDs for a procedure (0-255) Seconds to wait before SQL CALL fails 5-1800 or NOLIMIT (no timeout occurs)

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

14

Specifies the maximum number of result sets that the stored procedure can return to the client application.

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

1

PROC1

2

PROC1

BO

3

PROC2

SILVIO

4

PROC3

LUNAME

LUXEMBRG

LUTEST

LOADMOD

...

PROG1

...

PROG2

...

PROG3

...

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 Description . . . . . . Subsystem Type . . . . . Procedure Name . . . . . Start Parameters . . . .



. . . . .

. . . . .

. . . . .



ATMENV _________________________ Required Stored Proc for the ATM Appl.___ DB2_ Required JCLATM__ 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 W W W W W WW WW W W

L L L L LLLLL

M M MM MM M M M M M 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. 2. 3. 4. 5. 6. 7. 8. 9. 10.

Policies Workloads Resource Groups Service Classes Classification Groups Classification Rules Report Classes Service Coefficients/Options Application Environments 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. 2. 3. 4. 5. 6. 7. 8. 9. 10.

Policies Workloads Resource Groups Service Classes Classification Groups Classification Rules Report Classes Service Coefficients/Options Application Environments 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. 2. 3. 4. 5. 6. 7. 8. 9. 10.

Policies Workloads Resource Groups Service Classes Classification Groups Classification Rules Report Classes Service Coefficients/Options Application Environments 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 . Description . . . . Workload Name . . . Base Resource Group

. . . .

. . . .

. . . .

. . . .

. . . .



STPCDDF (Required) Stored Procedures from DDF DB2RES (name or ?) ________ (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.

 C S D W B S E

A *



Service-Class Notes Options Help ___________________________________________ ---------------------------| Choose a goal type for period 1 | ss Row 1 to 1 of 1 | | _____________________________ | | | 1 1. Average response time | ired) ____________________________________________________________________ | Average response time goal | | | | Enter a response time of up to 24 hours for period 1 | | | | Hours . . . . . 0__ (0-24) | | Minutes . . . . 0__ (0-99) | | Seconds . . . . 3_____ (0-9999) | | | | 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 . Description . . . . Workload Name . . . Base Resource Group

. . . .

. . . .

. . . .

. . . .

. . . .



STPCDDF (Required) Stored Procedures from DDF DB2RES (name or ?) ________ (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

 C S D W B S E

A

*



Service-Class Notes Options Help ___________________________________________ ---------------------------| Choose a goal type for period 2 | ss Row 1 to 2 of 2 | | _____________________________ | | | 1 1. Average response time | ired) ___________________________________________________________________ | Average response time goal | | | | Enter a response time of up to 24 hours for period 2 | | | | Hours . . . . . 0_ (0-24) | | Minutes . . . . 0_ (0-99) | | Seconds . . . . 50____ (0-9999) | | | | 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 . Description . . . . Workload Name . . . Base Resource Group

. . . .

. . . .

. . . .

. . . .

. . . .



STPCDDF (Required) Stored Procedures from DDF DB2RES (name or ?) ________ (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. 2. 3. 4. 5. 6. 7. 8. 9. 10.

Policies Workloads Resource Groups Service Classes Classification Groups Classification Rules Report Classes Service Coefficients/Options Application Environments 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

Action Type Description __ ASCH Use Modify to __ CICS Use Modify to __ DB2 Use Modify to 3_ DDF Use Modify to __ IMS Use Modify to __ IWEB Use Modify to __ JES Use Modify to __ LSFM Use Modify to __ OMVS Use Modify to __ SOM Use Modify to __ STC Use Modify to __ TSO Use Modify to *******************************



------Class------Service Report enter YOUR rules enter YOUR rules enter YOUR rules enter YOUR rules enter YOUR rules enter YOUR rules enter YOUR rules enter YOUR rules enter YOUR rules enter YOUR rules enter YOUR rules 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? Description . . . DRDA Stored Procedures



Y (Y or N)

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? Description . . . DRDA Stored Procedures



Y (Y or N)

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 ******************************

F1=Help

__________________________________________ | Qualifier name is required. (IWMAM724) | 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. 2. 3. 4. 5. 6. 7. 8. 9. 10.

Policies Workloads Resource Groups Service Classes Classification Groups Classification Rules Report Classes Service Coefficients/Options Application Environments 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 Description . . . . . . Subsystem Type . . . . . Procedure Name . . . . . Start Parameters . . . .



. . . . .

. . . . .

. . . . .



WLM_ENV1 Required stored procedures DB2 Required DBC1WLM1 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. 2. 3. 4. 5. 6. 7. 8. 9. 10.

Policies Workloads Resource Groups Service Classes Classification Groups Classification Rules Report Classes Service Coefficients/Options Application Environments 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

 F C D D D S f



File Utilities Notes Options Help _________________________________________________________________________ | Policy Selection List Row 1 to 6 of 15 | | Command ===> ________________________________________________________ | | | | The following is the current Service Definition installed on the WLM | | couple data set. | | | | Name . . . . : ITSO_SJ | | | | Installed by : DB2RES1 from system SC62 | | 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 // // // // EXEC

(999,POK),′ SAVE TIME′ , NOTIFY=&SYSUID., CLASS=A,MSGCLASS=T,REGION=5000K, TYPRUN=SCAN, MSGLEVEL=(1,1) 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

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





1

NULLS NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO YES

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 - --------1 1000 2

Imp 2 4

Goal description ---------------------------------------Average response time of 00:00:30.000 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 ATR143I IEF450I IEF404I IEF196I IEF196I IEF196I IEF196I

CANCEL REQUEST WAS RECEIVED FOR RRS. RRS HAS BEEN DEREGISTERED FROM ARM. RRS RRS - ABEND=S5C4 U0000 REASON=FFFF2222 064 RRS - ENDED - TIME=hh.mm.ss IEF472I RRS RRS - COMPLETION CODE - SYSTEM=5C4 USER=0000 REASON=FFFF2222 IEF373I STEP/RRS /START 1997303.1507 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: •

64

If RRS cannot find one of the log streams, you get the following when starting RRS:

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 49 parm-length PIC S9(4) USAGE IS COMP 49 parm-text PIC X(n)

CHAR(n) VAR

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) COMP-3.

DEC FIXED(x,y)

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 or PIC N(n)

GRAPHIC(n)

VARGRAPHIC(n)

struct {short int parm_len; wchar_t parm_data [ n ] ; } parm;

01 parm. 49 parm-length PIC S9(4) USAGE IS COMP 49 parm-data PIC G(n) USAGE IS DISPLAY-1 or 49 parm-data PIC N(n)

GRAPHIC(n) VAR.

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, --> // 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 --> // DD DISP=SHR, // DSN=DSN410.SDSNLOAD //LKED.SYSLMOD DD DSN=DSN410.RUNLIB.LOAD(TS0BMS), --> // DISP=SHR //LKED.SYSIN DD * INCLUDE SYSLIB(DSNALI) --> MODE AMODE(31) RMODE(ANY) --> //PREPS02 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(CENTDB2.SPCOLLID) MEMBER(SPPACKAG) LIBRARY(′ DSN410.DBRMLIB.DATA′ ) ACT(REP) ISOLATION(CS) VALIDATE(BIND) END //

(1)

(2)

(3)

(4) (5) (6)

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 ===>

1 2 3 4 5 6 7

-

Display/update stored procedures Insert stored procedure Display stored procedure statistics Start all stored procedures Stop all stored procedures Create view on SYSIBM.SYSPROCEDURES Display views on SYSIBM.SYSPROCEDURES

DB2 System: DBC1 DB2 SQL ID: DB2RES1

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:

106



CALL



CONNECT



SET CONNECT



RELEASE



CONNECT RESET



CREATE DATABASE



DROP DATABASE



BACKUP



RESTORE



FORWARD RECOVERY

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 io_sqlda.1.sqldata io_sqlda.1.sqllen io_sqlda.1.sqlind

= = = =

453 dataitem.1 20 dataitem.1.ind

io_sqlda.2.sqltype io_sqlda.2.sqldata io_sqlda.2.sqllen io_sqlda.2.sqlind

= = = =

497 dataitem.2 20 dataitem.2.ind

io_sqlda.3.sqltype io_sqlda.3.sqldata io_sqlda.3.sqllen io_sqlda.3.sqlind

= = = =

497 dataitem.3 20 dataitem.3.ind

io_sqlda.4.sqltype io_sqlda.4.sqldata io_sqlda.4.sqllen io_sqlda.4.sqlind

= = = =

497 dataitem.4 20 dataitem.4.ind

io_sqlda.5.sqltype io_sqlda.5.sqldata io_sqlda.5.sqllen io_sqlda.5.sqlind

= = = =

453 dataitem.5 8320 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 where is not delimited and has lowercase characters

Causes to be folded to uppercase.

CALL :hv where :hv is a host variable whose value is in lowercase

Fails with SQLCODE -113.

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 Host Languages (1)

Stored Procedure - REXX, CLI (2)

Compiled host language

Package for both applications: the client and the stored procedure

Package only for the client application

REXX, CLI, ODBC (3)

Package only for the stored procedure application

No packages

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

138

- Modified version of outcli.c - Calls mrspsrv and displays the returned result set. - Requires mrspsrv.c to be built on the server.

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 char my_errmsg[71]; .... ....

Bo.2 */

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 SQLCHAR SQLINTEGER SQLCHAR

146

String variable */ string1[254]; string1ind = 0; string2[254];

/* Will contain the sqlstring1 */ /* Indicator variable for string1 */ /* Will contain the sqlstring2 */

Getting Started with DB2 Stored Procedures

SQLINTEGER string2ind = 0; SQLCHAR string3[254]; SQLINTEGER string3ind = 0; short result_set_no = 0;

/* Indicator variable for string2 */ /* Will contain the sqlstring3 */ /* Indicator variable for string3 */

/* 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 char my_errmsg[71];

Bo.2 */

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 EXEC SQL PREPARE s2 FROM EXEC SQL PREPARE s3 FROM

*/ :stmt1; :stmt2; :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 A A A A

new new new new new

result set locator SQL data type ASSOCIATE LOCATORS SQL statement ALLOCATE CURSOR SQL statement DESCRIBE PROCEDURE SQL statement 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: − −

154

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.

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 02 SQLDVAR 03 03 03 03 03

PIC S9(4) COMP VALUE OCCURS 1 TO 5 TIMES DEPENDING ON SQLN. PIC S9(4) COMP. PIC S9(4) COMP. POINTER. POINTER.

0.

SQLTYPE SQLLEN SQLDATA SQLIND SQLNAME. 49 SQLNAMEL PIC S9(4) COMP. 49 SQLNAMEC PIC X(30). I PIC S9(4) COMP. F PIC S9(4) COMP. J PIC S9(4) COMP. Q10 PIC X(10) VALUE ′ Q20 PIC X(20) VALUE ′ CURSOR-NM PIC X(8). IDX PIC S9(4) COMP.

01 01 01 01 ?′ . 01 ?′ . 01 01 * * 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 77 77 77 77 77 77 77 156

ERR-CODE ERR-MINUS LINE-EXEC STOREPROC CURSOR-E CURSOR-TB CURSOR-E-NF CURSOR-TB-NF

PIC PIC PIC PIC PIC PIC PIC PIC

9(8) X X(20) X(8) X(30) X(30) X(30) X(30)

VALUE VALUE VALUE VALUE VALUE VALUE VALUE VALUE

Getting Started with DB2 Stored Procedures

0. SPACE. SPACE. ′ MR5BMS ′ . ′ TESTE-CURSOR′ . ′ TEST-TB-CURSOR′ . ′ TESTE-NF-CURSOR′ . ′ TEST-TB-NF-CURSOR′ .

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 :LOC-1 END-EXEC, WHEN 2 EXEC SQL ALLOCATE CURSOR1 CURSOR FOR :LOC-2 END-EXEC, WHEN 3 EXEC SQL ALLOCATE CURSOR1 CURSOR FOR :LOC-3 END-EXEC, WHEN 4 EXEC SQL ALLOCATE CURSOR1 CURSOR FOR :LOC-4 END-EXEC, WHEN OTHER EXEC SQL ALLOCATE CURSOR1 CURSOR FOR :LOC-5 END-EXEC, END-EVALUATE. PROCESS-E. PERFORM ALLOCATE-CURSOR. PERFORM FETCH-ROWS-1 VARYING F FROM 1 BY SQLCODE = +100. EXEC SQL CLOSE CURSOR1 END-EXEC. PROCESS-TB. PERFORM ALLOCATE-CURSOR. 158

Getting Started with DB2 Stored Procedures

RESULT SET

RESULT SET

RESULT SET

RESULT SET

RESULT SET

1 UNTIL

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 01 * 77 77 77 77 77 77

USAGE SQL TYPE IS RESULT-SET-LOCATOR VARYING. LOCNUM REDEFINES LOCPTR PIC S9(8) COMP. Cursor names from stored procedure STOREPROC PIC X(8) VALUE ′ MR5BMS ′ . CURSOR-E PIC X(30) VALUE ′ TESTE-CURSOR′ . CURSOR-TB PIC X(30) VALUE ′ TEST-TB-CURSOR′ . CURSOR-E-NF PIC X(30) VALUE ′ TESTE-NF-CURSOR′ . CURSOR-TB-NF PIC X(30) VALUE ′ TEST-TB-NF-CURSOR′ . 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. 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

2A

* 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

166

USAGE SQL TYPE IS RESULT-SET-LOCATOR VARYING.

Getting Started with DB2 Stored Procedures

77 77 77 77

I FETCH-END CUR-END1 CUR-END2

PIC PIC PIC PIC

9(5) S9(8) S9(8) S9(8)

VALUE 0. COMP VALUE +0. COMP VALUE +0. 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 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01

RECPTR POINTER. RECNUM REDEFINES RECPTR PIC S9(8) COMP. IRECPTR POINTER. IRECNUM REDEFINES IRECPTR PIC S9(8) COMP. I PIC S9(4) COMP. F PIC S9(4) COMP. J PIC S9(4) COMP. DUMMY PIC S9(4) COMP. MYTYPE PIC S9(4) COMP. COLUMN-IND PIC S9(4) COMP. COLUMN-LEN PIC S9(4) COMP. COLUMN-PREC PIC S9(4) COMP. COLUMN-SCALE PIC S9(4) COMP. INDCOUNT PIC S9(4) COMP. ROWCOUNT PIC S9(4) COMP. 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

01 LOC-2 01 LOC-3 01 LOC-4 01 LOC-5

RESULT-SET-LOCATOR USAGE SQL TYPE IS RESULT-SET-LOCATOR USAGE SQL TYPE IS RESULT-SET-LOCATOR USAGE SQL TYPE IS RESULT-SET-LOCATOR USAGE SQL TYPE IS RESULT-SET-LOCATOR

VARYING. VARYING. VARYING. VARYING. 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 77 77 77 77 77

ERR-CODE ERR-MINUS LINE-EXEC FETCH-END CUR-END1 CUR-END2

77 STOREPROC

PIC PIC PIC PIC PIC PIC

9(8) X X(20) S9(8) S9(8) S9(8)

PIC X(8)

VALUE 0. VALUE SPACE. VALUE SPACE. COMP VALUE +0. COMP VALUE +0. COMP VALUE +0. 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

178

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. 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 SYSIBM.SYSPROCEDURES catalog table However, the MVS load module identified SYSIBM.SYSPROCEDURES row could not

-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:

-504

a stored procedure and found the row in the associated with the requested procedure name. in the LOADMOD column of the be found.



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.

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). •

-751

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.

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: •

180

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

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 Name Name Name Name Name Name Name Name Name

: : : : : : : : : :

Sanders Pernal Marenghi O′ Brien Hanes Quigley Rothman James Koonitz Plotz

Id Id Id Id Id Id Id Id Id Id

: : : : : : : : : :

10 20 30 40 50 60 70 80 90 100

Salary Salary Salary Salary Salary Salary Salary Salary Salary Salary

: : : : : : : : : :

18357.50 18171.25 17506.75 18006.00 20659.80 16808.30 16502.83 13504.60 18001.75 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 inout_sqlda->sqlvar[0].sqldata inout_sqlda->sqlvar[0].sqllen inout_sqlda->sqlvar[0].sqlind

= = = =

SQL_TYP_NCSTR; data_item0; 101; &dataind0;

inout_sqlda->sqlvar[1].sqltype inout_sqlda->sqlvar[1].sqldata inout_sqlda->sqlvar[1].sqllen inout_sqlda->sqlvar[1].sqlind .... .... inout_sqlda->sqlvar[9].sqltype inout_sqlda->sqlvar[9].sqldata inout_sqlda->sqlvar[9].sqllen inout_sqlda->sqlvar[9].sqlind .... ....

= = = =

SQL_TYP_NCSTR; data_item1; 101; &dataind1;

= = = =

SQL_TYP_NCSTR; data_item9; 101; &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 char sname[21] = int sid = float ssalary = int cntr; char outline[80]; .... ....

Variables */ { 0 }; 0; 0;

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 Dim Dim Dim Dim Dim Dim

message(21) As Byte sqlerrm(75) As Byte procret As Long query as String pcb1 as Long pcb2 as Long 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.



Allocates the connection handle and connects to a database server. 3

2.

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.



Associates the parameter variables with the arguments of the stored procedure. 6.

5.

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.

204



The application deallocates the handles and disconnects from the database server. 9.



The application is coded with error handling statements to control its execution.

Getting Started with DB2 Stored Procedures

10.

; 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 P3 P4 P5

= = = =



SPACE(79) SPACE(435) 0 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. 2. 3. 4.

Create a new DataWindow Object. Choose Stored Procedures as data source. Choose a Presentation Style (for example, tabular). 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. 2. 3. 4. 5. 6.

Click on the Application Painter button on the PowerBar. Click on File on the menu bar. Select Open and open our sample file, query3.pbl. In the Select Application dialog box, choose query3 and click on OK. Click the Window button on the PowerBar. 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. 2. 3. 4.

Select DataWindow d_qry12. Click on Design from the menu bar. Select Data Source. 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. 2. 3. 4. 5. 6.

Click on the Application Painter button on the PowerBar. Click on File on the menu bar. Select Open and open our sample file, query3.pbl. In the Select Application dialog box, choose query3 and click on OK. Click on the Window button on the PowerBar. 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 P1 = P2 = P3 =

PROCEDURE FOR QRY22 :input_values, :RC, :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. 2. 3. 4. 5.

Select DataWindow d_qry22. Click on Design from the menu bar. Select Data Source. Click on the More > > button. 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.



220

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.

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 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′ , CRUN=, CPARM=′ OPTFILE(DD:CCOPT)′ CPARM2=′ NOMARGINS SOURCE′ , CPARM3=,

< COMPILER REGION SIZE < compiler run-time options 1 < compiler options < 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)′ ,
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 The The The

I/O stream class library complex mathematics class library application support class library (replaced by ASCCOLL) 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 //IEFPROC EXEC PGM=DSNX9STP,REGION=&RGN,TIME=&TME, // PARM=′&SUBSYS,&NUMTCB′ //STEPLIB DD DISP=SHR,DSN=DSN510.SDSNLOAD // DD DISP=SHR,DSN=CEE.SCEERUN // DD DSN=CBC.SCLBDLL,DISP=SHR // DD DISP=SHR,DSN=SG244693.SAMPLES.LOAD.SPAS //DSNAOINI DD DISP=SHR,DSN=SG244693.SAMPLES.SOURCE(CLIINI) //CLITRACE DD SYSOUT=* //DSNAOTRC DD DISP=SHR,DSN=SG244693.FB80



1 2 3 4 5 6 7 8 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 // SET DB2EXIT=DSN510.SDSNEXIT // SET DB2LOAD=DSN510.SDSNLOAD // SET LIBPRFX=CEE //* //DSNAOTRC EXEC PGM=IKJEFT01,COND=(04,LT), // REGION=0M //STEPLIB DD DSN=&DB2EXIT.,DISP=SHR // DD DSN=&DB2LOAD.,DISP=SHR // DD DSN=&LIBPRFX..SCEERUN,DISP=SHR // DD DSN=&CLBPRFX..SCLBDLL,DISP=SHR //SYSTSPRT DD SYSOUT=* //SYSPRINT DD SYSOUT=* //CEEDUMP DD SYSOUT=* //FMT DD SYSOUT=* //FLW DD SYSOUT=* //TRACECLI DD DISP=SHR,DSN=SG244693.FB80 //SYSTSIN DD * DSNAOTRC OFF DSNAOTRC FMT DD:TRACECLI DD:FMT DSNAOTRC FLW DD:TRACECLI DD:FLW /*

* * * *

* * * *



for class lib DB2 exits DB2 LE prefix

DB2 EXIT DB2 SYSTEM LIBRARY LE RUN-TIME CLASS

* TRACE FILE



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 809 810 811

 +

|SQLExecute2 fnc_entry | |CLI_sdaInitSqldaParm fnc_entry | | |CLI_sdaTermSqldaParm fnc_entry | | |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 ===> WLM environment ===> Program type ===> Ext security ===> Commit on return===> Press Enter to Update,



2 M N N or

(0: no result sets, 1-N: result sets (name of WLM environment to be used) (M: main routine, S: subroutine) (N: No, Y: RACF env. needed) (N: No, Y: UOW is to be commited) 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: Increment size: Total heap storage used (sugg. initial size): Successful Get Heap requests: Successful Free Heap requests: Number of segments allocated: Number of segments freed:

 614400 32768 838896 214 90 9 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. 2. 3. 4. 5. 6. 7. 8. 9. 10.

Make sure the CLI environment is already set up. Update the SOURCE me mb e r apddl with your data source, user ID, and password. Run the apddl JCL m e m b e r to compile, prelink, link, and execute. Update the SOURCE m e m b e r apdin with your data source, user ID, and password. Run the defspd29 me mb e r to define the stored procedure to SYSIBM.SYSPROCEDURES table. Run the spd29 JCL me mb e r to compile, prelink, and link. Run the apdin JCL me mb e r to compile, prelink, link, and execute SQL statements within apdin. Update the SOURCE me mb e r apd29 with your data source, user ID, and password. Manually drop the index TABLE2AX from TABLE2A. 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 JESMSGLG JESJCL JESYSMSG CLITRACE SYS00001 SYS00002 SYS00003

STEPNAME JES2 JES2 JES2 DBC1SPAS DBC1SPAS DBC1SPAS 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 V4

DB2 for OS/390 V5

DB2 Common Server V2

DB2 Universal Database V5

DRDA AR using parameters

Yes

Yes

Yes

Yes

DRDA AS using parameters

Yes

Yes

Yes

Yes

DRDA AR for result sets

Yes

DRDA AS for result sets

Yes

CLI ODBC 2.0 level 2

Yes

Yes(CLI)

Yes

CLI ODBC 3.0 level 1

Yes Yes

stored procedure name

must be in uppercase for CLI. See 8.6, “Case Sensitivity and Stored Procedure Name Folding” on page 129

case sensitive. On OS/2, we can use the EXPORTS section in the module definition file to allow uppercase. See 7.3.1, “Uppercase and Lowercase” on page 112

keep program in memory

update STAYRESIDENT = ′ Y′ in SYSPROCEDURES table

return(SQLZ_HOLD_PROC) in source code

remove program fro m m e m o r y

update STAYRESIDENT = ′ ′ in SYSPROCEDURES table

return(SQLZ_DISCONNECT_PROC) in 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: • •

236

Restrictions on stored procedures returning result sets How to pass a parameter with indicator to and from a stored procedure

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 procedure)

Parameters / indicators

Result Sets

11.12.2.1, “UDB to UDB Result Sets Using Private Protocol” on page 238

OK

OK

Chapter 11. CLI on DB2 Version 5

237

Table 16 (Page 2 of 2). Visible Differences in Result Sets Behavior. Scenario (client to stored procedure)

Parameters / indicators

Result Sets

11.12.2.2, “UDB to UDB Result Sets Using DRDA Protocol” on page 238

OK

Fails: not supported

11.12.2.3, “UDB to OS/390 Result Sets Using DRDA Protocol” on page 239 (CLI or embedded SQL)

OK

OK, but column names are not returned. The ordinal position of the column is returned instead.

UDB to OS/390 (stored procedure using embedded SQL), DRDA protocol

OK

OK, but column names are not returned. The ordinal position of 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 340 90 40



NAME Edwards Koonitz O′ Brien

SALARY 17844.00 18001.75 18006.00

.. . 160 Molinare 22959.20 >Disconnecting .....



B



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 340 90 40 20 100



2 Edwards Koonitz O′ Brien Pernal Plotz

3 17844.00 18001.75 18006.00 18171.25 18352.80



B

.. .



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> */ /* #include <sqlca.h> #include <sqlcli1.h> /* #include <decimal.h> /* #include ″samputil.h″ */ /* Header file for CLI #include ″v2sutil.h″ /* ODBC 2.0 CLI sample utilities

03 */ 04 */ sample code */ 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

/*--> SQLL1X58.SCRIPT */ /* int SQL_API_FN mrspsrv( void *reserved1, void *reserved2, struct sqlda *output_sqlda, struct sqlca *sqlca) */ /*here */ /* local variables */ SQLSMALLINT num_records; SQLINTEGER indicator;

/* 06 */

/* 07 */ /* 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 SQLSMALLINT

cli_sqlcode; length; /* 12 */

int main(SQLINTEGER argc, SQLCHAR *argv[] ) /*<-- */ { /* Declare CLI Variables */ /* SQLHANDLE henv, hdbc, hstmt1, hstmt2 ; */ SQLHENV henv ; SQLHDBC hdbc ; SQLHSTMT hstmt1, hstmt2 ; SQLRETURN rc ;

/* 13 */

/*--> */ SQLCHAR * stmt2 = ″SELECT count(*) FROM DB2RES1.STAFF″ ; SQLCHAR stmt1[80] ; SQLDOUBLE SQLINTEGER /*strcpy((char /*strcpy((char strcpy((char strcat((char

salary;

/* 14 */

counter = 0; *)stmt1, *)stmt1, *)stmt1, *)stmt1,

″SELECT ID, JOB , SALARY″ ) ″SELECT ID, NAME, SALARY″ ) ″SELECT ID, DEPT, SALARY″ ) ″ FROM DB2RES1.STAFF ORDER

; */ /* CHAR */ ; */ /* VARCHAR */ ; 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 ) ; */ CHECK_DBC(hdbc, rc);

/* 25 */

/*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 RESET which gets you to the DB2 in which this thread is “attached.”

DB2 requires a NULL CONNECT to be sure the user knows we connect to the “default” data source (DB2 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 = PLACED IN DSNT418I SQLSTATE DSNT415I SQLERRP

-751, ERROR: A STORED PROCEDURE HAS BEEN MUST_ROLLBACK STATE DUE TO SQL OPERATION COMMIT = 42987 SQLSTATE RETURN CODE = 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 //ICONV EXEC PROC=EDCICONV, // INFILE=, // OUTFILE=, // FROMC=′ IBM-037′ , // TOC=′ IBM-1047′

 1 2 3 4 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. 2. 3. 4.

Find out the code page for AIX. Find out the code page for OS/390. Use iconv() or EDCICONV to translate code pages. 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 F9=Shell

F2=Refresh F10=Exit

F3=Cancel Enter=Do

F8=Image



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 F9=Shell

F2=Refresh F10=Exit

F3=Cancel Enter=Do

F8=Image



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 F9=Shell

F2=Refresh F10=Exit

F3=Cancel F8=Image 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 Esc+5=Reset F9=Shell

F2=Refresh F6=Command F10=Exit

F3=Cancel F7=Edit Enter=Do



F4=List F8=Image



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 //RRSJCL //STEPLIB . . //SYSPRINT //DSNRRSAF //SYSUDUMP

JOB EXEC DD DD

MVS_jobcard_information PGM=RRS_application_program DSN=application_load_library DSN=DB2_load_library

DD DD DD

SYSOUT=* DUMMY 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 88 RRSAF-COMMIT 88 RRSAF-ROLLBACK * * INPUT FOR THE RRS/AF CALL * 01 RRS-INPUT. * RRSAF services constants 05 IDFYFN PIC X(18) 05 SIGNONFN PIC X(18) 05 CRTHRDFN PIC X(18) 05 TRMTHDFN PIC X(18) 05 TMIDFYFN PIC X(18) *

PIC X. VALUE SPACE. VALUE ′ R′ .

VALUE VALUE VALUE VALUE VALUE

′ IDENTIFY ′. ′ SIGNON ′. ′ CREATE THREAD ′. ′ TERMINATE THREAD ′ . ′ 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 05 05 05 05 *

CORRID COLLID ACCTTKN ACCTINT REUSE

PIC PIC PIC PIC PIC

RRSAF Variables set by 05 RIBPTR PIC 05 EIBPTR PIC 05 TERMCB PIC 05 STARTECB PIC 05 RETCODE PIC 05 RSNCODE PIC

X(12) X(18) X(22) X(6) X(8)

VALUE VALUE VALUE VALUE VALUE

SPACES. SPACES. SPACES. SPACES. SPACES.

DB2 X(4) X(4) X(4) X(4) 9(8) 9(8)

VALUE VALUE VALUE VALUE COMP. COMP.

SPACES. SPACES. ′0′. ′0′.

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 -RRSBMEX STEP01

RC 08

EXCP 67

CPU .00

SRB CLOCK .00 .0

SERV P 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 -RRSBMEX STEP01

RC 08

EXCP 67

CPU .00

SRB CLOCK .00 .0

SERV P 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 -RRSBMEX STEP01

RC 12

EXCP 67

CPU .00

SRB CLOCK .00 .0

SERV 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 -RRSBMEX STEP01

RC 12

EXCP 67

CPU .00

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

SRB CLOCK .00 .0

SERV PG 2417 0

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=® //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=®, // 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=&©LINK,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=®, // 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=&©LINK,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 PRotocol : Exci Conntype : Generic SInglesess : No DAtastream : User RECordformat : U Queuelimit : No Maxqtime : No OPERATIONAL PROPERTIES AUtoconnect : No INService : Yes SECURITY SEcurityname : ATtachsec : Local BINDPassword BINDSecurity Usedfltuser RECOVERY PSrecovery

Vtam | IRc | INdirect | Xm Appc | Lu61 | Exci Generic | Specific No | Yes User | 3270 | SCs | STrfield | Lms U | Vb No | 0-9999 No | 0-9999 No | Yes | All Yes | No

: : No : No

Local | Identify | Verify | Persist | Mixidpe PASSWORD NOT SPECIFIED No | Yes No | Yes

:

Sysdefault | None

Sessions

Sessions : XCIGSESS Group : EXCI DEscription : SESSION IDENTIFIERS Connection : XCIG SESSName : NETnameq : MOdename : SESSION PROPERTIES Protocol : Exci MAximum : 000 , 000 RECEIVEPfx : XG RECEIVECount : 005 SENDPfx : SENDCount : SENDSize : 04096 RECEIVESize : 04096 SESSPriority : 000 Transaction : OPERATOR DEFAULTS OPERId : OPERPriority : 000 OPERRsl : 0 OPERSecurity : 1 PRESET SECURITY USERId : 270

Appc | Lu61 | Exci 0-999 1-999 1-999 1-30720 1-30720 0-255

0-255

Getting Started with DB2 Stored Procedures

OPERATIONAL PROPERTIES Autoconnect : No INservice : Yes Buildchain : Yes USERArealen : 000 IOarealen : 04096 , 04096 RELreq : No DIscreq : No NEPclass : 000 RECOVERY RECOVOption : Sysdefault RECOVNotify

: None

No | Yes | All Yes | No 0-255 0-32767 No | Yes No | Yes 0-255 Sysdefault | Clearconv | Releaseses | Uncondrel | None None | Message | Transaction

Program

PROGram Group DEscription Language

: BOUNCE : HUGHPRG : :

RELoad : RESident : USAge : USElpacopy : Status : RSl : Cedf : DAtalocation : EXECKey : REMOTE ATTRIBUTES REMOTESystem : REMOTEName : Transid : EXECUtionset :

No No Normal No Enabled 00 Yes Below User

CObol | Assembler | Le370 | C | Pli | Rpg No | Yes No | Yes Normal | Transient No | Yes Enabled | Disabled 0-24 | Public Yes | No Below | Any User | Cics

Fullapi

Fullapi | Dplsubset

Transaction

TRANSaction : Group : DEscription : PROGram : TWasize : PROFile : PArtitionset : STAtus : PRIMedsize : TASKDATALoc : TASKDATAKey : STOrageclear : RUnaway : SHutdown : ISolate : REMOTE ATTRIBUTES DYnamic : REMOTESystem : REMOTEName : TRProf : Localq : SCHEDULING

EXCI DFH$EXCI DFHMIRS 00000 DFHCICSA

0-32767

Enabled 00000 Below User No System Disabled Yes

Enabled | Disabled 0-65520 Below | Any User | Cics No | Yes System | 0-2700000 Disabled | Enabled Yes | No

No

No | Yes

No | Yes

Chapter 13. Accessing Non-DB2 Resources

271

PRIOrity TClass TRANClass ALIASES Alias TASKReq XTRanid TPName XTPname

RECOVERY DTimout INdoubt RESTart SPurge TPUrge DUmp TRACe COnfdata SECURITY RESSec CMdsec Extsec TRANSec RSl

: 001 : No : DFHTCL00

0-255 No | 1-10

: : : : : : : : : : : : : : : :

0010 Backout No Yes Yes Yes Yes No

No | 1-6800 Backout | Commit | Wait No | Yes No | Yes No | Yes Yes | No Yes | No No | Yes

: : : : :

No No No 01 00

No | Yes No | Yes 1-64 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:

276



AIBRSNM1 to the PSB name.



AIBSFUNC is the subfunction and should be set to the string PREP.

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 77 77 77 77 77 77 77 77 77 77 77

GET-UNIQUE GET-HOLD-UNIQUE GET-NEXT ISRT DLET REPL CIMS APSB DPSB APPERR INVCMD NOKEY

PIC PIC PIC PIC PIC PIC PIC PIC PIC PIC PIC PIC

X(4) X(4) X(4) X(4) X(4) X(4) X(4) X(4) X(4) X(3) X(3) X(3)

VALUE VALUE VALUE VALUE VALUE VALUE VALUE VALUE VALUE VALUE VALUE VALUE

′ GU ′ . ′ GHU ′ . ′ GN ′ . ′ ISRT′ . ′ DLET′ . ′ REPL′ . ′ CIMS′ . ′ APSB′ . ′ DPSB′ . ′264′. ′440′. ′218′.

* DL/I CALL STATUS CODE 77 END-OF-DATABASE PIC X(4) VALUE ′ GB′ . * MESSAGES 77 MDEL 77 MADD 278

PIC X(40) VALUE ′ ENTRY WAS DELETED PIC X(40)

Getting Started with DB2 Stored Procedures

′.

77 MDIS 77 MUPD1 77 MTEST 77 MMORE 77 MINV 77 MUPD0 77 MNODATA 77 MNONAME 77 MNOENT 77 MISRTE 77 MDLETE 77 MREPLE

VALUE ′ ENTRY WAS ADDED PIC X(40) VALUE ′ ENTRY WAS DISPLAYED PIC X(40) VALUE ′ ENTRY WAS UPDATED PIC X(40) VALUE ′ TEST REQUEST WAS ENDED PIC X(40) VALUE ′ DATA IS NOT ENOUGH PIC X(40) VALUE ′ PROCESS CODE IS NOT VALID PIC X(40) VALUE ′ PLEASE UPDATE ENTRY PIC X(40) VALUE ′ NO DATA WAS ENTERED PIC X(40) VALUE ′ LAST NAME WAS NOT SPECIFIED PIC X(40) VALUE ′ SPECIFIED PERSON WAS NOT FOUND PIC X(40) VALUE ′ ADDITION OF ENTRY HAS FAILED PIC X(40) VALUE ′ DELETION OF ENTRY HAS FAILED PIC X(40) VALUE ′ UPDATE OF ENTRY HAS FAILED

′. ′. ′. ′. ′. ′. ′. ′. ′. ′. ′. ′. ′.

* VARIABLES 77 77 77 77

TEMP-ONE TEMP-TWO REPLY DBCTLID

PICTURE PICTURE PICTURE PICTURE

X(8) VALUE SPACES. X(8) VALUE SPACES. X(16). X(8).

* CONSTANTS 77 77 77 77 77 77 77 77 77 77 77 77

SSA1 APSBNME DPCBNME GSAMIN GSAMOUT APPLNME2 VAIBID TDBCTLID TDBCTLALL SFINIT SFTERM SFPREP

PIC PIC PIC PIC PIC PIC PIC PIC PIC PIC PIC PIC

X(9) X(8) X(8) X(8) X(8) X(8) X(8) X(8) X(8) X(4) X(4) X(4)

VALUE VALUE VALUE VALUE VALUE VALUE VALUE VALUE VALUE VALUE VALUE VALUE

′ A1111111 ′ . ′ DFSIVP34′ . ′ TELEPCB1′ . ′ TELEPCB2′ . ′ TELEPCB3′ . ′ DFSTDB2P′ . ′ DFSAIB ′ . ′ SYS3 ′. ′ ALL ′. ′ INIT′ . ′ TERM′ . ′ 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 02 AIBLEN 02 AIBSFUNC 02 AIBRSNM1 02 AIBRSNM2 02 AIBRESV1 02 AIBOALEN 02 AIBOAUSE 02 AIBRESV2 02 AIBRETRN 02 AIBREASN 02 AIBRESV3 02 AIBRESA1 02 AIBRESA2 02 AIBRESA3 02 AIBRESV4 02 AIBSAVE 02 AIBTOKN 02 AIBTOKC 02 AIBTOKV 02 AIBTOKA

PIC X(8). PIC 9(9) USAGE BINARY. PIC X(8). PIC X(8). PIC X(8). PIC X(8). PIC 9(9) USAGE BINARY. PIC 9(9) USAGE BINARY. PIC X(12). PIC 9(9) USAGE BINARY. PIC 9(9) USAGE BINARY. PIC X(4). USAGE POINTER. USAGE POINTER. USAGE POINTER. PIC X(40). OCCURS 18 TIMES USAGE POINTER. OCCURS 6 TIMES USAGE POINTER. PIC X(16). PIC X(16). 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 02 SEG-KEY-NAME 02 SSA-KEY 02 FILLER

PIC PIC PIC PIC

X(8) VALUE ′ A1111111′ . X(11) VALUE ′ ( A1111111 =′ . X(10). X VALUE ′ ) ′ .

LINKAGE SECTION. 280

Getting Started with DB2 Stored Procedures

01 IOPCB. 02 LTERM-NAME 02 IO-RESERVE-IMS 02 IO-STATUS 02 CURR-DATE 02 CURR-TIME 02 IN-MSN 02 MODNAME 02 USERID *01 DBPCB. * 02 DBD-NAME * 02 SEG-LEVEL * 02 DBSTATUS * 02 PROC-OPTIONS * 02 RESERVE-DLI * 02 SEG-NAME-FB * 02 LENGTH-FB-KEY * 02 NUMB-SENS-SEGS * 02 KEY-FB-AREA

PIC PIC PIC PIC PIC PIC PIC PIC

X(8). X(2). X(2). X(4). X(4). X(4). X(8). X(8).

PIC PIC PIC PIC PIC PIC PIC PIC PIC

X(8). X(2). X(2). X(4). X(4). X(8). 9(4). 9(4). X(17).

* DATA AREA FOR DB2 STORED PROCEDURES INPUT/OUTPUT 01 01 01 01 01

DB2IO-COMMAND DB2IO-LAST-NAME DB2IO-FIRST-NAME DB2IO-EXTENSION DB2IO-ZIP-CODE

PIC PIC PIC PIC PIC

X(8). X(10). X(10). X(10). X(7).

* DATA AREA FOR DB2 STORED PROCEDURES OUTPUT 01 01 01 01 01

DB2OUT-SEGMENT-NO DB2OUT-AIBRETRN DB2OUT-AIBREASN DC-ERROR-CALL DC-ERROR-STATCDE

PIC PIC PIC PIC PIC

9(4). 9(9) USAGE BINARY. 9(9) USAGE BINARY. X(4). 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.

*

282

CHECK THE LEADING SPACE IN INPUT LAST NAME AND TRIM IT OFF

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 DECLARE DECLARE DECLARE DECLARE DECLARE DECLARE DECLARE DECLARE DECLARE

1 1 1 1 1 1 1 1 1 1

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

CHAR(8); CHAR(10); CHAR(10); CHAR(10); CHAR(7); BIN FIXED(15); BIN FIXED(31); BIN FIXED(31); CHAR(4); 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 DB2IO_LAST_NAME DB2IO_FIRST_NAME DB2IO_EXTENSION DB2IO_ZIP_CODE

= = = = =

*/

*/

′ DIS ′; /* ADD & WTO */ ′ LAST1 ′; ′ FIRST1 ′; ′ X-XXX-XXXX′ ; ′ XXX/XXX′ ;

DISPLAY(′ DB2IO_COMMAND DISPLAY(′ DB2IO_LAST_NAME DISPLAY(′ DB2IO_FIRST_NAME DISPLAY(′ DB2IO_EXTENSION DISPLAY(′ DB2IO_ZIP_CODE DISPLAY(′ DB2OUT_SEGMENT_NO DISPLAY(′ DB2OUT_AIBRETRN DISPLAY(′ DB2OUT_AIBREASN DISPLAY(′ DC_ERROR_CALL DISPLAY(′ DC_ERROR_STATCDE

= = = = = = = = = =

′ ′ ′ ′ ′ ′ ′ ′ ′ ′

|| || || || || || || || || ||

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 (′ ** 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 DISPLAY(′ DB2IO_LAST_NAME DISPLAY(′ DB2IO_FIRST_NAME DISPLAY(′ DB2IO_EXTENSION DISPLAY(′ DB2IO_ZIP_CODE DISPLAY(′ DB2OUT_SEGMENT_NO DISPLAY(′ DB2OUT_AIBRETRN DISPLAY(′ DB2OUT_AIBREASN DISPLAY(′ DC_ERROR_CALL DISPLAY(′ DC_ERROR_STATCDE

= = = = = = = = = =

′ ′ ′ ′ ′ ′ ′ ′ ′ ′

|| || || || || || || || || ||

**′ ) ;

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 );

/*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 Code

Reason Code

Possible Cause

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

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

72

DRA RESLIB is not authorized

0108

0110

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 Code

Reason Code

Possible Cause

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

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

0108

290

Getting Started with DB2 Stored Procedures

Table 22 (Page 2 of 2). Existing Reason and Return Codes Return Code

0110

Reason Code

Possible Cause

0320

PSBW/DMB/PSB pool too small

0324

Invalid ′ L′ or ′LS′ option

0328

Fast Path buffer fix error

032C

Invalid processing intent

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: • •

292

The ACBNAME specification must match the LU name assigned to IMS The SCHED specification must match the IMS system ID.

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, LINKAGE, COLLID, STAYRESIDENT, IBMREQD, PARMLIST, RESULT_SETS, WLM_ENV, COMMIT_ON_RETURN ) VALUES(′ IMSBMS′ , ′ ′, ′ ′, ′ SAMPLESP′ , ′ ′, ′ N′ , ′ CHAR(8) IN′ , 1, ′ WLMENV2′ , ′ N′ ) ; COMMIT;

LUNAME, LOADMOD, LANGUAGE, ASUTIME, RUNOPTS, PGM_TYPE, EXTERNAL_SECURITY, ′ ′, ′ COBOL′ , ′ ′, ′ M′ ,

′ IMSBMs′ , 0, ′ N′ ,

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 IMSTRAN CHAR (8) IMSDATA VARCHAR(71) COMMIT ;

DEFAULT, NOT NULL, NOT NULL);

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, LINKAGE, COLLID, STAYRESIDENT, IBMREQD, PARMLIST, RESULT_SETS, WLM_ENV, COMMIT_ON_RETURN ) VALUES(′ IBUBMS′ , ′ ′, ′ ′, ′ SAMPLESP′ , ′ ′, ′ N′ , ′ CHAR(8) IN, CHAR(71) IN 1, ′ WLMENV2′ , ′ Y′ ) ; COMMIT;

LUNAME, LOADMOD, LANGUAGE, ASUTIME, RUNOPTS, PGM_TYPE, EXTERNAL_SECURITY, ′ ′, ′ COBOL′ , ′ ′,

′ IBUBMs′ , 0,

′ M′ ,

′ N′ ,

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, LINKAGE, COLLID, STAYRESIDENT, IBMREQD, PARMLIST, RESULT_SETS, WLM_ENV, COMMIT_ON_RETURN ) VALUES(′ IBDBMS′ , ′ ′, ′ N′ , ′ SAMPLESP′ , ′ ′, ′ N′ , ′ CHAR(8) IN, CHAR(71) IN 0, ′ WLMENV2′ , ′ N′ ) ; COMMIT;

LUNAME, LOADMOD, LANGUAGE, ASUTIME, RUNOPTS, PGM_TYPE, EXTERNAL_SECURITY, ′ ′, ′ COBOL′ , ′ ′, ′ M′ ,

′ IBDBMs′ , 0, ′ N′ ,

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

dynamic SQL

static SQL

static compound SQL

static unfenced SQL

Type

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 INSERT INSERT INSERT INSERT INSERT INSERT INSERT INSERT INSERT

INTO INTO INTO INTO INTO INTO INTO INTO INTO INTO

PRESIDENTS PRESIDENTS PRESIDENTS PRESIDENTS PRESIDENTS PRESIDENTS PRESIDENTS PRESIDENTS PRESIDENTS PRESIDENTS

(NAME) (NAME) (NAME) (NAME) (NAME) (NAME) (NAME) (NAME) (NAME) (NAME)

VALUES VALUES VALUES VALUES VALUES VALUES VALUES VALUES VALUES VALUES

(:president1); (:president2); (:president3); (:president4); (:president5); (:president6); (:president7); (:president8); (:president9); (: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 (seconds)

Compound (seconds)

Static (seconds)

Dynamic (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 Called

In Memory (SQLZ_HOLD_PROC)

Not in Memory (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

310

APPL ACBNAME=SCC370, APPC=YES, AUTOSES=10, DDRAINL=NALLOW, DMINWNL=16, DMINWNR=16,

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. 2. 3. 4. 5. 6.

Create a working directory on AIX. Go to working directory. Copy sqllib/samples/cli/samputil.c to working directory. Copy sqllib/samples/cli/samputil.h to working directory. FTP the redbook samples from diskette \AIX\CLI\*. 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. 2. 3. 4. 5.

Create a working directory on AIX. Go to working directory. Copy sqllib/samples/cli/mrspsrv.*. Copy sqllib/samples/cli/makefile. 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. 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.

IMSBMCBM

imubmcox.c

SHR(1)

Performs similar function to the MVS client 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.

IMUBMCBM

pr0cxs

DH

This is inpsrv.sqc, identical to the OS/2 version pr0c2s. It loops through the parameters passed by the caller to insert rows into a table.

pr0cxcc2.sqc

pr0c2ccx

DH

Renamed from sample inpcli shipped with DB2 Common 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.

pr0c2s

pr0c2crx.cmd

DH

Renamed from sample inpcli shipped with DB2 Common 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.

pr0c2s

pr0r2crx.cmd

DH

Variation on inpcli, going to OS/2.

pr0r2s.cmd

sm0pmcrx.cmd

HN

Passes DB2 commands to stored procedure on OS/390 (MVS) and retrieves results.

SM0PMS

sr1

NHR(1)

Modified version of mrspcli.c shipped with DB2 Common Server V2 and DB2 Universal Database V5. It can go to any of the mrspsrv.c equivalents on any platform. Figure 126 on page 237 shows how client sr1 interacts with other stored procedures.

SR1CMS SR1OMS SR1PMS SR1XMS 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

dd1c2s

Used as a simple test for measuring performance. See 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 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.

dd1c2cr2

imdbmcb2

SH

This is a sample MVS batch client program that invokes 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.

IMSBMS

pr0cxcc2

DH

Renamed from sample inpcli. shipped with DB2 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.

pr0cxs

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 Common Server V2 and DB2 Universal Database V5. This is a stored procedure that accepts calls from clients. It 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.

PR0C2CCN pr0c2crx.cmd pr0c2ccx.sqc

pr1c2s

DH

Modified from pr0c2s (inpsrv), this stored procedure is 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.

PR0C2CCN

pr2c2s

DH

Modified from pr0c2s (inpsrv), this stored procedure is 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.

PR0C2CCN

pr3c2s

DH

Modified from pr0c2s (inpsrv), this stored procedure is 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.

PR0C3CCN

pr4c2s

DH

Identical to pr2c2s except this stored procedure is 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.

PR0C3CCN

pr0b2cc2

DHN

Invokes pr0b2s to update news in color.

pr0b2s

tr0c2cc2

D

Calls the tr0c2s stored procedure. See 9.3, “Blocking Rows” on page 180

tr0c2s

tr0c2s

D

A example of transferring multiple rows of data by 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

tr0c2cc2

mr3c2co2

SD

CLI client program processing a result set based on a 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.

mr3c2s

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 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.

mr3c2co2

mr4c2co2

SD

CLI client program processing three result sets based on 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

mr4c2s

SD

C program with embedded SQL. Accepts three SQL 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.

mr4c2co2

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 Procedures” on page 336. spbo1.sp is missing.

spbo1.bas

pr0r2cr2.cmd

NHD

Modified from inpcli.

pr0r2s.cmd

pr0cxcr2.cmd

NHD

This is a REXX OS/2 client calling an AIX C stored 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.

pr0cxs

sm0pmcr2.cmd

NHD

This is a REXX OS/2 client calling an MVS PL/I stored 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.

SM0PMS

sr2o2s.c

NHR(1)

This is renamed from the V2 CLI result set sample, mrspsrv.c.

sr2o2co2.c

sr2o2co2.c

NHR(1)

This is renamed from the V2 CLI result set sample, mrspcli.c.

sr2o2s.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 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.

IMDBMS

PR0C2CCN

DH

This is a client call to a stored 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.

pr0c2s

S02VNCVN

D

This client calls a stored procedure and determines the median salary of all the employees listed in the staff table of the sample database. Renamed from the UDB sample salcltvb.

S02VNS

S02VNS

D

This stored procedure accepts calls from a client that is 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.

S02VNCVN

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 requests that a display thread command be issued on the MVS system. The resulting information from the command is passed back to the client.

SM0PWS

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: •

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

cl2o2s

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 S H D R

-

SIMPLE WITH NULLS linkage convention SIMPLE linkage convention using host variables to pass parameters using SQLDA to pass parameters 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 STAFF table. Similar to PL/I version SR1PMS. See 11.12.2, “Differences in Handling Result Sets” on page 237

(AIX)mrspcli.c (AIX)sr1.c

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 Guide and Reference

SPD29

SPD29

SHR(2)

Sample stored procedure from DB2 for OS/390 V5 Call Level Interface Guide and Reference

APD29

SRSOMS

SR(1)

Sample stored procedure demonstrating single result set. 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:

SRSBMCBM

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)

(AIX)sr1.c

CLI version of UDB CLI samples mrspsrv.c against the 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

BOUNCE

Possible partners

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 the CA0BMS MVS stored procedure using a constant as the stored procedure name. It used the stored procedure linkage convention SIMPLE.

CA0BMS

CA0BMS

SH

This stored procedure calls an external program, EXTPROG, that does not access DB2 data.

CA0BMCBM

CA1BMCBM

SH

This is a sample MVS batch client program that invokes the CA1BMS MVS stored procedure using a constant as the stored procedure name. It used the stored procedure linkage convention SIMPLE.

CA1BMS

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 stored procedure.

CA0BMCBM

EXTPROG1

This is the external program called by the CA1BMCBM stored procedure. It contains SQL code to update a DB2 Table.

CA1BMCBM

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 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.

IMSBMS

IMDBMS

SH

This stored procedure shows how to activate an IMS transaction through APPC. IMDBMS does a 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. The received IMS data is stored into a VARCHAR parameter and returned to the client with the number of lines received.

IMS IVP transactions IMDBMCBM imdbmcb2 imdbmcbn

IMUBMCBM

SHR

This is a sample MVS batch client program that invokes 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

IMUBMS

SHR

This stored procedure shows how to activate an IMS transaction through APPC. IMDBMS does a 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.

IMS IVP transactions

IMSBMCBM

SHR

This is a sample MVS batch client program that invokes 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

IMSBMS

SHR

This stored procedure shows how to activate an IMS transaction through APPC. IMSBMS does a 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.

IMS transaction PART

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 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

MRSBMS

R

This stored procedure returns two result sets back with NULL columns.

MRSBMCBM

This DB2 sample application COBOL provides a means to allocate main storage to MR5BMCBM. This is required for program MR5BMCBM to do pointer manipulation in using this storage for the SQLDA.

MR5BMCBM

MR0BMCBM

MR5BMCBM

NDR

This is a sample MVS BATCH client program that invokes 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

MR5BMS

NR

This stored procedure shows how to receive multiple 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.

MR5BMCBM

PA0BMCBM

NH

This is a sample MVS BATCH client program that invokes the PA0BMS MVS stored procedure using a constant as the stored procedure name. It uses the SIMPLE WITH NULLS linkage.

XC0BMCBM

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 invokes the IMS V6 IVP transactions and updates a DB2 table. It uses RRSAF to coordinate the updates between DB2 and IMS V6, and to attach them to DB2.

IMS IVP transactions

S10BMCPM

NHR(1)

This is a sample COBOL MVS BATCH client program 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.

MRSPSRV

S01BMCC2

NH

This is a sample MVS batch client program that invokes the ″pr0c2s″ a OS2 stored procedure.

pr0c2s

SD0BMCBM

NH

This is a sample MVS batch client program that invokes 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.

SD0BMS

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 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.

SD0BMCBM

SRSBMCBM

R

This is a sample MVS batch client program that invokes the SRSBMS MVS stored procedure, using a single result set. By changing SYSPROCEDURES to point to different modules and collections, this client can execute the PL/I version (SRSPMS) or the CLI version (SRSOMS) of the stored procedure.

SRSBMS SRSOMS SRSPMS

SRSBMS

R

This MVS stored procedure shows how to return a single result set with NULL columns.

SRSBMCBM

TS2BMCB2

SH

This is a sample MVS batch client program that invokes 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.

ts2b2s

TS0BMCBM

D

This is a sample MVS batch client program that invokes the TS0BMS MVS stored procedure using an SQLDA to pass parameters.

TS0BMS

TS0BMS

SH

This stored procedure is a sample of how to receive parameters without indicator variables.

TS0BMCBM

XC0BMCBM

SH

This is a sample MVS batch client program that invokes the XC0BMS MVS stored procedure using SIMPLE parameters.

XC0VMS

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 stored procedure. We modified SYSIBM.SYSPROCEDURES to pick up the PL/I module MRSPMS instead of the COBOL module MRSBMS, and run client MRSBMCBM.

MRSBMCBM

SM0PMCPM

NH

Copy of sample SDSNSAMP(DSN8EP1), JCL from SDSNSAMP(DSNTEJ6P). Client calling SM0PMS.

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

sm0pmcr2.cmd sm0pmcrx.cmd SM0PMCPM

Copy of sample SDSNSAMP(DSN8EP2), JCL in SDSNSAMP(DSNTEJ6S). Stored procedure using IFI to run DB2 commands. It processes the display thread DB2 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 positional run-time parameter to specify location and stored procedure name.

SRSPMS

SRSPMS

R(1)

PL/I version of COBOL sample SRSBMS: single result set stored procedure. The stored procedure address space needs to allocate a SYSPRINT statement when running SRSPMS.

SRSPWCPM

SR1PMS

NHR(1)

PL/I version of UDB CLI samples mrspsrv.c against the STAFF table.

(AIX)mrspcli.c (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

SJXPART1

n/a

APPC/IMS sample from Client/Server Computing with 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.

n/a

SJXPART2

n/a

APPC/IMS sample from Client/Server Computing with 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.

n/a

376

Getting Started with DB2 Stored Procedures

Possible partners

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.



380

Transaction Tx5 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 (Length in Bytes)

Columns

Indexes

Preload ( % )

Variable/ Fixed

Partitioned

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 (22)

3

1

12

Variable

No

T5

100,000 (91)

4

1

100

Fixed

No

T6

240,000 (42)

8

2

12

Variable

No

T7

240,000 (679)

21

2

12

Fixed

Yes

T8

800,000 (322)

17

1

20

Fixed

Yes

T9

2,399,791 (75)

10

1

12

Variable

Yes

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)

BP0

2000

System defaults

BP1

2000

Table T1

382

Getting Started with DB2 Stored Procedures

Table and Index

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 T9 T6 T6

BP5

4000

Table T4 Table T6

BP6

20000

Table T9

BP7

12500

Table T7

BP8

20000

Table T8

Total

76500

Index Index Index 1 Index 2

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 = |-------------------------| PowerBuilder client tps | ---If OS/2 client tps PowerBuilder client tps # OS/2 clients # PowerBuilder clients then

= = = =

---| | * (# OS/2 clients)| + (# PowerBuilder clients) | | ----

1.476 tps .128 tps 60 6

Estimated PowerBuilder Clients

------| | | 1.476 tps | = |----------- * 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 Clients

OS/2 Clients

Actual Clients

Est. PowerBuilder 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

T2

Tx2

Tx3

Tx5

Tx6

Tx7

Yes

T3

Yes

T4

Yes

Yes Yes

T5 T6

Tx4

Yes Yes

T7

Yes Yes

T8

Yes

T9

Yes

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

T6

Yes

T7 T9

392

Tx2

Tx3

Tx4

Tx5

Tx6

Tx7 Yes

Yes Yes

Getting Started with DB2 Stored Procedures

Yes Yes

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

T1

Yes

T2

Yes

T3

Yes

Tx4

Tx5

Tx6

Tx7

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

T5

Tx4

Tx5

Tx6

Tx7

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 T5

Tx1

Tx2

Tx3

Tx4

Tx5

Tx6

Tx7

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

T3

Yes

T8

Yes

T9

Yes

396

Tx2

Tx3

Tx4

Tx5

Tx6

Tx7

Yes

Getting Started with DB2 Stored Procedures

Yes

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

T4

Yes

Yes

T6

Yes

Yes

T7 T9

Tx3

Tx4

Tx5

Tx6

Yes Yes

Tx7

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 = |-------------------------| PowerBuilder client tps | ---If OS/2 client tps PowerBuilder client tps # OS/2 clients # PowerBuilder clients then

= = = =

---| | * (# OS/2 clients)| + (# PowerBuilder clients) | | ----

1.41 tps .128 tps 40 6

Estimated PowerBuilder Clients

------| | | 1.41 tps | = |----------- * 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 Clients

OS/2 Clients

Actual Clients

Est. PowerBuilder 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 AIX - User

C10 Running DDCS for AIX - System

9121-742 Running DB2 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 •



400

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.

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 •





402

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

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

T2

Tx2

Tx3

Tx5

Tx6

Tx7

Yes

T3

Yes

T4

Yes

Yes Yes

T5 T6

Tx4

Yes Yes

T7

Yes Yes

T8

Yes

T9

Yes

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

T6

Yes

406

Tx2

Tx3

Getting Started with DB2 Stored Procedures

Tx4

Tx5

Tx6

Tx7 Yes

Table 61 (Page 2 of 2). Potential Lock Contention for Transaction Tx2: DDCS for AIX Table

Tx1

T7 T9

Tx2

Tx3

Tx4

Yes

Tx5

Tx6

Tx7 Yes

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

T1

Yes

T2

Yes

T3

Yes

Tx4

Tx5

Tx6

Tx7

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

T5

Tx4

Tx5

Tx6

Tx7

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 T5

Tx1

Tx2

Tx3

Tx4

Tx5

Tx6

Tx7

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

T3

Yes

T8

Yes

T9

Yes

410

Tx2

Tx3

Tx4

Tx5

Tx6

Tx7

Yes

Getting Started with DB2 Stored Procedures

Yes

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

T4

Yes

Yes

T6

Yes

Yes

T7 T9

Tx2

Tx3

Tx4

Tx5

Tx6

Yes Yes

Tx7

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: •

412

How does the data throughput compare to my environment or proposed environment? − On the LAN? − Through DDCS? − Through the NCP?

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 PC704 PC704 PC704

with with with with

4x100 4x166 2x166 1x166

MHz MHz MHz MHz

Pentium Pentium Pentium Pentium

processors Pro processors with 512 KB cache Pro processors with 512 KB cache 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 (Length in Bytes)

Columns

Indexes

Preload Value (%)

T1

100,000 (91)

4

1

100

T2

240,000 (42)

8

1

30

T3

240,000 (679)

21

2

30

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 = |-------------------------| PowerBuilder client tps | ---If OS/2 client tps PowerBuilder client tps # OS/2 clients # PowerBuilder clients then

= = = =

---| | * (# OS/2 clients)| + (# PowerBuilder clients) | | ----

2.630 tps 0.146 tps 5 6

---|

---|

Appendix C. DB2 Connect Result Set Study

419

Estimated PowerBuilder Clients

| 2.630 tps = |----------- * | 0.146 tps | ----

| 5 clients | + (6 clients) | | ----

= 96 clients

Table 69. Number of Clients in Relation to Aggregate Throughput (TPS) Throughput (TPS)

PowerBuilder Clients

OS/2 Clients

Actual Clients

Est. PowerBuilder 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 (TPS)

PC704 (1X166)

14.31

45.61%

15.07

PC720 (4X100)

PC704 (2X166)

33.77%

26.29% 26.37%

16.05

21.35

60.59%

27.52% 33.21%

48.10%

36.78%

67.87%

37.57%

21.54

35.69%

21.77 23.31

27.23% 13.02%

20.93

9672-R61 24.49%

16.00

19.12

PC704 (4X166)

37.39% 17.78%

54.74%

23.75 24.14

37.30% 41.38%

39.45%

41.01% 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 Dot line Dash

- Qry1_2 - Qry1_9 - 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 Pentium Pentium Pentium Pentium

430

II II II II

Processor Processor Processor Processor

SPECint_base95 300 266 266 233

MHz MHz MHz(w/ECC memory) MHz

11.60 10.80 10.40 9.49

Pentium Pro Processor 200 MHz Pentium Pro Processor 180 MHz Pentium Pro Processor 150 MHz

8.20 7.28 6.25

Pentium Processor 200 MHz MMX Pentium Processor 166 MHz MMX

6.41 5.59

Pentium Pentium Pentium Pentium Pentium Pentium Pentium Pentium

5.00 4.52 4.05 3.96 3.55 3.20 2.88 2.39

Processor Processor Processor Processor Processor Processor Processor Processor

200 MHz 166 MHz 150 MHz 133 MHz 120 MHz 100 MHz 90 MHz 75 MHz

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 OS/2 IBM DRDA AIX/6000 OS/400 SAA C/370 RISC System/6000 PowerPC CICS RACF VisualGen 400 DATABASE 2 COBOL/370 VTAM PowerPC 601 RMF PROFS

MVS/ESA AIX Distributed Relational Database Architecture ACF/VTAM CICS/ESA IMS/ESA AD/Cycle Language Environment ES/9000 PS/2 IMS SP SP1 VisualAge AT Presentation Manager LANStreamer Resource Measurement Facility DatagLANce

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 System/390 Redbooks Collection Networking and Systems Management Redbooks Collection Transaction Processing and Data Management Redbook Lotus Redbooks Collection Tivoli Redbooks Collection AS/400 Redbooks Collection RS/6000 Redbooks Collection (HTML, BkMgr) RS/6000 Redbooks Collection (PostScript) RS/6000 Redbooks Collection (PDF Format) Application Development Redbooks Collection

Subscription Number SBOF-7201 SBOF-7370 SBOF-7240 SBOF-6899 SBOF-6898 SBOF-7270 SBOF-7230 SBOF-7205 SBOF-8700 SBOF-7290

Collection Kit Number SK2T-2177 SK2T-6022 SK2T-8038 SK2T-8039 SK2T-8044 SK2T-2849 SK2T-8040 SK2T-8041 SK2T-8043 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 [email protected] 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:

In United States: In Canada: Outside North America: •



United States (toll free) Canada (toll free)

1-800-879-2755 1-800-IBM-4YOU

Outside North America (+45) 4810-1320 - Danish (+45) 4810-1420 - Dutch (+45) 4810-1540 - English (+45) 4810-1670 - Finnish (+45) 4810-1220 - French

(long (+45) (+45) (+45) (+45) (+45)

distance charges apply) 4810-1020 - German 4810-1620 - Italian 4810-1270 - Norwegian 4810-1120 - Spanish 4810-1170 - Swedish

Mail Orders — send orders to: I B M Publications 144-4th Avenue, S.W. Calgary, Alberta T2P 3N5 Canada

IBM Direct Services Sortemosevej 21 DK-3450 Allerød D enmark

Fax — send orders to: United States (toll free) Canada Outside North America



Internet [email protected] [email protected] [email protected]

Telephone orders

I B M Publications Publications Customer Support P.O. Box 29570 Raleigh, NC 27626-0570 USA •

IBMMAIL usib6fpl at ibmmail caibmbkz at ibmmail dkibmbsh at ibmmail

1-800-445-9269 1-403-267-4455 (+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 [email protected]



On the World Wide Web Redbooks Web Site IBM Direct Publications Catalog



http://www.redbooks.ibm.com 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 [email protected] 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

First name

Order Number

Quantity

Last name

Company Address City

Postal code

Telephone number

Telefax number



Invoice to customer number



Credit card number

Credit card expiration date

Card issued to

Country VAT number

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 Special Characters .bas file 334, 336 &IWMSSNM symbolic parameter

32

Numerics 3270 terminal emulation 3745 379 5648-A25 85 9121-742 379

307

A abend 315 absolute-path!function-name 128 ACBNAME specification 292, 311 ACCEPT SQL CALL parameter 9 access profile 71 accounting 3, 7 ACTION(REJECT) specification 34 administration tasks (DB2 for MVS/ESA) 13 administration tool (ODBC) 187 Advanced Program-to-Program Communication See APPC AERTDLI interface 274 AIB 274, 275, 276 AIBREASN field 290 AIBTDLI interface 274 AIX DB2 Connect 68 diskette 347, 351 prerequisites 3 product overview 68 VAB 331 aliases 86, 87, 151 ALL TEST suboption 313, 315 allied address space 11 ALLOCATE CURSOR statement CLI 222 format 153 relationship among new SQL statements 153 SQL extension 152 AMODE parameter 100 APAR PN78797 85 PQ02582 221 PQ06894/UQ11231 221 PQ07001 221 PQ11161 18 UN86398 308 UN86441 308 UN86554 85 UN87131 308

 Copyright IBM Corp. 1996 1998

APF authorized 290 APPC access CICS systems 265 connection 5 DB2 Connect 68 IMS 272, 292 including code in your stored procedure 291 MVS definitions 310 preferences file 315 PWS debug tool 306, 308 RRS 265 RRSAF 260 APPCPMxx member 311 APPLENV parameter 53, 55 application environment CLI 229, 231 problem 54 QUIESCED state 58 WLM-established stored procedure 29 APPSUPP option 227 APSB function call 274, 276, 290 array host variable 121 SQLarrayCALL 337 VAB 332, 335 ASA2013I message 65 ASA2016I message 65 ASCCOLL option 227 ASCHPMxx member 310 ASCII 191 Assembler COLLID column 14 DB2 on MVS 85 stored procedures overview 1 ASSOCIATE LOCATORS statement CLI 222 format 153 relationship among new SQL statements 153 SQL extension 152 ASUTIME column 14 AT debug command 319, 327 ATBPBI module 293 ATBSDFMU utility 293 ATR130I message 65 ATRBACK 275, 277 ATRCMT 277 ATRRRS procedure 63 AUTH SIGNON function call 257, 259 AUTHID column 14, 15 authorization client program 132, 265 ID 13, 14 required to run a stored procedure 134 RRSAF 255, 259, 261 WLM-established address space 53

447

auto c o mmi t 194 AUTOCOMMIT keyword 141, 204, 205 automatic control 32, 33, 57, 58 AVAILABLE state 34

B backup 70 BACKUP command 106 BASIC extensions 333 language 79 statements 342 VAB 331, 332 batch debug tool 306, 314, 328 DSNTIAD program 103 EXCI call 269 mode 315 multiple TCBs 272 MVS 306 benchmark 377 bind CLI 221 client program 147 column 144, 145 DB2 on MVS 99, 100 DDCSMVS.LST file 131 DRDA 131 DYNAMICRULES 7 EXCI 269 files 83 ODBC 187 parameter statement 197 REXX 132 SQLBindParameter 194 stored procedure 100 VAB 332 validation 83 BLOCK TEST suboption 313 blocking rows 180 BMP 291 B o r l a n d C + + 187 bottleneck 399 break mode 342 breakpoints CODE-LISTING window 318, 323 CODE/370 306, 312, 315 debug tool 316 VAB 331, 340 bridges 431 buffer DB2 Connect result set study 418 START PROCEDURE command 19, 104 SYSIBM.SYSPROCEDURES 14 workload 406, 410 buffer pool 382, 383, 418 build .bas files 334

448

Getting Started with DB2 Stored Procedures

build (continued) DB2CLI.PROCEDURES 332 files 334 r e m o t e debug 343 samples 78 stored procedure 112, 336 VAB 134, 331 build files 334

C C C/370 305 CLI 82 client p r o g r a m 130, 132 COLLID column 14 data type 90, 197 DB2 for AIX 105 DB2 for OS/2 105 DB2 on MVS 85 DB2 on the workstation 105 DB2CLI.PROCEDURES 79 diskette 347, 348, 351, 354 example 94, 108, 115, 116 performance 300, 303 precompiler 132 prelink utility 102 RENT compiler option 102 SQLarrayCALL 337 stored procedures overview 1 TEST compiler option 312, 313 VAB 332, 335 Visual Basic VisualGen 134 Windows 187, 220 C/370 95, 102, 305 C++ client program 132 COLLID column 14 DB2 for AIX 105 DB2 for OS/2 105 DB2 on MVS 85 DB2 on the workstation 105 DB2CLI.PROCEDURES 79 precompiler 132 SQLarrayCALL 337 stored procedures overview 1 VAB 332 Windows 187 CAE 69 CAE for Windows 188, 379, 412 CAF DB2-established address space 87 link-edit 100 performance goals 29 RACF 11 WLM-established address space 59 call attachment facility See CAF

CALL DSNALI statement 87 CALL DSNRLI statement 257 call level interface See CLI 77 call stack 331, 342 CALL statement authorizations 134 CALL statement 117 CLI and ODBC applications 127 connection to the DB2 server 117 DB2 Common Servers V1 71 DB2 on MVS 86, 119 DB2 on the workstation 123 DDF 8 DRA 274 embedded SQL 123 examples 122, 125 flow 7 in a stored procedure 106 location specification 129 MRSP 151 NULL 91, 121 number of parameters 18 performance goals 29 preparation 193 privilege 101 qualify 111 queuing 34 SET CURRENT PACKAGESET statement SIMPLE linkage convention 90 SQL extension 153 SQLCODE 96 SQLeproc 127 SQLPrepare 141, 193 statement handle 145 stored procedures overview 1 Sysplex 32 VAB 337, 338 Visual Basic 195, 196 WLM-established stored procedure 30 calling other programs 97 CANCEL command 33 capacity planning 377, 384, 399, 412 case sensitivity 53, 112, 129, 236 cbColDef 190 cbValueMax 190 CCOPT statement 224 CCU 386, 388, 401, 402 CEETEST 314 CFRM policy 59, 61 CGI 69 CHAR data type 96 character conversion 17 CHARACTER parameter 17 CICS access IMS databases 273 APPC 292 CODE/370 306 commit coordination 11

97

CICS (continued) COMMIT_ON_RETURN 18 DRA 273 methods to access 265 MQI 272 MQSeries 291 non-DB2 resources 265 performance goals 29 RRS 265 tables 269 CIMS function call 274, 275 cl2o2cr2 302 cl2o2s 302 classification rules associating with stored procedures 45 definition menu 45 qualifier 28 susbsystem type 32 CLEAR MONITOR debug command 327 CLI advantages 83 application trace 230 CALL statement 127 client program 130, 132 code page translation between platforms 250 code specific to the OS/390 implementation 247 coding the stored procedure 222 compiling 223 DB2 Connect result set study 429 DB2 on MVS 85 DB2 on the workstation 82 DB2 Version 5 221 DB2CLI.PROCEDURES 77 diagnosis trace 230 diskette 347, 348, 351, 354 escape clause 135 executing the client program 222 host variables 82 how to invoke a stored procedure 221 implementing 221 MR3C2CO2.C client program 139 MRSP 137, 151, 152 MRSP for your client application in the workstation or if you are 137 parameters 118 performance 302 porting applications 235 PowerBuilder 206 precompile 106 prelinking and link-editing 226 privilege 101 problem determination tracing 229 PROCCOLS sample 78 PROCS sample 78 receiving parameters 222 result sets 146, 223 sample 116, 203 stored procedures address space requirements 228

Index

449

CLI (continued) SYSIBM.SYSPROCEDURES 228 trace 189 VAB 332, 337 Visual Basic 189 Windows 187 CLI0109E message 190 clicall.c 139 clicked event 211 client pro gra m CODE/370 307 coding 117 DB2 on the workstation 132 MRSP 137 preparation 130 VAB 332, 337, 339 VisualGen 134 client/server 1, 331, 377 close 200 CLSE function call 274 CM/2 308, 311 CMD file 106 CMS 306 COBOL batch debug tool 328 calling other programs 97 client program 130 COBOL/370 305 COLLID column 14 data type 90 DB2 for AIX 105 DB2 for OS/2 105 DB2 on MVS 85 DB2 on the workstation 105 DB2CLI.PROCEDURES 79 diskette 348, 355, 361, 372 example 93, 99, 122, 266 MRSP 164, 166 precompiler 132 RENT compiler option 102 SQLDATA 155 stored procedures overview 1 TEST compiler option 312, 313 VAB 332, 335 varying-length character 17 VisualGen 134 Windows 187 COBOL for OS/390 and VM 85 code editor 331, 334 code module 333, 334, 336 code page 106, 250 code points 150 code segment 114 CODE statement 114 CODE-LISTING window 323 CODE/370 batch debug tool 328 compile tool 310 debug tool session example 316

450

Getting Started with DB2 Stored Procedures

CODE/370 (continued) displaying variables 324 edit tool 310 installation 307 LE/370 86 o v e r v i e w 305 PTF 308 source code 317 step o v e r 325 step return 325 step through 325 using the debug tool 314 coded character set 250 COLLECT option 227 collection calling other programs 97 classification rules 28 client program 100 COLLID column 14 RRSAF 259 SET CURRENT PACKAGESET statement 98 WLM-established stored procedure 28 COLLID column 14, 100, 228 command bind 131 building stored procedures 113 DB2 on MVS 19 db2start 75, 107 debug 306, 312, 317, 327 DISPLAY PROCEDURE 21 DISPLAY THREAD 23 EXCI call 266 file 315, 328 in a stored procedure 86 SET CURRENT PACKAGESET 97 START DB2-established address space 11 START PROCEDURE 19 STOP PROCEDURE 20 terminate current process 107 unsupported 106 VAB 342 Visual Basic 194 Windows 187 COMMAREA 266 COMMENT debug command 327 commit client program 118 coordination 11 DB2 Connect result set study 429 DB2 on MVS 7 implicit 222, 249 lock 381, 386, 412 mode 199, 204 network flow 389, 403 non-DB2 resources 11, 265 ODBC 199 transaction characteristics 380 COMMIT statement CLI 204

COMMIT statement (continued) COMMIT_ON_RETURN 18 CONNECT TYPE 2 88, 107 DB2 on MVS 8 not supported statements 86 RRSAF 256 Visual Basic 194 COMMIT_ON_RETURN accessing IMS databases 277 APPC 295 column 15 considerations 18 MRSP 151 commitment control 272 common gateway interface See CGI Communications Manager/2 See CM/2 compatibility mode application environment 30 considerations 33 testing 58 compile accessing IMS databases 287 CFRM policy 63 CLI 131 client program 130 CODE/370 305, 310, 312 DB2 on MVS 99 embedded SQL 106, 132 nonreentrant 102 ODBC 131 options 113 PL/I 94 reentrant 102 REXX 131 source code 327 TEST(ALL) option 323 varying-length character 17 VS COBOL II 85 compound SQL 67, 301 concurrency 67 condition handling 85 CONFIG.SYS file 112, 126 configuration CODE/370 308 DB2 Connect result set study 415 host for CODE/370 310 technical report 377 used in the measurements 377 CONNECT RESET statement 106, 249 CONNECT statement CLI 203, 222 CONNECT TYPE 2 88 thread 7, 89 three-part names 87 unsupported 86, 106 variables 195 Visual Basic 196

CONNECT TYPE 1 18, 87, 89, 118 CONNECT TYPE 2 18, 87, 89, 107 connection 7, 195 connection handle CLI 142 DBconnect function 141 null connection 222 ODBC 193, 200 Visual Basic 196, 197 constants CALL statement 117 DB2 on MVS 93 specifying arguments 120, 124 stored procedure name 124, 127 VAB 334 constraints 67 contention design 381 I/O 382, 395 locking DB2 for MVS/ESA utilization 389 response time 390 transaction Tx1 391, 405 transaction Tx2 392, 406 transaction Tx3 393, 408 transaction Tx4 394, 408 transaction Tx5 395, 409 transaction Tx6 396, 410 transaction Tx7 404, 411 Control Center 70 control structures 76 conversion DB2 on MVS 124 DRDA 17 parameters assignment 96 undelimited constant 130 Unicode 191 CONVERT option 111 CoOperative Development Environment/370 See CODE/370 COPY statement 111 core functions 132 correlation ID 258 couple data sets 26, 34, 59 coupling facility 59, 61 CPI-C side information 310, 311, 315 CPU DB2 Connect result set study 420 DDCS for AIX 398, 399, 405, 407, 410 DDCS for OS/2 385 locking contention 403 thread 7 CREATE call 87 CREATE DATABASE command 106 CREATE THREAD function call 257, 259, 264 cursor blocking rows 183 close 200 COMMIT_ON_RETURN 18

Index

451

cursor (continued) MRSP 137, 139, 143, 150 names 150 order of result sets 153 reasons why not returned to client statement handle 197 used in stored procedure 137

170

D D WLM command 54 DARI CALL statement 123 DB2 Common Servers V2 71 DB2CLI.PROCEDURES 79 using to invoke stored procedures 127 VAB 337 data areas 200 data control language See DCL data conversion 13, 237, 247, 249 data definition language See DDL data integrity 67 data length 119 data manipulation language See DML data replication 68 data segments 113 data sharing 19 data source commit mode 204 handle 196 register 187 SQLConnect 196 statement handle 197 data transformation 3 data type assignment rules 95 C 197 client program 118, 121 conversion 96 object extenders 68 PARMLIST column 89 print_results function 144 specifying arguments 124 SQLDA 119 data warehouse 68 database agent process 76 database application remote interface See DARI database control system See DBCTL database request module See DBRM database resource adapter See DRA DatagLANce Network Analyzer for Ethernet and Token-Ring for OS/2 380

452

Getting Started with DB2 Stored Procedures

DataJoiner 68, 69 DATE data type 96 DB2 accounting and statistics traces 380 DB2 Administration Tool 103 DB2 Client Application Enabler See CAE DB2 Common Servers C application for Windows 220 coding considerations 105 MRSP 150 performance 299 VisualGen 134 DB2 Connect COMMIT_ON_RETURN 18 MRSP 137, 150 PowerBuilder 205 product overview 68 result set study 415 DB2 for AIX client program 89 DRDA stored procedure support 1 REXX 111 searching stored procedures 126 stored procedure name 130 VisualGen 134 DB2 for HP-UX 1, 67 DB2 for MVS/ESA C application for Windows 220 connections 384, 399 DRDA stored procedure support 1 line capacity 387, 401 measurement conclusions 412 measurements taken 377 MRSP 150 network protocol 379 stored procedures architecture 7 thread 384, 399 tuning 398 utilization 389, 403 DB2 for OS/2 client program 89 DRDA stored procedure support 1 LIBPATH 111 searching stored procedures 126 stored procedure name 130 VisualGen 134 DB2 for OS/390 DB2 Connect 68 DB2 Connect result set study 416 MRSP 137, 150 stored procedures architecture 7 DB2 for OS/400 1, 68, 124, 129 DB2 for Sinix 67 DB2 for Solaris 1 DB2 for Sun/Solaris 67 DB2 for VM and VSE 68 DB2 for Windows NT 1, 67 DB2 kernel 301

DB2 on MVS authorizations 134 client program 88, 130, 131 coding stored procedures 85 commands related to stored procedure 19 constants 93 conversion 124 debugging 305 host variables 93 languages 85 SQLDA 93 stored procedure name 129 Visual Basic 189 VisualGen 134 DB2 on the workstation authorizations 134 CALL statement 123 client program 130, 132 coding considerations 106 MRSP 137 parameters 118 searching stored procedures 126 stored procedure name considerations 128 DB2 Parallel Edition 68 DB2 UDB coding considerations 105 DRDA stored procedure support 1 MRSP 150 product overview 68 tools 70 DB2 Version 4 access IMS databases 274 COMMIT statement 8 DB2 Version 5 access IMS databases 274 CLI 221 COMMIT statement 8 DB2 WWW Connection 69 DB2-established stored procedures address space APPC 291 CLI traces 231 JCL to start 10 load module 52 MRSP 151 RACF 11 RRSAF 59 DB2CKPTR environment variable 107 db2cli.ini file 190, 204, 208, 429 DB2CLI.LST file 187 DB2CLI.PROCEDURES columns 79 creation 77 register 332 VAB 337 db2dari process 303 DB2INFO EXEC 377 DB2SSN keyword 32 db2start command 75, 107

DBADM 78 DBconnect function 141, 203, 204 DBCTL 273, 274, 276, 277 DBRM 100 DCE 67 DCL 3, 86 dd1c2cr2 302 dd1c2s 302 DDCS COMMIT_ON_RETURN 18 follow-on product 68 MRSP 150 DDCS for AIX capacity planning 377 client equivalence 398 configuration 378 CPU 398, 399, 405, 407, 410 disk capacity 400 measurement conclusions 412 measurement results 398 MRSP 138 network 401 protocols 379 R A M 399, 400 transactions 404 DDCS for OS/2 capacity planning 377 configuration 377 CPU 385 disk capacity 386 measurement conclusions 412 measurement results 383 MRSP 138 network 386 protocols 379 R A M 384 DDCSMVS.LST 131 DDF 8, 29, 46, 47 DDL 3, 86 debug CLI 231 CODE/370 306, 314 DB2 on MVS 305 DB2 on the workstation 114 LE/370 86 mode 340 r e m o t e 343, 345 tool session example 316 VAB 340 VisualGen 134 Debug Tool Command Log window DECIMAL data type 96 DECIMAL parameter 17 DEF file 113 DEFINER column 79 definition file 334, 336 definition menu panel 38 delay CPU 403, 407

327

Index

453

delay (continued) disk 389 line 402 network 412 role played 386, 401 DELAY parameter 386, 388, 401, 402, 422, 431 DELETE statement 13, 152 delimited identifier 130 DEQ function call 274 DESCRIBE CURSOR statement example 170 format 163 returned information 163 SQL extension 152 DESCRIBE PROCEDURE statement example 170 format 155 MR2BMCBM sample program 160 number of result sets 152 returned information 154 SQL extension 152 DESCRIBE statement 150 DESCRIPTION statement 113 DESCSTAT bind option 164, 192 DESTNAME parameter 293, 315 DFSCDL10 module 275 diagnostic information 189, 193, 199 dictionary tables 312 differences between stored procedures and other programs 106 directories search 126 directory structure 347 discretionary goals 27 DISPLAY privilege 21 DISPLAY PROCEDURE command 21 DISPLAY statement 57 DISPLAY THREAD command 23 DISPLAY WLM command 34, 57 Distributed Computing Environment See DCE distributed data facility See DDF Distributed Database Connection Services See DDCS for Common Servers Distributed Relational Database Architecture See DRDA distributed unit of work 67 see DUW DLET function call 274 DLL CLI 222, 229 compile option 223 function name 195 LINK386 113 OS/2 106, 111 prelink 224 side deck 228 DML 3, 86

454

Getting Started with DB2 Stored Procedures

DOS 67 DOS_RQRIOBLK 386, 401 DOUBLE parameter 17 DPSB call 274, 276, 290 DRA 272, 273 DRDA bind 131 character conversion 17 CODE/370 308 COMMIT_ON_RETURN 18 data type conversion 96 DB2 Connect 68 DB2 for MVS/ESA 8 DB2 for OS/390 8 DDCSMVS.LST 131 measurements taken 377 MRSP 150 SQLeproc 127 stored procedures overview 1, 3 system-directed access 87, 129 temporary table 151 Visual Basic 188 DROP DATABASE command 106 DSN8EP2 member 57 DSNALI module 52, 87, 100 DSNAOCLI collection 228 DSNAOINI file 222 DSNAOINI statement 229 DSNAOTRC statement 229 DSNARLI module 275 DSNCLINC package 221 DSNRLI module 52, 59, 100, 257, 260 DSNRRSAF statement 260 DSNT408I message 249 DSNTIAD 103 DSNTIJUZ 12 DSNTINST CLIST 8, 12 DSNTIPG panel 10 DSNTIPX panel 8, 11, 21 DSNV429I message 23 DSNX968I message 58 DSNX981E message 53, 55 DSNX982I message 53 DSNX9WLM program 229 dual mode 114 dynamic breakpoints 306 dynamic SQL authorizations 134 CALL statement 1, 118 compound SQL 301 considerations 81 DB2 on MVS 86 DESCRIBE CURSOR statement 164 performance 300, 303 privilege 7 system-directed access 87 VisualGen 134 DYNAMICRULES(BIND) 7, 134

E ECB 255, 258 EDC6006E message 222 EDCICONV procedure 250 embedded SQL CALL statement 123 client application 132 considerations 81 MRSP 139 performance 302, 303 precompile 106 static 83 Windows 187 encapsulation 83 Encina 18 enclave 25 enqueue 12 entry point 336 environment handle CLI 141, 142, 203 ODBC 193, 200 Visual Basic 196 environment variables 107 error application environment 35 case sensitive 112 CLI 249 coding 35 compiler options 113 full-path specification 120 handling statements 204 JCL 35, 55 MRSP 138 ODBC 198 parm-name parameter 17 ROLLBACK statement 87 RRS 64 RRSAF 263 source code 306 SQLConnect 196 START PROCEDURE command 20 statement handle 197 user program 11 VAB 340 WLM 34 ERROR TEST suboption 315 ES/9000 4 escape clause 128, 135 ESCON 431 Ethernet 380, 416, 429, 430, 431 event control block See ECB EXCI access CICS systems 265 access IMS databases 272 CICS tables 269 program preparation 267 using in a stored procedure 266

EXE file 106 executable file 113, 132, 337 EXECUTE privilege 101 EXECUTE statement 81, 198 execution velocity goal 27 expanded storage 379 explicit APPC support 291 EXPORT function 223 EXPORTS section 236 EXPORTS statement 112, 114 External CICS Interface See EXCI 265 external program name 129 EXTERNAL_SECURITY column 15, 53, 265

F F WLM command 33 Fast Path data entry databases 273 FENCED column 80 fenced stored procedure concept 76 LIBPATH 112 MRSP 138 performance 301 precompile 111 searching 126 FETCH statement measurements 389, 403 MRSP 139, 151 result 137 RESULT_SETS column 150 FFFF2222 64 flat files 12, 53, 265 FLD function call 274 FLOAT data type 96, 124 FLOAT parameter 17 folding 129, 130 fopen() command 12 FOR subtype DATA parameter 17 FORTRAN DB2 for AIX 105 DB2 for OS/2 105 DB2 on MVS 85 DB2 on the workstation 105 DB2CLI.PROCEDURES 79 precompiler 132 stored procedures overview 1 FORWARD RECOVERY command 106 function calls 82 case sensitive 112 coding considerations 106 multiple in the same library 128 name 128, 130 procedures (VAB) 333 stored procedure preparation 111 VAB 334

Index

455

function descriptor 226 FUNCTIONAME 112

G GHN function call 274 GHU function call 274 global temporary table accessing IMS databases 151, 272 result sets 239 sample application 292, 294, 353, 373 GMSG function call 274 GN function call 274 goal mode application environment 30, 32 operation 33, 58 Sysplex 26 testing 57 WLM-established stored procedure 25 GRAPHIC data type 96, 111 GRAPHIC parameter 17 GROUP parameter 386, 388, 401, 402 GU function call 274

H handler 132 handles allocation 196 CLI sample 203 data areas 200 deallocation 204 e r r o r 199 program structure 193 SQLFreeEnv 200 variables 194 header file 247 HEAP size 234 history file 336 home page 345, 377 host language client program 130 compound SQL 301 considerations 81 DB2 on the workstation 106 package 134 HOST parameter 386, 388, 401, 402 host variables array 121 CALL statement 117 CLI 82, 132 DB2 on MVS 93 example 122 full-path specification 120 MRSP 180 ODBC 132 passing parameters 125 specifying arguments 120, 124 SQLDA 107

456

Getting Started with DB2 Stored Procedures

host variables (continued) stored procedure name 118, 120, 124 structure 121 VAB 332 varying-length character 17 HP 68 HP-UX 331 HTML 69

I I/O PCB 275 IBM AIX XL FORTRAN Version 2 Release 3 4 IBM AIX XL FORTRAN/6000 Version 2.3 105 IBM C for AIX Version 3 Release 1 3 IBM C for AIX Version 3.1 105 IBM C Set++ Version 2 Release 1 4 IBM C/C++ for MVS/ESA Version 3 Release 1 3 IBM C/SET++ for AIX Version 2.1 or Version 3.1 105 IBM C/Set++ for OS/2 Version 2.1 105 IBM COBOL for MVS and VM Version 1 Release 1 3 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 1 4 IBM COBOL VisualSet for OS/2 Version 1.1 105 IBM High Level Assembler/MVS Version 1 Release 1 3 IBM Internet Connection Server 69 IBM PL/I for MVS and VM Version 1 Release 1 3 IBM Procedures Language 2/REXX 4, 106 IBM SAA AD/Cycle C/370 Version 1 Release 2 3 IBM SAA AD/Cycle COBOL/370 85 IBM SAA AD/Cycle Language Environment/370 Version 1 Release 1 3 IBM VisualAge C++ for OS/2 Version 3 105 I B M V i s u a l A g e C + + f o r W i n d o w s 187 IBM VisualAge for COBOL for OS/2 and Windows 187 IBM XL C Compiler Version 1.2.1 or Version 1.3 105 IBM XL C Version 1 Release 2.1 3 IBM XL FORTRAN for AIX Version 3.2 105 IBMREQD column 14 ICMD function call 274 IDENTIFY function call 87, 257, 261 IEASYSnn member 59 IEFSSNxx member 63 IFI calls 86, 100, 255 ILINK 113 IMDBMCB2 sample 292 IMDBMCBM sample 292, 296 IMDBMCBN sample 292 IMDBMS sample 292, 296 Immediate window 342 implicit APPC support 291 IMPORT statement 223, 226 importance 27

IMS accessing databases 272 APPC 291, 292 CODE/370 306 c o mmi t coordination 11 DataJoiner 68 DRA 272, 274 MQSeries 291 performance goals 29 RRSAF 260 synch point processing 277 temporary table 151 IMSBMCBM sample 292, 294 IMSBMS sample 292, 294 IMUBMCBM sample 292, 295 IMUBMS sample 292, 295 IN parameter 17 inbound translation 53 include files 224 index DB2 Connect result set study 418, 432 matching predicates 390 performance benchmark 381, 382 spreading 382 indicator array 14, 91 indicator variable array 14, 91 client program 118, 121 DB2 on the workstation 111 SIMPLE WITH NULLS linkage convention specifying arguments 124 stored procedure name 120, 124 using nulls to reduce traffic 92 Informix 68 INIT function call 274 INIT_UID_PWD macro 140 initialization file 222, 250 INITINSTANCE 113 INOUT parameter 17, 92 INQY function call 274 INSERT statement 13 Inspector window 341 installation CODE/370 307 DB2 for MVS/ESA 8 DB2 for OS/390 8 updating parameters 12 installation control specification See ICS 25 installation performance specification See IPS 25 instrumentation facility interface See IFI call INTEGER data type 96, 124 INTEGER parameter 16 Intel 67, 68 interactive mode 306 interactive test facility 134

interface block 275 International Organization for Standardization/American National Standards Institute See ISO/ANSI Internet 68, 69, 345 interpreter 342 interprocess communication 301 IPA option 226 IPS 25 IPX 5 IRXINIT routine 99 ISIS parameter 277 ISO/ANSI 1, 95, 96, 117 isolation level 221, 381, 418, 429 ISPF variables 99 ISRT function call 274 IWM001I message 54 IWM007I message 33 IWM008I message 33 IWM029I message 54, 57, 58 IWM032I message 54, 58 IWM034I message 55, 57 IWMAM052 message 37 IXCMIAPU utility 60 IXG231I message 65 IXGLOGR prefix 60

91

J Java 68, 187 Java Database Connectivity See JDBC JCL LE/370 library 10 prepare stored procedure 99 stored procedures address space JDBC 68, 187 join 151, 381

9, 12

K KEEPDARI 72, 75, 303, 304 keystroke time 384

L LAN 5, 68, 388, 403 language BASIC 79 CLI 221 CODE/370 305 DB2 on MVS 85 DB2 on the workstation 105 DRA 274 MRSP 139, 151, 152 RRSAF 256 stored procedures overview 1 VAB 333

Index

457

LANGUAGE column 14, 79, 228 language interface 52 large objects See LOB latching 383, 398 LE/370 calling other program 98 client program 131 CODE/370 305, 315 DB2 Version 4 85 introduction 85 library name 10 link-edit 100 MRSP 151 PTF 307 resident 102 RUNOPTS 14 RUNTIME parameter 10 stored procedures address space 7 SYSIBM.SYSPROCEDURES 13 virtual storage 9 level functions 132 LIBPATH 111, 126 library case sensitive 112 DB2 on the workstation 106 LE/370 86 name 130 path 128 SQLZ_DISCONNECT_PROC 109 SQLZ_HOLD_PROC 109 STOPPING state 35 stored procedure name considerations stored procedure preparation 111 VAB 334, 336 LIBRARY statement 113 line 387, 388, 401 LINE TEST suboption 313 link-edit 52 accessing IMS databases 275, 287 APPC 293 CAF 87 CFRM policy 63 CLI 223, 226 CODE/370 306 DB2 on MVS 99 LE/370 100 reentrant 102 RENT option 102 REUS option 102 LINK386 113 LINKAGE column 14, 90 LIST debug command 319, 321, 327 load library 11, 100 load module CALL flow 7 CLI 226 CODE/370 314, 317 DB2CLI.PROCEDURES 79

458

128

Getting Started with DB2 Stored Procedures

load module (continued) DISPLAY PROCEDURE command 21 DISPLAY THREAD command 23 LE/370 86 LOADMOD column 14 nonreusable 102 reentrant 102 REFRESH option 35 reusable 102 STAYRESIDENT column 14 STOP PROCEDURE command 20, 21 SYSIBM.SYSPROCEDURES 13 test version 15 WLM-established address space 52 LOAD utility 13 LOADMOD column 14, 21, 52, 104 LOB 67, 197 Local and Global Monitor List windows 326 local application 8 local call 338 local client 1, 117 location 120, 129, 131 lock accessing IMS databases 277 CPU 403 DB2 Connect result set study 418 DB2 on MVS 7 definitions for the measurements 381 delay 389, 401, 403 network 386, 401 page level 381 result sets 151 row level 381 three-part names 89 LOG function call 274 log mode 293, 311 log streams 59, 60, 64 logical partitions 379 LONG VARCHAR data type 17 LONGNAME option 223, 224 loopback connection 138, 149 lowercase DB2 for OS/2 130 function name 195 stored procedure name 112, 129 LSEARCH option 224 LU 6.2 265, 379, 416 LU name 13, 293, 310 LUNAME column 14, 15, 311

M Macintosh 67 mainframe interactive debug tool See MFI makefile - T i + o p t i o n 113 build stored procedure 112 COPY statement 111

makefile (continued) mrspcli3.sqc 139 VAB 336 manual control 32 massively parallel processing See MPP MAX ABEND COUNT parameter 9, 12 MAXAGENTS 74, 304 MAXDARI 72, 74, 75, 304 measurements 419 DDCS for AIX gateway 378 DDCS for OS/2 gateway 377 IRRW 380 KEEPDARI 303 performance benchmark 377 PowerBuilder 412 sample program used 299 m e m b e r 19, 32 memory blocking rows 181 handle allocation 196 library 109 performance 303 SQLAllocStmt 197 SQLFreeEnv 200 STAYRESIDENT column 14 stored procedures overview 3 message queue 275 Message Queue Interface See MQI 265 MFI 306 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 migration 8, 237 mixed data 17 MKTTOOLS 377 MODENAME 293 MODIFY command 33 module definition file 112, 113 monitor CODE-LISTING window 323 CODE/370 306, 316 components used in benchmark 380 Control Center 71 DB2 Common Servers features 67 LAN 388, 403 MONITOR GLOBAL LIST debug command 327 MONITOR LOCAL LIST debug command 327 MOVE debug command 321, 327 MPP 68 MQI 265, 272 MQSeries 291 MR0BMCBM sample program 170 MR1BMCBM sample program 155 MR2BMCBM sample program 160 MR3C2CO2.C client program 139, 140 MR3C2S.SQC stored procedure 139, 143

MR4C2CO2.C client program 146 MR4C2S.SQL stored procedure 148 MR5BMCBM sample 170 MRSBMCBM sample 166 MRSBMS sample 169 MRSP 137 access IMS databases 272 COMMIT_ON_RETURN 18 DB2 for OS/390 150 example 164 porting CLI from AIX to OS/390 236 mrspcli sample 222 mrspcli.c 138 mrspcli2.c 139 mrspcli3.sqc 139 mrspsrv.c 138 mrspsrv2.sqc 138 multimedia 68 multiple concurrent connections 83 multiple functions 128 multiple result sets 137 multiple result sets using stored procedures See MRSP multiple rows 15, 21, 180 must rollback state 87 MVS DB2 PROC NAME parameter 10 diskette 347, 363 measurements 379 prerequisites 3 PROC NAME parameter 9

N named pipe 138 NCP 386, 401, 402, 412, 430 nested 313, 342 Net.Data 68, 69 NetBIOS 5 Netscape 69 NetView Performance Monitor See NPM network client program 118 compound SQL 301 DB2 Connect result set study 422 DB2 on the workstation 111 DDCS for AIX 401 DDCS for OS/2 386 delays 412 lock 386, 401 MRSP 138 performance 300 protocols 379 statement handle 197 stored procedures overview 2 using nulls to reduce traffic 92 Network Control Program See NCP 386

Index

459

NOBLOCK TEST suboption 313 NOCONVERT option 76, 111 NOEXECOPS run-time option 94 NOLINE TEST suboption 313 non-DB2 resources accessing from a stored procedure 8, 265 change the JCL procedure 11 RACF 12, 53 WLM-established address space 53 NONE TEST suboption 313, 315 NOPATH TEST suboption 313 NOSYM TEST suboption 313 Not-fenced stored procedures See unfenced stored procedure NPM 380 null blocking rows 184 CALL statement 121 character string 144, 145 client program 118 DB2 on MVS 90 DB2 on the workstation 111 LINKAGE column 14 pointer 107 specifying arguments 120, 124 terminator 198 VAB 335 Visual Basic 204 NULL CONNECT term 249 null connection 222, 248 NULL keyword 91, 120 NUMBER OF TCBS parameter 9 NUMTCB parameter 12, 13, 57, 273

O object-relational extenders 68 ODBC administration tool 187 bind 187 CALL statement 127 CLI 82 client program 130 DB2 Common Servers features 67 DB2 Connect result set study 429 e r r o r 198 escape clause 135 handle allocation 196 migration 237 MRSP 137, 151, 152 parameters 118 PowerBuilder 205, 206 privilege 101 program structure 193 sample application 192 setting the environment 187 Software Development Kit 133 Visual Basic 189 Windows 187

460

Getting Started with DB2 Stored Procedures

ODBC.INI file 188 OLTP 68 OO COBOL COLLID column 14 DB2 on MVS 85 stored procedures overview 1 open 138, 200 OPEN CURSOR statement 170 Open Database Connectivity See ODBC OPEN function call 274 OpenEdition 12 operator commands 58 OPTFILE option 224 optimizer 67 Oracle 68 OS/2 client 299, 384, 398 COBOL 134 CODE/370 305 DB2 Connect 68 debug 306 desktop 187 diskette 347, 348, 353 DLL 106, 111 function 128 IBM Procedures Language 2/REXX LIBPATH 112 PATH 112 prerequisites 4 product overview 68 server 299 SPM/2 380 test 303 VAB 331 Warp 5 OS/390 25, 54, 206, 221, 274, 275 OTS-COMMIT 277 OTS-ROLLBACK 277 OUT parameter 17 overhead 181 OWNER 7, 101

P PACKADM authority 101 package calling other programs 97 classification rules 28 CLI 221 client program 130, 131 COLLID column 14 DB2 on MVS 99, 100 DB2CLI.PROCEDURES 79 embedded SQL 83 isolation level 381 privilege 7, 101 RRSAF 259 system-directed access 87

4

package (continued) WLM-established stored procedure 28 parallel processing 68 parameter marker question mark 127, 195 SQLBindParameter 141, 197 SQLExecute 198 Visual Basic 196 parameters assignment rules 95, 96, 121 CLI 118, 203 client program 118 DB2 on MVS 89, 118 DB2 on the workstation 107, 118 input 91, 103, 124 MRSP 151 null 91 number 119 ODBC 118 output 91, 124 passing to REXX procedure 99 passing using host variables 125 receiving in DB2 on MVS 93 receiving in DB2 on the workstation 107 SQLDA 118 stored procedures overview 1 VAB 335 parm-name parameter 16 PARM_LIST column (DB2CLI.PROCEDURES) 80 PARM_STYLE column 79 PARMLIB member 310 PARMLIST column assignment rules 95 data type 96 syntax 16 SYSIBM.SYSPROCEDURES 14, 89 PARTNER_LU specifcation 293, 311 path 128 PATH environment variable 111 PATH TEST suboption 313 pbibm050.ini file 208 PCCU parameter 386, 388, 401, 402 Pentium 379 performance access IMS databases 272 classification rules 28 CLI 249 CODE/370 306 considerations 299 Control Center 71 DB2 Common Servers features 67 DB2 Connect result set study 429 goal 27 KEEPDARI parameter 72 query 68 reentrant 102 SQL_HOLD_PROC 110 static SQL 83 stored procedures overview 2

performance (continued) technical report 377 unfenced stored procedure 76 Visual Basic 189 performance goals assigning to a stored procedures 29 classification rules 32 defining 26 relationship among WLM definitions 25 service class period 27 testing 57 unit of work 29 PGM_TYPE column 15 PKGNAME column 79 PKGSCHEMA column 79 PL/I client program 130 CODE/370 305 data type 90 DB2 on MVS 85 diskette 375 example to call a REXX procedure 98 PROC OPTIONS(REENTRANT) 102 stored procedures overview 1 TEST compiler option 312 plan accessing IMS databases 287 calling a stored procedure from a local client CLI 228 for a stored procedure 100 privilege 101 RRSAF 256, 259, 261, 263 PLEXCFG parameter 59 PLI value 14 PLIST(MVS) run-time option 95 portability application 221 CLI 83, 236 receiving parameters 93 stored procedure name 129 VAB 332 VisualGen 134 POS function call 274 PowerBuilder client equivalence 384 DB2 Connect result set study 415, 416 diskette 348, 360 IRRW 380 multiple result sets 216 no result sets 208 performance benchmark 379 single result set 213 PowerPC 601 379 pr1c2cr2 300, 303 pr1c2s 300, 303 pr2c2cr2 300 pr2c2s 300 pr3c2cr2 301

Index

98

461

pr3c2s 301 pr4c2cr2 302 pr4c2s 302 precision 145 precompile client pro gra m 130 CODE/370 313 DB2 on MVS 99 embedded SQL statements 81 precompiler 120 VAB 332 preferences file 315 prelink 102, 224, 226 preload 381, 382, 394, 408, 418 PREPARE statement 81, 197 preprocessor 81 primary authorization 101 print_results function 144, 146 priority RRS 64 WLM-established stored procedure 25, 56 private protocol 1, 151 privileges DB2 on MVS 101 DB2CLI.PROCEDURES 332 DISPLAY PROCEDURES command 21 embedded SQL 83 execute a stored procedure 101, 134 non-DB2 resources 12 START PROCEDURE command 19 STOP PROCEDURE command 20 SYSIBM.SYSPROCEDURES 104 PROC OPTIONS(REENTRANT) 102 PROC_LOCATION column 79 PROCCOLS sample 78 PROCEDURE column 14, 120, 129 procedure-library!function-name 128 process db2dari 303 fenced stored procedure 76 KEEPDARI parameter 72 terminating 107 PROCNAME column 79 PROCS sample 78 PROCSCHEMA column 79 program hooks 312 program specification block See PSB project manager 331 prompt level 315 protected mode 114 protected resources 59 PROTMODE statement 114 PS/2 4 PSB 276 pseudonym files 293 PTF 85, 307

462

Getting Started with DB2 Stored Procedures

Q QSAM files 12, 53, 151 qualified name 120 querying 78 queuing 56, 58 QuickTest 331, 343 QUIESCE option 33, 34 QUIESCED state 34, 58 QUIESCING state 33, 34, 58 QUIT debug command 327

R RACF accessing IMS databases 277 DB2-established address space 11, 265 RRSAF 255 WLM-established stored procedures address space 25, 53, 265 R A M 385, 386, 399, 400 RCMD function call 274 RDO 189, 190, 191, 192 rdoDefaultLoginTimeout property 192 REAL data type 96 REAL parameter 16 reason code 00E79002 55 00E79009 53 1592312 reason code 264 15925250 reason code 263 15925393 263 1592554 reason code 264 receive operation 2 Recoverable Resource Manager attachment facility See RRSAF recoverable resource manager services attachment facility See RRSAF 253 recovery 67, 70 reentrant 99, 102, 247 referential integrity 67 refresh 34 REFRESH option 35 REFRESHING state 33, 35 region controller 272 REGION parameter 11 registering stored procedures 77, 187, 332 RELEASE statement 86, 88, 106 REMARKS column 80 remote call 338 remote client 117 remote data objects See RDO 189 remote data services 1 RENT compiler option 102, 224 RENT link-edit option 102 REPL function call 274

replication 70 resident 86, 102 Resource Measurement Facility See RMF 416 resources 200 response time goal 27 restarting DB2 11 RESTORE command 106 result set CLI 83 cursor 137, 138 DB2 Version 4 93 DB2 Version 5 93 MRSP 146 number of columns 144 sample 138 result set locator DESCRIBE PROCEDURE statement 155 relationship among new SQL statements 153 SQL extension 152 RESULT_SETS column 14, 80, 150 RESUME option 34, 35 RESUMING state 34 return code CLI 203 e r r o r 194 function procedure 333 making a stored procedure resident (workstation) 248 ODBC 193 SQL_NO_DATA_FOUND 145 variable 194, 198 REUS link-edit option 102 reusable 102, 333 REXX calling a procedure 98 calling from a stored procedure 86, 98 client program 130, 132 command file 111 DB2 for AIX 105, 111 DB2 for OS/2 106 DB2 on the workstation 105 DB2CLI.PROCEDURES 79 diskette 347, 348, 352, 356 example 108, 114, 125 library 106 PATH environment variable 111 performance 299, 303 precompile 106 stored procedure name considerations 129 stored procedures overview 1 VAB 332, 335 variable pool 108 rgbValue column 190, 191 RISC System/6000 4 RMF 380, 416 RMODE(ANY) 100 ROLL function call 275

ROLLB function call 275 rollback client program 118 DB2 on MVS 7 RRSAF 256 ROLLBACK statement COMMIT_ON_RETURN 18 CONNECT TYPE 2 107 must rollback state 87 unsupported statement 86 Visual Basic 194 ROLS function call 274 routers 431 RPTOPTS option 230 RPTSTG option 230, 234 RQRIOBLK 386, 401, 422, 429, 430 rr22xsp0 300 RRS adding the subsystem name 64 CFRM policy 63 CICS 265 COMMIT_ON_RETURN 18 coupling facility 61 DASD log streams 60 DRA 274 errors 64 implementing 59 JCL procedure 63 not active 53 staging data sets 60 starting and stopping 64 synch point processing 277 RRSAF coding stored procedures 87 COMMIT_ON_RETURN 18 DB2-established address space 52 e r r o r 263 performance goals 29 programming 253 RACF 53 RRS implementation 59 RRSAFCOB sample 260 RRSBACK 275 RUN debug command 327 RUNOPTS column DB2CLI.PROCEDURES 80 LE/370 14, 230 TEST run-time option 314 virtual storage 9 RUNTIME parameter 10 RUSIZE 386, 401, 422

S S5C4 abend code 64 SAA 127 SAF 255, 261 samputil.c 141, 144, 203

Index

463

samputil.h 140 SBCS 17 scale 198 SCHED specification 292 scheduling 29 SCHEMA 129, 337 SCO 68 scripts 70 SDK for Common Servers 138 SEARCH option 224 searching stored procedures 16, 126 secondary authorization 101 security 3, 7, 83, 277 SELECT statement blocking rows technique 180 CLI 141 DESCRIBE CURSOR statement 163 DESCSTAT bind option 192 mr3c2o2 sample program 140 MR4C2S.SQC program 149 MRSP 139, 143, 151 WITH RETURN clause 249 WITH RETURN option 357 send operation 2 SENDDA sample 116 serialization 12, 32, 53, 265 service class 26, 56, 57 service class period 27 service definition 25, 30, 35 WLM 26 service policy 26, 35, 38 service units 14, 103 serviceability trace 229 SET CONNECTION statement 86, 106 SET CURRENT PACKAGESET statement 97 SET CURRENT SQLID statement 86 SET PATH statement 129 SET SOURCE ON debug command 327 SETRRS CANCEL command 64 SETS function call 274 setting variables 193, 203 SETU function call 274 SETXCF command 63 SHOWDA sample 116 side deck 227 side information 293 SIDEINFO 310 sign on 7, 255 SIGNON function call 87, 257, 258, 261 SIMPLE linkage convention 14, 90, 92 SIMPLE WITH NULLS linkage convention 14, 91, 92, 164 simulate 149, 306 SINIX 68 SMALLINT data type 96 SMALLINT parameter 16 SmartGuide 70, 331, 344 SMS class 60

464

Getting Started with DB2 Stored Procedures

SNA 293, 309, 416 SNAP function call 274 software prerequisites 3 Solaris 331 source code .bas file (VAB) 333 CODE-LISTING window 317, 323 CODE/370 317 VAB 331 viewing (CODE/370) 313 sp file 334, 336 sp0r2cr2 300 sp0r2s 300 special characters 120, 124, 127 speed line 387, 401 SPM/2 380 SQL_CLOSE 138 SQL_COMMIT 142 SQL_DROP 138, 142, 200 SQL_NO_DATA_FOUND 145, 148, 192 SQL_NTS 190, 204 SQL0969N message 55 SQL1106N message 112 SQL1109 message 112 SQL3 1, 117 SQL92 Entry Level 152 SQLAllocConnect 141, 196, 203 SQLAllocEnv 140, 196 SQLAllocStmt 141, 197 SQLarrayCALL 337 SQLBindCol 145, 249 SQLBindParameter function call CLI 204, 221 parameter marker 141 parameter markers 127, 197 rgbValue column 190 Visual Basic 190, 194 SQLBrowseConnect 132 SQLCA client program 89 DB2 on the workstation 107 MRSP 143 porting CLI applications 248 PowerBuilder 211, 216 RRSAF 260 VAB 334, 335 sqlcli.h header file 223 SQLCODE -113 129, 195 -1133 107 -114 179 -204 179 -30090 89 -301 96 -302 96 -303 374 -312 220 -406 96 -426 19

SQLCODE (continued) -440 18, 179 -444 179 -470 220 -471 21, 53, 55, 179 -496 179 -499 179 -504 179 -751 86, 180, 249 -805 228 -842 88 -925 18 -926 18 464 150, 152 466 164 494 SQLCODE 178 blocking rows 184 client program 89 SQLColAttributes 145, 249 SQLConnect 141, 193, 196, 203 SQLD field DESCRIBE CURSOR statement 163 DESCRIBE PROCEDURE statement 154 setting before the SQL CALL statement 121, 125 SQLDA CALL statement 117, 125 DB2 Common Servers 107 DB2 on MVS 93 DESCRIBE CURSOR statement 163 DESCRIBE PROCEDURE statement 154, 155 example 122 MRSP 143 multiple rows 180 parameters 118 porting CLI applications 248 REXX 125 SENDDA 116 SHOWDA 116 specifying arguments 120, 124 SQLD 107 SQLVAR field 108 USING DESCRIPTOR 121 VAB 332, 334, 335 VisualGen 134 SQLDABC 121, 124 SQLDAID field 163 SQLDATA field 125, 155 SQLDBS 132 SQLDescribeCol 144, 239 SQLDescribeParam 132 SQLDisconnect 142, 200 SQLeproc 123, 127, 337 SQLError 199, 249 SQLEXEC 132 SQLExecDirect 249 SQLExecute function call CALL statement 191 CLI 141 ODBC 194

SQLExecute function call (continued) Visual Basic 190, 191, 196, 198 SQLFetch 145, 148 SQLFreeConnect 142, 200 SQLFreeEnv 142, 200, 222 SQLFreeStmt 138, 142, 200 SQLGetData 249 SQLGetSQLCA 249 SQLIND field 121, 125, 154 SQLLEN field 121, 125, 163 SQLMoreResults 148, 222 SQLN 121, 124 SQLNAME field DESCRIBE CURSOR statement 163 DESCRIBE PROCEDURE statement 154 SQLNumResultCols 144 SQLPrepare function call CALL statement 141, 191 passing a string 193 Visual Basic 194, 195, 197 SQLProcedureColumns 77, 78 SQLProcedures 77, 78 SQLRIDA stem variable 108 SQLRODA stem variable 108 SQLSetConnect function call 192 SQLSetConnectOption function call 141, 199, 222, 249 SQLSetPos 132 SQLSTATE 197 SQLTransact 142, 200, 222, 249 SQLTYPE field 114, 116, 121, 125, 163 SQLVAR field assigning 108 client program 111 DESCRIBE CURSOR statement 163 DESCRIBE PROCEDURE statement 154 host variable 124 stored procedure parameter 121 SQLZ_DISCONNECT_PROC 79, 109, 303 SQLZ_HOLD_PROC 79, 109, 303, 304 SRB 25 SRRBACK function 255, 256, 261, 277 SRRCMIT function ACCTINT field 258 CICS 265 DRA 277 RRS 255, 256 RRSAF 261 SRSBMCBM sample 164 SRSBMS sample 165 START command 11, 32, 33 START PROCEDURE command 14, 19, 104 START RRS command 64 started task 27, 33 startup 21 STAT function call 274 statement handle CLI 141, 204 MRSP 144, 145

Index

465

statement handle (continued) ODBC 193 Visual Basic 196, 197 static SQL compound SQL 301 considerations 81 DB2 on MVS 86 DESCRIBE CURSOR statement 164 performance 300 privilege 7 status 196, 197, 198, 336 STATUS field of DISPLAY PROCEDURE command STAYRESIDENT column 14, 79, 86, 102, 248 STCB 25 STEP debug command 327 step mode 306 step over 325, 341 step return 325 step through breakpoint 341 Code Editor window 340 CODE/370 306, 325 VAB 331 Step/Run window 324 STEPLIB 311 STMT TEST suboption 313 STOP PROCEDURE command 20, 34 STOPPED state 35, 53, 54 STOPPING state 35 storage link-edit 100 management 85 measurements 379 pointer 107 print_results function 144 store assignment rules 95 stored procedure name case sensitivity 130 considerations 128 DB2 on MVS 129 DB2 on the MVS platform 120 embedded SQL 124 folding 129, 130 load module 7 supplied at execution time 1 Visual Basic 195 stored procedures address space architecture 7 batch debug tool 328 bringing down 58 CODE/370 311 installation 9 language-specific libraries 86 load library 100 multiple 57 non-DB2 resources 265 resident 102 START PROCEDURE command 19 STOP PROCEDURE command 20

466

Getting Started with DB2 Stored Procedures

22

STORPROC parameter 12 STORPROC.DLL 77 STORPROC.LOG 77 STORPROC.XMP 78 STORTIME 55 StrConv function 192 string variable 193 structure 121 subprocedures 333, 338, 341, 342 subprogram 85 subscript variable 155 subsystem identifier 32 subtask 255 Sun 68 Sybase 68 SYM TEST suboption 313 symbol table 313 symbolic destination 311, 315 synch point manager 265 synch point processing 277 synchronous execution 265 SYNCLEVEL 291 SYNCLVL specification 265 synonyms 151 SYS1.MIGLIB library 60 SYS1.SAMPLIB library 63 SYSADM authority 19, 20, 21, 101 SYSCTRL authority 19, 20, 21 SYSDEFSD data set 226, 227 SYSEXEC statement 99 SYSIBM.SYSLOCATIONS 221 SYSIBM.SYSPROCEDURES application environment 30 CALL flow 7 CLI 228 columns 14 entries required to run in DB2 and WLM-established address space 52 indicator variables 92 INSERT statement 103 MRSP 150 passing nulls 90 restricting access 104 search precedence 16 START PROCEDURE command 19 updating 13 SYSOPR 19, 20, 21 SYSOUT statement 57 Sysplex application environment 30, 32 checking WLM data sets 56 couple data sets 26 DISPLAY command 34 log streams 59 MODIFY command 33 MONOPLEX 60 OS/390 level 37 RRS CFRM policy 63 RRS implementation 59

Sysplex (continued) service policy 26 STOPPING state 35 VARY command 34 VARY WLM command 34 SYSPROC 120, 129 System Application Architecture See SAA system authorization facility see SAF System Automation for OS/390 33 system logger 59 System Performance Monitor/2 See SPM/2 system-directed access 87, 129 SYSTEM(MVS) compile option 94

T table space 70 task control block See TCB TCB application environment 30 changing the number 13 DRA 273, 275 multiple 272 number of 9 RRSAF 256 stored procedures address space 7 testing 57 TCP/IP 5, 149, 379, 416 TERMINATE call 87 TERMINATE IDENTIFY function call 257, 260, 261 TERMINATE THREAD function call 257, 259, 261 TERMINSTANCE 113 test user program 11 VAB 340, 343 VisualGen 134 TEST compiler option 312 TEST run-time option 311, 314, 316 TEST suboptions 312 think time 384 thread CONNECT TYPE 2 89 creation 7 DB2 for MVS/ESA 22, 384 must rollback state 86 porting CLI applications 249 RRSAF 255 three-part names 18, 86, 87, 88, 129 threshold 387, 402 throughput aggregate 389, 404, 405 client/server 412 DDCS for AIX 398 DDCS for OS/2 383, 384 NCP 387, 401

TIME data type 96 time stamp 336 timeout 21, 55 TIMEOUT VALUE parameter 9, 12, 23 TIMESTAMP data type 96 TP profile 293 TPN 292, 293, 308 TPNAME 293, 311 TR0C2CC2 client 181 TR0C2S stored procedure 183 TRACEFILENAME statement 229 traditional coding 299 transaction control 199 transaction program name See TPN transaction Tx1 description 380 potential lock contention 391, 405 SQL statements 390, 404 transaction Tx2 description 380 potential lock contention 392, 406 SQL statements 391, 406 transaction Tx3 description 380 potential lock contention 393, 408 SQL statements 393, 407 transaction Tx4 description 380 potential lock contention 394, 408 SQL statements 394, 408 transaction Tx5 description 380 potential lock contention 395, 409 SQL statements 395, 409 transaction Tx6 description 381 potential lock contention 396, 410 SQL statements 396, 410 transaction Tx7 description 381 potential lock contention 397, 411 SQL statements 397, 411 TRANSLATE function call 87, 256, 257, 260 triggers 67 TRUNC(BIN) option 17 truncation 190 trusted stored procedure See unfenced stored procedure TSO 29, 305, 306 tuning buffer pool 382 database 389 DB2 Connect 428 DB2 for MVS/ESA 398 two-phase commit accessing IMS databases 277 APPC 291 DRDA 3

Index

467

two-phase commit (continued) RRS 265 RRSAF 256 WLM-established stored procedure type 2 indexes 381, 418

25

U UDF 67, 129, 331, 333 udf files 334 UDT 67, 335 undelimited constant 130 unfenced stored procedures environment variables 107 LIBPATH 112 measurement 302 MRSP 138 performance 302, 304 placement 111 searching 126 Unicode 189, 190, 191 unit of work client program 118 COMMIT_ON_RETURN 18 CONNECT TYPE 2 88, 89 DB2 for MVS/ESA 8 DB2 for OS/390 8 DB2 on MVS 7 non-DB2 resources 265 performance goals 29 rollback 87 RRSAF 258 unit-of-recovery 59 UNIX 67, 128 unqualified name 120 UPDATE statement 13, 152 uppercase DB2 for AIX 130 DB2 for OS/2 130 delimited identifier 130 function name 114, 195 porting applications 236 stored procedure name 112, 129, 195 undelimited constant 130 user-defined functions See UDF user-defined types See UDT USING DESCRIPTOR 121, 124 util.c 139 util.h 139

V V2SUTIL utility 228, 248 VAB client 132, 337, 339 creating stored procedures 332 debugging and testing with VAB 340

468

Getting Started with DB2 Stored Procedures

VAB (continued) developing stored procedure 335 development environment 331 diskette 348 editing a project 334 functions and features 331 home page 345 remote debugger 343 testing using QuickTest 343 VARCHAR data type 96 VARCHAR parameter 17, 296 VARGRAPHIC data type 96 VARGRAPHIC parameter 17 variable descriptor 226 variable pool 108 VARY WLM command 33, 34, 55, 58 VBX 331, 332, 337 views 104, 151 virtual storage 9, 11, 102 Visual Basic coding considerations 189 coding the application 194 diskette 359 ODBC driver 187 VAB 331, 332, 337 visual explain 67 VisualAge 113 VisualAge for Basic See VAB 135 VisualDebugger 86 VisualGen 85, 132, 134 v m s t a t 380 VS COBOL II 85 VSAM DataJoiner 68 JCL requirement 265 RACF 12, 53 RRS log streams 60 temporary table 151 VTAM 310, 379, 386, 401, 416

W wait state 322 WARP 379 WATCOM FORTRAN 77 32 Version 9.5 WCHARTYPE option 76, 111 Web enablement 68 Net.Data 69 WIN-OS/2 187 Windows client support 67 coding considerations 187 diskette 348 protected mode 114 STORPROC.DLL 77 VAB 331

4, 105

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 [email protected]

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

SG24-4693-01

IBML

SG24-4693-01 Printed in the U.S.A.

Getting Started with DB2 Stored Procedures: Give Them a Call through the Network

Related Documents

Db2
October 2019 26
Db2
November 2019 17
Db2
November 2019 24
Db2
July 2020 13
Db2
November 2019 19
Db2
November 2019 29