Cross-Platform DB2 Stored Procedures: Building and Debugging

Setting up the environment for DB2

Building DB2 stored procedures

Debugging DB2 stored procedures

Maria Sueli Almeida Marian Alcazar Paolo Bruni Sabine Kaschta Mark Leung ibm.com/redbooks

SG24-5485-01 International Technical Support Organization

Cross-Platform DB2 Stored Procedures: Building and Debugging

May 2001 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 497.

Second Edition (May 2001)

This edition applies to Version 6 of IBM 2 Universal Database Server for OS/390 (DB2 UDB Server for OS/390 Version 6), Program Number 5645-DB2, Version 7 of DB2 UDB for UNIX, Windows, OS/2, IMS Version 6, Release 3 of CICS Transaction Server for OS/390, Program Number 5655-147, and other current versions and releases of IBM products. Make sure you are using the correct edition for the level product.

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 1999, 2001. 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...... xiii

Tables...... xix

Preface...... xxi The team that wrote this redbook...... xxi Comments welcome...... xxiii

Part 1. Introduction ...... 1

Chapter 1. How this book is organized ...... 3 The content ...... 3

Part 2. Infrastructure ...... 5

Chapter 2. The IBM DB2 Stored Procedure Builder ...... 7 2.1 Overview ...... 7 2.1.1 What is DB2 SPB? ...... 7 2.1.2 Programming languages supported ...... 9 2.2 Product Installation on Windows NT ...... 10 2.2.1 Prerequisites for SPB ...... 10 2.2.2 Installing the SPB ...... 11 2.3 Advanced configuring of the SPB ...... 11 2.4 Concepts and terminology ...... 12 2.4.1 Project ...... 13 2.4.2 Create ...... 13 2.4.3 Generate ...... 13 2.4.4 Build ...... 14 2.4.5 Register ...... 14 2.4.6 Run ...... 14 2.4.7 Get source ...... 14 2.4.8 Modify ...... 15 2.4.9 Dirty procedures...... 15 2.4.10 Database connection ...... 15 2.5 The SPB components...... 15 2.5.1 The stored procedure wizards ...... 16 2.5.2 The SQL Assistant ...... 18 2.5.3 Client configuration assistant ...... 19 2.5.4 IBM Distributed Debugger ...... 19 2.6 Working with SPB projects ...... 20

© Copyright IBM Corp. 2001 iii 2.6.1 Creating projects under the SPB ...... 21 2.6.2 Managing SPB projects ...... 23 2.7 Using the Stored Procedure Builder ...... 23 2.7.1 Viewing existing stored procedures ...... 24 2.8 Creating new stored procedures...... 27 2.8.1 The stored procedure wizard ...... 29 2.8.2 SQL Assistant...... 37 2.9 Building stored procedures...... 47 2.10 Modifying existing stored procedures ...... 47 2.11 Copying and pasting stored procedures across connections...... 49 2.12 The SPB additional considerations ...... 50 2.12.1 Java 1.2 support for the IBM DB2 Stored Procedure Builder. . . 51 2.12.2 Building SQL Procedures on the Intel and UNIX platforms . . . . 52 2.12.3 UNIX installations and the SPB ...... 52 2.12.4 Known problems and limitations ...... 53

Chapter 3. SQL Procedures language...... 55 3.1 Introduction to stored procedures ...... 55 3.2 What is the SQL Procedures language?...... 56 3.3 Planning to use the SQL Procedures language ...... 57 3.3.1 Why use it? ...... 57 3.3.2 When to use SQL stored procedures? ...... 61 3.4 Comparing SQL procedures and external stored procedures ...... 64 3.4.1 Development ...... 64 3.4.2 Runtime ...... 66 3.5 Current implementation of SQL Procedures language ...... 66 3.5.1 How does this work in general? ...... 67 3.5.2 Declaring SQL local variables...... 68 3.5.3 Language elements ...... 70 3.5.4 Handling errors in an SQL stored procedure...... 92 3.5.5 Returning result sets...... 103 3.6 SQL Procedures portability...... 106 3.6.1 How to read the portability tables ...... 107

Chapter 4. IBM Distributed Debugger ...... 127 4.1 Distributed Debugger for the workstation ...... 128 4.1.1 Installing the Distributed Debugger on the workstation ...... 128 4.2 Distributed Debugger for OS/390 ...... 128 4.2.1 Installing the Distributed Debugger on OS/390 ...... 129 4.2.2 Setting up for remote debugging...... 129

Chapter 5. OS/390 Workload Manager...... 131 5.1 Introduction to OS/390 Workload Manager (WLM) ...... 131 5.1.1 What is WLM? ...... 132

iv Cross-Platform DB2 Stored Procedures: Building and Debugging 5.1.2 WLM definitions — relationships...... 132 5.1.3 Classification rules ...... 135 5.2 Application environments ...... 137 5.2.1 Defining the application environment ...... 137 5.2.2 Specifying application environments to WLM ...... 138 5.3 Compatibility mode...... 141 5.4 Goal mode ...... 142 5.5 Managing application environments ...... 143 5.5.1 The QUIESCE option ...... 144 5.5.2 The RESUME option ...... 144 5.5.3 The REFRESH option...... 144 5.6 Handling error conditions in the application environment ...... 145 5.7 Defining a service definition ...... 145 5.8 Existing service definition ...... 146 5.9 RACF considerations for WLM-established address space...... 147 5.10 Operations and problem determination...... 148 5.11 Experimenting with goal and compatibility modes...... 152 5.11.1 DB2 and WLM setup...... 152 5.11.2 Client and server programs used for testing purposes ...... 153 5.11.3 WLM Goal mode using automatic control ...... 153 5.11.4 WLM compatibility mode using automatic control ...... 155 5.12 Refreshing the WLM environment through stored procedures . . . . 156 5.12.1 Using the WLM_REFRESH stored procedure ...... 156 5.12.2 WLM_REFRESH stored procedure security ...... 157 5.12.3 WLM_REFRESH stored procedure environment...... 157 5.12.4 Installing the WLM_REFRESH stored procedure ...... 158 5.12.5 WLM environment for WLM_REFRESH stored procedure . . . 158 5.12.6 Customizing DSNTEJ6W for preparing and testing WLM_REFRESH ...... 159 5.13 Implementing OS/390 resource recovery services (RRS) support. . 160 5.13.1 RRS log streams ...... 161 5.13.2 Activating the CFRM policy to support RRS ...... 166 5.13.3 Making the RRS JCL procedure available...... 166 5.13.4 Adding RRS subsystem name ...... 167 5.13.5 Starting and stopping RRS ...... 168 5.13.6 RRS error samples ...... 168

Chapter 6. OS/390 Recoverable Resource Manager Services ...... 171 6.1 Prerequisite knowledge ...... 171 6.2 Capabilities of RRSAF applications ...... 171 6.3 Task capabilities...... 172 6.4 Programming languages supported ...... 172 6.5 Program size ...... 172

v 6.6 RRSAF use of load...... 173 6.7 and rollback operations ...... 173 6.8 Run environment ...... 173 6.9 RRSAF language interface ...... 173 6.10 How to use RRSAF ...... 174 6.10.1 IDENTIFY function ...... 174 6.10.2 SIGNON function ...... 176 6.10.3 AUTH SIGNON function ...... 177 6.10.4 CREATE THREAD function ...... 177 6.10.5 TERMINATE THREAD function ...... 178 6.10.6 TERMINATE IDENTIFY function...... 178 6.10.7 TRANSLATE function ...... 179 6.10.8 Sample JCL to use RRSAF...... 179 6.11 Common RRSAF errors ...... 179 6.11.1 IDENTIFY return code 8 reason code 15925393...... 179 6.11.2 IDENTIFY return code 8 reason code 15925250...... 180 6.11.3 IDENTIFY return code 12 ...... 180 6.11.4 CREATE THREAD return code 12 ...... 180

Part 3. Accessing non-DB2 resources ...... 181

Chapter 7. DB2 stored procedures and CICS ...... 183 7.1 Accessing CICS systems ...... 183 7.2 Using EXCI in a stored procedure ...... 184 7.2.1 Preparing CICS for EXCI ...... 185 7.2.2 CICS definitions ...... 185 7.2.3 Preparing stored procedure for EXCI ...... 192 7.3 Application scenario ...... 196 7.3.1 Sample stored procedure ...... 198 7.3.2 Sample CICS program ...... 200 7.3.3 Program preparation for EXCI ...... 201

Chapter 8. DB2 stored procedures and IMS ...... 205 8.1 Accessing IMS ...... 206 8.2 What is ODBA? ...... 207 8.3 Using DB2 stored procedure in conjunction with ODBA ...... 208 8.3.1 ODBA architecture ...... 209 8.4 Considerations for using ODBA ...... 210 8.4.1 What types of IMS can DB2 ODBA SPs connect to?...... 210 8.4.2 Limitations of ODBA programming ...... 211 8.4.3 Multiple access to IMS subsystems ...... 211 8.4.4 Refreshing WLM application environments ...... 211 8.4.5 Software prerequisites ...... 211

vi Cross-Platform DB2 Stored Procedures: Building and Debugging 8.4.6 Miscellaneous questions and answers ...... 212 8.5 Getting started with ODBA and DB2 stored procedure: step by step. 213 8.6 Create DB2 ODBA stored procedure environments ...... 217 8.6.1 Step 1: Create IMS DRA startup table ...... 218 8.6.2 Step 2: Create JCL: WLM DB2 stored procedure address space218 8.6.3 Step 3: Create the WLM application environment ...... 219 8.6.4 Sample WLM AE setup for DB2 ODBA stored procedures . . . . 219 8.7 Program preparation ...... 222 8.7.1 Step 1: A sample DB2 ODBA stored procedure ...... 222 8.7.2 Step 2: Compiling and linking the stored procedure ...... 227 8.7.3 Step 3: Binding the stored procedure ...... 229 8.7.4 Step 4: Defining the stored procedure to DB2...... 229 8.8 Running DB2 ODBA stored procedures ...... 230 8.8.1 Start relevant IMS and DB2 subsystems...... 230 8.8.2 Executing the DB2 ODBA stored procedure ...... 231 8.8.3 Terminating a DB2 ODBA stored procedure address space . . . 232 8.8.4 Problem determination ...... 236 8.9 Testing DB2 ODBA stored procedures ...... 238 8.9.1 Tracing DL/I calls with image capture ...... 238 8.9.2 Using the DL/I test program DFSDDLT0 ...... 240 8.10 DB2 ODBA stored procedures explained ...... 240 8.10.1 DB2 ODBA stored procedure coding overview ...... 240 8.10.2 The DRA startup table ...... 245 8.10.3 Security considerations...... 248 8.10.4 Making calls to IMS ...... 249 8.10.5 Writing an ODBA program ...... 255 8.10.6 What happens when the ODBA stored procedure runs ...... 260 8.10.7 The life of a thread in a DB2 ODBA stored procedure...... 261 8.10.8 Application programming considerations...... 265 8.11 Sample DB2 ODB2 stored procedure scenarios ...... 266 8.11.1 DB allocation problem scenario ...... 266 8.11.2 PSB not found scenario ...... 268 8.11.3 Running multiple DB2 ODBA SPs to the same IMS ...... 269 8.11.4 DRA initialization problem case study for Fast Path ...... 272 8.12 Defining IMS resources ...... 274 8.12.1 A sample including IMS steps...... 274 8.12.2 Defining what IMS databases a program can access ...... 274 8.12.3 Defining databases and programs to IMS ...... 277 8.12.4 Building the IMS database and making it operational ...... 280

vii Part 4. Implementing SQL Procedures ...... 281

Chapter 9. Installation cookbook ...... 283 9.1 Required software components ...... 283 9.2 Windows NT — platform...... 284 9.2.1 DB2 UDB for WIN/NT Version 7.1...... 285 9.2.2 DB2 UDB for WIN/NT Version 7.1 Fixpack 1...... 314 9.3 OS/390 — platform...... 316 9.3.1 DB2 UDB for OS/390 V6...... 316 9.3.2 Make REXX support available ...... 316 9.3.3 SQL Procedure support ...... 317 9.3.4 WLM definitions ...... 319 9.4 Visual Age for JAVA V3.5 for Windows...... 328

Chapter 10. SQL Procedures for DB2 for UNIX, Windows, OS/2 . . . . 331 10.1 General considerations...... 331 10.2 Creating an SQL procedure ...... 332 10.2.1 Retaining intermediate files ...... 335 10.3 Coding considerations ...... 335 10.3.1 Recommendations for writing portable stored procedures. . . . 336 10.3.2 Structure of SQL stored procedures ...... 336 10.3.3 Coding the SQL stored procedures body ...... 337 10.4 Stored procedures preparation ...... 346 10.4.1 Privileges required to prepare an SQL stored procedure. . . . . 348 10.4.2 Copying SQL stored procedures between DB2 UDB servers . 348

Chapter 11. SQL Procedures — OS/390 platform ...... 349 11.1 General considerations...... 349 11.2 Coding considerations ...... 349 11.2.1 Length and size limits ...... 350 11.2.2 Parameters and variables...... 351 11.2.3 Handling SQLCODE and SQLSTATE values ...... 351 11.2.4 SQL statements ...... 352 11.2.5 Client application ...... 353 11.3 Stored procedure preparation...... 353 11.3.1 Steps to create an SQL stored procedure ...... 354 11.3.2 Authorization ...... 355 11.3.3 Using the SPB to create an SQL stored procedure ...... 356 11.3.4 Using batch DSNTPSMP to create an SQL stored procedure . 359 11.3.5 Using JCL to create an SQL stored procedure ...... 373 11.4 Use of different WLM environments in SPB ...... 381 11.5 Dropping stored procedures considerations ...... 387

viii Cross-Platform DB2 Stored Procedures: Building and Debugging Chapter 12. SQL Procedures for DB2 UDB for AS/400 ...... 389 12.1 General considerations...... 389 12.2 System requirements and planning...... 389 12.3 System catalog tables ...... 390 12.3.1 SYSROUTINES catalog ...... 390 12.3.2 SYSPARAMS catalog ...... 391 12.4 Creating an SQL stored procedure ...... 391 12.4.1 Creating an SQL SP with traditional tools ...... 392 12.4.2 Creating an SQL SP with Operations Navigator GUI...... 397 12.4.3 Creating an SQL SP with the Run SQL Scripts utility ...... 399 12.4.4 Verifying the stored procedure properties ...... 402 12.5 Deleting or replacing the SQL stored procedure ...... 403 12.5.1 Procedure overloading ...... 405 12.5.2 Dropping overloaded procedures ...... 406 12.6 Using the Stored Procedure Builder ...... 406 12.6.1 Prerequisites ...... 406 12.6.2 Setting up the DB2 UDB for AS/400 project ...... 407 12.6.3 Working with SQL SP on the AS/400 system ...... 409 12.7 Error handling...... 412 12.8 Debugging SQL stored procedures...... 415 12.8.1 The ILE Source Debugger ...... 416 12.8.2 Preparing SQL stored procedure for debugging ...... 417 12.8.3 Testing QL stored procedure in traditional environment . . . . . 420 12.8.4 Testing QL stored procedure in client/server environment . . . 423 12.9 Porting considerations ...... 430 12.9.1 Handler declaration ...... 430 12.9.2 The order of DECLARE statements ...... 431 12.9.3 Nested compound statements ...... 432

Part 5. Debugging stored procedures ...... 433

Chapter 13. Debugging stored procedures — cross-platform ...... 435 13.1 Debugging stored procedures ...... 435 13.1.1 Setting up the SPB for debugging...... 436 13.1.2 Setting Debug properties on a workstation server...... 437 13.1.3 Setting the TCP/IP address and port for the debugger ...... 437 13.1.4 Setting debug properties on OS/390 server ...... 438 13.1.5 Some debugging experience on OS/390 platform ...... 439 13.2 Debugging stored procedures on UNIX and Windows ...... 443 13.2.1 Platforms supported for remote debugging ...... 444 13.2.2 The DB2DBG.ROUTINE_DEBUG debugger table ...... 444 13.2.3 DB2 environment variables for debugging ...... 445 13.2.4 Starting the debugger client ...... 446

ix 13.2.5 Debugging stored procedures through SPB ...... 446

Part 6. Appendices ...... 447

Appendix A. SQL procedures samples...... 449 A.1 Naming convention ...... 449 A.2 Windows NT stored procedures samples ...... 449 A.2.1 SP01LNS.SQL sample ...... 449 A.2.2 SP02LNS.SQL sample ...... 451 A.2.3 SP03LNS.SQL sample ...... 451 A.2.4 SP04LNS.SQL sample ...... 452 A.2.5 SP05LNS.SQL sample ...... 452 A.2.6 SP06LNS.SQL sample ...... 453 A.2.7 SP07LNS.SQL sample ...... 453 A.2.8 SP08LNS.SQL sample ...... 454 A.2.9 SP09LNS.SQL sample ...... 454 A.2.10 SP10LNS.SQL sample ...... 455 A.2.11 SP11LNS.SQL sample ...... 455 A.2.12 SP12LNS.SQL sample ...... 456 A.2.13 SP13LNS.SQL sample ...... 456 A.2.14 SP14LNS.SQL sample ...... 457 A.2.15 SP15LNS.SQL sample ...... 457 A.2.16 SP16LNS.SQL sample ...... 458 A.2.17 SP17LNS.SQL sample ...... 458 A.2.18 CALLEE sample for NT ...... 459 A.2.19 CF025 sample for NT ...... 460 A.3 OS/390 stored procedures samples ...... 462 A.3.1 CALLEE sample for OS/390 ...... 462 A.3.2 SP01LMS.SQL sample...... 465 A.3.3 SP02LMS.SQL sample...... 467 A.3.4 SP03LMS.SQL sample...... 467 A.3.5 SP04LMS.SQL sample...... 468 A.3.6 SP05LMS.SQL sample...... 468 A.3.7 SP06LMS.SQL sample...... 469 A.3.8 SP07LMS.SQL sample...... 469 A.3.9 SP08LMS.SQL sample...... 470 A.3.10 SP09LMS.SQL sample...... 470 A.3.11 SP10LMS.SQL sample...... 471 A.3.12 SP11LMS.SQL sample...... 472 A.3.13 SP12LMS.SQL sample...... 472 A.3.14 SP13LMS.SQL sample...... 473 A.3.15 SP14LMS.SQL sample...... 473 A.3.16 SP15LMS.SQL sample...... 474

x Cross-Platform DB2 Stored Procedures: Building and Debugging A.3.17 SP16LMS.SQL sample...... 475 A.3.18 SP17LMS.SQL sample...... 475 A.4 AS/400 stored procedures samples ...... 476 A.4.1 SP01L4S.SQL sample ...... 476 A.4.2 SP02L4S.SQL sample ...... 477 A.4.3 SP03L4S.SQL sample ...... 478 A.4.4 SP04L4S.SQL sample ...... 478 A.4.5 SP05L4S.SQL sample ...... 479 A.4.6 SP06L4S.SQL sample ...... 480 A.4.7 SP08L4S.SQL sample ...... 480 A.4.8 SP09L4S.SQL sample ...... 481 A.4.9 SP11L4S.SQL sample ...... 481 A.4.10 SP12L4S.SQL sample ...... 482 A.4.11 SP13L4S.SQL sample ...... 482 A.4.12 SP14L4S.SQL sample ...... 482 A.4.13 SP15L4S.SQL sample ...... 483 A.4.14 SP16L4S.SQL sample ...... 484 A.4.15 SP17L4S.SQL sample ...... 484

Appendix B. DB2 and IMS ODBA samples...... 487 B.1 Putting the ODBA samples onto OS/390 ...... 487 B.2 IMS DB samples: GN an ISRT calls ...... 488 B.2.1 Sample source members ...... 489 B.2.2 Sample SQL members ...... 489 B.2.3 Sample JCL members ...... 490 B.3 ICMD samples ...... 490 B.3.1 AIB ICMD BMP sample ...... 490 B.3.2 AIB ICMD ODBA sample ...... 491 B.3.3 AIB ICMD ODBA stored procedure sample ...... 491

Appendix . Using the additional material ...... 493 C.1 Locating the additional material on the Internet ...... 493 C.1.1 Non-DB2 resources ...... 494 C.1.2 SQL stored procedures for AS/400 ...... 494 C.1.3 SQL stored procedures for Windows/NT ...... 495 C.1.4 SQL stored procedures for OS/390 ...... 495 C.2 Using the Web material ...... 496 C.2.1 How to use the Web material ...... 496

Appendix D. Special notices ...... 497

Appendix E. Related publications ...... 501 E.1 IBM Redbooks ...... 501 E.2 IBM Redbooks collections...... 501

xi E.3 Other resources ...... 501 E.4 Referenced Web sites...... 503

How to get IBM Redbooks ...... 505 IBM Redbooks fax order form ...... 506

Glossary ...... 507

Abbreviations and acronyms ...... 525

Index ...... 529

IBM Redbooks review ...... 537

xii Cross-Platform DB2 Stored Procedures: Building and Debugging Figures

1. The SPB environment ...... 7 2. The SPB topology ...... 9 3. SPB - environment properties ...... 12 4. SPB main panel - Project window ...... 16 5. SPB inserting a procedure using wizard ...... 17 6. The stored procedure wizards ...... 17 7. SQL Assistant window ...... 19 8. SPB projects (*.spp), connections and stored procedures ...... 20 9. Creating new project “ITSO SG245485” ...... 21 10. Tree of existing stored procedures ...... 24 11. Detailed view of existing stored procedures ...... 25 12. Filtering the list of stored procedures...... 26 13. The Filter dialog window ...... 27 14. Creating a new SQL stored procedure ...... 28 15. The Name panel of the stored procedure wizard...... 29 16. The Pattern panel of the stored procedure wizard...... 30 17. The SQL Statement panel of the stored procedure wizard ...... 32 18. The Parameters panel of the stored procedure wizard ...... 33 19. The Define Parameter dialog ...... 34 20. The Options panel of the stored procedure wizard ...... 35 21. The Advanced SP Options for DB2 for OS/390 SQL stored procedures. . 36 22. The Advanced Build Options for DB2 for OS/390 SQL stored procedures 37 23. The Tables panel of the SQL Assistant ...... 38 24. The Joins panel of the SQL Assistant ...... 39 25. Changing the type of Join created by SQL Assistant...... 40 26. The Conditions panel of the SQL Assistant ...... 41 27. The Expression Builder - Conditions ...... 42 28. Specifying a variable for a condition ...... 42 29. The Columns panel of the SQL Assistant ...... 43 30. The Order panel of the SQL Assistant...... 44 31. The Review panel of the SQL Assistant ...... 45 32. Entering values for variables in the SQL statement...... 46 33. Displaying the results of the SQL Statement ...... 46 34. Modifying an existing stored procedure ...... 48 35. Copying one SQL stored procedure ...... 49 36. Paste the stored procedure at the target server ...... 50 37. The usual SQL client, where the logic sends many SQL queries ...... 59 38. SQL client using the same logic, but within an SQL stored procedure . . . 59 39. An example of shielding tables from users ...... 61 40. ALLOCATE, ASSOCIATE, RESULT SET LOCATOR statements ...... 71

© Copyright IBM Corp. 2001 xiii 41. CONTINUE handler ...... 94 42. CONTINUE handler with blocks...... 95 43. CONTINUE handler with error in IF statement ...... 96 44. EXIT handler ...... 97 45. EXIT handler with called procedure...... 98 46. UNDO handler ...... 99 47. DECLARE handler statement with BEGIN ...END ...... 100 48. DECLARE handler statement with IF ...END IF...... 100 49. WLM — service definition ...... 133 50. Workload, Service Classes, and Service Class Periods ...... 134 51. Summary of the performance goals of a service class ...... 135 52. Assigning performance goals to stored procedures...... 136 53. SYSIBM.SYSROUTINES, application environment, JCL procedures . . . 139 54. Sample of the Application-Environment panel ...... 139 55. Relationship among WLM definitions...... 146 56. Choose Service Definition Panel ...... 147 57. CICS connection definition (1 of 2) ...... 186 58. CICS connection definition (2 of 2) ...... 187 59. CICS sessions definition (1 of 3) ...... 188 60. CICS sessions definition (2 of 3) ...... 189 61. CICS sessions definition (3 of 3) ...... 189 62. CICS transaction definition (1 of 4) ...... 190 63. CICS transaction definition (2 of 4) ...... 190 64. CICS transaction definition (3 of 4) ...... 191 65. CICS transaction definition (4 of 4) ...... 191 66. CICS program definition...... 192 67. WLM-established address space...... 193 68. Testing a stored procedure from the SPB (input) ...... 194 69. Testing a stored procedure from the SPB (output) ...... 195 70. Display command to see CICS regions defined to the Coupling Facility . 196 71. Application scenario...... 197 72. DRA architecture in a DB2 stored procedures context ...... 209 73. How WLM application environment WLMIMSD is defined...... 220 74. JCL procedure WLMIMS ...... 221 75. JCL INCLUDE member #IMSD ...... 221 76. JCL INCLUDE member #DBZ2 ...... 221 77. Invoking sample OD1BPMS using the SPB...... 231 78. Output from executing the stored procedure ...... 232 79. Output from a display command for the WLM ...... 233 80. Response from cancelling DB2 ODBA stored procedure address space 233 81. JCL to execute IMS File Select and Formatting Print Utility DFSERA10. 239 82. Output from print utility DFSERA10 in data set TRCPUNCH ...... 239 83. SYSPRINT output from DFSERA10 print utility ...... 240

xiv Cross-Platform DB2 Stored Procedures: Building and Debugging 84. The IMS control region DFSRRC00...... 242 85. Specifying execution parameter for BMP versus ODBA programs . . . . . 245 86. Using AERTDLI and the AIB Application Interface Block ...... 251 87. A PL/I example of an AIB mask ...... 254 88. Which PCBs will work with ODBA ...... 256 89. DB2 ODBA stored procedure flow ...... 261 90. Using DIS CCTL ALL command to identify jobname...... 263 91. Output from DIS UOR in IMS...... 264 92. RRS archive log from RRS Log Stream Browse Selection, option 1 . . . . 264 93. Output from IMS address space ...... 267 94. Output from DIS CCTL ALL and DIS UOR commands ...... 267 95. Output from DISPLAY THREAD command in DB2 ...... 268 96. Output from /DISPLAY CCTL ALL...... 270 97. Output from DB2 DISPLAY THREAD and DISPLAY PROCEDURE. . . . 271 98. DBD, PSB and ACB generation...... 275 99. DATABASE and APPLCTN macros to include sample DBD and PSB . . 277 100.Adding databases and programs to IMS with an online change ...... 278 101.Output from /dis prog command for a valid program...... 279 102.Output from /dis prog command for an invalid program ...... 279 103.Find out version and installed service packs of WIN/NT ...... 284 104.WIN/NT version and service pack information ...... 285 105.DB2 f. WIN/NT first installation screen ...... 286 106.DB2 f. WIN/NT — decide to install server version...... 287 107.DB2 f. WIN/NT — decide how to install...... 287 108.Choose Destination Location ...... 288 109.Install DB2 UDB — Choose username and password ...... 289 110.DB2 UDB installation — information about missing admin user ...... 289 111.DB2 UDB installation — start copying files ...... 290 112.DB2 UDB installation — install OLAP starter Kit? ...... 291 113.Open the CCA ...... 292 114.CCA — available DB2 databases ...... 293 115.Add Database Wizard ...... 294 116.Add Database Wizard — select protocol...... 295 117.Specify TCP/IP communications parameters ...... 296 118.Sample DSNJU004 JCL to print the BSDS ...... 296 119.DDF communication record in BSDS ...... 297 120.Specify the subsystem to which you want to connect ...... 297 121.Register database as ODBC data source ...... 298 122.Specify security options...... 299 123.Confirmation ...... 299 124.Test connection ...... 300 125.Connection test successful ...... 300 126.DB2 UDB installation — select to install a client ...... 301

xv 127.Required disk space for client installation ...... 302 128.DB2 UDB client installation — configure NetBIOS ...... 302 129.DB2 UDB installation — enter username for DB2 control center ...... 303 130.DB2 UDB installation — information about missing admin user ...... 304 131.DB2 UDB installation — specified user lacks authority ...... 304 132.DB2 UDB installation — final screen for client ...... 305 133.Open the CCA ...... 306 134.CCA — Add Database ...... 307 135.CCA — Add Database Wizard ...... 308 136.CCA — select communication protocol...... 309 137.CCA — specify TCP/IP communication parameters ...... 310 138.IPCONFIG to identify own TCP/IP address...... 311 139.DB2 UDB — DB2 GET DBM CFG output ...... 312 140.DB2 UDB TCP/IP port number ...... 312 141.CCA — specify the database to which to connect ...... 313 142.Open Command Window ...... 315 143.DB2LEVEL command output ...... 316 144.PROCEDURENAME after PTF UQ45625...... 318 145.WLM panel ...... 320 146.Choose service definition ...... 320 147.Definition Menu — for application environments...... 321 148.Application Environment selection list ...... 321 149.Create an Application Environment...... 323 150.WLM-definition Menu ...... 324 151.WLM utility pull down menu...... 324 152.WLM utility pull-down menu — activate service policy ...... 325 153.Policy selection list ...... 326 154.WLM flowchart...... 327 155.Visual Age for Java installation — first installation screen ...... 328 156.Visual Age for Java — select setup type...... 329 157.Visual Age for Java installation — Edit Features ...... 330 158.Using the same name for variables and parameters...... 339 159.Using variables with the same name as a ...... 340 160.Assigning special registers to variables ...... 341 161.Assigning results of built-in functions to variables...... 342 162.Setting SQLCODE and SQLSTATE variables to program variables. . . . 343 163.Nested compound statement ...... 344 164.Setting a ...... 344 165.Ways to create SQL stored procedures in DB2 UDB ...... 346 166.Preparation steps for SQL stored procedures in DB2 UDB ...... 347 167.CREATE PROCEDURE statement from SYSUT2 ...... 353 168.Three methods for preparing SQL stored procedures...... 354 169.SQL Costing Information panel ...... 359

xvi Cross-Platform DB2 Stored Procedures: Building and Debugging 170.Input / output for SQL Procedures processor ...... 360 171.DSNTPSMP - The BUILD process ...... 365 172.DESTROY process ...... 366 173.DSNHSQL process ...... 374 174.Advanced OS/390 options screen...... 383 175.Change WLM environment for an existing procedure ...... 384 176.Build and Debug screen for existing procedure ...... 385 177.Change default WLM environment for SPB ...... 386 178.Stored procedures in SPROCLIB library ...... 391 179.Entering source code ...... 393 180.Creating the SQL stored procedure ...... 394 181.Working with spool files...... 395 182.Displaying SQL precompiler error messages ...... 396 183.Parameters definition for SQL stored procedure...... 398 184.Entering SQL statements ...... 399 185.Creating SQL SP with script utility...... 400 186.Job log window ...... 401 187.Saving SQL Script File ...... 402 188.Displaying the stored procedure properties...... 403 189.Deleting a stored procedure ...... 404 190.Creating new DB2 UDB for AS/400 project...... 408 191.Main SPB window ...... 409 192.Inserting new database connection...... 410 193.Copying an SQL SP between DB2 UDB servers ...... 411 194.Visual Basic client returning a result set ...... 414 195.User-defined error condition ...... 414 196.RUNSQLSTM command ...... 418 197.Specifying the DBGVIEW and OUTPUT parameters ...... 419 198.Starting a debug session...... 420 199.Debug session...... 421 200.INVDSK2LMS source code ...... 422 201.Running Java client ...... 424 202.Finding the database server job ...... 425 203.Job log for a database server job ...... 425 204.Calling the stored procedure from Java ...... 426 205.IBM Distributed Debugger — topology ...... 435 206.Debugging process ...... 439 207.Starting listener without VisualAge for Java installed ...... 440 208.Debugger: Error message: EQ2382E ...... 441 209.IBM Distributed Debugger daemon ...... 441 210.IBM Distributed Debugger main window ...... 442 211.Monitoring variables ...... 443 212.Naming convention for samples ...... 449

xvii 213.Data sets used for ODBA samples ...... 487 214.Samples tree ...... 493

xviii Cross-Platform DB2 Stored Procedures: Building and Debugging Tables

1. SPB support...... 10 2. SQL statements in SQL Procedures - portability across DB2 servers. . . 108 3. SQL statements in SQL Procedures - portability across DB2 platforms . 117 4. Limits in SQL Procedures - portability across DB2 platforms ...... 122 5. Other remarks on SQL Procedures - portability across DB2 platforms . . 123 6. POST codes for types of DB2 terminations ...... 175 7. IMS types...... 205 8. Ways to access IMS database...... 206 9. Creating our test environment step by step ...... 215 10. Names and their environments ...... 236 11. Tracking down steps during the life of a stored procedure execution . . . 237 12. DB PCB structure...... 243 13. DFSPRP macro keywords ...... 246 14. IMS function calls supported by ODBA ...... 250 15. Contents of AIB for AERTDLI calls by DB2 ODBA stored procedures . . 252 16. How to fill in the AIB for typical IMS DL/I calls ...... 255 17. AIB Mapping after executing CALL ...... 258 18. Life of a dependent region versus life of a thread ...... 262 19. Putting the pieces together for DB2 ODBA stored procedure ...... 262 20. Type mapping table for SQL, JDBC, and Java ...... 265 21. Sequence of events for database allocation problem ...... 266 22. PSB not found problem ...... 268 23. Reaching limit of MAXTHD in DRA startup table ...... 270 24. Sequence of events for DRA initialization problem ...... 272 25. ODBA sample database ...... 276 26. Sample ODBA data sets ...... 488 27. ODBA sample source ...... 489 28. ODBA sample SQL members ...... 489 29. ODBA sample JCL members...... 490 30. Sample BMP to show ICMD calls ...... 490 31. Sample ODBA stored procedure to show ICMD calls ...... 491 32. Sample SPI stored procedure to show ICMD calls ...... 491

© Copyright IBM Corp. 2001 xix xx Cross-Platform DB2 Stored Procedures: Building and Debugging Preface

This IBM Redbook is the result of a residency project conducted at the IBM International Technical Support Organization, San Jose Center. The project tested and implemented stored procedures executing in DB2 for OS/390, DB2 for Windows NT, DB2 UDB for AIX, and DB2 for AS/400 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 book covers the SQL Procedures language (which provides the customer with the facility for developing their stored procedures in a standard and portable language across the DB2 family and OEM DBMSs), the IBM Stored Procedure Builder, and the IBM Distributed Debugger. In addition, it explains how to implement DB2 stored procedures accessing non-DB2 resources.

We developed and documented several sample stored procedure programs to illustrate the theory discussed in this book. The samples are documented in detail and they are available to be downloaded. These programs are useful for getting started with the SQL Procedures language in your own environment and gaining some hands-on experience on whatever platform you may have.

This book 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 and Distributed Architecture connectivity among 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.

Maria Sueli Almeida is a Certified I/T Specialist - Systems Enterprise Data. During the writing of this redbook, she was a DB2 for OS/390 and Distributed Relational Database System (DRDS) specialist at the International Technical Support Organization, San Jose Center. Before joining the ITSO in 1998, Maria Sueli worked at IBM Brazil assisting customers and IBM technical professionals on DB2, data sharing, , performance, and DRDA connectivity.

© Copyright IBM Corp. 2001 xxi Marian Alcazar is a DB2 specialist in Spain. She has over 12 years of experience in the field of information technology, mainly in DB2 for OS/390. Her areas of expertise include application design and development, database design and management, DB2 performance optimization and tuning, and datasharing.

Paolo Bruni is on assignment as a Data Management Specialist for DB2 for OS/390 at the International Technical Support Organization, San Jose Center, where he conducts projects on all areas of DB2 for OS/390. Before joining the ITSO in 1998, Paolo worked as Consultant IT Architect in IBM Italy. During his 31 years with IBM, in development and in the field, Paolo’s work has been mostly related to database systems.

Sabine Kaschta is a DB2 specialist working for IBM Global Learning Services in Germany as an education consultant. She has 10 years of experience working with DB2. Before she joined IBM in 1998, she worked for a third-party vendor providing second-level support for DB2 utility products. She is also experienced in DB2 system programming and client/server implementations within an insurance practice in Germany. She is also a co-author of the IBM Redbook DB2 UDB Server for OS/390 Version 6 and Continuous Availability, SG24-5486.

Mark Leung is DB2 specialist in Australia. He currently works as a performance test analyst for IBM Global Services Australia in Brisbane. Prior to moving to Brisbane, he has worked as a DB2 DBA and an application programmer in Sydney, and as a DB2 system tester at IBM Toronto Lab. He has contributed in previous redbooks on DB2 stored procedures and in PL/I programming.

Jarek Miszczyk is a Senior Software Engineer at the PartnerWorld for Development organization in Rochester, Minnesota. Before joining the PWD, he has worked for three years at the International Technical Support Organization, Rochester Center. He writes extensively and teaches IBM classes worldwide in all areas of DB2 UDB for AS/400. He has 13 years experience in the computer field. His areas of expertise include cross-platform database programming, SQL, and object-oriented programming. Jarek holds a master degree in Computer Science from the Technical University in Wroclaw, Poland.

xxii Cross-Platform DB2 Stored Procedures: Building and Debugging Thanks to the following people for their invaluable contributions to this project:

Yvonne Lyon Claudia Traver Phil Wakelin International Technical Support Organization, San Jose Center

Peggy Abelite Rick Becraft David Compton Patrick Dantressangle Thomas Eng Marion Farber Rick Long Connie Nelin Peggy Rader IBM Silicon Valley Laboratory

Dougie Lawson Pete Sadler IBM UK

Gustavo Arocena IBM Toronto Laboratory

Giri Giritharan IBM Global Services Australia

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 “IBM Redbooks review” on page 537 to the fax number shown on the form. • Use the online evaluation form found at ibm.com/redbooks • Send your comments in an Internet note to [email protected]

xxiii xxiv Cross-Platform DB2 Stored Procedures: Building and Debugging Part 1. Introduction

© Copyright IBM Corp. 2001 1 2 Cross-Platform DB2 Stored Procedures: Building and Debugging Chapter 1. How this book is organized

This chapter explains how this book is organized in order to describe the implementation of DB2 stored procedures in several different scenarios. In addition, it describes all the infrastructure required for those implementations.

The content The content of this book is divided into six parts. We recommend that you read the parts pertaining to your own area of exploitation, then peruse the other parts of the book for additional functions and enhancements which you may also find valuable. • Part 1: Introduction — Introduces the book and its contents. • Part 2: Infrastructure — Describes, for each platform, the software required for the implementation of the stored procedures. • Part 3: Accessing non-DB2 resources — Shows how DB2 stored procedures can work together with non-DB2 resources, such as CICS and IMS. • Part 4: Implementing SQL stored procedures — Explains, for each platform, how to implement the SQL stored procedures with or without using the IBM DB2 Stored Procedure Builder. • Part 5: Debugging stored procedures — Explains how to debug stored procedures through the use the IBM Distributed Debugger. • Part 6: Appendices — Present all the samples developed during the project to write this book. These samples are also delivered as additional material for this book. See Appendix C, “Using the additional material” on page 493.

© Copyright IBM Corp. 2001 3 4 Cross-Platform DB2 Stored Procedures: Building and Debugging Part 2. Infrastructure

© Copyright IBM Corp. 2001 5 6 Cross-Platform DB2 Stored Procedures: Building and Debugging Chapter 2. The IBM DB2 Stored Procedure Builder

This chapter describes the IBM DB2 Stored Procedure Builder (SPB) tool, and explains how it can be used to help with the development and maintenance of stored procedures for DB2 UDB, cross-platform.

2.1 Overview This section describes the DB2 SPB, its main components, prerequisites, installation, and customization.

2.1.1 What is DB2 SPB? The DB2 SPB is a graphical tool designed to help with the development of DB2 stored procedures. It provides all the functions required to create, build, test, and deploy new stored procedures. Using Stored Procedure Builder, you can also run stored procedures that you created in another editor and that use a language other than Java or the SQL procedure language. You might also want to test the execution of existing installed stored procedures.

The SPB provides a single development environment that supports the entire DB2 family ranging from the workstation to System/390. Figure 1 shows the environment for development and deploy stored procedures with SPB. With the SPB you can focus on the logic of your stored procedure rather than on the process details of creating stored procedures on a DB2 server.

Develop Deploy

jdbc DB2 Server

NT/SUN/AIX Windows Windows 95/98/2000 95/98/2000/NT From: SUN Stand-alone AIX Microsoft Visual Basic OS/390 IBM VisualAge for Java AS/400 LINUX

Figure 1. The SPB environment

© Copyright IBM Corp. 2001 7 The SPB supports two languages for the development of new stored procedures: Java, and SQL Procedures language.

It is important to notice that the SPB is not a prerequisite to write stored procedures for DB2 servers. The support for stored procedures, even for the SQL Procedures language, is built-in to the DB2 base code. For more details on the new SQL Procedures language, refer to Chapter 3, “SQL Procedures language” on page 55. For details on the implementation of SQL stored procedures in different DB2 servers, see the specific platform chapter on Part 4, “Implementing SQL Procedures” on page 281.

In summary, using the SPB you can perform a variety of tasks associated with stored procedures, such as: • Creating new stored procedures • Listing existing stored procedures • Modifying existing stored procedures (Java and SQL stored procedures) • Running existing stored procedures • Copying and pasting stored procedures across connections • One-step building of stored procedures on target databases • Customizing the settings to enable remote debugging of installed stored procedures.

The IBM DB2 Stored Procedure Builder is implemented with Java, and all database connections are managed by using a Java Database Connectivity (JDBC) API. Using a JDBC driver, you can connect to any DB2 database by using a local alias. See Figure 2.

8 Cross-Platform DB2 Stored Procedures: Building and Debugging Development Deployment

MicrosoftMicrosoft Visual Basic Stored Microsoft Visual Studio Studio procedure JDBC Builder IBMIBM VisualAge VisualAge for for Java Java

Platforms AIX, Sun Sun Solaris Solaris Windows NT, 95, 98, 2000 Windows NT, 2000, AIX, OS/2, OS/390, OS/400, Sun Solaris Debugger daemon

Debugger client Debugger backend

Figure 2. The SPB topology

2.1.2 Programming languages supported With Stored Procedure Builder, you create stored procedures in Java and the SQL procedure language. Creating stored procedures in Java and the SQL procedure language produces stored procedures that are highly portable among operating systems.

The SPB supports both Java and SQL Procedures languages to create, build, and debug stored procedures on DB2 UDB servers. For Java stored procedures, SPB allows the use of both supported Java interfaces: JDBC and SQLJ. The main difference between JDBC and SQLJ is that JDBC stored procedures execute as a dynamic SQL program, while SQLJ stored procedures execute as a static SQL program.

Chapter 2. The IBM DB2 Stored Procedure Builder 9 Table 1 summarizes the SPB support. Table 1. SPB support DB2 SPB V6 DB2 SPB V7 Language DB2 for DB2 for DB2 for DB2 for DB2 for DB2 for UWO OS/390 AS/400 UWO OS/390 AS/400

SQL No No No V 7 and V5 and V4 R4 higher higher and higher

Java V6 and No No V6 and coming Future higher higher for V6, V7 and higher

DB2 UWO stands for DB2 UDB for UNIX, Windows and OS/2.

Note: Existing stored procedures written in any supported language, and registered in the DB2 server, are also listed. However, stored procedures written in other languages can only be executed from SPB. You will not be able to modify, build, get source for, or debug these procedures.

2.2 Product Installation on Windows NT The following sections describe the prerequisites and the steps required to install SPB in the Windows NT environment.

2.2.1 Prerequisites for SPB There are a few requirements to run the SPB in your workstation. If you plan to develop stored procedures for remote DB2 servers, you have to define the connection to the server. To access DB2 UDB servers, you only need to catalog the remote database in your workstation.

To access a DRDA server, you need to install the DB2 Connect product in your workstation or in a gateway, and catalog the remote database.

SPB is implemented in Java, and all database connections are managed by using Java Database Connectivity (JDBC). To write stored procedures with SPB, you only need to be able to connect to a local or remote DB2 database alias. See Chapter 9, “Installation cookbook” on page 283 for more details.

10 Cross-Platform DB2 Stored Procedures: Building and Debugging 2.2.2 Installing the SPB The SPB is included with the DB2 Software Developer’s Kit (SDK) and is available for the Windows 95, 98, 2000 and NT, SUN and AIX environments. The SDK was renamed in DB2 UDB V 7.1. Its new name is Application Development Client. The DB2 Application Development Client (ADC) is included with DB2 UDB server editions (Workgroup Edition, Enterprise Edition, and Enterprise-Extended Edition), DB2 Developers editions (Personal Edition, and Universal Edition), and DB2 Connect. You can install ADC together with DB2 UDB server or in a separate client workstation.

DB2 for OS/390 users can also get the SPB from the DB2 Management Tools Package.

When you install the ADC in your machine, a path to SPB is automatically included in the DB2 UDB program group. You can launch the SPB from the DB2 UDB program group, or you can launch SPB as an add-in tool from any of the following applications: • IBM VisualAge for Java • Microsoft Visual Studio Version 5 and higher • Microsoft Visual Basic Version 5 and higher

2.3 Advanced configuring of the SPB You can customize your SPB environment by using a Windows initialization (INI) file. SPB uses the DB2SPB.INI file to save information about your preferences and environment. The DB2SPB.INI file is located in the SPB subdirectory x:\sqllib\spb, where x: is the drive on which you have installed DB2 SDK.

If you need to change the stored procedure option defaults, you can change the DB2SPB.INI file manually or via the Environment Properties notebook in SPB. Enter FILE -> Environment Properties to get the notebook shown in Figure 3.

Chapter 2. The IBM DB2 Stored Procedure Builder 11 Figure 3. SPB - environment properties

The DB2SPB.INI file contains several sections marked by a section name surrounded by brackets ([]). The entries in each section contain keynames and their associated values. Refer to Chapter 9, “Installation cookbook” on page 283 for detailed information of how we configured the SPB for our project.

2.4 Concepts and terminology SPB uses some terms to define objects and operations related to the creation and maintenance of stored procedures. Following are some of the most important terms associated with SPB objects and operations.

12 Cross-Platform DB2 Stored Procedures: Building and Debugging 2.4.1 Project The SPB manages your work by using projects. When using SPB, you must create a project. Each SPB project saves the following information: • Your connections to specific databases. • The filters you created to display subsets of the stored procedures on each database. When opening a new or existing Stored Procedure Builder project, you can filter stored procedures so that you view stored procedures based on their name, schema, language, or collection ID (for OS/390 only). • The Stored procedure objects that have not been successfully built to a target database.

You can identify Stored Procedure Builder project files by their SPP file extension.

The Project window shows all of the stored procedures on the DB2 database to which you are connected. (See Figure 4 on page 16, which describes the parts of the Project window.)

2.4.2 Create The create function is associated with the creation of new stored procedures using the stored procedure wizard. At the end of the creation of the stored procedure you can choose to generate the stored procedure, or to generate and build the stored procedure.

Through the SPB the process of creating and installing stored procedures on a DB2 database server is greatly simplified. When you build a stored procedure on a target database, you no longer have to manually register the stored procedure with DB2 by using the CREATE PROCEDURE statement.

Note for OS/390 If you are using SPB with authid SYSADM, and the SQL procedure is owned by XYZ, then both function "rebuild" and "destroy", will not work, because there is a check that the owner of the procedure matches the current sqlid.

2.4.3 Generate The process of generating a new stored procedure is started by the stored procedure wizard. The generate option creates a base skeleton for your stored procedure based on the information provided through the wizard. Note

Chapter 2. The IBM DB2 Stored Procedure Builder 13 that the generate function runs locally and does not include any information about the stored procedure on the DB2 server, that is, the source code is generated in memory.

If the stored procedure is in Java, the Build action compiles the source in local temporary directories, creates a jar file to contain the executables, and then calls the sqlj_install.jar() utility to add the jar file to the server. When developing SQL stored procedures, the source is generated in local memory, and the CREATE PROCEDURE statement is compiled and processed on the server.

2.4.4 Build The build function is responsible for performing all the tasks necessary to create and register the stored procedure on the DB2 server. When you create and build a stored procedure by using a wizard, Stored Procedure Builder compiles the source code on your client workstation, copies the source code to the DB2 server, registers the stored procedure in the stored procedure catalog table and stores the procedure’s source in the catalog.

Only when you build the stored procedure, does it become available for use at the DB2 server.

2.4.5 Register The register function is part of the building process, and basically it is responsible of inserting the for a stored procedure into the DB2 table for stored procedures, along with the associated parameters of those stored procedures.

2.4.6 Run After building the stored procedure, the SPB allows you to execute the stored procedure without writing a client program. The run function invokes the stored procedure on the DB2 server, prompts for parameters, and displays the results of the stored procedure. You can use the run function to execute any stored procedure registered at the DB2 server, regardless of the language of the stored procedure.

2.4.7 Get source Stored procedures built by Stored Procedure Builder have their source codes stored at the DB2 server in control tables. When working with SPB, you can request the stored procedure source code from the DB2 server by using the get source function.

14 Cross-Platform DB2 Stored Procedures: Building and Debugging With DB2 UDB, procedures written in SQL Procedures language always have their source stored in the DB2 tables, even if they were created outside SPB. However, Java procedures created outside SPB may not have their sources stored in the DB2 tables. In this case, if the procedures were registered with LANGUAGE JAVA and PARAMETER STYLE JAVA, when SPB cannot find the source code in the DB2 tables, a popup window is displayed and you can associate a file with the Java procedure source code, and this source code will be stored by SPB in the DB2 tables.

With DB2 for OS/390, your SQL stored procedures may not have their source codes in DB2 tables if they were not created using SPB. In this case, when SPB cannot find the source code in the DB2 tables, a popup window is displayed and you can associate a file with the SQL stored procedures source code, and this source code will be stored by SPB in the DB2 tables. The file with the source code must be downloaded from the mainframe, and has to reside on a disk that can be accessed by SPB.

2.4.8 Modify Once you have the stored procedures source code available in SPB, you can change the stored procedure using the source code editor and the SQL Assistant. You can only modify stored procedures written in Java or SQL Procedures language.

2.4.9 Dirty procedures A dirty procedure is indicated in SPB by having its name in bold. A stored procedure is considered dirty if you have made modifications to the stored procedures source code that have not been built back to the DB2 server.

2.4.10 Database connection SPB can be used to develop stored procedures to access many servers. Within a project, you can have different database connections to the DB2 servers being accessed.

2.5 The SPB components The SPB has many components to help you create, build, and debug your stored procedures. The SPB main panel, shown in Figure 4, provides icons and fast paths to other components.

Chapter 2. The IBM DB2 Stored Procedure Builder 15 w Vie e Insert Procedure re w T Ic ons Vie ils ta De

Output Area

Figure 4. SPB main panel - Project window

Following is a description of the main components of SPB.

2.5.1 The stored procedure wizards The stored procedure wizards are graphical user interfaces that help you to create a new stored procedure written in Java or SQL Procedures language. The wizards help you to specify the name, the general pattern for the source code, the query to run, the SQL data types for the parameters, and the build options for a new stored procedure.

You can start the stored procedure wizards by clicking on the Insert Java Procedure icon or the Insert SQL Procedure icon. You can also start the wizards by right-clicking the entry Stored Procedures, in the tree-view, and choosing Insert and then Java Stored Procedure Using Wizard or SQL Stored Procedure Using Wizard. This is shown in Figure 5.

16 Cross-Platform DB2 Stored Procedures: Building and Debugging Figure 5. SPB inserting a procedure using wizard

Figure 6 shows the initial window of the stored procedure wizards.

Figure 6. The stored procedure wizards

Chapter 2. The IBM DB2 Stored Procedure Builder 17 The wizard has many features to help you build your stored procedure: • Field Sensitive Help: You can click any object in the wizard windows and press F1. Help information and tips are presented in a yellow box near the object. • Smart Fields: Whenever you need to type information in the wizard, smart input fields will help you. If the border is blue, the field is selected and contains valid information. If the border turns red, the wizard has found a problem with your input. When a problem is detected, a grey popup message appears showing the error. If you press F1, a tip with a possible solution is displayed.

2.5.2 The SQL Assistant The SQL Assistant is a wizard that steps you through the processing of creating SQL statements. You can select tables on which to run queries, join tables, enter conditions and columns, determine how to sort the result, and display the SQL statement so that you can copy or test the SQL query. In SQL Assistant, the tables that you can view and build queries from are listed from the catalog tables of the current database alias.

The SQL Assistant can be invoked from the editor, or from the stored procedure wizard dialogs.

18 Cross-Platform DB2 Stored Procedures: Building and Debugging Figure 7 shows the first window of the SQL Assistant.

Figure 7. SQL Assistant window

2.5.3 Client configuration assistant The DB2 Client Configuration Assistant wizard can be invoked from SPB to catalog new databases, if necessary. During the creation of a new project or when inserting a new database connection, if you click the Add... button near the database alias pulldown, the Client Configuration Assistant is started. Refer to Chapter 9, “Installation cookbook” on page 283 for detailed information.

2.5.4 IBM Distributed Debugger The IBM Distributed Debugger, also referred as VisualAge Remote Debugger, is the client debugger application running on your workstation that allows you to remotely debug a stored procedure executing on the server. The client debugger must be connected to the debugger backend on the DB2 server. You can debug stored procedures written in Java or SQL Procedures language executing on DB2 servers on Windows NT, AIX, or OS/390. Other platforms will be added in the future for remote debugging.

Chapter 2. The IBM DB2 Stored Procedure Builder 19 2.6 Working with SPB projects SPB manages the work by using projects. A project stores the information about the databases with which you are working, and also stored procedures that have not yet been built into the DB2 server. A project can contain many connections to different DB2 databases or servers; each of these databases can contain many stored procedures. Figure 8 shows the relationships among projects, connections, and stored procedures.

Project (proj.spp)

Connection 1 spjdbc1 Database DB2A

Stored Procedures spsqlj2

spsqlp3

Connection 2 Database DB2B spcobol4

Figure 8. SPB projects (*.spp), connections and stored procedures

The SPB does not control concurrent access on a project file and/or stored procedures. You must be careful when many developers are working with the same databases, to avoid unintentional destruction of stored procedures or changes.

When SPB starts, it prompts you to either create a new project, or work with an existing project. The following sections describe how to create and manage SPB projects.

20 Cross-Platform DB2 Stored Procedures: Building and Debugging 2.6.1 Creating projects under the SPB The first thing you have to do when working with SPB is to specify your project. You can open an existing project or create a new one. When creating a new project, you have to provide some initial information about the project, such as the project name, and the database being accessed. Figure 9 shows the New Project window used to create a new project.

1 - Creating new project "SG245485"

2 3

4

6

5 7

Figure 9. Creating new project “ITSO SG245485”

Note the following items in Figure 9: 1. Project name. This is the name of your new project. The project name can be up to 256 characters, and can contain any alphanumeric character and the underscore ’_’ character. If you violate any of these rules, when you click OK, a popup window with an error message is displayed. SPB will save your project in a file with extension .spp and the same name as the project. This .spp file is created in the project path.

Chapter 2. The IBM DB2 Stored Procedure Builder 21 2. Project path. The project path defines the location of your project in your workstation or in a shared disk. By default, the project path points to x:\sqllib\spb\projects, where x: is the drive on which you have installed DB2 SDK. 3. Driver. Select the appropriate driver for your connection to the database on which you want to build stored procedures. When you install the DB2 SDK, the following IBM DB2 drivers are installed on your workstation. When you select one of these drivers for a new SPB project, the JDBC URL and driver class are automatically entered for you. In this release of the product, only the following drivers are supported: - IBM DB2 alias — When the DB2 database to which you want to connect is defined as an alias in your DB2 database client, select the IBM DB2 alias driver. When you use the IBM DB2 alias driver, you do not need to enter the host name and port for the DB2 database in SPB. By default, SPB selects the IBM DB2 alias driver for a connection. You may also click the Add button; this will invoke the DB2 Client Configuration Assistant, and allow you to create a new alias to a database. - AS/400 Toolbox for Java — Refer to 12.6, “Using the Stored Procedure Builder” on page 406. 4. Alias. Select the database alias you plan to use. You may also click the Add button; this will invoke the DB2 Client Configuration Assistant, and allow you to create a new alias to a database. After you create your project, you will be able to connections to other databases, in the same project, by using the Insert Connection dialog. 5. Userid and Password. Type the userid and password for accessing the DB2 server database. For security reasons, even if you specify your password here, whenever you open your project, you will be prompted for the password to access remote DB2 servers. 6. Use your current user ID and password check box. Select this if you want to use the current window userid and password to connect to the DB2 server. 7. Filter. If the database you are connecting to contains a large number of existing stored procedures and you want to limit the stored procedures displayed in the tree view, you can click the Filter... button. You will be able to filter the procedures displayed using the name, the schema, or the collection ID (OS/390 only) of the stored procedure.

22 Cross-Platform DB2 Stored Procedures: Building and Debugging 2.6.2 Managing SPB projects After creating your SPB projects you are ready to start working with SPB. You may change your project properties such as name and description using the Project Properties dialog clicking on File --> Project Properties.You cannot change the path of you project.

When you first create your project, only one database connection is defined. You may however, define other connections using the Insert Connection dialog. If you right-click the connection at any time, you will also be able to delete, refresh, filter, or change properties of your connections.

A good practice is to refresh your connections periodically to check changes that other users of the database might have made.

You can save your project at any time you want. If you have made changes to stored procedures, but have not built them to the database, the changes are saved with your project, so you can continue working with them later.

Note: Other developers working in different projects with connections to the same database will not be able to see your changes until you build them to the database.

2.6.2.1 Sharing SPB projects The way that SPB currently works is not suitable for a team development environment. The current version of SPB does not control concurrence in projects and does not provide check-in/check-out mechanisms, versioning, or any other feature to control accesses in your project.

Saving a project in a shared disk is possible, and may be helpful when more than one developer wants to copy a project with changes from another developer. However, you should not have one project file being used by many developers, since this may lead to unintentional destruction of changes not built into the database.

When sharing SPB projects, it is important to have the same database aliases pointing to the same database servers in all the developers’ workstations.

2.7 Using the Stored Procedure Builder The SPB provides you a single development environment for your stored procedures. You will be able to perform all tasks related to the creation and maintenance of stored procedures in DB2 UDB servers.

Chapter 2. The IBM DB2 Stored Procedure Builder 23 2.7.1 Viewing existing stored procedures The SPB allows you to view all the stored procedures that are registered in the DB2 server catalog tables for stored procedures. Regardless of the language in which the stored procedure was written, you can view the existing procedures and parameters being passed. However, you can only get the source, modify, or rebuild existing stored procedures written in SQL Procedures language or Java.

Since only SQL stored procedures and Java stored procedures are mandatory to be registered in the DB2 UDB catalog, it is possible that you have stored procedures in other languages that will not be shown, because they were not registered in the DB2 UDB catalog using the CREATE PROCEDURE statement.

When you create or open an SPB project, all the registered stored procedures in the defined database connections are displayed in the SPB main window tree view. Figure 10 shows the tree view of existing stored procedures in SPB.

Figure 10. Tree view of existing stored procedures

24 Cross-Platform DB2 Stored Procedures: Building and Debugging Note that in the tree view, the stored procedures are presented in alphabetical order, and also, the parameters are not shown. You can easily access detailed information on the existing stored procedures, such as parameter lists, specific name, and language, by double-clicking the folder Stored Procedures in the tree view. A detailed list of the stored procedures, in alphabetical order, is displayed in the list view part of the SPB main window. Figure 11 shows the detailed view of the existing registered stored procedures.

Figure 11. Detailed view of existing stored procedures

Chapter 2. The IBM DB2 Stored Procedure Builder 25 If you have a large number of registered stored procedures, you can filter the list of the stored procedures to be displayed. To open the filter dialog, right-click the Stored Procedures folder in the tree view, and choose Filter, as shown in Figure 12.

Figure 12. Filtering the list of stored procedures

26 Cross-Platform DB2 Stored Procedures: Building and Debugging The Filter dialog window is displayed, and you can filter the list of stored procedures based on the name or the schema of the registered stored procedures. You can filter using the complete name of the stored procedure or schema or just a substring of the name or schema. If you are using a substring, you can choose to list procedures that start or end with the substring, or that contains the substring. Figure 13 shows the Filter dialog window, and some of the filter options.

Figure 13. The Filter dialog window

2.8 Creating new stored procedures Using SPB, you can create new stored procedures in the SQL Procedures or Java languages. The stored procedure wizard helps you in creating the base skeleton of the stored procedure, so you can later include your business logic in it. For DB2 for OS/390 servers, SPB can only create SQL stored procedures. Support for Java stored procedures for DB2 for OS/390 through SPB is not yet available.

Chapter 2. The IBM DB2 Stored Procedure Builder 27 To inv oke the stored procedure wizard to create a new SQL stored procedure, right-click the Stored Procedures folder, and choose Insert SQL Stored Procedure, as shown in Figure 14. You can also click the Insert SQL Procedure icon in the SPB toolbar.

Figure 14. Creating a new SQL stored procedure

The stored procedure wizards guide you through five steps to create your stored procedure, as follows: 1. Name: In this step, you provide the name of the new stored procedure. 2. Pattern: In this step, you provide the characteristics that describe the pattern of your stored procedure, such as, if your stored procedure returns a result set, or if your stored procedure runs a single SQL. 3. SQL Statement: In this step, you can type one SQL query to be run by your stored procedure. If in the Pattern panel, you have chosen Run one query from a set of queries, you can specify multiple queries in the SQL Statement panel. From the SQL Statement panel, you can also invoke the SQL Assistant wizard to help you build your query, by clicking on the SQL Assist button. 4. Parameters: In this step, you provide the parameters and associated datatypes being passed to or from your stored procedure. This step is optional, and if your stored procedures do not expect parameters, you may skip this panel.

28 Cross-Platform DB2 Stored Procedures: Building and Debugging 5. Options: In this panel, you specify options for generating the basic skeleton of you SQL stored procedure, and for building your stored procedure at the DB2 server.

2.8.1 The stored procedure wizard When you start the stored procedure wizard,theName panel appears, as shown in Figure 15. In any panel of the wizard, if you position your mouse on any field, a popup window appears with more information related to that field. This can be very helpful when you are in doubt of the meaning of the fields in a specific panel.

Figure 15. The Name panel of the stored procedure wizard

When you are creating a new SQL stored procedure for a DB2 UDB server, the name of the stored procedure is presented already prefixed with your userid as the schema name. If you are creating a new SQL stored procedure for a DB2 for OS/390 server, the name of the stored procedure is not prefixed, and the default schema SYSPROC is used. If you want, you can type a new entry or change the schema in the stored procedure name field.

Chapter 2. The IBM DB2 Stored Procedure Builder 29 After providing a name to your stored procedure, you can click the Next button. The Pattern panel is displayed, as shown in Figure 16.

Figure 16. The Pattern panel of the stored procedure wizard

The Pattern panel is divided into three sections: Statement, Output, and Errors.

The Statement section allows you to specify if your stored procedure executes only one query or a set of queries. If you specify that your stored procedure executes a set of queries, the SQL Statement panel will allow multiple SQL statements to be defined, and your skeleton source code will include a CASE statement and an input parameter to select which SQL statement to run. If you specify that your stored procedure executes a single query, only one SQL statement will be allowed in the SQL Statement panel. However, even if you specify a single query, after the SQL stored procedure skeleton code is generated, you can modify it to include other SQL statements required for your stored procedure function.

In fact, usually stored procedures execute more than one SQL statement throughout the procedure logic. For these cases, you can select the Run a single query radio button, and later modify your procedure to include the additional statements.

30 Cross-Platform DB2 Stored Procedures: Building and Debugging The Output section allows you to specify if your stored procedure returns a result set to the calling application. If you select the Return a result set checkbox, a RESULT SETS 1 parameter is included in the CREATE PROCEDURE statement for your stored procedure. If your SQL stored procedure returns more than one result set, you can change the numbers of result sets in the CREATE PROCEDURE statement manually after the source code generation.

The Errors section allows you to specify how you want your stored procedure to handle errors. For SQL stored procedures, the first option Generate SQLEXCEPTION does not generate any code in the source, and if an SQL error occurs, the stored procedure will be terminated.

The second option, Output arguments for SQLSTATE and SQLCODE, includes output parameters and a handler in your SQL stored procedure source code to provide the client application with the values of SQLSTATE and SQLCODE variables. SQL stored procedures can return SQLSTATE and SQLCODE information, but not SQLMESSAGE.

Following is an example of the code generated by this option: CREATE PROCEDURE DRDARES1.PROC3 ( OUT SQLSTATE_OUT char(5), OUT SQLCODE_OUT int ) SPECIFIC DRDARES1.S1022844 RESULT SETS 1 LANGUAGE SQL P1: BEGIN DECLARE SQLSTATE CHAR(5) DEFAULT '00000'; DECLARE SQLCODE INT DEFAULT 0; DECLARE EXIT HANDLER FOR SQLEXCEPTION SET SQLCODE_OUT = SQLCODE; DECLARE CONTINUE HANDLER FOR SQLWARNING SET SQLSTATE_OUT = SQLSTATE;

END P1

For more information on handling errors in SQL stored procedures running on DB2 UDB, refer to Chapter 10, “SQL Procedures for DB2 for UNIX, Windows, OS/2” on page 331.

Chapter 2. The IBM DB2 Stored Procedure Builder 31 After choosing your options in the Pattern panel, when you click the Next button, the SQL Statement panel is displayed, as shown in Figure 17.

Figure 17. The SQL Statement panel of the stored procedure wizard

The SQL Statement panel allows you to create one or multiple SQL statements to be included in your SQL stored procedures code. You can type your SQL statement in the left area of the panel, or you can use the SQL Assistant wizard. The SQL Assist button invokes the SQL Assistant wizard, that helps you to create SELECT, INSERT, UPDATE, and DELETE statements through dialogs that access the DB2 catalog. For more information on the SQL Assistant wizard, refer to “SQL Assistant” on page 37.

The Actual Costs button is only available when you are creating an SQL stored procedure for a DB2 for OS/390 server. After you define your SQL statement, if you click the Actual Costs button, the stored procedure DSNWSPM is invoked at the DB2 for OS/390 server to evaluate the cost of your SQL statement and the results are presented by SPB. See Chapter 11, “SQL Procedures — OS/390 platform” on page 349 for detailed information.

32 Cross-Platform DB2 Stored Procedures: Building and Debugging Click the Next button, and the Parameters panel is displayed, as shown in Figure 18.

Figure 18. The Parameters panel of the stored procedure wizard

Chapter 2. The IBM DB2 Stored Procedure Builder 33 In the Parameters panel, you define the parameters that are sent to, or received from, the SQL stored procedure. If you click the Add button, the Define Parameter dialog is displayed, as shown in Figure 19.

Figure 19. The Define Parameter dialog

In the Define Parameter dialog, you specify the characteristics of your SQL stored procedure parameters. The parameter mode defines if a parameter is used as an input, output, or input/output for the stored procedure. In this dialog, you also define the name and SQL type of the parameter. The length, unit, precision, and scale fields are requested according to the SQL type of the parameter. You cannot use user defined datatypes as SQL types for SQL stored procedures parameters.

The parameters you define in the Parameters panel are included in the generated CREATE PROCEDURE statement for the SQL stored procedure. Before generating the code for your SQL stored procedure, you can also change, delete, or change the order of the parameters in the Parameters panel. After the code is generated, you can change the definition of your parameters by editing the CREATE PROCEDURE statement.

34 Cross-Platform DB2 Stored Procedures: Building and Debugging After you define your stored procedure parameters, you can click the Next button to go to the last panel of the stored procedure wizard,theOptions panel, as shown in Figure 20.

Figure 20. The Options panel of the stored procedure wizard

The Options panel allows you to specify options for generating and building your stored procedure. The options available are different for DB2 for OS/390 and DB2 UDB servers.

The Options panel displayed in Figure 20 is for DB2 UDB servers. For DB2 UDB servers, you may define the specific name of your SQL stored procedure. The specific name you type in the input field is included in the generated CREATE PROCEDURE statement.

In the Completion area of the panel, you can specify if you want to generate the source code and automatically build the procedure at the DB2 server, or if you want only to generate the source code. In most cases, you should choose the Generate only option, to add specific logic to your SQL stored procedure. After the generation, you will be able to change the SQL stored procedure source to include your changes, and then build the procedure.

Chapter 2. The IBM DB2 Stored Procedure Builder 35 The Build the stored procedure for debugging checkbox should be selected if you want to use the IBM Distributed Debugger to debug your procedure. When selected, this option includes an entry in the DB2 UDB debugger table.

The Options panel for DB2 for OS/390 SQL stored procedures allows you to specify the collection ID and load module name for the SQL stored procedure in entry fields. For DB2 for OS/390, the Options panel also includes an Advanced options button. If you click the Advanced button, the OS/390 Options window is displayed, as shown in Figure 21 and Figure 22. In this window, you can specify parameters used during the build process, that are passed to the DSNTPSMP stored procedure in the mainframe.

Figure 21. The Advanced SP Options for DB2 for OS/390 SQL stored procedures

36 Cross-Platform DB2 Stored Procedures: Building and Debugging Figure 22. The Advanced Build Options for DB2 for OS/390 SQL stored procedures

Note that in the OS/390 Options, you can also specify the name of the stored procedure to be invoked for the build process in the Build name entry field. By default, SPB invokes the DSNTPSMP REXX stored procedure, but you can change this procedure for your installation, and specify the name of your customized build procedure in the OS/390 options. If a new build utility is specified, then the parameters must match the order and SQL types of parameters in DSNTPSMP as shipped by DB2.

2.8.2 SQL Assistant The SQL Assistant is an wizard that steps you through the processing of creating SQL statements. You can select tables on which to run queries, join tables, enter conditions and columns, determine how to sort the result, and display the SQL statement so that you can copy or test the SQL query.

You can invoke the SQL Assistant during the creation of a new stored procedure, by clicking the SQL Assist button in the SQL Statement panel of the stored procedure wizard. You can also invoke the SQL Assistant when modifying your stored procedure by clicking on the Insert SQL icon from the SPB toolbar.

Chapter 2. The IBM DB2 Stored Procedure Builder 37 The SQL Assistant guides you through a series of steps to create your SQL statement. In the first step, you choose the type of SQL statement being generated and the tables that are referenced by your statement, as shown in Figure 23.

Figure 23. The Tables panel of the SQL Assistant

In the Tables panel of the SQL Assistant, you can choose if you want to generate a SELECT, INSERT, UPDATE, or DELETE statement. However, if you select more than one table from the list, the SQL Assistant only allows SELECT statements to be generated. You can refine the list of tables being presented by using the View schemas and the Filter tables buttons.

38 Cross-Platform DB2 Stored Procedures: Building and Debugging After selecting the tables for your SQL statement, you can either select the Columns tab to select specific columns of the selected tables, or you can select the Joins tab to display the Joins panel of the SQL Assistant, as shown in Figure 24.

Figure 24. The Joins panel of the SQL Assistant

Chapter 2. The IBM DB2 Stored Procedure Builder 39 In the Joins panel, you can click the columns on each table that are used to join the tables to highlight them. After that, you can click the Join button to create the join. By default, an inner join is created, but if you click the Join Type button, you can change the type of the join being created, as shown in Figure 25. In the Join Type panel, you can choose if you want to create an inner join, a left outer join, or a right outer join between the selected tables.

Figure 25. Changing the type of Join created by SQL Assistant

40 Cross-Platform DB2 Stored Procedures: Building and Debugging The next panel of the SQL Assistant is the Conditions panel. In this panel you can specify search conditions that are included in the WHERE clause of your SQL statement. The Conditions panel is shown in Figure 26.

Figure 26. The Conditions panel of the SQL Assistant

Chapter 2. The IBM DB2 Stored Procedure Builder 41 Next is the Expression Builder - Conditions panel, as shown in Figure 27.

Figure 27. The Expression Builder - Conditions

In the Conditions panel, you can include search conditions based in any column of any of the tables included in your SQL statement. Just select the table to which you want to add the condition, and click the column name and operator you want to highlight. Then, in the Values section of the panel, type the search value for your condition. To check the existing values for the column you are defining your condition, just click Find below the Values section. If you want, you can click the Add Variables button to define a variable for your search condition, as shown in Figure 28.

Figure 28. Specifying a variable for a condition

42 Cross-Platform DB2 Stored Procedures: Building and Debugging You can define as many conditions as you want. Perform the following steps to define multiple conditions of a WHERE clause: 1. Construct the first condition using the top half of the tab, or invoke the Advanced Expression button. 2. Select the AND or OR radio button 3. Click the ADD button to insert the condition into the large text field. 4. Repeat as necessary for each condition

The next panel of the SQL Assistant is the Columns panel, as shown in Figure 29.

Figure 29. The Columns panel of the SQL Assistant

In the Columns panel, just select the columns of each table that you want to include in your SQL statement, by highlighting the column name and then clicking the Add button.

Chapter 2. The IBM DB2 Stored Procedure Builder 43 After selecting the columns for your SQL statement, you can specify one or more columns to be used to sort the output of your statement, using the Sort panel, as shown in Figure 30.

Figure 30. The Order panel of the SQL Assistant

In the Sort panel, you can select the columns of any of the referenced tables to be used for sorting the output. The columns you select are included in the ORDER BY clause of your SQL statement.

44 Cross-Platform DB2 Stored Procedures: Building and Debugging The last panel of the SQL Assistant is the Review panel, as shown in Figure 31.

Figure 31. The Review panel of the SQL Assistant

The Review panel displays the generated SQL statement that will be included in your stored procedure. If you click the OK button, the SQL Assistant ends and the SQL statement is inserted in the stored procedure source code. Before closing the SQL Assistant, in the SQL panel you have three buttons that you can use.

The Save button saves the generated SQL statement to a file in your hard disk. The Run button allows you to test the generated SQL statement, before inserting the statement in your SQL stored procedure code.

If your SQL statement is expecting variables, when you click the Run button, you are prompted to enter the values for the variables, as shown in Figure 32.

Chapter 2. The IBM DB2 Stored Procedure Builder 45 Figure 32. Entering values for variables in the SQL statement

Enter the values for the variables and click the Run button again. The results of your SQL statement are displayed as shown in Figure 33. You can copy these results to the clipboard, or save them to a file if you want. Click the OK button to return to the Review panel of the SQL Assistant.

Figure 33. Displaying the results of the SQL Statement

46 Cross-Platform DB2 Stored Procedures: Building and Debugging 2.9 Building stored procedures The process of building a stored procedure is different between DB2 for OS/390 and DB2 UDB servers. SPB handles this difference and builds the stored procedure according to the DB2 server being accessed.

For DB2 for OS/390 servers, the current version of SPB only supports creation and building of stored procedures written in the SQL Procedures language. The build process of SPB, by default, invokes the OS/390 Procedure Processor, which is a REXX stored procedure (DSNTPSMP), in the mainframe to build the new or changed stored procedure. You can customize the DSNTPSMP procedure at the mainframe to better fit the needs of your environment, and change SPB parameters, so it will invoke your customized procedure instead of the default DSNTPSMP.

For DB2 UDB for UNIX, Windows, and OS/2, the build process invokes the command processor of DB2 to build the new or changed procedure.

For DB2 UDB for AS/400, refer to Chapter 12, “SQL Procedures for DB2 UDB for AS/400” on page 389 for detailed information about how to build an SQL stored procedure for DB2 UDB for AS/400.

In all cases, prior to building the stored procedure, SPB drops the existing version of the stored procedure on the DB2 server.

The process of building an SQL stored procedure involves the creation of the executable file and the registration of the stored procedure at the DB2 server.

To create the executable file, both DB2 UDB and DB2 for OS/390 engines generate an intermediate C source code that is precompiled, compiled, and linked at the DB2 server. For more information refer to Chapter 11, “SQL Procedures — OS/390 platform” on page 349, Chapter 10, “SQL Procedures for DB2 for UNIX, Windows, OS/2” on page 331 and Chapter 12, “SQL Procedures for DB2 UDB for AS/400” on page 389.

2.10Modifyingexistingstoredprocedures Using SPB, you can easily modify SQL stored procedures already built in the DB2 for OS/390 or DB2 UDB servers.

To modify an existing stored procedure, double-click the name of the stored procedure. SPB gets the SQL stored procedure source from the DB2 server and opens the edit window, as shown in Figure 34.

Chapter 2. The IBM DB2 Stored Procedure Builder 47 Figure 34. Modifying an existing stored procedure

For DB2 UDB servers, the source of the SQL stored procedure is saved in the SYSIBM.SYSPROCEDURES table, regardless of the method used to create the procedure. In this case, SPB always find the source code on the DB2 server and displays it for your modifications.

For DB2 for OS/390 servers, when you create your SQL stored procedure using SPB, the source code is stored in the SYSIBM.SYSPSM table. However, if you did not use the SPB to build your procedure, it is possible that the source code is not stored in the server. In this case, when you try to get the source of your SQL stored procedure, SPB displays a window prompting you to specify a file, residing on your workstation, containing the source code.

After the source code is displayed in the edit window, you can type any modifications you want to your stored procedure. The current version of the SPB editor does not check the syntax of the statements you are including or changing. Syntax errors are only detected during the build process of the stored procedure.

Any changes you do to your stored procedure are not included in the DB2 server until you build it again. While you are changing the SQL stored procedure, the name of the procedure is shown in bold characters in the tree view part of the SPB main window. In this case, the procedure is referred as a

48 Cross-Platform DB2 Stored Procedures: Building and Debugging dirty procedure, meaning that the code you have in SPB is not the same as in the DB2 server.

If you make changes to your SQL stored procedures, and do not build the procedure back to the DB2 server, when you close SPB you are prompted to save your changes locally, so you do not lose any of your modifications. Remember that other developers will not be able to see your changes until you build them to the DB2 server, and that SPB does not control concurrent access to the same SQL stored procedure.

2.11 Copying and pasting stored procedures across connections You can copy your stored procedures from one DB2 server to another. SPB provides a copy and paste facility to help you copy individual procedures. In version 7.1 of Stored Procedure Builder, you can export SQL Stored Procedures to files, and you can reload the file under the same of different database connections after editing any changes.

To copy one SQL stored procedure to another DB2 server, you can right-click the procedure name in the tree view of SPB, and select Copy procedure as shown in Figure 35.

Figure 35. Copying one SQL stored procedure

Chapter 2. The IBM DB2 Stored Procedure Builder 49 When you select Copy Procedure, SPB gets the source of the stored procedure from the DB2 server tables, and copies the source to the SPB clipboard.

To copy the procedure to another DB2 server, in the SPB tree view, right-click the Stored Procedures folder of the connection to the target DB2 server, as shown in Figure 36.

Figure 36. Paste the stored procedure at the target server

When pasting the stored procedure at the target server, you have two options. If you choose Paste Procedure, the procedure is created only in SPB but not on the target DB2 server. In this case, you can change the stored procedure code before building it to the DB2 server. If you do not plan to change the stored procedure, you can select Paste and Build Procedure, that copies the procedure and builds it to the DB2 server without any changes to the original source code.

2.12 The SPB additional considerations The following sections present some considerations related to the SPB.

50 Cross-Platform DB2 Stored Procedures: Building and Debugging 2.12.1 Java 1.2 support for the IBM DB2 Stored Procedure Builder The IBM DB2 Stored Procedure Builder supports building Java stored procedures using Java 1.2 functionality. In addition, the Stored Procedure Builder supports bi-directional languages, such as Arabic and Hebrew, using the bi-directional support in Java 1.2. This support is provided for Windows NT platforms only. In order for the Stored Procedure Builder to recognize and use Java 1.2 functionality, Java 1.2 must be installed.

To install Java 1.2: 1. JDK 1.2.2 is available on the DB2 UDB CD under the DB2\bidi\NT directory. ibm-inst-n122p-win32-x86.exe is the installer program, and ibm-jdk-n122p-win32-x86.exe is the JDK distribution. Copy both files to a temporary directory on your hard drive, then run the installer program from there. 2. Install it under \java\Java12, where is the installation path of DB2. 3. Do not select JDK/JRE as the System VM when prompted by the JDK/JRE installation. 4. Export the variable JAVA_DIR, specifying the location of the JDK. This variable is used by the file SQLLIB/SPB/DB2SPB.

After Java 1.2 is installed successfully, start the Stored Procedure Builder in the normal manner.

To execute Java stored procedures using JDK 1.2 support, set the database server environment variable DB2_USE_JDK12 to TRUE using the following command: DB2SET DB2_USE_JDK12=TRUE

Also, set your JDK11_PATH to point to the directory where your Java 1.2 support is installed. You set this path by using the following command: DB2 UPDATE DBM CFG USING JDK11_PATH

To stop the use of Java 1.2, you can either uninstall the JDK/JRE from \java\Java12, or simply rename the \java\Java12 subdirectory.

Note: Do not confuse \java\Java12 with \Java12. \Java12 is part of the DB2 installation and includes JDBC support.

Chapter 2. The IBM DB2 Stored Procedure Builder 51 2.12.2 Building SQL Procedures on the Intel and UNIX platforms Before you can use the Stored Procedure Builder to successfully build SQL Procedures on your Intel or UNIX database, you must configure your server for SQL Procedures. For information on how to configure your server for SQL Procedures, see the IBM DB2 Universal Database Application Building Guide.

The database manager configuration parameter KEEPDARI must be set to NO. This can be done using the command db2 update dbm cfg using KEEPDARI NO, or using the Control Center. If KEEPDARI is set to YES, you may get message SQL0454N when attempting to build an SQL stored procedure that was previously built and run.

2.12.3 UNIX installations and the SPB For Sun Solaris installations, and if you are using a Java Development Kit or Runtime other than the one installed on AIX with UDB, you must set the environment variable JAVA_HOME to the path where Java is installed (that is, to the directory containing the /bin and /lib directories).

The IBM Stored Procedure Builder is not supported on Linux, but can be used on supported platforms to build and run stored procedures on DB2 UDB for Linux systems.

2.12.3.1 Using the DB2 SPB on the Solaris platform To use the Stored Procedure Builder on the Solaris platform: 1. Download and install JDK 1.1.8. You can download JDK 1.1.8 from the JavaSoft Web site. 2. Set the environment variable JAVA_HOME to the location where you installed the JDK. 3. Set your DB2 JDK11_PATH to the directory where you installed the JDK. To set the DB2 JDK11_PATH, use the command: DB2 UPDATE DBM CFG USING JDK11_PATH.

52 Cross-Platform DB2 Stored Procedures: Building and Debugging 2.12.4 Known problems and limitations SQL Procedures are not currently supported on Windows 98.

For Java stored procedures, the JAR ID, class names, and method names cannot contain non-ASCII characters.

On AS/400 the following V4R4 PTFs must be applied to OS/400 V4R4: • SF59674 • SF59878

Stored procedure parameters with a character subtype of FOR MIXED DATA or FOR SBCS DATA are not shown in the source code in the editor pane when the stored procedure is restored from the database.

Currently, there is a problem when Java source code is retrieved from a database. At retrieval time, the comments in the code come out collapsed. This will affect users of the IBM DB2 Stored Procedure Builder who are working in non-ASCII code pages, and whose clients and servers are on different code pages.

2.12.4.1 Using DB2 SPB with Traditional Chinese locale There is a problem when using Java Development Kit or Java Runtime 1.1.8 with the Traditional Chinese locale. Graphical aspects of the Stored Procedure Builder program (including menus, editor text, messages, and so on) will not display properly. The solution is to make a change to the file font.properties.zh_TW, which appears in one or both of the following directories: sqllib/java/jdk/lib sqllib/java/jre/lib

Change: monospaced.0=\u7d30\u660e\u9ad4,CHINESEBIG5_CHARSET,NEED_CONVERTED

To this : monospaced.0=Courier New,ANSI_CHARSET

Chapter 2. The IBM DB2 Stored Procedure Builder 53 54 Cross-Platform DB2 Stored Procedures: Building and Debugging Chapter 3. SQL Procedures language

The SQL Procedures language is a common programming language across the DB2 family for writing stored procedures. The use of SQL Procedures provides to customers the benefit of writing their stored procedures in a standard and portable language. This chapter describes in detail the SQL Procedures programming language.

Any differences in current releases are due to differences in how we roll out features for a given platform. However, DB2 will be continuing to enhance the SQL Procedures language on all platforms and reduce any current platform differences.

3.1 Introduction to stored procedures Stored procedures are blocks of code that are stored on the same system as the DBMS server. This code may be written in an extended form of SQL such as SQL Procedures language, or in generalized programming language such as C, C++, COBOL, FORTRAN, or Java. In any case, procedures are typically written to contain multiple SQL data manipulation language (DML) statements as well as procedures logic constructs such as loops and if/else statements. Therefore, stored procedures are conceptually similar to “small” applications, providing useful, database-intensive business service to multiple applications. These applications, which typically are remote from DBMS itself, invoke the procedure with a single call statement.

When coding stored procedures, they can require parameters for input (IN), output (OUT) or input and output (INOUT). They may return one or more sets of results. If you have the appropriate authorization, you can query your database catalog to determine the names of the procedures available on the system, as well as the specific parameters and/or result sets associated with them. In some situations, you may even be able to inspect the source code for the procedures to better understand their function.

While using stored procedures often yields performance benefits, such benefits are not guaranteed. Indeed, there are circumstances under which the use of stored procedures can actually cause performance to degrade. For example, if you create a stored procedure that simply issues one INSERT statement and call this procedure from a remote application, network traffic will not be reduced: your application still has to make a network call to invoke the procedure, just as it would to issue an INSERT statement. Furthermore, the DBMS may need to load the procedure and incur inter-process communications overhead to execute it. Thus, your application may actually

© Copyright IBM Corp. 2001 55 run slower by using such a stored procedure. Fortunately, most “legacy” stored procedures deployed in production environments are already known to provide some clear business value, ranging from improved performance to simplified application development and maintenance.

If you are planning on creating new stored procedures to support, or if you are trying to tune existing stored procedures, you should be aware that language issues and creation options can significantly influence your results. For example, in some DBMS products, procedures written in Java may perform more poorly than an equivalent procedure written in C. In addition, procedures that run in a separate address space from the DBMS (“fenced” procedures) perform more poorly than procedures that run in the same address space as the DBMS (“unfenced” procedures). However, running any user-written software in an address space separate from the DBMS itself is obviously a safer bet.

If performance is your utmost concern, investigate whether or not your DBMS supports a fenced/unfenced option. If so, build and thoroughly test any new procedures as fenced, then drop and recreate them as unfenced when you are satisfied they are bug-free. Finally, investigate any functional restrictions associated with fenced and unfenced procedures during your design phase. For example, some DBMSs require that stored procedures that return result sets must be fenced.

With DB2 UDB for OS/390 V5, and DB2 for UNIX, Windows and OS/2 Version 7, IBM started delivering support for a set of features and capabilities. These features and capabilities are designed to help customers and software vendors to migrate or port their applications, stored procedures, and data from other DBMS to DB2 on one or more platforms.

One of those features is the SQL Procedures language, which is described in the next section.

3.2 What is the SQL Procedures language? The SQL Procedures language is a procedural language that was designed only for writing stores procedures. It is available across the entire DB2 family. The use of SQL Procedures provides to customers the benefit of writing their stored procedures in a standard and portable language.

The SQL Procedures language is based on SQL extensions as defined by the SQL/PSM (Persistent Stored Modules) standard. SQL/PSM (an ISO/ANSI standard for SQL3) is a high level language — similar to other RDBMS

56 Cross-Platform DB2 Stored Procedures: Building and Debugging languages such as Transact SQL (T/SQL) from Sybase, and Procedural Language (PL/SQL) from Oracle — that extends SQL to procedural support.

The ISO/ANSI SQL3 is an open solution for SQL among database management system vendors that support the SQL ISO/ANSI standard.

The SQL stored procedure source code, that is the CREATE PROCEDURE statement, is stored in the database after a successful compilation and registration of the SQL stored procedure in the appropriate DB2 tables (see chapter for specific platform).

As explained later, SQL stored procedures are different from external stored procedures that are written in a third generation language like C, COBOL, or Java.

Local client as well as remote client applications, connected to the DB2 server through network protocols (for example, TCP/IP), can invoke an SQL stored procedure by executing the SQL CALL statement. The SQL CALL statement is also part of ISO/ANSI SQL3.

The ability to write stored procedures greatly enhances the power, efficiency, and flexibility of SQL. The client program can pass parameters to the SQL stored procedure and receive parameters from it, as well as result sets. The SQL CALL statement can be executed as either static or dynamic SQL. Parameters in the CALL statement, including the stored procedure name, can be supplied at execution time. The SQL CALL statement can be used to invoke dynamically any SQL stored procedure supported by DB2.

The following DB2 servers currently support SQL stored procedures: • DB2 UDB for UNIX, Windows, and OS/2 • DB2 UDB for AS/400 • DB2 UDB for OS/390

3.3 Planning to use the SQL Procedures language This section contains information about planning for the use of DB2 stored procedures, and provides specific information to help you develop stored procedures using the SQL Procedures language. For more information about specific hardware and software requirements, see the chapter in this book that covers the specific platform you are planning to use.

3.3.1 Why use it? This section describe the benefits of using SQL stored procedures.

Chapter 3. SQL Procedures language 57 Consistency with the data SQL stored procedures are fully SQL, which means that they are written using only SQL statements. Like other SQL object, they are always stored in the database system in which they are used and for which they were developed. Storing SQL stored procedures within the database system allows dependencies to be checked between the SQL schema objects (tables, views, and so on) and the procedure, as soon as a manipulation is done (like dropping or altering an object). An SQL stored procedure must not get out of sync with the SQL schema objects it works with.

On the other hand, this out of sync status can happen with external stored procedures, where the executable is stored at the system level, away from the database data management system. The backup and restore operations could be done out of sync with the backup and restore of the data, leading to inconsistencies in the processing.

The actual DB2 UDB support for SQL Procedures translates an SQL stored procedure into an external stored procedure, thus allowing potential inconsistencies. However, the source code of each stored procedure is stored inside the database itself, making it possible to recreate the correct executable of the procedure.

Modular programming An SQL stored procedure can be created once and then stored in the database. Any userid with the necessary authorization can access the stored procedure through the CALL SQL statement. For instance, an SQL stored procedure could be created or modified by someone who is a specialist in SQL stored procedure language programming, and can be called by client programs developed by other programmers. This allows the DBA to control the development of the business logic at the server, which is a very sensitive area.

Network traffic reduction An operation requiring many SQL statements can be performed through a single CALL statement that executes the same SQL code inside a procedure, rather than sending every individual SQL query over the network. For instance, Figure 37 shows what a client application written in C or CLI or any other embedded SQL language has to send and receive through the network to execute two SQL statements.

Figure 38 shows the same logic embedded in an SQL stored procedure. The client has to send one SQL CALL statement to the server. The results sent back are the same. As you can see, the two SQL statements from Figure 37 are reduced to one SQL CALL statement.

58 Cross-Platform DB2 Stored Procedures: Building and Debugging Figure 37. The usual SQL client, where the logic sends many SQL queries

Figure 38. SQL client using the same logic, but within an SQL stored procedure

The savings can be important. The SQL CALL statement is a very short network message. On the contrary, a single SQL statement with many synchronized queries could be a few kilobytes long, up to 32k or 64k, depending of the version of DB2 UDB installed, and this could result in many network messages sent to the server. The savings are greater if the logic you want to execute requires many SQL statements or many network messages, like the FETCH operation with cursors. The network transfer time between the client and the server could become longer than the execution of the SQL statement themselves, depending on network availability.

Another point to be considered is that, while the client based query must return every row across the network, a stored procedure can return only a subset of the rows, or potentially none at all, and can return values derived from subsequent logic.

Chapter 3. SQL Procedures language 59 Can be used as a security/shield mechanism It is often useful to shield the data and the tables from developers and database users. This can be done by restricting access to tables to only a few trusted users, and by granting the right to execute specific stored procedures, developed for updating, inserting or deleting rows to less trusted users.This can ensure that applications cannot execute direct SQL statements against important data, but must make modifications only through the filter of stored procedures.

These stored procedures can even have more complex logic than just basic SQL statements. A stored procedure that deletes one customer could also update other tables related to that customer to keep information for audit or further references. should be able to do this, but sometimes, it is easier and faster to use a stored procedure, because depending on the context of the modification, different actions will have to be executed. Triggers or referential integrity constraints on a table are not context sensitive, because only the data in the rows are available. There is no possibility to have a specific DELETE, UPDATE or INSERT operation according to the current context of the application.

For example, for the following SQL statement: DELETE CUSTOMER WHERE CUSTID=11111

You may want to take one of the following actions: • Delete this customer, but insert a log record of it in the custlog table for audit later. • Delete this customer, but keep the statistics in the custstats table until end of year. • Delete this customer, but also delete corresponding rows in custlog and custstats tables.

Note: The custlog and custstats tables mentioned here are tables you created for your application design.

The delete trigger on the customer table will not be able to choose one of these different actions because it has to be generic. When you delete the customer, you cannot specify another action along with the delete SQL statement. A stored procedure would be able to decide what to do, according to an input parameter value.

60 Cross-Platform DB2 Stored Procedures: Building and Debugging Another example is shielding tables from users. Figure 39 shows that the developer shielded the tables A, B and C from the client applications Cl1, Cl2, Cl3 and Cl4 by inserting a layer of SQL stored procedures SP1, SP2 and SP3. These SQL stored procedures can execute complex SQL queries like insert, update and delete on one or more tables. When called, SP1 will modify only table A, SP2 will modify table A and table C, and SP3 will modify table B and table C.

Cl 1 Cl 2 Cl 3 Cl 4 LOGIC SP1 SP2 SP3 DATA Table A Table B Tab l e C DB2 UDB Server

Figure 39. An example of shielding tables from users

3.3.2WhentouseSQLstoredprocedures? In general, SQL stored procedures can be used as soon as a client application needs to send dynamic SQL statements, or multiple SQL operations, like FETCH, to the server. Grouping the same functional SQL statements in an SQL stored procedure allows performance and network bandwidth improvement. It also simplifies programming, improves maintainability, and facilitates deployment of applications.

The following topics describe in more detail why SQL stored procedures are really useful: • Easier and faster to program than external stored procedures SQL stored procedures are very similar to SQL. The control-flow statements are really simple, and the programmer does not need to understand C or COBOL. SQL stored procedures are the perfect solution for business logic, since they can be totally developed with SQL statements and control-flow logic.

Chapter 3. SQL Procedures language 61 That is, you do not need to access any other external resource besides the RDBMS. They are fast to develop and maintain. • No use of specific system services or resources If the business logic needs to access system services or external resources, or call other external programs, SQL stored procedures may not be applicable. In fact, there is no possibility yet, in the SQL/PSM standard, to call a shared library, execute a system command, or send e-mail. For the time being, the only solution is to use external stored procedures written in C or COBOL. For instance, a stored procedure that has to send an e-mail to the credit manager every time a credit limit is exceeded, or execute a system command when a threshold is reached, has to be an external stored procedure developed in C or COBOL. Note: This is true except for the Windows platforms. DB2 UDB for Windows allows OLE stored procedures which can invoke operating system and other platform capabilities like E-mail through the use of OLE services. Refer to the DB2 UDB for Windows manuals for more details on use of OLE automation. So you can use more than C or COBOL stored procedures when you need system services and are running on Windows. • No vital performance needed Due to the actual implementation of SQL stored procedures, the execution performance may not be as fast as an optimized external stored procedure written in C or COBOL. Although the difference is very small for most of the business logic functionality, some applications may need the extra time difference that can be gained only by using an optimized procedure programmed in C or COBOL language. How do we choose, then? Usually, only a few parts of a company business logic application needs real performance. The designer of the application should find the right compromise between development time and maintainability versus execution performance.

Important SQL stored procedures are not interpreted. They are translated to C, so the build process has more steps, but the resulting procedure is compiled. The preprocessors and translators also add optimization.

62 Cross-Platform DB2 Stored Procedures: Building and Debugging • Extensive business logic The more business logic you have, the more you will save in development, maintenance, and execution time. The modularity allowed by stored procedures is certainly a gain in maintenance, especially when the client programs are developed in different languages. Changing some business logic does not mean changing all the different COBOL and C or Visual Basic (VB) clients that were executing these SQL statements. Only the stored procedure involved in this business logic needs to be changed, assuming that the signature — which means the list of parameters and types of the stored procedure — is still the same. • Highly distributed application (deployment) Deployment of clients having business logic embedded is hard to maintain. Every time the business logic changes or an error is fixed, all the clients have to be updated again. This can lead to out of sync clients accessing good data in the wrong way. However, fixing one stored procedure fixes all the clients at once. The maintenance is faster, and problems arise less often. • What portion of the business logic should reside on the server? Numerous documents have been written on this subject, and not everybody agrees on the conclusions. But let us consider the two major solutions that are seen most often. Usually, the two rules of 80% on client and 20% on server, or 20% on client and 80% on server, could apply for most applications, depending on the level of risk the developers and company expect. - 80%-20% client-to-server ratio: This corresponds to applications that do not want to rely too heavily on specific stored procedure languages. The 20% consists mainly of SQL statements. This is typically the case for most independent software vendors (ISVs) that want to deal with a minimum of different stored procedures languages (T/SQL or PL/SQL, or even DB2 SQL Procedures language) because their programs will have to be ported on different RDBMSs. They are usually constrained to a subset of SQL, portable across all the RDBMSs. The counterpart of this solution is that this kind of application cannot use the full possibilities of an RDBMS, and would usually not perform as well as a 20%-80% solution (because of using more network bandwidth, for instance).

Chapter 3. SQL Procedures language 63 - 20%-80% client-to-server ratio: This kind of application is tuned to access business logic on the server, mainly as stored procedures. This application will rely heavily on RDBMS features, and should hopefully be more efficient than an 80%-20% solution by optimizing bandwidth, deployment, and development time. This is typically the kind of application developed by a company for itself. The drawback of this type of application is that the company relies on one RDBMS, which could be troublesome for future migrations. Of course, various methods of apportionment can be seen, and the company’s final choice will depend only on the evaluation between level of risk/RDBMS dependency versus application performance/savings during the development and maintenance phase.

3.4 Comparing SQL procedures and external stored procedures External stored procedures are stored procedures developed using host programming language such as C, C++, COBOL, Fortran, Java, and REXX. This was the original way to develop stored procedures with DB2, which means that stored procedures could not be written totally in SQL, on all platforms (except for DB2 UDB on AS/400). Such stored procedures are stored in files on the machine where the database server is located and not in the database itself. That is why they are called external stored procedures.

3.4.1 Development SQL stored procedures are stored procedures written in the SQL Procedures programming language. An SQL stored procedure is developed totally in SQL, and its source code is stored in the database, so it can be executed directly within the DBMS environment.

3.4.1.1 Lower development cost External stored procedures are developed in a procedural language such as C, Java or COBOL. Using programming languages for database programming requires much experience and a deep understanding of how the SQL data types and features are mapped to the host language.

64 Cross-Platform DB2 Stored Procedures: Building and Debugging For example, in the C language, an SQL VARCHAR variable called myvar would have to be represented as a structure like the following: struct { short len; char data[31]; } myvar;

You would represent the same VARCHAR variable like this, using SQL Procedures language: DECLARE myvar VARCHAR(30);

As you can see, it is simpler in SQL Procedures language to declare variables of an SQL type.

The conceptual differences between SQL and host languages adds complexity to the programming of external stored procedures, making them longer in the number of lines, with more possibilities for mistakes, and making them more difficult to debug. Programmers of external stored procedures must be well trained database SQL programmers as well as having extensive experience working with third generation languages.

On the other hand, SQL Procedures rely on SQL. Variable handling is fully SQL (no structures to deal with VARCHAR) and the procedural extensions use an easy common syntax very close to BASIC or PASCAL. The benefit of programming with SQL Procedures language is immediate. Once you know SQL, you can learn the SQL Procedures language in a matter of hours. You do not have to deal with obscure representation and manipulation of your variables, but can just use them directly.

For example, assuming that two VARCHAR variables v1 and v2 are declared, the code in SQL Procedures language is as follows to assign v2 to v1: /* in SQL Procedures language*/ SET v1 = v2; The same code in C is as follows: /* in C */ memcpy(v1.data, v2.data, v2.len); v1.len=v2.len;

As you can see, you need to know the internal representation of a VARCHAR variable in C to be able to copy it into a C program.

Chapter 3. SQL Procedures language 65 Another advantage of using SQL Procedures is that you can develop them anywhere, as soon as you have a DB2 UDB connection ready. The source code is stored in the database, allowing the programmer to fetch it back for modification. Unlike external stored procedures, there is no need to access the file system. This simplifies the development by focusing only on the DB2 UDB functionality, that is, programmers do not have to learn system tools such as file transfer protocols, system specific editors or compiler options. They just learn SQL and its procedural extensions.

The Stored Procedure Builder, provided with DB2 UDB, relies on this feature, allowing the same easy, graphical interface to build SQL or Java stored procedures on any DB2 UDB platforms with nothing more needed than a DB2 UDB connection. See Chapter 2, “The IBM DB2 Stored Procedure Builder” on page 7 for details.

3.4.1.2 Leverage programming skills By using SQL Procedures, you leverage the programming skills needed in your company, lowering the cost of development of application. For example, the same person that knows SQL can also be the programmer.

It also makes things easier for porting, maintaining the source code, and deployment (same code everywhere). This can be an important saving for companies that have many programmers.

3.4.2 Runtime Calling an SQL stored procedure is no different than calling an external stored procedure. The same SQL CALL statement works for both of them.

Because the SQL Procedures language is higher level, it may have to do more tasks for the programmer (like checking for exception condition after every SQL stored procedure statement). Also, it may be slower to execute than the usual C or COBOL stored procedure written by a specialist or expert (which may bypass some error checking). But the cost in performance is justified because of the savings that can be obtained during development and maintenance.

3.5 Current implementation of SQL Procedures language The actual choice made by IBM is to translate an SQL Procedures language program into an external C stored procedure. This is done under-the-covers by the engine, and the programmer does not need to understand how it is done. The only thing needed is a C or C++ compiler to be installed along with the DB2 UDB server on the server machine.

66 Cross-Platform DB2 Stored Procedures: Building and Debugging 3.5.1 How does this work in general? Once you send the SQL stored procedure source code (the CREATE PROCEDURE statement) to the DB2 UDB engine from the Stored Procedure Builder or from the DB2 UDB command line, the DB2 UDB engine processes it, creates a C file with embedded SQL, compiles it and installs it in the right place for its first execution. The implementation is slightly different on OS/390, as compared to AS/400 and distributed platforms due to platform differences.

For details see the specific platform chapter on Part 4, “Implementing SQL Procedures” on page 281.

The Database Language SQL - Part 4: Persistent Stored Modules of ISO/IEC 9075 specifies the syntax and semantics of a database language for declaring and maintaining persistent database language routines in SQL-server modules. The scope of the current implementation is limited to SQL stored procedures and does not include support for SQL functions and Feature P01, "Stored Modules".

The following stored procedure database language capabilities are generally supported, but there are still some differences depending on the platform where you build and run your SQL procedures: • ALLOCATE CURSOR • ASSIGNMENT statement • ASSOCIATE LOCATOR statement • CALL statement • CASE statement • COMPOUND statement • FOR statement • GET DIAGNOSTICS statement • GOTO statement • IF statement • ITERATE statement • LEAVE statement • LOOP statement • REPEAT statement • RESIGNAL statement • RETURN statement • SIGNAL statement • WHILE statement • SQL statements

Chapter 3. SQL Procedures language 67 See Table 3 on page 117, Table 4 on page 122 and Table 5 on page 123 to compare differences and similarities between Windows, OS/390 and AS/400.

3.5.2 Declaring SQL local variables To store data that you use only within an SQL stored procedure, you can declare SQL local variables. The SQL local variables can have the same data types and lengths as DB2 table columns. The general form of an SQL variable declaration is: DECLARE SQL-variable-name data-type;

DB2 folds all SQL variable names to uppercase. Thus, you cannot declare two SQL variables named varx and VARX. You cannot declare an SQL variable with a name that is the same as a parameter name or an SQL reserved word. Refer to the appropriate SQL Reference for your DB2 system for a list of reserved words. However, you can declare an SQL variable name that is the same as a DB2 column name.

If a name in an SQL statement can be either a column name or an SQL variable name, the runtime behavior differs depending on which platform the stored procedure is executed. DB2 UDB for WIN/NT will verify first if it is a column name, and then verify if it is an SQL variable name. DB2 UDB for OS/390 always assumes that the given name is a variable or parameter name. If you want to refer to the column name on OS/390, you must qualify the column name with the table name.

For DB2 UDB for WIN/NT, you can also specify which scope, that is, the compound statement label the variable was declared into, by qualifying the variable name with the scope name. This is useful for nested scopes, where it may be needed to refer to variables declared in a "higher" scope, or to avoid conflicts between variables and column names in SQL statements. This option does not apply to DB2 UDB for OS/390, because you cannot use nested compound statements on this platform.

In the SQL Procedures language there are no host variables; all variables are considered SQL variables. So, you cannot put colons in front of variables in the SQL Procedures language.

Another important remark about SQL variables declaration is the order that they are declared. All variable and condition declarations must precede handler declarations.

68 Cross-Platform DB2 Stored Procedures: Building and Debugging Here is an example of declarations for the most common data type supported:

CREATE PROCEDURE p1() LANGUAGE SQL BEGIN declare c1 integer; declare c2 CHAR(30); declare c3 VARCHAR(30); declare c31 VARCHAR(30); declare c34 LONG VARCHAR default'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxa'; declare cdate DATE default '03/01/1999'; declare ctime TIME default '11:11:22'; declare cstamp TIMESTAMP default '1990-01-01-12.01.00.000000'; declare c4 REAL default 12345.456; declare c5 DECIMAL(9,2) default 12345.456 ; declare c6 BIGINT default 1234567890123456789; declare LOC1 result_set_locator varying;

SET c1 = (select count(*) from employee); SET c2 = (select max(empno) from employee); SET c3 = (select min(empno) from employee); insert into result(proc,res) values ( 'exec P1','C1='||CHAR(C1)||' C2='||C2||' C3='||C3); insert into result(proc,res) values ( 'exec P1','date='|| CHAR(cdate)); insert into result(proc,res) values ( 'exec P1','time='|| CHAR(ctime)); insert into result(proc,res) values ( 'exec P1','timestamp='|| CHAR(cstamp)); insert into result(proc,res) values ( 'exec P1','REAL='|| CHAR(c4)); insert into result(proc,res) values ( 'exec P1','decimal(9,2)='|| CHAR(c5)); insert into result(proc,res) values ( 'exec P1','LONG VARCHAR='||c34); insert into result(proc,res) values ( 'exec P1','BIG INT='||CHAR(c6)); END

Chapter 3. SQL Procedures language 69 Important Notes for OS/390: • OS/390 does not have a BIGINT data type or RESULT SET LOCATOR • OS/390 does not support LONGVARCHAR in SQL procedures • The example shows SET varname = (SELECT ...) which is not yet supported on OS/390 • The date format must be a valid date format, but not exactly the one specified in your DB2 system configuration.

Important Notes for AS/400: • AS/400 does not support LONG VARCHAR or RESULT SET LOCATORS specified in your DB2 system configuration.

3.5.3 Language elements The following sections describe and show examples of each type of statement and language element.

The examples shown assume that a table result is created in the database that keeps an execution trace of the SQL stored procedure. The following is the DDL used to create the table result: create table result ( proc char(22), res varchar(128))

Note that, because the SQL Procedures language is SQL, names (variables, labels, and so on) are not case sensitive.

3.5.3.1 ALLOCATE CURSOR statement The ALLOCATE CURSOR statement is not valid for DB2 UDB for OS/390 and DB2 UDB for AS/400.

The ALLOCATE CURSOR statement defines a cursor and associates it with a result set locator variable.

Figure 40 shows the relationship between the ALLOCATE, ASSOCIATE and RESULT SET LOCATOR statements. The numbers in figure Figure 40 represent the sequence in which the statements are performed. 1. SQL procedure PROC1 calls SQL procedure PROC2. 2. Cursor SAL in PROC2 is declared as WITH RETURN TO CALLER wich means that the result set generated by this cursor will be returned to the calling procedure, which is procedure PROC1 in our case.

70 Cross-Platform DB2 Stored Procedures: Building and Debugging 3. Cursor SAL is opened. This OPEN actually performs the SELECT from table EMP coded in the cursor. As you can see in Figure 40, the generated result sets contains three rows. 4. This result set is returned to the calling procedure, which is PROC1. 5. The ASSOCIATE LOCATORS statement in PROC1 now associates the name LOC1 to this result set. 6. To work with the returned result set now, you ALLOCATE a cursor name to the returned result set. 7. If you now fetch from this associated result set, which is still the same as we talked about in 3, you can read and process row by row from this result set.

The variable names used in the CALL statement in PROC1, which are used to receive the result set values, must be defined as OUT variables in the called procedures that delivers the result set rows. Therefore you must make sure that the data type used in the OUT parm definition matches with the data types of table DB2NAMES in our example.

PROC1 PROC2

.... 1 .... CALL PROC2 ; DECLARE SAL CURSOR WITH RETURN TO CALLER .. 4 2 FOR SELECT NAME, SALARY ASSOCIATE RESULT SET LOCATOR (LOC1) FROM EMP 5 WITH PROCEDURE PROC2; WHERE JOBRESP = 'DB2'; 6 ALLOCATE C1 CURSORFORRESULTSETLOC1; ..... 3 OPEN SAL; WHILE ..... DO .... FETCH FROM C1 INTO OUTPARM1,OUTPARM2; 7 Result Set: INSERT INTO DB2NAMES (NAME, FIRSTNAME) Almeida Sueli VALUES (OUTPARM1,OUTPARM2); Kaschta Sabine Leung Mark

DB2NAMES EMP Name Firstname Name Firstname Jobresp Almeida Sueli Kaschta Sabine Almeida Sueli DB2 Leung Mar k Kaschta Sabine DB2 Porter James CICS Leung Mar k DB2 Obermeier Raghel OS/390

Figure 40. ALLOCATE, ASSOCIATE, RESULT SET LOCATOR statements

The cursor name must not identify a cursor that has already been declared in the source program.

Chapter 3. SQL Procedures language 71 The result set locator variable must contain a valid result set locator value, as returned by a ASSOCIATE LOCATOR statement.

The following rules apply when you use an allocated cursor: • You cannot open an allocated cursor with the OPEN statement (SQLSTATE 24502). • You can close an allocated cursor with the CLOSE statement. Closing an allocated cursor closes the associated cursor in the stored procedure. • You can allocate only one cursor to each result set.

The life of an allocated cursor ends with a rollback operation, an implicit close, or an explicit close that destroys allocated cursors.

For example, define and associate cursor C1 with the result set locator variable LOC1 for the first result set returned by the stored procedure, cursor C2 with result set locator LOC2 for the second result set returned by the stored procedure: DECLARE LOC1 RESULT_SET_LOCATOR VARYING; DECLARE LOC2 RESULT_SET_LOCATOR VARYING; CALL P1; ASSOCIATE RESULT SET LOCATORS (LOC1, LOC2) WITH PROCEDURE P1; ALLOCATE C1 CURSOR FOR RESULT SET LOC1; ALLOCATE C2 CURSOR FOR RESULT SET LOC2;

See more complex samples in Appendix A.2.19, “CF025 sample for NT” on page 460 and Appendix A.2.18, “CALLEE sample for NT” on page 459.

3.5.3.2 ASSOCIATE LOCATOR statement The ASSOCIATE LOCATORS statement gets the result set locator value for each result set returned by a stored procedure. One result set locator variable is required for each result set that the stored procedure will return. Note that the ASSOCIATE LOCATOR statement is not valid for DB2 UDB for OS/390 and DB2 UDB for AS/400.

When the ASSOCIATE LOCATORS statement is executed, the procedure name or specification must identify a stored procedure that the requester has already executed using the CALL statement. That means the ASSOCIATE LOCATORS statements always follows the CALL statement. The procedure name in the ASSOCIATE LOCATORS statement must be specified in the same way that it was specified on the CALL statement.

72 Cross-Platform DB2 Stored Procedures: Building and Debugging For example, if a two-part name was specified on the CALL statement, you must use a two-part name in the ASSOCIATE LOCATORS statement. If the CALL statement was made with a three-part name and the current server is the same as the location in the three-part name, you can omit the location name and specify a two-part name.

Rules: • You can assign multiple locators to the same result set. • If the number of result set locator variables that are listed in the ASSOCIATE LOCATORS statement is less than the number of locators returned by the stored procedure, all variables in the statement are assigned a value, and a warning is issued. • If the number of result set locator variables that are listed in the ASSOCIATE LOCATORS statement is greater than the number of locators returned by the stored procedure, the extra variables are assigned a value of 0. • If a stored procedure is called more than once from the same caller, only the most recent result sets are accessible.

In the following example, two result set locators (LOC1,LOC2) are associated with the stored procedure P1. DECLARE LOC1 RESULT_SET_LOCATOR VARYING; DECLARE LOC2 RESULT_SET_LOCATOR VARYING; CALL P1; ASSOCIATE RESULT SET LOCATORS (LOC1, LOC2) WITH PROCEDURE P1;

See more complex samples in Appendix A.2.19, “CF025 sample for NT” on page 460 and Appendix A.2.18, “CALLEE sample for NT” on page 459.

Note The fact that the ALLOCATE CURSOR and ASSOCIATE LOCATOR statement is not supported on DB2 UDB for OS/390 does not mean that you are not able to handle result sets. Refer to Section 3.5.5, “Returning result sets” on page 103 for further information.

3.5.3.3 Assignment statement The assignment statement assigns a value to an output parameter or to an SQL variable, which is a variable that is defined and used only within a procedure body.

Chapter 3. SQL Procedures language 73 Rules: • Assignment statements in SQL procedures must conform to the SQL assignment rules. • The data type of the target and source must be compatible. • When a string is assigned to a fixed-length variable and the length of the string is less than the length attribute of the target, the string is padded on the right with the necessary number of blanks. • When a string is assigned to a variable and the string is longer than the attribute of the variable, an error is issued. • A string assigned to a variable is first converted, if necessary, to the code page of the target. • If truncation of the whole part of the number occurs on assignment to a numeric variable, an error is raised. • If an assignment is the only statement in the procedure body, the statement cannot end with a semicolon. Otherwise, the statement must end with a semicolon.

Example: CREATE PROCEDURE B(OUT var1 INTEGER,OUT var2 INTEGER) LANGUAGE SQL BEGIN SET var1 = 10; SET var2 = (SELECT count(*) FROM customer); END

Important The assignment statement: SET var2 = (SELECT COUNT(*) FROM CUSTOMER) shown in the example above is not yet supported on the OS/390 platform. This means that you cannot use a SELECT statement on the right hand side of a SET statement.

3.5.3.4 CALL statement This statement is the regular CALL SQL statement, which calls a stored procedure. It can be an external stored procedure (C, Java, COBOL) or an SQL stored procedure. CREATE PROCEDURE F (IN ASSEMBLY_NUM CHAR(10) ) LANGUAGE SQL BEGIN CALL MYSP2( ASSEMBLY_NUM); END

74 Cross-Platform DB2 Stored Procedures: Building and Debugging DB2 UDB for OS/390 accepts parameters that are variables, constants or Expressions in the CALL statement.

On DB2 UDB for AS/400, the CALL statement only accepts parameters that are variables, constants, special registers or NULL. Expressions are not allowed.

DB2 UDB for UNIX, Windows and OS/2 accepts only parameters that are variables.

If the CALL statement is the only statement in the procedure body, the statement cannot end with a semicolon. Otherwise, the statement must end with a semicolon.

3.5.3.5 CASE statement The CASE statement selects an execution path based on the evaluation of one or more conditions. This statement is similar to the CASE expression, which is described in the SQL Reference of DB2 UDB, Chapter 3, Language Elements, topic CASE expression.

The following is a sample of a simple-case-statement-when-clause, where the value of the expression prior to the first WHEN keyword is tested for equality with the value of each expression that follows the WHEN keyword. if the search condition is true, the THEN statement is executed. If the result is unknown or false, processing continues to the next search condition. If the result does not match any of the search conditions, and an ELSE clause is present, the statements in the ELSE clause are processed. CREATE PROCEDURE I1(IN var1 CHAR(3) ) LANGUAGE SQL BEGIN CASE var1 WHEN 'AAA' THEN insert into result(proc,res) values ('exec of I1','AAA found.'); WHEN 'BBB' THEN insert into result(proc,res) values ('exec of I1','BBB found.'); ELSE insert into result(proc,res) values ('exec of I1','default case value=' || CHAR(tt) ); END CASE; END

Chapter 3. SQL Procedures language 75 In the next sample, you can see a searched-case-statement-when-clause, where the search-condition following the WHEN keyword is evaluated. If it evaluates to true, the statements in the associated THEN clause are processed. If it evaluates to false, or unknown, the next search-condition is evaluated. If no search-condition evaluates to true and an ELSE clause is present, the statements in the ELSE clause are processed. CREATE PROCEDURE I6(IN var1 CHAR(3),IN var2 CHAR(3)) LANGUAGE SQL BEGIN CASE WHEN var1='AAA' THEN INSERT INTO result(proc,res) VALUES ('exec of I6','var1=AAA'); WHEN var2=’AAA’ THEN INSERT INTO result(proc,res) VALUES ('exec of I6','var2=AAA'); END CASE; END

Note for OS/390 and AS/400 For CASE statements with simple-case-statement-when-clauses, you can have up to three nested levels of CASE statements.

If you use searched-case-statement-when-clauses, there are no limits.

If none of the conditions specified in the WHEN are true, and an ELSE clause is not specified, an error is issued at runtime, and the execution of the case statement is terminated.

3.5.3.6 Compound statement Roughly, we can say that a compound statement is a set of one or more SQL statements between the BEGIN and END keywords.

A compound statement may contain SQL variable declarations, condition handlers declaration, or cursor declarations. The order of statements in a compound statement is: a. SQL variable and condition declarations b. Cursor declarations c. Handler declarations d. Assignment statements, control-flow statements such as CASE, IF, LOOP, REPEAT, and WHILE, and SQL statements such as SELECT, INSERT, UPDATE, DELETE, CALL, CREATE TABLE, and so on

76 Cross-Platform DB2 Stored Procedures: Building and Debugging The use of condition handlers is described in Section 3.5.4, “Handling errors in an SQL stored procedure” on page 92.

A compound statement may be declared as: • ATOMIC, which means that all actions performed by the compound statement must succeed, or the entire set of database modifications made by those actions are rolled back. The following is an example of an ATOMIC compound statement: CREATE PROCEDURE D(PARM1 char(10) ) LANGUAGE SQL BEGIN SC: BEGIN ATOMIC DECLARE zz iNTEGER DEFAULT 11; INSERT INTO result(proc, res) VALUES('exec of D','In atomic block before error test:'||PARM1);

IF (Parm1 = '1') THEN SET aaa = (select job from employee ); ELSE SET aaa = (SELECT job FROM employee WHERE empno = '000020'); END IF; INSERT INTO result(proc, res) VALUES('exec of D','In atomic block after error test:'|| aaa); END; END SC • NOT ATOMIC, which means that an error occurring within the compound statement does not cause all actions performed by the compound statement to be rolled back. The NOT ATOMIC string is optional. It is the default for a compound statement. The following is an example of a NOT ATOMIC compound statement: CREATE PROCEDURE D(PARM1 char(10) ) LANGUAGE SQL BEGIN SC: BEGIN NOT ATOMIC declare zz integer default 11; insert into result(proc, res) values ('exec of D', ' In non atomic block before error test :' || PARM1);

if (Parm1 = '1') then set aaa = (select job from employee );

Chapter 3. SQL Procedures language 77 else set aaa = (select job from employee where empno = '000020'); end if; insert into result(proc, res) values ('exec of D', ' In non atomic block after error test :' || aaa); END; END SC

Important: • ATOMIC compound statements are not yet supported on the OS/390 and AS/400 platforms. • Nested compound statements are not supported on the OS/390 and AS/400 platforms.

3.5.3.7 FOR statement The FOR statement executes a group of statements repeatedly. It must be associated with a query expression and terminates after the group of statements is executed for every row in the result of query expression.

The following example shows FOR usage in SQL stored procedures: DECLARE X INTEGER DEFAULT 0; FOR L1 AS SELECT balance FROM accounts DO SETX=X+balance; END FOR;

The body of a FOR statement is not allowed to contain a LEAVE statement that refers to L1. But cursor columns can be prefixed with the name of the FOR statement L1. This is also valid. SET X=X+L1.balance.

It is very useful to refer to variables in nested FOR loops that access the same table, as in this example: DECLARE X INTEGER DEFAULT 0; FOR L1 AS SELECT balance FROM accounts WHERE DEP > ’C02’ DO FOR L2 AS SELECT balance FROM accounts WHERE DEP<’D01’ DO SETX=L2.balance + L1.balance; END FOR; /* do something here with X*/ END FOR;

78 Cross-Platform DB2 Stored Procedures: Building and Debugging A cursor is implicitly opened at the beginning of execution; closed automatically at the end of execution. In the preceding example, a cursor is created for the SQL statement SELECT balance FROM accounts and for each line of the result set instruction SET X= L2.balance + L1.balance is executed.

It is also possible to specify a name for the implicit cursor as in the following example: FORL1AScurs1 CURSOR FOR SELECT * FROM accounts WHERE balance=0DO DELETE FROM accounts WHERE CURRENT OF curs1; END FOR;

The body of a FOR statement is not allowed to contain an OPEN, FETCH, or CLOSE statement that refers to curs1. Furthermore, is it not possible to reference a cursor specified in a FOR statement.

The select list must consist of unique column names, and the table specified in the select list must exist when the procedure is created, or it must be a table created in a previous SQL procedure statement.

DB2 UDB for AS/400 uses the label on the FOR statement to qualify variables as shown in the following example: I2: FOR L1 AS SELECT BALANCE FROM ACCOUNTS SET I2.BALANCE = BALANCE + 1 END FOR

Note for OS/390 The FOR statement is not yet supported on the OS/390 platform.

3.5.3.8 GET DIAGNOSTICS statement The GET DIAGNOSTICS statement obtains information about the previous SQL statement invoked.

See the following example to execute a GET DIAGNOSTICS statement to determine how many rows were updated by the last SQL statement.

Chapter 3. SQL Procedures language 79 CREATE PROCEDURE sqlprocg (IN deptnbr VARCHAR(3)) LANGUAGE SQL BEGIN DECLARE SQLSTATE CHAR(5); DECLARE rcount INTEGER; UPDATE CORPDATA.PROJECT SET PRSTAFF = PRSTAFF + 1.5 WHERE DEPTNO = deptnbr; GET DIAGNOSTICS rcount = ROW_COUNT; -- At this point, rcwount contains the number of rows that were updated. ... END

Note • The GET DIAGNOSTICS statement is not a specific PSM function, however, people coming from the Sybase or Oracle background will probably find it useful to have samples that demonstrate this function. • The keyword ROW_COUNT is valid for all DB2 platforms we looked at when we wrote this book. These platforms are: DB2 UDB for OS/390, DB2 UDB for AS/400, and DB2 UDB for Windows.

The next example shows how to use the GET DIAGNOSTICS statement to handle the returned status value from the invocation of a stored procedure called TRYIT. TRYIT could either explicitly RETURN a positive value indicating a user failure, or encounter SQL errors that would result in a negative return status value. If the procedure is successful, it returns a value of zero. CREATE PROCEDURE TESTIT () LANGUAGE SQL A1:BEGIN DECLARE RETVAL INTEGER DEFAULT 0; ... CALL TRYIT; GET DIAGNOSTICS RETVAL = RETURN_STATUS; IF RETVAL <> 0 THEN ... LEAVE A1; ELSE ... END IF; END A1

80 Cross-Platform DB2 Stored Procedures: Building and Debugging Note The keyword RETURN_STATUS is not supported for DB2 UDB for OS/390.

The GET DIAGNOSTICS statement does not change the contents of the diagnostics area (SQLCA). If an SQLSTATE or SQLCODE special variable is declared in the SQL procedure, those variables contain the SQLCODE and SQLSTATE from the previous SQL statement.

Note that a condition handler may be specified to return error or warning information about the previous statement. If information is desired about an error, the GET DIAGNOSTICS statement must be the first statement specified in the handler that will handle the error.

If information is desired about a warning, the following conditions apply: • If a handler will get control for the warning condition, the GET DIAGNOSTICS statement must be the first statement specified in that handler. • If a handler will not get control for the warning condition, the GET DIAGNOSTICS statement must be the next statement executed after that previous statement. • There are three additional keywords for the GET DIAGNOSTICS statement: • MESSAGE_TEXT — Identifies the message text of the error or warning returned from the previous SQL statement that was executed. If the previous SQL statement completes with an SQLCODE equal to zero, an empty string or blanks is returned. • MESSAGE_LENGTH or MESSAGE_OCTET_LENGTH — Identifies the length of the message text of the error or warning returned from the previous SQL statement that was executed. If the previous SQL statement completes with an SQLCODE equal to zero, a length of 0 is returned. In an SQL procedure, execute a GET DIAGNOSTICS statement to retrieve the message text for an error.

Chapter 3. SQL Procedures language 81 Here is another example: CREATE PROCEDURE divide2 (I numerator INTEGER, IN denominator INTEGER, OUT divide_result INTEGER, OUT divide_error VARCHAR(70)) LANGUAGE SQL BEGIN DECLARE CONTINUE HANDLER FOR SQLEXCEPTION GET DIAGNOSTICS EXCEPTION 1 SET divide_error =MESSAGE_TEXT ; SET divide_result =numerator /denominator; END ;

Note: In ISO/ANSI standard, you can keep information for n conditions. If more than one condition is kept, it is necessary to specify which exception you are interested in. Today, DB2 on all platforms only supports keeping information about 1 condition — hence, in standard syntax, the only thing that is valid would be EXCEPTION 1.

3.5.3.9 GOTO statement The GOTO statement transfers program control to a labelled statement.

The labelled statement and the GOTO statement must be in the same scope. The following rules apply to the scope: • If the GOTO statement is defined in a compound statement, label must be defined inside the same compound statement. label cannot be in a nested compound statement. • If the GOTO statement is defined in a handler, label must be defined in the same handler and follow the other scope rules. • If the GOTO statement is defined outside of a handler, label must not be defined within a handler.

A label name cannot be the same as the name of the SQL procedure in which the label is used.

The following is a sample for the use of the GOTO statement: CREATE PROCEDURE SAMPLE.SP12L4S ( INOUT SERVICE dec(8,2), IN V_EMPNO char(6), IN RATING int, OUT RETURN_PARM dec(8,2) ) LANGUAGE SQL SPECIFIC SAMPLE.SP12LMS

82 Cross-Platform DB2 Stored Procedures: Building and Debugging BEGIN DECLARE NEW_SALARY DECIMAL ( 9 , 2 ) ; SELECT SALARY , DAYS ( CURRENT_DATE)-DAYS(HIREDATE ) INTO NEW_SALARY , SERVICE FROM SAMPLE . EMPLOYEE WHERE EMPNO = V_EMPNO ; IF SERVICE < 10000 THEN GOTO EXIT_RTN ; ENDIF; IF RATING = 1 THEN SET NEW_SALARY = NEW_SALARY * 1.1 ; ELSEIF RATING = 2 THEN SET NEW_SALARY = NEW_SALARY * 1.05 ; ENDIF; UPDATE EMP SET SALARY = NEW_SALARY WHERE EMPNO = V_EMPNO ; EXIT_RTN : SET RETURN_PARM = SERVICE ; END

3.5.3.10 IF statement The IF statement selects an execution path based on the evaluation of a condition. CREATE PROCEDURE B1(IN v CHAR(1)) LANGUAGE SQL BEGIN IF (v >'F') THEN INSERT into result(proc,res) VALUES ('exec of B1',' v > F v='|| v); ELSEIF (v >'D') THEN INSERT INTO result(proc,res) VALUES ('exec of B1',' v > D v='|| v); ELSEIF (v >'B') THEN INSERT INTO result(proc,res) VALUES ('exec of B1',' v > B v=' || v); ELSEIF (v >'A') THEN INSERT INTO result(proc,res) VALUES ('exec of B1',' v > A v=' || v); ELSE INSERT INTO result(proc,res) values ('exec of B1','Else branch done.'); END IF; END

Chapter 3. SQL Procedures language 83 Here is another example of an IF statement: CREATE PROCEDURE MM (in PA INTEGER) LANGUAGE SQL BEGIN IF ( PA in (12,13,10)) THEN INSERT INTO result(proc,res) VALUES ('exec of MM',' PA='|| CHAR(PA) || ' found in (12,13,10)'); ELSE INSERT INTO result(proc,res) VALUES ('exec of MM',' PA='|| CHAR(PA) || ' not found in (12,13,10)'); END IF; END

3.5.3.11 ITERATE statement The ITERATE statement causes the flow of control to return to the beginning of a labelled loop.

This sample below uses a cursor to return information for a new department. If the not_found condition handler was invoked, the flow of control passes out of the loop. If the value of v_dept is 'D11', an ITERATE statement passes the flow of control back to the top of the LOOP statement. Otherwise, a new row is inserted into the DEPARTMENT table. CREATE PROCEDURE ITERATOR() LANGUAGE SQL BEGIN DECLARE v_dept CHAR(3); DECLARE v_deptname VARCHAR(29); DECLARE v_admdept CHAR(3); DECLARE at_end INTEGER DEFAULT 0; DECLARE not_found CONDITION FOR SQLSTATE '02000'; DECLARE c1 CURSOR FOR SELECT deptno, deptname, admrdept FROM department ORDER BY deptno; DECLARE CONTINUE HANDLER FOR not_found SET at_end = 1; OPEN c1; ins_loop: LOOP FETCH c1 INTO v_dept, v_deptname, v_admdept; IF at_end = 1 THEN LEAVE ins_loop; ELSEIF v_dept = 'D11' THEN ITERATE ins_loop; END IF;

84 Cross-Platform DB2 Stored Procedures: Building and Debugging INSERT INTO department (deptno, deptname, admrdept) VALUES ('NEW', v_deptname, v_admdept); END LOOP; CLOSE c1; END

Note Labels are not supported on DB2 UDB for AS/400.

3.5.3.12 LEAVE statement The LEAVE statement transfers program control out of a loop or a block of code (see statement LEAVE myloop in the sample below). When a LEAVE statement transfers control out of a compound statement, all open cursors in the compound statement, except cursors that are used to return result sets, are closed.

In addition, the LEAVE statement can be used to exit the stored procedure (see statement LEAVE PP in the sample below).

In the example shown below, the last insert is not processed if ‘a>integer(assembly_num)’ and if ‘a>1000’. In that case the whole procedure is left because of the LEAVE pp statement.

If a integer(assembly_num) ) THEN LEAVE myloop;/* exit the loop */ ELSE SETa=a+assembly_num; IF (a> 1000) ) THEN LEAVE PP;/* exit the procedure*/ END IF; END IF; END LOOP myloop; INSERT INTO result(proc,res) VALUES ( 'proc F', 'AFTER LOOP') END

Chapter 3. SQL Procedures language 85 3.5.3.13 LOOP statement The LOOP statement executes a statement or group of statements multiple times.

You can use the LEAVE statement described in Section 3.5.3.12, “LEAVE statement” on page 85, or the GOTO statement described in Part 3.5.3.9, “GOTO statement” on page 82, to leave a loop.

Note: Section 3.5.3.12, “LEAVE statement” on page 85 also shows the sample use of a LOOP statement.

3.5.3.14 REPEAT statement The REPEAT statement executes a group of statements until a search condition is true.Within the group of statement of a REPEAT statement, a LEAVE statement transfers program control out of the REPEAT and an ITERATE statement causes the flow of control to return to the beginning of the REPEAT. CREATE PROCEDURE F (IN ASSEMBLY_NUM CHAR(10) ) LANGUAGE SQL BEGIN DECLARE b INTEGER DEFAULT 0; REPEAT INSERT INTO result(proc,res) VALUES ('proc F','REPEAT '|| CHAR(b) ); SETb=b+1; UNTIL (b>5) END REPEAT; END

3.5.3.15 RESIGNAL statement The RESIGNAL statement resignals an exception condition, and it can only be coded as part of a condition handler.

Rules: • If the RESIGNAL statement is specified without an SQLSTATE clause or a condition-name, the SQL routine returns to the caller with the identical condition that invoked the handler. • If a RESIGNAL statement is issued, and specifies an SQLSTATE or condition-name, the SQLCODE assigned is: - +438 if the SQLSTATE begins with '01' or '02' - -438 otherwise

86 Cross-Platform DB2 Stored Procedures: Building and Debugging When a RESIGNAL statement is issued with no options, the SQLCODE is unchanged from the exception that caused the handler to be invoked. • If the SQLSTATE or condition indicates that an exception is signalled (an SQLSTATE class other than '01' or '02'): - Then, the exception is handled and control is transferred to a handler, provided that a handler exists in the next outer compound statement (or a compound statement even further out) from the compound statement that includes the handler with the resignal statement, and the compound statement contains a handler for the specified SQLSTATE, condition-name, or SQLEXCEPTION; - Otherwise, the exception is not handled and control is immediately returned to the end of the compound statement. • If the SQLSTATE or condition indicates that a warning (SQLSTATE class '01') or not found condition (SQLSTATE class '02') is signalled: - Then the warning or not found condition is handled and control is transferred to a handler, provided that a handler exists in the next outer compound statement (or a compound statement even further out) from the compound statement that includes the handler with the resignal statement, and the compound statement contains a handler for the specified SQLSTATE, condition-name, SQLWARNING (if the SQLSTATE class is '01'), or NOT FOUND (if the SQLSTATE class is '02'); - Otherwise, the warning is not handled and processing continues with the next statement.

Example: This example detects a division by zero error. The IF statement uses a SIGNAL statement to invoke the overflow condition handler. The condition handler uses a RESIGNAL statement to return a different SQLSTATE value to the client application. See also the description of the SIGNAL statement in Section 3.5.3.17, “SIGNAL statement” on page 89. CREATE PROCEDURE divide ( IN numerator INTEGER IN denominator INTEGER OUT result INTEGER LANGUAGE SQL CONTAINS SQL BEGIN DECLARE overflow CONDITION FOR SQLSTATE '22003'; DECLARE CONTINUE HANDLER FOR overflow RESIGNAL SQLSTATE'22375' ; IF denominator = 0 THEN

Chapter 3. SQL Procedures language 87 SIGNAL overflow; ELSE SET result = numerator / denominator; END IF; END

Note for OS/390 The RESIGNAL statement is not yet supported on the OS/390 platform.

3.5.3.16 RETURN statement The RETURN statement is used to return from the routine. For SQL functions or methods, it returns the result of the function or method. For an SQL procedure, it optionally returns an integer status value.

Notes: When a value is returned from a procedure, the caller may access the value: • By using the GET DIAGNOSTICS statement to retrieve the RETURN_STATUS when the SQL procedure was called from another SQL procedure. • By using the parameter bound for the return value parameter marker in the escape clause CALL syntax (?=CALL...) in a CLI application. • Directly from the SQLCA returned from processing the CALL of an SQL procedure by retrieving the value of SQLERRD[0] when the SQLCODE is not less than zero (assume a value of -1 when SQLCODE is less than zero).

Example: Use a RETURN statement to return from an SQL stored procedure with a status value of zero if successful, and -200 if not. BEGIN ... GOTO FAIL ... SUCCESS: RETURN 0 FAIL: RETURN -200 END

88 Cross-Platform DB2 Stored Procedures: Building and Debugging Note for OS/390 The RETURN statement is not supported on the OS/390 platform.

3.5.3.17 SIGNAL statement The SIGNAL statement is used to signal an error or warning condition. It causes an error or warning to be returned with the specified SQLSTATE, along with optional message text.

Rules: • If a SIGNAL statement is issued, the SQLCODE that is assigned is: - +438 if the SQLSTATE begins with '01' or '02' - -438 otherwise • If the SQLSTATE or condition indicates that an exception (SQLSTATE class other than '01' or '02') is signaled: - Then the exception is handled and control is transferred to a handler, provided that a handler exists in the same compound statement (or an outer compound statement) as the signal statement, and the compound statement contains a handler for the specified SQLSTATE, condition-name, or SQLEXCEPTION; - Otherwise, the exception is not handled and control is immediately returned to the end of the compound statement. • If the SQLSTATE or condition indicates that a warning (SQLSTATE class '01') or not found condition (SQLSTATE class '02') is signaled: - Then the warning or not found condition is handled and control is transferred to a handler, provided that a handler exists in the same compound statement (or an outer compound statement) as the signal statement, and the compound statement contains a handler for the specified SQLSTATE, condition-name, SQLWARNING (if the SQLSTATE class is '01'), or NOT FOUND (if the SQLSTATE class is '02'); - Otherwise, the warning is not handled and processing continues with the next statement.

Chapter 3. SQL Procedures language 89 • SQLSTATE values are comprised of a two-character class code value, followed by a three-character subclass code value. Class code values represent classes of successful and unsuccessful execution conditions. Any valid SQLSTATE value can be used in the SIGNAL statement. However, it is recommended that programmers define new SQLSTATEs based on ranges reserved for applications. This prevents the unintentional use of an SQLSTATE value that might be defined by the database manager in a future release. - SQLSTATE classes that begin with the characters '7' through '9', or 'I' through 'Z' may be defined. Within these classes, any subclass may be defined. - SQLSTATE classes that begin with the characters '0' through '6', or 'A' through 'H' are reserved for the database manager. Within these classes, subclasses that begin with the characters '0' through 'H' are reserved for the database manager. Subclasses that begin with the characters 'I' through 'Z' may be defined.

Example: An SQL procedure for an order system that signals an application error when a customer number is not known to the application. The ORDERS table includes a to the CUSTOMER table, requiring that the CUSTNO exist before an order can be inserted. CREATE PROCEDURE SUBMIT_ORDER (IN ONUM INTEGER, IN CNUM INTEGER, IN PNUM INTEGER, IN QNUM INTEGER) SPECIFIC SUBMIT_ORDER MODIFIES SQL DATA LANGUAGE SQL BEGIN DECLARE EXIT HANDLER FOR SQLSTATE VALUE '23503' SIGNAL SQLSTATE '75002' SET MESSAGE_TEXT = 'Customer number is not known'; INSERT INTO ORDERS (ORDERNO, CUSTNO, PARTNO, QUANTITY) VALUES (ONUM, CNUM, PNUM, QNUM); END

Note for OS/390 The SIGNAL statement is not yet supported on the OS/390 platform.

90 Cross-Platform DB2 Stored Procedures: Building and Debugging 3.5.3.18 WHILE statement The WHILE statement repeats the execution of a statement or group of statements while a specified condition is true. The LEAVE statement transfers program control out of the WHILE. The ITERATE statement causes the flow of control to return to the beginning of the WHILE. CREATE PROCEDURE E() LANGUAGE SQL BEGIN DECLARE aaa char(30); DECLARE zz INTEGER DEFAULT 11; ------THIS WHILE LOOP WILL TEST THE WHILE STATEMENT ITSELF ------while (zz>0)do INSERT INTO result(proc,res) VALUES('proc E','descending = '||CHAR(zz)); SET zz = zz -1; end while; ------THIS WHILE LOOP WILL TEST THE LEAVE STATEMENT ------xx:while (zz<5)do INSERT INTO result(proc,res) VALUES ('proc E','ascending= '||CHAR(zz)); SET zz = zz +1; LEAVE xx; INSERT INTO result(proc,res) VALUES ('proc E','leave not done= '||CHAR(zz)); end while; ------THIS WHILE LOOP WILL TEST THE ITERATE STATEMENT ------SETzz=0; xx1: while (zz<5)do INSERT INTO result(proc,res) VALUES ('proc E','ascending= '||CHAR(zz) ); SET zz = zz +1; ITERATE xx1; INSERT INTO result(proc,res) VALUES ( 'proc E', 'iterate not done= '||CHAR(zz) ); end while; INSERT INTO result(proc,res) VALUES ( 'proc E', 'end ' ); END

Chapter 3. SQL Procedures language 91 3.5.3.19 SQL statements Most of the SQL statements that are available for your platform are supported in SQL stored procedures. However, depending on your DB2 platform, some SQL statements might not be supported. See Table 3 on page 117 to find out which SQL statements are supported for WIN/NT, OS/390 and AS/400. There are two columns for each platform.

The first column tells you if this statement is available on this platform in general. A dash (-) means that this statement is not available at all. Y means it is available and N means it is not available. The second column for a specific platform tells you if this SQL statement is a valid statement in SQL stored procedures, contains a remark if there is something special to point on and has a link to a sample procedure in the appendix.

Refer to the SQL Reference Guide for your platform for a more detailed explanation.

Note The CALL and CASE statements may be the only statements within a procedure body. If so, the statement cannot end with a semicolon. Otherwise, the statement must end with a semicolon.

3.5.4 Handling errors in an SQL stored procedure To handle SQL errors, warnings or any other conditions within an SQL stored procedure, you must use so called handlers.

Conditions specified in a condition handler can be: • SQLSTATE value SQLSTATE is a special variable that DB2 sets to the SQLSTATE value that it returns after it executes an SQL statement. For more information on SQLSTATE values, see Appendix C of DB2 Messages and Codes. • Condition name ( user defined) This condition must be previously devined in a condition declaration. • SQLEXCEPTION (all SQLSTATE values with class other than 00, 01, or 02)

92 Cross-Platform DB2 Stored Procedures: Building and Debugging • SQLWARNING (all SQLSTATE values with class 01) • NOT FOUND (all SQLSTATE values with class 02)

The general form of a handler declaration is: DECLARE handler-type HANDLER FOR condition SQL-procedure-statement;

A condition handler must specify: • A set of conditions it is prepared to handle. • Action to perform to handle the condition. • Where to resume the execution after handling the condition.

The action specified in a condition handler can be any SQL statement, including a compound statement.

Note On DB2 UDB for OS/390 and AS/400, compound statements are not valid in condition handlers.

A condition handler gets executed automatically when a condition it is prepared to handle is detected anytime during the execution of the containing compound statement.

In general, the way that a handler works is that when a situation occurs that matches the condition,theSQL-procedure-statement executes. When SQL-procedure-statement completes, DB2 performs the action that is indicated by the handler-type.

There are three types of handlers: CONTINUE, EXIT, and UNDO.

• CONTINUE handler After the handler is invoked sucessfully, control is returned to the SQL statement that follows the statement that raised the exception. Several uses of the CONTINUE handler are described below.

Chapter 3. SQL Procedures language 93 The sample in Figure 41 shows a CONTINUE handler which is looking for SQLWARNING conditions. If an SQLWARNING occurs, the handler is fired (1). The result of statement2 in this example is SQLCODE +562. The action defined in the handler (SET CODE = SQLCODE) sets variable CODE to 562 (2). Since this is a CONTINUE handler, the execution of the procedure continues with the next statement (3) and finally stops its execution after it reached the END statement.

CONTINUE handler

Begin .... DECLARE CONTINUE HANDLER FOR SQLWARNING SET CODE = SQLCODE; ..... statement1; 1 2 statement2; results in SQLCODE +562 CODE = +562 HANDLER fired! ment th next state statement3; ontinues wi 4 Execution c 3 statement4

END

Figure 41. CONTINUE handler

If the error that raised the exception is a FOR, IF, CASE, WHILE, or REPEAT statement, then control returns to the statement that follows the END FOR, END IF, END CASE, END WHILE, or END REPEAT. This means the error must really occur for example in the IF A > B statement. The procedure does not jump to the END IF, if the error occurs on a statement within the IF statement body.

94 Cross-Platform DB2 Stored Procedures: Building and Debugging In Figure 42, the procedure does not continue after the END IF although the CONTINUE handler is fired, because the error occured inside the IF ... END IF block.(Actually, it works exactly the same way as it does in the sample described in Figure 41.)

CONTINUE handler with blocks

Begin .... DECLARE CONTINUE HANDLER FOR SQLWARNING SET CODE = SQLCODE; ..... statement1;

IF ....THEN 1 2 statement2; results in SQLCODE +562 CODE = +562 HANDLER fired! statement3; 3 ELSE statement4 END IF;

statement 5

END

Figure 42. CONTINUE handler with blocks

Chapter 3. SQL Procedures language 95 If the error occurs in the IF statement, as shown in Figure 43, after assigning nnn to variable CODE (2), the procedure continues its processing with statement 5, which is the first statement after the END IF (3).

CONTINUE handler error in IF statement

Begin .... DECLARE CONTINUE HANDLER FOR SQLWARNING SET CODE = SQLCODE; ..... statement1; 1 2 IF ....THEN results in SQLCODE +nnn CODE = +nnn HANDLER fired!

statement2;

statement3; ELSE statement4 END IF; 3

statement 5

4 END

Figure 43. CONTINUE handler with error in IF statement

96 Cross-Platform DB2 Stored Procedures: Building and Debugging • EXIT handler After the handler is invoked successfully, control is returned to the end of the compound statement. As shown in Figure 44, the EXIT handler is fired by an SQLEXCEPTION that returned SQLCODE -601 (1). This SQLCODE is assigned to variable CODE (2) and the procedure continues at the end of the compound statement.

Note For OS/390 it is not allowed to have nested compound statements. Therefore, for SQL procedures on OS/390, the EXIT handler will always end, not just the compound statement, but it will always end the execution of the complete procedure.

EXIT handler

Begin .... DECLARE EXIT HANDLER FOR SQLEXCEPTION SET CODE = SQLCODE; ..... statement1; 1 2 results in SQLCODE -601 statement2; HANDLER fired! CODE = -601 he statement3; nd of t to the e turned 3 ol is re END Contr tement und sta 4 compo

Figure 44. EXIT handler

Chapter 3. SQL Procedures language 97 A handler is only active within the compound statement in which it is declared. In the sample shown in Figure 45, procedure PROCA calls PROCB (1). In procedure PROCB we have two handler definitions. One CONTINUE handler for SQLEXCEPTIONS and one EXIT handler for SQLWARNINGS. During the execution of statement2, an SQLWARNING occurs (3). The variable CODE is set to the contents of special register SQLCODE (+562) (4) and the control is returned to the end of the compound statement in which this handler is defined (5). After this the control is returned to the calling procedure PROCA. Although the process previously encountered an SQLWARNING, the procedure continues with statement3 (7).

Exit handler with called procedure PROC A PROC B

2 Begin Begin ...... DECLARE EXIT HANDLER FOR SQLWARNING DECLARE CONTINUE HANDLER SET CODE = SQLCODE; FOR SQLEXCEPTION ..... SET CODE = SQLCODE; statement1; DECLARE EXIT HANDLER FOR SQLWARNING 1 SET CODE = SQLCODE; CALL PROC B ..... statement1; statement3; 3 4 results in SQLCODE +562 statement2; 7 HANDLER fired! CODE = +562 END statement3; 5 END

Figure 45. EXIT handler with called procedure

• UNDO handler Specifies that all the SQL statements done from the beginning of the containing compound statement, until the error point, are rolled back, and then, after the SQL-procedure-statement completes, execution continues at the end of the compound statement that contains the handler. This behavior is shown in Figure 46. After the NOT FOUND statement occured (1) variable CODE is set to the contents of special register SQLCODE (2). The changes made in statement1 are rolled back (3) and the procedure continues with the END statement of the compound statement in which the handler is defined(4).

98 Cross-Platform DB2 Stored Procedures: Building and Debugging Important UNDO handlers are not yet supported for DB2 UDB for OS/390.

UNDO handler

Begin .... DECLARE UNDO HANDLER FOR NOT FOUND SET CODE = SQLCODE; ..... statement1; 1 2 statement2; no matching row found results in SQLCODE 100 CODE = +100 statement3; 3 Rollback statement1 statement4 4 e rned to th END ol is retu t Contr statemen mpound end of co

Figure 46. UNDO handler

Chapter 3. SQL Procedures language 99 Special considerations for condition handling on OS/390: In DB2 UDB for OS/390 we distinguish between repeatable and nonrepeatable handler conditions.

Nonrepeatable handler conditions are: • SQLEXCEPTION • SQLWARNING • NOT FOUND

Nonrepeatable means that you can only use one of these handler conditions on one handler declaration. If you want to trigger more than one of these conditions, you have to declare multiple handlers.

Repeatable conditions are: • SQLSTATE ... • Previously declared conditions (condition name)

For the other platforms, all conditions are repeatable in the handler declaration.

Since you cannot use nested compound statements in your SQL procedures on DB2 UDB for OS/390, you cannot use the statement shown in Figure 47 to group a set of statements you would like to have executed when the handler conditions are met.

DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN SET CODE = SQLCODE; insert into result (proc,res) values(‘exec of proc1’,’continue handler fired’); END;

Figure 47. DECLARE handler statement with BEGIN ...END

In some situations you can use the simple work-around shown in Figure 48. Here we use an unconditional IF statement to group some procedure statements.

DECLARE CONTINUE HANDLER FOR SQLEXCEPTION IF 1=1 insert into result (proc,res) values(‘exec of proc1’,’continue handler fired’); set handlercount = handlercount+1; END IF;

Figure 48. DECLARE handler statement with IF ...END IF

100 Cross-Platform DB2 Stored Procedures: Building and Debugging Unfortunately this method is just fine as long as you do not want to capture the contents of the special registers SQLCODE or SQLSTATE, because the unconditional IF statement which is always true and therefore produces an SQLCODE 0 and SQLSTATE ‘00000’ destroys the original values which caused the handler to be executed.So if you want SQLCODE and SQLSTATE intact, you can only execute one statement in the handler.

One way to get out of this situation is to call another stored procedure from the handler. You can pass the SQLCODE and SQLSTATE to the called procedure as a parameter, and then you can execute as many statements as you want in the called procedure.

Important: — Consider the following sample: CREATE PROCEDURE db2res3.exitsamp() LANGUAGE SQL MODIFIES SQL DATA COLLID SG245485 WLM ENVIRONMENT WLMSQL ASUTIME NO LIMIT RUN OPTIONS 'NOTEST(ALL,*,,VADTCPIP&9.1.151.58:*)' BEGIN declare selname char(20); declare sqlstate char(5) default '00000'; declare c2 condition for sqlstate '02000'; DECLARE exit HANDLER FOR not found insert into result(proc,res) values ('exec of exitsamp','not found:'||sqlstate); DECLARE exit HANDLER FOR c2 insert into result(proc,res) values ('exec of exitsamp','c2:'||sqlstate); select name into selname from sysibm.sysdatabase where name = 'sqlprodb'; END

The ORDER of checking the conditions to execute the handler is this: The handler for condition C2 is checked FIRST, then the handler for condition NOT FOUND is checked SECOND. So since the C2 condition handler is checked first, it is found to be true, so the values 'exec of exitsamp','c2:'||sqlstate' get inserted into the table, and the procedure terminates (i.e. the NOT FOUND handler never gets triggered).

The following short example triggers any SQLEXCEPTIONS and some special values for the special register SQLSTATE.

If an SQLEXCEPTION occurs, one line is inserted into table result.

Chapter 3. SQL Procedures language 101 In the following sample, the exception handler is fired, because statement SET mydate = '12' || '13' || '99'; is wrong. mydate is defined as data type DATE. Variable mydate is set to ’121399’. This is no valid date format. A valid date format would be for example ’12/13/99’, which would require a SET statement like SET mydate = '12/' || '13/' || '99'. CREATE PROCEDURE G3() LANGUAGE SQL BEGIN declare mydate DATE; DECLARE C1 condition for SQLSTATE '22007'; DECLARE EXIT HANDLER FOR SQLEXCEPTION insert into result(proc,res) values ('exec of G3','EXIT HANDLER fired:SQLSTATE=' ||SQLSTATE||' SQLCODE='||CHAR(SQLCODE)); DECLARE EXIT HANDLER FOR C1, SQLSTATE '22008' insert into result(proc,res) values ('exec of G3','EXIT HANDLER fired:SQLSTATE=' ||SQLSTATE||' SQLCODE='||CHAR(SQLCODE)); insert into result(proc,res) values ('exec of G3','start of procedure'); SET mydate = '12' || '13' || '99'; END

The following is another example that uses exception handlers:

CREATE PROCEDURE PSM031 (IN NUM_PARTS CHAR(10) ) LANGUAGE SQL BEGIN DECLARE lc1,i, nb, lc2,lc1c2 integer default 0; DECLARE CONTINUE HANDLER FOR NOT FOUND BEGIN insert into result(proc,res) values ( 'exec from PSM031', 'NOT FOUND Handler fired'); END; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN insert into result(proc,res) values ( 'exec from PSM031', 'SQLEXCEPTION handler fired SQLCODE='||CHAR(SQLCODE)); END; DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN insert into result(proc,res) values ( 'exec from PSM031', 'SQLWARNING handler fired'); END;

DECLARE cur1 CURSOR FOR Select c1,c2 from t1;

102 Cross-Platform DB2 Stored Procedures: Building and Debugging delete from t1; insert into t1(c1,c2) values (1,1); insert into t1(c1,c2) values (1,2); set nb = (select count(*) from t1); OPEN cur1; seti=0; while (i < nb) do FETCH FROM cur1 INTO lc1,lc2; insert into result(proc,res) values ( 'exec from PSM031', 'row:'||CHAR(i)||' c1='|| CHAR(lc1) || ' c2='|| CHAR(lc2)); set i=i+1; end while; CLOSE cur1; END

3.5.5 Returning result sets In this section we consider the handling of result sets.

3.5.5.1 Creating result sets in an SQL stored procedure Passing a result set back to a calling application ( embedded SQL application or SQL stored procedure) is done by declaring with a SELECT statement a cursor on the rows that are to be passed back. Many result sets can be returned, but each requires an independent DECLARE CURSOR statement.

If the caller is an application, the cursor declaration has to use a "WITH RETURN TO CLIENT" clause, as in the following example: CREATE PROCEDURE sp_called_from_app LANGUAGE SQL BEGIN DECLARE result_set_1 cur1 CURSOR WITH RETURN TO CLIENT FOR Select empno,firstnme from employee ; OPEN result_set_1; END

If the result set has to be passed back to another stored procedure, the cursor declaration has to specify a "WITH RETURN TO CALLER" clause, as in the example below: CREATE PROCEDURE sp_called_from_sp LANGUAGE SQL BEGIN DECLARE result_set_1 cur1 CURSOR WITH RETURN TO CALLER FOR Select empno,firstnme from employee ; OPEN result_set_1; END

Chapter 3. SQL Procedures language 103 Note for OS/390 • On DB2 UDB for OS/390, the statement is just WITH RETURN. • It is currently not possible on OS/390 to process result sets returned by a call to a stored procedure WITHIN an SQL Procedure.

3.5.5.2 Retrieving result sets in the caller To retrieve the result sets properly, the caller (embedded SQL application or another SQL stored procedure) must perform certain operations. We will focus on the SQL stored procedure syntax only, but the steps are similar in embedded SQL or CLI applications using host variables.

Here is a high level view for retrieving a result set in the caller: • Declare a result set locator for each result set expected (DECLARE RESULT SET LOCATOR...). • CALL the stored procedure. • ASSOCIATE each locator to the procedure. • ALLOCATE each cursor for each result set locator. • FETCH the data for each cursor. • CLOSE each cursors opened with the ALLOCATE statement.

Each step is detailed below.

Following is an example of an SQL stored procedure Y4 that retrieves one result set from an SQL stored procedure Y41.

CREATE PROCEDURE Y41 (IN parm1 INTEGER ) LANGUAGE SQL BEGIN DECLARE cur1 CURSOR WITH RETURN TO CALLER FOR Select empno,firstnme from employee ; OPEN cur1 ; END

In the following procedure Y4, note the use of the CONTINUE HANDLER declaration to detect the end of the result set using the NOT FOUND condition. When this handler is fired, it sets the RESULT_SET_END variable to 1. After the execution of this handler, execution resumes after the FETCH statement, and the loop will finally terminates.

104 Cross-Platform DB2 Stored Procedures: Building and Debugging CREATE PROCEDURE Y4(IN parm1 INTEGER) LANGUAGE SQL BEGIN DECLARE LOC_RES1 RESULT_SET_LOCATOR VARYING; DECLARE rc1,rc2 CHAR(20); DECLARE RESULT_SET_END integer default 0; DECLARE CONTINUE HANDLER FOR NOT FOUND BEGIN SET RESULT_SET_END = 1; END;

CALL Y41(parm1); ASSOCIATE RESULT SET LOCATOR( LOC_RES1) WITH PROCEDURE Y41; ALLOCATE RES1 CURSOR FOR RESULT SET LOC_RES1; SET RESULT_SET_END = 0; WHILE(RESULT_SET_END = 0) DO FETCH FROM RES1 INTO rc1,rc2; IF(RESULT_SET_END=0) THEN insert into result(proc,res)values('exec Y4','rc1='||rc1||'rc2='||rc2); END IF; END WHILE; CLOSE RES1; END

3.5.5.3 Processing the result set Once the ASSOCIATE and ALLOCATE statements are done, processing a results set in the stored procedure is achieved by FETCHing the result set rows into an SQL variable until the end of the result set is reached. After a result set is processed, a CLOSE cursor statement must be executed.

In the example below, the SQL stored procedure processes two result sets by inserting each row into the result table. CREATE PROCEDURE P1() LANGUAGE SQL BEGIN DECLARE LOC1 RESULT_SET_LOCATOR VARYING; DECLARE LOC2 RESULT_SET_LOCATOR VARYING; DECLARE AT_END INTEGER DEFAULT 0; DECLARE column1,columns2 VARCHAR(30); DECLARE CONTINUE HANDLER FOR NOT FOUND SET AT_END = 1;

CALL P1;/*retrieve 2 results sets,both of them with 2 varchar(30) columns*/ ASSOCIATE RESULT SET LOCATORS (LOC1, LOC2) WITH PROCEDURE P1; ALLOCATE C1 CURSOR FOR RESULT SET LOC1;

Chapter 3. SQL Procedures language 105 ALLOCATE C2 CURSOR FOR RESULT SET LOC2; SET AT_END=0;

WHILE (AT_END = 0 ) DO /* processing result set #1 */ FETCH C1 INTO column1, columns2; INSERT INTO RESULT(proc,res) VALUES (’result 1’,column1||columns2); END WHILE;

CLOSE C1;

SET AT_END=0; WHILE (AT_END = 0 ) DO /* processing result set #1 */ FETCH C2 INTO column1, columns2; INSERT INTO RESULT(proc,res) VALUES (’result 1’,column1||columns2); END WHILE; CLOSE C2; END

Important • The OS/390 platform does not support result set locators yet (DECLARE xx RESULT SET LOCATOR, ASSOCIATE, ALLOCATE). • The example shown in Section 3.5.5.2, “Retrieving result sets in the caller” on page 104 with CONTINUE HANDLER shows a compound statement in the handler, which is not supported on OS/390.

3.6 SQL Procedures portability It is our intention to provide SQL Procedures support across the DB2 Universal Database family of products using a common SQL Procedures language and a common application development tool, the DB2 Stored Procedure Builder, on every platform. We also expect that a significant number of customers will want to develop their stored procedures on an individual workstation, for example, a PC running Windows NT, using a local database, for example, DB2 for Windows NT; and as they move that application and its stored procedures into production, they will deploy it on DB2 for Windows NT, on a different server or a DB2 for OS/390 platform.

Some customers will initially use their stored procedures against a departmental server running DB2 for AIX or DB2 for Sun Solaris, and then as usage scales up and more capacity is needed, they will consider moving their

106 Cross-Platform DB2 Stored Procedures: Building and Debugging stored procedures to DB2 for OS/390. We will support these development and usage scenarios by providing common SQL Procedures language and Stored Procedure Builder support across all platforms.

Because of differences in release cycles and platform priorities, it is not always possible (or desirable) to deliver the same functionality on all platforms at exactly the same time. To help application developers identify and use the very large set of SQL Procedures language features that are common across all of the DB2 platforms, we have produced three portability Tables. It is important to emphasize, however, that DB2 will be continuing to enhance the SQL Procedures language on all platforms and reduce any current platform differences.

Table 3 on page 117 gives you an overview about the available SQL statements for DB2 UDB for WIN/NT, OS/390 and AS/400.

Table 4 on page 122 gives you an overview about the available SQL procedure statements for DB2 UDB for WIN/NT, OS/390 and AS/400. The structure of this table is the same as described for Table 3.

Table 5 on page 123 is a summary of differences which exist between the three platforms. See the remarks below Table 5 for a more detailed description about the compared topic.

3.6.1 How to read the portability tables The first column tells you if this statement is available on this platform in general. A dash (-) means, that this statement is not available at all. The Y means it is available and N means it is not available.

The second column for a specific platform tells you if this SQL statement is a valid statement in SQL stored procedures, contains a remark if there is something special to point on and has a link to a sample procedure in the appendix.

Table 2 summarizes the availability and validity of SQL statements.

Table 3 on page 117 summarizes the availability and validity of SQL procedure statements. The name of the SQL procedure statement itself appears bold letters. If there is nothing special to be mentioned for this statement, no other entries belonging to this statement follow. If there are some additional information which should be mentioned, you will find them in plain letters. See the compound statement in Table 3 on page 117 as an example.

Chapter 3. SQL Procedures language 107 Table 2. SQL statements in SQL Procedures - portability across DB2 servers SQL UNIX,Windows,and OS/390 AS/400 Statement OS/2

S S S U U U P Valid / P Valid / P Valid / P P P O Remarks/ O Remarks/ O remarks / see Sample R Sample R sample T T T E E E D D D

ALLOCATE CURSOR Y Y Y N - -

ALTER BUFFERPOOL Y N - - - -

ALTER DATABASE - - Y Y - -

ALTER FUNCTION - - Y Y in V7 - -

ALTER INDEX - - Y Y - -

ALTER NICKNAME Y N Y N - -

ALTER NODEGROUP Y N - - - -

ALTER PROCEDURE - - Y Y in V7 - -

ALTER SERVER Y N - - - -

ALTER STOGROUP - - Y Y - -

ALTER TABLE Y N Y Y Y Y

ALTER TABLESPACE Y N Y Y - -

ALTER TYPE Y N - - - -

ALTER USER YN -- -- MAPPING

ALTER VIEW Y N - - - -

ASSOCIATE YY YN - - LOCATOR

BEGIN DECLARE Y? YN YN SECTION

108 Cross-Platform DB2 Stored Procedures: Building and Debugging SQL UNIX,Windows,and OS/390 AS/400 Statement OS/2

S S S U U U P Valid / P Valid / P Valid / P P P O Remarks/ O Remarks/ O remarks / see R R R T Sample T Sample T sample E E E D D D

CALL Y Y / Up to 16 Y Y/Upto16 Y Y / No limited levels/ levels / levels/ Refer to Refer to Refer to Appendix A.3.2, Appendix A.3.4, Appendix A.4.3, “SP01LMS.SQL “SP03LMS.SQL “SP03L4S.SQL sample” on sample” on sample” on page 465. page 467. page 478.

CLOSE Y Y YY/ YY Refer to Refer to Appendix A.2.1, Appendix A.3.2, “SP01LNS.SQL “SP01LMS.SQL sample” on sample” on page 449. page 465.

COMMENTON YY YY YY

COMMIT Y Y Y N / YY/ Supported in V7 Only allowed for NOT ATOMIC procedures that are NOT invoked through DRDA

COMPOUND SQL Y ? - - ? ?

CONNECT Y N Y Y / YY/ Refer to Refer to Appendix A.3.6, Appendix A.4.5, “SP05LMS.SQL “SP05L4S.SQL sample” on sample” on page 468. page 479.

CREATEALIAS YN YY YY

CREATE AUXILIARY -- YN -- TABLE

CREATE YN -- -- BUFFERPOOL

Chapter 3. SQL Procedures language 109 SQL UNIX,Windows,and OS/390 AS/400 Statement OS/2

S S S U U U P Valid / P Valid / P Valid / P P P O Remarks/ O Remarks/ O remarks / see R R R T Sample T Sample T sample E E E D D D

CREATE DATABASE - - Y Y Y Y

CREATE DISTINCT YN YYinV7 YY TYPE

CREATE EVENT YN -- -- MONITOR

CREATE FUNCTION Y N Y Y in V7 Y Y / Only external functions can be created in an SQL routine

CREATE GLOBAL -- YY/ -- TEMPORARY TABLE Refer to Appendix A.3.5, “SP04LMS.SQL sample” on page 468 (just replace DECLARE with CREATE in the sample)

CREATE INDEX Y Y Y Y Y Y

CREATE INDEX YN -- -- EXTENSION

CREATE METHOD Y N - - - -

CREATE NICKNAME Y N - - -? -

CREATE YN -- -- NODEGROUP

110 Cross-Platform DB2 Stored Procedures: Building and Debugging SQL UNIX,Windows,and OS/390 AS/400 Statement OS/2

S S S U U U P Valid / P Valid / P Valid / P P P O Remarks/ O Remarks/ O remarks / see R R R T Sample T Sample T sample E E E D D D

CREATE PROCEDURE Y N Y Y in V7 Y Y / Static CREATE / Only external procedures can be created in an SQL routine

CREATE SCHEMA Y N - - Y Y

CREATE SERVER Y N - - - -

CREATE STOGROUP - - Y Y - -

CREATE - - Y Y Y Y

CREATETABLEYYYYYY

CREATE YY YY - - TABLESPACE

CREATE TRANSFORM Y N - - - -

CREATE TRIGGER Y N Y Y in V7 Y N

CREATETYPE YN - - YY

CREATE TYPE YN -- -- MAPPING

CREATE USER YN -- -- MAPPING

CREATEVIEWYYYYYY

CREATE WRAPPER Y N - - - -

DECLARE CURSOR Y Y / YY/ YY/ Refer to Refer to Refer to Appendix A.2.1, Appendix A.3.2, Appendix A.4.1, “SP01LNS.SQL “SP01LMS.SQL “SP01L4S.SQL sample” on sample” on sample” on page 449. page 465. page 476.

Chapter 3. SQL Procedures language 111 SQL UNIX,Windows,and OS/390 AS/400 Statement OS/2

S S S U U U P Valid / P Valid / P Valid / P P P O Remarks/ O Remarks/ O remarks / see R R R T Sample T Sample T sample E E E D D D

DECLARE GLOBAL YY/ YY/ -- TEMPORARY TABLE Refer to Refer to Appendix A.2.4, Appendix A.3.5, “SP04LNS.SQL “SP04LMS.SQL sample” on sample” on page 452 page 468.

DECLARE YY/ YY/ YN STATEMENT Refer to Refer to Appendix A.2.6, Appendix A.3.7, “SP06LNS.SQL “SP06LMS.SQL sample” on sample” on page 453. page 469.

DECLARE TABLE - - Y N - -

DELETE Y Y / Y Y / Create YY/ Refer to procedure fails Refer to Appendix A.2.1, when DELETE Appendix A.4.1, “SP01LNS.SQL without WHERE “SP01L4S.SQL sample” on condition / sample” on page 449. Refer to page 476. Appendix A.3.2, “SP01LMS.SQL sample” on page 465.

DESCRIBE Y? YN YN

DISCONNECT Y N - - Y Y

DROPYYYYYY

END DECLARE Y? YN YN SECTION

112 Cross-Platform DB2 Stored Procedures: Building and Debugging SQL UNIX,Windows,and OS/390 AS/400 Statement OS/2

S S S U U U P Valid / P Valid / P Valid / P P P O Remarks/ O Remarks/ O remarks / see R R R T Sample T Sample T sample E E E D D D

EXECUTE Y Y / YY/ YY Refer to Refer to Appendix A.2.7, Appendix A.3.8, “SP07LNS.SQL “SP07LMS.SQL sample” on sample” on page 453. page 469.

EXECUTE IMMEDIATE Y Y / YY/ YY/ Refer to Refer to Refer to Appendix A.2.6, Appendix A.3.7, Appendix A.4.6, “SP06LNS.SQL “SP06LMS.SQL “SP06L4S.SQL sample” on sample” on sample” on page 453. page 469. page 480.

EXPLAIN Y ? Y N N N

FETCH Y Y / YY/ YY/ Refer to Refer to Refer to Appendix A.2.1, Appendix A.3.2, Appendix A.4.1, “SP01LNS.SQL “SP01LMS.SQL “SP01L4S.SQL sample” on sample” on sample” on page 449. page 465. page 476.

FLUSH EVENT Y? -- -- MONITOR

FREE LOCATOR Y ? Y N Y N

GRANTYYYYYY

HOLD LOCATOR - - Y N - -

INCLUDE Y ? Y N Y N

INSERT Y Y / YY/ YY/ Refer to Refer to Refer to Appendix A.2.1, Appendix A.3.2, Appendix A.4.1, “SP01LNS.SQL “SP01LMS.SQL “SP01L4S.SQL sample” on sample” on sample” on page 449. page 465. page 476.

Chapter 3. SQL Procedures language 113 SQL UNIX,Windows,and OS/390 AS/400 Statement OS/2

S S S U U U P Valid / P Valid / P Valid / P P P O Remarks/ O Remarks/ O remarks / see R R R T Sample T Sample T sample E E E D D D

LABEL ON - - Y Y Y Y

LOCK TABLE Y ? Y Y Y Y

OPEN Y Y / YY/ YY/ Refer to Refer to Refer to Appendix A.2.1, Appendix A.3.2, Appendix A.4.1, “SP01LNS.SQL “SP01LMS.SQL “SP01L4S.SQL sample” on sample” on sample” on page 449. page 465. page 476.

PREPARE Y Y / YY/ YY Refer to Refer to Appendix A.2.7, Appendix A.3.8, “SP07LNS.SQL “SP07LMS.SQL sample” on sample” on page 453. page 469.

REFRESH TABLE Y ? - - - -

RELEASE Y ? Y Y Y Y

RELEASE SAVEPOINT Y Y / YY/ NN Refer to Refer to Appendix A.2.7, Appendix A.3.8, “SP07LNS.SQL “SP07LMS.SQL sample” on sample” on page 453. page 469.

RENAME Y? YY YY

RENAME Y? -- -- TABLESPACE

REVOKE YN YY YY

ROLLBACK Y Y Y Y in V7 Y Y

114 Cross-Platform DB2 Stored Procedures: Building and Debugging SQL UNIX,Windows,and OS/390 AS/400 Statement OS/2

S S S U U U P Valid / P Valid / P Valid / P P P O Remarks/ O Remarks/ O remarks / see R R R T Sample T Sample T sample E E E D D D

ROLLBACK YY/ YY/ NN SAVEPOINT Rollback only Refer to possible to the Appendix A.3.8, most recent “SP07LMS.SQL savepoint. sample” on Nested page 469. not supported. SQLCODE -20112 occurs at runtime. Build procedure works fine even if nested savepoints in SP.

Savepoints are not allowed in atomic compound statements./

Refer to Appendix A.2.7, “SP07LNS.SQL sample” on page 453.

SAVEPOINT Y Y / YY/ NN Refer to Refer to Appendix A.2.7, Appendix A.3.8, “SP07LNS.SQL “SP07LMS.SQL sample” on sample” on page 453. page 469.

Chapter 3. SQL Procedures language 115 SQL UNIX,Windows,and OS/390 AS/400 Statement OS/2

S S S U U U P Valid / P Valid / P Valid / P P P O Remarks/ O Remarks/ O remarks / see R R R T Sample T Sample T sample E E E D D D

SELECT INTO Y Y / YY/ YY/ Refer to Refer to Refer to Appendix A.2.2, Appendix A.3.3, Appendix A.4.2, “SP02LNS.SQL “SP02LMS.SQL “SP02L4S.SQL sample” on sample” on sample” on page 451. page 467. page 477.

SET assignment Y Y / YY/ YY/ Refer to Refer to Refer to Appendix A.2.8, Appendix A.3.9, Appendix A.4.7, “SP08LNS.SQL “SP08LMS.SQL “SP08L4S.SQL sample” on sample” on sample” on page 454. page 470. page 480.

SET CURRENT .. Y ? Y Y / Y Y / Supported for SET CURRENT PATH ...

SIGNAL SQLSTATE Y Y Y N Y Y / Only supported in SQL routines

UPDATE YY YY YY

VALUES YY YN YN

VALUESINTO YY YN YY

WHENEVER Y ? Y N Y N

116 Cross-Platform DB2 Stored Procedures: Building and Debugging Table 3. SQL statements in SQL Procedures - portability across DB2 platforms SQL UNIX, Windows, and OS/390 AS/400 Statement OS/2

S S S U U U P Valid / P Valid / P Valid / P P P O Remarks/ O Remarks/ O remarks / see R Sample R Sample R sample T T T E E E D D D

ALLOCATE CURSOR YY YN YY

ASSIGNMENT YY YY YY statement

Select statement on YY YN/See YY right hand side of SET description of statement assignment statement in Section 3.5.3.3, “Assignment statement” on page 73.

ASSOCIATE YY YN NN LOCATOR statement

CALL statement YY/ YY/ YY/ Refer to Refer to Refer to Appendix A.2.3, Appendix A.3.4, Appendix A.4.3, “SP03LNS.SQL “SP03LMS.SQL “SP03L4S.SQL sample” on sample” on sample” on page 451. page 467. page 478.

CASE statement YY/ YY/ YY/ Allowedupto Allowedupto Refer to three levels for three levels for Appendix A.4.4, both simple and simple case “SP04L4S.SQL searched case statement when sample” on statement when clause. Unlimited page 478. clause./ for searched Refer to case statement Appendix A.2.4, when clause / “SP04LNS.SQL Refer to sample” on Appendix A.3.5, page 452. “SP04LMS.SQL sample” on page 468.

Chapter 3. SQL Procedures language 117 SQL UNIX, Windows, and OS/390 AS/400 Statement OS/2

S S S U U U P Valid / P Valid / P Valid / P P P O Remarks/ O Remarks/ O remarks / see R R R T Sample T Sample T sample E E E D D D

COMPOUND YY YY YY statement

ATOMIC Y Y - - Y Y

NOT ATOMIC Y Y / YY/ YY/ Refer to Refer to Refer to Appendix A.2.9, Appendix A.3.10, Appendix A.4.8, “SP09LNS.SQL “SP09LMS.SQL “SP09L4S.SQL sample” on sample” on sample” on page 454. page 470. page 481.

Variable name with the YY/ YY/ YY/ same name as column DB2 interprets DB2 interprets DB2 interprets the identifier as thenameasan the identifier as column SQL variable or column Refer to parameter name. Appendix A.2.17, Qualify column “SP17LNS.SQL name with table sample” on name to refer to page 458. it. / Refer to Appendix A.3.18, “SP17LMS.SQL sample” on page 475.

CLOB data type Y Y Y N Y Y

BIGINT data type Y Y / - - Y Y

BLOB data type Y Y Y N Y Y

CHARACTER data type Y Y / YY/ YY/ max 255 bytes max 255 bytes max 32740 bytes

DATALINK data type Y N - - Y Y

DATE data type Y Y Y Y Y Y

DBCLOB data type Y Y / with Fixpack 2 - - Y Y

DECIMAL data type Y Y Y Y Y Y

118 Cross-Platform DB2 Stored Procedures: Building and Debugging SQL UNIX, Windows, and OS/390 AS/400 Statement OS/2

S S S U U U P Valid / P Valid / P Valid / P P P O Remarks/ O Remarks/ O remarks / see R R R T Sample T Sample T sample E E E D D D

DOUBLE data type Y Y Y Y Y Y

FLOAT data type Y Y Y Y Y Y

GRAPHIC data type Y Y / with Fixpack 2 Y Y Y Y

INTEGERdatatype Y Y Y Y Y Y

LONGVARGRAPHIC YN - - YN data type

REAL data type Y Y Y Y Y Y

SMALLINT data type Y Y Y Y Y Y

TIME data type Y Y Y Y Y Y

TIMESTAMP data type Y Y Y Y Y Y

User defined data types Y N Y N Y Y

VARCHAR data type Y Y / YY/ YY/ max 32672 bytes max 32704 bytes max 32740 bytes

VARGRAPHIC data type Y N Y Y Y Y

CONTINUE handler Y Y / YY/ YY all conditions are SQLEXCEPTION, repeatable SQLWARNING, and NOT FOUND are unrepeatable conditions.

EXIT handler Y Y / YY/ YY Refer to Refer to Appendix A.2.10, Appendix A.3.11, “SP10LNS.SQL “SP10LMS.SQL sample” on sample” on page 455. page 471.

Chapter 3. SQL Procedures language 119 SQL UNIX, Windows, and OS/390 AS/400 Statement OS/2

S S S U U U P Valid / P Valid / P Valid / P P P O Remarks/ O Remarks/ O remarks / see R R R T Sample T Sample T sample E E E D D D

UNDO handler Y Y / -- YY ATOMIC must be specified

Nested ATOMIC NN -- -- compound statement

Nested NOT ATOMIC YY -- -- compound statement

Specific order of NN YY/ YY/ statements in compound 1) SQL variable 1) SQL variable statement? and condition and condition declarations declarations 2) Cursor 2) Cursor declarations declarations 3) Handler 3) Handler declarations declarations 4) Procedure 4) Procedure body statements body statements (CASE, IF ...) (CASE, IF ...)

Only compound YY/ YN ?? statement in procedure The statement body cannot end with a semicolon

FOR statement YY - - YY

GET DIAGNOSTICS YYYYY statement

row_count Y Y / YY/ YY/ Refer to Refer to Refer to Appendix A.2.11, Appendix A.3.12, Appendix A.4.9, “SP11LNS.SQL “SP11LMS.SQL “SP11L4S.SQL sample” on sample” on sample” on page 455. page 472. page 481.

return_status Y Y - - Y Y

120 Cross-Platform DB2 Stored Procedures: Building and Debugging SQL UNIX, Windows, and OS/390 AS/400 Statement OS/2

S S S U U U P Valid / P Valid / P Valid / P P P O Remarks/ O Remarks/ O remarks / see R R R T Sample T Sample T sample E E E D D D message_text N N - - Y message_length N N - - Y Y message_octet_length N N - - Y Y

GOTO statement YY YY YY

IF statement YY/ YY/ YY/ Refer to Refer to Refer to Appendix A.2.13, Appendix A.3.14, Appendix A.4.11, “SP13LNS.SQL “SP13LMS.SQL “SP13L4S.SQL sample” on sample” on sample” on page 456. page 473. page 482.

ITERATE statement YY -- --

LEAVE statement YY/ YY/ YY/ Refer to Refer to Refer to Appendix A.2.14, Appendix A.3.15, Appendix A.2.14, “SP14LNS.SQL “SP14LMS.SQL “SP14LNS.SQL sample” on sample” on sample” on page 457. page 473. page 457.

LOOP statement YY/ YY/ YY/ Refer to Refer to Refer to Appendix A.2.14, Appendix A.3.15, Appendix A.4.12, “SP14LNS.SQL “SP14LMS.SQL “SP14L4S.SQL sample” on sample” on sample” on page 457. page 473 page 482.

REPEAT statement YY/ YY/ YY/ Refer to Refer to Refer to Appendix A.2.15, Appendix A.3.16, Appendix A.4.13, “SP15LNS.SQL “SP15LMS.SQL “SP15L4S.SQL sample” on sample” on sample” on page 457. page 474. page 483.

RESIGNAL statement YY - - YY

RETURN statement YY - - YY

Chapter 3. SQL Procedures language 121 SQL UNIX, Windows, and OS/390 AS/400 Statement OS/2

S S S U U U P Valid / P Valid / P Valid / P P P O Remarks/ O Remarks/ O remarks / see R R R T Sample T Sample T sample E E E D D D

SIGNAL statement YY - - YY

WHILE statement YY/ YY/ YY Refer to Refer to Appendix A.2.15, Appendix A.3.17, “SP15LNS.SQL “SP16LMS.SQL sample” on sample” on page 457. page 475.

Table 4. Limits in SQL Procedures - portability across DB2 platforms SQL WIN/NT OS/390 AS/400 Statement

Max length of procedure name 64 characters 18 characters / use 128 characters only 8 characters when you work with the SPB. See 11.2.1, “Length and size limits” on page 350 for further information

Max length of parameter 128 characters 18 characters 30 characters names (unqualified name) / 128 characters in V5R1

Max length of source code 64 Kb 32 Kb 32 Kb

122 Cross-Platform DB2 Stored Procedures: Building and Debugging Table 5. Other remarks on SQL Procedures - portability across DB2 platforms SQL WIN/NT OS/390 AS/400 Statement

Authorization behavior with Supported Supported Supported only dynamic SQL statements; will Note: can be Note: can be through use executor's authority for overridden through overriden through RUNSQLSTM both DML and DDL bind options with new bind options with new command dynamic rules (bind) dynamic rules (bind) to change DML to change DML authorization to static authorization to static model. model.

Returning result sets Supported Supported / Supported Refer to Refer to Refer to Appendix A.2.3, Appendix A.3.4, Appendix A.4.3, “SP03LNS.SQL “SP03LMS.SQL “SP03L4S.SQL sample” on page 451 sample” on page 467 sample” on page 478 and Appendix A.2.5, and Appendix A.3.6, and Appendix A.4.5, “SP05LNS.SQL “SP05LMS.SQL “SP05L4S.SQL sample” on page 452. sample” on page 468. sample” on page 479.

Returning multi-rowed result Supported Supported / Supported from a sets Refer to Refer to client via Client Appendix A.2.2, Chapter A.3.3, Access ODBC and “SP02LNS.SQL “SP02LMS.SQL Java Toolbox JDBC. sample” on page 451. sample” on page 467. Supported from the server through CLI and JDBC.

Not supported through DRDA till next release.

Refer to Appendix A.4.2, “SP02L4S.SQL sample” on page 477.

Stand-alone Supported Supported Supported SQLCODE/SQLSTATE 1

Single statement procedure 2 Supported Supported Supported

Label on all statements Supported Not yet supported Supported since (for GOTOs) V4R1

Chapter 3. SQL Procedures language 123 SQL WIN/NT OS/390 AS/400 Statement

C comment 3 Supported Supported on V6 with Supported APAR PQ40299/40300 applied

Overriding of PREP and Supported Supported Supported via options compile options in Client Access. Supported on the RUNSQLSTM interface / Supported via SET OPTION in statement in V5R1

Newlinestoredinthecatalog- Supported Newline markers are Currently strip out all consistency stored in extra blanks and SYSIBM.SYSPSMfor control characters. SPB to recover the This is partially initial "look" of the because the catalog stored procedure. column is The debugger will VARCHAR(18432), display PSM source but a procedure body as 80 byte wide lines can be larger than (a DB2 for OS/390 that. precompiler restriction) This will be supported in V5R1.

Recognition of procedure end Supported End of file indicates Supported. (for prep) 4 the end of the SQL Note: No special procedure unique ending necessary.

LOB locator Not yet supported Not yet supported Supported

DATE arithmetic Supported Supported Supported (for example: mydate+5 days)

124 Cross-Platform DB2 Stored Procedures: Building and Debugging 1. Standalone SQLSTATE/SQLCODE means: You can have a PSM variable named SQLCODE or SQLSTATE that will be updated after every SQL statement execution. You cannot have 2 of these (one global and one in a local block). They must be declared once in the main block of the SP. This function is important for people that do not want to use the handler programming model. These customers typically migrated from SYBASE or MS SQLServer to DB2 and are used to test an error code (like @@error) after every SQL statement to decide to leave or continue the procedure or do something else. Attention: Standalone SQLCODE/SQLSTATE are not part of SQL/PSM standard and this should be used only for application that are migrated from other RDBMS, so the code looks nearly similar. Very important: New applications should directly code with exception handlers. 2. Single statement procedures only have one SQL statement in them. It could be a huge SELECT statement or a big CASE statement with plenty of SQL statements in it. There is no BEGIN..END block like in the following example. create procedure A( x int, y int out ) language SQL CASE x WHEN A = 10 THEN SET y=10; ELSE SET y=(select count(*) from staff); END CASE % Note: If you are working with a single SQL statement in your stored procedure, you do not have to put an extra BEGIN..END block finishing with a ; or % . 3. In the C-language procedure that is generated under-the-covers for an SQL Procedure, the original SQL source is placed at the top of the C-source module surrounded by comment delimiters (/***$$$ and $$$***/). With the specified APARS, the support for C-style comments in the SQL source itself is added. Thus you could have an SQL Procedure like this: CREATE PROCEDURE CTEST (OUT PARM1 INT) LANGUAGE SQL -- This is the other kind of comment supported BEGIN /* This is a C-style comment */ SET PARM1 = 10; END

Chapter 3. SQL Procedures language 125 4. The procedure end is recognized by the statement delimiter. On WIN/NT you can set this delimiter with the following statement: db2 -td% -f xx.psm

126 Cross-Platform DB2 Stored Procedures: Building and Debugging Chapter 4. IBM Distributed Debugger

The IBM Distributed Debugger is a client/server application that enables you to detect and diagnose errors in your programs. This client/server design makes it possible to debug programs running on systems accessible through a network connection as well as debug programs running on your workstation.

The debugger server, also known as a debug engine, runs on the same system where the program you want to debug runs. This system can be your workstation or a system accessible through a network. If you debug a program running on your workstation, you are performing local debugging. If you debug a program running on a system accessible through a network connection, you are performing remote debugging.

The debug engine can either start the program you want to debug or attach to an already running program. Once started, the debug engine controls the execution of your program.

The debugger client is a graphical user interface where you can issue commands used by the debug engine to control the execution of your program. For example, you can set breakpoints, step through your code and examine the contents of variables.

To use the remote debugging capability for stored procedures on the Intel and UNIX platforms, you need to install the IBM Distributed Debugger. The IBM Distributed Debugger is included on the VisualAge for Java Professional Edition CD. The debugger client runs only on the Windows platform. Supported server platforms include: Windows, AIX and Solaris. At this time, only Java and C stored procedures can be debugged remotely. At a later date, the Debugger will be integrated into DB2. Support for SQL procedures will then be available.

To debug SQL procedures on the OS/390 platform, you must also have the IBM C/C++ Productivity Tools for OS/390 R1 product. For more information on the IBM C/C++ Productivity Tools for OS/390 R1, go to the following Web site: http://www.ibm.com/software/ad/c390/pt/

© Copyright IBM Corp. 2001 127 4.1 Distributed Debugger for the workstation The Distributed Debugger is shipped with VisualAge for Java Enterprise Edition. Even though it is a separate product it comes on the same CD as VisualAge for Java.

4.1.1 Installing the Distributed Debugger on the workstation If you insert the VisualAge for Java CD in your CDROM drive, the Install Selection panel gives you the option to install the Distributed Debugger. Click “Install Distributed Debugger” and follow the installation instructions.

Upgrades are mostly available as zip files. To install an upgrade, you usually need to copy the zip file to a local temporary directory, unzip the file with your favorite unzip utility, start setup.exe, and follow the instructions.

4.2 Distributed Debugger for OS/390 On OS/390 the Distributed Debugger is known as Debug Tool. It is available as a product feature of the following products: • C/C++ for MVS & VM • COBOLforMVS&VM • COBOL for OS/390 & VM • OS/390 C/C++ feature • PL/I for MVS & VM • VisualAge for Java, Enterprise Edition for OS/390

Debug Tool can also be obtained by ordering CODE/370.

Ensure you have the most recent version of the product installed, along with all applicable maintenance, to take advantage of the latest level of the debugger. Also ensure you have the respective JDK level installed which is especially important if you debug Java bytecode.

We recommend also to visit http://www.s390.ibm.com/dt for the latest information about Debug Tool.

128 Cross-Platform DB2 Stored Procedures: Building and Debugging 4.2.1 Installing the Distributed Debugger on OS/390 Information regarding installation, and any maintenance requirements, for Debug Tool can be found in the installation material for the products listed in Section 3.2, “Distributed Debugger for OS/390” on page 50.

In order to run the debugger the data set EQA.V1R2M0.SEQAMOD is used. If you debug your program from within ET/390 of VisualAge for Java Enterprise Edition, this means, if you work directly from the VisualAge workbench, you do not need to add EQA.V1R2M0.SEQAMOD to the STEPLIB, because this is done automatically when you start debugging.

However, for better performance of the debugger, your system programmer could copy the entire EQA.V1R2M0.SEQAMOD data set into the LPA. If this is done, EQA.V1R2M0.SEQAMOD should be removed from the environment variable STEPLIB.

4.2.2 Setting up for remote debugging After you apply Debug Tool service onto an OS/390 release 2 or later environment, you must enable Debug Tool before it can be used. You do not need to enable Debug Tool each time service is applied, only the first time. If Debug Tool is not enabled and a user attempts to use it, a message similar to the following is generated: MSGIFA104I REGISTRATION HAS BEEN DENIED FOR PRODUCT WITH OWNER=IBM CORP NAME=OS/390 FEATURE=VAJAVA/DEBUG VERSION=.. ID=5655-JAV

To enable Debug Tool, include an entry for Debug Tool in the IFAPRDxx PARMLIB member. Only one entry in IFAPRDxx for Debug Tool is required. For example, if you have IBM COBOL for OS/390 & VM Full Function feature (which includes Debug Tool) and now have installed VisualAge for Java Enterprise Edition for OS/390, you only need to have a single entry in IFAPRDxx for Debug Tool which would be the one that you have already added for COBOL. You will be able to use Debug Tool to debug applications written in COBOL, Java, or both.

If you do not have an IFAPRDxx entry for the Debug Tool so far, include one for VisualAge for Java like shown below: PRODUCT OWNER('IBM CORP') NAME('IBM VAJAVA/390') ID(5655-JAV) VERSION(*) RELEASE(*) MOD(*) FEATURENAME(VAJAVA-DEBUG) STATE(ENABLED)

Chapter 4. IBM Distributed Debugger 129 When you have updated IFAPRDxxx, Debug Tool is enabled in OS/390.

Notes: Refer to OS/390 V2R6.0 Planning for Installation, GC28-1726 or later, or instructions on dynamically enabling features including alerting your IBM representative that you are starting to use the newly enabled features.

For additional information on Debug tool, refer to Debug Tool User's Guide and Reference, SC09-2137-03, and visit the following Web sites: • C/C++ productivity Tools for OS/390 R1 — http://www.ibm.com/software/ad/c390/pt/ • COBOL debug tool — http://www.s390.ibm.com/dt/

130 Cross-Platform DB2 Stored Procedures: Building and Debugging Chapter 5. OS/390 Workload Manager

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

DB2 (with OS/390 Release 3 or above) enables you to run multiple WLM-managed stored procedures address spaces. With WLM-established stored procedures address spaces, 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

5.1 Introduction to OS/390 Workload Manager (WLM) In this section, we summarize the main elements of WLM. If you do not 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.

© Copyright IBM Corp. 2001 131 5.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), which is called the compatibility mode. The new goal-oriented performance management with the service definition (see Section 5.1.2, “WLM definitions — relationships” on page 132) 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. The 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.

5.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 49, a service definition applies to several supported types of work (such as DB2, DDF, and CICS), and consists of one or more service policies.

132 Cross-Platform DB2 Stored Procedures: Building and Debugging SERVICE DEFINITION

APPLIES TO CONSISTS OF

TYPE OF SERVICE WORK POLICY

A C T I V E

DB2 CICS DDF IMS ... SERVICE SERVICE SERVICE POLICY 1 POLICY 2 POLICY 3

Figure 49. WLM — 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 50, you associate a workload with one or more service classes.

Chapter 5. OS/390 Workload Manager 133 GROUP OF WORK WORKLOAD (CICS: TRX1, TRX2 DB2: APL1, APL2

SERVICE CLASS 1 SERVICE CLASS 1 SERVICE CLASS 1 (grouped by (grouped by (grouped by characteristics 1) characteristics 2) characteristics 3)

SERVICE SERVICE SERVICE SERVICE SERVICE SERVICE SERVICE CLASS CLASS CLASS CLASS CLASS CLASS CLASS PERIOD 1 PERIOD 2 PERIOD 1 PERIOD 2 PERIOD 3 PERIOD 2 PERIOD 2

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

134 Cross-Platform DB2 Stored Procedures: Building and Debugging • 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 51 summarizes the performance goals of a service class period.

SERVICE CLASS PERIOD

HAS

PERFORMANCE GOAL

IMPORTANCE GOAL

lowest to highest (5 levels)

discretionary response time velocity (low priority) (how quick (how fast

ex: transaction) ex: long batch)

Figure 51. Summary of the performance goals of a service class

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

Chapter 5. OS/390 Workload Manager 135 As illustrated in Figure 52, performance goals for stored procedures generally inherit the performance of the calling client application.

WLM DEFINITION DDF STPC1 CLIENT PERF.GOAL W PERFORMANCE GOAL x . STPC1 . EXECSQLCALLSTPC1... . . PERFORMANCE GOAL X IMS, CICS, TSO, CAF, RRSAF

CLIENT

PERFORMANCE GOAL Y STPC1 EXEC SQL CONNECT... . . EXEC SQL SELECT... PERFORMANCE GOAL Y . . EXECSQLCALLSTPC1... DDF

STPC1 CLIENT

PERFORMANCE GOAL Z EXEC SQL CONNECT... PERFORMANCE GOAL Z . . EXECSQLCALLSTPC1... WLM STORED PROCEDURE . . ADDRESS SPACE

Figure 52. Assigning performance goals to stored procedures

For example, if the stored procedure is invoked by an CICS transaction, IMS transaction, TSO attachment, CAF, or RRSAF, the stored procedure inherits the performance goals of the client transaction (for example, in Figure 52, 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 52, 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.

136 Cross-Platform DB2 Stored Procedures: Building and Debugging • 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 52, 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.

5.2 Application environments We begin by defining the application environment in general.

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

Chapter 5. OS/390 Workload Manager 137 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.

5.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. • The 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 53 shows the relationship among the information contained in the SYSIBM.SYSROUTINES table, the application environment, and the JCL procedure used to start the stored procedures address space.

138 Cross-Platform DB2 Stored Procedures: Building and Debugging DB2 SYSIBM.SYSROUTINES

NAME WLM_ENVIRONMENT

SP01 LMS WLMSQL

WLM APPLICATION ENV NAME = WLMSQL PROCEDURE NAME = WLMSQL

SY B S1.PROC LI W LMSQL

Figure 53. SYSIBM.SYSROUTINES, application environment, JCL procedures

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

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

Application Environment . . . ______Required Description ...... ______Subsystem Type ...... ____ Required Procedure Name ...... ______Start Parameters ...... ______

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 54. Sample of the Application-Environment panel

Chapter 5. OS/390 Workload Manager 139 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.SYSROUTINES, for all stored procedures that use this application environment. This name can be any name, but it 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

140 Cross-Platform DB2 Stored Procedures: Building and Debugging 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.

5.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 OS/390 operator START command to start the stored procedures address space and the OS/390 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:

Chapter 5. OS/390 Workload Manager 141 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 Section 5.5, “Managing application environments” on page 143.

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

142 Cross-Platform DB2 Stored Procedures: Building and Debugging 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.

5.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: VARY WLM,APPLENV=xxxxx,option

Where: • xxxxx is the application environment name. • option can be QUIESCE, RESUME, or REFRESH.

Chapter 5. OS/390 Workload Manager 143 5.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.

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

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

144 Cross-Platform DB2 Stored Procedures: Building and Debugging 5.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.

5.7 Defining a service definition The DB2 UDB for OS/390 Administration Guide, SC26-9003, 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 Section 5.8, “Existing service definition” on page 146 for a description of how to perform this task.

If you do not 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 55 shows the relationship among the WLM definitions.

Chapter 5. OS/390 Workload Manager 145 APPLICATION ENV

NAME = WLMSQL SUBSYSTEMTYPE = DB2

CLASSIFICATION RULES DB2 TYPE - DB2 SYSIBM.SYSROUTINES PROCEDURE NAME SP0ILMS SERVICE = HIGHPRT

SERVICE CLASS

NAME = HIGHPRT WORKLOAD = ONLINE SERVICE CLASS PERIODS

WORKLOAD

NAME = ONLINE

Figure 55. Relationship among 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.

Refer to Section 9.3.4, “WLM definitions” on page 319 for a detailed information how to perform those definitions.

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

146 Cross-Platform DB2 Stored Procedures: Building and Debugging 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 56.

------

Command ===> ______

EsssssssssssssssssssssssssssssssssssssssssssssN e Choose Service Definition e ee e Select one of the following options. e e 2_ 1. Read saved definition e e 2. Extract definition from WLM e e couple data set e e 3. Create new definition e ee e F1=Help F2=Split F5=KeysHelp e e F9=Swap F12=Cancel e DsssssssssssssssssssssssssssssssssssssssssssssM ENTER to continue

Figure 56. Choose Service Definition Panel

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 Section 5.7, “Defining a service definition” on page 145.

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

Chapter 5. OS/390 Workload Manager 147 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.

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

148 Cross-Platform DB2 Stored Procedures: Building and Debugging 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: 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

Chapter 5. OS/390 Workload Manager 149 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 PROC= 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: 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

150 Cross-Platform DB2 Stored Procedures: Building and Debugging 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 do not 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

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:

Chapter 5. OS/390 Workload Manager 151 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 do not 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

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

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

152 Cross-Platform DB2 Stored Procedures: Building and Debugging The following is the extract for the SCDB2STP service class: * Service Class SCDB2STP - serv class for db2 stored proc Base goal: # Duration Imp Goal description ------1 1000 2 Average response time of 00:00:30.000 2 4 Average response time of 00:04:00.000

The following is the extract for the HIGHPRT service class: * Service Class HIGHPRT - test sched + 1 ad spc Base goal: # Duration Imp Goal description ------1 5 Average response time of 00:00:00.015

5.11.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 OS/390 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.

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

Chapter 5. OS/390 Workload Manager 153 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

5.11.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 OS/390 console, which 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 OS/390 console. 5. After about 8 to 10 minutes, without submitting any more work, WLM brought down all but one WLM-established stored procedure.

154 Cross-Platform DB2 Stored Procedures: Building and Debugging 5.11.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

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

Chapter 5. OS/390 Workload Manager 155 We then issued the start OS/390 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 OS/390 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.)-- 6. When we issued the command to vary the application environment with the resume option, the stored procedure was executed.

5.12 Refreshing the WLM environment through stored procedures If you are using stored procedures on DB2for OS/390, probably you have already faced a need for a method of permitting authorized users to refresh WLM-managed address spaces on remote systems without operations assistance.

The APAR PQ38433 adds a sample code and JCL for WLM_REFRESH, a stored procedure that can be invoked from a remote location to recycle a WLM environment specified as an input parameter. The WLM_REFRESH uses the System Access Facility (SAF) RACROUTE command to verify that the current SQLID of the caller is authorized to request the refresh. Basically it implements an stored procedure called WLM_REFRESH, which issues a request to OS/390 refresh a specified WLM environment.

5.12.1 Using the WLM_REFRESH stored procedure The syntax for the CALL statement is: >>--CALL--SYSPROC.WLM_REFRESH--(------> >------wlm-environment-name--,-> >------ssid--,------> >------status-message--,------> >------return-code--)------><

Where: • wlm-environment-name — is a VARCHAR(32) input parameter that accepts the name of a WLM environment to be refreshed. • ssid — is a VARCHAR(4) input parameter that accepts the DB2 subsystem id associated with that WLM environment. • status-message — is a VARCHAR(120) output parameter (see section 3 WLM_REFRESH messages, below).

156 Cross-Platform DB2 Stored Procedures: Building and Debugging • return-code — is an INTEGER output parameter: • 0995 — WLM_REFRESH was not invoked APF-authorized. • 0990 — Unexpected SQLCODE from SQL SELECT. • 0008 — The CURRENT SQLID is not authorized to refresh the specified WLM environment. • 0004— Either of the following: - No resource profile exists for WLM_REFRESH and the specified WLM environment and DB2 subsystem id. - The current SQL ID is undefined to the System Access Facility (SAF).

The WLM_REFRESH stored procedure uses parameter style GENERAL, so does not accept or return parameters.

In DB2 Version 5, WLM_REFRESH runs with EXTERNAL_SECURITY(NO); From Version 6 onward, it runs with SECURITY(DEFINER).

5.12.2 WLM_REFRESH stored procedure security Before issuing a refresh request, WLM_REFRESH verifies that the CURRENT SQLID of the caller is authorized to refresh the specified WLM environment. To be authorized, the SQLID must have READ access or higher to the following SAF resource profile, which must have been created within resource class DSNR as follows: .WLM_REFRESH.

Where: • WLM-environment-name — is the name of an environment to be refreshed. • ssid — is the DB2 subsystem id associated with that environment.

5.12.3 WLM_REFRESH stored procedure environment The WLM_REFRESH stored procedure itself must run under control of a WLM-established stored procedures address space. It can be used to recycle its own environment as well as others.

The DSNTWR, the external module for WLM_REFRESH, must reside in an APF-authorized library because it uses the MGCRE macrotoissuetheWLM refresh command, and the MODESET macro to enter supervisor state key 0 for the duration of the MGCRE call.

Chapter 5. OS/390 Workload Manager 157 All libraries in the STEPLIB concatenation of the WLM startup procedure for WLM_REFRESH must also be APF authorized.

5.12.4 Installing the WLM_REFRESH stored procedure The PTF adds the following parts to the SDSNSAMP library of DB2 for OS/390 Version 5 and DB2 UDB for OS/390 Version 6: • DSNTWR — Assembler source code for the WLM_REFRESH stored procedure external module • DSN8ED6 — C-language source code for a sample caller of WLM_REFRESH • DSNTEJ6W — Sample JCL that can be used to: - Create a sample SAF resource profile required by WLM_REFRESH - Register the stored procedure WLM_REFRESH - Prepare and bind DSNTWR - Prepare, bind, and execute DSN8ED6

This PTF modifies the following existing parts: • DSNTEJ0: Removes DB2 sample objects - updated to remove the plan for DSN8ED6. • DSNTINS1: DB2 for OS/390 Install CLIST - modified to customize new sample job DSNTEJ6W

After applying this PTF, you need to perform the following activities: 1. Provide a WLM environment to manage the stored procedures address space where WLM_REFRESH runs. 2. Customize sample job DSNTEJ6W to prepare and test WLM_REFRESH. 3. ) Run DSNTEJ6W.

5.12.5 WLM environment for WLM_REFRESH stored procedure As mentioned in Section 5.12.3, “WLM_REFRESH stored procedure environment” on page 157, the WLM_REFRESH itself must run in a WLM-established stored procedures address space. 1. See Section 9.3.4, “WLM definitions” on page 319 for information about establishing WLM environments for DB2 stored procedures. 2. Create the JCL procedure for the WLM_REFRESH stored procedure address space in the system PROCLIB. Following is an example of a "minimal" procedure for WLM_REFRESH:

158 Cross-Platform DB2 Stored Procedures: Building and Debugging //************************************************************* //* JCL FOR RUNNING A WLM-ESTABLISHED STORED PROCEDURES //* ADDRESS SPAC FOR WLM_REFRESH //* RGN -- THE MVS REGION SIZE FOR THE ADDRESS SPACE. //* DB2SSN -- THE DB2 SUBSYSTEM NAME. //* APPLENV -- THE MVS WLM APPLICATION ENVIRONMENT //* SUPPORTED BY THIS JCL PROCEDURE. //************************************************************* //DSNWLM PROC RGN=0K, // APPLENV=,DB2SSN= //IEFPROC EXEC PGM=DSNX9WLM,REGION=&RGN,TIME=NOLIMIT, // PARM='&DB2SSN,1,&APPLENV' //***All libs concatenated to STEPLIB must be APF-authorized*** //STEPLIB DD DISP=SHR,DSN=.SCEERUN // DD DISP=SHR,DSN=.SDSNEXIT // DD DISP=SHR,DSN=.SDSNLOAD //SYSTSPRT DD SYSOUT=* //SYSPRINT DD SYSOUT=*

5.12.6 Customizing DSNTEJ6W for preparing and testing WLM_REFRESH After applying the PTF, use sample/IVP job DSNTEJ6W to create and test the WLM_REFRESH stored procedure. You can customize DSNTEJ6W for your environment either manually or by using the DB2 Install CLIST. 1. Manual customization of DSNTEJ6W: a. Copy member DSNTEJ6W from the prefix.SDSNSAMP data set to prefix.NEW.SDSNSAMP(DSNTEJ6W). b. Edit prefix.NEW.SDSNSAMP(DSNTEJ6W) and follow the directions in the prologue. 2. Automatic customization of DSNTEJ6W using the DB2 Install CLIST: a. Run the installation CLIST in INSTALL or MIGRATE mode by responding INSTALL or MIGRATE in field 1 of panel DSNTIPA1. b. For the INPUT MEMBER NAME (field 6 on panel DSNTIPA1), use the name of the defaults file in which the defaults for your existing DB2 are stored. (This is probably the name you entered in field 7 on panel DSNTIPA1 when you originally installed or migrated this DB2). c. On panel DSNTIPT, change the data set names in fields 1 and 3 (TEMP CLIST LIBRARY and SAMPLE LIBRARY). This prevents the prefix.NEW.SDSNSAMP and prefix.NEW.SDSNTEMP data sets from your original installation from being overwritten.

Chapter 5. OS/390 Workload Manager 159 d. If you are using DB2 UDB for OS/390 Version 6, do the following: on panel DSNTIPX, in the WLM ENVIRONMENT field, enter the name of the WLM environment that manages the stored procedures address space for WLM_REFRESH (as identified in Section 5.12.5, “WLM environment for WLM_REFRESH stored procedure” on page 158). e. Keep the default values for all the rest of the panels. When this run of the installation CLIST completes, your customized version of the DSNTEJ6W (as well as other jobs) will be in the prefix.NEW.SDSNSAMP data set whose name you entered in field 3 of panel DSNTIPT. f. Copy the just-customized version of DSNTEJ6W to the prefix.NEW.SDSNSAMP data set for your original installation of DB2, and discard the prefix.NEW.SDSNSAMP and prefix.NEW.SDSNTEMP data sets from this run. g. If you are using DB2 for OS/390 Version 5, do the following: Edit DSNTEJ6W and replace all occurrences of the string !WLMENV! with the name of the WLM environment that manages the stored procedures address space for WLM_REFRESH.

The DSNTEJ6W job prepares DSN8ED6, which is a sample caller of WLM_REFRESH. The DSN8ED6 is a C language program. If you do not have a C compiler, you cannot prepare and run DSN8ED6. In that case, you need to remove steps PH06WS05 and PH06WS07 which prepare and run DSN8ED6, and you need to modify step PH06WS06 to bind only the package for DSNTWR.

Refer to the APAR/PTF documentation for more information about running the DSNTEJ6W and for the WLM_REFRESH stored procedure messages.

5.13 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 consisting of one or more MVS systems that reside on one or more processors, and share the same Sysplex couple data sets.

160 Cross-Platform DB2 Stored Procedures: Building and Debugging • 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 do not 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 OS/390 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; they 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 subsystem to MVS.

5.13.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: • 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 (optional but recommended) — ATR.gname.ARCHIVE

Where: gname can be your Sysplex name or any name in a non-Sysplex environmentTo define the RRS log streams, use IXCMIAPU, a utility program provided in the SYS1.MIGLIB system library.

Chapter 5. OS/390 Workload Manager 161 5.13.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.

162 Cross-Platform DB2 Stored Procedures: Building and Debugging 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: //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) /*

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

Chapter 5. OS/390 Workload Manager 163 //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) (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) PREFLIST(CF02.CF01) REBUILDPERCENT(5) STRUCTURE NAME(RRS_ARCHIEVE) INITSIZE(8000) SIZE(16000) PREFLIST(CF02) REBUILDPERCENT(5)

164 Cross-Platform DB2 Stored Procedures: Building and Debugging 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) /*

Chapter 5. OS/390 Workload Manager 165 5.13.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

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

166 Cross-Platform DB2 Stored Procedures: Building and Debugging //* //* 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: //* //* 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.

5.13.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 OS/390, 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.

Chapter 5. OS/390 Workload Manager 167 5.13.5 Starting and stopping RRS Once you have set address space priority, provided the statement in IEFSSNXX, and know that the system logger is active, you can start RRS with the following operator command: START RRS,SUB=MSTR

You can stop RRS with the following operator command: SETRRS CANCEL

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

Notice that RRS abends with S5C4 code. No action is necessary for reason code X’ FFFF2222’.

5.13.6 RRS error samples In this section, we examine some errors that you may encounter and the possible causes: • If RRS cannot find one of the log streams, you get the following error message when starting RRS: 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.

168 Cross-Platform DB2 Stored Procedures: Building and Debugging • 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 5. OS/390 Workload Manager 169 170 Cross-Platform DB2 Stored Procedures: Building and Debugging Chapter 6. OS/390 Recoverable Resource Manager Services

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 OS/390 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 OS/390 system.

6.1 Prerequisite knowledge To use RRSAF, you need some prerequisite knowledge. You must be familiar with the following OS/390 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

6.2 Capabilities of RRSAF applications An application program using RRSAF can: • Use the OS/390 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 OS/390 tasks in an address space. • Switch a DB2 thread among OS/390 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).

© Copyright IBM Corp. 2001 171 • 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.

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

6.4 Programming languages supported RRSAF applications can be written in assembler language, C, COBOL, FORTRAN, and PL/I. If you use OS/390 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.

6.5 Program size Youhavetoplanonestimating10KBto20KBmoreforyourRRSAF 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.

172 Cross-Platform DB2 Stored Procedures: Building and Debugging 6.6 RRSAF use of load RRSAF uses OS/390 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.

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

6.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 detailed explanation of the RRSAF run environment, see “Run environment,” in DB2 UDB for OS/390 Version 6 Application Programming and SQL Guide, SC26-9004.

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

Chapter 6. OS/390 Recoverable Resource Manager Services 173 For information on loading or link-editing this module, see “Accessing the RRSAF language interface” in DB2 UDB for OS/390 Version 6 Application Programming and SQL Guide, SC26-9004.

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

6.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 UDB for OS/390 Version 6 Application Programming and SQL Guide, SC26-9004.

Here is a COBOL example of this command: CALL ‘DSNRLI’ USING IDFYFN SSNM RIBPTR EIBPTR TERMCB STARTECB RETCODE RSNCODE.

Where: • IDFYN — This is an 18-byte area containing IDENTIFY followed by 10 blanks. • SSNM — This 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.

174 Cross-Platform DB2 Stored Procedures: Building and Debugging • RIBPTR — This 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 — This 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 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 — This 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 6.

Table 6. POST codes for types of DB2 terminations POST code Termination type

8 QUIESCE

12 FORCE

16 ABTERM

• STARTECB — This is the address of the application’sstartupECB.IfDB2 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.

Chapter 6. OS/390 Recoverable Resource Manager Services 175 • RETCODE — This 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 — This 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.

6.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 UDB for OS/390 Version 6 Application Programming and SQL Guide, SC26-9004.

Here is a COBOL example of this command: CALL ‘DSNRLI’ USING SIGNONFN CORRID ACCTTKN ACCTINT RETCODE RSNCODE.

Where: • SIGNONFN — This is an 18-byte area containing SIGNON followed by twelve blanks. • CORRID — This 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 — This 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 — This 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.

176 Cross-Platform DB2 Stored Procedures: Building and Debugging 6.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 UDB for OS/390 Version 6 Application Programming and SQL Guide, SC26-9004.

Here is a COBOL example of this command: CALL ‘DSNRLI’ USING ASGNONFN CORRID ACCTTKN ACCTINT PAUTHID ACEEPTR SAUTHID RETCODE RSNCODE.

Where: • ASGNONFN — This is an 18-byte area containing AUTH SIGNON followed by seven blanks. • PAUTHID — This 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 — This 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 — This 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.

6.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 UDB for OS/390 Version 6 Application Programming and SQL Guide, SC26-9004.

Here is a COBOL example of this command: CALL ‘DSNRLI’ USING CRTHRDFN PLAN COLLID REUSE RETCODE RSNCODE.

Where: • CRTHRDFN — This is an 18-byte area containing CREATE THREAD followed by five blanks.

Chapter 6. OS/390 Recoverable Resource Manager Services 177 • PLAN — This 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 — This 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.

6.10.5 TERMINATE THREAD function The TERMINATE THREAD function deallocates the plan. See “TERMINATE THREAD: Syntax and Usage” in DB2 UDB for OS/390 Version 6 Application Programming and SQL Guide, SC26-9004.

Here is a COBOL example of this command: CALL ‘DSNRLI’ USING TRMTHDFN RETCODE RSNCODE.

Where: • TRMTHDFN — This is an 18-byte area containing TERMINATE THREAD followed by two blanks.

6.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” inDB2 UDB for OS/390 Version 6 Application Programming and SQL Guide, SC26-9004.

Here is a COBOL example of this command: CALL ‘DSNRLI’ USING TMIDFYFN RETCODE RSNCODE. • TMIDFYFN — This is an 18-byte area containing TERMINATE IDENTIFY.

178 Cross-Platform DB2 Stored Procedures: Building and Debugging 6.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 UDB for OS/390 Version 6 Application Programming and SQL Guide, SC26-9004.

Here is a COBOL example of this command: CALL ‘DSNRLI’ USING XLATFN SQLCA RETCODE RSNCODE.

Where: • XLATFN — This is an 18-byte area containing the word TRANSLATE followed by nine blanks. • SQLCA — This is the program’sSQLCA.

6.10.8 Sample JCL to use RRSAF Use the sample JCL that follows as a model for using RRSAF in a batch environment. The DD statement for DSNRRSAF starts the RRSAF trace. Use that DD statement only if you are diagnosing a problem. The sample is as follows: //jobname JOB MVS_jobcard_information //RRSJCL EXEC PGM=RRS_application_program //STEPLIB DD DSN=application_load_library DD DSN=DB2_load_library . . //SYSPRINT DD SYSOUT=* //DSNRRSAF DD DUMMY //SYSUDUMP DD SYSOUT=*

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

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

Chapter 6. OS/390 Recoverable Resource Manager Services 179 -JOBNAME STEPNAME PROCSTEP RC EXCP CPU SRB CLOCK SERV P -RRSBMEX STEP01 08 67 .00 .00 .0 2201

PROGRAM ***RRSAFCOB*** STARTED *** RRS/AF IDENTIFY RRSAF ERROR, RETCODE = 00000008 RSNCODE = 15925393

6.11.2 IDENTIFY return code 8 reason code 15925250 When the DB2 subsystem address space is not running, you get a return code 8 from the IDENTIFY function. The reason code returned is 15925250. -JOBNAME STEPNAME PROCSTEP RC EXCP CPU SRB CLOCK SERV P -RRSBMEX STEP01 08 67 .00 .00 .0 2201

PROGRAM ***RRSAFCOB*** STARTED *** RRS/AF IDENTIFY RRSAF ERROR, RETCODE = 00000008 RSNCODE = 15925250

6.11.3 IDENTIFY return code 12 When the SSNM variable has an invalid DB2 subsystem name, a return code 12 is returned from the IDENTIFY function. The reason code returned is 1592554. -JOBNAME STEPNAME PROCSTEP RC EXCP CPU SRB CLOCK SERV -RRSBMEX STEP01 12 67 .00 .00 .0 1993

PROGRAM ***RRSAFCOB*** STARTED *** RRS/AF IDENTIFY RRSAF ERROR, RETCODE = 00000012 RSNCODE = 15925254

6.11.4 CREATE THREAD return code 12 When the PLAN variable has an invalid DB2 plan name, a return code 12 is returned from the CREATE THREAD function. The reason code returned is 1592312. -JOBNAME STEPNAME PROCSTEP RC EXCP CPU SRB CLOCK SERV PG -RRSBMEX STEP01 12 67 .00 .00 .0 2417 0

PROGRAM ***RRSAFCOB*** STARTED *** RRS/AF IDENTIFY *** RRS/AF SIGNON *** RRS/AF CREATE THREAD RRSAF ERROR, RETCODE = 00000012 RSNCODE = 15925312

180 Cross-Platform DB2 Stored Procedures: Building and Debugging Part 3. Accessing non-DB2 resources

© Copyright IBM Corp. 2001 181 182 Cross-Platform DB2 Stored Procedures: Building and Debugging Chapter 7. DB2 stored procedures and CICS

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

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

© Copyright IBM Corp. 2001 183 Since Version 5 DB2 supports RRS, it is possible to have coordination between a DB2/WLM-established stored procedure address space and CICS 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 commit (SRRCMIT), it instructs the CICS transaction to commit. So while there are two commit coordinators (RRS and CICS), it is still a two-phase commit transaction.

During our project, we tested only the EXCI calls. Below we briefly describe how to code calls within a stored procedure.

7.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 address space 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 (Initialize-User, Allocate_Pipe, Open_Pipe, DPL call, Close_Pipe, and Deallocate_Pipe) 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 CICS: Transaction Server for OS/390: CICS External Interfaces Guide, SC33-1944.

Considering a DB2 stored procedure running in the DB2 or in the WLM-established address space, the EXCI commands allow the stored procedure to call a program running in a CICS region. The calling program, in this case the DB2 stored procedure, and the CICS server region (the region where the server program runs or is defined) must be in the same OS/390 image unless: • The CICS region is running in a Sysplex that supports cross-system MRO (XCF/MRO). • All distributed program link (DPL) requests issued by the client program specify the SYNCONRETURN option.

184 Cross-Platform DB2 Stored Procedures: Building and Debugging The advantage of using this architecture is that the server program, in this case the CICS program, can be one used by existing CICS applications and reused externally by any number of stored procedures (see the description of our scenario in Part 7.3, “Application scenario” on page 196).

7.2.1 Preparing CICS for EXCI Calling CICS programs from DB2 stored procedures via EXCI does not require any particular definition in CICS. Stored procedures use EXCI just as a batch job could do.

If you have not activated the External CICS Interface yet, CICS provides a single group, DFH$EXCI, with samples of all the required definitions (connections, sessions, transactions and programs). You can add this group to the GRPLIST of any CICS region and use it as delivered, or create your own group with the required definitions according to your naming conventions.

All the DFH$EXCI connections definitions contain the connection property PROTOCOL(EXCI), as opposed to the typical APPC or LU6.1. You can probably use the SESSIONS definitions in the DFH$EXCI group without modification. The EXCI connections do not require a large number of sessions, because the volume of calling programs will be much less than the usual in a typical CICS transactional environment. The RECEIVECount in the sample SESSIONS contains a value of 9 (see Figure 59 on page 188), which is probably adequate for most users, but this value can be up to 999.

For more information about all of these definitions required for EXCI, refer to CICS Transaction Server for OS/390: CICS External Interfaces Guide, SC33-1944.

Once the preparation is complete, you can develop calling programs, in our scenario stored procedures, to execute code within the CICS region.

7.2.2 CICS table definitions Some definitions on CICS are required to issue EXCI calls. Refer to the CICS: Transaction Server for OS/390: CICS External Interfaces Guide, SC33-1944 for information about how to customize your environment for EXCI. Some EXCI samples are provided with CICS, and you can use them to ensure that your EXCI environment is working.

Chapter 7. DB2 stored procedures and CICS 185 We used these definitions for the following: • Connection (see Figure 57 on page 186 and Figure 58 on page 187) • Sessions (see Figure 59 on page 188, Figure 60 on page 189, and Figure 61 on page 189) • Transaction (see Figure 62 on page 190, Figure 63 on page 190, Figure 64 on page 191, and Figure 65 on page 191) • Program (see Figure 66 on page 192 and Figure 67 on page 193)

Mandatory values are shown in bold.

7.2.2.1 Connection Parameters CONNTYPE(GENERIC) and SINGLESESS(NO) are for multiple users.

OVERTYPE TO MODIFY CICS RELEASE = 0530 CEDA DEFine Connection( XCIG ) Connection : XCIG Group : EXCI DEscription ==> CONNECTION IDENTIFIERS Netname ==> INDsys ==> REMOTE ATTRIBUTES REMOTESYSTem ==> REMOTEName ==> REMOTESYSNet ==> CONNECTION PROPERTIES ACcessmethod ==> IRc Vtam | IRc | INdirect | Xm PRotocol ==> Exci Appc | Lu61 | Exci Conntype ==> Generic Generic | Specific SInglesess ==> No No | Yes DAtastream ==> User User | 3270 | SCs | STrfield | Lms + RECordformat ==> U U | Vb

SYSID=PAA9 APPLID=SCSCPAA9

PF 1 HELP 2 COM 3 END 6 CRSR 7 SBH 8 SFH 9 MSG 10 SB 11 SF 12 CNCL

Figure 57. CICS connection definition (1 of 2)

186 Cross-Platform DB2 Stored Procedures: Building and Debugging OVERTYPE TO MODIFY CICS RELEASE = 0530 CEDA DEFine Connection( XCIG ) + Queuelimit ==> No No | 0-9999 Maxqtime ==> No No | 0-9999 OPERATIONAL PROPERTIES AUtoconnect ==> No No | Yes | All INService ==> Yes Yes | No SECURITY SEcurityname ==> ATtachsec ==> Local Local | Identify | Verify | Persistent | Mixidpe BINDPassword : PASSWORD NOT SPECIFIED BINDSecurity ==> No No | Yes Usedfltuser ==> No No | Yes RECOVERY PSrecovery ==> Sysdefault | None Xlnaction ==> Keep Keep | Force

SYSID=PAA9 APPLID=SCSCPAA9

PF 1 HELP 2 COM 3 END 6 CRSR 7 SBH 8 SFH 9 MSG 10 SB 11 SF 12 CNCL

Figure 58. CICS connection definition (2 of 2)

Chapter 7. DB2 stored procedures and CICS 187 7.2.2.2 Sessions SESSIONS definitions must be in the same group as the CONNECTION definition to which they refer.

OVERTYPE TO MODIFY CICS RELEASE = 0530 CEDA DEFine Sessions( XCIGSESS ) Sessions : XCIGSESS Group : EXCI DEscription ==> SESSION IDENTIFIERS Connection ==> XCIG SESSName ==> NETnameq ==> MOdename ==> SESSION PROPERTIES Protocol ==> Exci Appc | Lu61 | Exci MAximum ==> 000 , 000 0-999 RECEIVEPfx ==> XG RECEIVECount ==> 009 1-999 SENDPfx ==> SENDCount ==> 1-999 SENDSize ==> 04096 1-30720 + RECEIVESize ==> 04096 1-30720

SYSID=PAA9 APPLID=SCSCPAA9

PF 1 HELP 2 COM 3 END 6 CRSR 7 SBH 8 SFH 9 MSG 10 SB 11 SF 12 CNCL

Figure 59. CICS sessions definition (1 of 3)

188 Cross-Platform DB2 Stored Procedures: Building and Debugging OVERTYPE TO MODIFY CICS RELEASE = 0530 CEDA DEFine Sessions( XCIGSESS ) + SESSPriority ==> 000 0-255 Transaction : OPERATOR DEFAULTS OPERId : OPERPriority : 000 0-255 OPERRsl : 0 0-24,... OPERSecurity : 1 1-64,... PRESET SECURITY USERId ==> OPERATIONAL PROPERTIES Autoconnect ==> No No | Yes | All INservice : Yes No | Yes Buildchain ==> Yes Yes | No USERArealen ==> 000 0-255 IOarealen ==> 04096 , 04096 0-32767 RELreq ==> No No | Yes + DIscreq ==> No No | Yes

SYSID=PAA9 APPLID=SCSCPAA9

PF 1 HELP 2 COM 3 END 6 CRSR 7 SBH 8 SFH 9 MSG 10 SB 11 SF 12 CNCL

Figure 60. CICS sessions definition (2 of 3)

OVERTYPE TO MODIFY CICS RELEASE = 0530 CEDA DEFine Sessions( XCIGSESS ) + NEPclass ==> 000 0-255 RECOVERY RECOVOption ==> Sysdefault Sysdefault | Clearconv | Releasesess | Uncondrel | None RECOVNotify : None None | Message | Transaction

SYSID=PAA9 APPLID=SCSCPAA9

PF1HELP2COM3END 6CRSR7SBH8SFH9MSG10SB11SF12CNCL

Figure 61. CICS sessions definition (3 of 3)

Chapter 7. DB2 stored procedures and CICS 189 7.2.2.3 Transaction

OVERTYPE TO MODIFY OR PRESS ENTER TO EXECUTE CICS RELEASE = 0530 CEDA DEFine TRANSaction( EXCI ) TRANSaction ==> EXCI Group ==> DFH$EXCI DEscription ==> PROGram ==> DFHMIRS TWasize ==> 00000 0-32767 PROFile ==> DFHCICSA PArtitionset ==> STAtus ==> Enabled Enabled | Disabled PRIMedsize : 00000 0-65520 TASKDATALoc ==> Any Below | Any TASKDATAKey ==> User User | Cics STOrageclear ==> No No | Yes RUnaway ==>System System|0|500-2700000 SHutdown ==> Disabled Disabled | Enabled ISolate ==> Yes Yes | No Brexit ==> + REMOTE ATTRIBUTES

SYSID=PAA9 APPLID=SCSCPAA9

PF1HELP2COM3END 6CRSR7SBH8SFH9MSG10SB11SF12CNCL

Figure 62. CICS transaction definition (1 of 4)

OVERTYPE TO MODIFY OR PRESS ENTER TO EXECUTE CICS RELEASE = 0530 CEDA DEFine TRANSaction( EXCI ) + DYnamic ==> No No | Yes ROutable ==> No No | Yes REMOTESystem ==> REMOTEName ==> TRProf ==> Localq ==> No | Yes SCHEDULING PRIOrity ==> 001 0-255 TClass : No No | 1-10 TRANClass ==> DFHTCL00 ALIASES ALias ==> TASKReq ==> XTRanid ==> TPName ==> ==> + XTPname :

SYSID=PAA9 APPLID=SCSCPAA9

PF1HELP2COM3END 6CRSR7SBH8SFH9MSG10SB11SF12CNCL

Figure 63. CICS transaction definition (2 of 4)

190 Cross-Platform DB2 Stored Procedures: Building and Debugging OVERTYPE TO MODIFY OR PRESS ENTER TO EXECUTE CICS RELEASE = 0530 CEDA DEFine TRANSaction( EXCI ) +: : RECOVERY DTimout ==> 0010 No | 1-6800 RESTart ==> No No | Yes SPurge ==> No No | Yes TPUrge ==> No No | Yes DUmp ==> Yes Yes | No TRACe ==> Yes Yes | No COnfdata ==> No No | Yes INDOUBT ATTRIBUTES ACtion ==> Backout Backout | Commit WAIT ==> Yes Yes | No WAITTime ==> 00 , 00 , 00 0-99 (Days,Hours,Mins) INdoubt : Backout Backout | Commit | Wait SECURITY + RESSec ==> No No | Yes

SYSID=PAA9 APPLID=SCSCPAA9

PF1HELP2COM3END 6CRSR7SBH8SFH9MSG10SB11SF12CNCL

Figure 64. CICS transaction definition (3 of 4)

OVERTYPE TO MODIFY OR PRESS ENTER TO EXECUTE CICS RELEASE = 0530 CEDA DEFine TRANSaction( EXCI ) + CMdsec ==> No No | Yes Extsec : No No | Yes TRANSec : 01 1-64 RSl : 00 0-24 | Public

SYSID=PAA9 APPLID=SCSCPAA9

PF1HELP2COM3END 6CRSR7SBH8SFH9MSG10SB11SF12CNCL

Figure 65. CICS transaction definition (4 of 4)

Chapter 7. DB2 stored procedures and CICS 191 7.2.2.4 Program CICS autoinstall will autoinstall program definitions, therefore, the program definition is not required if CICS program autoinstall is active.

OVERTYPE TO MODIFY OR PRESS ENTER TO EXECUTE CICS RELEASE = 0530 CEDA DEFine PROGram( BOUNCE ) + REMOTEName ==> Transid ==> EXCI EXECUtionset ==> Fullapi Fullapi | Dplsubset JVM ATTRIBUTES JVM ==> No No | Yes | Debug JVMClass ==> ==> ==> ==> ==>

SYSID=PAA9 APPLID=SCSCPAA9

PF1HELP2COM3END 6CRSR7SBH8SFH9MSG10SB11SF12CNCL

Figure 66. CICS program definition

7.2.3 Preparing stored procedure for EXCI If you plan to write stored procedures in COBOL, as we did in our scenario, you have to compile them using the Language Environment (LE)/370 libraries. This requirement means that the LE/370 run library must be in the stored procedure address space (DB2 or WLM-established) STEPLIB concatenation (see 1 in Figure 67).

Also, because the stored procedures run only in those address spaces, the application load library where the stored procedure load module resides must be part of the STEPLIB concatenation (see 2 in Figure 67).

Using EXCI stored procedures, the stored procedure address space must have the CICS load library (SDFHEXCI) in its concatenation and security access to any of the necessary CICS regions (see 3 in Figure 67).

192 Cross-Platform DB2 Stored Procedures: Building and Debugging //DBZ2WLM2 PROC RGN=0K,APPLENV=DBZ2WLM2,DB2SSN=DBZ2,NUMTCB=8 //IEFPROC EXEC PGM=DSNX9WLM,REGION=&RGN,TIME=NOLIMIT, // PARM='&DB2SSN,&NUMTCB,&APPLENV' //STEPLIB DD DISP=SHR,DSN=DB2V61Z1.RUNLIB.LOAD // DD DISP=SHR,DSN=DSN610.SDSNLOAD // DD DISP=SHR,DSN=CEE.SCEERUN 1 // DD DISP=SHR,DSN=SG245485.WORKING.LOADLIB 2 // DD DISP=SHR,DSN=CICSTS13.CICS.SDFHEXCI 3 //SYSPRINT DD SYSOUT=* //CEEDUMP DD SYSOUT=* /*

Figure 67. WLM-established address space

All stored procedures must conform to a few programming specifications, the most important one is that they must use COBOL compile options EXCI and COBOL2. The source code shown in 7.3.1, “Sample stored procedure” on page 198 has as initial statement: — CBL XOPTS(EXCI,COBOL2) — which is added at compile time to ensure that these options become part of the module. In addition, note that the EXCI call to connect CICS — EXEC CICS LINK PROGRAM... — ends without SYNCONRETURN. This is because with CICS TS 1.3, the OS/390 Resource Recovery Services (RRS) coordinates the updates of the EXCI client and the CICS server program (for more information refer to the CICS: Transaction Server for OS/390: CICS External Interfaces Guide, SC33-1944).

The stored procedure must also contain a — COPY DFHXCPLO — statement, which is resolved at compile time from the CICS library SDFHCOB — CICSTS13.CICS.SDFHCOB. This statement copies in the required COBOL return codes that can be encountered during execution. There are corresponding copybooks for the other programming languages (Refer to The EXCI CALL interface chapter in CICS External Interfaces Guide).

When compiling the stored procedure, you must first use to compile LE/370 LOADLIB in the concatenation (see 7.3.3, “Program preparation for EXCI” on page 201). If you are using a DB2 established address space, the link step uses DB2 CAF (DSNALI) instead of the normal TSO application interface (DSNELI). If you are using the WLM-established address space, the link step uses DB2 CAF (DSNRLI). Stored procedures that contain SQL statements must be bound as a package to be executed.

If the stored procedure is called remotely, the client program must have a package on the DB2 system where the stored procedure executes, meaning a remote bind of the client program is required. In such a case, the stored procedure collection does not need to be included in the client plan.

Chapter 7. DB2 stored procedures and CICS 193 Many people use the DISPLAY function in the stored procedure or the client program, especially during development, to get visual feedback of the values stored or passed during execution. In our scenario we are using the IBM SPB as a client to test the stored procedure. The advantage is that we do not need to have a client program to test the execution of the stored procedure.

Figure 23 and Figure 24, respectively, show the input and output testing an stored procedure. This is a stored procedure with only one input parameter, that is informed in the first screen. It has one output parameter and two result sets as you can see in the second screen.

Figure68.TestingastoredprocedurefromtheSPB(input)

194 Cross-Platform DB2 Stored Procedures: Building and Debugging Figure 69. Testing a stored procedure from the SPB (output)

7.2.3.1 Sysplex exploitation Although it may appear that the example used in our scenario uses a DB2 WLM SPAS and target CICS region on the same OS/390 image (LPAR), that is actually not the case. The DB2 WLM SPAS exists on one OS/390 image and the CICS region on another.

As mentioned before, the advantage of this implementation is that you can reuse code and produce flexible solutions wherever the data and applications are located. If multiple OS/390 images are connected in a Sysplex configuration with all required software and hardware, the stored procedure could execute on one LPAR and connect to a CICS region on another LPAR via cross system Coupling Facility (XCF) connections.

Chapter 7. DB2 stored procedures and CICS 195 EXCI cannot run across OS/390 images in a Sysplex if you are using Transaction EXCI (that is, with RRS). This means that you cannot use EXEC CICS LINK (without SYNCONRETURN), from an EXCI client in one image to a CICS region in another image.In effect, the data and application are location independent and, therefore, available regardless of where the request initiates.

To determine if the CICS region is connected and available to any OS/390 LPAR, issue the command D XCF,GROUP,DFHIR000. This command will display all CICS regions defined to the Coupling Facility in the DFHIR000 group and, therefore, available as a target to the stored procedure. CICS adds the entries to the DFHIR000 group it is not something that a user has to concern themselves with. More important is that the number of slots in this group is limited by the MAXMEMBER parameter defined in the XCF Sysplex couple data set. This can only go up to 1023, and the current setting can be displayed using the command /D XCF,COUPLE.

The name SCSCPAA9 in bold that you see in Figure 70 is the name of the CICS region in our scenario.

Display Filter View Print Options Help ------SDSF ULOG CONSOLE DB2RES2 LINE COMMAND ISSUED COMMAND INPUT ===> /D XCF,GROUP,DFHIR000 SCROLL ===> CSR RESPONSE=SC61 IXC332I 14.15.56 DISPLAY XCF 656 GROUP DFHIR000: SCSCPAAS SCSCPAAV SCSCPAAY SCSCPAAZ SCSCPAA1 SCSCPAA6 SCSCPAA8 SCSCPAA9 SCSCPAGV SCSCPCA1 SCSCPCB1 SCSCPWA1

Figure 70. Display command to see CICS regions defined to the Coupling Facility

7.3 Application scenario One of the major benefits of using stored procedures is code reuse. There are many opportunities to use stored procedures, and one of them is calling a CICS program through EXCI. For example, a CICS program already in production can be reused for a new application, being called from another platform using stored procedures.

As in our scenario (see Figure 71 on page 197), the CICS program BOUNCE, on the one hand it is called from a stored procedure XC0BMS and for another from a CICS transaction.

196 Cross-Platform DB2 Stored Procedures: Building and Debugging OS/390 DB2 WLM CICS

SYSIBM XC0BMS SYSROUTINES BOUNCE

CLIENT SPB in our case

CICS TRANSACTION CLIENT LU 0, LU 6.2 ...

Figure 71. Application scenario.

In our scenario, the client program calls the stored procedure example XC0BMS (refer to the sample listing in 7.3.1, “Sample stored procedure” on page 198), passing two parameters. The first parameter (PARM1) is used to specify in which CICS the program BOUNCE, called by XC0BMS, should be run. The second parameter (PARM2) is used as a communication area between the client program and BOUNCE.

As this very simple program does nothing but returning the value “bounce”, the client program should receive this value in PARM2 if the call is completed successfully. Otherwise, if the call could not be completed, this parameter receives an error return code. Additionally, whenever a successful call to BOUNCE is executed, XC0BMS inserts a new row, with the value “bounce” in a DB2 table.

In this case, the information is passed back to the client and is available in the working storage field used for the call. From here the client program could call other programs, call additional stored procedures, or write a report.

Chapter 7. DB2 stored procedures and CICS 197 7.3.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. EXEC SQL INCLUDE RESULT END-EXEC.

01 LINK-ERROR PIC X(6) VALUE 'ERROR '. *======* * DECLARE CALL LEVEL,DPL, AND EXEC LEVEL RETURN CODE AREAS. * *======* COPY DFHXCPLO. *======* * INITIALISE TARGET INFORMATION VARIABLES. * *======* 01 TARGET-PROGRAM PIC X(8) VALUE 'BOUNCE '. 01 TARGET-TRANSID PIC X(4) VALUE 'EXCI'. 01 TARGET-SYSTEM PIC X(8). *======* * DEFINE COMMAREA STRUCT. * *======* 01 COMMAREA. 05 FILE-NAME PIC X(6) VALUE SPACES. *======* * INITIALISE 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). 01 EXEC-LEVEL-MSG. 05 EXEC-LEVEL-MSG-TEXT PIC X OCCURS 128 TIMES.

198 Cross-Platform DB2 Stored Procedures: Building and Debugging PROCEDURE DIVISION USING PARM1, PARM2. MOVE PARM1 TO TARGET-SYSTEM. MOVE PARM2 TO COMMAREA. *======* * * * SECTION-1: 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) END-EXEC.

IF EXEC-RESP IS EQUAL TO ZERO THEN MOVE COMMAREA TO PARM2 EXEC SQL INSERT INTO RESULT (PROC, RES, DT) VALUES ('XC0BMS', :PARM2, CURRENT TIMESTAMP) END-EXEC ELSE MOVE LINK-ERROR TO PARM2 END-IF.

GOBACK.

Chapter 7. DB2 stored procedures and CICS 199 7.3.2 Sample CICS program The following example shows a called CICS program 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:

IDENTIFICATION DIVISION. PROGRAM-ID. BOUNCE.

********************************************************** * THIS PROGRAM TEST LINK OF USER KEY PROGRAM TO CICS KEY * **********************************************************

ENVIRONMENT DIVISION. DATA DIVISION. WORKING-STORAGE SECTION. 77 JUNK PIC X(40).

LINKAGE SECTION. 01 DFHCOMMAREA. 02 KEY-HIT PIC X(6).

PROCEDURE DIVISION. SEND-RTN. MOVE 'BOUNCE' TO KEY-HIT. EXEC CICS RETURN END-EXEC. GOBACK.

200 Cross-Platform DB2 Stored Procedures: Building and Debugging 7.3.3 Program preparation for EXCI The following example shows the JCL used to prepare the stored procedure in DB2 v6. //DB2RES2C JOB (999,POK),'DBZ1 INSTALL',CLASS=A,MSGCLASS=T, // NOTIFY=&SYSUID.,TIME=1440,REGION=0M /*JOBPARM L=9999,SYSAFF=SC61 // JCLLIB ORDER=(DSN610.PROCLIB) //* //DFHYXTVL PROC SUFFIX=1$, Suffix for translator module // INDEX='CICSTS13.CICS', Qualifier(s) for CICS libraries // LE370HLQ='CEE', Qualifier(s) for LE/370 libraries // OUTC=A, Class for print output // REG=4M, Region size for all steps // LNKPARM='AMODE(31),RMODE(ANY),LIST,XREF', //* Application // APPLSRC='SG245485.WORKING.FTE', // APPLCOPY='SG245485.WORKING.COPYS', // APPLDBRM='SG245485.WORKING.DBRMLIB', // PROGLIB='SG245485.WORKING.LOADLIB', // MBR=XC0BMS, //* Link edit parameters // WORK=SYSDA Unit for work datasets //* //* This procedure is used to translate,compile and linkedit //* batch application programs using the external CICS //* interface (EXCI). //* //* The procedure contains 4 steps //* 1. Exec the COBOL translator //* (using the supplied suffix 1$) //* 2. Exec the AD/Cycle VS COBOL II compiler //* 3. Reblock SDFHMAC(DFHEXLI) for use by the linkedit step //* 4. Linkedit the output to dataset &PROGLIB //* //* The following JCL should be used //* to execute this procedure //* //* //APPLPROG EXEC DFHEXTVL //* //TRN.SYSIN DD * //* . //* . Application program //* . //* /* //* //LKED.SYSIN DD * //* NAME anyname(R) //* /*

Chapter 7. DB2 stored procedures and CICS 201 //* //* Where anyname is the name of your application program. //* (refer to the system definition guide for full details.) //* //* DB2 //PC EXEC PGM=DSNHPC, // PARM=('HOST(COB2),APOST,SOURCE,XREF') //STEPLIB DD DSN=DSN610.SDSNLOAD,DISP=SHR //DBRMLIB DD DISP=SHR,DSN=&APPLDBRM.(&MBR.) //SYSCIN DD DSN=&&DSNHOUC,DISP=(MOD,PASS), // UNIT=SYSDA,SPACE=(800,(500,500)) //SYSLIB DD DSN=&INDEX..SDFHCOB,DISP=SHR // DD DISP=SHR,DSN=&APPLCOPY. //SYSPRINT DD DSN=&&SYSPRIC1,UNIT=SYSDA, // SPACE=(CYL,(5,5)), // DCB=(RECFM=FBA,LRECL=121,BLKSIZE=0),DISP=(,PASS) //SYSTERM DD SYSOUT=(*,,F443),FCB=F810,CHARS=TA08 //SYSUDUMP DD SYSOUT=(*,,F443),FCB=F810,CHARS=TA08 //SYSUT1 DD SPACE=(800,(500,500),,,ROUND),UNIT=SYSDA //SYSUT2 DD SPACE=(800,(500,500),,,ROUND),UNIT=SYSDA //SYSIN DD DISP=SHR,DSN=&APPLSRC.(&MBR.) //* //* CICS //TRN EXEC PGM=DFHECP&SUFFIX, // PARM='COBOL2,EXCI', // 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)) //SYSIN DD DSN=&&DSNHOUC,DISP=(OLD,DELETE) <--- FROM DB2 PRECOMPILE //* //* COBOL //COB EXEC PGM=IGYCRCTL,REGION=®, // PARM='NODYNAM,LIB,OBJECT,RENT,RES,APOST,MAP,XREF' //STEPLIB DD DSN=CEE.SCEELKED,DISP=SHR //SYSLIB DD DSN=&INDEX..SDFHCOB,DISP=SHR // DD DSN=&INDEX..SDFHMAC,DISP=SHR // DD DSN=&INDEX..SDFHSAMP,DISP=SHR // DD DISP=SHR,DSN=&APPLCOPY. //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))

202 Cross-Platform DB2 Stored Procedures: Building and Debugging //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 // DD DISP=SHR,DSN=CICSTS13.CICS.SDFHLOAD // DD DISP=SHR,DSN=CEE.SCEECICS // DD DISP=SHR,DSN=CEE.SCEERUN // DD DISP=SHR,DSN=DSN610.SDSNLOAD //SYSLMOD DD DSN=&PROGLIB.(&MBR.),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 //SYSIN DD DUMMY // PEND //* //APPLPROG EXEC DFHYXTVL //LKED.SYSIN DD * INCLUDE SYSLIB(DSNRLI) NAME XC0BMS(R) /* /*------

Chapter 7. DB2 stored procedures and CICS 203 We used the sample DFHYXTVL procedure to prepare the batch program with EXCI calls (refer to The CICS-supplied procedures for the external CICS interface in the CICS External Interface Guide). We included one step for the DB2precompiler(seestepPCinthisexample).ForthisJCLsampleweused DFHYXTVL as an in-stream procedure. This procedure is supplied in the CICSTS13.CICS.SDFHPROC library.

Notes: 1. This example shows the correct order of the libraries in the SYSLIN DD in the LKED (linkedit) step. It is different from the order in the DFHYXTVL JCL provided in the SDFHPROC (in our case, CICSTS13.CICS.SDFHPROC). When you run your stored procedure, if you do not have the right order, you might receive sqlcode -927: “The Language Interface (LI) was called when the connecting environment was not established. The program should be invoked under the DSN command.”

2. You might receive reason code 00E79006 when you run the stored procedure. If you look at the WLM address space which executed this stored procedure, you will probably find the following additional information: +DSNX962I DSNX9WLS THE LE/370 CEEPIPI SERVICE RETURNED AN UNEXPECTED RETURN CODE '0000000C'X FOR FUNCTION ADD_ENTRY SSN= DBZ2 PROC=DBZ2WLM2 ASID= 01FC WLM_ENV= DBZ2WLM2 This error might occur because your module was not linked with the needed Language Environment modules during the linkedit step. To solve this problem, linkedit the load module again and make sure that the CEESTART module is included in.

204 Cross-Platform DB2 Stored Procedures: Building and Debugging Chapter 8. DB2 stored procedures and IMS

With the growth of e-business, companies with IMS systems seek to Web-enable their investments. There are several ways to Web-enable access to IMS applications and IMS databases, depending on the needs of the organization: • Writing new IMS Java applications using the IMS Java classes for JDBC IMS database access • Using CICS transactions to access IMS databases: - Java - CICS Web Interface - CICS transactions - DBCTL - IMS DB - Java - CICS Transaction Gateway - CICS transactions - DBCTL - IMS DB • Accessing IMS databases through the use of IMS Open Database Access (ODBA), without the need for an IMS transaction manager or CICS • Invoking (existing) IMS transactions from outside IMS transaction manager (TM) using IMS Open Transaction Manager Access (OTMA), without having to code for IMS database access. For example: - Using IMS Connect to access OTMA from TCP/IP to invoke IMS transactions - Using Java - MQSeries - MQ Bridge to OTMA to invoke IMS transactions

Table 7 summarizes the different types of IMS and indicates whether we can use OTMA and ODBA with each.

Table 7. IMS types IMS Transaction Database (DB) Use OTMA Use ODBA Type Manager (TM)

DB/DC Yes Yes Yes Yes

DBCTL Yes Yes

DCCTL Yes Yes

This chapter deals specifically with access to IMS databases. For information regarding the other two types of IMS access mentioned, please refer to the IMS homepage, http://www.software.ibm.com/data/ims,aswellastheIBM Redbook, IMS e-business Connect Using the IMS Connector, SG24-5427.

© Copyright IBM Corp. 2001 205 For this chapter In this chapter, the term “IMS system” refers to either an IMS DC or an IMS DBCTL environment. IMS manuals are referred to by their title in your release of IMS unless otherwise stated. Use of the forward slash “/” character: When entering MVS commands via SDSF, we need to prefix the command with a forward slash “/”. This is not to be confused with the forward slash which is part of the IMS command syntax, for example: /DISPLAY

8.1 Accessing IMS databases There are a variety of ways to access IMS databases, each with different syncpoint coordinators. Table 8 summarizes these different approaches and how syncpoint is coordinated. Table 8. Ways to access IMS database Details Syncpoint coordinator

ODBA Using the database resource adapter RRS is the syncpoint coordinator and (DRA) callable interface manager: DB2 uses RRS and issues commits to RRS.

IMS TM As a transaction, a batch message IMS TM, except for batch DL/I processing (BMP) program, a message programs, which runs under their own processing program (MPP), an IMS copies of the IMS control region. Fast Path (IFP) program or as batch. IMSisincontrolineverycase.InBMP and in batch, you are running DFSRRC00, which sets up the IMS control blocks for the application program.

CICS / CICS EXCI CICS defined to IMS like a subsystem, For DBCTL, CICS is the coordinator. using the DRA startup table. IMS is in IMS is a CICS resource manager. control of coordinating syncpoints. We can also use the EXCI interface as described in Chapter 7, “DB2 stored procedures and CICS” on page 183.

206 Cross-Platform DB2 Stored Procedures: Building and Debugging Details Syncpoint coordinator

APPC Use APPC to invoke an IMS or a CICS Includes APPC code in the stored transaction procedure. An IMS or CICS transaction can be invoked by APPC.

MQI - CICS MQSeries using the MQ Interface (MQI) CICS to access CICS transaction.

MQI - OTMA- IMS MQSeries using the MQ Interface (MQI) IMS to place a transaction on the IMS message queue.

8.2 What is ODBA? IMS ODBA provides access to full function (FF) IMS databases and Fast Path (FP) IMS Data Entry Databases (DEDB) without the need to run IMS Transaction Manager (IMS TM) or CICS as a transaction manager. Instead ODBA uses OS/390 Recoverable Resource Services (RRS) to coordinate syncpoints.

An ODBA application uses the ODBA callable interface to access databases managed by an IMS Database Manager (IMS DB) subsystem. ODBA uses the IMS DRA function to establish a connection to the IMS subsystem specified by the IMSID/DBCTLID coded in the DRA startup table. This whole mechanism is also known as the DRA.

ODBA consists of a startup table for each IMS system, and a group of modules that make up the ODBA callable interface.

The DRA startup table specifies how to connect to a particular IMS subsystem, for example, the subsystem name and how many threads are allowed.

The ODBA callable interface modules manage threads connecting an ODBA application to an IMS system, as well as providing some recovery services. They provide a set of DL/I database calls and system services calls. Application programs establish connections to IMS systems and make IMS database and system function calls using AERTDLI, whose syntax is very similar to the IMS language interface module (DFSLI000, ASMTDLI, CBLTDLI, PLITDLI).

Chapter 8. DB2 stored procedures and IMS 207 ODBA requires the use of the Application Interface Block (AIB). The AIB is a storage area obtained by the application program, and is passed to IMS as a parameter in the AERTDLI call list when the application program issues DL/I calls. For ODBA, the AIB also provides the area the application program uses to keep track of the thread token.

ODBA applications use RRS application programming interfaces (APIs) to invoke commit processing.

However, since we cannot code COMMITs in DB2 stored procedures, commit processing is invoked either by the client program, or when we have COMMIT ON RETURN in the stored procedure definition.

8.3 Using DB2 stored procedure in conjunction with ODBA Depending on the method and the level of product you use, you can have different degrees of: • Commitment control • Complexity of the code • Performance

When you run DB2 stored procedures with ODBA, the WLM-established stored procedure address space already does some of the initialization and later on, some cleaning up, on your behalf.

With DB2 stored procedures, 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 the following sections, we describe how to use DB2 stored procedures with ODBA.

208 Cross-Platform DB2 Stored Procedures: Building and Debugging 8.3.1 ODBA architecture Figure 72 describes the architecture of DRA. The callable interface resides in the WLM-established DB2 stored procedures address space which is recognized by IMS as an application execution region (AER).

OS/390 Application AS IMS Address Spaces FP DEDB DB2 SPAS D

DSNX9WLM R

M

M

T T

Stored A DFSAERG0 DFSAERM0 DFSAERA0 FF AIB PST proc DL/I

Stored AIB

S S DBRCDBRC AERTDLI PST

(DFSCDLI0) A

proc A

S S Control Region

Control Region

I I /

AIB / L FF Stored L

PST D proc D DL/I OS/390 RRS

Figure 72. DRA architecture in a DB2 stored procedures context

The DRA maintains threads. The DFSPRP macro from the IMS macro library sets up the parameters for the DRA startup table.

The DRA is also used by coordinator controllers (CCTL) such as CICS. A CCTL is a subsystem consisting of the DRA and a transaction management subsystem. A CCTL provides communications and transaction management services for a DBCTL environment, which has no transaction management facilities of its own.

Using the ODBA-callable interface the stored procedure can access 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.

For a description of the IMS DRA-callable interface modules DFSAERG0, DFSAERM0 and DFSAERA0, refer to the IMS/ESA Release Planning Guide, GC26-8744.

Chapter 8. DB2 stored procedures and IMS 209 When the DB2 stored procedures address space starts up, the presence of a DFSRESLB DD statement causes DSNX9WLM, which is the DB2 stored procedure address space, to issue a CIMS INIT command without specifying a DRA startup table. A DB2 stored procedure accesses an IMS subsystem region by specifying a 1-4 byte identifier which makes up the DRA startup table name, and a PSB name to schedule, in an APSB call. This establishes a thread to IMS, and ODBA returns a thread token associated with this thread. All subsequent IMS calls need to refer to this thread token.

Note An ODBA program can also specify the DRA startup table name during a CIMS INIT call. However, the WLM DB2 stored procedure address space already calls CIMS INIT when it starts up to initialize the ODBA environment. It cannot specify the DRA table because it does not know, in advance, which IMS the stored procedure wants to connect to.

When we have finished processing, the stored procedure issues a DPSB call with ‘PREP’ subfunction, again using the thread token. For WLM goal mode, the quiesce command /vary wlm,applenv=...,quiesce causes the DSNX9WLM program to issue a CIMS TALL command which cleans up the ODBA environment.

Section 8.10, “DB2 ODBA stored procedures explained” on page 240 describes this in more detail.

8.4 Considerations for using ODBA Here we describe design considerations and software prerequisites for ODBA.

8.4.1 What types of IMS can DB2 ODBA SPs connect to? A stored procedure using ODBA can use the DL/I services of an IMS DB/DC or DBCTL control region. It is common for CICS users to have a stand-alone DBCTL system. But IMS does allow CCTL connections to a DB/DC system.

For this project we used a stand-alone DBCTL system.

210 Cross-Platform DB2 Stored Procedures: Building and Debugging 8.4.2 Limitations of ODBA programming ODBA programs must execute on the same MVS image (LPAR) as the IMS system(s).

GSAM databases are allocated by the dependent region (local), not by IMS subsystem. GSAM databases are not allowed for ODBA.

8.4.3 Multiple access to IMS subsystems Provided that we have coded the DRA startup table so that we can have more than 1 thread concurrently (maxthd > 1), it is the application programmer’s responsibility to keep track of each thread token after every APSB call in our stored procedure by using the AIB.

8.4.4 Refreshing WLM application environments Application developer and testers will often need to refresh, resume and quiesce WLM application environments. One way to doing this is by using the MVS command VARY. Most sites restrict the use of commands.

An alternative may be to consider using the sample stored procedure WLM_REFRESH to refresh a WLM environment from a remote location. This sample is delivered via PTFs UQ47799 (DB2 V5) and UQ47800 (DB2 V6).

8.4.5 Software prerequisites ODBA uses RRS to coordinate syncpoint. For DB2 stored procedures to use ODBA, we need the RRS support. This means we need to: • Be running at least DB2 v5 which provides WLM SPAS support • Have RRS running • Have WLM set up • Be using Language Environment (LE) for our external stored procedures

8.4.5.1 IMS and DB2 maintenance The IMS-supplied ODBA callable interface allows an OS/390 application execution environment (AEE), such as a stored procedures address space, access to IMS database through the IMS DBCTL system.

This facility was introduced into IMS Version 6 via an APAR (PQ15784). It is part of the base function of IMS Version 7.

IMS Version 6 requires the following APARS / PTFs:

Chapter 8. DB2 stored procedures and IMS 211 • UQ26690 • UQ30900 • UQ30901 • UQ31515 • UQ38712 • UQ42850 • UQ46670 • UQ40575 • UQ44482 • UQ46670

ODBA support: • PTF UQ22187

Preconditioning, to allow follow on service that introduces IMS functions OTMACI and ODBA: • PTF UQ22097

IMS Version 7 requires the following APARS / PTFs • PQ38545 and PQ37325 are still in OPEN status

DB2 for OS/390 Version 5 • PTF UQ24296 • PTF UQ26564 — DB2 ODBA stored procedure example

DB2 for OS/390 Version 6 • PTF UQ28826 • Outstanding APAR PQ38316 for sample DSN8EC1

In this redbook, we are working with IMS Version 6, running WLM in goal mode and OS/390 v2r8.

8.4.6 Miscellaneous questions and answers The following sections present some commonly asked questions about setting up ODBA.

8.4.6.1 Number of TCBs ODBA itself creates a connection manager TCB and it creates a TCB for each IMS it connects to. For example, if it attaches to two IMS systems, there will be three TCBs. These TCBs are all created and managed by ODBA, not by the stored procedure or the stored procedure address space. Your ODBA program attaches to these TCBs.

212 Cross-Platform DB2 Stored Procedures: Building and Debugging When you are setting up the WLM SPAS, you do not have to account for these TCBs when specifying the NUMTCB parameters passed to the stored procedures address space during initialization.

8.4.6.2 How to set up DB2 supplied ODBA sample SP To run DSNTEJ62, you must update the PSB source for DFSIVP6 and add a name TELEPCB1 to the DB PCB (using the label field or PCBNAME=TELEPCB1).

8.5 Getting started with ODBA and DB2 stored procedure: step by step The following sections describe how to implement a DB2 stored procedure to access an IMS system through the ODBA. This redbook includes samples that access IMS DB PCB and also IMS IOPCB (ICMD). Samples are described in Appendix B, “DB2 and IMS ODBA samples” on page 487 and are available for download as described in Appendix C, “Using the additional material” on page 493. We assume we already have a DB2 subsystem and an IMS system up and running.

The tasks can be broken up into the following areas: 1. Setting up ODBA for the IMS subsystem. This is done by customizing the DRA startup table. It enables DB2 stored procedures and other applications to use ODBA for this IMS subsystem. 2. Setting up the DB2 stored procedure address space for ODBA. This includes setting up a new WLM-established DB2 stored procedure address space, or modifying an existing one. It can also involve setting up a new WLM application environment for this address space. 3. Building the stored procedure. Compile, linkedit, and bind (if the stored procedure contains SQL statements). Define the stored procedure to DB2 using a CREATE PROCEDURE SQL statement. 4. Defining the application program (which is our stored procedure) to IMS. This includes building the required IMS control blocks: DBD, PSB and ACB; and MODBLKS gen, which are part of stage 1 and stage 2 IMS gen, and security gen; online copy into inactive libraries, and online change to swap in the changed control blocks.

We have two examples to illustrate the first 3 steps. These examples do not require setting up any new IMS DBD or PSB, provided you already have a suitable PSB to use.

Chapter 8. DB2 stored procedures and IMS 213 The first stored procedure retrieves a root segment from a PSB / PCB and an IMS system which you specify by running the stored procedure builder. We invoke our stored procedures using the SPB. Refer to Section 8.11, “Sample DB2 ODB2 stored procedure scenarios” on page 266 for a description of how we use our sample stored procedures to explore DB2 ODBA behavior.

The second stored procedure uses an IOPCB to issue ICMD calls. We discuss how to terminate a DB2 ODBA stored procedure address space, and share our experience of problem determination.

Section 8.12, “Defining IMS resources” on page 274 contains our third example. We follow the same steps as the first example. In addition, we go through the steps to create a new database and the necessary IMS control blocks so that a program can access our database. We load data into our test IMS database.

An excellent source of general IMS information is found in The IMS Primer, SG24-5352. For a sequence of the steps we take, we refer to Appendix B, “INSTALL/IVP JOBs and TASKs” in the manual, IMS Installation Volume 1: Installation and Verification, GC26-8736.

Table 9 summarizes the steps taken to create our test environment. The first part of the table shows the prerequisites for the ODBA.

While some of the jobs are taken straight from the IMS V6 installation verification program (IVP), and may need some tailoring in your environment, they are included to give an idea what was run in our environment. You can use IMS V7 IVP as a reference also.

The overview column gives a concise description of the task. The detail column gives cross references to more in depth description of the task. The IVP job name column specifies the corresponding installation verification job that perform each of the tasks. These jobs are delivered in IMS.INSTALIB. The underscore character is used as in the Appendix B in IMS/ESA Installation Volume 1: Installation and Verification, GC26-8736 where 2 is for aDBCTLsystemand3forDB/DCsystem.

The sample job name refers to member names in SG245485.SAMPLES.JCL delivered with this redbook. Some jobs are consolidated into one longer job in the sample.

The sample source member column gives you the member name in SG245485.SAMPLES.SOURCE where appropriate. These source members are often modelled on IMS IVP source members in IMS.DFSISRC (V6) or IMS.SDSFISRC (V7).

214 Cross-Platform DB2 Stored Procedures: Building and Debugging Sources reside in SG245485.SAMPLES.SOURCE and jobs reside in SG245485.SAMPLES.JCL data sets. Where there is mention of a corresponding IMS IVP job, source refers to the DFSISRC (SDFSISRC) data set and jobs reside in INSTALIB. Table 9. Creating our test environment step by step Overview Detail IVP job Sample job Sample source name name member(s)

Tasks specifically for enabling DB2 ODBA stored procedures

Create DRA startup Section 8.6.1, “Step 1: IV_E304J DRAASM DFSIMSD0 table for IMS system Create IMS DRA startup table” on page 218

Establish and define This has to do with the IMS -- - the connection system. We leave it as is for security and the this example. PSB security to be Refer to Section 8.10.3, used for security “Security considerations” control on page 248

Create WLM Section 8.6.2, “Step 2: -- - application Create JCL: WLM DB2 environment stored procedure address space” on page 218

Create JCL for DB2 Section 8.6.2, “Step 2: -- WLMIMS ODBA stored Create JCL: WLM DB2 #IMSD procedures to run stored procedure address space” on page 218

Prepare DB2 ODBA stored procedure

Compile and link Section 8.7.2, “Step 2: DSNTEJ61 - Compile jobs edit Compiling and linking the DSNHPLI stored procedure” on @DEFAULT page 227

Bind package to Section 8.7.3, “Step 3: -- - DB2 Binding the stored procedure” on page 229

Define stored Section 8.7.4, “Step 4: DSNTEJ61 - Last step in our procedure to DB2 Defining the stored compile jobs procedure to DB2” on page 229

Tasks related to IMS application development

Chapter 8. DB2 stored procedures and IMS 215 Overview Detail IVP job Sample job Sample source name name member(s)

Design database Section 8.12.2.1, - SJCDB1 “Designing our database - and writing our DBD source” on page 275

Generate DBD Section 8.12.2.2, IV_E201J SJCDB1 which is “Generating DBD” on basedonIVP page 276 HDAM sample member DFSIVD2

Generate PSB Section 8.12.2.3, IV_E202J SJCPSB “Generating PSB” on SJCPSBL page 276 Generate DBD using Generate ACB Section 8.12.2.4, IV_E203JOD1$GEN n/a “Generating ACB” on page 277

Delete / define Section 8.12.4.1, “Defining IV_G101J Instream SYSIN database and image data sets for IMS database part of job copy data sets and image copies” on page 280

MDA dynamic Executes procedure IV_E301J based on - allocation macro IMSDALOC IV3E301J

Initial load of Section 8.12.4.3, “Loading IV_G103J database data into IMS database” on page 280

Initialize RECON / IV2G102J register databases

Batch image copies IV2G104J

Compile and link Section 8.7, “Program OD1BPMS stored procedure preparation” on page 222 and so on, for each sample.

IMS system gen - more operational.

216 Cross-Platform DB2 Stored Procedures: Building and Debugging Overview Detail IVP job Sample job Sample source name name member(s)

Define new n/a databases / Update IMS gen stage 1 programs to IMS source to include new DATABASE and APPLCTN Stage 1 macros. See IV2C203J - Notpartof Section 8.12.3.1, Stage 2 IV2C301J samples for - “MODBLKS and MATRIX this redbook. Security genonline change” on page 277 IV2E313J -

Online copy IV2E315J

Restart IMS /s ims610d,parm1=’auto=n’ /nre chkpt 0 format all

Bringing down IMS In TM and DBCTL, /CHE PURGE. or use /che dumpq. in TM and /che freeze. in DBCTL

Check for updates Use the IMS test program DFSDDLT0 (“diddle-toe”)

Between IMS V6 and IMS V7 there has been a data set name change from RESLIB to SDFSRESL. If you are using older copies of IMS procedures, please take note of the data set name changes.

8.6 Create DB2 ODBA stored procedure environments DB2 ODBA stored procedures are dual citizens of DB2 and IMS. We need to set up both IMS and DB2 environments for them.

On the IMS side, we need to create the DRA startup table which is used in the APSB call.

On the DB2 side, DB2 ODBA stored procedures must run in WLM-SPAS. We need to make sure that the WLM-established DB2 SPAS JCL contains the DRA startup table and also the necessary ODBA modules.

Chapter 8. DB2 stored procedures and IMS 217 8.6.1 Step 1: Create IMS DRA startup table Application programs (in particular DB2 stored procedures) use information specified in the DRA startup table to establish an ODBA connection to an IMS system.

The IMS DRA startup table is equivalent to DFSPZP00 which is used for CICS. For ODBA, the member name is DFSnnnn0. IMS provides a sample DRA startup table, DFSPZP00. Chapter 9, “Accessing IMS Databases with CICS” from IMS Installation Volume 2: System Definition and Tailoring, GC26-8737 describes how to set up the DRA startup table. To understand the DRA startup table, it is helpful to compare it with how BMPs execute.

Whether you are using Fast Path or not determines how this table is coded.

Our job that builds the DRA startup table is based on the IVP job IV_E304J and on the JCL procedure HLASMCL delivered as part of High Level Assembler to assemble and linkedit source code. Some sites may choose to retain the “old name”, ASMACL.

For more information on setting up the DRA startup table, please refer to Section 8.10.2, “The DRA startup table” on page 245.

8.6.2 Step 2: Create JCL: WLM DB2 stored procedure address space

Use of WLM Please also refer to Chapter 5, “OS/390 Workload Manager” on page 131 in this redbook, regarding use of WLM.

Add the following DD statements to the WLM SPAS JCL: 1. To the STEPLIB DD statement, add the library where the DRA startup table resides. In our case the RESLIB 2. For debugging with the debug tool, add the library for the debug tool (EQA) to the STEPLIB DD statement 3. The WLM-established DB2 stored procedure address space needs a DFSRESLB DD statements which includes the DRA startup table and DRA modules DFSCDLI0, DFSAERM0, DFSAERA0, DFSAERG0 in order to establish an ODBA environment during startup. These modules need to be APF authorized. Every data set in this DD statement needs to be APF authorized.

218 Cross-Platform DB2 Stored Procedures: Building and Debugging 4. Any additional data sets required for the stored procedure. For instance, our PL/I stored procedure uses PUT SKIP statements to write to SYSPRINT in order to help us debug. Therefore we need to add a SYSPRINT DD statement.

Also we may wish to add a CEEDUMP DD statement for Language Environment related dumps.

8.6.3 Step 3: Create the WLM application environment Use the WLM ISPF application option 9 Application Environment to define the application environment.

Use the Utilities pulldown -> Install definition to install and select Activate service policy to make it effective.

Now the environment is set up.

8.6.4 Sample WLM AE setup for DB2 ODBA stored procedures In our LPAR, we have multiple DB2 subsystems as well as multiple IMS systems. Since we can have DB2 subsystems (or IMS systems) at different versions and releases at a given time, we need a separate WLM application environment for each DB2/IMS combination.

We create the WLM application environment, WLMIMSD (1) in our case, as shown in Figure 73. It calls JCL procedure WLMIMS (2).

Chapter 8. DB2 stored procedures and IMS 219 Application-Environment Notes Options Help ------Modify an Application Environment Command ===> ______

Application Environment Name . : WLMIMSD (1) Description ...... SP for ODBA for IMSD (v6) Subsystem Type ...... DB2 Procedure Name ...... WLMIMS (2) Start Parameters ...... DB2SSN=&IWMSSNM,NUMTCB=1, (3) APPLENV=WLMIMSD,IMSID=IMSD (4)

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 73. How WLM application environment WLMIMSD is defined

We want to have as few WLM SPAS JCL as we can to simplify maintenance. In our sample, we make use of a symbolic variable &IWMSSNM (3) provided by WLM which contains the subsystem identifier.

So what is contained in this variable? Since the WLM application environment is started by DB2 when it resolves the WLM application environment name with the stored procedure schema and name, the subsystem named in &IWMSSNM is the DB2 subsystem ID. By using this symbolic variable, we can have multiple WLM-AEs sharing the same JCL for different DB2 subsystems.

When a DB2 stored procedure is called (by schema and procedure name), DB2 resolves the WLM application environment name. The application environment WLMIMSD is scheduled (1). WLM will start up a new WLMIMS (2). &IWMSSNM (3) contains the DB2 subsystem ID because DB2 is the subsystem starting the WLM application environment.

The IMSID (4) is passed to the JCL procedure WLMIMS which is listed in Figure 74.

220 Cross-Platform DB2 Stored Procedures: Building and Debugging //WLMIMS PROC RGN=0M,APPLENV=WLMIMS,DB2SSN=&IWMSSNM.,NUMTCB=8 //IEFPROC EXEC PGM=DSNX9WLM,REGION=&RGN,TIME=NOLIMIT, // PARM='&DB2SSN,&NUMTCB,&APPLENV' // INCLUDE MEMBER=#&IMSID. (5) // INCLUDE MEMBER=#&DB2SSN. (6) //STEPLIB DD DISP=SHR,DSN=CEE.SCEERUN // DD DISP=SHR,DSN=&DB2LOAD. <--- SET ABOVE // DD DISP=SHR,DSN=&RESLIB. <--- SET ABOVE // DD DISP=SHR,DSN=EQA.DTDEBUG.V1R2M0.INT2.SEQAMOD <--- DEBUG // DD DISP=SHR,DSN=SG245485.SAMPLES.LOAD <--- SAMPLES // DD DISP=SHR,DSN=DB2V61Z1.RUNLIB.LOAD <--- IVP //DFSRESLB DD DISP=SHR,DSN=&DRATBL. <--- DRA STARTUP TABLE //DFSSTAT DD SYSOUT=* <--- DON'T THINK THIS WILL BE OPENED ... //*SYSUDUMP DD SYSOUT=* // INCLUDE MEMBER=SG245485 //CEEDUMP DD SYSOUT=* <--- FOR CEEPIPI PROBLEMS //SYSPRINT DD SYSOUT=* <--- FOR PLI PUT MESSAGES

Figure 74. JCL procedure WLMIMS

The WLM application environment is set up so that the IMSID parameter determines which JCL include member (5) to pick up. In this case, we have a JCL INCLUDE member #IMSD as shown in Figure 75.

//* JCL INCLUDE MEMBER FOR IMSD // SET RESLIB=IMS610D.RESLIB <--- RESLIB // SET DRATBL=IMS610D.RESLIB <--- DRA STARTUP TABLE

Figure 75. JCL INCLUDE member #IMSD

Similarly for JCL INCLUDE member #DBZ2 listed in Figure 76.

//* JCL INCLUDE MEMBER FOR DBZ2 // SET DB2LOAD=DSN610.SDSNLOAD

Figure 76. JCL INCLUDE member #DBZ2

We adopt this approach to demonstrate how to use only one piece of JCL to maintain for WLM established DB2 stored procedure address space, even though really we also have a need to have the #IMSD and #DBZ2 members, for example. This approach may be useful if you want different types of WLM SPAS for different projects or different business functions.

Chapter 8. DB2 stored procedures and IMS 221 8.7 Program preparation DB2 ODBA stored procedures are dual citizens of DB2 and IMS.

In addition to normal program preparation procedure for DB2 stored procedures, we need to link in the ODBA callable interface AERTDLI (DFSCDLI0).

We will now consider how to prepare the program for execution: 1. The SQL CREATE PROCEDURE statement. 2. Compile and link-edit the client program. 3. Bind the plan for the client program. 4. Execute the client program.

8.7.1 Step 1: A sample DB2 ODBA stored procedure We create a DB2 ODBA stored procedure OD1DPMS written in PL/I. The caller program, or client, passes the following parameters to the stored procedure: • The name of the DRA startup table to use • The name of the PSB to schedule • The name of the PCB to use • The segment name • A ‘Y’ if we want the stored procedure to pause in the middle of an execution by waiting for console input

Warning If you use the pause flag when invoking the stored procedure, you must have operator access in order to enter replies via the console.

The stored procedure: 1. Allocates (schedules) a PSB in the IMS subsystem specified in the DRA startup table. 2. Builds an unqualified segment search argument (SSA) to using the passed segment name. 3. Reads (50 bytes of) an IMS database record (our root segment) using the passed PCB and the SSA. 4. Deallocates the PSB.

222 Cross-Platform DB2 Stored Procedures: Building and Debugging Because the PSB, PCB and segment name are all passed at execution time, provided you have a PSB and valid PCBs, you can run this stored procedure without having to build IMS databases and PSBs. We show the IMS steps in Section 8.12, “Defining IMS resources” on page 274.

8.7.1.1 PL/I sample program source OD1DPMS OD1DPMS: PROCEDURE ( INOUT_DRA_Startup_Table , INOUT_PSB , INOUT_PCB , INOUT_SEGNAME , INOUT_Function , INOUT_Pause , OUT_AIBRETRN , OUT_AIBREASN , OUT_DLI_STATUS , OUT_SEGDATA ) OPTIONS(MAIN NOEXECOPS REENTRANT) ; /*******************************************************************/ /* Based on OD1CPMS but you need to specify the PCB and segment */ /* name. It performs a GU. A bare bones sample just to retrieve */ /* a segment. The INOUT_Function parameter is ignored. */ /* */ /* MUST UPDATE so that if update etc fail, we get code back to */ /* client */ /* */ /* Decimals are not showing correctly ... needs more work ... */ /* */ /*******************************************************************/

/*******************************************************************/ /* Variables for Stored Procedure from / to caller */ /*******************************************************************/ DCL INOUT_DRA_Startup_Table CHAR (04) ; DCL INOUT_PSB CHAR (08) ; DCL INOUT_PCB CHAR (08) ; DCL INOUT_SEGNAME CHAR (08) ; DCL INOUT_Function CHAR (08) ; DCL INOUT_Pause CHAR (01) ; DCL OUT_AIBRETRN CHAR (08) ; DCL OUT_AIBREASN CHAR (08) ; DCL OUT_DLI_STATUS CHAR (02) ; DCL OUT_SEGDATA CHAR (50) ;

Chapter 8. DB2 stored procedures and IMS 223 /*******************************************************************/ /* Literals for DL/I calls */ /*******************************************************************/

DCL APSB CHAR(4) INIT('APSB'); DCL CIMS CHAR(4) INIT('CIMS'); DCL DPSB CHAR(4) INIT('DPSB'); DCL GU CHAR(4) INIT('GU'); DCL GN CHAR(4) INIT('GN'); DCL ISRT CHAR(4) INIT('ISRT'); DCL DB_PTR POINTER; DCL 1 DB_PCB BASED(DB_PTR), 2 FILLER1 CHAR(8), 2 FILLER2 CHAR(2), 2 DLI_STATUS_CODE CHAR(2); DCL 1 IOAREA , 5 KEY CHAR(21) , 5 DATA CHAR(29); DCL THREE FIXED BIN(31) INIT(3); DCL FOUR FIXED BIN(31) INIT(4); DCL TWO FIXED BIN(31) INIT(2); DCL RETCODE FIXED BIN(31);

/*******************************************************************/ /* AIB */ /*******************************************************************/

DECLARE 1 AIB , 3 AIBID CHAR(8), /* EYECATCHER - 'DFSAIB ' */ 3 AIBLEN FIXED BIN (31), /* DFSAIB ALLOCATED LENGTH */ 3 AIBSFUNC CHAR(8), /* SUBFUNCTION CODE */ 3 AIBRSNM1 CHAR(8), /* RESOURCE NAME 1 */ 3 AIBRSNM2 CHAR(8), /* RESOURCE NAME 2 */ 3 AIBRESV1 CHAR(8), /* RESERVED */ 3 AIBOALEN FIXED BIN (31), /* OUTPUT AREA LENGTH (MAX) */ 3 AIBOAUSE FIXED BIN (31), /* OUTPUT AREA LENGTH (USED) */ 3 AIBRESV2 CHAR(12), /* RESERVED */ 3 AIBRETRN FIXED BIN (31), /* RETURN CODE */ 3 AIBREASN FIXED BIN (31), /* REASON CODE */ 3 AIBERRXT FIXED BIN (31), /* ERROR CODE EXTENSION */ 3 AIBRSA1 PTR , /* RESOURCE ADDRESS 1 */ 3 AIBRSA2 PTR , /* RESOURCE ADDRESS 2 */ 3 AIBRSA3 PTR , /* RESOURCE ADDRESS 3 */ 3 AIBRESV4 CHAR(40), /* RESERVED @PQ15784*/

224 Cross-Platform DB2 Stored Procedures: Building and Debugging 3 AIBSAVE (18) FIXED BIN (31), /* SA for AERAIB calls @PQ15784*/ 3 AIBTOKN (6) /* NAME/TOKEN AREA FOR AER@PQ15784*/ FIXED BIN (31), 3 AIBTOKC CHAR(16), /* NAME VALUE @PQ15784*/ 3 AIBTOKV CHAR(16), /* TOKEN VALUE @PQ15784*/ 3 AIBTOKA (2) /* NAME/TOKEN AREA FOR AER@PQ15784*/ FIXED BIN (31) ; DECLARE PIC_AIBRETRN PIC '(8)9' ; DECLARE PIC_AIBREASN PIC '(8)9' ; DECLARE AERTDLI ENTRY OPTIONS( ASSEMBLER ); DECLARE DATETIME BUILTIN ; DECLARE STORAGE BUILTIN ;

/*******************************************************************/ /* Schedule a PSB */ /*******************************************************************/ dcl line char (72) init ('------') ; AIB.AIBID = 'DFSAIB ' ; AIB.AIBLEN = storage(AIB) ; AIB.AIBSFUNC = '' ;

AIB.AIBRSNM1 = INOUT_PSB ; AIB.AIBRSNM2 = INOUT_DRA_Startup_Table ; AIB.AIBOALEN = storage(ioarea); put skip edit (line) (a) ; put skip data (AIB) ; CALL AERTDLI (TWO,APSB,AIB); put skip edit (line) (a) ; put skip data (AIB) ;

If ( AIB.AIBRETRN = 0 & AIB.AIBREASN = 0 ) Then Do ; /***************************************************************/ /* GU */ /***************************************************************/

AIB.AIBRSNM1 = INOUT_PCB ; /* PCBNAME */ put skip edit (line) (a) ; put skip data (AIB) ; dcl ssa char (09) ; ssa = INOUT_SEGNAME || ' ' ;

Chapter 8. DB2 stored procedures and IMS 225 CALL AERTDLI (GU, AIB, IOAREA, SSA); put skip edit (line) (a) ; put skip data (AIB) ; db_ptr = AIB.AIBRSA1 ; put skip data (db_pcb) ; put skip data (ioarea) ;

OUT_AIBRETRN = AIB.AIBRETRN ; /* set output here */ OUT_AIBREASN = AIB.AIBREASN ; OUT_DLI_STATUS = DB_PCB.DLI_STATUS_CODE ;

dcl response char (1) init('R') ; If INOUT_Pause = 'Y' Then display ('respond with "' || response || '"') reply (response);

OUT_AIBRETRN = AIB.AIBRETRN ; /* set output here */ OUT_AIBREASN = AIB.AIBREASN ; OUT_DLI_STATUS = DB_PCB.DLI_STATUS_CODE ; OUT_SEGDATA = string(ioarea) ;

/***************************************************************/ /* Deallocate a PSB but letting DSNX9WLM invoke CIMS TALL */ /***************************************************************/

AIB.AIBID = 'DFSAIB ' ; AIB.AIBRSNM1 = INOUT_PSB ; AIB.AIBRSNM2 = INOUT_DRA_Startup_Table ; AIB.AIBSFUNC = 'PREP ' ; put skip edit (line) (a) ; put skip data (aib) ; CALL AERTDLI (TWO,DPSB,AIB); put skip edit (line) (a) ; put skip data (aib) ;

End ; Else Do ; PIC_AIBRETRN = AIB.AIBRETRN ; /* set output here */ PIC_AIBREASN = AIB.AIBREASN ; OUT_AIBRETRN = PIC_AIBRETRN ; /* set output here */ OUT_AIBREASN = PIC_AIBREASN ; End ;

END OD1DPMS;

226 Cross-Platform DB2 Stored Procedures: Building and Debugging 8.7.2 Step 2: Compiling and linking the stored procedure Here is the JCL procedure we use to compile and link our stored procedure: //********************************************************************** //* Notes for SG24-5485 //* 1/ We may continue to use the OS PL/I compiler name IEL0AA //* if we rename the PLI for MVS compiler from IEL1AA to IEL0AA //********************************************************************** //*$ COMPILE AND LINKEDIT A PL/I PROGRAM //* //DSNHPLI PROC WSPC=500 ,MEM=TEMPNAME,USER=USER //* //* SET PLINCL=DSN610.SRCLIB.DATA //* //* PROCESS PL/I MACROS //********************************************************************** //PPLI EXEC PGM=IEL1AA,PARM='MACRO,NOSYNTAX,MDECK,NOINSOURCE' //STEPLIB DD DISP=SHR,DSN=&PLICOMP. // DD DISP=SHR,DSN=&SCEERUN. //SYSLIN DD DUMMY //SYSIN DD DISP=SHR,DSN=&SOURCE.(&MEM) //SYSPRINT DD SYSOUT=*, // DCB=(RECFM=VBA,LRECL=125,BLKSIZE=629) //SYSPUNCH DD DSN=&&DSNHIN,DISP=(MOD,PASS),UNIT=SYSDA, // SPACE=(CYL,(5,2),RLSE) //SYSUDUMP DD SYSOUT=* //SYSUT1 DD SPACE=(1024,(60,60),,CONTIG),UNIT=SYSDA, // DCB=BLKSIZE=1024 //* //* PRECOMPILE THE PL/I PROGRAM //* //PC EXEC PGM=DSNHPC,PARM='HOST(PLI) SOURCE',REGION=4096K, // COND=(8,LT,PPLI) //DBRMLIB DD DISP=OLD,DSN=&DBRMLIB.(&MEM.) //STEPLIB DD DISP=SHR,DSN=&DB2EXIT. // DD DISP=SHR,DSN=&DB2LOAD. //SYSCIN DD DSN=&&DSNHOUT,DISP=(MOD,PASS),UNIT=SYSDA, // SPACE=(800,(&WSPC,&WSPC)) //SYSIN DD DSN=&&DSNHIN,DISP=(OLD,DELETE) //SYSLIB DD DISP=SHR,DSN=&PLINCL. //SYSPRINT DD SYSOUT=* //SYSTERM DD SYSOUT=* //SYSUDUMP DD SYSOUT=* //SYSUT1 DD SPACE=(800,(&WSPC,&WSPC),,,ROUND),UNIT=SYSDA //* //* COMPILE THE PL/I PROGRAM IF THE PRECOMPILE //* RETURN CODE IS 4 OR LESS

Chapter 8. DB2 stored procedures and IMS 227 //* //PLI EXEC PGM=IEL1AA,PARM='OBJECT,NODECK,OFFSET,AG', // COND=((4,LT,PC),(8,LT,PPLI)) //STEPLIB DD DISP=SHR,DSN=&PLICOMP. // DD DISP=SHR,DSN=&SCEERUN. //SYSIN DD DSN=&&DSNHOUT,DISP=(OLD,DELETE) //SYSLIB DD DISP=SHR,DSN=CICSTS13.CICS.SDFHPL1 // DD DISP=SHR,DSN=GDDM.SADMSAM //SYSLIN DD DISP=SHR,DSN=&OBJLIB.(&MEM.) //* //SYSLIN DD DSN=&&LOADSET,DISP=(MOD,PASS),UNIT=SYSDA, //* // SPACE=(800,(&WSPC,&WSPC)) //SYSPRINT DD SYSOUT=* //SYSUDUMP DD SYSOUT=* //SYSUT1 DD SPACE=(800,(&WSPC,&WSPC),,,ROUND),UNIT=SYSDA //SYSUT2 DD SPACE=(800,(&WSPC,&WSPC),,,ROUND),UNIT=SYSDA //SYSUT3 DD SPACE=(800,(&WSPC,&WSPC),,,ROUND),UNIT=SYSDA //SYSUT4 DD SPACE=(800,(&WSPC,&WSPC),,,ROUND),UNIT=SYSDA //* //* LINKEDIT IF THE COMPILE RETURN CODE IS 8 OR //* LESS AND PRECOMPILE RETURN CODE IS 4 OR LESS //* //LKED EXEC PGM=IEWL,PARM='XREF', // COND=((8,LT,PLI),(4,LT,PC),(8,LT,PPLI)) //SYSLIB DD DISP=SHR,DSN=&SCEELKED. // DD DISP=SHR,DSN=&DB2LOAD. // DD DISP=SHR,DSN=&RESLIB. // DD DISP=SHR,DSN=CICSTS13.CICS.SDFHLOAD // DD DISP=SHR,DSN=ISP.SISPLOAD // DD DISP=SHR,DSN=GDDM.SADMMOD // DD DISP=SHR,DSN=SYS1.CSSLIB //SYSLIN DD DDNAME=SYSIN //SYSLMOD DD DISP=SHR,DSN=&APPLLOAD.(&MEM.) //OBJECT DD DISP=SHR,DSN=&OBJLIB. //SYSPRINT DD SYSOUT=* //SYSUDUMP DD SYSOUT=* //SYSUT1 DD SPACE=(1024,(50,50)),UNIT=SYSDA //*DSNHPLI PEND REMOVE * FOR USE AS INSTREAM PROCEDURE

Here is the JCL which executes the JCL procedure just described.

In the link edit step, we include the ODBA module DFSCDLI0 which contains entry point AERTDLI. We also include DSNRLI because this is the DB2 language interface for RRS.

The last step CREATESP executes SQL statements to create the stored procedure.

228 Cross-Platform DB2 Stored Procedures: Building and Debugging //#OD1DPMS JOB (999,POK),'VARIATION ON OD1BPMS',CLASS=A,MSGCLASS=T, // NOTIFY=&SYSUID,TIME=1440,REGION=4M /*JOBPARM L=9999,SYSAFF=SC61 //* // JCLLIB ORDER=SG245485.SAMPLES.JCL // INCLUDE MEMBER=@DEFAULT * PICK UP SYMBOLICS FOR SAMPLES //* //*------//*$ PREPARE PL/I ODBA STORED PROCEDURE SAMPLE //* The first time this job is run, it is OK to get SQLCODE = -204 //* for the DROP PROCEDURE and have a final return code of 8 //*------//* //BUILDIT EXEC PROC=DSNHPLI,MEM=OD1DPMS //LKED.SYSIN DD * INCLUDE SYSLIB(DFSCDLI0) INCLUDE SYSLIB(DSNRLI) INCLUDE SYSLIB(DSNTIAR) INCLUDE OBJECT(OD1DPMS) NAME OD1DPMS(R) /* //*------//* CREATE THE STORED PROCEDURE //*------//* //CREATESP EXEC PROC=DSNTIAD,COND=(04,LT) //DSNTIAD.SYSIN DD DISP=SHR,DSN=SG245485.SAMPLES.SQL(OD1DPMS)

8.7.3 Step 3: Binding the stored procedure Since our DB2 ODBA stored procedure OD1DPMS does not contain any SQL statements, we do not need to bind it to DB2.

8.7.4 Step 4: Defining the stored procedure to DB2 Below are SQL statements in DB2 v6 syntax to drop and create stored procedure. DROP PROCEDURE OD1DPMS RESTRICT; CREATE PROCEDURE OD1DPMS ( DRA_STARTUP_TABLE CHAR (04) INOUT , PSB CHAR (08) INOUT , PCB CHAR (08) INOUT , SEGMENT_NAME CHAR (08) INOUT , FUNCTION CHAR (08) INOUT , PAUSE CHAR (01) INOUT , AIB_RETURN_CODE CHAR (08) OUT , AIB_REASON_CODE CHAR (08) OUT

Chapter 8. DB2 stored procedures and IMS 229 , DLI_STATUS CHAR (02) OUT , SEGMENT_DATA CHAR (50) OUT ) LANGUAGE PLI DETERMINISTIC NO SQL EXTERNAL NAME 'OD1DPMS' ASUTIME LIMIT 900 PARAMETER STYLE GENERAL STAY RESIDENT NO RUN OPTIONS 'MSGFILE(OUTFILE),RPTSTG(ON),RPTOPTS(ON)' WLM ENVIRONMENT WLMIMSD PROGRAM TYPE MAIN SECURITY DB2 COMMIT ON RETURN NO;

8.8 Running DB2 ODBA stored procedures The following sections describe the how to run DB2 ODBA stored procedures.

8.8.1 Start relevant IMS and DB2 subsystems We use the following simple checklist prior to executing. • Start IRLM for IMS. The IRLM is only required in a data sharing environment. If the IRLM is required it must be up before IMS can start as IMS cannot check or create database locks without it. If the IMS system is stand-alone then Program Isolation (PI) is used instead. • Start IMS up using /NRE CHKPT 0 FORMAT ALL. • Start DB2. • Make sure that the PSB is available using /dis prog psbname. • Make sure the stored procedure is not stopped with this command: -dis proc(schema.stproc)

230 Cross-Platform DB2 Stored Procedures: Building and Debugging 8.8.2 Executing the DB2 ODBA stored procedure We invoke the DB2 ODBA stored procedure via the stored procedure builder on NT. We assume that the NT client is already set up using DB2 client configuration assistant (DB2CCA) to catalog the remote database server.

Figure 77 shows how to invoke one of the sample stored procedures from this redbook using the SPB.

Figure 77. Invoking sample OD1BPMS using the SPB

Chapter 8. DB2 stored procedures and IMS 231 We check Treat empty strings as nulls in the SPB and we leave the code in uppercase with blanks to fill the entry fields. The stored procedure has only very basic string handling (see Figure 78). DB2RES1.OD1BPMS - The value(s) of the output parameters: DRA_STARTUP_TABLE = IMSD PSB = SJCPSB FUNCTION = Comment

DB2RES1.OD1BPMS - The value(s) of the output parameters: DRA_STARTUP_TABLE = IMSD PSB = SJCPSB FUNCTION = Comment

Figure 78. Output from executing the stored procedure

8.8.3 Terminating a DB2 ODBA stored procedure address space During development of stored procedures, you may want to bring down the WLM SPAS. This section describes what needs to be done.

If IMS has active threads with another address space and that address space terminates abnormally, IMS does not know what state the active transactions are in and subsequently it will abend with U0113. This is a situation you want to avoid. Refer to termination isolation in IMS manuals.

How we shut down WLM SPAS depends on the mode in which WLM is running. Running WLM in goal mode versus in compatibility mode determines how one shuts down a WLM-established DB2 stored procedure address space. When you are running in goal mode, the WLM quiesce command terminates the address space.

In compatibility mode, you can cancel the address space.

To find out whether you are running in goal or comspatibility mode, you can issue the operator command: d wlm,systems

In SDSF you will prefix the command with a forward slash “/”. The result of this command is shown in Figure 79.

232 Cross-Platform DB2 Stored Procedures: Building and Debugging D WLM,SYSTEMS IWM025I 16.28.20 WLM DISPLAY 841 ACTIVE WORKLOAD MANAGEMENT SERVICE POLICY NAME: SPSTPC ACTIVATED: 2000/10/31 AT: 18:25:51 BY: DB2RES1 FROM: SC61 DESCRIPTION: serv pol for db2 stor proc resid RELATED SERVICE DEFINITION NAME: DB2Jjava INSTALLED: 2000/10/31 AT: 18:25:30 BY: DB2RES1 FROM: SC61 WLM VERSION LEVEL: LEVEL008 *SYSNAME* *MODE* *POLICY* *WORKLOAD MANAGEMENT STATUS* SC04 GOAL SPSTPC ACTIVE SC42 GOAL SPSTPC ACTIVE SC47 GOAL SPSTPC ACTIVE SC48 GOAL SPSTPC ACTIVE SC49 GOAL SPSTPC ACTIVE SC61 GOAL SPSTPC ACTIVE

Figure 79. Output from a display command for the WLM

Where we have more than 1 WLM SPAS with the same jobname, if you CANCEL or FORCE the address space without specifying an address space identifier ASID, you will receive the following message: IEE842I WLMIMS DUPLICATE NAME FOUND- REENTER COMMAND WITH 'A=' KEYWORD

You will need to cancel using the ASID. For example: /force wlmims,a=asid

If we try to CANCEL a WLM stored procedure address space which is connected to IMS DBCTL, we will get a message from IMS telling us we cannot cancel the address space as shown in Figure 80.

C WLMIMS DFS0802I CANCEL COMMAND REJECTED BY IMS, USE /STOP REGION COMMAND TO STOP IMS DEPENDENT REGION, JOBNAME = WLMIMS IMSB So you cannot stop an ODBA session by cancelling the WLM-established DB2 stored procedure address space

Figure 80. Response from cancelling DB2 ODBA stored procedure address space

The IMS subsystem interface broadcast exit DFSISI00 stops you from cancelling.

Chapter 8. DB2 stored procedures and IMS 233 Warning A termination of a CCTL subsystem can cause IMS DB failure. Be careful when setting up of the timeout value DRA TERM to make sure it is large enough.

Avoid using CANCEL or FORCE commands against a DB2 ODBA stored procedure that is connected to IMS DB.

During our testing, we have brought down IMS systems to see what happens. The commands we have used are: /che freeze.

This waits for all transactions to complete. For our DBCTL system (CICS-IMS) we used: /che purge.

Refer to Appendix D in the IMS Version 7 Application Programming: Database Manager, SC26-9422, about terminating the DRA.

Refer to the Chapter on “OS/390 (MVS/ESA) Commands Used for IMS” in the IMS/ESA Version 6 Operator ‘s Reference, SC26-8742.

8.8.3.1 CANCEL/FORCE ODBA application address space This section is reproduced from APAR PQ34951 for your convenience. It essentially describes the downgrading of the cancel / force commands.

Format: CANCEL jobname FORCE jobname

Step 1: Reason: User wants to terminate an ODBA application address space with an active connection to an IMS subsystem. Usage: CANCEL jobname (where jobname is the ODBA application address space). Action taken: If there are no threads active under this connection to IMS, allow the CANCEL command to be processed by MVS. If there appear to be active threads (IDTTHDCT is greater than zero), the CANCEL command is rejected and message DFS0802I is issued.

234 Cross-Platform DB2 Stored Procedures: Building and Debugging Explanation: The CANCEL is rejected to protect the IMS control region from ABENDU0113s or other related abends. If it is invalid for threads to be active at this time, documentation should be gathered to determine the reason for the active thread(s).

Step 2: Reason: User wants to terminate an ODBA application address space with an active connection to an IMS subsystem but the CANCEL from step 1 was rejected. Usage: FORCE jobname (where jobname is the ODBA application address space). Action taken: If this is the first time that FORCE has been issued against the current iteration of the ODBA application address space, DFSISI00 will change the FORCE to a CANCEL and allow MVS to process the CANCEL command. Explanation: Use the FORCE with caution. By allowing MVS to CANCEL the address space, it is possible that the IMS control region may terminate abnormally depending on the actual state of the active thread(s). It is recommended that steps be taken to resolve the outstanding active threads prior to issuing the FORCE command Note: It is recommended that a CANCEL be attempted prior to the FORCE, but it is neither required nor enforced.

Step 3: Reason: User wants to terminate an ODBA application address space with an active connection to an IMS subsystem but the CANCEL from step 1 was rejected and the first FORCE from step 2 was not successful. Usage: FORCE jobname (where jobname is the ODBA application address space). Action taken: If a prior FORCE has been issued against the current iteration of the ODBA application address space, allow MVS to process the FORCE command. Explanation: Use the FORCE with caution. By allowing MVS to FORCE the address space, it is possible that the IMS control region may terminate abnormally depending on the actual state of the active thread(s).

Chapter 8. DB2 stored procedures and IMS 235 8.8.4 Problem determination For an explanation of the application interface block (AIB), refer to Section 8.10.4.1, “The application interface block (AIB)” on page 250. You should always check the IMS status code, the reason code, and the return code after an IMS call. 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 non-blank spaces for status code (for example, GE and GB may be valid status codes indicating no more segment found, or end of database reached).

If you keep getting AIBRETRN=260,AIBRETRN=520 (that is, 104, 208 respectively in hex), then it is likely you are not using the label in the PCBNAME macro (see Section 8.10.5.1, “Using the DFSCDLI0 AERTDLI interface” on page 256)

Important tips! The value of AIBREASN and AIBRETRN fields are given in decimal. When looking up the IMS Application Programming: Database Manager manual, the values are given in hexadecimal. There you will need to convert your values back to hexadecimal. You can use a simple REXX built-in function d2x() to convert the value.

Table 10 shows what names appear in which environments. Table 10. Names and their environments DB2 IMS RRS

Client jobname -dis thd(*)

WLM SPAS /dis cctl all shows ASID. Use SDSF to find out WLM SPAS name

UOR -dis uor /dis cctl all Use RRS ISPF -dis thd(*) application type(ndoubt)

236 Cross-Platform DB2 Stored Procedures: Building and Debugging 8.8.4.1 An overview of problem determination Table 11 describes how to track down each step during a stored procedure execution. Table 11. Tracking down steps during the life of a stored procedure execution Task Details

Execute DB2 client program to For DB2 UDB on workstation, use Client Configuration Assistant to connect to a DB2 server display where the server resides, or use the db2 list db / node / dcs directory commands.

For DB2 on OS/390 check the communications database to locate the DB2 server.

Client program invokes a stored For DB2 OS/390 v5, the DB2 stored procedure name is in procedure using the SQL SYSIBM.SYSPROCEDURES statement CALL procedurename For DB2 OS/390 v6 and above, the schema and the DB2 stored with optional parameters procedure name are in SYSIBM.SYSROUTINES DB2 server resolves characteristics of the stored procedure using catalogtableskeyedonstoredprocedurename DB2 server resolves stored procedure name

In either case, the procedure name will point to a WLM_ENVIRONMENT name. Note: Since DB2 ODBA stored procedures require WLM-established DB2 stored procedure address space, the value of the WLM_ENVIRONMENT has to be non-blank (because blank invokes a DB2-established stored procedure address space)

WLM starts off application The value of the WLM application environment matches the active environment address space service policy. You can display the status of WLM AEs with the /d wlm,applenv=* command and quiesce / resume / restart the WLM AE WLM then starts the JCL procedure specified for this AE and schedules the DB2 stored procedure, or the stored procedure can run in an existing AE depending on the set up of the WLM AE.

DB2 WLM-stored procedure On finding a DFSRESLB DD statement, DSNX9WLM will issue CIMS address space program INIT without specifying IMS subsystem ID. It either issues DSNX9WLM starts up +DSNX991I DSNX9WLM IMS ODBA INITIALIZATION COMPLETED or +DSNX992E IMS ODBA INITIALIZATION FAILURE, AIB RC =

Check if the IMS transactions / Use /DISPLAY TRAN and /DISPLAY PROG programs are installed properly If Fast Path is installed in the system, you can also consider using /DISPLAY PSB xxx

Chapter 8. DB2 stored procedures and IMS 237 8.9 Testing DB2 ODBA stored procedures Apart from checking results from AERTDLI calls and checking the PCBs for IMS status codes, we can use techniques found in Chapter 11 of IMS Application Programming: Design Guide, SC26-8728. Testing an ODBA Application Program. These are using the DL/I testing program DFSDDLT0 and tracing DL/I calls with image capture.

8.9.1 Tracing DL/I calls with image capture In this section we describe tracing DL/I calls with Image Captures by using the IMS command: /TRACE SET ON PSB psbname COMP

If the trace output is sent to the IMS log datasets, use the File Select and Formatting Print utility DFSERA10 and a DL/I call trace exit routine. The following is a sequence of events for tracing PSB SJCPSB: 1. Turn on trace with this command: /TRACE SET ON PSB SJCPSB COMP 2. Run the DB2 ODBA stored procedure 3. Turn off trace with this command: /TRACE SET OFF PSB SJCPSB 4. Switch the online log data sets (OLDS). This also causes the contents to be archived to the secondary log data sets (SLDS) with this command: /SWITCH OLDS 5. Execute the print utility, specifying the latest SLDS as input in SYSUT1 DD statement, as shown in Figure 81.

238 Cross-Platform DB2 Stored Procedures: Building and Debugging //#TRACE JOB (999,POK),'IMS PRINT UTILITY',NOTIFY=&SYSUID., // CLASS=A,MSGCLASS=T,REGION=5000K, //* TYPRUN=SCAN, // MSGLEVEL=(1,1) /*JOBPARM L=9999,SYSAFF=SC61 //* // EXEC PGM=DFSERA10 //STEPLIB DD DSN=IMS610D.RESLIB,DISP=SHR //SYSPRINT DD SYSOUT=* //SYSIN DD * OPTION PRINT EXITR=DFSERA50 //TRCPUNCH DD SYSOUT=* //SYSUT1 DD DISP=SHR,DSN=IMS610D.SLDSP.IMSD.D00325.T0207185.V02

Figure 81. JCL to execute IMS File Select and Formatting Print Utility DFSERA10

We code a DD statement in DFSERA10 input stream defining sequential output dataset default DD name TRCPUNCH, blksize=80. This output data set contains DFSDDLT0 control statements as shown in Figure 82 (with sequence numbers removed in position 73-80) which can be used as input to a DFSDDLT0 execution. Please note that these control statements are column dependent.

U DATE=2000/327 TIME= 5.34.11 SJCPSB S11111 S 1 1 1 1 1 000011 L GU FOOTPRNT E DATA 20001120051232900 IMSDSJCPSB Whatever E 01 FOOTPRNT 002120001120051232900 U DATE=2000/330 TIME= 6.06.41 SJCPSB S11111 S 1 1 1 1 1 000011 L ISRT FOOTPRNT L DATA 20001125060641949 IMSDSJCPSB Blah E 01 FOOTPRNT 002120001125060641949

Figure 82. Output from print utility DFSERA10 in data set TRCPUNCH

Chapter 8. DB2 stored procedures and IMS 239 The SYSPRINT data set contains a control report for the log print program, as shown in Figure 83.

OPTION PRINT EXITR=DFSERA50 DFS707I END OF FILE ON INPUT DFS708I OPTION COMPLETE DFS703I END OF JOB

Figure 83. SYSPRINT output from DFSERA10 print utility

8.9.2 Using the DL/I test program DFSDDLT0 Just like DB2 application programmers often execute the imbedded SQL statements using tools such as SPUFI and QMF in isolation when developing a DB2 application program, IMS programmers often test IMS calls using the DL/I test program DFSDDLT0 in isolation. You can read more about DFSDDLT0 in Appendix C.Using the DL/I Test Program (DFSDDLT0) of IMS Application Programming: Database Manager, SC26-8727.

For a broader discussion on testing IMS applications, refer to Chapter 9, “Testing an IMS Application Program”,intheIMS Application Programming Design Guide, SC26-8728.

8.10 DB2 ODBA stored procedures explained This section explains each step in our DB2 ODBA stored procedure example in greater detail.

8.10.1 DB2 ODBA stored procedure coding overview Knowing how batch IMS programs work will help you understand ODBA programming, because there are parallels. Calling the ODBA callable interface using DFSCDLI0 (AERTDLI) is very similar to the IMS programming language interface DFSLI000 (CBLTDLI, PLITDLI, and so on). For professionals who already know how to code DL/I calls using the IMS Language Interface Module, comparing these two approaches also helps you learn ODBA programming quickly. As you can see, the two are similar. This section describes the similarities and differences between writing a batch IMS program and an ODBA program.

240 Cross-Platform DB2 Stored Procedures: Building and Debugging 8.10.1.1 Batch IMS program overview Batch programs call the IMS Language Interface Module DFSLI000 to request access to IMS databases. This module is also known by the entry point into the various programming languages — for example, ASMTDLI, CBLTDL, and PLITDLI, as well as AIBTDLI, which can be called in all valid IMS programming languages.

Figure 84 describes how the IMS dependent region DFSRRC00 interacts with an application program.

When an IMS batch application program executes, it executes under the control of the IMS (BMP) dependent region (DFSRRC00). The dependent region is passed the PSB name to be used by the application program. The dependent region connects to IMS using the IMSID. The other parameters are: • Application program name • PSB name • Fast Path buffers • Other parameters for execution — for example, DBRC on or off; application group name (AGN) for security

These are also set when calling the control region.

The dependent region connects to the specified IMS, loads the application program (2) and passes a set of pointers to it. These pointers correspond to the PCBs coded within the PSB. Each pointer points to a control block. For example the control block “1st PCB” corresponds to the PCB with name DB1PCB1.

The application calls the Language Interface Module (4) using one of the PCB pointers as a parameter. This PCB (5) points to DBD SJCDB1 (6).

IMS processes the request. Data is returned by the Language Interface Module into the IOAREA specified by the call, and the status of the call is now in the PCB area (8).

Chapter 8. DB2 stored procedures and IMS 241 The application can examine the fields in the PCB to assess the status of the call (9). If the status indicates a successful call, the application can now use the data in the IOAREA. Figure 84 illustrates the relationship of these components.

// EXEC PGM=DFSRRC00, 1 // PARM='BMP,SJCPGM,SJCPSB,...' PSB SJCPSB source code IMS dependent region 2 PCB TYPE=DB, PCBNAME=DB1PCB1, IMS language 5 DBDNAME=SJCDB1, PROCOPT=A, interface module KEYLEN=21 SENSEG NAME=FOOTPRNT, DFSLI000 PARENT=0, PROCOPT=A PCB TYPE=DB, PCBNAME=DB2PCB2, DBDNAME=SJCDB2, PROCOPT=A, 6 KEYLEN=21 SENSEG NAME=SEGM2, PARENT=0, prog SJCPGM 3 PROCOPT=A PSBGEN PSBNAME=SJCPSB, LANG=ASSEM, declare passed pointers CMPAT=YES, 8 OLIC=YES Cobol: 4 END CALL 'CBLTDLI' USING $4 1st PCB ,'GUbb' , PCB-PTR1 7 , IOAREA , SSA SJCDB1 PL/I: CALL PLITDLI( $4 2nd PCB ,'GUbb' , PCB_PTR2 , IOAREA 9 , SSA); ... check status in PCB

Figure 84. The IMS control region DFSRRC00

Database program control block (DB PCB) Table 12 shows the structure of an IMS database program control block (DB PCB). The “check” column specifies which fields should be checked by the application program.

242 Cross-Platform DB2 Stored Procedures: Building and Debugging Table 12. DB PCB structure Field Attributes Description Check?

COBOL PL/I

Database name PIC X(8) char (8) Database accessed

Segment level PIC X(2) char (2) Right justified numeric character data Y number

Status code PIC X(2) char (2) Describes the results of the DL/I call. Refer Y to the DL/I status code section in the IMS Messages and Codes manual

Processing PIC X(4) char (4) 4-byte field, coded in the PROCOPT - options parameter of the PCB statement in the PSB. It tells IMS what type of calls this program can issue.

Reserved for PIC S9(9) fixed bin (31) - - IMS USAGE IS BINARY

Segment name PIC X(8) char (8) The name of the last segment that satisfied Y a successful call

Length of key PIC S9(9) fixed bin (31) Describes the current length of the key Y feedback area USAGE IS feedback area. Note that the key feedback BINARY area is not usually cleared between calls. The application program needs to use this value to determine the length of the relevant current concatenated key in the key feedback area.

Number of PIC S9(9) fixed bin (31) Number of segments the program can - sensitive USAGE IS access segments BINARY

Key feedback Depends on the value of The concatenated key of the retrieve Y area the length of key feedback segment at completion of a retrieval or area ISRT call. If IMS cannot satisfy the call, the key feedback area contains the key of the segment at the last level that was satisfied. A segment's concatenated key is made up of the keys of each of its parents and its own key. Keys are positioned left to right, starting with the key of the root segment and following the hierarchic path.

Chapter 8. DB2 stored procedures and IMS 243 8.10.1.2 How the ODBA callable interface works With ODBA, we no longer invoke the IMS dependent region. Instead we invoke the application program directly. Like a BMP, we need to specify a number of characteristics when connecting to IMS and making DL/I calls: • The name of the IMS to connect to • The name of the PSB to use • Security related parameters like the AGN • If we are using Fast Path, we need to specify Fast Path related parameters such as NBA and OBA • Address of the PCB to check the status of our IMS DL/I calls

For ODBA, these parameters are specified in a number of places: the DRA startup table, the AIB and the CIMS INIT and / or the APSB call.

Figure 85 describes the similarities and differences between specifying execution parameters for BMP and ODBA programs. We choose a particular case of an ODBA program here because it best resembles a DB2 ODBA stored procedure.

For a BMP, the execution parameters are passed to the dependent region. The dependent region loads the application program.

An ODBA program does not run under the IMS dependent region. Instead it runs in its own address space. It establishes the ODBA environment using a CIMS INIT call. In this example it only connects to IMS during an APSB call, specifying a DRA startup table tbl1. The DRA resolves the connection characteristics such as IMSID, minimum and maximum number of threads. It creates a thread and returns a thread token to the calling program. All subsequent IMS calls for this schedule instance of the PSB must specify this thread token. (The token is for this schedule instance of the PSB. Subsequent schedules of the same PSB will get unique tokens.)

Here is one way to look at a thread token. You are going to the theatre on a rainy night. You leave your raincoat to the cloakroom attendants for safekeeping during the performance. In return the attendant gives you a ticket with a number to uniquely identify your raincoat. You know what the number is, and so does the attendant. Your raincoat in this case is a PSB. The ticket number is analogous to a thread token returned by an APSB call (the attendant). It is your responsibility to keep the token.

For people familiar with ODBC programming, the thread token is similar to a connection handle.

244 Cross-Platform DB2 Stored Procedures: Building and Debugging IMS BMP program IMS ODBA program DRA startup table tbl1

Execution parameters: DFSPRP DSECT=NO, DBCTLID=IMSD,

IMSID FPBUF=0, FPBOF=0, fast path buffer allocation CNBA=0, application group name AGN program name AGN=, PSB name MINTHRD=1, MAXTHRD=1 IMS dependent region (BMP) END

ODBAappl AERTDLI ... initialise ODBA environment CIMS INIT

... allocate PSB IMSAPPL APSB psb1 tbl1 ... save thread token ... and use it in subsequent DL/I calls, eg. GHU aib ioarea ssa

... commit using RRS API SRRCMIT thread token ... deallocate PSB DPSBpsb1tbl1 for IMSD, psb1

Figure 85. Specifying execution parameter for BMP versus ODBA programs

8.10.2 The DRA startup table The startup table defines to the ODBA callable interface how to connect to an IMS. The table is built using the DFSPRP macro. For detailed description on each operand of this macro, refer to Appendix D, “Using the Database Resource Adapter (DRA” in IMS/ESA Application Programming: Database Manager, SC26-8727.

We can divide these keywords by their function: • Keyword describing the resources required for a connection: -WhichIMSID - Minimum and maximum numbers of threads - For Fast Path data entry database (DEDB), the Fast Path buffers required on the IMS control region side - Destination for SNAP dumps - DRA function level - DRA library DD and data set names

Chapter 8. DB2 stored procedures and IMS 245 • Keywords describing the behavior of the threads - Number of retries to establish a connection to IMS -Timeout • Security: AGN and USERID for the CCTL

Table 13 describes each of the keywords for coding the DFSPRP macro in the startup table. The column ‘FF’ denotes full function database and ‘FP’ denote Fast Path database. For example ‘Y’ in ‘FP’ means you will need to code this keyword for Fast Path.

You can find an example of the DFSPRP macro in IVP job INSTALIB(IV_E304J).

Table 13. DFSPRP macro keywords Keyword Description Default FF FP

AGN 1-8 character application group name. This is used as part of the IMS DB and DB/DC security function.

CNBA Total number of Fast Path NBA buffers for the CCTL’s 0Y use. These buffers are in the IMS region (not the DB2 stored procedure address space)

DBCTLID The four-character name of the IMS DB or DB/DC region. SYS1 Y Y This is the same as the IMSID parameter in the DBC procedure.

DDNAME 1-8 character ddname to be used with the dynamic CCTLDD allocation of the DBCTL execution library. This library must contain the DRA modules. As far as ODBA goes, it is not used at all.

DSNAME 1-44 character data set name of the DBCTL execution IMS V6: library. This library must contain the DRA modules and IMS.RESLIB must be APF authorized. The default is dsname. IMS V7: IMS.SDFSRESL

FPBOF The number of Fast Path DEDB overflow buffers to be 0Y allocated per thread

FPBUF The number of Fast Path DEDB buffers allocated and 0Y fixed per thread.

FUNCLV Specifies what level of the DRA the CCTL supports. The 1 default is 1. There is no other value possible.

IDRETRY 0-255. The number of attempts an OS/390 application 0 region is to attempt to IDENTIFY (or attach) to IMS after the first IDENTIFY attempt fails.

246 Cross-Platform DB2 Stored Procedures: Building and Debugging Keyword Description Default FF FP

MAXTHRD 1-999. The maximum number of DRA thread TCBs 1 available at one time.

MINTHRD 1-999. The minimum number of DRA thread TCBs to be 1 available at one time.

SOD The output class used for a SNAP DUMP of abnormal AYY thread termination.

TIMEOUT Is the amount of time (in seconds) a CCTL should wait for 60 the successful completion of a DRA TERM request. This value should be specified only if the CCTL is coded to use it. This value is returned to the CCTL upon completion of an INIT request.

TIMER The time (in seconds) between attempts of the DRA to 60 identify itself to IMS DB or DB/DC during an INIT request.

USERID 1-8 character name of the CCTL or ODBA region. We have not set it for our examples.

8.10.2.1 IMS Fast Path considerations In this section we offer some considerations on the use of IMS Fast Path.

Normal buffer allocation for CCTL regions and threads CCTL (coordinator control) regions, requiring Fast Path resources, need the following parameters specified in the DRA start-up table: • CNBA — is the normal buffer allocation of each active CCTL region. • FPB — is the normal buffer allocation for CCTL threads.

When the CCTL connects to DBCTL, the number of CNBA buffers is page fixed in the Fast Path buffer pool. However, if CNBA buffers are not available, the connect fails.

Each CCTL thread that requires DEDB buffers is assigned its Fast Path buffers (FPB) out of the total number of CNBA buffers.

For planning and monitoring purposes, we can run the IMS monitor to check I/O to bufferpools, or use tools such as IMS Performance Analyzer to evaluate the impact of adding ODBA access to your Fast Path bufferpools.

During IMS control region initialization, parameters are read in and listed by DFS0578I messages.

Chapter 8. DB2 stored procedures and IMS 247 The CNBA must be at least as large as the FPBUF x MAXTHRD, but small enough so as not to fail during identify.

CNBA = (FPBUF x MAXTHRD) + FPBOF

A number of the IMS PROCLIB startup parameters in member DFSPBxxx relate to Fast Path. DBBF is the number of buffers in the IMS Fast Path buffer pool. DBFX is the number of IMS Fast Path buffers that are long term page fixed during IMS startup (a subset of DBBF). BSIZ is the size of a single buffer. FPBUF is allocated from DBBF (CNBA must be less than DBBF).

All the FPBOF (and OBA, Overflow Buffer Allocation) values for all dependent regions are compared, IMS gets a single OBA allocation based on the largest OBA value used in the IMS system (allocated out of DBBF). When one user needs it (watch for IMS status code GC), it becomes a serialized resource (so is something to avoid).

In our DBCTL environment, we do not have Fast Path and therefore these numbers are set to zero.

For a description of Fast Path DEDB buffer usage, see IMS/ESA Version 6 Administration Guide: System, SC26-8730.

8.10.3 Security considerations IMS resources accessed from an AEE and an unauthorized AEE connections to the IMS 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 IMS. 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 IMS. Note that connection to different IMS systems from the same stored procedures address space, can have different USERID and AGN security because the IMS 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.

248 Cross-Platform DB2 Stored Procedures: Building and Debugging The ISIS value is in the start up DFSPBxxx member. Also if we have TYPE=(NOAGN,...) in the security macro in the IMS gen, we turn off security and will not need to specify an AGN. If you use IMS default security, you can execute transactions, but not commands.

Refer to section 1.4, “Establishing IMS Security” in the IMS Administration Guide: System for an in depth discussion about IMS security.

8.10.4 Making calls to IMS You can code the ODBA stored procedure in any language supported by DB2 stored procedures except for SQL Procedures Language, REXX, and Java. You access IMS databases using the language CALL statement the AERTDLI interface (DFSCDLI0).

The AERTDLI entry point for PL/I programs must be declared as an assembler language entry: DCL AERTDLI OPTIONS(ASM);

The format of the CALL is: CALL AERTDLI parmcount,function,AIB,...

Where: • parmcount is an optional parameter which 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. This is kept for compatibility with the existing syntax for the IMS language interface module. • 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.

Table 14 shows the IMS function calls supported by the ODBA-callable interface. The GU/GN/ISRT calls to I/O PCB are not supported because no access is provided to the IMS message queues. The I/O PCB is only for DL/I system service calls.

Chapter 8. DB2 stored procedures and IMS 249 Table 14. IMS function calls supported by ODBA Database function calls System function call

DEQ CIMS DLET APSB FLD DPSB GHN ICMD GHNP INIT GHU INQY (also add to parameter list - GN AIBFUNC=FIND|DBQUERY|ENVIRON) GNP LOG GU RCMD ISRT ROLS POS SETS/SETU REPL SNAP STAT

Important! • For the INQY function call, the PROGRAM subfunction is not supported. • ROLL and ROLB are not supported because RRS is used as the syncpoint manager. Although SRRBACK and ATRBACK are supported with RRS, you cannot issue them from a stored procedure. • ROLS, SETS/SETU should not be used in an ODBA DB2 stored procedure because you cannot issue COMMITs from within a DB2 stored procedure (V6). These IMS function calls only apply to full function DLI resources and not DEDB or DB2 that may also have been updated. • 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.

8.10.4.1 The application interface block (AIB) The AIB is used by application programs to issue IMS DL/I calls using a PCB name instead of a PCB address, or to issue calls which are not associated with a PCB. It provides a standard mechanism for IMS and the application to exchange information. The AIB mask enables application programs to interpret the control block defined.

250 Cross-Platform DB2 Stored Procedures: Building and Debugging The AIB structure must be defined in working storage, on a fullword boundary, and initialized according to the order and byte length of the fields as shown in Table 15. The field description column describes each field. Where it straddles across columns, the field must be initialized according to the description. For example, for APSB, DL/I and DPSB calls, the AIBID must be initialized with ‘DFSAIB’.

Figure 86 shows the fields defined in the AIB. The arrows from the ODBA application program (1) in the diagram show fields that need to be set prior to an IMS call. Some calls actually require fewer fields that indicated in the diagram.

The arrows from DFSCDLI0 / AERTDLI (2) show the more important fields set by AERTDLI. The greyed out fields should be of no concern to the application program. Apart from the return code AIBRETRN and reason code AIBREASN, of particular interest are the field AIBRSA1 that contain a pointer to the program communication block (PCB) and the field AIBRSA3 which contains the thread token. The thread token is returned after the APSB call and all subsequent calls must use this token to access the allocated PSB.

AIB

AIBID 1 AIBLEN ODBA stored procedure AIBSFUNC AIBRSNM1 AIBRSNM2 AIBRESV1 2 AIBOALEN DFSCDLI0 AIBOAUSE AERTDLI AIBRESV2 DB PCB AIBRETRN AIBREASN DB name AIBERRXT Segment level AIBRSA1 Status code AIBRSA2 PROCOPT AIBRSA3 Reserved AIBSAVE Segment name AIBTOKN KFDB length #ofsenseg KFDB area thread token

Figure 86. Using AERTDLI and the AIB Application Interface Block

Chapter 8. DB2 stored procedures and IMS 251 Table 15 shows the each of the fields in an AIB mask. This table is adapted to describe how the fields are used in common calls made by DB2 ODBA stored procedures. For a more complete treatment, please refer to IMS Version 7 Application Programming: Database Manager, SC26-9422. Table 15. Contents of AIB for AERTDLI calls by DB2 ODBA stored procedures Field name Field description Usage

APSB DL/I calls using DPSB PCBs

AIBID AIB identifier. 8-byte char field. You must initialize AIBID in your application program to ‘DFSAIBbb’,where‘b’ is a blank, before you issue DL/I calls. This field is required. When the call is completed, the information returned in this field is unchanged.

AIBLEN DFSAIB Allocated Length. 4 byte Before you issue DL/I calls, you must initialize this binary field. length to the actual length of the AIB you allocated. This field contains the actual For ODBA, the AIB length must be at least 264. 4-byte length of the AIB as When the call is completed, the information returned defined by your program. in this field is unchanged. This field is required.

AIBSFUNC Subfunction Code. 8-byte char ‘PREPbbbb’ field. Contains the subfunction code for those calls that use a subfunction. You must initialize AIBSFUNC in your application program before you issue DL/I calls. When the call is completed, the information returned in this field is unchanged.

AIBRSNM1 Resource Name. 8-byte char PSB name PCBNAME PSB name field. Contains the name of a The PCB name for resource, which varies PCBs is defined in depending on the call. You must the PCBNAME= initialize AIBRSNM1 in your parameter in application program before you PSBGEN. issue DL/I calls. When the call is complete, the information returned in this field is unchanged. This field is required.

AIBRSNM2 Resource Name 2. 8 byte char DRA startup table identifier xxxx. IMS takes the field. 4-byte value xxxx and generates DRA startup table member name DFSxxxx0 from it.

AIBRESV1 Reserved

252 Cross-Platform DB2 Stored Procedures: Building and Debugging Field name Field description Usage

APSB DL/I calls using DPSB PCBs

AIBOALEN Maximum Output Area Length. You must initialize AIBOALEN in your application 4-byte binary field. Contains the program for all calls that return data to the output length of the output area in bytes area. When the call is completed, the information that was specified in the call list. returned in this area is unchanged.

AIBOAUSE Used Output Area Length. 4-byte Returned by IMS for all calls that return data to the binary field. output area. When the call is completed this field contains the length of the I/O area used for this call.

AIBRESV2 Reserved

AIBRETRN Return code. 4 byte binary field. Always check these. When the call is completed, this 4-byte field contains the return code. Notice these are given in decimal. You need to convert them to hexadecimal to check with the manuals. If you have hex 900 here, you must check PCB for IMS status code

AIBREASN Reason Code. 4 byte binary field. Always check these. When the call is completed, this 4-byte field contains the reason code. Again convert to hexadecimals first before looking up the manuals.

AIBERRXT Error Code Extension. 4-byte field. Contains additional error information depending on the return code in AIBRETRN and the reason code in AIBREASN.

AIBRSA1 Resource Address. 4 byte Contains PCB address field. address returned by IMS.

AIBRSA2

AIBRSA3 Resource Address 3. 4 byte The APSB call returns a 4 byte thread token. This address field. thread token is required for all subsequent DL/I calls, and the DPSB call related to this thread.

AIBRESV4

AIBSAVE Save area for AER, 72 bytes reserved

AIBTOKN 56 bytes reserved

AIBTOKC Name value. 16 byte char field

Chapter 8. DB2 stored procedures and IMS 253 Field name Field description Usage

APSB DL/I calls using DPSB PCBs

AIBTOKV Token value. 16 byte char field

AIBTOKA Name/token area for AER

Figure 87 is a sample AIB mask written in PL/I.

/*******************************************************************/ /* AIB */ /*******************************************************************/

DECLARE 1 AIB , 3 AIBID CHAR(8), /* EYECATCHER - 'DFSAIB ' */ 3 AIBLEN FIXED BIN (31), /* DFSAIB ALLOCATED LENGTH */ 3 AIBSFUNC CHAR(8), /* SUBFUNCTION CODE */ 3 AIBRSNM1 CHAR(8), /* RESOURCE NAME 1 */ 3 AIBRSNM2 CHAR(8), /* RESOURCE NAME 2 */ 3 AIBRESV1 CHAR(8), /* RESERVED */ 3 AIBOALEN FIXED BIN (31), /* OUTPUT AREA LENGTH (MAX) */ 3 AIBOAUSE FIXED BIN (31), /* OUTPUT AREA LENGTH (USED) */ 3 AIBRESV2 CHAR(12), /* RESERVED */ 3 AIBRETRN FIXED BIN (31), /* RETURN CODE */ 3 AIBREASN FIXED BIN (31), /* REASON CODE */ 3 AIBERRXT FIXED BIN (31), /* ERROR CODE EXTENSION */ 3 AIBRSA1 PTR , /* RESOURCE ADDRESS 1 */ 3 AIBRSA2 PTR , /* RESOURCE ADDRESS 2 */ 3 AIBRSA3 PTR , /* RESOURCE ADDRESS 3 */ 3 AIBRESV4 CHAR(40), /* RESERVED @PQ15784*/ 3 AIBSAVE (18) FIXED BIN (31), /* SA for AERAIB calls @PQ15784*/ 3 AIBTOKN (6) /* NAME/TOKEN AREA FOR AER@PQ15784*/ FIXED BIN (31), 3 AIBTOKC CHAR(16), /* NAME VALUE @PQ15784*/ 3 AIBTOKV CHAR(16), /* TOKEN VALUE @PQ15784*/ 3 AIBTOKA (2) /* NAME/TOKEN AREA FOR AER@PQ15784*/ FIXED BIN (31) ;

Figure 87. A PL/I example of an AIB mask

254 Cross-Platform DB2 Stored Procedures: Building and Debugging Table 16 shows the IMS DL/I calls and the fields that need updating, in addition to AIBID, AIBLEN, AIBOALEN. The shaded rows denote calls that a stored procedure will not need to code. The CIMS INIT call is done by the WLM SPAS itself. The CIMS TALL is also done by WLM SPAS when it shuts down.

DPSB calls with blank subfunction requires that a commit has taken place. With IMS, a DPSB without prior commit will always lead to backout. Since DB2 stored procedures themselves cannot issue commits, we cannot issue DPSB calls with blank subfunction. Table 16. How to fill in the AIB for typical IMS DL/I calls AIBRSNM1 AIBRSNM2 AIBSFUNC AIBOALEN

CIMS INIT

APSB PSBname ODBA startup table

DLET

GN / GHN DB PCB name Length of I/O area in the GNP / GHNP call list ISRT

REPL

DPSB PSB name

DPSB PSB name PREP

CIMS TERM

CIMS TALL

Apart from PCB-related calls, you can also use system service calls such as the STAT command, which obtains monitoring information about buffer usage for performance.

8.10.5 Writing an ODBA program We now describe how to use the AERTDLI interface and look at some of the most commonly used calls.

Chapter 8. DB2 stored procedures and IMS 255 8.10.5.1 Using the DFSCDLI0 AERTDLI interface For non-ODBA IMS DB programming, the application always goes through the IMS control region DFSRRC00 to initialize the IMS environment. The PCB pointers are passed back to the application. IMS calls are made using the DFSLI000 language interface with entry points ASMTDLI, CBLTDLI, CEETDLI and PLITDLI etc.

With ODBA programming, the IMS control blocks are built through an APSB call (or environments other than WLM established DB2 stored procedures, through a CIMS INIT with an IMS subsystem ID specified). References to PCBs are via the label specified by the PCBNAME keyword in a PSB or the label in the PCB macro as shown in Figure 88.

PCBNAME is an optional keyword in the PSB macro. Since ODBA requires PCBNAME, not all existing PSBs will work with ODBA. You may need to add a PCBNAME keyword for those PCBs you wish to access. Alternatively you can code a new PSB.

PCB TYPE=DB,DBDNAME=IVPDB1,PROCOPT=A,KEYLEN=10,SB=COND SENSEG NAME=A1111111,PARENT=0,PROCOPT=A PCBLABEL PCB TYPE=DB,DBDNAME=IVPDB1,PROCOPT=A,KEYLEN=10,SB=COND SENSEG NAME=A1111111,PARENT=0,PROCOPT=A PCB TYPE=DB,DBDNAME=IVPDB1,PCBNAME=PCBNAME1, X PROCOPT=A,KEYLEN=10,SB=COND SENSEG NAME=A1111111,PARENT=0,PROCOPT=A PSBGEN LANG=ASSEM,PSBNAME=MINGPSB,CMPAT=YES,OLIC=YES END

Figure 88. Which PCBs will work with ODBA

CMPAT=YES is required if your application program is going to use IMS System Service DL/I calls that use an IO/PCB and in the IMS gen on the APPLCTN macro you defined your PSB as BATCH.

8.10.5.2 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 DSNX9WLM to initialize and to terminate the ODBA environment. You do not need to code CIMS calls inside a stored procedure.

256 Cross-Platform DB2 Stored Procedures: Building and Debugging The following subfunctions are supported: • INIT, which establishes the ODBA environment • TERM, which terminates one and only one IMS connection. AIBRSNM2 which specifies the 4 character ID of the startup table member representing the IMS connection to be terminated. You must also put in AIBRSA3 the thread token which passed back from IMS when you first executed the APSB call. • TALL, which terminates all IMS connections and terminates the ODBA environment in the application address space (the WLM SPAS in case of DB2 ODBA stored procedures).

The CIMS INIT is done by DB2 during initialization of the stored procedures address space and not by the stored procedure. Therefore, you do not 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 TALL when shutting down the WLM-SPAS.

8.10.5.3 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 AERTDLI parmcount,APSB,AIB

Where: • parmcount is an optional 4-byte binary field with the value of 2. • APSB is the function call. • AIB is the application interface block.

The purpose of the APSB call is to allocate a PSB and specify which IMS (within the same MVS image) to connect to.

You must set the following fields in the AIB: • AIBRSNM1 to the PSB name • AIBRSNM2, to the ID of the IMS that you wish to connect

After the call is executed, the AIB contains the fields shown in Table 17.

For every successful APSB call, you must have a corresponding DPSB call to deallocate the PSB. Each successful APSB call gives you a thread token which is returned in AIBRSA3 in the AIB mask.

Chapter 8. DB2 stored procedures and IMS 257 Table 17. AIB Mapping after executing CALL AIB field Description AIBID 8 byte character field eyecatcher (‘DFSAIB ’) AIBLEN 8 byte binary field length of AIB (264) AIBSFUNC 8 byte character field with blanks AIBRSNM1 jobname - 6 bytes, ASID - 2 bytes AIBRSNM2 IMS name AIBRSA1 chain pointer for connection AIBs AIBRSA2 ECB AIBSAVE address of IDENTIFY TCB for this IMS 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 Section 8.10.5.4, “DPSB Call” on page 258.

When you use a new APSB call, you can also change the IMS ID in the AIB, by specifying a different IMS ID as the resource name. This way you can process different sets of IMS databases if you have different IMS control regions.

8.10.5.4 DPSB Call The DPSB call deallocates a PSB and terminates the connection from a stored procedure to IMS. The format of the DPSB call is the following: CALL AERTDLI parmcount,DPSB,AIB

Where: • parmcount is a 4-byte binary field with the value of 2. • DPSB is the function call. • AIB is the application interface block.

You must set the following fields in the AIB: • AIBRSNM1 to the PSB name. • AIBSFUNC is the subfunction and should be set to the string PREP for stored procedures

258 Cross-Platform DB2 Stored Procedures: Building and Debugging The DPSB call releases the PSB, terminates the thread to IMS, and completes signoff processing. If the stored procedure does not update IMS databases, no locks are 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 syncpoint processing on behalf of the stored procedure.

8.10.5.5 Syncpoint processing The IMS DBCTL utilizes: • OS/390 Registration Services • OS/390 Resource Recovery Services (RRS) • OS/390 Context Services

This is done when the services are available. Since DBCTL is a participant in syncpoint processing, it uses a two-phase commit to record a syncpoint. In general an AEE application program uses the RRS to process commit or roll back using the following interfaces: • ATRCMIT/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.

8.10.5.6 Link-edit requirements All DB2 stored procedures that use SQL and execute in a WLM-established stored procedure address space must be link-edited with DSNRLI.

All IMS ODBA programs must be link-edited with a special version of the IMS language interface DFSCDLI0 (not DFSLI000). They can call the IMS interface dynamically by loading DFSCDLI0 (or its alias AERTDLI).

This new module provides the AERTDLI application interface block for an OS/390 AEE application region.

8.10.5.7 Runtime requirements For a general ODBA application, when using the AERTDLI interface for C/MVS, COBOL, or PL/I language application programs, the language run-time options for suppressing abend interception (that is, NOSPIE and NOSTAE) must be specified.

Chapter 8. DB2 stored procedures and IMS 259 For Language Environment-conforming application programs, the NOSPIE and NOSTAE restriction is removed. As DB2 stored procedures all use LE, this requirement is automatically taken care of.

8.10.6 What happens when the ODBA stored procedure runs An DB2 ODBA stored procedure executes in the WLM SPAS just like any DB2 stored procedure defined with a WLM application environment. It also communicates with the IMS control region in order to process DL/I calls. Failures can occur not only in the WLM SPAS but also in the IMS control region.

Symptoms of potential problems can manifest themselves anywhere from the DB2 client, the WLM SPAS or the IMS side.

In order to gain a better understanding of how to investigate problems, we now look at the sequence of events leading up to the ODBA stored procedure establishing a connection to IMS DBCTL. 1. Submit JCL to invoke client program 2. Client program connects to database server and CALLs stored procedure 3. SYSIBM.SYSROUTINES defines which stored procedure to be started in which WLM application environment 4. If the stored procedure address space is not already running, it will be started up. 5. The stored procedure address space program DSNX9WLM notices the DFSRESLB DD statement and issues a CIMS INIT call without specifying DRA table name. 6. On successful establishment of ODBA environment, we see a message in the stored procedure address space: +DSNX991I DSNX9WLM IMS ODBA INITIALIZATION COMPLETED If unsuccessful, you will get +DSNX992E IMS ODBA INITIALIZATION FAILURE, AIB RC = 7. Stored procedure starts up. On successful APSB call, the ODBA syncpoint mother and daughter TCBs are initialized. You will see the following 2 messages issued in the IMS control region DFS3613I - ODM TCB INITIALIZATION COMPLETE IMSD DFS3613I - ODS TCB INITIALIZATION COMPLETE IMSD

260 Cross-Platform DB2 Stored Procedures: Building and Debugging These messages only occur once for each IMS control region. So once established, the ODBA syncpoint support remains in the IMS control region until it comes down. 8. The ODBA stored procedure issues a DPSB PREP for each APSB call on successful completion. 9. The WLM SPAS finally issues a CIMS TALL to sever all IMS connections and then shuts down.

Figure 89 shows how the various address spaces interact with each other.

Client application DB2 1 DDF MSTR DBM1 IRLM CONNECT

SQL Call 2 SYSIBM schema.stproc SYSROUTINES:

WLM_ENV External name

3 WLM IMSD LE SPAS CIMS INIT schema.stproc call AERTDLI appl APSB PSBname A load lib startup table A PSBname A

DL/I calls DRA startup table A

DFSPRP ... call AERTDLI DBCTLID=IMSD... DPSB PREP CIMS TALL

Figure 89. DB2 ODBA stored procedure flow

8.10.7 The life of a thread in a DB2 ODBA stored procedure Table 18 describes the life of a thread. Threads are allocated when the connection to IMS is made, not when a PSB is scheduled. The difference between CICS and ODBA is that under CICS, there is an actual thread TCB (that belongs to the DRA not to CICS) whereas ODBA does not own the thread TCB. However, ODBA will allocate MINTHRD thread blocks that are reused. Additional thread blocks are allocated (up to MAXTHRD) as required.

Chapter 8. DB2 stored procedures and IMS 261 Table 18. Life of a dependent region versus life of a thread Process IMS (ODBA) What you see DB2 stored DB2 stored procedure calls in the IMS procedure control region address space address space DSNX9WLM

Identify APSB or CIMS Issues CIMS with DRA startup when WLM SPAS table prefix starts up

Signon / APSB ODM message The stored procedure can Create allocate multiple PSBs if the thread DRA startup table allows it to. The SP is completely Signoff / DPSB or DPSB ODS message responsible for the thread Terminate PREP tokens. thread

Terminate CIMS TERM + Issues CIMS TALL identify prefix, or CIMS when SPAS shuts TALL down

Table 19 shows where and how to find each of the different names associated with the life of a DB2 ODBA stored procedure invocation. Table 19. Putting the pieces together for DB2 ODBA stored procedure Client address Stored procedure DB2 IMS console space address space

Client program -dis thd(*) det at server

Stored procedure At server: with /DIS CCTL ALL -dis thd(*) det command, we can see the -dis proc(*.*) WLM stored procedure address space name

PSB name - - - with /DIS CCTL ALL and with /DIS A show the PSB name, and the status (for example, ACTIVE)

RRS UOR ID with /DIS CCTL ALL or use /DIS UOR

262 Cross-Platform DB2 Stored Procedures: Building and Debugging Figure 90 shows the output from an IMS command: /DIS CCTL ALL

CCTL stands for Coordinator Controller. It is a subsystem consisting of the database resource adapter (DRA) and a transaction management subsystem, such as CICS.

For DB2 ODBA stored procedures, we can look at RRS being the controller with commit requests initiated from DB2. A CCTL provides communications and transaction management services for a DBCTL environment, which has no transaction management facilities of its own.

You can see the CCTL ID which is ODBA01FC. This identifies our DB2 WLM SPAS. The last 4 bytes of this identifier / token corresponds to the ASIDX field in SDSF (as opposed to ASID which is the decimal representation of ASIDX). This is the same as the ASID field you can see in the SPAS job output in IEF403I and IEF404I messages:

IEF403I WLMIMS - STARTED - TIME=18.32.04 - ASID=01FC.

IEF404I WLMIMS - ENDED - TIME=18.37.06 - ASID=01FC.

The CCTL ID uses this format as opposed to the job name of the WLM SPAS because there can be more than one WLM SPAS of the same name executing concurrently. The ASID provides uniqueness.

The status of active with a non-zero recovery token implies a PSB has been scheduled, and we have an active thread to this IMS. (See Figure 90.)

DFS4445I CMD FROM MCS/E-MCS CONSOLE USERID=DB2RES1: DIS CCTL ALL IMSD DFS000I MESSAGE(S) FROM ID=IMSD CCTL PSEUDO-RTKN RECOVERY-TOKEN REGID PSBNAME STATUS ODBA01FC ATTACHED 0000000200000000 1 SJCPSB ACTIVE *00311/142649*

Figure 90. Using DIS CCTL ALL command to identify jobname

Figure 91 shows the output from an IMS command to display units of recovery: /DIS UOR

You can use these two commands in IMS to show you the RRS unit of recovery ID.

Chapter 8. DB2 stored procedures and IMS 263 DFS4445I CMD FROM MCS/E-MCS CONSOLE USERID=DB2RES1: DIS UOR IMSD DFS000I MESSAGE(S) FROM ID=IMSD ST P-TOKEN PSBNAME RRS-URID IMS-RECTOKN A SJCPSB B4E7DEE97EA9B2C80000009B01060000 ODBA01FC00 + 00000200000000 LUWID=08BA1048AER TASK FOR ODBA *00311/142708* DFS3613I - ODS TCB INITIALIZATION COMPLETE IMSD

Figure 91. Output from DIS UOR in IMS

Next we can go into the RRS ISPF application to see what RRS thinks the status is for this particular unit of recovery (Figure 92).

SC61 2000/11/06 14:29:15.550918 BLOCKID=00000000005118B9 URID=B4E7DEE97EA9B2C80000009B01060000 JOBNAME=DBZ2MSTR USERID=STC PARENT URID=00000000000000000000000000000000 WORK MANAGER NAME=DSN.RRSPAS.IBM.DBZ2 SYNCPOINT=AtraCmt RETURN CODE=00000000 START=2000/11/06 19:29:15.353094 COMPLETE=2000/11/06 19:29:15.550684 EXITFLAGS=00800000 LUWID= TID= GTID=

FORMATID= (decimal) (hexadecimal) GTRID=

BQUAL=

RMNAME=DSN.RRSPAS.IBM.DBZ2 ROLE=SDSRM FLAGS=10000000 PROTOCOL=PresumeNothing StateCheck EXIT RC=Uncalled Prepare EXIT RC=00000000 DistSp EXIT RC=Uncalled Commit EXIT RC=Uncalled Backout EXIT RC=Uncalled EndUr EXIT RC=Uncalled ExitFailed EXIT RC=Uncalled Completion EXIT RC=Uncalled OnlyAgent EXIT RC=Uncalled RMNAME=IMS.IMSD____V061.STL.SANJOSE.IBM ROLE=Participant FLAGS=10020000 PROTOCOL=PresumeAbort StateCheck EXIT RC=Uncalled Prepare EXIT RC=00000000 DistSp EXIT RC=Uncalled Commit EXIT RC=00000000 Backout EXIT RC=Uncalled EndUr EXIT RC=Uncalled ExitFailed EXIT RC=00000000 Completion EXIT RC=Uncalled OnlyAgent EXIT RC=Uncalled

Figure 92. RRS archive log from RRS Log Stream Browse Selection, option 1

264 Cross-Platform DB2 Stored Procedures: Building and Debugging 8.10.8 Application programming considerations Refer to Language Environment for OS/390 & VM: Writing Interlanguage Communication Applications, SC28-1943, which helps you to translate data types between languages.

If you have existing IMS code and you are porting to DB2 ODBA stored procedures, refer to the chapter on “Embedding SQL statements in host languages“ in DB2 UDB for OS/390 V6 Application Programming and SQL Guide, SC26-9004 for details. This manual has tables mapping the host programming language against SQL data types.

Table 20 has been reproduced from the SPB help for your convenience. This can be helpful if you are writing a Java client for your stored procedure. Table 20. Type mapping table for SQL, JDBC, and Java SQL JDBC Java

SMALLINT SMALLINT short

INTEGER INTEGER int

BIGINT BIGINT long

DECIMAL DECIMAL java.math.BigDecimal

REAL REAL float

DOUBLE DOUBLE double

CHAR CHAR, BINARY string, byte[]

CHAR FOR BIT DATA BINARY byte[]

VARCHAR VARCHAR, VARBINARY string, byte[]

VARCHAR FOR BIT DATA VARBINARY byte[]

LONGVARCHAR LONGVARCHAR, string, byte[] LONGVARBINARY

CLOB LONGVARCHAR string

GRAPHIC CHAR string

VARGRAPHIC VARCHAR string

LONGVARGRAPHIC LONGVARCHAR string

DBCLOB LONGVARCHAR string

DATE DATE java..Date

Chapter 8. DB2 stored procedures and IMS 265 SQL JDBC Java

TIME TIME java.sql.Time

TIMESTAMP TIMESTAMP java.sql.Timestamp

BLOB LONGVARBINARY byte[]

8.11 Sample DB2 ODB2 stored procedure scenarios Here are some scenarios to illustrate what we will see when we invoke the sample stored procedures.

8.11.1 DB allocation problem scenario The following scenario in Table 21 demonstrates why you should check DL/I status code even when AIBRETRN return code is not hex 900. We create a stored procedure to access an IMS database and we “omit” to register this database with DBRC.

If we had used INIT.RECON NOFORCER or CHANGE.RECON NOFORCER, this would not have happened. Table 21. Sequence of events for database allocation problem Action AIBRETRN AIBREASN DL/I Description status code

APSB 0 0 Successful

GU 264 (hex 580 (hex NA Although AIBRETRN is not 900, the DL/I unqualified 108) 244) status ‘NA’ already show us that the database SSA was unavailable. However notice that NA is not really for QUERY REFRESH ...

DPSB PREP 260 (hex 524 (hex The manuals say this is a CPIC driven issuing 104) 20C) DL/I call before scheduling a PSB.

Figure 93 shows the output from the IMS address space.

266 Cross-Platform DB2 Stored Procedures: Building and Debugging DFS4445I CMD FROM MCS/E-MCS CONSOLE USERID=DB2RES6: DIS PROG SJCPSB IMSD DFS000I MESSAGE(S) FROM ID=IMSD PROGRAM TRAN TYPE SJCPSB BMP *00310/213749* DFS000I MESSAGE(S) FROM ID=IMSD DFS2500I DATABASE SJCDB1 SUCCESSFULLY ALLOCATED DFS3613I - ODM TCB INITIALIZATION COMPLETE IMSD DFS000I MESSAGE(S) FROM ID=IMSD DFS047A - UNABLE TO OBTAIN AUTHORIZATION FOR DATA BASE SJCDB1 . REA + SON CODE = 20. PSB=SJCPSB DFS000I MESSAGE(S) FROM ID=IMSD DFS3303I PSB SJCPSB PCB SJCDB1 DBD SJCDB1 NOTAUTHD JOBNAM + E WLMIMS RGN 00001 DFS000I MESSAGE(S) FROM ID=IMSD DFS554A WLMIMS 00001 WLMIMS SJCPSB (5) 000,3303 2000 + /310 22:05:20 RTKN= ODBA009F0000000100000000

Figure 93. Output from IMS address space

We issue the /dis cctl all and /dis uor commands to get the output as shown in Figure 94.

DFS4445I CMD FROM MCS/E-MCS CONSOLE USERID=DB2RES4: DIS CCTL ALL IMSD DFS000I MESSAGE(S) FROM ID=IMSD CCTL PSEUDO-RTKN RECOVERY-TOKEN REGID PSBNAME STATUS ODBA009F ATTACHED *00310/222531* DFS4445I CMD FROM MCS/E-MCS CONSOLE USERID=DB2RES4: DIS UOR IMSD DFS000I MESSAGE(S) FROM ID=IMSD ST P-TOKEN PSBNAME RRS-URID IMS-RECTOKN *00310/222548*

Figure 94. Output from DIS CCTL ALL and DIS UOR commands

Figure 95 shows the output from a display thread command in DB2.

Chapter 8. DB2 stored procedures and IMS 267 =DBZ2 DIS PROC(DB2RES1.OD1*) DSNX940I =DBZ2 DSNX9DIS DISPLAY PROCEDURE REPORT FOLLOWS - 667

------SCHEMA=DB2RES1 PROCEDURE STATUS ACTIVE QUEUED MAXQUE TIMEOUT WLM_ENV OD1APMS STARTED 1 0 1 0 WLMIMSD DSNX9DIS DISPLAY PROCEDURE REPORT COMPLETE DSN9022I =DBZ2 DSNX9COM '-DISPLAY PROC' NORMAL COMPLETION =DBZ2 DIS THD(*) DETAIL DSNV401I =DBZ2 DISPLAY THREAD REPORT FOLLOWS - DSNV402I =DBZ2 ACTIVE THREADS - 672 NAME ST A REQ ID AUTHID PLAN ASID TOKEN SERVER SP 1288 db2spb.exe DB2RES1 DISTSERV 0081 245 V437-WORKSTATION=N00ECE43, USERID=db2res1, APPLICATION NAME=db2spb.exe V436-PGM=NULLID. , SEC=0, STMNT=0 V429 CALLING PROCEDURE=DB2RES1 .OD1APMS , PROC=WLMIMS , ASID=009F, WLM_ENV=WLMIMSD V445-G901973A.GE04.001106025949=245 ACCESSING DATA FOR 9.1.151.58 V447--LOCATION SESSID A ST TIME V448--9.1.151.58 33370:1038 W S2 0031022051757

Figure 95. Output from DISPLAY THREAD command in DB2

It may be easier when creating a new database to run the IMS test program DFSDDLT0 as a BMP to make sure we can access the database.

8.11.2 PSB not found scenario A PSB was not defined to IMS: we did not perform an online change. We invoked OD1DPMS with the following parameters: DRA_STARTUP_TABLE = IMSD PSB = NOTHERE1 PCB = NOTHERE2 SEGMENT_NAME = NOTHERE3 FUNCTION = ???????? PAUSE = N

When we run it, we can see from the WLM SPAS got in Table 22:

Table 22. PSB not found problem Action AIBRETRN AIBREASN DL/I status code Description

An IMS call 264 (hex 108) 772 (hex 304) PSB not found involving a PCB

268 Cross-Platform DB2 Stored Procedures: Building and Debugging This can easily be checked by issuing the /DIS PROG NOTHERE IMS command. To resolve this problem, you will need to define the program: 1. Make sure DBD has been generated successfully 2. Make sure PCBNAME is coded for PCBs in PSB required for ODBA programming 3. Generate ACB 4. Upgrade IMS source (for example, in IV_C201T) for IMS stage 1 generation to add APPLCTN macros defining the program/PSB: APPLCTN PSB=NEWPSB,PGMTYPE=BATCH 5. Run IMS stage 1 and stage 2 MODBLKS generation 6. Run online copy for ACB, MODBLKS and FORMAT 7. Perform online change for MODBLKS and ACB using /modify prepare ... /modify commit For a DB/DC system, you can display what programs have changed at this point using: /modify prepare lterm wtor 8. Use /dis prog NEWPSB to check the PSB using the NEWPSB PSB is ready for testing

8.11.3 Running multiple DB2 ODBA SPs to the same IMS Client 1 executes DB2RES1.OD1DPMS specifying PAUSE = ‘Y’ to keep the thread active until we reply to the outstanding operator message.

Client 1: DRA_STARTUP_TABLE = IMSD PSB = SJCPSB PCB = DB1PCB1 SEGMENT_NAME = FOOTPRNT FUNCTION = ???????? PAUSE = Y

We follow this by client 2 executing DB2RES1.OD1CPMS.

Client 2: DRA_STARTUP_TABLE = IMSD PSB = SJCPSB FUNCTION = ???????? PAUSE = N

Chapter 8. DB2 stored procedures and IMS 269 We want to allow a maximum of 4 threads to our IMS via the DRA. MAXTHD in the DRA startup table was coded as 4. Our PSB SJCPSB was not coded with SCHDTYP=PARALLEL in the APPLCTN macro. The second client received what is shown in Table 23: Table 23. Reaching limit of MAXTHD in DRA startup table Action AIBRETRN AIBREASN DL/I Description status code

An APSB 264 (hex 788 (hex The PSB could not be allocated since it was call 108) 314) already scheduled and it does not support parallel scheduling.

If we had exceeded MAXTHD, we would get a return code of hex 104 and reason code hex 22C.

From the output of /dis cctl all in Figure 96, we can see we have an active thread.

DFS4445I CMD FROM MCS/E-MCS CONSOLE USERID=DB2RES1: DIS CCTL ALL IMSD DFS000I MESSAGE(S) FROM ID=IMSD CCTL PSEUDO-RTKN RECOVERY-TOKEN REGID PSBNAME STATUS ODBA009E ATTACHED 0000001B00000000 1 SJCPSB ACTIVE *00328/051652* DFS000I MESSAGE(S) FROM ID=IMSD DFS554A WLMIMS 00002 WLMIMS SJCPCB (5) 000,0428 2000 + /328 5:17:23

Figure 96. Output from /DISPLAY CCTL ALL

270 Cross-Platform DB2 Stored Procedures: Building and Debugging Figure 97 shows the output from DB2 DISPLAY THD and DISPLAY PROC.

DSN9022I =DBZ2 DSNVDT '-DIS THD' NORMAL COMPLETION DSNV401I =DBZ2 DISPLAY THREAD REPORT FOLLOWS - DSNV402I =DBZ2 ACTIVE THREADS - NAME ST A REQ ID AUTHID PLAN ASID TOKEN SERVER SP 1382 db2spb.exe DB2RES1 DISTSERV 0084 25 V437-WORKSTATION=*, USERID=db2res1, APPLICATION NAME=db2spb.exe V436-PGM=NULLID. , SEC=0, STMNT=0 V429 CALLING PROCEDURE=DB2RES1 .OD1CPMS , PROC=WLMIMS , ASID=00A3, WLM_ENV=WLMIMSD V445-G9B9D44A.N408.01CB23090303=25 ACCESSING DATA FOR 9.185.212.74 V447--LOCATION SESSID A ST TIME V448--9.185.212.74 33370:2164 W S2 0032805165049 SERVER SP 1385 db2spb.exe DB2RES2 DISTSERV 0084 26 V437-WORKSTATION=*, USERID=db2res2, APPLICATION NAME=db2spb.exe V436-PGM=NULLID. , SEC=0, STMNT=0 V429 CALLING PROCEDURE=DB2RES1 .OD1DPMS , PROC=WLMIMS , ASID=009E, WLM_ENV=WLMIMSD V445-G9B9D44A.N808.023F23090430=26 ACCESSING DATA FOR 9.185.212.74 V447--LOCATION SESSID A ST TIME V448--9.185.212.74 33370:2168 W S2 0032805095769 DISPLAY ACTIVE REPORT COMPLETE DSN9022I =DBZ2 DSNVDT '-DIS THD' NORMAL COMPLETION DSNX940I =DBZ2 DSNX9DIS DISPLAY PROCEDURE REPORT FOLLOWS -

------SCHEMA=DB2RES1 PROCEDURE STATUS ACTIVE QUEUED MAXQUE TIMEOUT WLM_ENV OD1BPMS STARTED 0 0 1 0 WLMIMSD OD1CPMS STARTED 1 0 1 0 WLMIMSD OD1DPMS STARTED 1 0 1 0 WLMIMSD DSNX9DIS DISPLAY PROCEDURE REPORT COMPLETE DSN9022I =DBZ2 DSNX9COM '-DISPLAY PROC' NORMAL COMPLETION

Figure 97. Output from DB2 DISPLAY THREAD and DISPLAY PROCEDURE

Since the stored procedure is not doing any SQL, SEC and STMT are both 0. NULLID is the collection ID associated with the calling package. Since DB2 has not identified a program (DBRM), we have blanks for the program name after NULLID.

Chapter 8. DB2 stored procedures and IMS 271 The general format for V436 is:

DSNV436I PGM=collection.package, SEC=section, STMNT=statement

This message appears in the output of the Display Thread report when a detail display is specified. The message is displayed if the DB2 database is currently processing an SQL statement and if so, identifies the program and specific SQL statement within the program of the current SQL statement being executed. collection The collection ID associated with the package. If the SQL statement being executed is not associated with a package, rather, it is associated with a DBRM that was directly bound as part of the plan, then the collection ID is not applicable and is indicated by an asterisk (*). package The package or DBRM member. section The SQL section number associated with the package or DBRM. statement The SQL statement number associated with the package or DBRM.

The message number and subsystem recognition character are not included in this message. However, V436 is included in the message text to identify the message.

In DB2 V7, the V436 message will not be displayed if the SP has not issued any SQL.

8.11.4 DRA initialization problem case study for Fast Path We use both DBCTL and DB/DC IMS systems for our examples. The following in Table 24 is a description of how we tracked down a DRA initialization problem in a Fast Path DB/DC environment.

For this example, we were using the DB2 supplied sample, DSNTEJ62. When we specified a DRA startup table which was not coded correctly, our stored procedure gets an error during the APSB call. Table 24. Sequence of events for DRA initialization problem Action AIBRETRN AIBREASN DL/I Description status code

APSB 264 (hex 1344 (hex No active communication with IMS DB 108) 540)

272 Cross-Platform DB2 Stored Procedures: Building and Debugging We can see a CCTLSNAP DD statement in our WLM SPAS. The CCTLSNAP is issued by DB2 side. Look for ‘FAILURE’.

JOB WLMIMS STEP WLMIMS TIME 224144 DATE 00297 PAGE 00000014

-STORAGE DRA FAILURE 0B5DFD80 40404040 * * DFSPRA10, DBCTL FAILURE DURING IDENTIFY 0B5DFD80 40404040 * * CCTL IDENTIFIER 0005AD40 E6D3D4C9 D4E24040 * WLMIMS * FAILURE REASON CODE 0005ABA0 80000038 * .... *

In the case above, the reason code is hex 38 (at the end of the x’80’) and this translates to decimal 56. This value x'80000038' should also be in the AIB field AIBERRXT. Next we look up ABENDU0056 in the IMS Version 7 Failure Analysis and Structure Tables (FAST) for Dump Analysis, LY37-3739 to find out the message for the error.

We can find out how our IMS is set up for Fast Path: IMS V7 echoes buffer settings in the IMS address space. If you are running IMS V6, you will need to look at the PROCLIB members mentioned during IMS startup for information.

Y IMS710B STC13982 DSID 2 LINE 0 COLUMNS 02- 133 SCROLL ===> CSR ************** TOP OF DATA ******************************************** JES2 JOB LOG --SYSTEM SC61 --NODE WTSCP

--- MONDAY, 23 OCT 2000 ---- IEF695I START IMS710B WITH JOBNAME IMS710B IS ASSIGNED TO USER STC $HASP373 IMS710B STARTED IEF403I IMS710B - STARTED - TIME=21.51.48 - ASID=0209. DFS0578I - READ SUCCESSFUL FOR DDNAME PROCLIB MEMBER = DFSPBIV1 IMSB DFS0578I - READ SUCCESSFUL FOR DDNAME PROCLIB MEMBER = DFSVSMDC IMSB DFS0578I - READ SUCCESSFUL FOR DDNAME PROCLIB MEMBER = DFSFIXDC IMSB DFS0578I - READ SUCCESSFUL FOR DDNAME PROCLIB MEMBER = DBFMSDBC IMSB DFS0578I - READ SUCCESSFUL FOR DDNAME PROCLIB MEMBER = DFSMPLDC IMSB DFS670I IMS710B.IMS710B. - MODULES HAVE BEEN PRE-LOADED IMSB

Having changed CNBA from 50 to 10 and reassembled DFSIMSB0, our DRA startup table, we re-ran the DB2 IVP job DSNTEJ62. And now we can see the following messages in the IMS address space for IMS710B: DFS3613I - ODM TCB INITIALIZATION COMPLETE IMSB DFS3613I - ODS TCB INITIALIZATION COMPLETE IMSB

So, we have a thread!

Chapter 8. DB2 stored procedures and IMS 273 8.12 Defining IMS resources The following sections illustrate how to set up a sample which includes defining IMS resources.

8.12.1 A sample including IMS steps We create a DB2 ODBA stored procedure OD1BPMS written in PL/I. The caller program or client, passes the following parameters to the stored procedure: • The name of the DRA startup table to use • The name of the PSB to schedule • A ‘Y’ if we want the stored procedure to pause in the middle of an execution by waiting for console input

Warning If you use the pause flag when invoking the stored procedure, you must have operator access in order to enter replies via the console.

The stored procedure does the following: 1. Allocates (schedule) a PSB in the IMS subsystem specified in the DRA startup table. 2. Reads an IMS database record (our root segment). 3. Writes another root segment with the date / time stamp as key. 4. Deallocates the PSB.

We can then invoke this stored procedure using the SPB to illustrate some common problems encountered as well as examine syncpoint (commit) processing.

8.12.2 Defining what IMS databases a program can access This is the logical side.

Figure 98 describes the steps required to generate the DBDs, the PSBs, and the ACBs.

274 Cross-Platform DB2 Stored Procedures: Building and Debugging DBD PSB Source Source Code Code

Assemble Assemble and and Link Edit Link Edit

DBD PSB Object Object Code Code

Assemble IMS Control and ACBLIB Link Edit REGION

Figure 98. DBD, PSB and ACB generation

First we have to design a database.

8.12.2.1 Designing our database and writing our DBD source If you are using an existing database, you do not need this step.

The database description (DBD) is an IMS control block that describes the physical organization of an IMS database, how the segments hang together.

For our examples we developed a simple root-only database called SJCDB1. It is based on the IVP HDAM database IVPDB2. We want to avoid having duplicate keys on insert (a status code of ‘II’). A simple approach is the make use of the date time stamp from PL/I (the DATETIME() function which returns a 17 byte character field) and Cobol (the CURRENT-DATE function which returns a 21 byte character field).

Warning Using a timestamp as is a poor database design for a production application from a performance perspective. However, it is adequate for our purpose of illustrating how ODBA works.

Chapter 8. DB2 stored procedures and IMS 275 Table 25 displays the characteristics of our database. Table 25. ODBA sample database DBD source DBD name Model DD name Segment

SJCDB1 SJCDB1 IVPDB2 SJCDS1 FOOTPRNT

The DBD source for the IVP is found in DFSISRC(DFSIVD2) for IMS V6 and SDFSISRC(DFSIVD2) for IMS V7.

8.12.2.2 Generating DBD If you are using an existing database, you do not need this step.

Having designed our database and written our DBD, we now generate the control block. You may be using existing IMS databases, in which case you already have existing DBDs and can skip this step.

We run Database Description Generation (DBDGEN) JCL procedure to create database description blocks (DBDs). Refer to section 1.1 Database Description (DBD) Generation in the IMS/ESA Utilities Reference: System, SC26-8770 (V6) or SC26-9441 (V7).

8.12.2.3 Generating PSB If you are using an existing PSB, and if the PCBs you need has PCBNAME coded, or has a label for the PCB macro, then you can skip this step.

A program specification block (PSB) specifies what database access a program has. There is no restriction to make a PSB name the same as a program name but often people adopt naming conventions to link the PSB and program name together.

A PSB can contain one or more database program control blocks (DB PCBs). Each PCB specifies a database to which our program has access. It also specifies what segments are accessible to the program, as well as the type of access (Get, Replace, Insert, Delete, or All which includes G,R,I,D) permitted through the PROCOPT keyword in the PCB macro.

For more details about coding and generating PSBs, refer to section 1.2, “Program Specification Block (PSB)” in the IMS/ESA Utilities Reference: System, SC26-8770 (V6) or SC26-9441 (V7).

276 Cross-Platform DB2 Stored Procedures: Building and Debugging Next, we create two PSBs: SJCPSB and SJCPSBL which has a PCB for every DBD in our SJC suite of applications.

SJCPSB allows the program all access (PROCOPT=A) to the databases. SJCPSBL has the PCBs required for loading databases initially (PROCOPT=LS). We choose to have the LS PROCOPT in a separate PSB because this access is not compatible with online, so it is better to separate, in case we want to move into online later.

If we have non-zero return code, search for ‘MNOTE’ in the assembly listing.

8.12.2.4 Generating ACB Once we have generate both the DBDs and PSBs, we can generate application control blocks (ACBs) which will be used by the IMS system. When we generate ACBs, we typically generate them into a staging library. Once this is done, we will have move to the operational side of this preparation.

8.12.3 Defining databases and programs to IMS We have now progressed from the logical side to the operational side of the IMS database preparation. If you are reusing existing databases and PSBs without any modifications, you can skip this step.

8.12.3.1 MODBLKS and MATRIX online change To add new databases and programs to IMS, we first update the IMS stage 1 gen. Figure 99 shows how to include the new or modified databases (DBD) using the DATABASE macro. To include new or modified programs (ACBs), use the APPLCTN macros in stage 1.

********************************************************************** * SG24-5485 samples ********************************************************************** DATABASE DBD=SJCDB1,ACCESS=UP HDAM/VSAM APPLCTN PSB=SJCPSB,PGMTYPE=BATCH SPACE 2

Figure 99. DATABASE and APPLCTN macros to include sample DBD and PSB

An IMS system has 3 types of IMS control blocks that control access to IMS database for IMS programs. These are the MODBLKS, MATRIX and ACB. Figure 100 describes the components of online change to add to change.

Chapter 8. DB2 stored procedures and IMS 277 MODBLKS are IMS control blocks that specify which databases, programs and transactions are defined to IMS. We have 3 MODBLKS libraries: a staging library and a suffix A and a suffix B. MODBLKS are built from stage 1 and stage 2 of the IMS gen process (4). IMS stage 2 gen places these control blocks into the staging library (4).

MATRIX libraries contain the security tables created by the IMS Security Maintenance utility. We have 3 MATRIX libraries corresponding to the MODBLKS libraries.

The active MATRIX data set (in use in the online system) at any time corresponds directly to the MODBLKS data set that is active; they must have the same suffix. If MODBLKSA is the active data set, security data is taken from MATRIXA. If MODBLKSB is the active data set, security data is taken from MATRIXB. After the online copy utility (6) and (7), a /modify prepare modblks followed by a /modify commit command swaps both MODBLKSA and MATRIXA into active status in our example.

staging active 1 acbliba

ACBGEN 3 acblib 2 acblibb inactive

staging inactive 4 6 modblksa

stage 1 + 2 modblks

matrixa 8 5 active 7 modblksb security gen matrix

matrixb

Figure 100. Adding databases and programs to IMS with an online change

278 Cross-Platform DB2 Stored Procedures: Building and Debugging After an online change, verify that the new database and program are defined to IMS by issuing the display command and checking output. For example, to check database SJCDB1, issue /dis db sjcdb1

For program SJCPSB, issue /dis prog sjcpsb to get output as displayed in Figure 101.

DFS4445I CMD FROM MCS/E-MCS CONSOLE USERID=DB2RES6: DIS PROG SJCPSB IMSD DFS000I MESSAGE(S) FROM ID=IMSD PROGRAM TRAN TYPE SJCPSB BMP *00310/213749*

Figure 101. Output from /dis prog command for a valid program

If you have not defined the PSB properly, you will see a message to the effect that the program is invalid, as shown in Figure 102.

DFS4445I CMD FROM MCS/E-MCS CONSOLE USERID=DB2RES1: DIS PROG BADPSB IMSD DFS000I MESSAGE(S) FROM ID=IMSD PROGRAM TRAN TYPE BADPSB IS INVALID *00299/152959*

Figure 102. Output from /dis prog command for an invalid program

8.12.3.2 ACBLIB online change Like the MODBLKS and MATRIX libraries in Figure 100, we have a set of 3 ACB libraries. Upon successful generation of the ACBs into the staging ACB library (1), we execute the online copy utility (2) to put the ACBs into the inactive ACB library. We then perform an online change (3) and swap the inactive ACBLIB into active. IMS can now access these new ACBs.

To activate a change, we first use the online copy utility to copy the contents from the staging libraries into the inactive libraries (2), (6) and (7). We then use the /modify prepare acblib command followed by the /modify commit command to swap the ACBLIB (3). In our example, after the ACBLIB swap, ACBLIBB becomes the new active ACBLIB.

8.12.3.3 Generating dynamic allocation macro for database (MDA) We use the dynamic allocation macro DFSMDA to specify the data set names for full function DBDs.

Chapter 8. DB2 stored procedures and IMS 279 For Fast Path databases, if the database data sets to be allocated are registered in DBRC, the information required to dynamically allocate the data sets is obtained from DBRC. You do not need to supply DFSMDA members for them.

8.12.4 Building the IMS database and making it operational Before we can use the IMS database, in order to render it operational, we need to: 1. Create an IMS database. 2. Tell IMS how to allocate the database. 3. Load data into the database. 4. Register the database to DBRC for our database recovery.

8.12.4.1 Defining data sets for IMS database and image copies We use IDCAMS DELETE/DEFINE to create the physical database and its image copies. Based on IVP job IV_G101J.

8.12.4.2 Dynamic allocation macro IMS supplies JCL procedure IMSDALOC to build the dynamic allocation macro (MDA) which tells IMS the physical data set names for a database.

8.12.4.3 Loading data into IMS database Based on IV_G103J, this job uses the IMS supplied JCL procedure DLIBATCH to execute the IMS test program, DFSDDLT0, using the PSB to load data into the database. IMS knows where to find the database because of the dynamic allocation macro.

8.12.4.4 Registering databases to DBRC Our job is based on IVP job IV_G102J. Database Recovery Control (DBRC) is a feature of the IMS Database Manager that facilitates easier recovery of IMS databases. DBRC maintains information required for database recoveries, generates recovery JCL, verifies recovery input, maintains a separate change log for database data sets, and supports sharing of IMS databases and areas by multiple IMS subsystems.

We keep our IMS DBRC skeleton JCL in the default JCLPDS DD statement in the DBRC address space. For reference, there is an excellent IBM Redbook, Database Recovery Control (DBRC) Examples and Usage Hints, SG24-3333.

You can check member ICJCL in JCLPDS DD statement of the DBRC address space.

280 Cross-Platform DB2 Stored Procedures: Building and Debugging Part 4. Implementing SQL Procedures

© Copyright IBM Corp. 2001 281 282 Cross-Platform DB2 Stored Procedures: Building and Debugging Chapter 9. Installation cookbook

This chapter is designed as a “cookbook” that describes what you need to consider and what you need to do when setting up an environment for the DB2 Stored Procedure Builder (SPB) tool and the Distributed Debugger for both, Windows NT and OS/390.

9.1 Required software components To be able to work with the SPB and the Distributed Debugger, you need quite a few software components. The list provided below gives you an overview of what has to be available to use SPB and Distributed Debugger. Further on in this chapter, there is a detailed description of the installation process and/or some special remarks for all components. 1. WIN/NT 4 with Service Pack 4 or above 2. DB2 UDB for WIN/NT Version 7.1 & DB2 Connect 3. DB2 UDB for WIN/NT Version 7.1 Fixpack 1 4. OS/390 Release Version1 Release 3 a. Language Environment b. Workload Manager c. Recoverable Resource Manager Services d. REXX e. Support for REXX stored procedure f. C Compiler 5. DB2 UDB for OS/390 V6 a. Make REXX support available b. SQL procedure support c. WLM established stored procedure address space running in goal mode 6. Visual Age for JAVA V3.5 for Windows 7. IBM Distributed Debugger 8. C++ Compiler for WIN/NT 9. Stored Procedure Builder as part of DB2 UDB for WIN/NT Version 7.1

If you are just using SQL procedures on WIN/NT, you can skip steps 4 and 5.

© Copyright IBM Corp. 2001 283 9.2 Windows NT — platform To properly work with SPB and Distributed Debugger, make sure that at least you have installed WIN/NT Version 4 with Service Pack 4 on your machine.

To evaluate the current status of your WIN/NT system, you can follow the steps described below: 1. Go to Start -> Programs -> Administrative Tools ->Windows NT Diagnostics as shown in Figure 103.

Figure 103. Find out version and installed service packs of WIN/NT

284 Cross-Platform DB2 Stored Procedures: Building and Debugging 2. Once you have selected Windows NT Diagnostics, you will see the window shown in Figure 104:

Figure 104. WIN/NT version and service pack information

As you can see, WIN/NT V4 and Service Pack 6 is installed on our machine.

9.2.1 DB2 UDB for WIN/NT Version 7.1 To be able to use SPB at least you have to install DB2 UDB Software Developers Kit (SDK) V 6.1, but we would recommend to start working with DB2 UDB SDK V 7.1. The screen prints shown in this book entirely belong to DB2 UDB V7.1.

To install DB2 UDB for WIN/NT V 7.1 either start the installation process by letting the CD ROM being auto started or double click on SETUP.EXE in the main path of your CD ROM.

Select Install from the very first screen, as shown in Figure 105.

Chapter 9. Installation cookbook 285 Figure 105. DB2 f. WIN/NT first installation screen

In the next screen the installation process asks you about what you want to install. Since you need to know what to do next for both options, either Client or Server installation, we will first describe what needs to be done for a server installation, and after that, we describe how to connect a client to this gateway server.

Install an DB2 UDB Gateway server 1. To install this DB2 subsystem as a server, you should select the first option, DB2 Enterprise Edition. See Figure 106.

286 Cross-Platform DB2 Stored Procedures: Building and Debugging Figure 106. DB2 f. WIN/NT — decide to install server version

2. Select Typical install as shown in Figure 107.

Figure 107. DB2 f. WIN/NT — decide how to install

Chapter 9. Installation cookbook 287 3. After pressing Enter, you will be informed that the typical installation includes the OLE DB support and that you need to install some special Microsoft feature to use it. Since we do not need it, just click OK. 4. In the next screen you have to decide where to store the files needed by you DB2 UDB system. C:\Program Files\SQLLIB is preselected, but if you want to install in any other folder or even any other hard drive, just select the Browse button and choose whatever you want.

Figure 108. Choose Destination Location

As you can see from Figure 108, this screen also informs you about the available and the needed disk space. Press Enter when you selected a destination folder and you available disk space meets the space requirements. 5. As you can see in Figure 109, the next window lets you decide which username to use as administrator ID for the DB2 control center. Since this is a Server installation, it might be a good idea not to use your personal name, but keep the ID DB2ADMIN, choose a password, and enter it twice to confirm it. If the current installation is not the first DB2 installed on this NT machine, you need to know the password for user DB2ADMIN.

288 Cross-Platform DB2 Stored Procedures: Building and Debugging Figure 109. Install DB2 UDB — Choose username and password

If the specified user does not already exist on your WIN/NT, the installation process creates the db2admin username and it also makes it a member of the administrators group. In order for this username and password to be used by the Administration Server to log on as a service, the setup program will assign the following user rights to this account: - Log on as a service - Act as part of the operating system - Create a token object - Increase quotas - Replace a process level token The installation process will inform you about the missing user name, as shown in Figure 110.

Figure 110. DB2 UDB installation — information about missing admin user

Chapter 9. Installation cookbook 289 6. After pressing Enter you will reach the screen shown in Figure 111 which gives you an overview about what you have selected so far and which components will be installed. If you agree with the selection just press Enter. If you do not agree, you can click the Back button to review and change the information entered in previous screens.

Figure 111. DB2 UDB installation — start copying files

7. After the installation process has completed copying all files, the screen shown in Figure 112 will pop up. Since we do not need OLAP support for SPB and Distributed Debugger, you might choose Do not install the OLAP starter kit as selected.

290 Cross-Platform DB2 Stored Procedures: Building and Debugging Figure 112. DB2 UDB installation — install OLAP starter Kit?

The installation is finished now. If you want to connect to DB2 UDB for OS/390 you have to perform some additional steps which are described now. 1. Open the Client Configuration Assistant (CCA) as shown in Figure 113.

Chapter 9. Installation cookbook 291 Figure 113. Open the CCA

2.The Client Configuration Assistant shows a list of all data bases which have already been defined. As you can see from Figure 114, until now there is no DB2 for OS/390 subsystem known. Click the Add button to add a new description for a DB2 for OS/390 subsystem.

292 Cross-Platform DB2 Stored Procedures: Building and Debugging Figure 114. CCA — available DB2 databases

3. On the next screen shown in Figure 115, select Manually configure a connection to a data base.

Chapter 9. Installation cookbook 293 Figure 115. Add Database Wizard

4. The first screen you will reach after that is shown in Figure 116. Choose TCP/IP as the protocol you will be using to connect to your DB2 UDB for OS/390 subsystem. After you select this choice, you have to check small box below indicating that the subsystem which you would like to connect to resides on a host. Checking this box makes two more choices available. Since we just installed the server version of the DB2 UDB, we are not going to use any other server as a gateway to the host but choose Connect directly to the server. Clicking the Next button leads you to the Specifying TCP/IP communication parameters screen.

294 Cross-Platform DB2 Stored Procedures: Building and Debugging Figure 116. Add Database Wizard — select protocol

5. In the Specify TCP/IP communications parameters screen you have to enter the host name and the TCP/IP port number for your DB2 UDB for OS/390 subsystem. In the field host name in Figure 117 you have to enter either the TCP/IP address for you host OS/390 system or, if available, its domain name alias. As you can see below, we entered the TCP/IP address for our OS/390 system.

Chapter 9. Installation cookbook 295 Figure 117. Specify TCP/IP communications parameters

When working with TCP/IP you also have to provide the correct TCP/IP port for your DB2 subsystem. If you are not sure which port is assigned to your DB2 subsystem, you can find the requested information in the BSDS of your DB2 UDB for OS/390. Use DSNJU004 as shown in Figure 118 to print the contents of the associated BSDS.

//your job card //PRTBSDS EXEC PGM=DSNJU004 //STEPLIB DD DSN=your.sdsnload,DISP=SHR //SYSPRINT DD SYSOUT=* //*YSUT1 DD DSN=your..BSDS01,DISP=SHR

Figure 118. Sample DSNJU004 JCL to print the BSDS

Figure 119 shows the DDF communication record which is located at the bottom of the DSNJU004 output. As you can see here, the port number which we have to enter is 33370.

296 Cross-Platform DB2 Stored Procedures: Building and Debugging **** DISTRIBUTED DATA FACILITY **** COMMUNICATION RECORD 21:51:37 OCTOBER 10, 2000 -LOCATION=DBZ1 LUNAME=SCPDBZ2 PASSWORD=(NULL) GENERICLU=(NULL) PORT=33370 RPORT=33372 -DSNJ200I DSNJU004 PRINT LOG UTILITY PROCESSING COMPLETED SUCCESSFULLY

Figure 119. DDF communication record in BSDS

Click Next to continue with the definition. 6. In the next window shown in Figure 120, you need to enter the database name and database alias to which you want to connect. For DB2 UDB for OS/390 you have to enter the subsystem’s location name here. You can find the appropriate location name in the Print log map output as well as you can see in Figure 119.

Figure 120. Specify the subsystem to which you want to connect

Click Next to continue with the definition. 7. Check box Register this database for ODBC and as a system data source as shown in Figure 121.

Chapter 9. Installation cookbook 297 Figure 121. Register database as ODBC data source

Click Next to continue with the definition. 8. You do not need to specify any node options. Just click Next again to specify the security options. 9. Specify Host or AS/400 authentication (DCS) as shown in Figure 122. Click Finish now to save your entries.

298 Cross-Platform DB2 Stored Procedures: Building and Debugging Figure 122. Specify security options

10.After clicking Finish, you can choose to test the newly created connection as shown in Figure 123.

Figure 123. Confirmation

If you click Test Connection now, you are prompted to enter your OS/390 userid and password. See Figure 124.

Chapter 9. Installation cookbook 299 Figure 124. Test connection

If the test works fine, you will see the message shown in Figure 125.

Figure 125. Connection test successful

Install an DB2 UDB Client

If you just want to install a UDB Client, the installation process and the configuration of the connection to DB2 UDB for OS/390 via any previously defined gateway server is a little bit different. Just follow the steps described below to perform a Client installation: 1. To install the DB2 UDB Client, select DB2 Application Development Client from the first window after you started the installation as shown in Figure 126.

300 Cross-Platform DB2 Stored Procedures: Building and Debugging Figure 126. DB2 UDB installation — select to install a client

2. Choose Typical Installation from the next Window. 3. After pressing Enter, you will be informed that the typical installation includes the OLE DB support and that you need to install some special Microsoft feature to use it. Since we do not need it, just click O.K. 4. In the next window you have to decide where to store the files needed by you DB2 UDB system. C:\Program Files\SQLLIB is preselected, but if you want to install in any other folder or even any other hard drive, just select the Browse button and choose whatever you want. If you compare the amount of needed disk space in Figure 127 with the amount displayed in Figure 108 on page 288, you will find out that it is much smaller.

Chapter 9. Installation cookbook 301 Figure 127. Required disk space for client installation

5. Normally you do not need to configure the NetBIOS adapter. If this is also true for your environment, just unselect the box as shown in Figure 128. Click Next to continue.

Figure 128. DB2 UDB client installation — configure NetBIOS

302 Cross-Platform DB2 Stored Procedures: Building and Debugging 6. In the window shown in Figure 129 you have to choose any username for the command center.

Figure 129. DB2 UDB installation — enter username for DB2 control center

If the specified user does not already exist on your WIN/NT, the installation process creates the specified username and it also makes it a member of the administrators group. In order for this username and password to be used by the Administration Server to log on as a service, the setup program will assign the following user rights to this account: - Log on as a service - Act as part of the operating system - Create a token object - Increase quotas - Replace a process level token The installation process will inform you about the missing user name as shown in Figure 110.

Chapter 9. Installation cookbook 303 Figure 130. DB2 UDB installation — information about missing admin user

If you specify any username which exists on your NT system but does not have the necessary rights, you will be informed about that after pressing Enter. You might for example receive the message shown in

Figure 131. DB2 UDB installation — specified user lacks authority

If you receive that message, you either have to use another userid which is part of the administrators group of you have to choose any new user which will be created during the installation process. Press Enter to proceed. 7. You now received the last window before the actual installation starts. The window displayed in Figure 132 gives you an overview about what you have selected in the previous steps and what will be created.

304 Cross-Platform DB2 Stored Procedures: Building and Debugging Figure 132. DB2 UDB installation — final screen for client

Click Next to start the installation.

After the installation finished successfully, you have to configure the connections to the databases you plan to work with. Follow the instructions below to define one connection to a DB2 UDB for OS/390 subsystem: 1. Open the Client Configuration Assistant as shown in Figure 113.

Chapter 9. Installation cookbook 305 Figure 133. Open the CCA

Once you opened the Client Configuration Assistant, you will see the window shown in Figure 134.

306 Cross-Platform DB2 Stored Procedures: Building and Debugging Figure 134. CCA — Add Database

Select Add Database. 2. On the next screen shown in Figure 135, select Manually configure a connection to a data base.

Chapter 9. Installation cookbook 307 Figure 135. CCA — Add Database Wizard

3. The first screen you will reach after that is shown in Figure 136.

308 Cross-Platform DB2 Stored Procedures: Building and Debugging Figure 136. CCA — select communication protocol

Choose TCP/IP as the protocol you will be using to connect to your DB2 UDB for OS/390 subsystem. Clicking the Next button leads you to the Specifying TCP/IP communication parameters window which you can see in Figure 137. You must enter the host name and the port number here. The host name is either the Domain Name Server alias of the DB2 Server or its TCP/IP address. To receive the correct TCP/IP address, just open a MSDOS command screen. If you

Chapter 9. Installation cookbook 309 Figure 137. CCA — specify TCP/IP communication parameters

You must enter the host name and the port number here. The host name is either the Domain Name Server alias of the DB2 Server or its TCP/IP address. To receive the correct TCP/IP address, just open a MSDOS command screen on you server machine and enter IPCONFIG there. You will receive the information shown in Figure 138. As you can see, the IP address of the machine we used to create this sample is 9.1.151.150.

310 Cross-Platform DB2 Stored Procedures: Building and Debugging Figure 138. IPCONFIG to identify own TCP/IP address

To find the correct port number, you have to perform two steps on your DB2 UDB server: a. Click Start -> Programs ->IBM DB2 - > Command Window. Enter the command DB2 GET DBM CFG | more. Go through the database manager configuration information by pressing the Enter key several times until you reach a line which provides the following information: TCP/IP Service name (SVCENAME) = xxxxxxx where xxxxxxx is the service name we need to know. See Figure 139 for a sample output.

Chapter 9. Installation cookbook 311 Figure 139. DB2 UDB — DB2 GET DBM CFG output

b. Now you must open file C:\WINNT\SYSTEM32\DRIVERS\ETC\SERVICES to find the TCP/IP port which points to this service name.

Figure 140. DB2 UDB TCP/IP port number

As you can see in Figure 140, in our sample environment we are working with TCP/IP port 50000. Enter this number to your add database wizard field port number. 4. Select option 4 now to specify the name of the database to which you want to connect. If the database in question resides on OS/390, enter the location name of your DB2 subsystem here as shown in Figure 141. If you do not know the correct location name, refer to Figure 119 on page 297 and the related text for an explanation.

312 Cross-Platform DB2 Stored Procedures: Building and Debugging Figure 141. CCA — specify the database to which to connect

Next you have to specify a database alias for your connection. You can choose any suitable name with up to eight characters here. If you want to, you can now enter any comment which length can not exceed 30 characters. 5. Skip options 5 and 6, and proceed with option 7, Security options. You should choose Use authentication value specified in the servers DBM configuration. This value indicates that authentication is dictated by the server instance's DBM authentication parameter. Click Finish. 6. The installation process now asks you if you wish to test the new connection now. Select Test Connection from the window shown in Figure 123 on page 299. Enter your userid and password in the next window. If the test fails, you can simply choose Change to return to the Configuration Wizard to apply any change or you can rerun the connection test if you suspect that you used a wrong userid or password.

Chapter 9. Installation cookbook 313 9.2.2 DB2 UDB for WIN/NT Version 7.1 Fixpack 1 To be sure that you work with the latest version of DB2 UDB for WIN/NT, you should have the latest available fixpack applied to your system.

To check which fixpacks are available for your DB2, you can use the DB2 UDB for Windows homepage on the internet. The URL where you can start from is: http://www-4.ibm.com/software/data/db2/udb/udb-nt/. Select Support from the menu on the left hand site. This leads you to the DB2 UDB & DB2 Connect Online Support homepage. Scroll down the window a little bit. You will find a section called FixPacks and Clients. Enter the needed information and download the available fixpacks. At the time when the book was written, fixpack 1 was available for DB2 UDB for WIN/NT V7. Install the fixpack on your computer as described in the README.TXT file that comes with the fixpack.

If you are not sure if fixpack 1is already applied to your DB2 system, you can perform the following two steps to check this: 1. Open the DB2 command window as shown in Figure 142.

314 Cross-Platform DB2 Stored Procedures: Building and Debugging Figure 142. Open Command Window

2. Once the Command Window is opened, you can enter command db2level in the command line to display release level information for your DB2 system. As you can see in Figure 143, we are currently working with DB2 V7.1.0.1. In addition to that, you can see that PTF level WR21298 is applied.

Chapter 9. Installation cookbook 315 Figure 143. DB2LEVEL command output

9.3 OS/390 — platform The following sections document what is required at the OS/390 platform.

9.3.1 DB2 UDB for OS/390 V6 At the time when the book was written, the Recommended Maintenance Level (RML) for DB2 UDB for OS/390 V6 is PDO level 0015, which includes service up to PUT 0003, or ESO level 0003.The information provided in this book is based on this level. Therefore we would highly recommend you to apply this RML to your DB2 UDB for OS/390 subsystem before you start working with SPB and Distributed Debugger.

There are three things that need to be done for DB2 UDB for OS/390 V6 if you intend to work with SQL procedures:

9.3.2 Make REXX support available If you want to use SPB to build your SQL stored procedures, you have to have REXX support implemented on your DB2 subsystem. To build the SQL procedures, SPB invokes the OS/390 SQL Procedure Processor, which is a REXX stored procedure. The name of this SP is DSNTPSMP. See Chapter 11, “SQL Procedures — OS/390 platform” on page 349 for more detailed information on DSNTPSMP.

The base code of DB2 V6 did not include REXX Language Support. You can either install RML level for your DB2 subsystem or order REXX Language Support separately. The FMID for REXX Language Support is JDB661H with component IDs (COMPID) 5740XYR00.

Refer to DB2 Universal Database for OS/390 Installation Guide V6, GC26-9008-01 to see that, apart from the necessary SMP/E steps, installation job DSNTIJRX is the only job you need to run to make REXX

316 Cross-Platform DB2 Stored Procedures: Building and Debugging support available to your DB2 subsystem. In addition to that, there is one installation verification job, DSNTEJ65, which invokes the Procedure Processor (DSNTPSMP). Refer to chapter 2.9.12.19 Job DSNTEJ65 in the Installation Guide for further information.

9.3.3 SQL Procedure support If you installed your DB2 V6 subsystem with base code, some necessary steps to make the Procedure Processor available might not have been generated in your installation or migration jobs. SQL procedures install and sample support is brought to DB2 UDB for OS/390 V6 by PTF UQ41205 which supersedes PTF UQ39824 with the following changes detailed below: 1. Create stored procedure DSNTPSMP. 2. These existing DB2 Install parts are changed: a. DSNTIJSG is extended to create the objects used by DSNTPSMP and the SPB. These changes are also separately supplied in a new Install job DSNTIJSQ. These changes include the creation of the SQL Procedure database DSNDPSM with the following objects: 1. Table space DSNSPSM 2. Table SYSIBM.SYSPSM with indexes SYSIBM.DSNPSMX1 and SYSIBM.DSNPSMX2. 3. Table SYSIBM.SYSPSMOPTS with index SYSIBM.DSNPSMOX1. 4. Table SYSIBM.SYSPSMOUT, a global temporary table required by DSNTPMSP for returning result sets. 5. Grant execute on DSNTPSMP to PUBLIC 6. Grant INSERT, UPDATE, DELETE and SELECT on SYSIBM.SYSPSM and SYSIBM.SYSPSMOPTS to PUBLIC. b. DSNTIJFV is extended for fallback purposes. c. DSNTIJMV is extended to create DSNHSQL, a new language procedure for SQL procedures d. DSNTIJVC is extended to copy DSNTPSMP to prefix.NEW.SDSNCLST from prefix.SDSNCLST. e. DSNTINS1 is updated to support the changes described above in the install and sample jobs. f. DSNTINS2 is updated to support the changes described above in the migration jobs.

Chapter 9. Installation cookbook 317 3. Installation job DSNTEJ0, which drops sample objects from DB2 is modified to drop objects created by new SQL procedure sample applications. 4. Sample WLM procedure DSN8WLMP is added. Copy this procedure to your system PROCLIB where your WLM procedures reside. 5. New sample applications are added.

To make SQL procedure support available to your DB2 subsystem, follow the installation instructions of PTF UQ41205.

Important: If you are already using SPB and SQL Procedures Language in your installation, you must consider: • After applying this PTF, the PROCEDURENAME in SYSIBM.SYSPSMOPTS does no longer contain the schema name as part of its name. Figure 144 shows how the procedure name used to be (1), and how it is after applying the PTF (2).

------+------+------+------+------+---- SELECT * FROM SYSIBM.SYSPSMOPTS ------+------+------+------+------+---- SCHEMA PROCEDURENAME BUILDSCHEMA BUILDNAME ------+------+------+------+------+---- DSN8 DSN8.DSN8ES2 DSNTPSMP (1) MASUELI PROC1 DSNTPSMP (2) MASUELI P12345678901234567 DSNTPSMP DB2RES1 PROC10 DSNTPSMP MASUELI PROC3 DSNTPSMP DB2RES2 PROC11 DSNTPSMP DSNE610I NUMBER OF ROWS DISPLAYED IS 6

Figure 144. PROCEDURENAME after PTF UQ45625

• Apply the PTF UQ43183, which corrects the following problems in samples delivered for DB2 UDB for OS/390 Version 6: -DSNTEJ71— step PH071S04: RUN PROGRAM statement is too long to accommodate full DSN on one line and must be split - DSNTPSMP (SQL procedure processor) — Does not allow LE runtime options greater than 72 bytes -DSNTEJ63— step PH063S01: Requires explicit override for PCC.SYSLIB to prevent a possible JCL error

318 Cross-Platform DB2 Stored Procedures: Building and Debugging -DSN8ED4— (sample DSNTPSMP caller): Hardcoded LRECL causes options data set handling errors under JES3 -DSNTEJ2U— step PH02US12, return code 0008 because UDFs ALTDATE, ALTTIME, DAYNAME, and MONTHNAME experience SQLCODE -443 if settings for DATE and TIME in DSNHDECP are not set to 'ISO'. • Apply the PTF UQ48752 — see detailed information at the PTF documentation. • Apply the PTF related to the APAR PQ43397 — This will clean up the value in the project file for SPB, and a drop of the procedure exists in SYSIBM.SYSROUTINES. • Visit the Web site: www-4.ibm.com/software/data/db2/os390/sqlproc/sqlp6.htm This summarizes the recommended PTFs for stored procedures.

9.3.4 WLM definitions As stated before, the Procedure Processor itself is a stored procedure. Stored Procedures can either be executed in so called DB2 established or in WLM established address spaces.

The DSNTPSMP should be executed in a WLM established address space running in goal mode and the NUMTCB parameter must be = 1. This is because the DSNTPSMP uses temporary datasets allocated to the address space during initialization. If more than 1 DSNTPSMP were running in that address space, they would be stepping over each other's data. '

The following steps need to be done to make an WLM established stored procedure address available for the Procedure Processor: 1. Create the JCL for this address space. To do this, you can use the sample JCL provided by PTF UQ39824.

Note The APPLENV=xxx,DB2SSN=xxx,NUMTCB=x parameters are overridden with the values contained in the WLM application environment.

Chapter 9. Installation cookbook 319 2. To define the application environment, you must perform the WLM task associated with setting up the WLM application environment. These procedures are usually performed by the individual responsible for the WLM product. We are assuming that you currently have WLM managing the system workload. Enter WLM in your ISPF command line to utilize the WLM ISPF interface. Figure 145 is the initial WLM ISPF interface panel.

Command ===> ______

WWL MM WWL MMMM WWW L MMM WW WW L M M W W LLLLL M M

Licensed Materials - Property of IBM

5647-A01 (C) Copyright IBM Corp. 1998. All rights reserved.

ENTER to continue

Figure 145. WLM panel

3. Choose option 2 to extract the current WLM definition from the couple data set. Refer to Figure 146.

Command ===> ______

EsssssssssssssssssssssssssssssssssssssssssssssN e Choose Service Definition e ee e Select one of the following options. e e 2 1. Read saved definition e e 2. Extract definition from WLM e e couple data set e e 3. Create new definition e ee ee ee DsssssssssssssssssssssssssssssssssssssssssssssM ENTER to continue

Figure 146. Choose service definition

320 Cross-Platform DB2 Stored Procedures: Building and Debugging 4. To create the WLM application environment you select option 9. This is where you define the new WLM application environment for the DB2 stored procedure. Refer to Figure 147.

Functionality LEVEL004 Definition Menu WLM Appl LEVEL008 Command ===> ______

Definition data set . . : none

Definitionname.....DB2JAVA (Required) Description...... ______

Select one of the followingoptions.....9__1.Policies 2. Workloads 3. Resource Groups 4. Service Classes 5. Classification Groups 6. Classification Rules 7. Report Classes 8. Service Coefficients/Options 9. Application Environments 10. Scheduling Environments

Figure 147. Definition Menu — for application environments

5. Once you select option 9 to define the application environment for a stored procedure, you will receive the Application Environment Selection list displayed in Figure 148. From the Application Environment Selection List screen (Figure 148) you can move to the Create an Application environment screen by selecting option 1 next to one of the existing application environments.

Application-Environment Notes Options Help ------Application Environment Selection List Row 43 to 46 of 46 Command ===> ______

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

Action Application Environment Name Description __ WLMJAVADB2V SG24-5485 DBS1 WLM addr sp JAVA 1_ WLMPSM SP for psm, currently only dbz2 __ WLMSQL SP for sql, currently only dbz2 __ WLMXENVIRONMENTX03 Large Stored Proc Env. ******************************* Bottom of data ********************************

Figure 148. Application Environment selection list

Chapter 9. Installation cookbook 321 During the creation of the application environment, you define your WLM Application Environment utilized by the stored procedure. -TheApplication Environment field must match the value specified in the WLM ENVIRONMENT column of SYSIBM.SYSROUTINES, for all stored procedures that use this application environment. -TheDescription field is an optional field up to 32 characters that defines this application environment. - Subsystem Type must be DB2. - Procedure Name is the 1- to 8-character name of the JCL procedure that WLM uses to start the address space. - Start parameters are the parameters passed to the JCL procedure defined in the Procedure name field. These values are used for symbolic substitution in the JCL procedure. -Thelastvalue"Limit on starting server address spaces for a subsystem instance:" is how you control the number of address spaces available for startup by WLM for this application environment. For stored procedures application environments, you can only specify either no limit or a single address space per system.

Note The one value that is most beneficial in a data sharing environment for DB2 continuous availability is the value you pass as the DB2SSN= parameter. If you use DB2SSN=&IWLMSSNM, WLM will replace 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 in the data sharing group. For example, If DBS1 were unavailable for any reason, the stored procedure would execute on another active data sharing member, in our case DBS2.

322 Cross-Platform DB2 Stored Procedures: Building and Debugging Application-Environment Notes Options Help ------Create an Application Environment Command ===> ______

Application Environment Name . : WLMPSM Description ...... SP for psm, currently only dbz2 Subsystem Type ...... DB2 Procedure Name ...... WLMPSM Start Parameters ...... DB2SSN=DBZ2,NUMTCB=1,APPLENV=WLMPSM ______

Limit on starting server address spaces for a subsystem instance: 1 1. No limit 2. Single address space per system

Figure 149. Create an Application Environment

Important Use NUMTCB=1 as start parameter. DSNTPSMP uses temporary datasets allocated to the address space during initialization. If more than one DSNTPSMP were running in that address space, they would be stepping over each other's data.

You must then save this information. Enter F3 to back out and save the changes. You will receive the message "Application environment WLMPSM1 was created", and control will be returned to the WLM definition Menu panel Figure 150.

Chapter 9. Installation cookbook 323 Application-Environment Notes Options Help ------Application Environment Selection List Row 43 to 47 of 47 Command ===> ______

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

Action Application Environment Name Description __ WLMJAVADB2V SG24-5485 DBS1 WLM addr sp JAVA __ WLMPSM SP for psm, currently only dbz2 __ WLMPSM1 WLM applenv for DBZ2 __ WLMSQL SP for sql, currently only dbz2 __ WLMXENVIRONMENTX03 Large Stored Proc Env. ******************************* Bottom of data ********************************

Figure 150. WLM-definition Menu

Press PF3 to return to the main Definition Menu. After the application environment is created, you must install it in the couple data set. Refer to Figure 151.

File Utilities Notes Options Help ----- ______------Funct | 1 1. Install definition | Appl LEVEL007 Comma | 2. Extract definition | ______| 3. Activate service policy | Defin | 4. Allocate couple data set | | 5. Allocate couple data set using CDS values | Defin ______Description ...... ______

Select one of the following options. . . . . ___ 1. Policies 2. Workloads 3. Resource Groups 4. Service Classes 5. Classification Groups 6. Classification Rules 7. Report Classes 8. Service Coefficients/Options 9. Application Environments 10. Scheduling Environments

Figure 151. WLM utility pull down menu

To install the new WLM application environment in the WLM couple data set, you must utilize the Utilities drop-down menu and select option 1, see Figure 151. First you must populate the Definition name fieldwiththe application environment you just created.

324 Cross-Platform DB2 Stored Procedures: Building and Debugging Once you press Enter, you will receive the message: Service definition was installed. Now you must activate the service policy. Again using the Utilities drop-down menu, select option 3, Figure 152.

File Utilities Notes Options Help ----- ______------Funct | 3 1. Install definition | Appl LEVEL007 Comma | 2. Extract definition | ______| 3. Activate service policy | Defin | 4. Allocate couple data set | | 5. Allocate couple data set using CDS values | Defin ______Description ...... ______

Select one of the following options. . . . . ___ 1. Policies 2. Workloads 3. Resource Groups 4. Service Classes 5. Classification Groups 6. Classification Rules 7. Report Classes 8. Service Coefficients/Options 9. Application Environments 10. Scheduling Environments

Figure 152. WLM utility pull-down menu — activate service policy

At this time the Policy Selection List panel shown in Figure 153 is displayed. You are given a list of available policies. You should select the currently active policy.

Chapter 9. Installation cookbook 325 File Utilities Notes Options Help Policy Selection List Row 13 to 18 of 18 e Command ===> ______

The following is the current Service Definition installed on the WLM couple data set.

Name . . . . : DB2JAVA

Installed by : DB2RES3 from system SC61 Installed on : 2000/11/06 at 20:13:49

Select the policy to be activated with "/"

Sel Name Description _ EQUALMED Policy for equal imp case _ IMSMAJ IMS majority policy _ PERFDEFT Default policy for performance _ POLTEST Test for Rich Conway _ SAPDB2 serv pol for SAP R/3 DB2 / SPSTPC serv pol for db2 stor proc resid

Figure 153. Policy selection list

Note: Some installations may have only one policy defined. In this case, you would not have to utilize the following display to find the currently active policy. Otherwise, you can find the currently active policy by using the WLM display WLM command as shown below: DWLM RESPONSE=SC61 IWM025I 20.28.19 WLM DISPLAY 226 ACTIVE WORKLOAD MANAGEMENT SERVICE POLICY NAME: SPSTPC ACTIVATED: 2000/11/02 AT: 12:40:44 BY: DB2RES1 FROM: SC61 DESCRIPTION: serv pol for db2 stor proc resid RELATED SERVICE DEFINITION NAME: xxxxxxx INSTALLED: 2000/11/02 AT: 12:40:34 BY: DB2RES1 FROM: SC61 WLM VERSION LEVEL: LEVEL008 From this display, you can see that the currently active policy is SPSTPC. This is the policy you will select; see Figure 153. Your new application environment is now defined and ready for use.

326 Cross-Platform DB2 Stored Procedures: Building and Debugging If you are not familiar with stored procedures and the WLM-established address space, see Figure 154, which shows how the process flows .

Call procedure

Verify with SQL statement: Is procedure No SELECT * known to DB2? FROM SYSIBM.SYSROUTINES WHERE NAME = 'yourprocname'

Yes

Verify with SQL statement: Is application SELECT WLM_ENVIRONMENT environment No FROM SYSIBM.SYSROUTINES (APPLENV) assigned to SP? WHERE NAME = 'yourprocname'

If value in column WLM_ENVIRONMENT is blank, xxxxSPAS is used to execute this Yes procedure.

Is APPLENV No defined in WLM? 1

Yes

Has number Is WLM address Yes TCBs in AS space started? readched NUMTCB?

No Yes No

Is WLM running Yes WLM starts another in GOAL mode? address space

No Start SP address space manually

Execute stored procedure

Figure 154. WLM flowchart

Chapter 9. Installation cookbook 327 Explanation for item 1: a. Check the status of the WLM. Use command: /D WLM b. Check the status of the application environment assigned to your stored procedure. Use command: /D WLM,applenv=yourapplenv c. Check WLM entries manually. Go to WLM and follow the steps described in the cookbook to see if all necessary entries are available here.

9.4 Visual Age for JAVA V3.5 for Windows The Distributed Debugger comes along with Visual Age for JAVA V3.5 for Windows. Since the Distributed Debugger uses at least some help resources from Visual Age for Java, we recommend that you install Visual Age for Java as well if you plan to work with the Distributed Debugger.

Start Setup.exe from your Visual Age for Java CD ROM. You will see the window shown in Figure 155.

Figure 155. Visual Age for Java installation — first installation screen

It does not matter which of the two available products, Distributed Debugger or Visual Age for Java, you decide to install first.

328 Cross-Platform DB2 Stored Procedures: Building and Debugging Let us first install Visual Age for Java. Select Install Visual Age for Java on the right. The next window that appears is shown in Figure 156.

Figure 156. Visual Age for Java — select setup type

Select Custom if you do not need Visual Age for Java for any other purposes than running the Distributed Debugger. This option will save some disk space on your hard drive. Select Next to proceed. As you can see from Figure 157, you can deselect some components. If you want to deselect a component, click the left mouse button and choose x This feature will not be available from the pop-up window. Apart from the required features, you just must select Enterprise Toolkit for OS/390 and/or Enterprise Toolkit for AS/400 depending on the platform you plan to work with.

Chapter 9. Installation cookbook 329 Figure 157. Visual Age for Java installation — Edit Features

You can now select if you want to store the repository on your local machine or on a server. If you decide to store the repository on your local machine, you can now actually start the installation if you click Install on the next window. After the installation is finished, you can proceed with the installation of the distributed debugger.

330 Cross-Platform DB2 Stored Procedures: Building and Debugging Chapter 10. SQL Procedures for DB2 for UNIX, Windows, OS/2

This chapter describes the support for the new SQL Procedures language in DB2 UDB servers. During this project we use Windows NT and UNIX platforms. As there are no differences related to the SQL Procedure Language support among the platform supported by this DB2 server, we mainly documented the Windows platform.

10.1 General considerations SQL Procedures is an easy-to-use, simple language, which provides a series of language elements that allow you to develop block-structured stored procedures, with exception handling, flow control, variable declarations, and so on. Using the SQL Procedures language, you have the same functions and performance as when using other supported languages, such as multiple parameters (input, output, input/output), returning multiple output result sets, and so on. However, the SQL Procedures language is easier for all developers to use, and is especially easy to learn for those developers familiar with Sybase, Oracle, Informix, and Microsoft SQL Server proprietary languages.

SQL stored procedures are created using the CREATE PROCEDURE statement and are registered in the DB2 catalog. There are four tables in the DB2 UDB catalog that contain information related to stored procedures: • SYSIBM.SYSPROCEDURES: Contains a row for each stored procedure that is created. • SYSIBM.SYSPROCPARMS: Contains a row for each parameter of every stored procedure. • SYSIBM.SYSPROCOPTIONS: Each row contains procedure-specific option values. • SYSIBM.SYSPROCPARMSOPTIONS: Each row contains procedure parameter specific option values.

The source code of SQL stored procedures is stored in the DB2 catalog. The TEXT column of SYSIBM.SYSPROCEDURES table contains the source of your SQL stored procedure. You can easily access the source code using a SELECT statement.

There are no changes related to coding client programs to invoke SQL stored procedures. The syntax of the SQL CALL statement is the same regardless of the language being used at the server stored procedure.

© Copyright IBM Corp. 2001 331 The support for SQL stored procedures in DB2 UDB is implemented through the generation of an intermediary C code. This C code is precompiled, compiled, and link-edited automatically, and an executable file (.DLL in Windows NT) is generated for the stored procedure. For more details, refer to 10.4, “Stored procedures preparation” on page 346.

Stored procedures written in the SQL Procedures language are portable to DB2 servers in other platforms with no changes or minimal changes to the sources. When other database management systems (DBMS) implement languages compatible with the SQL/PSM standard, it should be possible to port stored procedures from DB2 to other DBMSs and vice versa.

10.2 Creating an SQL procedure If you are creating an SQL procedure for DB2 for UNIX or Windows, you should consider the following:

When you work with DB2 UDB for Unix or Windows and you do not have Fixpack 2 applied, set the database manager configuration parameter KEEPDARI to 'NO' for developing SQL procedures. If an SQL procedure is kept loaded once it is executed, you may have problems dropping and recreating the stored procedure with the same name, as the library cannot be refreshed and the executables cannot be dropped from the filesystem. You will also have problems when you try to rollback the changes or drop the database because the executables cannot be deleted. See the section, “Updating the Database Manager Configuration File” in Chapter 2, “Setup" of the DB2 UDB Application Building Guide V6, SC09-2842 for more information on setting the KEEPDARI parameter.

Note: SQL procedures do not support the LONG VARGRAPHIC data type for parameters.

332 Cross-Platform DB2 Stored Procedures: Building and Debugging Following is a revised syntax diagram for the Compound Statement:

.-NOT ATOMIC--. >>-+------+--BEGIN----+------+------> '-label:--' '-ATOMIC------'

>-----+------+------> | .------. | |V || '-----+-| SQL-variable-declaration |-+---;---+--' +-| condition-declaration |----+ '-| return-codes-declaration |-'

>-----+------+------> | .------. | |V || '----| statement-declaration |--;---+--'

>-----+------+------> | .------. | |V || '----DECLARE-CURSOR-statement--;---+--'

>-----+------+------> | .------. | |V || '----| handler-declaration |--;---+--'

.------. V| >------SQL-procedure-statement--;---+---END--+------+------>< '-label--'

Chapter 10. SQL Procedures for DB2 for UNIX, Windows, OS/2 333 SQL-variable-declaration

.-,------. V| |---DECLARE------SQL-variable-name---+------>

.-DEFAULT NULL------. >-----+-data-type----+------+-+------| | '-DEFAULT--constant--' | '-RESULT_SET_LOCATOR--VARYING------'

condition-declaration

|---DECLARE--condition-name--CONDITION--FOR------>

.-VALUE-. .-SQLSTATE--+------+---. >----+------+---string-constant------|

statement-declaration

.-,------. V| |---DECLARE-----statement-name---+---STATEMENT------|

return-codes-declaration

|---DECLARE----+-SQLSTATE--CHAR (5)--+---+------+-| '-SQLCODE--INTEGER----' '-DEFAULT--constant--'

handler-declaration

|---DECLARE----+-CONTINUE-+---HANDLER--FOR------> +-EXIT-----+ '-UNDO-----'

.-,------. V .-VALUE-. | >------+-SQLSTATE--+------+--string--+--+------> +-condition-name------+ +-SQLEXCEPTION------+ +-SQLWARNING------+ '-NOT FOUND------'

>----SQL-procedure-statement------|

A statement-declaration declares a list of one or more names that are local to the compound statement. A statement name cannot be the same as another statement name within the same compound statement.

334 Cross-Platform DB2 Stored Procedures: Building and Debugging 10.2.1 Retaining intermediate files Issuing an SQL Procedures CREATE PROCEDURE statement, DB2 creates a number of intermediate files that are normally deleted if DB2 successfully completes the statement. If an SQL stored procedure does not perform as expected, you might find it useful to examine the SQC, C, PDB, and message log files created by DB2. To keep the files that DB2 creates during the successful execution of a CREATE PROCEDURE statement, you must set the value of the DB2_SQLROUTINE_KEEP_FILES DB2 registry variable to 1. This can be done through the following command: db2set DB2_SQLROUTINE_KEEP_FILES=1

The intermediate files will be retained by DB2 in the following directories: • Windows NT %DB2PATH%\function\routine\udp\%$DATABASE%\%SCHEMA% where: %DB2PATH%represents the instance directory %DATABASE%represents the database name %SCHEMA%represents the schema name with which the SQL stored procedures were created • AIX, Solaris $DB2PATH/function/routine/sqlproc/$DATABASE/$SCHEMA where: $DB2PATHrepresents the instance directory $DATABASErepresents the database name $SCHEMArepresents the schema name with which the SQL stored procedure were created

10.3 Coding considerations This section presents some considerations on coding SQL stored procedures for DB2 UDB. Most of the considerations and techniques described here are valid for Windows and UNIX servers, and any topic that applies only to one type of server will be clearly identified.

This section does not provide detailed information about the syntax of the SQL Procedures language. Some examples are provided, but for more information on the SQL Procedures language refer to Chapter 3, “SQL Procedures language” on page 55.

Chapter 10. SQL Procedures for DB2 for UNIX, Windows, OS/2 335 10.3.1 Recommendations for writing portable stored procedures Make sure that the built-in functions you use in your stored procedure are supported on all the target DB2 platforms you will use.

10.3.2 Structure of SQL stored procedures An SQL stored procedure consists of two main blocks: • A CREATE PROCEDURE statement to define the procedure • A procedure body with SQL statements and SQL control statements

10.3.2.1 The CREATE PROCEDURE statement The CREATE PROCEDURE statement is used to register a stored procedure in the DB2 server. For SQL stored procedures, most of the options of the CREATE PROCEDURE statement are not valid, because these options are related to external stored procedures.

For SQL stored procedures, using the CREATE PROCEDURE statement, you can specify the list of parameters being passed to or from the stored procedure, an specific name for the procedure, the number of result sets being returned, and if the stored procedure reads or modifies SQL data. Following is a typical CREATE PROCEDURE statement for an SQL stored procedure: CREATE PROCEDURE SQL1LNS (IN PARM1 CHAR(10), OUT PARM2 INTEGER) SPECIFIC S4141979 RESULT SETS 1 READS SQL DATA LANGUAGE SQL BEGIN .... END

With DB2 UDB, you can have various procedures with the same procedure name, as long as they have different specific names, and a different number of parameters. DB2 UDB recognizes which of the procedures with the same name you are actually calling, by comparing the number of parameters being passed and the number of parameters defined in the catalog. Note that DB2 UDB only counts the number of parameters; that is why you must have a different number of parameters for procedures with the same name.

For SQL stored procedures, you cannot specify the following options of the CREATE PROCEDURE statement: • NO SQL • FENCED/NOT FENCED • DETERMINISTIC/NOT DETERMINISTIC • CALLED ON NULL INPUT • DBINFO/NO DBINFO • EXTERNAL • PARAMETER STYLE • PROGRAM TYPE

336 Cross-Platform DB2 Stored Procedures: Building and Debugging The above options can only be used with external stored procedures. If you try to code your CREATE PROCEDURE statement for an SQL stored procedure using any of the above options, you will receive the following message: SQL0628N Multiple or conflicting keywords involving the "" clause are present. SQLSTATE=42613

SQL stored procedures execute as NOT FENCED, unless they are returning result sets to the calling program. If the SQL stored procedure returns result sets, it executes as a FENCED stored procedure. This is done internally, and you cannot change the mode of execution of your SQL stored procedure.

10.3.2.2 Defining parameters If your SQL stored procedure needs to send/receive parameters from the client program, you must define them in the CREATE PROCEDURE statement.

You can define input, output, or input/output parameters of any supported SQL data types. The LONG VARGRAPHIC and DATALINK types are not supported.

User Defined Data types (IUDs) are not supported, even if they are based on supported SQL data types.

10.3.3 Coding the SQL stored procedures body The stored procedures body in an SQL stored procedure contains the source statements for the stored procedure. The stored procedures body can contain a single SQL statement or a compound SQL statement. Following is an example of an SQL stored procedure with a single SQL statement: CREATE PROCEDURE SQL2LNS (OUT PARM1 CHAR(10)) LANGUAGE SQL SET PARM1=’FELIPE’

A stored procedures body with a compound SQL statement must be delimited by a BEGIN and an END statement. Following is an example of an SQL stored procedure with a compound SQL statement: CREATE PROCEDURE SQL3LNS (OUT PARM1 CHAR(10), OUT PARM2 CHAR(10)) LANGUAGE SQL P1:BEGIN SET PARM1=’ALINE’ SET PARM2=’RICARDO’ END P1

Chapter 10. SQL Procedures for DB2 for UNIX, Windows, OS/2 337 A compound SQL statement may have a label associated to it. In the above example, the label P1 was set for the compound SQL statement. The labels in your SQL stored procedures body must be unique, and must not be the same as the name of the stored procedure. Any variables within a labeled compound SQL statement may be prefixed with the label, if necessary. See 10.3.3.2, “Defining variables in SQL stored procedures” on page 338 for more details.

10.3.3.1 Statements in the stored procedures body The SQL stored procedures body may contain SQL statements and SQL control statements. All executable SQL statements can be contained within an SQL stored procedures body, with the exception of the following: • COMMIT • CONNECT • DISCONNECT • RELEASE • SET CONNECTION • REVOKE

Note: The above restrictions are intended to be removed in future releases of SQL Procedures support in DB2 UDB. Check your DB2 UDB manuals, to verify if these restrictions still apply.

SQL control statements can be assignment statements, CASE statements, IF statements, LOOP statements, and others, as defined in SQL Procedures. For more information regarding the syntax of the different SQL Procedures control statements, please refer to Chapter 3, “SQL Procedures language” on page 55.

10.3.3.2 Defining variables in SQL stored procedures Within a compound SQL statement you can declare SQL variables that can be referenced in other statements in the stored procedure using the DECLARE statement.

Recommended naming for parameters and variables: You do not need to declare your parameters as variables within your stored procedure. Your parameter description provides DB2 enough information to understand what the names and datatypes of the parameters are.

338 Cross-Platform DB2 Stored Procedures: Building and Debugging Name your local variables with different names than the parameters to your stored procedure. If you choose not to do this, then references to the ambiguous name will be interpreted as the local variable and not the parameter. To reference a parameter in this situation, you must qualify it with the stored procedure name. Figure 158 is an example of using variables and parameters with the same name.

Avoid: Naming your parameters and your local variables with the same name.

CREATE PROCEDURE DRDARES1.SMP4LNS (out v_var1 integer, out v_var2 double ) SPECIFIC DRDARES1.S1473953 LANGUAGE SQL

P1: BEGIN declare v_var1 integer; declare v_var2 smallint;

set v_var1 = 10; set smp4lns.v_var1 = p1.v_var1; set v_var2 = 20; set smp4lns.v_var2 = p1.v_var2;

END P1

Figure 158. Using the same name for variables and parameters

Note that the variable v_var2 does not have the same data type as the parameter, but DB2 handles data type conversions whenever possible.

You should avoid variables with the same name as DB2 table columns. If you have a variable with the same name as a table column, you must also qualify the variable in SQL statements with the compound statement label. If you do not qualify the variable, DB2 will interpret that variable as the column name. Figure 159 is an example of using a variable and a column with the same name.

Chapter 10. SQL Procedures for DB2 for UNIX, Windows, OS/2 339 CREATE PROCEDURE DRDARES1.SMP5LNS (out p_id integer ) LANGUAGE SQL

P1: BEGIN declare id integer; set id = 100; select id into id from staff where id=p1.id; set p_id = id;

END P1

Figure 159. Using variables with the same name as a column

Note that it is not necessary to qualify the variable in the INTO clause, only in the WHERE condition.

In variable declarations you can specify a default value. If a default value is not specified, the variable is initialized to NULL.

10.3.3.3 Assigning values to variables The SET statement is used to assign values to variables and parameters. With DB2 UDB, the value being assigned to the variable may be a constant, an expression, a DB2 special register, a result of a SELECT statement, and so on. Figure 160 is an example of assigning special register values to parameters in SQL stored procedures.

340 Cross-Platform DB2 Stored Procedures: Building and Debugging CREATE PROCEDURE DRDARES1.SMP2LNS ( out v_user char(8), out v_date1 date, out v_date2 date, out v_days1 integer, out v_time1 time, out v_time2 time, out v_timest1 timestamp, out v_timest2 timestamp) SPECIFIC DRDARES1.S5336343 LANGUAGE SQL P1: BEGIN set v_user = user; set v_date1 = current date; set v_date2 = v_date1 - 10 days + 3 years; set v_days1 = days(v_date2); set v_time1 = current time; set v_time2 = v_time1 +1 hour - 30 minutes; set v_timest1 = current timestamp; set v_timest2 = v_timest1 - days(v_date1 - 10 days) days;

END P1

Figure 160. Assigning special registers to variables

You can also assign the result of DB2 UDB built-in functions or User Defined Functions (UDFs) to variables or parameters. However, you should keep in mind that using DB2 UDB functions, may limit the portability of your SQL stored procedures, since some of the built-in functions or UDFs might not be available in other DB2 servers, such as DB2 for OS/390 Version 6. Figure 161 is an example of assigning results of built-in functions to variables.

Chapter 10. SQL Procedures for DB2 for UNIX, Windows, OS/2 341 CREATE PROCEDURE DRDARES1.SMP8LNS (out v1 double, out v2 double, out v3 integer, out v4 integer , out v5 integer, out v6 integer , out v7 char (5),out v8 char(10), out v9 char(10), out v10 char (20), out v11 char(5), out v12 char(10)) SPECIFIC DRDARES1.S8389109 LANGUAGE SQL P1: BEGIN set v1 = tan(.5) - (sin(.5)/cos(.5)); set v2 = exp(sin(.3)) + exp(cos(.3)); set v3 = rand(); set v4 = ceil(5.2) + floor(4.3); set v5 = quarter(current date); set v6 = week(current date); set v7 = repeat('*',5); set v8 = lcase('ALINE'); set v9 = replace('a1b1c1','1','2'); set v10 = monthname(current date) || dayname(current date); set v11 = ltrim('felipe '); set v12 = substr('abcdefghijklmnopq',5,10);

END P1

Figure 161. Assigning results of built-in functions to variables

10.3.3.4 Handling errors In DB2 UDB SQL stored procedures, you can make references in your stored procedures body code to SQLCODE or SQLSTATE. All you need to do is to declare them previously in your stored procedures body.

We strongly recommend that you use handlers for finding and handling error conditions in your SQL stored procedure. This is the only choice you should make if you intend for your SQL stored procedure to be portable across DB2 platforms. Here is an example of how to do this: CREATE PROCEDURE PROC1() LANGUAGE SQL BEGIN DECLARE SQLCODE INTEGER DEFAULT 0; DECLARE SQLSTATE CHAR(5) DEFAULT ’00000’; ...... END

342 Cross-Platform DB2 Stored Procedures: Building and Debugging Avoid checking SQLCA or SQLSTATE values. This is a tricky area and there are some platform differences. If you do use SQLSTATE or SQLCA checks explicitly in your SQL stored procedure, please note that you can only check one of these values.

You can declare program variables to hold the SQLCODE or the SQLSTATE for different tests. Keep in mind that you have to choose one of these variables, SQLCODE or SQLSTATE, because the second assignment statement will not get the return code of the original statement, but from the previous one. Figure 162 shows an example of trying to set both variables in an SQL stored procedure.

DECLARE SQLCODE INTEGER DEFAULT 0; DECLARE SQLSTATE CHAR(5) DEFAULT ’00000’; DECLARE SQLC INTEGER DEFAULT 0; DECLARE SQLST CHAR(5) DEFAULT ’00000’; ....

SELECT ID INTO VID FROM STAFF WHERE ID = 13; (1) SET SQLC = SQLCODE; (2) SET SQLST = SQLSTATE; (3) ....

Figure 162. Setting SQLCODE and SQLSTATE variables to program variables

Note that in Figure 162, when you execute the SELECT statement: (1) if the row is not found, automatically DB2 UDB sets SQLCODE to 100 and SQLSTATE to ’02000’. The SET statement (2) sets the program variable SQLC correctly to the value of SQLCODE, then SQLC is set to 100. However, the SET statement also resets the values of SQLCODE and SQLSTATE, and since the command executed successfully, they are both set to 0. When you execute the second SET statement (3), the SQLSTATE you get no longer refers to the SQLSTATE of the SELECT statement (1), but to the SQLSTATE of the SET statement (2). This is the reason why you can only work with one of the variables.

The best way to write portable SQL stored procedures is to perform error handling using the DECLARE CONDITION and the DECLARE HANDLER statements in your SQL stored procedures. This will ensure portability of your SQL stored procedures among different DB2 platforms.

Nested condition handlers are not supported in the SQL stored procedures body. For more information on declaration of handlers, refer to Chapter 3, “SQL Procedures language” on page 55.

Chapter 10. SQL Procedures for DB2 for UNIX, Windows, OS/2 343 10.3.3.5 Nested compound statements SQL Procedures support implemented by DB2 UDB allows you to have nested compound statements in your SQL stored procedures body. However, you cannot have ATOMIC compound statements nested. Figure 163 shows an example of a nested compound statement in an SQL stored procedure.

P1: BEGIN DECLARE CONTINUE HANDLER FOR NOT FOUND BEGIN SET SQLC=SQLCODE; SET VAR1=1; END;

SELECT id into vid FROM STAFF where id = vid;

END P1

Figure 163. Nested compound statement

Since you cannot have ATOMIC nested compound statements, if you want to be able to undo the changes performed only in the nested compound statement, you can set a SAVEPOINT before the nested compound statement.

10.3.3.6 Savepoints Savepoints are points within an SQL stored procedure, that you can set to be able to rollback your transaction to that savepoint. A savepoint is set using the SAVEPOINT statement, and may have a name associated to it. (See Figure 164.)

P1: BEGIN UPDATE... ; INSERT... ; ... SAVEPOINT S1; BEGIN SET VAR1=1; DELETE... ; INSERT ... ; END; ..... END P1

Figure 164. Setting a SAVEPOINT

344 Cross-Platform DB2 Stored Procedures: Building and Debugging In your SQL stored procedures, if you detect an error, you can use the ROLLBACK TO SAVEPOINT statement to rollback changes performed after the savepoint was set. A rollback to a savepoint rolls back just the work done after the savepoint, the savepoint itself still exists. You can rollback to it again, if necessary. A rollback to a savepoint undoes any changes, and also closes all open cursors.

If you plan to build portable SQL stored procedures, you must be aware that DB2 for AS/400 does not support savepoints, but DB2 UDB for OS/390 V6 does. Also, you must consider that DB2 for UNIX, Windows, and OS/2 just allow to return to the last savepoint and the DB2 for OS/390 supports nested savepoints.

10.3.3.7 Considerations for comments and blank lines Neither blank lines or comments are tolerated before the actual start of the stored procedure code, that is not in or before the CREATE PROCEDURE DDL statement. CREATE PROCEDURE TEAM.Proc1 ( OUT SQLSTATE_OUT char(5), OUT SQLCODE_OUT int ) SPECIFIC TEAM.S1036175 RESULT SETS 1 LANGUAGE SQL ------SQL stored procedure TEAM.Proc1 ------P1: BEGIN DECLARE SQLSTATE CHAR(5) DEFAULT '00000'; DECLARE SQLCODE INT DEFAULT 0;

-- Declare cursor DECLARE cursor1 CURSOR WITH RETURN FOR SELECT * FROM SYSCAT.PROCEDURES;

DECLARE EXIT HANDLER FOR SQLEXCEPTION IF (1 = 1) THEN SET SQLSTATE_OUT = SQLSTATE; SET SQLCODE_OUT = SQLCODE; END IF;

-- Cursor left open for client application OPEN cursor1;

SET SQLSTATE_OUT = SQLSTATE; SET SQLCODE_OUT = SQLCODE; END P1

Chapter 10. SQL Procedures for DB2 for UNIX, Windows, OS/2 345 10.4 Stored procedures preparation In DB2 UDB, there are many different ways to build your SQL stored procedures into your server. You can use the Stored Procedures Builder tool, the DB2 Command Line Processor, the DB2 Command Center, or any application program issuing the CREATE PROCEDURE statement. Figure 165 shows different ways to create your SQL stored procedures.

(1) Stored Procedure Press Builder Tool Build (Windows)

(2) Command Line SQL Processor Procedure Definition Compiled

(3) Any Client Application (Command Center/ Script Center)

Figure 165. Ways to create SQL stored procedures in DB2 UDB

It is important to notice that, regardless of the method used to start the creation of the stored procedure, the process that is used by DB2 UDB internally is always the same, and the results obtained are equal.

When you submit a CREATE PROCEDURE statement, DB2 UDB performs a series of steps to build your procedure in the server. These steps are always the same, and involve the creation of a C source from your SQL stored procedures source. This C source is precompiled, compiled, and linkedited to generate a DLL for your SQL stored procedures. So, your SQL stored procedures are not interpreted during execution, which is important in terms of performance. The last step in the preparation of your SQL stored procedures is registering the procedure and parameters in the DB2 catalog tables SYSIBM.SYSPROCEDURES and SYSIBM.SYSPROCPARMS.

Figure 166 shows the steps involved in the preparation of an SQL stored procedure.

346 Cross-Platform DB2 Stored Procedures: Building and Debugging Input Performed steps Output

.SQC source with SQL and CREATE PROCEDURE #line SQLPROC 1 SQL Parsing LANGUAGE SQL Input statements P1: BEGIN & generation DECLARE cur1 CURSOR WITH RETURN FOR SELECT * FROM employee; C OPEN cur1; precompile END P1 2 SQL listing C source Precompilation with messages

3 C Compile and Link Package

.o object installed in 4 DB2 UDB catalog /function/routines/udp/schema_name/... SYSCAT.PROCEDURES, DLL, C, SQC SYSCAT.PROCPARMS

Figure 166. Preparation steps for SQL stored procedures in DB2 UDB

Note that as a result of the first step, SQL Parsing and Generation, an SQC file with a C source for your stored procedure is generated. This file also contains, as comments, your SQL stored procedures source.

The executable files (DLLs in Windows NT) are created in the directory /sqllib/function/routines/udp/schema_name. The specific name of the stored procedure is used as the name for the executable file. As an example, if you have an SQL stored procedure named PROC1 with an specific name S4231567, an executable named S4231567 (S4231567.DLL in NT) will be created for your stored procedure.

An SQL stored procedure executes as a static application. A package is also bound as one of the steps of the preparation process. The specific name of the procedure is used as the package name.

Chapter 10. SQL Procedures for DB2 for UNIX, Windows, OS/2 347 10.4.1 Privileges required to prepare an SQL stored procedure To issue a CREATE PROCEDURE statement that creates an SQL stored procedure, the authorization ID executing the statement must have at least one of the following privileges: • SYSADM or DBADM authority • IMPLICIT_SCHEMA authority on the database, if the implicit or explicit schema name of the procedure does not exist • CREATIN privilege on the schema, if the schema name of the procedure refers to an existing schema

If the authorization ID has insufficient authority to perform the operation, an SQLSTATE 42502 is raised.

10.4.2 Copying SQL stored procedures between DB2 UDB servers When the support for SQL Procedures become available for DB2 UDB, it is possible that a utility to generate the source CREATE PROCEDURE statements for the SQL stored procedures will be included. However, since the source is available in the DB2 UDB catalog, it is very simple to generate a text file with the CREATE PROCEDURE statements and then submit this file to another DB2 UDB server to replicate the stored procedures.

To generate a sequential file, after connecting to the DB2 server, issue the following command, from the DB2 Command Window: db2 SELECT TEXT CONCAT ’$’ FROM SYSIBM.SYSPROCEDURES WHERE LANGUAGE = ’SQL’ > sqlp.ddl

The above command generates a file sqlp.ddl, that contains the CREATE PROCEDURE statements for all the SQL stored procedures in your database. You can include more conditions in the WHERE clause if you want to filter the procedures you want to copy. You can edit the file generated to remove the initial and final lines, and do any kind of changes you want, such as bulk changes to the schema name of the procedures, or table names.

After changing the file, you may submit it to another DB2 UDB server, by connecting to the server, and then issuing the following command: db2 -td$ -fsqlp.ddl

The above command creates all the SQL stored procedures in the sqlp.ddl file at the remote DB2 UDB server.

348 Cross-Platform DB2 Stored Procedures: Building and Debugging Chapter 11. SQL Procedures — OS/390 platform

In this chapter, we explain how to code SQL Procedures for DB2 UDB for OS/390 version 5 and version 6 servers. We focus on system requirements and planning, as well as the rules for writing, preparing, and debugging an SQL Procedures program. Also, we show how the new tool, Stored Procedure Builder (SPB), can be used in conjunction with the SQL Procedures support on OS/390.

11.1 General considerations The SQL Procedures language support on the OS/390 platform has been implemented for DB2 for OS/390 version 5 and DB2 UDB for OS/390 version 6.

The SQL Procedures support improves the development and usability of stored procedures, ensures the portability of SQL stored procedures across DB2 platforms, and simplifies migration to DB2 from other environments through the use of a translation tool.

There are three main methods, described in detail later in this chapter, for developing SQL stored procedures on OS/390: • Method 1 — Using the Stored Procedure Builder (SPB) tool, which runs on all current Windows, AIX and Sun platforms. The SPB invokes the OS/390 SQL Procedure Processor (DSNTPSMP) for building the stored procedure. • Method 2 — Using the OS/390 SQL Procedure Processor in batch. • Method 3 — Using Job Control Language (JCL) or Command List (CLIST).

For most situations, we recommend that you use Method 1, because the SPB tool helps you in coding, testing and debugging of your stored procedure, thereby improving the development process (see Chapter 2, “The IBM DB2 Stored Procedure Builder” on page 7 for more information about the SPB). However, you should also read the section for each corresponding method and choose the one that fits best in your environment.

11.2 Coding considerations In this section we document some of the issues that we found while creating SQL stored procedures on the OS/390 platform.

© Copyright IBM Corp. 2001 349 11.2.1 Length and size limits The size of your SQL stored procedure code is limited to 32K. Note that if you are using DSNTPSMP, the tables SYSIBM.SYSPSM, SYSIBM.SYSPSMPOPTS, and SYSIBM.SYSPSMOUT will be updated. Although the field PROCCREATESTMT in SYSIBM.SYSPSM, which contains the source code, is limited to 3800 characters, DSNTPSMP will break up your source into 3800 character "chunks" and use the SEQNO field to sequence these lines to keep the order of your source code.

When creating your SQL stored procedure using the SPB, the width of your statements must be limited to 87 bytes. Although the edit screen in SPB is wider than this, the DB2 pre-compiler will only read a width of 87 bytes.

The name of the SQL stored procedure can be a maximum of 18 characters, but due to OS/390 limitations, the member name created at the DBRMLIB, LOADLIB, and other libraries is limited to 8 bytes. If you nevertheless try to create procedure DB2USER.PROC12345678 for the first time, SPB completes without any problems. The associated DBRM and load module names are PROC1234. If you try to create procedure DB2USER.PROC123456789 afterwards, SPB tells you that there is already an existing DBRM with name PROC1234 and does not continue with the processing. The same happens to you if you try to create a procedure with the same name, but different schema. That means, you cannot create procedure DB2USER.PROC1234 and DB2USR.PROC1234 using the SPB.

At the time the book was written, APAR PQ43437 was still open. When the associated PTF for this APAR becomes available, the way SPB handles procedure names for OS/390 longer than 8 characters is changed. The new behavior will be: • You can use procedure names which are up to 18 character in length • All PDS members (DBRM, load module) will be generated names

Note: When you select the procedure out of the SYSROUTINES catalog, the loadmod name is the name of all the retained members (DBRM, load module, translated C source).

• Instead of checking the PDS members for duplicate names, only the DB2 catalog is checked to identify already existing procedure names. • You can now use the same procedure name with different schema names.

350 Cross-Platform DB2 Stored Procedures: Building and Debugging 11.2.2 Parameters and variables To store data used within an SQL stored procedure, you can declare SQL variables. SQL variables can have the same data types and lengths as SQL stored procedures parameters.

SQL stored procedures parameters and variables have the following restrictions: • Since the precompiler folds all SQL variables to uppercase, two variables cannot be declared the same except for their case. For example, variables VAR1 and var1 declared in the same SQL stored procedure will receive a compile error. • Variable and parameter names cannot be the same name. The following error message is issued: DSNH590I Name is not unique • An SQL reserved word cannot be used as a parameter or variable. • Do not precede the variable name with a colon.

The following items should be qualified to avoid ambiguity and also prevent compilation or bind errors: • When using a parameter in the procedure body, qualify the parameter name with the procedure name. • Qualify variable names with the label of the compound statement in which the variables appear. • Qualify column names with the table name. For example: SELECT STAFF.ID INTO V_ID FROM DB2RES1.STAFF WHERE STAFF.ID = V_ID; • A parameter name can be the same as a column name, but the column name must be qualified with the table name. • If you qualify a parameter with a misspelled procedure name, the following error message is issued: DSNH312I Undefined or unusable host variable This is also true of variables qualified with misspelled label names.

11.2.3 Handling SQLCODE and SQLSTATE values The Section A.3.7, “SP06LMS.SQL sample” on page 469 shows how the SQLCODE and SQLSTATE values can be captured and handled in an SQL stored procedure. But it is important to be aware of the following warning when trying to capture both the SQLCODE and SQLSTATE values:

Chapter 11. SQL Procedures — OS/390 platform 351 Important Since a SET statement is an SQL statement, the SQLCODE and SQLSTATE are set to the values returned by the SELECT generated under-the-covers for the SET statement.

Assume you are using the following SQL statement which receives SQLCODE -601, because the specified table already exists. CREATE TABLE T1 .....; SET CODE = SQLCODE; SET STATE = SQLSTATE;

In this case, the SQL statement 'SET CODE = SQLCODE' moves the SQLCODE -601to variable CODE.

SET CODE = SQLCODE is an SQL statement. If the move of -601 to CODE is performed successfully, the special register SQLCODE is set to 0 and SQLSTATE '00000'. Therefore statement result of statement 'SET STATE = SQLSTATE' is: STATE = '00000'.

For a more detailed description on the behaviors of handlers for DB2 UDB for OS/390, you can refer to Section 3.5.4, “Handling errors in an SQL stored procedure” on page 92.

11.2.4 SQL statements To define your SQL stored procedure to DB2 in version 6, a CREATE PROCEDURE DDL statement and will be generated for you from the SQL Procedures precompiler. You can look up the generated statement in the SYSTSPRT section of the WLM address space which is used to run the procedure processor. Search for SYSUT2 and you will find information which is similar to that shown in Figure 167.

352 Cross-Platform DB2 Stored Procedures: Building and Debugging *** SYSUT2 from precompiler CREATE PROCEDURE DB2RES3 . SABINESNEWPROC1 ( OUT VAR1 CHAR ( 20 ) ) LANG UAGE SQL MODIFIES SQL DATA COLLID TEST WLM ENVIRONMENT WLMPSM ASUTIME NO LIMIT RUN OPTIONS 'NOTEST(ALL,*,,VADTCPIP&9.1.151.105:*)' ; Subroutine: Precompile C precompile rc= 0 Subroutine: Bind_Rebind Bind/Rebind rc= 0 Subroutine: Compile Compile rc= 0 Subroutine: Prelink Prelink rc= 4 Subroutine: Update_Tables

Figure 167. CREATE PROCEDURE statement from SYSUT2

If you are building your SQL stored procedure through JCL, you must execute this generated statement through DSNTIAD or any other appropriate Job to define your SQL stored procedure to DB2. If you are using the SPB or calling DSNTPSMP directly, this will be automatically executed for you.

11.2.5 Client application No major change is needed in the way the client application is coded, or the way it calls a stored procedure written with the SQL Procedures programming language.

Note: Following the SQL/PSM standard, DB2 supports only the parameter style GENERAL WITH NULLS linkage convention for SQL stored procedures. This means that you should include a null indicator variable for each of the parameters that will be returned from the SQL stored procedure. Refer to DB2 UDB for OS/390 V6 Application Programming and SQL Guide, SC26-9004, for detailed information about linkage conventions.

11.3 Stored procedure preparation There are three methods available for preparing a stored procedure written in SQL Procedures language as shown in Section 11.1, “General considerations” on page 349. 1. The Stored Procedure Builder (SPB) Tool, which invokes the OS/390 Procedure Processor, can be used to build your SQL stored procedures. 2. The OS/390 Procedure Processor, called DSNTPSMP, can be used to build your SQL stored procedures.

Chapter 11. SQL Procedures — OS/390 platform 353 3. All steps required to build an SQL stored procedure can be run using JCL. You can use the DB2-supplied JCL procedure (DSNHSQL). The option to compile using the DB2 Interactive (DB2I) panels will be available from version 6.

1 2 3

OS/390 SPB Procedures Using JCL Processor

SQL Precompile normal precompile bind compile prelink link update DB2 tables

Figure 168. Three methods for preparing SQL stored procedures

11.3.1 Steps to create an SQL stored procedure To create an SQL stored procedure, you must perform the steps described in the following sequence: 1. Create the SQL stored procedures source (either manually or through prompted help via the SPB). 2. Precompile the source. The result of the precompile is a C language program complete with SQL and logic. 3. Precompile the C program with the normal DB2 precompiler (DSNHPC) as for any other program using parameter of HOST(C).

354 Cross-Platform DB2 Stored Procedures: Building and Debugging 4. Compile and linkedit the modified C source. 5. Bind the DBRM. 6. Define the SQL stored procedure using the CREATE PROCEDURE statement to DB2. The following tables might be updated: - SYSIBM.SYSROUTINES and SYSIBM.SYSPARMS - SYSIBM.SYSPSM - SYSIBM.SYSPSMOPTS - SYSIBM.SYSPSMOUT Notes: • The SYSIBM.SYSPSM and SYSPSMOPTS are DB2 catalog tables stored into the DSNDPDM DB2 database. See bellow: ------+------+------+------+ NAME TSNAME DBNAME ------+------+------+------+ SYSPSM DSNSPSM DSNDPSM SYSPSMOPTS DSNSPSM DSNDPSM

• If you are using Method 1 or 2, a DDL CREATE PROCEDURE statement, will be automatically executed for you. But if you are using Method 3, you need to execute this statement to define the procedure to DB2.

11.3.2 Authorization The authorization used for DB2 when generating and binding the SQL stored procedure is the current SQLID or submitter of the job.

The extra privileges needed by the person requesting the build of the SQL stored procedure: • DB2 version 6 — CREATEIN, DROPIN or ALTERIN to the SCHEMA name under which you will be creating your SQL stored procedure. • DB2 version 6 — (if using SPB or DSNTPSMP), you need EXECUTE ON PROCEDURE DSNTPSMP. • Alternatively, you need SYSADM or SYSCTRL authority.

The normal privileges are needed to bind to the collection being used for your SQL stored procedure and any privileges to tables referenced in your SQL stored procedure.

Chapter 11. SQL Procedures — OS/390 platform 355 Please also note that update access needs to be given on the datasets referenced in the WLM region, to the userid running the WLM.

11.3.3 Using the SPB to create an SQL stored procedure The easiest method of creating, generating, and testing your SQL stored procedure is to use the Stored Procedure Builder Tool. Only the OS/390 related options will be discussed here. See Chapter 2, “TheIBMDB2Stored Procedure Builder” on page 7 for a general description of using the SPB to build your SQL stored procedure.

The OS/390 Options screen is available from the Advanced button on the Options tab when using the Wizard to create your SQL stored procedure. See Figure 174 on page 383. It is also available from the Properties option when you right-click on your procedure name (see Figure 175 on page 384) and from the File -> Properties option where you set defaults for the whole project (see Figure 176 on page 385).

You specify on this panel the options that will be used when SPB builds your procedure.

The Build utility name needs to be changed if you are running the OS/390 Procedure processor in multiple WLM environments. See Section 11.4, “Use of different WLM environments in SPB” on page 381 for more details about this.

Once you have successfully generated and built your SQL stored procedure, you can then choose to test it by clicking the Run button from the main panel.

11.3.3.1 SQL costing information The SPB tool allows you to measure the costing of the SQL statements in your SQL stored procedure. This functionality is only available for the OS/390 environment.

The stored procedure monitor program DSNWSPM (which itself is an assembler stored procedure) returns CPU time and other DB2 costing information for the thread on which it is running. A client program can connect to DB2 on OS/390, execute SQL and then call DSNWSPM to find out how much CPU time it took.

DSNWSPM works on either a local or remote thread.

356 Cross-Platform DB2 Stored Procedures: Building and Debugging Setup of the stored procedure monitor program Since the setup of this functionality is not included in the installation process of DB2 UDB for OS/390, you must perform the steps listed below to set up the stored procedure monitor program DSNWSPM: 1. Install PTF PQ24891/UQ28282 2. Set up the DBRM alias. Check the DBRMLIB where you installed DSN@SPM. It may already contain a member named DSNWSPM, which is an alias of DSN@SPM. If an alias does not exist, you can create it under TSO option 6 using the command: RENAME ‘your_dbrmlib(DSN@SPM)’‘your_dbrmlib(DSNWSPM)’ ALIAS 3. Create DSNWSPM as a stored procedure in your DB2 subsystem. Use the following CREATE PROCEDURE statement to perform this step: CREATE PROCEDURE SYSPROC.DSNWSPM ( INOUT PA CHAR(8) FOR BIT DATA, INOUT PB CHAR(8) FOR BIT DATA, OUT P1 CHAR(16), OUT P2 CHAR(16), OUT P3 INTEGER, OUT P4 INTEGER, OUT P5 INTEGER, OUT P6 INTEGER, OUT P7 INTEGER ) DYNAMIC RESULT SET 0 EXTERNAL NAME DSNWSPM LANGUAGE ASSEMBLE NO WLM ENVIRONMENT COLLID DSNWSPM RUN OPTIONS 'TRAP(ON),TERMTHDAC(UADUMP)' PROGRAM TYPE MAIN MODIFIES SQL DATA ASUTIME NO LIMIT STAY RESIDENT NO COMMIT ON RETURN NO PARAMETER STYLE DB2SQL SECURITY DB2 ; 4. Bind DSNWSPM using the following DSN command: DSN SYSTEM(ssid)

BIND PACKAGE(DSNWSPM) - CURRENTDATA(N)) - MEMBER(DSNWSPM) - ACT(REP) - ISO(CS) - VAL(BIND)

Chapter 11. SQL Procedures — OS/390 platform 357 BIND PLAN (DSNWSPM) PKLIST(DSNWSPM.DSNWSPM) - ISO(CS) - ACTION(REPLACE)

END 5. Start and stop the stored procedures address space. 6. Make sure that accounting trace is running. If it it not, use DB2 command -START TRACE(ACCTG) CLASS(1,2,3) to start it.

Usage of the stored procedure monitor program From the SPB tool, click on the Actual Costs button to get the costs of running the SQL stored procedure against the OS/390 environment. This button is located on the SQL Query tab when generating your SQL stored procedure using the SmartGuide. For this release of the SPB, the actual costs will only be calculated for the whole SQL stored procedure, but in future releases you will be able to get the cost of each SQL statement by highlighting it.

The SPB calls the stored procedure monitor program DSNWSPM which starts the monitor trace and formats the output. From the output you can then view and sort by different columns. Note that the first time this is called, the number of GETPAGEs is higher because the module needs to be loaded into the buffer.

The instrumentation values that DSNWSPM provides are: • CPU time in external format • Latch/lock contention wait time, external format • CPU time as an integer in hundredths of a second • Latch/lock contention wait time • Number of GETPAGEs in integer format • Number of read I/Os in integer format • Number of write I/Os in integer format

Figure 169 shows an output of the SQL Procedures monitor program. You can sort the information shown by clicking on the columns. Additionally, if you place your mouse pointer over any SQL statement, it will be expanded for you.

358 Cross-Platform DB2 Stored Procedures: Building and Debugging Figure 169. SQL Costing Information panel

Needed authorizations The authority you need to execute the stored procedure is: MONITOR1, TRACE, and EXECUTE ON PROCEDURE

For example, to allow USRT011 to execute DSNWSPM: GRANT TRACE TO USRT011; GRANT MONITOR1 TO USRT011; GRANT EXECUTE ON PROCEDURE SYSPROC.DSNWSPM TO USRT011;

Invoking the stored procedure monitor program (DSNWSPM) You can call DSNWSPM in two ways: 1. Before and after executing the SQL 1. Only after executing the SQL

The preferred way to use DSNWSPM is the first method, because the time values are more accurate, as they are the delta values between beginning and ending time. If you call DSNWSPM using the second method, after executing the SQL only, the beginning CPU time returned to you will include the thread setup time, and may include the times for SQL that you have previously executed on the same thread.

11.3.4 Using batch DSNTPSMP to create an SQL stored procedure After coding the SQL stored procedure you can choose to prepare it using the OS/390 Procedure Processor (method 2). The processor automates and performs all the steps required to generate and build your SQL stored procedure.

The way to do this is to code a client program (coded in any language), which invokes the OS/390 Procedure Processor. The processor (DSNTPSMP) itself is a stored procedure which has input and output parameters. You pass to it the function that you wish performed on your SQL stored procedure source.

Chapter 11. SQL Procedures — OS/390 platform 359 The functions are: Build, Destroy, Rebuild, Rebind and Alter LE Run Options (see Section 11.3.4.4, “DSNTPSMP functions” on page 364).

Using this method, your client program will invoke DSNTPSMP and pass to it the parameters which it needs to completely build your stored procedure.

One of the reasons for coding a client program rather than using the SPB Tool is that the project administrator or DBA might wish to standardize the bind, link, or compile options within a project. One way of doing this is to only allow the programmer to pass a few parameters, for example: function, SQL stored procedure name, SQL stored procedure source. The other options can then be hardcoded in your client program and therefore "hidden" from the SQL stored procedure developer. See Section 11.3.4.5, “Example of a client program” on page 366 for a sample client program written in PL/1, which does this.

Figure 170 shows the input and output to DSNTPSMP. The WLM environment defined to be used by DSNTPSMP must be available before you call DSNTPSMP.

Input Parameters

1 Function Prelink Options 7

2 Procedure Name Link Options 8

3 Source Code LE Runtime Options 9

4 Bind Options Input Dataset 10

5 Compiler Options Build Schema 11

6 Precompiler Opts Build Name 12

DSNTPSMP D

B Output A C string

Result Set Datasets referenced in WLM DB2 tables updated

Figure 170. Input / output for SQL Procedures processor

360 Cross-Platform DB2 Stored Procedures: Building and Debugging 11.3.4.1 Input parameters for DSNTPSMP The parameters passed to DSNTPSMP must be in this order: 1. Function: The action that you want DSNTPSMP to perform on your SQL stored procedure. See 11.3.4.4, “DSNTPSMP functions” on page 364 for a description of each function. 2. Procedure Name: The name of your SQL stored procedure (maximum 27 characters — 8-byte schema, 1-byte dot, 18-byte routine name). This needs to be the same as the name you specify in your CREATE PROCEDURE statement. Refer to Section 11.2.1, “Length and size limits” on page 350 for more detailed information. 3. Source Code: The SQL stored procedure source code. This is not needed if you pass the source via an Input File data set. But if both parameters are passed, source will be taken from this parameter in preference to source from the data set. In version 6, source code passed in as a parameter can be 32K. If using a dataset for the input, there is no limit. 4. Bind Options: The options with which you wish to bind your SQL stored procedure package. The maximum length is 1024 characters. 5. Compiler Options: The options which you want to pass for use in compiling your SQL stored procedure module, for example, TEST/NOTEST. The maximum length is 255 characters. 6. Precompiler Options: The options to be used during pre-compilation of your SQL stored procedure. Maximum length is 255 characters. 7. Prelink Options: The options to be used to pre-link your module. Maximum length is 255 characters. 8. Link Options: The options passed to the linkage editor. Maximum length is 255 characters. 9. LE Runtime Options: The options to be passed to the Language Environment for execution of your module. Input passed here will be ignored for other functions. The maximum length is 254 characters. 10.Input Dataset: The data set containing the SQL stored procedure source code. If you pass this parameter, then you do not need to pass the source in the Source Code parameter. But if both parameters are passed, the source in the Source Code parameter is used in preference. 11. Build Schema: This contains the schema name for the procedure name you pass in the Build Name (parameter 12). Usually this is SYSPROC for version 5, and could be any name in version 6. 12.Build Name: A name for the OS/390 Procedures Processor, usually DSNTPSMP. The maximum length is 18 characters.

Chapter 11. SQL Procedures — OS/390 platform 361 11.3.4.2 DDNAMES used by DSNTPSMP on WLM The DDNAMES for the permanent datasets referenced on the WLM region that are used by DSNTPSMP are described here. They are used for both input and output: • SQLDBRM — Your SQL stored procedure DBRM module • SQLCSRC — Your SQL stored procedure precompiled C source code generated by DSNTPSMP • SQLLMOD — SQL stored procedure generated load module • SQLLIBC — Language C header files • SQLLIBL — Link libraries, run libraries, DB2 load libraries • SYSMSGS — SCEEMSG "C" messages library for prelinker

Other ddnames are also used, but permanent datasets do not need to be allocatedtothem.

Following is part of the JCL used in our WLM environment, which was set up for executing DSNTPSMP, showing the relevant ddnames : //************************************************************ //**** Data sets required by the SQL Procedures Processor **** //************************************************************ //SQLDBRM DD DISP=SHR, <== DBRM Library // DSN=DSN.DBRMLIB.DATA //SQLCSRC DD DISP=SHR, <== Generated C Source // DSN=DSN.SRCLIB.DATA //SQLLMOD DD DISP=SHR, <== Application Loadlib // DSN=DSN.RUNLIB.LOAD //SQLLIBC DD DISP=SHR, <== C header files // DSN=CEE.SCEEH.H // DD DISP=SHR, // DSN=CEE.SCEEH.SYS.H //SQLLIBL DD DISP=SHR, <== Linkedit includes // DSN=CEE.SCEELKED // DD DISP=SHR, // DSN=DSN.SDSNLOAD //SYSMSGS DD DISP=SHR, <== Prelinker msg file // DSN=CEE.SCEEMSGP(EDCPMSGE) //************************************************************ //**** Workfiles required by the SQL Procedures Processor **** //************************************************************ //SQLSRC DD UNIT=SYSALLDA,SPACE=(23440,(20,20)), // DCB=(RECFM=FB,LRECL=80,BLKSIZE=23440) //SQLPRINT DD UNIT=SYSALLDASYSALLDA,SPACE=(23440,(20,20)), // DCB=(RECFM=VB,LRECL=137)

362 Cross-Platform DB2 Stored Procedures: Building and Debugging //SQLTERM DD UNIT=SYSALLDA,SPACE=(23440,(20,20)), // DCB=(RECFM=VB,LRECL=137) //SQLOUT DD UNIT=SYSALLDA,SPACE=(23440,(20,20)), // DCB=(RECFM=VB,LRECL=137) //SQLCPRT DD UNIT=SYSALLDA,SPACE=(23440,(20,20)), // DCB=(RECFM=VB,LRECL=137) //SQLUT1 DD UNIT=SYSALLDA,SPACE=(23440,(20,20)), // DCB=(RECFM=FB,LRECL=80,BLKSIZE=23440) //SQLUT2 DD UNIT=SYSALLDA,SPACE=(23440,(20,20)), // DCB=(RECFM=FB,LRECL=80,BLKSIZE=23440) //SQLCIN DD UNIT=SYSALLDA,SPACE=(32000,(20,20)) //SQLLIN DD UNIT=SYSALLDA,SPACE=(8000,(30,30)), // DCB=(RECFM=FB,LRECL=80,BLKSIZE=23440) //SQLWORK1 DD UNIT=SYSALLDA,SPACE=(23440,(20,20))SPACE=(23440,(20,20)), <= Work C source // DCB=(RECFM=FB,LRECL=80,BLKSIZE=23440) //SQLWORK2 DD UNIT=SYSALLDA,SPACE=(23440,(20,20)), <= Work LOADMOD // DCB=(RECFM=U) //SYSMOD DD UNIT=SYSALLDA,SPACE=(23440,(20,20)), <= PRELINKER // DCB=(RECFM=FB,LRECL=80,BLKSIZE=23440)

11.3.4.3 Output parameters of DSNTPSMP Depending on whether your SQL stored procedure was successfully generated, the output from your call to DSNTPSMP will be as follows: • If your SQL stored procedure was successfully generated, the DBRM and load module members are placed into the data sets referenced by the ddnames on the WLM started task JCL. See "A" in Figure 170 on page 360. • If your SQL stored procedure was successfully generated, the caller of DSNTPSMP (which might be SPB or your own client) must commit the changes made to the DB2 tables. See "B" in Figure 170 on page 360. If there are any problems found by DSNTPSMP, and rows are returned in the result set, the caller must issue a ROLLBACK. • When an unrecoverable error was received, DSNTPSMP will store all diagnostic information into a temporary table and return these as a result set to the calling application (SPB Tool or your own) indicating the failing step and a return code. See "C" in Figure 170 on page 360. You need to code the normal result set processing to process the messages received. For example: - DESCRIBE PROCEDURE - ASSOCIATE LOCATORS - ALLOCATE CURSOR - DESCRIBE CURSOR

Chapter 11. SQL Procedures — OS/390 platform 363 See 11.3.4.5, “Example of a client program” on page 366 for a sample written in PL/1. Output received via the Output String (outstring) parameter. This contains the results of your call to DSNTPSMP. You should pass an output parameter (empty variable) of length 255 when you invoke DSNTPSMP. The outstring parameter returns with zero condition code or error messages (see "D" in Figure 170 on page 360). For the time being, the outstring returned is only an integer such as 0, 4, 8, and 999. No text is returned. This may be enhanced in the future. Below, the text after the = sign is an explanation or programmer action: outstring: 0 = successful operation 4 = successful operation with warnings, look at result set 8 or higher = failure, look at result set 999 = severe internal error look at result set Note: If you are using DSNTPSMP directly, the input source string should be broken up into lines of code <=80, with the separating character being an EBCDIC newline ('15'x) or linefeed ('25'x).

11.3.4.4 DSNTPSMP functions Following are the functions performed by the OS/390 Procedure Processor: • BUILD This function goes through all the necessary steps for preparing an SQL stored procedure. The build process will terminate if the build is requested for an SQL stored procedure which already exists: MEDSALRY already exists in SQLDBRM. Figure 171 shows the steps executed in a BUILD process. Given the SQL stored procedure source as input: a. DSNTPSMP defines the SQL stored procedure to DB2 by updating the DB2 tables SYSIBM.SYSROUTINES and SYSIBM.SYSPARMS. The unmodified SQL stored procedure source is stored in the SYSIBM.SYSPSM table, and the process options are stored in SYSIBM.SYSPSMOPTS. b. The SQL Procedures pre-compiler translates the SQL procedure source to a C host language stored procedure with embedded SQL. c. A "normal" precompile is then done to produce a DBRM and a modified source. d. A bind is performed to create a stored procedure package.

364 Cross-Platform DB2 Stored Procedures: Building and Debugging e. The modified source is compiled with the C compiler, pre-linked and linkedited to produce an executable load module. If BUILD abends halfway through this process, the caller (SPB or own client) must issue a ROLLBACK to back out of the updates made to the DB2 tables.

SQL procedure source 1

SQL 2 precompiler DB2 tables

C source + embedded SQL

C 3 precompiler

4 bind compile/pre-link 5 Package link LOAD module

Figure 171. DSNTPSMP - The BUILD process

Below is an example of a call to DSNTPSMP to perform a BUILD: EXEC SQL CALL DSNTPSMP( :func,:proc-name,:PSM-source,:bnd-opt, :comp-opt, :pcomp-opt,:plnk-opt,:link-opt, :lert-opt, :in-dsname, :build-schema, :build-name, :out-var ) END-EXEC. • DESTROY This function cleans up the definitions in the catalog and the members in the libraries which are associated with the SQL stored procedure.

Chapter 11. SQL Procedures — OS/390 platform 365 Figure 172 shows the actions taken for the destroy process. a. First the definition of the stored procedure is deleted from SYSIBM.SYSPROCEDURES (v5) or dropped from SYSIBM.SYSROUTINES and SYSIBM.SYSPARMS (v6). b. The SQL stored procedure source is then deleted from SYSIBM.SYSPSM and SYSIBM.SYSPSMOPTS. c. A drop package is done for the stored procedure package. d. The load module, DBRM, and C source are deleted from the relevant libraries referenced in the ddnames on the WLM JCL.

a b c d

Delete Drop Delete from Drop SYSPSM & from procedure package SYSPSMOPTS ddnames

Figure 172. DESTROY process

The parameters that need to be passed to DSNTPSMP are the function and the procedure name. The other parameters can be empty (nulls). CALL DSNTPSMP( :func,:proc-name,,,,,,,,, ) • REBUILD Performs the same functions as BUILD but will overwrite any DB2 rows and library members if necessary. It is generally performed against an existing SQL stored procedure but is also allowed for new non-existent routines. The parameters passed are the same as for Build function. • REBIND This function will be used against an existing SQL stored procedure to change bind options and rebind the stored procedure package.

11.3.4.5 Example of a client program Below is a sample of a PL/1 program which calls DSNTPSMP to perform a build of an SQL stored procedure.

It can be coded generically enough so that only three parameters need to be passed: function, procedure name, and the SQL stored procedure source data set.

366 Cross-Platform DB2 Stored Procedures: Building and Debugging You would only need to compile it once. Using this program, the DBA or project administrator can control the compile, link, and bind options being used to create SQL stored procedures for their project.

PL/1 sample client program //***************************************************** //PSMBUILD JOB 'USER=JONATHAN','JONATHAN',CLASS=K, // MSGCLASS=H,MSGLEVEL=(1,1) //***************************************************** //* COMPILE/LINK THE CALLING APPLICATION //***************************************************** //STEPPROC EXEC PROC=DSNHPLIA,DB2LEV=DB2A,MEM=STUBPGM //PC.SYSIN DD * STUBPGM: PROCEDURE(PARMS) OPTIONS(MAIN );

EXEC SQL INCLUDE SQLCA; EXEC SQL INCLUDE SQLDA;

/**************************************************/ /* INPUT PARAMETERS /**************************************************/

DECLARE PARMS CHAR(100) VARYING ;

DECLARE WHATTODO CHAR(8) VARYING; DECLARE SPNAME CHAR(8) VARYING; DECLARE SRCDSN CHAR(80) VARYING;

DECLARE space1 BIN FIXED(15); DECLARE space2 BIN FIXED(15); DECLARE parm_len BIN FIXED(15);

DECLARE action CHAR(20) VARYING; DECLARE member_name CHAR(18) VARYING; DECLARE psm_program CHAR(32672) VARYING; DECLARE bind_opts CHAR(1024) VARYING; DECLARE comp_opts CHAR(255) VARYING; DECLARE precomp_opts CHAR(255) VARYING; DECLARE prelink_opts CHAR(255) VARYING; DECLARE link_opts CHAR(255) VARYING; DECLARE le_opts CHAR(254) VARYING; DECLARE input_dsn CHAR(80) VARYING; DECLARE buildschema CHAR(8) VARYING; DECLARE buildname CHAR(18) VARYING; DECLARE out_string CHAR(255) VARYING;

Chapter 11. SQL Procedures — OS/390 platform 367 DECLARE SP1RS SQL TYPE IS RESULT_SET_LOCATOR VARYING; DECLARE STEP CHAR(16); DECLARE FILE CHAR(8); DECLARE SEQN BIN FIXED(31); DECLARE LINE CHAR(255);

action = ''; member_name = ''; psm_program = ''; bind_opts = ''; comp_opts = ''; precomp_opts = ''; prelink_opts = ''; link_opts = ''; le_opts = ''; input_dsn = ''; buildschema = ''; buildname = ''; out_string = '';

buildschema='SYSPROC'; /* Schema name of builder */ buildname='DSNTPSMP'; /* Builder name */

/**************************************************/ /* parse the input parameter to get - */ /* function */ /* SQL Procedure module name */ /* SQL Procedure source dataset */ /**************************************************/ parm_len = length(parms); space1 = index(parms,' '); space2 = index(substr(parms,space1+1,parm_len-space1),' ');

WHATTODO = SUBSTR(PARMS,1,space1-1); SPNAME = SUBSTR(PARMS,space1+1,space2-1); SRCDSN = SUBSTR(PARMS,space1+space2+1,parm_len-space1-space2);

PUT SKIP LIST('######################'); PUT SKIP LIST('Function=',WHATTODO) ; PUT SKIP LIST('Progname=',SPNAME) ; PUT SKIP LIST('Dataset =',SRCDSN); PUT SKIP LIST('######################'); CLOSE FILE(SYSPRINT) ;

SELECT (WHATTODO); WHEN('BUILDT') CALL program1; /* BUILD for debug */ WHEN('BUILD') CALL program2; /* BUILD normally */

368 Cross-Platform DB2 Stored Procedures: Building and Debugging WHEN('DESTROY') CALL program3; /* DESTROY */ WHEN('REBUILD') CALL program4; /* REBUILD */ WHEN('REBIND') CALL program6; /* REBIND */ OTHERWISE DO; PUT SKIP LIST('** NO ACTION SPECIFIED, EXITING **'); EXIT; END; END; /*********************************************************/

EXEC SQL CALL :BUILDNAME ( :action, :member_name, :psm_program, :bind_opts, :comp_opts, :precomp_opts, :prelink_opts, :link_opts, :le_opts, :input_dsn, :buildschema, :buildname, :out_string) ;

IF SQLCODE¬=0 THEN call Print_SQLCA; PUT SKIP LIST ('*** SQLCODE from call == ',sqlcode);

PUT SKIP LIST('** STUBPGM Call return from REXX stored proc **'); PUT SKIP LIST ('REXX output parm follows.....'); PUT SKIP EDIT('Returned outstring =', out_string) (A,A(100));

/* Will get result set only if errors received */ PUT SKIP LIST ('Doing associate locators....'); EXEC SQL ASSOCIATE LOCATORS (:SP1RS) WITH PROCEDURE DSNTPSMP; IF (SQLCODE ¬=0) & (SQLCODE ¬= -482)THEN call Print_SQLCA;

PUT SKIP LIST ('Doing allocate cursors....'); EXEC SQL ALLOCATE C1 CURSOR FOR RESULT SET :SP1RS; IF (SQLCODE¬=0) & (SQLCODE ¬= -423) THEN call Print_SQLCA;

Chapter 11. SQL Procedures — OS/390 platform 369 PUT SKIP LIST ('** Result set follows **'); do while (sqlcode=0); EXEC SQL FETCH C1 INTO :STEP, :FILE, :SEQN, :LINE ; PUT SKIP DATA (LINE); end; PUT SKIP LIST ('** End of result set **');

program1: procedure;

comp_opts='LIST,TEST,LONGNAME'; precomp_opts='SOURCE'; prelink_opts='NOMAP,DEBUG(SHOWIO)'; link_opts='AMODE=31,MAP,LIST=ALL'; le_opts='TRAP(OFF),RPTOPTS(ON)'; input_dsn=SRCDSN; action='BUILD'; psm_program = ''; bind_opts='PACKAGE(COLLID) ACT(REP) ISO(CS)'; member_name=SPNAME;

end;

program2: procedure;

comp_opts='LIST'; precomp_opts='SOURCE'; prelink_opts='NOMAP'; link_opts='AMODE=31,MAP'; le_opts='TRAP(OFF),RPTOPTS(ON)'; input_dsn=SRCDSN; action='BUILD'; bind_opts='PACKAGE(COLLID) ACT(REP) ISO(CS)'; member_name=SPNAME;

end;

program3: procedure;

action='DESTROY'; member_name=SPNAME;

end;

program4: procedure;

370 Cross-Platform DB2 Stored Procedures: Building and Debugging call program1; action='REBUILD'; end; program6: procedure;

action='REBIND'; comp_opts='LIST,TEST,LONGNAME'; precomp_opts='SOURCE'; prelink_opts='NOMAP,DEBUG(SHOWIO)'; link_opts='AMODE=31,MAP,LIST=ALL'; le_opts='TRAP(OFF),RPTOPTS(ON)'; input_dsn=SRCDSN; psm_program = ''; bind_opts='PACKAGE(COLLID)'; member_name=SPNAME;

end;

Print_SQLCA: procedure; PUT SKIP EDIT('DUMP SQLCA BY FIELDS') (A); PUT SKIP EDIT('SQLCAID=',SQLCAID) (A,A(8)); PUT SKIP EDIT('SQLCABC=',SQLCABC) (A,F(11)); PUT SKIP EDIT('SQLCODE=',SQLCODE) (A,F(11)); PUT SKIP EDIT('SQLERRM=',SQLERRM)(A,A(LENGTH(SQLERRM))); PUT SKIP EDIT('SQLERRP=',SQLERRP) (A,A(8)); PUT SKIP EDIT('SQLERRD(1)=',SQLERRD(1)) (A,F(11)); PUT SKIP EDIT('SQLERRD(2)=',SQLERRD(2)) (A,F(11)); PUT SKIP EDIT('SQLERRD(3)=',SQLERRD(3)) (A,F(11)); PUT SKIP EDIT('SQLERRD(4)=',SQLERRD(4)) (A,F(11)); PUT SKIP EDIT('SQLERRD(5)=',SQLERRD(5)) (A,F(11)); PUT SKIP EDIT('SQLERRD(6)=',SQLERRD(6)) (A,F(11)); PUT SKIP EDIT('SQLWARN0=',SQLWARN0) (A,A(1)); PUT SKIP EDIT('SQLWARN1=',SQLWARN1) (A,A(1)); PUT SKIP EDIT('SQLWARN2=',SQLWARN2) (A,A(1)); PUT SKIP EDIT('SQLWARN3=',SQLWARN3) (A,A(1)); PUT SKIP EDIT('SQLWARN4=',SQLWARN4) (A,A(1)); PUT SKIP EDIT('SQLWARN5=',SQLWARN5) (A,A(1)); PUT SKIP EDIT('SQLWARN6=',SQLWARN6) (A,A(1)); PUT SKIP EDIT('SQLWARN7=',SQLWARN7) (A,A(1)); PUT SKIP EDIT('SQLWARN8=',SQLWARN8) (A,A(1)); PUT SKIP EDIT('SQLWARN9=',SQLWARN9) (A,A(1)); PUT SKIP EDIT('SQLWARNA=',SQLWARNA) (A,A(1)); PUT SKIP EDIT('SQLSTATE=',SQLSTATE) (A,A(5)); end;

Chapter 11. SQL Procedures — OS/390 platform 371 END STUBPGM; //LKED.SYSIN DD * INCLUDE SYSLIB(DSNELI) INCLUDE SYSLIB(DSNTIAR) NAME STUBPGM(R) //*************************************************** //* BIND THE CALLING APPLICATION //**************************************************** //STEPBND EXEC TSOBATCH,DB2LEV=DB2A //SYSTSIN DD * DSN SYSTEM(V51A)

FREE PACKAGE(COLLID.STUBPGM) FREE PLAN(SPMAINT)

BIND PACKAGE(COLLID) MEMBER(STUBPGM) BIND PLAN(SPMAINT) PKLIST(DSNREXCS.DSNREXX, COLLID.STUBPGM)

//********************************************************** //* INVOKE THE CALLER //********************************************************** //STEPRUN EXEC TSOBATCH,DB2LEV=DB2A //SYSTSIN DD * DSN SYSTEM(V51A)

RUN PROGRAM(STUBPGM) - PLAN(SPMAINT) - PARMS('/BUILD MEDIANSALARY SG245485.SAMPLES.SOURCE(MEDSAL)') //* //* PARMS('/DESTROY MYTEST2 DUMMY') //* PARMS('/BUILD LT1PSM1 SG245485.SAMPLES.SOURCE(LT1PSM1)') //* PARMS('/REBUILD LT1PSM1 SG245485.SAMPLES.SOURCE(LT1PSM1)')

Once the calling program is compiled, the SQL stored procedure developer only needs to execute STEPRUN when they want to generate their own SQL stored procedure.

Below is the output received from the program above for a successful REBUILD of an SQL stored procedure: ###################### Function= REBUILD Progname= MEDSAL Dataset = SG245485.SAMPLES.SOURCE(MEDSAL) ###################### *** SQLCODE from call == 0

372 Cross-Platform DB2 Stored Procedures: Building and Debugging ** STUBPGM Call return from REXX stored proc ** REXX output parm follows..... Returned outstring =0 Doing associate locators... Doing allocate cursors.... ** Result set follows ** ** End of result set **

Now that your SQL stored procedure is built, you can test it by building the client application to call it, or testing it through the SPB Tool.

Note: DB2 delivers a sample C-language caller of DSNTPSMP called DSN8ED5. The sample job DSNTEJ65 shows how to prepare and run DSN8ED4 to call DSNTPSMP to prepare a sample SQL stored procedure called DSN8ES2. DSNTEJ65 also prepares and invokes a sample C-language caller of DSN8ES2 called DSN8ED5.

11.3.5UsingJCLtocreateanSQLstoredprocedure The SQL stored procedure can also be prepared by invoking the DB2 supplied JCL procedure DSNHSQL (11.3.5.2, “JCL for DSNHSQL procedure” on page 377).

See 11.3.5.1, “JCL for building an SQL stored procedure” on page 375 for a version 5 example of the steps mentioned here: • DELCATG — Executes DSNTEP2. If definitions already exist for the stored procedure, that is, you have already built it, this step drops it in SYSIBM.SYSROUTINES and SYSIBM.SYSPARMS. If not, you will not need to execute this step. An example of the DROP PROCEDURE statement follows: DROP PROCEDURE SMP1LMS RESTRICT; • PROCESS — Calls the DSNHSQL procedure which executes the steps shown in Figure 173. a. The precompiler DSNHPC is executed twice, first to convert the SQL procedure source code to C language source code with embedded SQL.The parameter used when calling DSNHPC for the first run is PARM='HOST(SQL)'. b. DSNHPC is called again with PARM=’HOST(C)’ to precompile the C source generated by the previous step to process the embedded SQL calls. c. C compiler CBCDRVR is called to perform a normal C compile.

Chapter 11. SQL Procedures — OS/390 platform 373 d. EDCPRLK is called to perform a normal pre-linkedit. e. IEWL is called to perform a normal linkedit.

DSNHSQL process

DSNHPC converts SQL procedure source to a) C language source with embedded SQL

b) DSNHPC to process embedded SQL calls

c) CBCDRVR to compile the C program

d) EDCPRLK to pre-linkedit object module

e) IEWL to linkedit the pre-linked module

Figure 173. DSNHSQL process

• ISRTCATG — Executes DSNTIAD to register the definition for your SQL stored procedure to DB2. The statements generated are from the step which executes the DSNHPSM precompile. A DDL CREATE PROCEDURE statement is generated to define the procedure to SYSIBM.SYSROUTINES and SYSIBM.SYSPARMS. For example: CREATE PROCEDURE SMP0LMS6 ( IN EMPLOYEE_NO CHAR ( 6 ) , OUT EMP_FIRSTNAME VARCHAR ( 12 ) , OUT EMP_LASTNAME VARCHAR ( 15 ) , OUT SQLCPARM INTEGER )

374 Cross-Platform DB2 Stored Procedures: Building and Debugging FENCED RESULT SET 0 LANGUAGE SQL DETERMINISTIC MODIFIES SQL DATA NO DBINFO COLLID SG245485 WLM ENVIRONMENT WLMENV1 ASUTIME NO LIMIT STAY RESIDENT NO PROGRAM TYPE MAIN SECURITY DEFINER COMMIT ON RETURN NO BEGIN ...... END. One row which defines your procedure is created in SYSIBM.SYSROUTINES. The SYSIBM.SYSPARMS catalog table will contain one row for each input or output parameter required by your SQL stored procedure. In the example above, four rows will be added. • BINDSP — Binds the DBRM for your SQL stored procedure. Note: If you did not specify the collection id in the CREATE PROCEDURE statement, DB2 will not execute your SQL stored procedure even if you subsequently bind the DBRM to a specific collection id in this step. If you wish to use the collection id of the client, specify NO COLLID. Later when you bind the client package, you can then bind the SQL stored procedure package to the same collection id and your SQL stored procedure will be executed successfully. • SELCATG — Executes DSNTEP2 to select from SYSIBM.SYSPROCEDURES to view the inserted values for the new procedure.

Note: DB2 delivers a sample job called DSNTEJ63 that demonstrates how to use DSNHSQL to prepare a sample SQL stored procedure called DSN8ES1. The sample job DSNTEJ64 prepares and calls a sample caller of DSN8ES1 called DSN8ED3.

11.3.5.1 JCL for building an SQL stored procedure This is the JCL to manually create stored procedures using the SQL Procedures language. The SQL stored procedures source is input in ddname PC.SYSIN.

Chapter 11. SQL Procedures — OS/390 platform 375 Note 1. The precompiler invokes Module DSNRLI, which is used for WLM established stored procedures. If you are not using WLM to run your stored procedures, you must specify DSNALI here. 2. You must only delete rows from SYSIBM.SYSPSM and SYSIBM.SYSPSMOPTS if you used DSNTPSMP to create procedure BASECASE.

//BUILDER JOB 'USER=KATHLEEN','KATHLEEN',CLASS=A, // MSGCLASS=H,REGION=4096K //*------//* BUILDING SOURCE -> BASECASE //*------//JOBLIB DD DSN=CEE.SCEERUN,DISP=SHR <- IBM LE RUNTIME // DD DSN=DB2A.DSNEXIT,DISP=SHR <- DB2 USER EXITS // DD DSN=DB2A.DSNLOAD,DISP=SHR <- DB2 LOAD MODS //********************************************************************* //* DELETE FROM CATALOG THIS PROCEDURE //********************************************************************* //DELCATG EXEC TSOBATCH,DB2LEV=DB2A //SYSTSIN DD * DSN SYSTEM(V61A) RUN PROGRAM(DSNTEP2) //SYSIN DD * DROP PROCEDURE DB2RES3.BASECASE RESTRICT; DELETE FROM SYSIBM.SYSPSM WHERE PROCEDURENAME = ‘BASECASE’; DELETE FROM SYSIBM.SYSPSMOPTS WHERE PROCEDURENAME = ‘BASECASE’; //* //PROCESS EXEC DSNHSQL,MEM=BASECASE, // COND=(4,LT), // PARM.PC='HOST(SQL),SOURCE,XREF,MAR(1,72),STDSQL(NO)', // PARM.PCC='HOST(C),SOURCE,XREF,MAR(1,80),STDSQL(NO)', // PARM.C='SOURCE LIST MAR(1,80) NOSEQ LO RENT', // PARM.LKED='AMODE=31,RMODE=ANY,MAP,RENT' //PC.SYSUT1 DD DSN=&&SPDML,DISP=(,PASS), // UNIT=SYSDA,SPACE=(TRK,1), // DCB=(RECFM=FB,LRECL=80) //PC.SYSIN DD DISP=SHR,DSN=USER.SAMPLES.SOURCE(&MEM.) //LKED.SYSLMOD DD DSN=USER.RUNLIB.LOAD(&MEM.), // DISP=SHR //LKED.SYSIN DD * INCLUDE SYSLIB(DSNRLI) NAME BASECASE(R)

376 Cross-Platform DB2 Stored Procedures: Building and Debugging //ISRTCATG EXEC PGM=IKJEFT01,DYNAMNBR=20 //SYSTSPRT DD SYSOUT=* //SYSTSIN DD * DSN SYSTEM(V51A) RUN PROGRAM(DSNTIAD) PLAN(DSNTIAD) END //SYSPRINT DD SYSOUT=* //SYSUDUMP DD SYSOUT=* //SYSIN DD DSN=&&SPDML,DISP=(OLD,DELETE) <-FROM PRECEDING STEP //********************************************************************* * //* BIND STEP //********************************************************************* * //BINDSP EXEC TSOBATCH,DB2LEV=DB2A //SYSTSIN DD * DSN SYSTEM(V51A) BIND PACKAGE(COLLID) MEMBER(BASECASE) ACT(REP) ISO(CS) //********************************************************************* //* SELECT FROM CATALOG THIS PROCEDURE //********************************************************************* //SELCATG EXEC TSOBATCH,DB2LEV=DB2A //SYSTSIN DD * DSN SYSTEM(V61A) RUN PROGRAM(DSNTEP2) //SYSIN DD * SELECT * FROM SYSIBM.SYSPROCEDURES WHERE PROCEDURE LIKE 'BASECASE%';

11.3.5.2 JCL for DSNHSQL procedure A sample of the JCL for DSNHSQL which was executed against a DB2 version 5 environment is shown below. This JCL is supplied when you install the SQL Procedures support. It performs the steps described in Figure 173 on page 374. //********************************************************************** //* DSNHSQL - COMPILE AND LINKEDIT A DB2 SQL PROCEDURE //* //DSNHSQL PROC WSPC=500,MEM=TEMPNAME,USER=USER //* //* Note: The DD statements for SYSCIN in step PCC and SYSIN in step C //* currently specify temporary data sets. If you want to use //* the Debug Tool, you need to override those DD statements to //* specify the name of a permanent data set. That data set //* must have a record format of FB and logical record length of //* 80 bytes. When you execute the Debug Tool, you use that //* data set as the input.

Chapter 11. SQL Procedures — OS/390 platform 377 //* //* Example of overriding PCC.SYSCIN and C.SYSIN: //* //* //PH063S02 EXEC DSNHSQL,MEM=SQLP //* //PC.SYSIN DD DISP=SHR,DSN=APPLDEV.SQLSRC(SQLP) //* //PCC.SYSCIN DD DISP=SHR,DSN=APPLDEV.DEBUG.TOOL.INPUT(SQLP) //* //C.SYSIN DD DISP=SHR,DSN=APPLDEV.DEBUG.TOOL.INPUT(SQLP) //* //********************************************************************* //* PC: Precompile the SQL Procedure source //********************************************************************* //PC EXEC PGM=DSNHPC, // PARM='HOST(SQL)' //STEPLIB DD DISP=SHR,DSN=DSN610.SDSNEXIT // DD DISP=SHR,DSN=DSN610.SDSNLOAD //SYSPRINT DD SYSOUT=* //SYSTERM DD SYSOUT=* //SYSUDUMP DD SYSOUT=* //SYSCIN DD DSN=&&DSNHSQL,DISP=(MOD,PASS),UNIT=SYSDA, // SPACE=(800,(&WSPC,&WSPC)) //SYSLIB DD DISP=SHR,DSN=&USER..SRCLIB.DATA //SYSUT1 DD DUMMY <-- DML to register SQL SP (V5.1 only) //SYSUT2 DD DUMMY <-- DDL to register SQL SP (V6.1 and subsequent) //* //********************************************************************* //* PCC: Precompile C source generated by the previous step //********************************************************************* //PCC EXEC PGM=DSNHPC, // PARM='HOST(C),MAR(1,80)', // COND=(4,LT,PC) //STEPLIB DD DISP=SHR,DSN=DSN610.SDSNEXIT // DD DISP=SHR,DSN=DSN610.SDSNLOAD //DBRMLIB DD DISP=SHR,DSN=&USER..DBRMLIB.DATA(&MEM) //SYSPRINT DD SYSOUT=* //SYSTERM DD SYSOUT=* //SYSUDUMP DD SYSOUT=* //SYSIN DD DSN=&&DSNHSQL,DISP=(OLD,DELETE) //SYSCIN DD DSN=&&DSNHOUT,DISP=(MOD,PASS),UNIT=SYSDA, // SPACE=(800,(&WSPC,&WSPC)) //SYSLIB DD DISP=SHR,DSN=&USER..SRCLIB.DATA //SYSUT1 DD SPACE=(800,(&WSPC,&WSPC),,,ROUND),UNIT=SYSDA //SYSUT2 DD SPACE=(800,(&WSPC,&WSPC),,,ROUND),UNIT=SYSDA //* //********************************************************************* //* C: Compile the output from the precompiler //********************************************************************* //C EXEC PGM=CBCDRVR,

378 Cross-Platform DB2 Stored Procedures: Building and Debugging // PARM=('MAR(1,80) NOSEQ LO RENT'), // COND=((4,LT,PC),(4,LT,PCC)) //STEPLIB DD DISP=SHR,DSN=CBC.SCBCCMP // DD DISP=SHR,DSN=CEE.SCEERUN //SYSLIB DD DISP=SHR,DSN=CEE.SCEEH.H // DD DISP=SHR,DSN=CEE.SCEEH.SYS.H //SYSLIN DD DSN=&&LOADSET,DISP=(MOD,PASS),UNIT=SYSDA, // SPACE=(32000,(30,30)), // DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200) //SYSPRINT DD SYSOUT=* //SYSCPRT DD SYSOUT=* //SYSTERM DD DUMMY //SYSIN DD DSN=&&DSNHOUT,DISP=(OLD,DELETE) //SYSUT1 DD UNIT=SYSDA,DISP=(NEW,PASS), // SPACE=(32000,(30,30)), // DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200) //SYSUT2 DD UNIT=SYSDA,DISP=(NEW,PASS), // SPACE=(32000,(30,30)), // DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200) //SYSUT3 DD UNIT=SYSDA,DISP=(NEW,PASS), // SPACE=(32000,(30,30)), // DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200) //SYSUT4 DD UNIT=SYSDA,DISP=(NEW,PASS), // SPACE=(32000,(30,30)), // DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200) //SYSUT5 DD UNIT=SYSDA,DISP=(NEW,PASS), // SPACE=(32000,(30,30)), // DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800) //SYSUT6 DD UNIT=SYSDA,DISP=(NEW,PASS), // SPACE=(32000,(30,30)), // DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800) //SYSUT7 DD UNIT=SYSDA,DISP=(NEW,PASS), // SPACE=(32000,(30,30)), // DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800) //SYSUT8 DD UNIT=SYSDA,DISP=(NEW,PASS), // SPACE=(32000,(30,30)), // DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800) //SYSUT9 DD UNIT=SYSDA,DISP=(NEW,PASS), // SPACE=(32000,(30,30)), // DCB=(RECFM=VB,LRECL=137,BLKSIZE=882) //SYSUT10 DD SYSOUT=* //SYSUT14 DD UNIT=SYSDA,DISP=(NEW,PASS), // SPACE=(32000,(30,30)), // DCB=(RECFM=FB,LRECL=3200,BLKSIZE=12800) //* //********************************************************************* //* PLKED: Pre-linkedit the object module from the C compiler

Chapter 11. SQL Procedures — OS/390 platform 379 //********************************************************************* //PLKED EXEC PGM=EDCPRLK, // COND=((4,LT,PC),(4,LT,PCC),(4,LT,C)) //STEPLIB DD DISP=SHR,DSN=CEE.SCEERUN //SYSMSGS DD DISP=SHR,DSN=CEE.SCEEMSGP(EDCPMSGE) //SYSLIB DD DUMMY //SYSIN DD DSN=&&LOADSET,DISP=(OLD,DELETE) //SYSMOD DD DSN=&&PLKSET,UNIT=SYSDA,DISP=(MOD,PASS), // SPACE=(32000,(30,30)), // DCB=(RECFM=FB,LRECL=80,BLKSIZE=3200) //SYSOUT DD SYSOUT=* //SYSPRINT DD SYSOUT=* //* //********************************************************************* //* LKED: Linkedit the output from the pre-linkeditor //********************************************************************* //LKED EXEC PGM=IEWL, // PARM='MAP', // COND=((4,LT,PC),(4,LT,PCC),(4,LT,C),(4,LT,PLKED)) //SYSLIB DD DISP=SHR,DSN=CEE.SCEELKED // DD DISP=SHR,DSN=DSN610.SDSNLOAD //SYSLIN DD DSN=&&PLKSET,DISP=(OLD,DELETE) // DD DDNAME=SYSIN //SYSLMOD DD DISP=SHR,DSN=&USER..RUNLIB.LOAD(&MEM) //SYSPRINT DD SYSOUT=* //SYSUT1 DD SPACE=(32000,(30,30)),UNIT=SYSDA //*DSNHSQL PEND REMOVE * FOR USE AS INSTREAM PROCEDURE

Once the SQL stored procedure is created and its definition registered in DB2, you can test it by invoking it from a client application or by using the SPB Tool. Through the SPB Tool, all you need to do is to insert a connection to the OS/390 database, highlight the relevant procedure, and choose the RUN button.

Note: If your SQL stored procedure does not return any output, you must follow the checklist presented below: • Stored procedure linkage - DSNRLI should be used with WLM - DSNALI should be used for other stored procedures • Mismatching collection identifiers for caller and called procedure • In addition, for SQL procedures: - Negative sqlcode returned within an SQL procedure and no suitable error handler

380 Cross-Platform DB2 Stored Procedures: Building and Debugging - Missing null indicators in caller's parameter list check if it was linked and bound correctly.

If the procedure is created manually (not using the OS/390 Procedures Processor), the definition for your SQL stored procedure will not be inserted into the tables SYSIBM.SYSPSM or SYSIBM.SYSPSMOPTS. Therefore, the source cannot be viewed through the SPB Tool automatically.

If you wish to view the source using the SPB Tool, you need to download the SQL stored procedure source to the workstation environment, where the SPB is installed, and save it in any directory. After that, when you choose the Get Source option, you can then point to where you have saved it. See Chapter 2, “The IBM DB2 Stored Procedure Builder” on page 7 for more details on this option.

You can even choose to save all your SQL stored procedure source for your project in a shared drive. This could be important in an environment where the DB2 application developer or DB2 administrator wishes to keep track of the stored procedures for tuning or maintenance purposes through the SPB Tool.

11.4 Use of different WLM environments in SPB Since the OS/390 Procedure Processor itself is a stored procedure, it is associated with a particular WLM environment. The JCL to run this WLM environment is, therefore, set up with ddnames referencing a single set of application libraries.

The DSNTPSMP is written using REXX, and it was designed to attend customers in general. When you install the SQL Procedures support, you get the source code of the DSNTPSMP, which can be customized to a specific environment. Refer to DB2 UDB Server for OS/390 Version 6 - Technical Update, SG24-6108 for a more detailed information about setting up DSNTPSMP.

You might want the processor to be able to use more than one WLM environment, so that a different set of libraries can be referenced. You might do this if, for example, you are building SQL stored procedures for different projects, or if you want to set up different environments for test and production, or even if you just want to be able to test in a WLM environment without affecting or being affected by other people who may be testing.

Chapter 11. SQL Procedures — OS/390 platform 381 To be able to set up your environment so that DSNTPSMP can be used in more than one WLM environment, you need to define a new stored procedure based on the existing DSNTPSMP, but: • Use a different procedure name. • Use a different WLM environment.

Here is an example of defining a new OS/390 Procedure Processor called NEWTPSMP to use a WLM region called WLMENV2: CREATE PROCEDURE NEWTPSMP ( IN VARCHAR(20) CCSID EBCDIC , IN VARCHAR(27) CCSID EBCDIC , IN VARCHAR(32672) CCSID EBCDIC , IN VARCHAR(1024) CCSID EBCDIC , IN VARCHAR(255) CCSID EBCDIC , IN VARCHAR(255) CCSID EBCDIC , IN VARCHAR(255) CCSID EBCDIC , IN VARCHAR(255) CCSID EBCDIC , IN VARCHAR(254) CCSID EBCDIC , IN VARCHAR(80) CCSID EBCDIC , IN VARCHAR(8) CCSID EBCDIC , IN VARCHAR(18) CCSID EBCDIC , OUT VARCHAR(255) CCSID EBCDIC ) RESULT SET 1 EXTERNAL NAME DSNREXCS LANGUAGE REXX PARAMETER STYLE GENERAL MODIFIES SQL DATA COLLID DSNREXCS WLM ENVIRONMENT WLMENV2 ASUTIME NO LIMIT STAY RESIDENT NO PROGRAM TYPE MAIN SECURITY USER RUN OPTIONS 'TRAP(OFF),MSGFILE(SYSPRINT)' COMMIT ON RETURN NO; • Note that the other definitions should be the same as what was originally defined for DSNTPSMP. • Register the new WLM environment.For more detailed information about how to do this, refer to DB2 UDB Server for OS/390 Version 6 - Technical Update, SG24-6108. • Set up the JCL for the WLM started task JCL to reference the other set of libraries.

382 Cross-Platform DB2 Stored Procedures: Building and Debugging You can use either of the three methods described below t make the SPB recognize this new procedure name for the DSNTPSMP.

During insertion of a new SQL procedure As already described in Chapter 2, “The IBM DB2 Stored Procedure Builder” on page 7 when inserting a new stored procedure and decide to use the wizard to do this, you can enter the name of the procedure processor you want to use in field build utility as shown in Figure 174.

Figure 174. Advanced OS/390 options screen

Change WLM environment for an existing procedure You can also change the WLM environment for any existing procedure. To do so, just right click on the stored procedure for which you plan to change the WLM environment. As you can see in Figure 175, you can now choose Properties from the selection window.

Chapter 11. SQL Procedures — OS/390 platform 383 Figure 175. Change WLM environment for an existing procedure

If you choose Properties, you will see the window shown in Figure 176. Enter the name of the new WLM environment in field Build utility.If you now Rebuild this procedure, SPB will use the new WLM environment.

384 Cross-Platform DB2 Stored Procedures: Building and Debugging Figure 176. Build and Debug screen for existing procedure

Use another WLM environment as default If you want to change the name of the default WLM environment, you can select File -> Environment properties from the Stored Procedure Builder main window. The Environment Properties window appears on your screen. Select OS/390 options to get the window shown in Figure 177. Analogous to the two methods described above, you can now enter your new WLM environment name in the Build utility field. Starting from now, the default WLM environment to be used for a build of a new stored procedure is the one you just entered. Already existing procedures are not affected by this change. They will keep on using the initially used WLM environment.

Chapter 11. SQL Procedures — OS/390 platform 385 Figure 177. Change default WLM environment for SPB

When you generate and build this new SQL stored procedure using NEWTPSMP, the DBRM, load, and source modules will be placed in the data sets referenced by the ddnames in the WLM environment associated with NEWTPSMP.

If you are building your SQL stored procedure by calling the procedure processor directly, it is just a simple matter of changing the called procedure name from DSNTPSMP to NEWTPSMP.

386 Cross-Platform DB2 Stored Procedures: Building and Debugging 11.5 Dropping stored procedures considerations When you drop a stored procedure with the DROP function within the SPB, the DBRM and compiled C Source are not deleted from the PDF file. If you try to create a new stored procedure with the new name after the drop, you will receive an error message telling that the DBRM already exists: • If you then delete the DBRM, and try again to create the procedure, you are informed, that you have to delete the compiled C code. • If you drop a stored procedure, you have to delete the associated rows from the SYSPSM and SYSPSMOPTS manually.

Chapter 11. SQL Procedures — OS/390 platform 387 388 Cross-Platform DB2 Stored Procedures: Building and Debugging Chapter 12. SQL Procedures for DB2 UDB for AS/400

This chapter describes the SQL Procedures language support available for DB2 UDB for AS/400. The SQL Procedures language was introduced in V4R2.

12.1 General considerations An SQL stored procedure is created with the CREATE PROCEDURE statement that includes a procedure body written in SQL or more precisely in SQL Procedures language. There are two naming conventions that can be used in DB2 UDB for AS/400 programming: system (*SYS) and SQL (*SQL). The naming convention used affects the method for qualifying stored procedure names. For SQL naming convention, the procedure will be created in the collection or library specified by the implicit or explicit qualifier. For system naming, the procedure will be created in the collection or library specified by the qualifier. If no qualifier is specified, the procedure will be created in the current library (*CURLIB). Refer to ‘DB2 UDB for AS/400 SQL Programming’, SC41-5611 for a detailed discussion on the two naming conventions that can be used in DB2 UDB for AS/400.

Stored procedures are automatically registered in the system catalog, when the procedure is created or restored onto another system. Client applications (ODBC, JDBC, ADO based) cannot invoke stored procedures unless they are registered in the database catalogs.

The DB2 UDB for AS/400 does not provide an SQL stored procedure statement debugger, so the ILE C program debugger must be used for any debug that is needed on the stored procedure program.

12.2 System requirements and planning Before you start to develop the SQL stored procedures on the AS/400 system, make sure that you are running on V4R2 or a higher release of the OS/400 with the latest CUMPTF loaded.

When you execute the CREATE PROCEDURE statement for the SQL stored procedure, DB2 UDB for AS/400 walks through a multiphase process to create an ILE C program object (*PGM). During this process DB2 UDB for AS/400 generates an intermediary ILE C code with embedded SQL statements. This ILE C code is then precompiled, compiled, and linked automatically. This means that the SQL Development Kit for AS/400, and the

© Copyright IBM Corp. 2001 389 ILE C compiler, need to be installed on the system where you plan to develop SQL stored procedures. Once the ILE C object is created, it can be restored onto any V4R2 or higher system and run without the SQL Development Kit and ILE C compiler.

Please note that, for performance reasons, the ILE C program object is created with Activation Group parameter set to *CALLER.

12.3 System catalog tables Every CREATE PROCEDURE statement, including the registration with Operations Navigator, generates entries in the SYSROUTINES and SYSPROCS catalog tables. In this section, you see how to view the stored procedure information using the SYSROUTINES catalog, the SYSPROCS view, and the SYSPARMS view.

12.3.1 SYSROUTINES catalog All external stored procedures that are registered with the CREATE PROCEDURE statement or using Operation Navigator are stored in the SYSROUTINES catalog. Refer to DB2 UDB for AS/400 SQL Reference, SC41-5612, for the detailed description of the catalog views.

Note The SYSROUTINES catalog contains information pertaining to both stored procedures and user-defined functions (UDS). You may use the SYSPROCS catalog view to work with stored procedures. The SYSFUNCS catalog view contains the information for the UDFs.

The following SQL statement displays the content of SYSROUTINES: select * from qsys2.sysroutines ;

The result includes all information about all procedures and functions. The number of returned rows may be very large on a busy production system. You should always try to narrow the scope of your query. The following SELECT statement retrieves relevant information about the stored procedures registered in the SPROCLIB library: select specific_schema,routine_name,routine_type,routine_body,parameter_style from qsys2.sysroutines where routine_schema = 'SPROCLIB' and routine_type = 'PROCEDURE';

390 Cross-Platform DB2 Stored Procedures: Building and Debugging If you run this statement in the Run SQL Scripts utility, the query results viewer displays stored procedure details, as shown in Figure 178.

Figure 178. Stored procedures in SPROCLIB library

12.3.2 SYSPARAMS catalog The SYSPARMS catalog contains one row for each parameter of a stored procedure created by the CREATE PROCEDURE statement. Refer to DB2 UDB for AS/400 SQL Reference, SC41-5612, for detailed layout of this catalog. The SYSPARMS catalog contains parameters for both UDFs and stored procedures.

Let’s suppose you want to retrieve the parameter details for all instances of the SELPGMRES stored procedure located in the SPROCLIB library. You can run the following SQL statement to display the required information: select * from qsys2/sysparms where Specific_schema='SPROCLIB'

12.4 Creating an SQL stored procedure In this section, we document the steps required to edit and compile an SQL stored procedure (SP). On the AS/400 system there are many different ways to built your SQL stored procedure. You can use following methods: • Traditional 5250 programming using Source Entry Utility (SEU) and RUNSQLSTM utilities. This gives the best control over the compiler parameters and allows you to debug the ILE C program object. • Operations Navigator GUI • Operations Navigator SQL script utility • Stored Procedure Builder

Chapter 12. SQL Procedures for DB2 UDB for AS/400 391 12.4.1 Creating an SQL SP with traditional tools The steps required to create your SQL stored procedures with traditional 5250 tools are outlined in the following list: • Create a library if you do not have one already. • Create a source physical file; this is the file where all the SQL source members are going to be stored. • Start a Source Entry Utility (SEU) editing session. • Enter the SQL stored procedure source code. • Create the SQL stored procedure using the RUNSQLSTM command to issue a CREATE PROCEDURE command. This creates a C program object that runs when the procedure is called. If there are problems generating the procedure, there is a listing that shows the syntax errors of the source. • Invoke the stored procedure through the SQL CALL statement passing the parameter list. • Check for the completion status of the SQL stored procedure.

Let’ s see how to implement this scenario. First, create a library, a source file, and start an editing session. 1. To create a library called SQLPROCS, type the following CL command at the 5250 emulation prompt: CRTLIB LIB(SQLPROCS) 2. To create a source physical file called QSQLSRC, type the following command: CRTSRCPF FILE(SQLPROCS/QSQLSRC) RCDLEN(112) TEXT(’ Source physical file for SQL Procedures’ ) The CRTSRCPF command creates a source physical file QSQLSRC in SQLPROCS library. 3. To start an editing session and create a source member, named SDK2LMS, type the following command: STRSEU SRCFILE(ORDAPPLIB/QSQLSRC) SRCMBR(SDK2LMS) TYPE(TXT) OPTION(2) Entering OPTION(2) indicates that you want to start a session for a new member. The STRSEU command creates a new member, SDK2LMS, in the QSQLSRC file in the SQLPROCS library and starts an edit session. 4. Use SEU to enter the procedure’s source code as shown in Figure 179.

392 Cross-Platform DB2 Stored Procedures: Building and Debugging CREATE PROCEDURE SDK2LMS ( IN empnum CHAR(6) 1 INOUT rating SMALLINT ) LANGUAGE SQL - The procedure’s body begins here BEGIN DECLARE not_found CONDITION FOR '02000'; DECLARE EXIT HANDLER FOR not_found SET rating = -1; IF rating = 1 THEN UPDATE employee SET salary = salary * 1.10, bonus = 1000 WHERE empno = empnum; ELSEIF rating = 2 THEN UPDATE employee SET salary = salary * 1.05, bonus = 500 WHERE empno = empnum; ELSE UPDATE employee SET salary = salary * 1.03, bonus = 0 WHERE empno = empnum; END IF; END;

Figure 179. Entering source code

Note: 1 We intentionally omitted a comma, which should separate the parameters to produce an error listing in the next step. 5. Run the RUNSQLSTM command to create the procedure. We recommend using the Debugging view option *LIST and Listing output *PRINT. It is useful for debugging and testing purposes. Refer to section 12.8.2, “Preparing SQL stored procedure for debugging” on page 417 for more details.

Chapter 12. SQL Procedures for DB2 UDB for AS/400 393 Run SQL Statements (RUNSQLSTM)

Type choices, press Enter.

Source file ...... > QSQLSRC Name Library ...... > SQLPROCS Name, *LIBL, *CURLIB Source member ...... > SDK2LMS Name Commitment control ...... > *NONE *CHG, *ALL, *CS, *NONE... Naming ...... *SYS *SYS, *SQL

Additional Parameters

Debugging view ...... > *LIST *STMT, *LIST, *NONE Listing output ...... > *PRINT *NONE, *PRINT

Bottom F3=Exit F4=Prompt F5=Refresh F10=Additional parameters F12=Cancel F13=How to use this display F24=More keys

Figure 180. Creating the SQL stored procedure

6. If there are syntax errors in your source code, the SQL9010 ’RUNSQLSTM command failed’ message appears on your screen. To check for possible errors, you need to look at the spool file created by the precompiler. Type following CL command at the command prompt: WRKSPLF The list of your spool files appears. Find the spool file named SDK2LMS and User Data value SQL. To display the spool file contents, use option 5 as shown in Figure 181.

394 Cross-Platform DB2 Stored Procedures: Building and Debugging Work with All Spooled Files

Type options, press Enter. 1=Send 2=Change 3=Hold 4=Delete 5=Display 6=Release 7=Messages 8=Attributes 9=Work with printing status

Device or Total Cur Opt File User Queue User Data Sts Pages Page Copy 5 SDK2LMS JAREK QPRINT SQL RDY 3 1

Bottom Parameters for options 1, 2, 3 or command ===> F3=Exit F10=View 4 F11=View 2 F12=Cancel F22=Printers F24=More keys

Figure 181. Working with spool files

7. The SQL stored procedure listing appears. Scroll down and find the SQL messages section as shown in Figure 182.

Chapter 12. SQL Procedures for DB2 UDB for AS/400 395 Display Spooled File File.....: SDK2LMS Page/Line 2/17 Control..... Columns 1 - 130 Find......

*...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8....+....9.. ..+....0....+....1....+....2....+....3 13 WHERE empno = empnum; 14 ELSEIF rating = 2 15 THEN UPDATE employee 16 SET salary = salary * 1.05, bonus = 500 17 WHERE empno = empnum; 18 ELSE UPDATE employee 19 SET salary = salary * 1.03, bonus = 0 20 WHERE empno = empnum; 21 END IF; 22 END; ***** END OF SOURCE ***** RCHASM20 - V04R04M00 - 471125 5769ST1 V4R4M0 990521 Run SQL Statements SDK2LMS 09/14/99 13:52:46 Page Record *...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 SEQNBR Last change MSG ID SEV RECORD TEXT SQL0199 30 3 Position 11 Keyword INOUT not expected. Valid tokens: ) , . SQL0104 30 8 Position 20 Token HANDLER was not valid. Valid tokens: SCROLL.

More...

Figure 182. Displaying SQL precompiler error messages

8. In the preceding listing, there is a syntax error that probably generated the other ones. Correct the syntax error using the SEU utility and execute the RUNSQLSTM command again. This time the command should complete successfully.

After the procedure has been successfully created, two system catalog tables are updated: SYSROUTINES and SYSPARMS. The SYSROUTINES view contains one row for each procedure or User Defined Function. The SYSPARMS table contains one row for each parameter of a procedure or UDF.

396 Cross-Platform DB2 Stored Procedures: Building and Debugging Once the procedure has been created, it can be invoked with the SQL call statement using any interface that supports SQL (embedded SQL, ODBC, JDBC, SQLJ, CLI, and so on).

12.4.2 Creating an SQL SP with Operations Navigator GUI The Operations Navigator provides an attractive graphical interface that allows you to perform typical tasks. It allows easy access to all server administration tools, gives a clear overview of the entire database system, enables remote database management, and provides assistance for complex tasks.

In this section, you will learn how to efficiently use the GUI administration tools offered by Client Access Express to work with SQL stored procedures on the AS/400 system. We assume that you already know how to set up the Operations Navigator connection to your AS/400.

The steps below show you how to create an SQL stored procedure using the Create New SQL Procedure dialog: 1. Double click the Operations Navigator icon on your desktop. In the main panel right-click on the library, which contains your database. In our case the name of the library is SAMPLE. Select New ->Procedure-> SQL. The New SQL Procedure dialog appears. 2. Enter the following for the stored procedure name: SDK2LMS. 3. For the description, type the following: Increase salary depending on rating. 4. Click on the Parameters tab. 5. Click the Insert button. For the first parameter name, type the following: empnum. From the type drop down list, select CHARACTER. In the parameter length box, enter the number ’6’. Change the parameter style to IN/OUT. 6. Insert the second parameter as shown in Figure 183.

Chapter 12. SQL Procedures for DB2 UDB for AS/400 397 Figure 183. Parameters definition for SQL stored procedure

7. Click on SQL Statements tab. Type the procedure body as shown in Figure 184.

398 Cross-Platform DB2 Stored Procedures: Building and Debugging Figure 184. Entering SQL statements

8. Click the OK button. The stored procedure is now created.

12.4.3 Creating an SQL SP with the Run SQL Scripts utility The Run SQL Script utility is yet another interface that you can use on the AS/400 system to create a stored procedure. The script utility is available through the Operations Navigator GUI. It allows you to create, edit, run, and troubleshoot scripts of SQL statements. You can also save the scripts with which you work on your PC.

The steps below show you how to create an SQL stored procedure using the SQL Script utility. 1. Double click the Operations Navigator icon on your desktop. In the main panel right-click the Database object and select Run SQL Script. The Run SQL Scripts windows appears. 2. Type the procedure body as shown in Figure 185.

Chapter 12. SQL Procedures for DB2 UDB for AS/400 399 Figure 185. Creating SQL SP with script utility

3. To run the CREATE PROCEDURE statement, select Run->All from the Run pull down menu. If the syntax of your SQL statement is correct, the SQL stored procedure is created in the SAMPLE library on your AS/400 system. Check for the completion status in the run history panel of the Run SQL Script window. The last message displayed in this panel should read: Statement ran successfully

If the run history panel does not supply sufficient information about the execution of the SQL statements, you can view the AS/400 job log to get

400 Cross-Platform DB2 Stored Procedures: Building and Debugging additional, more specific information. From the View drop down menu, select Job Log. A job log window appears as shown in Figure 186.

Figure 186. Job log window

Note: You may not have the same messages in the job log.

To view a second level message in the job log, double click the item you wish to view. A dialog window appears with all of the information for that message.

To save the script that contains the source code for the SDK2LMS stored procedure, select File->Save As from the script utility menu bar. The Save As dialog is displayed (Figure 187). In the Save in list combo, open the directory you wish to use as your SQL script repository. In our case we use d:\sg24_5485\work_in_progress directory. Enter sdk2lms in the file name input field.

Chapter 12. SQL Procedures for DB2 UDB for AS/400 401 Figure 187. Saving SQL Script File

Click Save to return to the Run SQL Script dialog.

The Run SQL Script utility proved to be very useful when we ported the SQL stored procedures from other DB2 UDB platforms to the AS/400. All we had to do was to copy the scripts to our working directory, and change the file extension from .stp to .sql. Then we could double click a stored procedure file from the Windows Explorer window to load the script into the Run SQL Script utility.

12.4.4 Verifying the stored procedure properties Once the stored procedure has been successfully created, you can verify its properties by using the Operations Navigator interface: 1. In the main Operations Navigator window double click the SAMPLE library icon. The right-hand panel displays now all DB2 UDB for AS/400 objects in this library. 2. Find the SDK2LMS stored procedure icon and right-click it. The context menu for this object appears. Select Properties. The SDK2LMS Properties window shows up. It has three tabs: - The General page specifies the name by which the procedure is known to SQL programs and the number of result sets it should return. If you want to call an external program as a procedure, you need to define the program as a procedure before you can call it from an SQL program.

402 Cross-Platform DB2 Stored Procedures: Building and Debugging - The Parameters page specifies the parameters that the procedure uses. - The SQL Statements page contains the code for the external SQL program that you are defining as a procedure. You can use the SQL statement examples and fill in the necessary information to make coding SQL easier. After an SQL stored procedure has been created, the SQL statements cannot be changed.

The Parameters page for the SDK2LMS stored procedure is shown in Figure 188.

Figure 188. Displaying the stored procedure properties

12.5 Deleting or replacing the SQL stored procedure When you create a procedure, its signature must be unique to register the SQL stored procedure in the catalogs. The signature of a procedure can be defined as a combination of the qualified name and the number of parameters in the procedure. The CREATE PROCEDURE statement does not have a

Chapter 12. SQL Procedures for DB2 UDB for AS/400 403 replace option. For this reason, if you want to re-create or delete an existing procedure, use the DROP PROCEDURE statement. If you try to create a stored procedure that already exists in a given library, you will receive an error return code SQL0454.

For example, when we tried to re-run the CREATE PROCEDURE statement for the SDK2LMS stored procedure the following error message was displayed in the run history panel of the SQL Script utility: SQL0454 - ’Function SDK2LMS in SAMPLE with the same signature already exists’.

There are several ways to drop a stored procedure from the AS/400 system: • In the traditional "green screen" environment, start the interactive SQL session with the STRSQL command, and at the ISQL prompt, type the following SQL statement: DROP PROCEDURE library/procedure-name • In the Operations Navigator environment, in the right panel of the main Operations Navigator window, right-click the procedure you want to drop and select the Delete option. A window appears with the stored procedure object selected for deletion. Confirm that this is the procedure you want to delete, and click the Delete button, as shown in Figure 189.

Figure 189. Deleting a stored procedure

• In the Run SQL Script utility, insert the DROP PROCEDURE procedure-name statement in the workable area and then select Run->All from the menu bar.

404 Cross-Platform DB2 Stored Procedures: Building and Debugging The system catalog tables, SYSROUTINES and SYSPARMS, are updated when a DROP PROCEDURE statement is executed. In the SYSROUTINES table, a row is deleted corresponding to the information of the deleted procedure. In SYSPARMS table, the number of rows deleted depends on the number of parameters defined in the procedure.

12.5.1 Procedure overloading The DB2 UDB for AS/400 supports the concept of procedure overloading. This means that you can have two or more procedures with the same name in the same library, provided they have different signatures.

No two procedures in the library can have the same signature. Therefore, no two procedures with the same name and the same number of parameters can co-exist in the same library. For example, the following two stored procedures can co-exist in the same library: MyStorProc( char(5), int) MyStorProc( int)

However, these two stored procedures cannot exist in the same library: MyStorProc( char(5)) MyStorProc( int)

Procedure overloading is the reason why the RESTORE commands tend not to overlay existing stored procedures. In other words, if you try to restore a stored procedure to a library, where the same named procedure already exists, the system tends to register a new procedure instance rather than to overlay the existing one.

Important The stored procedure signature differs from the user-defined function (UDF) signature. The UDF signature consists of a name, number, and types of parameters. The following two UDFs can coexist in the same library: myUDF( char(5) ) myUDF ( int )

Refer to DB2 UDB for AS/400 Object Relational Support, SG24-5409, for a detailed discussion on UDFs.

Chapter 12. SQL Procedures for DB2 UDB for AS/400 405 12.5.2 Dropping overloaded procedures Dropping overloaded procedures can be tricky. Since the procedure name is overloaded, it is not sufficient to supply this name on the DROP PROCEDURE statement. There are two methods that can be used to properly resolve the overloaded name. Let’s suppose you created following the two stored procedures:

create procedure myStorproc(p1 int) language sql specific spint BEGIN IF ( P1 = 0 OR P1 = 1 ) THEN UPDATE DUMMY SET COL1 = P1 ; END IF ; END;

create procedure myStorproc(p1int,p2char) language sql specific spintchar BEGIN IF ( P1 = 0 OR P1 = 1 ) THEN UPDATE DUMMY SET COL1 = P2; END IF ; END;

To drop the second procedure, you need to use one of the methods listed here: • Specify the specific procedure name: drop specific procedure spintchar; • Include the parameter types on the DROP PRCEDURE statement: drop procedure myStorproc( int, char );

12.6 Using the Stored Procedure Builder The Stored Procedures Builder allows you to easily create, generate, and test SQL stored procedures on the AS/400 system. The SPB maybe specially useful in the heterogeneous environment, where you need to develop and deploy SQL stored procedures on different DB2 UDB platforms. In this section we discuss only topics related to the DB2 UDB for AS/400.

12.6.1 Prerequisites The SPB requires that the AS/400 database is cataloged and accessible through the DB2 Connect DRDA connection. Refer to ‘DB2 UDB for AS/400 Advanced Database Functions’, SG24-4249 for details on how to setup the AS/400 connection using the Client Configuration Assistant. We strongly recommend that you install the latest DB2 Connect Service Pak on your workstation, as well as the latest version of the DB2 UDB for AS/400 FixPak on your database server.

406 Cross-Platform DB2 Stored Procedures: Building and Debugging As mentioned earlier, the SPB is implemented in Java and uses JDBC to communicate with the database server. To be able to build the stored procedures on the AS/400 system you need to install the AS/400 Toolbox for Java JDBC driver on your workstation. It is available for download at the following Web site: http://www.ibm.com/iseries/toolbox

You also have to set the CLASSPATH variable to point to the Toolbox classes. For example, to set this variable on a Windows NT workstation start the Control Panel, select System->Environment. Update the CLASSPATH in the system variables. In our case we attached the following string to the CLASSPATH variable: d:\jt450\jt400.zip;

Notice that you may use jt400.jar rather than jt400.zip. We tested the SPB using JDK 1.1.7 for Windows NT. We set the full path of the \jdk1.1.7\bin directory attaching the following string to the PATH environment variable: d:\jdk1.1.7\bin;

12.6.2 Setting up the DB2 UDB for AS/400 project When creating a new SPB project for the AS/400 system, you need to make sure that you specify the appropriate JDBC driver and login information. Refer to Figure 190 for an example on how to set up a project for DB2 UDB for AS/400.

Chapter 12. SQL Procedures for DB2 UDB for AS/400 407 1

2

3

4

Figure 190. Creating new DB2 UDB for AS/400 project

Notes: 1. We specify the project that will be used to build the SQL SPs on the AS/400 system. 2. From the Driver pull-down menu we need to select the AS/400 Toolbox for Java option. Note that at this point the Location (URL) and the Driver class properties in the Database section are automatically updated. 3. We use the database alias that was specified for our AS/400 connection. In our case it is AS400WS. 4. We specify the user ID and password that will be used to access the DB2 UDB for AS/400 database.

Once the connection to the AS/400 system was successfully established, the SPB retrieves from the server the list of all stored procedures registered in the DB2 UDB for AS/400 catalogs. The list of the stored procedures appears in the left-hand panel of the main SPB window as shown in Figure 191.

408 Cross-Platform DB2 Stored Procedures: Building and Debugging Figure 191. Main SPB window

Note: At this point, the AS/400 SPB support is limited to the SQL stored procedures. The DB2 UDB for AS/400 Java stored procedures are greyed out similarly to other external stored procedures. The AS/400 Java stored procedures implementation is covered in detail in the IBM Redbook, DB2 UDB for AS/400 Advanced Database Function, SG24-4249.

12.6.3 Working with SQL SP on the AS/400 system Let’s suppose now that you want to quickly port an existing SQL stored procedure from the DB2 UDB for NT server. This section outlines the steps required to perform this task. 1. To insert a new database connection to the existing project right-click the project name in the left panel of the main SPB window and select Insert Connection from the pull-down menu. The Inserting Database Connection dialog appears. Here you can specify the attributes for your

Chapter 12. SQL Procedures for DB2 UDB for AS/400 409 DB2 UDB for NT connection. In our case we connect to the SAMPLE database as shown in Figure 192.

Figure 192. Inserting new database connection

Note that we select the IBM DB2 alias driver to connect to the DB2 UDB for NT. 2. After the connection to the DB2 server on NT is successfully opened, the list of the procedures in the left panel is refreshed and now you should see the stored procedures registered in DB2 UDB for NT listed along with the DB2 UDB for AS/400 procedures. In the list of DB2 UDB for NT procedures double-click the procedure you wish to port to the AS/400 system. In our case the name is SP02LNS. The source code of the procedure appears in the right panel of SPB. Copy the source code into the clipboard. 3. Right-click the Stored Procedures icon just below the AS/400 connection. From the pull-down menu select Insert->SQL Stored Procedure. A template for a new procedure appears. Paste the content of the stored procedure into the right panel as shown in Figure 192.

410 Cross-Platform DB2 Stored Procedures: Building and Debugging Figure 193. Copying an SQL SP between DB2 UDB servers

4. Usually your migrated stored procedure will require some manual changes like changing the qualified schema name. As mentioned earlier, there are also some differences in the SQL SP support on different DB2 UDB platforms. Refer to “Porting considerations” on page 430 for more details. 5. Once the required changes are entered, you may build the stored procedure on the AS/400 system by right-clicking the procedure and selecting Build from the pull-down menu. Monitor the Messages panel for the completion status. If it reads built successful you’re done! In case of errors make sure that you have all prerequisite software installed on your AS/400 development system as listed in “System requirements and planning” on page 389.

Refer to ***** Chapter The DB2 Stored Procedure Builder **** for a detailed discussion of the SPB’s functions and features.

Chapter 12. SQL Procedures for DB2 UDB for AS/400 411 12.7 Error handling In this section we discuss a methodology that allows you to adopt a consistent approach for error handling. This methodology may be useful especially in a heterogeneous environment with both SQL stored procedures and external Java stored procedures.

As mentioned earlier you can handle errors by declaring condition variables and a handler for each condition. SQL does not communicate directly with the programmers, but rather returns error codes to the application program when an error occurs in a form of SQLCODE and SQLSTATE. The SQLSTATE provides application programs with a platform independent error code.

In our methodology we use the RESIGNAL control statement to return a user-defined SQLSTATE and a user-defined error message to the calling process. This approach allows you to return the SQL exceptions that cannot be handled by the SQL stored procedure along with a meaningful description of the error condition that occurred.

The following example defines all key elements of the user-defined error handling: DECLARE EXIT HANDLER FOR SQLSTATE '75000' RESIGNAL SQLSTATE '75000' SET MESSAGE_TEXT = 'Invalid department number.'; SELECT count(*) INTO rec_cnt FROM sample.STAFF WHERE DEPT = DEPTNR; IF rec_cnt = 0 THEN SIGNAL SQLSTATE '75000' ; END IF;

In the example, we check first, whether the department number passed as an input parameter DEPTNR exists in the STAFF table. If the department number doesn’t exist we signal an exception with the user-defined SQLSTATE 75000. This in turn transfers the control to the exit handler defined for this state. The error handler resignals the SQLSTATE and additionally sets the user-defined message. On return from the stored procedure the SQL runtime sets the SQLCODE to -438.

The equivalent Java SQLException used in a Java stored procedure can be defined as shown here: if (rec_cnt == 0) throw new SQLException("Invalid department number.", "75000", -438);

Note: The user-defined SQLSTATE classes should begin with the characters '7' through '9', or 'I' through 'Z'. You may also use other classes provided the

412 Cross-Platform DB2 Stored Procedures: Building and Debugging subclass begins with the characters 'I' through 'Z'. Refer to ‘DB2 UDB for AS/400 SQL Reference’, SC41-5612 for more details.

Both the JDBC and ODBC drivers monitor the -438 SQL return code and pass the user-defined SQL state and error message to the client application.

Note Here, we refer to the Open Source version of the JDBC driver that is available for download at: http://www.as400.ibm.com/toolbox/

For the ODBC functionality, you need to make sure that you have the latest version of the Client Access Express Service Pack loaded on your workstation. We also recommend that you install the latest database FixPak on your AS/400 system.

The complete listing of our stored procedure is shown below: CREATE PROCEDURE sample.GETDEPTNAMES ( IN DEPTNR smallint ) RESULT SETS 1 LANGUAGE SQL BEGIN DECLARE rec_cnt INTEGER; DECLARE C1 CURSOR WITH RETURN FOR SELECT NAME , JOB , SALARY FROM sample.STAFF WHERE DEPT = DEPTNR ORDER BY NAME ; DECLARE EXIT HANDLER FOR SQLSTATE '75000' RESIGNAL SQLSTATE '75000' SET MESSAGE_TEXT = 'Invalid department number.' ; SELECT count(*) INTO rec_cnt FROM sample.STAFF WHERE DEPT = DEPTNR; IF rec_cnt = 0 THEN SIGNAL SQLSTATE '75000' ; END IF; OPEN C1 ; END;

The procedure returns a list of employees for a given department number or an user-defined error condition if the department number doesn’t exist.

Once the procedure was successfully registered with the database we can test its behavior with a Visual Basic client. We use ActiveX Data Objects (ADO) interface to send SQL requests to the AS/400 server job. If the department number entered as the input parameter on the client exists in the STAFF table a result set containing all members of a given department is returned to the client and displayed in the GUI window as show in Figure 194.

Chapter 12. SQL Procedures for DB2 UDB for AS/400 413 Figure 194. Visual Basic client returning a result set

However, if the department number doesn’t exist the application displays a relevant error message shown in Figure 195.

Figure 195. User-defined error condition

As discussed earlier, if the return SQLCODE is set to -438 the ODBC driver retrieves the user-defined SQLSTATE and the associated error message from the SQLCA returned by the database server. The following code snippet illustrates how to use the ADO Connection object to retrieve the database SQL errors: Function ResolveError(ErrCn As ADODB.Connection)

414 Cross-Platform DB2 Stored Procedures: Building and Debugging Dim strErrMsg As String Dim i As Integer Fori=0ToErrCn.Errors.Count - 1 strErrMsg = "Collection Element"+CStr(i) + vbCrLf strErrMsg = strErrMsg & "Error Number" & CStr(ErrCn.Errors(i).NativeError) & vbCrLf strErrMsg = strErrMsg & "Source: " & ErrCn.Errors(i).Source & vbCrLf strErrMsg = strErrMsg & ErrCn.Errors(i).Description & vbCrLf strErrMsg = strErrMsg & "SQLSTATE: " & ErrCn.Errors(i).SQLState MsgBox strErrMsg Next i End Function

Similarly, we can use the JDBC Toolbox driver to retrieve the user-defined error condition in a Java client. The following code example shows how to use the SQLException object to display the database SQL errors: catch (SQLException ex) { while (ex != null) { System.out.println("SQLState: " + ex.getSQLState()); System.out.println("Message: " +ex.getMessage()); System.out.println("Vendor code: " + ex.getErrorCode ()); ex.printStackTrace (); ex = ex.getNextException (); System.out.println (""); } }

12.8 Debugging SQL stored procedures In this section we show how to debug an SQL stored procedure on the AS/400 system. DB2 UDB for AS/400 does not provide a native SQL debugger, so the processes of eliminating run-time errors requires a certain level of programming skills in the AS/400 Integrated Language Environment (ILE). As discussed in 12.2, “System requirements and planning” on page 389, when you create an SQL stored procedure, under the covers, the system is creating an ILE C program object, which implements the procedure. The ILE C programs, in turn can be debugged with the ILE Source Debugger. We start this section with a brief description of the basic ILE Source Debugger functions.

Chapter 12. SQL Procedures for DB2 UDB for AS/400 415 12.8.1 The ILE Source Debugger The ILE source debugger is used to detect errors in and eliminate errors from program objects and service programs. By using debug commands with any ILE program, you can: • View the program source or change the debug view • Set and remove conditional and unconditional breakpoints • Step through a specified number of statements • Display or change the value of fields, structures, and arrays • Equate a shorthand name with a field, expression, or debug command

Many debug commands are available for use with the ILE source debugger. These debug commands and their parameters are entered on the debug command line displayed in the bottom of the Display Module Source display and the Evaluate Expression display. These commands can be entered in uppercase, lowercase, or mixed case.

Note: The debug commands on the debug command line are not CL commands.

The most important debug commands are briefly described in the following list: Command Description ATTR Permits you to display the attributes of a variable. The attributes are the size and type of the variable. BREAK Permits you to enter either an unconditional or conditional breakpoint at a position in the program being tested. Use BREAK line-number WHEN expression to enter a conditional breakpoint. CLEAR Permits you to remove conditional and unconditional breakpoints. DISPLAY Allows you to display the names and definitions assigned by using the EQUATE command. EQUATE Allows you to assign an expression, variable, or debug command to a name for shorthand use. EVAL Allows you to display or change the value of a variable or to display the value of expressions, records, structures, or arrays. QUAL Allows you to define the scope of variables that appear in subsequent EVAL commands.

416 Cross-Platform DB2 Stored Procedures: Building and Debugging STEP Allows you to run one or more statements of the procedure being debugged. FIND Searches forwards or backwards in the module currently displayed for a specified line number or string or text. UP Moves the displayed window of source towards the beginning of the view number of lines entered. DOWN Moves the displayed window of source towards the end of the view number of lines entered. LEFT Moves the displayed window of source to the left. RIGHT Moves the displayed window of source to the right by the number of characters entered. TOP Positions the view to show the first line. BOTTOM Positions the view to show the last line. NEXT Positions the view to the next breakpoint in the source currently displayed. PREVIOUS Positions the view to the previous breakpoint in the source displayed. HELP Shows the online help information for the available source debugger commands.

12.8.2 Preparing SQL stored procedure for debugging A program or module must have debug data available if you are to debug it. Since debug data is created during compilation, you need to specify the DBGVIEW parameter on the RUNSQLSTM command. The DBVIEW parameter specifies the type of source debug information to be provided by the SQL precompiler. The default value for this parameter is *NONE, so no debugging information is included in the program object.

To create the SQL stored procedure with the debug data follow the steps outlined below: 1. At the CL command prompt type RUNSQLSTM and press F4 for prompting. Provide the source file name, library, and source member as shown in Figure 196 for our SDK2LMS example.

Chapter 12. SQL Procedures for DB2 UDB for AS/400 417 Run SQL Statements (RUNSQLSTM)

Type choices, press Enter.

Source file ...... > QSQLSRC Name Library ...... > SQLPROCS Name, *LIBL, *CURLIB Source member ...... > SDK2LMS Name Commitment control ...... *CHG *CHG, *ALL, *CS, *NONE... Naming ...... *SYS *SYS, *SQL

Additional Parameters

Severity level ...... 10 0-40 Date format ...... *JOB *JOB, *USA, *ISO, *EUR... Date separator character . . . . *JOB *JOB, /, ., ,, -, ' ', *BLANK Time format ...... *HMS *HMS, *USA, *ISO, *EUR, *JIS Time separator character . . . . *JOB *JOB, :, ., ,, ' ', *BLANK Default collection ...... *NONE Name, *NONE IBM SQL flagging ...... *NOFLAG *NOFLAG, *FLAG ANS flagging ...... *NONE *NONE, *ANS More... F3=Exit F4=Prompt F5=Refresh F12=Cancel F13=How to use this display F24=More keys

Figure 196. RUNSQLSTM command

2. Press the Page Down key to scroll to the DBGVIEW parameter. Set the parameter value to *LIST as shown in Figure 197. We also recommend that you set the OUTPUT parameter to *PRINT. The OUTPUT parameter specifies whether the precompiler listing is generated.

Note: In our example we use the system naming convention, which gives much more naming flexibility on the AS/400 system than the SQL naming convention. In the SDK2LMS SQL source, we did not qualify the procedure name with a library name, so it is going to be created in the current library. If you want the stored procedure to be created in the SAMPLE library, make sure it is your current library at the time you run the RUNSQLSTM command. You can use the Display Library List (DSPLIBL) command to display your library list, and the Change Current Library (CHGCURLIB) command to change the current library for your AS/400 job.

418 Cross-Platform DB2 Stored Procedures: Building and Debugging Run SQL Statements (RUNSQLSTM)

Type choices, press Enter.

Decimal Point ...... *JOB *JOB, *SYSVAL, *PERIOD... Sort sequence ...... *JOB Name, *HEX, *JOB... Library ...... Name, *LIBL, *CURLIB Language id ...... *JOB *JOB, *JOBRUN... Print file ...... QSYSPRT Name Library ...... *LIBL Name, *LIBL, *CURLIB Statement processing ...... *RUN *RUN, *SYN Allow copy of data ...... *OPTIMIZE *OPTIMIZE, *YES, *NO Close SQL cursor ...... *ENDACTGRP *ENDMOD, *ENDACTGRP Allow blocking ...... *ALLREAD *ALLREAD, *NONE, *READ Delay PREPARE ...... *NO *YES, *NO Debugging view ...... > *LIST *STMT, *LIST, *NONE User profile ...... *NAMING *NAMING, *USER, *OWNER Dynamic user profile ...... *USER *USER, *OWNER Listing output ...... > *PRINT *NONE, *PRINT Target release ...... *CURRENT *CURRENT, VxRxMx Bottom F3=Exit F4=Prompt F5=Refresh F12=Cancel F13=How to use this display F24=More keys

Figure 197. Specifying the DBGVIEW and OUTPUT parameters

The possible values for the Debugging view parameter are: *STMT Allows the compiled module object to be debugged using program statement numbers and symbolic identifiers. *NONE The debug view is not be generated. *LIST Generates the listing view for debugging the compiled module object.

The possible values for the Listing output parameter are: *PRINT The precompiler listing is generated. *NONE The precompiler listing is not generated.

You must specify *STMT or *LIST if you want debugging data to be saved in the program. After the RUNSQLSTM command has successfully created the procedure, we are ready to test it.

Chapter 12. SQL Procedures for DB2 UDB for AS/400 419 12.8.3 Testing QL stored procedure in traditional environment As you have probably realized by now, the SQL control statements do not include the PRINT or DISPLAY statements. Therefore, the easiest way to test the execution of the procedure is to use ILE C source code debugging.

While debugging and testing your program, ensure that your library list is changed to direct the programs to a test library containing the test data so that any existing real data is not affected.

To start a debugging session, type the SRTDBG command at the CL prompt and press F4 for prompting. Provide the program name and the library. Make sure that you change the Update production files parameter to *YES. Even if you work with the test data the library attribute is set to PROD, and your procedure will fail miserably the first time you try to access the data. An example of the STRDBG command is shown in Figure 198.

Start Debug (STRDBG)

Type choices, press Enter.

Program ...... > SDK2LMS Name, *NONE Library ...... > SAMPLE Name, *LIBL, *CURLIB + for more values *LIBL Default program ...... *PGM Name, *PGM, *NONE Maximum trace statements . . . . 200 Number Trace full ...... *STOPTRC *STOPTRC, *WRAP Update production files . . . . > *YES *NO, *YES OPM source level debug . . . . . *NO *NO, *YES Service program ...... *NONE Name, *NONE Library ...... Name, *LIBL, *CURLIB + for more values

More... F3=Exit F4=Prompt F5=Refresh F10=Additional parameters F12=Cancel F13=How to use this display F24=More keys

Figure 198. Starting a debug session

Note: When your session is in debug mode, the job log of the session saves a lot of information related to the SQL statements being executed. The application developer can use this information for problem detection and performance tuning.

420 Cross-Platform DB2 Stored Procedures: Building and Debugging Once you have filled all the required parameters, press Enter to initialize the debug session. The ILE Source Debugger loads the ILE C source created for your SQL stored procedure. At the debug prompt, type the following command: find main and hit ENTER. This positions you at the main function as shown in Figure 199. Now you can set a breakpoint. It always a good idea to check, at the beginning of a stored procedure execution, whether the parameters were passed correctly, so set the breakpoint at line 110. You are all set now — just press F12 to return to the command line prompt.

Display Module Source

Program: SDK2LMS Library: SAMPLE Module: SDK2LMS 101 void main(int argc, char* argv[]) { 102 1 SQLP_IND = (short int*) argv[3]; 103 2 sqlcap = (SQLCA*) argv[4]; 104 3 SQLInitSQLCA((SQLCA*)&sqlca); 105 4 SDK2LMS.SQLP_I1 = *(SQLP_IND+0); 106 5 if (SDK2LMS.SQLP_I1 != SQLP_NULLIND) 107 6 strcpy(SDK2LMS.EMPNUM, argv[1]); 108 7 SDK2LMS.SQLP_I2 = *(SQLP_IND+1); 109 8 if (SDK2LMS.SQLP_I2 != SQLP_NULLIND) 110 9 SDK2LMS.RATING = * (short *) argv[2]; 111 10for(;;){ 112 SQLP_L2: 113 11 sqlca.sqlcaid[6] = 0x00; 114 12 SQLP_RC1 = 0; 115 if (SQLP_RC1 != -1 && More... Debug . . .

F3=End program F6=Add/Clear breakpoint F10=Step F11=Display variable F12=Resume F17=Watch variable F18=Work with watch F24=More keys

Figure 199. Debug session

The next step in the stored procedure testing is to actually invoke the procedure. As mentioned earlier, you cannot invoke the stored procedure from the command prompt; you need to use the SQL call.

To test the SDK2LMS stored procedure, we coded a small embedded SQL ILE C program that calls the procedure and displays the results. The source code for the INVSDK2LMS is shown in Figure 200. You can compile this program with the following CL command: CRTSQLCI OBJ(SQLPROCS/INVSDK2LMS) SRCFILE(SQLPROCS/QCSRC) OBJTYPE(*PGM) OUTPUT(*PRINT) DBGVIEW(*SOURCE)

Chapter 12. SQL Procedures for DB2 UDB for AS/400 421 #include #include #include

EXEC SQL INCLUDE SQLCA;

EXEC SQL BEGIN DECLARE SECTION; char Employee_Number??( 6 ??); short Rating; EXEC SQL END DECLARE SECTION;

void main( int argc, char **argv ) { /* copy the paremters to the host variables */ strcpy(Employee_Number, argv??(1??)); Rating = (short)*argv??( 2 ??);

/* any sql errors at the call time? */ EXEC SQL WHENEVER SQLERROR GOTO badnews;

EXEC SQL CALL SAMPLE/SDK2LMS( :Employee_Number, :Rating ); if( Rating != -1) printf("Stored Procedure ran successfully...\n"); else printf("Error in Stored Procedure.\n"); exit(0);

badnews: printf( "Error occured in invoking program. SQLCODE = %5d\n", SQLCODE); exit(1); }

Figure 200. INVDSK2LMS source code

To run the INVSDK2LMS program, call the program from the command prompt, passing two required parameters as shown below: CALL PGM(SQLPROCS/INVSDK2LMS) PARM('000010' 1)

The INVSDK2LMS program, in turn invokes the stored procedure and passes the control to it. The stored procedure hits the breakpoint, and the debugger session is activated. On the debugging line, you can enter any of the debug commands. In this way, you can display the content of any variable, check the SQL return code and so on. You can also step through the program using the F10 key.

422 Cross-Platform DB2 Stored Procedures: Building and Debugging Since your session is in debug mode, the job log has all the messages related to the execution of the procedure. We highly recommend that, while developing stored procedures, you always check the joblog messages inserted by the DB2 UDB for AS/400 optimizer.

Note: If your stored procedure is defined with only IN parameters and it does not return any results sets, you can test it very easily using the Interactive SQL. Let’s suppose you created a stored procedure called setSalary, which takes two input parameters: employee_number of type char(6) and salary of type decimal(11,2). You could test this procedure from the ISQL session by typing the following statement: CALL setSalary (’000010’, 65000.00)

12.8.4 Testing QL stored procedure in client/server environment Testing and debugging of SQL stored procedures in the client/server environment maybe a little bit more tricky than in the traditional AS/400 environment. In this section we will outline the steps required to debug an SQL stored procedure called from the Java client. The combination of Java running on the client and SQL running on a powerful database server like the AS/400 can result in a highly scalable and robust software solution.

In our test scenario, we coded a Java client, which uses the AS/400 JDBC driver, to send the SQL request to DB2 UDB for AS/400. In the AS/400 client/server architecture, a JDBC client communicates with a corresponding AS/400 server job, which runs the SQL requests on behalf of this client. In other words, when we call a stored procedure from the Java client, there is an AS/400 server job that actually invokes the stored procedure on the server and then passes back the results to the client. The AS/400 server jobs associated with the database access are named QZDASOINIT, and run in the QSERVER subsystem. At any given time, there maybe a large number of database server jobs active in the QSERVER subsystem, so the first step in our debug procedure is to find the server job, which serves our client. The Java client code we used to debug the SDK2LMS stored procedure is listed in section 12.8.4.1, “Java client calling the SP on the AS/400 server” on page 427. 1. Start the Java code in debug mode and set the breakpoint at the line just below the invocation of the getConnection method, as shown in Figure 201.

Chapter 12. SQL Procedures for DB2 UDB for AS/400 423 Figure 201. Running Java client

Note: The AS/400 server job is assigned to your client after the connection was established; that is why you need to set the breakpoint below the getConnection method invocation. 2. Switch to the AS/400 session. To find the QZDASOINIT job serving your Java client, run the following CL command: WRKOBJLCK OBJ(TEAMXX) OBJTYPE(*USRPRF) where TEAMXX is the user profile you use to log into the AS/400 system. The Work with Object Locks dialog appears. There should be one job named QZDASOINIT listed. Type 5 in the Option field next to this job, as shown in Figure 202, and hit Enter.

424 Cross-Platform DB2 Stored Procedures: Building and Debugging Work with Object Locks System: AS20 Object: TEAMXX Library: QSYS Type: *USRPRF

Type options, press Enter. 4=End job 5=Work with job 8=Work with job locks

Opt Job User Lock Status Scope Thread 5 QZDASOINIT QUSER *SHRRD HELD *JOB

Bottom F3=Exit F5=Refresh F12=Cancel

Figure 202. Finding the database server job

On the Work with Job dialog, select Option 10 ’Display job log, if active or on job queue’. The Display Job Log screen appears. Find the first message in the joblog and write down the fully qualified job name for your database server job, as shown in Figure 203.

Display Job Log System: AS20 Job . . : QZDASOINIT User . . : QUSER Number . . . : 064728

Job 064728/QUSER/QZDASOINIT started on 09/28/99 at 15:38:56 in subsystem QSERVER in QSYS. Job entered system on 09/28/99 at 15:38:56. Printer device QPRINT not found. Servicing user profile TEAMXX. Servicing user profile TEAMXX from client 10.10.10.10

Figure 203. Job log for a database server job

In our case, the fully qualified name is: 064728/QUSER/QZDASOINIT. 3. Return to the command prompt and run following CL command: STRSRVJOB JOB(064728/QUSER/QZDASOINIT )

Note: The Start Service Job (STRSRVJOB) command starts the remote service operation for a specified job so that other service commands can be entered to service the specified job. Any dump, debug, and trace commands can be run in that job until service operation ends.

Chapter 12. SQL Procedures for DB2 UDB for AS/400 425 4. Start the ILE C Source Debugger for your server job with the following CL command: STRDBG PGM(SAMPLE/SDK2LMS) UPDPROD(*YES) The ILE Source Debugger loads the ILE C source created for your SQL stored procedure. Set the breakpoint and return to the command line. 5. Switch back to the Java client session and set the breakpoint at the statement that calls the stored procedure on the AS/400 system, as shown in Figure 204.

Figure 204. Calling the stored procedure from Java

Run the statement at the breakpoint. The execution of the client code is now suspended, since the control was passed to the stored procedure on the AS/400 system. 6. Switch to the AS/400 session. The ILE C Source Debugger was activated, and you can step through your stored procedure on the server. Run the procedure to the completion. The control returns to the client, and you can continue to work with the Java code.

426 Cross-Platform DB2 Stored Procedures: Building and Debugging 12.8.4.1 Java client calling the SP on the AS/400 server The following example Java program shows you how to use the AS/400 JDBC driver to connect to the AS/400 system and call a stored procedure. It also teaches you how to bind IN and INOUT parameters to the CallableStatement class. You need to pass two arguments: employee’s number and rating, to the program, when calling it from the command line, as shown in the example below: java TestStoredProcedure 000010 1

Note: Make sure the host server is up and running on the AS/400 system and that jt400.zip is in your classpath on the client. Refer to AS/400 Toolbox for Java Setup Guide, SC41-5438 for more details. import java.io.*; import java.util.*; import java.sql.*; import com.ibm.as400.access.*; import java.math.*;

class TestStoredProcedure {

// declaration of instance vars private Connection conn; private CallableStatement callableStmt;

public String connectToDB( ) {

String dbDriver = null; String dbURL = null; String rtnValue = null; String uid = null; String pwd = null;

try { //Retrieve driver name and url from config.properties file

dbDriver = "com.ibm.as400.access.AS400JDBCDriver"; dbURL = "jdbc:as400://as20"; uid = "TEAMXX"; pwd = "TEST26T";

// Register driver try { DriverManager.registerDriver(new com.ibm.as400.access.AS400JDBCDriver());

Chapter 12. SQL Procedures for DB2 UDB for AS/400 427 } catch (Exception ex) { System.out.println("cannot register JDBC driver: " + dbDriver); ex.printStackTrace(); return "cannot register JDBC driver"; }

// Get Connection to DB, passing in properties conn = DriverManager.getConnection(dbURL, uid, pwd);

// Create a callable statement callableStmt = conn.prepareCall("CALL SAMPLE.SDK2LMS(?, ?)"); rtnValue = ("Connected To "+ dbURL); } catch (Exception e) { System.out.println("Connection Failed."); System.out.println(e); }

return (rtnValue); }

public void dispose() {

try { // close the the statement, the lastly the connection

if (null != callableStmt) { callableStmt.close(); } if (null != conn) { conn.close(); } System.exit(0); } catch (Exception e) { System.out.println("Error while closing..."); System.out.println(e); } }

public void setSalary(String empnum, short rating) { try{ // take over commitment control within getInfo method conn.setAutoCommit(false);

428 Cross-Platform DB2 Stored Procedures: Building and Debugging // set the input parameters callableStmt.setString(1, empnum); callableStmt.setShort(2, rating); //register the output parameter callableStmt.registerOutParameter(2,java.sql.Types.SMALLINT);

// execute Stored Procedure callableStmt.executeUpdate();

// retrieve the values of the output parameter short returnCode = callableStmt.getShort(2); // print out the result of the call if( returnCode != -1) System.out.println("Stored Procedure ran successfully"); else System.out.println("ERROR in Stored Procedure");

// commit and give back commitment control conn.commit(); conn.setAutoCommit(true); } catch (Exception e) { System.out.println("Error while retrieving information from " + "Database."); System.out.println(e); try { // error -> rollback and give back commitment control conn.rollback(); conn.setAutoCommit(true); } catch (Exception e2) { System.out.println("Error in rollback"); System.out.println(e2); } }

return; } /** * Starts the application. * @param args an array of command-line arguments */ public static void main(java.lang.String[] args) {

String empnum = args[0]; short rating = new Short(args[1]).shortValue();

Chapter 12. SQL Procedures for DB2 UDB for AS/400 429 String connect = null; TestStoredProcedure jsp = new TestStoredProcedure();

try { //connect to Database connect = jsp.connectToDB(); System.out.println(connect);

//Retrieve information from Database jsp.setSalary(empnum, rating);

//clean up jsp.dispose(); } catch (Exception e){ System.out.println(e); } }

12.9 Porting considerations Each DB2 UDB brand member's code version is unique and developed by different IBM laboratories. As a result there are certain functional differences among the supported platforms. These differences are due to the fact that not all new features are made available at the same time across all platforms. This difference in timing is caused by the fact that different release schedules and different customer requirements exist for each DB2 Universal Database product.

The AS/400 was the first DB2 platform which implemented the PSM standard for the SQL SP. Consequently there may be some changes required to make the DB2 UDB code executable on the AS/400 system.

12.9.1 Handler declaration In the current implementation you can’t combine the special conditions in one handler declaration. The following declaration fails: DECLARE CONTINUE HANDLER FOR SQLEXCEPTION,SQLWARNING,NOT FOUND SET v_sqlcode = SQLCODE;

430 Cross-Platform DB2 Stored Procedures: Building and Debugging Circumvention: You need to specify a separate handler for each special condition. The following code snippet shows the AS/400 equivalent: DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET v_sqlcode = SQLCODE; DECLARE CONTINUE HANDLER FOR SQLWARNING SET v_sqlcode = SQLCODE; DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_sqlcode = SQLCODE;

12.9.2 The order of DECLARE statements The DB2 UDB for AS/400 requires that the DECLARE statements appear in a SQL SP in the following order: BEGIN [ ] [ < local cursor declaration list> ] [ < local handler declaration list> ] [ < SQL statement list> ] END

Circumvention: Let’s suppose a DB2 UDB SP contains the following statements: DECLARE CONTINUE HANDLER FOR SQLEXCEPTION,SQLWARNING,NOT FOUND SET v_sqlcode = SQLCODE;

DECLARE temp_cursor CURSOR WITH HOLD WITH RETURN TO CLIENT FOR SELECT v_CorpCustAKANameNum AS CorpCustAKANameNum FROM TABLE (VALUES 1) AS temp_table;

You need to modify this code in the following way: DECLARE temp_cursor CURSOR WITH HOLD WITH RETURN FOR SELECT v_CorpCustAKANameNum AS CorpCustAKANameNum FROM dummy;

DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET v_sqlcode = SQLCODE; DECLARE CONTINUE HANDLER FOR SQLWARNING SET v_sqlcode = SQLCODE; DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_sqlcode = SQLCODE;

Chapter 12. SQL Procedures for DB2 UDB for AS/400 431 12.9.3 Nested compound statements The nested compound statements are not supported.

Circumvention: Let’s suppose a SQL SP on DB2 UDB contains the following statements: BEGIN DECLARE SQLSTATE char(5); DECLARE PrvSQLState char(5) DEFAULT ‘00000’; DECLARE ExceptState int;

DECALRE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN SET PrvSQLState = SQLSTATE; SET ExceptState = TRUE; END;

You need to modify this code in the following way: BEGIN DECLARE SQLSTATE char(5); DECLARE PrvSQLState char(5) DEFAULT ‘00000’; DECLARE ExceptState int;

DECALRE CONTINUE HANDLER FOR SQLEXCEPTION ExceptHandler: LOOP SET PrvSQLState = SQLSTATE; SET ExceptState = TRUE; LEAVE ExceptHandler; END LOOP;

432 Cross-Platform DB2 Stored Procedures: Building and Debugging Part 5. Debugging stored procedures

© Copyright IBM Corp. 2001 433 434 Cross-Platform DB2 Stored Procedures: Building and Debugging Chapter 13. Debugging stored procedures — cross-platform

This chapter discusses the debugging of stored procedures, cross-platform.

13.1 Debugging stored procedures Using IBM DB2 Stored Procedure Builder, the IBM Distributed Debugger (available separately as part of IBM VisualAge for Java), and the debugger component running on the DB2 server, you can remotely debug a stored procedure installed on a DB2 server. You are not required to debug a stored procedure from within an application program because you can run a stored procedure in debug mode within Stored Procedure Builder. Therefore, you can separate debugging your stored procedure from debugging the client application program that calls the stored procedure.

When you build a stored procedure for debugging and run it in Stored Procedure Builder, DB2 initializes the debugger component on the database server. The debugger component on the DB2 server uses the IP address and port that you set in Stored Procedure Builder to launch the IBM Distributed Debugger on your workstation (Figure 205).

Debugger DB2 Server settingssettings IBMIBM Distributed Distributed Stored Debugger Debugger procedure

IBMIBM Distributed Distributed Debugger

Figure 205. IBM Distributed Debugger — topology

The IBM Distributed Debugger reviews each programming instruction and displays the states of the variables in the executing stored procedure as it runs on the DB2 server.

© Copyright IBM Corp. 2001 435 For information about how to use the IBM Distributed Debugger, see Chapter 4, “IBM Distributed Debugger” on page 127 and the IBM VisualAge for Java documentation.

13.1.1 Setting up the SPB for debugging To set up a stored procedure in Stored Procedure Builder for debugging, you must: • Build the stored procedure in debug mode — When you create a stored procedure with a stored procedure wizard, select Enable debugging from the Options page. For existing stored procedures, you can enable debugging by selecting Build the stored procedure for debugging on the Build and Debug page of the Stored Procedure Properties notebook. • When you are building stored procedures to a workstation server, enter debug records for the stored procedure in the debug table to grant debugging authorization to particular users. These records are stored in DB2DBG.ROUTINE_DEBUG on the DB2 server. If you are a DBA or the creator of a selected stored procedure, you can authorize other users to debug the stored procedure by entering debug records for the stored procedure in the Stored Procedure Properties notebook.

You can also enable or disable debugging for several stored procedures within the same connection by right-clicking the database connection in the tree and selecting Debug Records.

13.1.1.1 Considerations Restriction — For SQL stored procedures, the RUNOPTS column of the table SYSIBM.SYSPROCEDURES (SYSIBM.SYSROUTINES) stores the port and IP address that the debugger uses to connect to your client workstation. Stored procedures built on a DB2 for OS/390 database server do not use the debug table. Therefore, only one user at a time can debug a stored procedure.

Optional — Change the global settings (port and IP address) that Stored Procedure Builder uses for the connection between the IBM Distributed Debugger and stored procedures by using the Debug page in the Environment Properties notebook. When you change these global settings, they affect stored procedures that you subsequently create. The IP address and port setting for existing stored procedures are not affected.

436 Cross-Platform DB2 Stored Procedures: Building and Debugging 13.1.2 Setting Debug properties on a workstation server The Build and Debug page in the Stored Procedure Properties notebook displays all debug records in the database for the selected stored procedure. The DB2 database uses the debug records to determine which users have authorization to debug the selected stored procedures from particular workstations and ports. You can use the Build and Debug page to add and remove debug authorizations for individual stored procedures.

13.1.2.1 Setting debug authorizations 1. Right-click a stored procedure in the tree and select Properties. The Stored Procedure Properties notebook opens. 2. Click the Build and Debug tab. The Debug options group shows the users who have authority to debug this stored procedure from the specified workstations. 3. Select the Build the stored procedure for debugging check box. A debug record appears in the table. 4. Select the On/off check box to enable a user to debug this stored procedure. When this check box is cleared for a record, that user does not have authority to debug this stored procedure. 5. Edit the Authorization ID, IP address, and Port fields by clicking each field and typing over the default entries. 6. To add a user to the list of authorized users and workstations, click Add. A row is added to the debug records. The default IP address and port are those of the client workstation where IBM DB2 Stored Procedure Builder is installed. 7. To remove a user from the list of authorized users and workstations, click the row you want to remove to select it, then click Remove. The row is removed from the debug records. 8. Click OK to save your changes and close the Stored Procedure Properties notebook. The changes that you made to the debug records are applied to the database when you rebuild the stored procedure.

13.1.3 Setting the TCP/IP address and port for the debugger Use the Debug page in the Environment Properties notebook to specify the TCP/IP address and port the debugger can use to connect to your workstation. IBM DB2 Stored Procedure Builder allows you to remotely debug stored procedures installed on a DB2 database server by using the IBM Distributed Debugger and a debugger backend.

Chapter 13. Debugging stored procedures — cross-platform 437 Note: If the IP address of your workstation changes, you must use this page to specify the new TCP/IP address and port for the debugger.

To set the TCP/IP address and port for the debugger to connect to your workstation, you should do the following: 1. Click the Debug tab in the Environment Properties notebook. 2. In the IP address field, type the IP address or host name of the workstation where you debug stored procedures. Because Stored Procedure Builder specifies the IP address of your client workstation by default, you might not have to change this field. 3. In the Port field, type the port number through which the debugger can connect to your workstation. The default port setting is 8000. 4. Click OK to apply your changes.

13.1.4 Setting debug properties on OS/390 server Note: When built for debugging, stored procedures built on DB2 for OS/390 database servers do not use the debug table. The RUNOPTS column of the table SYSIBM.SYSROUTINES stores the port and IP address that the debugger uses to connect to your client workstation. Therefore, only one user at a time can debug the stored procedure.

13.1.4.1 Setting the debug authorization: 1. In the tree, right-click a stored procedure built to an OS/390 server and select Properties. The Stored Procedure Properties notebook opens. 2. Click the Build and Debug tab. 3. Select the Build the stored procedure for debugging check box. When you build the stored procedure for debugging you can use the IBM Distributed Debugger and debugger backend to debug your stored procedure logic. 4. In the first Runtime options field, type a string (254 characters maximum) that specifies the IBM Language Environment run time options to use with stored procedures. Language Environment is an IBM product that combines run time libraries for different programming languages. If you do not specify any run time options, Language Environment uses its installation defaults. 5. In the second Runtime options field, type a string that specifies run time test options to use with stored procedures. The run time option TEST generates debugging information at run time. If NOTEST is specified, no debugging information is generated.

438 Cross-Platform DB2 Stored Procedures: Building and Debugging 6. Click OK to save your changes and close the Stored Procedure Properties Notebook.

13.1.5 Some debugging experience on OS/390 platform As describe in previous sections there are a few tasks to perform at both the DB2 server and client workstations. If you plan to debug your stored procedure, it has to be prepared with parameters that will trigger the debugging process during the execution of the stored procedure. The steps to prepare the SQL stored procedure at the DB2 server for debugging are different for DB2 UDB and DB2 for OS/390 servers.

The client workstation for debugging remote stored procedures must be executing a Windows NT environment.

The DB2 SPB is not a prerequisite for debugging your SQL stored procedures. You can debug your SQL stored procedures even if you did not create them with SPB. The SPB can help you with panels to customize the DB2 server for debugging, but the process of debugging is independent of SPB. Figure 206 shows how the debugger process is triggered for stored procedures.

Figure 206. Debugging process

SPB also avoids the need to create a client application to debug your stored procedure. You can invoke your procedure from SPB and the debugging process is triggered.

To be able to debug remote stored procedures, you must have the IBM Distributed Debugger client daemon executing on your workstation. To start the debugger client daemon, you can issue the following command: idebug -qdaemon -quiport=8000

Chapter 13. Debugging stored procedures — cross-platform 439 The above command starts the debugger client listener in TCP/IP port 8000. In your DB2 server running the procedure, you need to inform this port and the IP address of your client machine, so when the stored procedure executes on the server, the debugger is started in your workstation.

Notes: • When VisualAge for Java is not installed (in the client workstation), an error message occurs always when starting the daemon with IDEBUG -qdaemon -quiport=8000 on the Windows NT workstation. This message does not influence the way the Distributed Debugger works, but it is just disturbing during start (Figure 207).

Figure 207. Starting listener without VisualAge for Java installed

440 Cross-Platform DB2 Stored Procedures: Building and Debugging The error message only occurs with the second start of the daemon after the installation. • The EQA.DTDEBUG library must be included in WLM address space, if not, you get the message shown in Figure 208.

Figure 208. Debugger: Error message: EQ2382E

Figure 209 shows the IBM Distributed Debugger daemon window, when waiting for a remote connection.

Figure 209. IBM Distributed Debugger daemon

When your procedure starts in the DB2 server, the debugger code in the server, sends a message to the debugger client, and the IBM Distributed Debugger main window is started. Figure 210 shows the IBM Distributed Debugger main window.

Chapter 13. Debugging stored procedures — cross-platform 441 Figure 210. IBM Distributed Debugger main window

The IBM Distributed Debugger main window is divided into three main parts: one containing the source code of your stored procedure, one with monitors, and one with stacks. On the top of the window, you have controls that allow you to manage the execution of your procedure, step-by-step if you want.

In the source code part of the main window, an arrow shows the current statement being executed. Due to the fact that SQL Procedures generates a C code, during our project with the beta version of the debugger, we had to step many times to go from one SQL stored procedure statement to the following, because it was actually stepping on the C code generated. This may change when the final version is released.

You can also set breakpoints in your source code, indicated by a red dot next to the line number. To set breakpoints, all you have to do is double-click next to the line number and the breakpoint is set. You can only set breakpoints in lines that actually execute some code, so you will not be able to set breakpoints in lines with comments, for example.

In the monitor part of the main window, you can monitor and change values of variables and parameters of your stored procedure. To start monitoring the values of a variable, just click on Monitor -> Add variable to program

442 Cross-Platform DB2 Stored Procedures: Building and Debugging monitor. The Monitor Expression window appears and you can type the name of the variable you want to monitor. Figure 211 shows the Monitor Expression window.

Figure 211. Monitoring variables

Remember that during the generation of the C code your parameters are prefixed with the procedure name, and your variables declared within a compound statement are prefixed with the label of the compound statement. You must remember to type the prefixed name of the variable, or you will not be able to add the variable to the monitor. In our example, this is the name of the stored procedure, DEBUG, as typed before the name of the parameter we wanted to monitor, EMPNUM.

After you have added your variable or parameter to the monitor, you can easily change the contents of it, by simply double clicking on the name.

With the IBM Distributed Debugger graphical interface, it is very easy to understand and debug the logic of your stored procedures running in any DB2 server in your network.

13.2 Debugging stored procedures on UNIX and Windows The support for SQL Procedures implemented in DB2 UDB allows you to remotely debug stored procedures executing on the DB2 UDB server. The remote debug is already available for Java stored procedures. However, at the time of writing this redbook, remote debugging for SQL stored procedures (and C/C++) was still being developed, so we could not test this support.

In this section, we describe the steps required to remotely debug SQL stored procedures executing on a DB2 UDB server, based on the steps required for

Chapter 13. Debugging stored procedures — cross-platform 443 debugging Java stored procedures. Note that since we did not have the final version of the product, these steps may be different when the support for SQL Procedures is available.

13.2.1 Platforms supported for remote debugging Although the support for SQL Procedures is implemented in all DB2 UDB server platforms, remote debugging of SQL stored procedures is only available for DB2 UDB servers executing on Windows NT, OS/2, AIX, and Sun platforms.

The IBM Distributed Debugger client must also be executing in a Windows NT system connected to the DB2 UDB server. The IBM Distributed Debugger client is included with DB2 UDB.

13.2.2 The DB2DBG.ROUTINE_DEBUG debugger table DB2 UDB holds information about the stored procedures you want to debug in a table named DB2DBG.ROUTINE_DEBUG. You must create this table in every DB2 UDB server database that you plan to debug stored procedures.

The file db2debug.ddl contains all the DDL to create the DB2DBG.ROUTING_DEBUG table. This file is located in the \SQLLIB\MISC directory. To create the table, you must connect to the DB2 UDB server database and issue the following command: db2 -tf x:\sqllib\misc\db2debug.ddl

The current version of the db2debug.ddl file creates the DB2DBG.ROUTINE_DEBUG table, a view named DB2DBG.ROUTINE_DEBUG_USER, and two triggers on the base table. The DB2DBG.ROUTINE_DEBUG_USER view, limits the access to the table only to rows belonging to the user connected to the database. The definition for the triggers is going to change, since the current triggers are used to ensure that the stored procedure being inserted in the table is a Java stored procedure.

The DB2DBG.ROUTINE_DEBUG table must be populated using INSERT, UPDATE, and DELETE SQL statements, or using the SPB Debug Properties dialog. Every stored procedure you want to debug must contain a row in the DB2DBG.ROUTINE_DEBUG table. Following is an example of an INSERT statement to include an entry in the debug table: DB2 INSERT INTO db2dbg.routine_debug (AUTHID, TYPE, ROUTINE_SCHEMA, SPECIFICNAME, DEBUG_ON, CLIENT_IPADDR, CLIENT_PORT) VALUES ('DRDARES1', 'S', 'DRDARES1', 'S2351892', 'Y', '9.179.186.15',8000)

444 Cross-Platform DB2 Stored Procedures: Building and Debugging You must provide values for the columns of the table as follows: • AUTHID: This contains the authorization id that is associated with the debugging of the stored procedure. DB2 UDB will search the debug table using the authorization id passed in the connect statement. • TYPE: In the current version, the only value supported for this column is ’S’ for stored procedures. In future versions, when the debugging facilities become available for other DB2 objects, such as functions, other values will be valid. • ROUTINE_SCHEMA: This is the schema associated with the stored procedure that you want to debug. • SPECIFICNAME: This is the specific name of the stored procedure. If you do not know the specific name of the stored procedure you want to debug, you can check the SYSIBM.SYSPROCEDURES table to get the specific name. • DEBUG_ON: This column can contain a ’Y’ to turn debugging for the stored procedure on, or a ’N’ to turn off the debugging. • CLIENT_IPADDR: contains the IP address of the client workstation running the IBM Distributed Debugger client. When the stored procedure starts on the DB2 server, the debugger client will be started in the machine specified here. Note that this machine must be executing the IBM Distributed Debugger client daemon for receiving the debugger requests. • CLIENT_PORT: This contains the port number for the IBM Distributed Debugger client. This port number is specified when starting the debugger client in the client workstation.

There are two additional columns, DEBUG_STARTN and DEBUG_STOPN, that are not used in the current version.

13.2.3 DB2 environment variables for debugging DB2 UDB has two environment variables that are used for the debugging of stored procedures.

The DB2ROUTINE_DEBUG variable enables debugging for stored procedures in your DB2 UDB server instance. To debug your stored procedures, you must set this variable to ON, as follows: db2set DB2ROUTINE_DEBUG=ON

To turn off debugging for your DB2 instance, reset the value of the DB2ROUTINE_DEBUG variable, as follows: db2set DB2ROUTINE_DEBUG=

Chapter 13. Debugging stored procedures — cross-platform 445 The DER_DBG_PATH environment variable is used if the source code for the stored procedure resides on the client. This variable should be set at the client machine, and must provide the path where the source code resides on the client. In case of SQL stored procedures where the code resides in the DB2 tables, this variable is not used.

13.2.4 Starting the debugger client After you perform the previous steps in the DB2 UDB server, you are ready to debug your stored procedure. You must ensure that the IBM Distributed Debugger client is installed and started in the client workstation specified in the debugger table. To start the IBM Distributed Debugger client, you can use the following command: idebug.exe -qdaemon -quiport=8000 You can invoke the stored procedure from any client workstation, using a client program, SPB, or the PCALL generic client program provided with DB2. When the stored procedure starts at the DB2 server, the debugging process begins in the client workstation. For more information about the IBM Distributed Debugger client, refer to Section 13.2.5, “Debugging stored procedures through SPB” on page 446.

13.2.5 Debugging stored procedures through SPB Following is what needs to be done for debugging your stored procedure through the SPB, which provides an easy way to debug it:

On the server side: • Set the following: db2set DB2ROUTINE_DEBUG=on

On the client side: 1. Start the debugger daemon: idebug.exe -qdaemon -quiport=8000 2. Start SPB, write your stored procedure, select the stored procedure, right-click -> "Debug Properties" -> "Add" (the values for the IP address are taken from the SPB machine) -> "OK" 3. Run the stored procedure through the SPB.

The SPB will take care of creating the debugger table and inserting/deleting/updating the entries.

446 Cross-Platform DB2 Stored Procedures: Building and Debugging Part 6. Appendices

© Copyright IBM Corp. 2001 447 448 Cross-Platform DB2 Stored Procedures: Building and Debugging Appendix A. SQL procedures samples

This appendix shows examples illustrating SQL stored procedures for DB2 server. The same samples were executed against OS/390, NT, and AS/400. The sample SQL stored procedure programs illustrate the theory discussed in this redbook and are useful for getting started with the SQL Procedures language in your own environment and gaining some hands-on experience, whatever platform you have. These samples are available for downloading from the same panel describing this redbook on the ITSO Web site at: ibm.com/redbooks

See Appendix C, “Using the additional material” on page 493 for detailed information how to download the samples.

A.1 Naming convention We used the following naming convention shown in Figure 212 for these sample SQL stored procedures:

xxxxLEP Purpose: C - Client, S - SQL procedure Environment: N - Windows NT M-OS/390 4 - AS/400 Language: L - SQL Procedures language Uniquely identifies sample

Figure 212. Naming convention for samples

A.2 Windows NT stored procedures samples Following are the SQL stored procedure samples developed/tested during our project for Windows NT platform.

A.2.1 SP01LNS.SQL sample

CREATE PROCEDURE DRDARES3.SP01LNS ( IN DEPTNO CHAR(3), OUT DEPTSAL DECIMAL(15,2), OUT BONUSCNT INT ) LANGUAGE SQL

© Copyright IBM Corp. 2001 449 RESULT SET 1 ------SQL Stored Procedure ------P1: BEGIN NOT ATOMIC DECLARE EMPLOYEE_NUMBER CHAR(6); DECLARE EMPLOYEE_FIRSTNME CHAR(12); DECLARE EMPLOYEE_LASTNAME CHAR(15); DECLARE EMPLOYEE_SALARY DECIMAL(15,2) DEFAULT 0; DECLARE EMPLOYEE_BONUS DECIMAL(15,2) DEFAULT 0; DECLARE TOTAL_SALARY DECIMAL(15,2) DEFAULT 0; DECLARE BONUS_COUNTER INT DEFAULT 0; DECLARE ENDTABLE INT DEFAULT 0;

-- Cursor for result set of employees who got a bonus DECLARE DSN8ES1_RS_CSR CURSOR WITH HOLD WITH RETURN FOR SELECT SEQUENCE, EMPNO, FIRSTNME, LASTNAME, BONUS FROM RS_TBL ORDER BY SEQUENCE; -- Cursor to fetch department employees DECLARE C1 CURSOR FOR SELECT EMPNO, FIRSTNME, LASTNAME, SALARY, BONUS FROM EMPLOYEE WHERE WORKDEPT = DEPTNO; DECLARE CONTINUE HANDLER FOR NOT FOUND SET ENDTABLE = 1; DECLARE EXIT HANDLER FOR SQLEXCEPTION SET DEPTSAL = NULL; -- Clean residual from the result set table DELETE FROM RS_TBL where 1=1; OPEN C1; FETCH C1 INTO EMPLOYEE_NUMBER, EMPLOYEE_FIRSTNME, EMPLOYEE_LASTNAME, EMPLOYEE_SALARY, EMPLOYEE_BONUS; WHILE ENDTABLE = 0 DO SET TOTAL_SALARY = TOTAL_SALARY + EMPLOYEE_SALARY + EMPLOYEE_BONUS; IF EMPLOYEE_BONUS > 0.00 THEN SET BONUS_COUNTER = BONUS_COUNTER + 1; -- Add the employee’s data to the result set INSERT INTO RS_TBL ( SEQUENCE, EMPNO, FIRSTNME, LASTNAME, SALARY, BONUS ) VALUES( P1.BONUS_COUNTER, P1.EMPLOYEE_NUMBER, P1.EMPLOYEE_FIRSTNME, P1.EMPLOYEE_LASTNAME,

450 Cross-Platform DB2 Stored Procedures: Building and Debugging P1.EMPLOYEE_SALARY, P1.EMPLOYEE_BONUS ); END IF; FETCH C1 INTO EMPLOYEE_NUMBER, EMPLOYEE_FIRSTNME, EMPLOYEE_LASTNAME, EMPLOYEE_SALARY, EMPLOYEE_BONUS; END WHILE; CLOSE C1; SET DEPTSAL = TOTAL_SALARY; SET BONUSCNT = BONUS_COUNTER; -- Open the cursor to the result set OPEN DSN8ES1_RS_CSR; END P1

A.2.2 SP02LNS.SQL sample

CREATE PROCEDURE DRDARES3.SP02LNS (IN MEDSAL DOUBLE, OUT AVGSAL DOUBLE) LANGUAGE SQL RESULT SETS 2 ------SQL Stored Procedure ------BEGIN --DECLARE AVGSAL DOUBLE; -- USE WITH RETURN IN DECLARE CURSOR TO RETURN A RESULT SET DECLARE C2 CURSOR WITH RETURN FOR SELECT NAME, JOB, INTEGER(SALARY) FROM STAFF WHERE SALARY > MEDSAL ORDER BY SALARY; -- YOU CAN RETURN AS MANY RESULT SETS AS YOU LIKE, JUST -- ENSURE THAT THE EXACT NUMBER IS DECLARED IN THE RESULT SETS -- CLAUSE OF THE CREATE PROCEDURE STATEMENT -- USE WITH RETURN IN DECLARE CURSOR TO RETURN ANOTHER RESULT SET DECLARE C3 CURSOR WITH RETURN FOR SELECT NAME, JOB, INTEGER(SALARY) FROM STAFF WHERE SALARY < MEDSAL ORDER BY SALARY DESC; -- SELECT AVG(SALARY) INTO AVGSAL FROM STAFF; -- RETURN 1ST RESULT SET, DO NOT CLOSE CURSOR OPEN C2; -- RETURN 2ND RESULT SET, DO NOT CLOSE CURSOR OPEN C3; END

A.2.3 SP03LNS.SQL sample

CREATE PROCEDURE DRDARES3.SP03LNS ( out maxnonew char(6), out rc char(2) ) LANGUAGE SQL ------SQL Stored Procedure ------BEGIN declare maxno char(6); insert into result(proc,res) values ('CALLER', 'begin'); CALL SP05LNS(MAXNO); if maxno is null then

Appendix A. SQL procedures samples 451 set rc = 'KO'; else set rc = 'OK'; set maxnonew = maxno; end if; insert into result(proc,res) values ('SP03LMS', 'end'); END

A.2.4 SP04LNS.SQL sample

CREATE PROCEDURE DRDARES3.SP04LNS ( ) LANGUAGE SQL ------SQL Stored Procedure ------begin declare a int; declare SQLSTATE char(5) default '00000';

DECLARE CONTINUE HANDLER FOR NOT FOUND insert into result(proc,res) values ('exec of DDL', 'CONTINUE handler fired. SQLSTATE=' || SQLSTATE);

DECLARE CONTINUE HANDLER FOR SQLEXCEPTION insert into result(proc,res) values ('marian0', 'CONTINUE handler fired. SQLSTATE=' || SQLSTATE);

DECLARE CONTINUE HANDLER FOR SQLWARNING insert into result(proc,res) values ('exec of DDL', 'CONTINUE handler fired. SQLSTATE=' || SQLSTATE);

insert into result(proc,res,dt) values('exec DDL', ' Start', current timestamp); IF (a is null) THEN create table DDLTEST(c1 int); create table t4(c1 int, c2 int, c3 int); create index i1 on t4(c1); comment on table t4 is 'PSM is great'; grant all on t4 to public; grant all on DDLTEST to public; create view v1 as select * from t4; grant update on v1 to newton; END IF; declare global temporary table t3 like t4 with replace not logged; declare global temporary table t31 like t4 not logged; drop table t4; drop table DDLTEST; drop view v1;

insert into result(proc,res,dt) values('exec DDL', 'End', current timestamp);

END

A.2.5 SP05LNS.SQL sample

CREATE PROCEDURE DRDARES3.SP05LNS ( OUT MAXNO CHAR(6) ) LANGUAGE SQL ------SQL Stored Procedure ------BEGIN

452 Cross-Platform DB2 Stored Procedures: Building and Debugging -- CONNECT TO SAMPLE; -- CONNECT TO SAMPLE USER drdares3 USING drdares3; SELECT MAX(EMPNO) INTO MAXNO FROM EMPLOYEE; END

A.2.6 SP06LNS.SQL sample

CREATE PROCEDURE DRDARES3.SP06LNS (OUT CODE INT ) LANGUAGE SQL ------SQL Stored Procedure ------P1: BEGIN DECLARE STMT VARCHAR(200); DECLARE SQLCODE INT DEFAULT 0; DECLARE EXIT HANDLER FOR SQLEXCEPTION SET CODE = SQLCODE; GRANT select on table sysibm.systables to anyone; SET STMT = 'GRANT select on table sysibm.systables to someone' ; execute immediate stmt; SET CODE = SQLCODE; END P1

A.2.7 SP07LNS.SQL sample

CREATE PROCEDURE DRDARES3.SP07LNS ( OUT CODE INT ) LANGUAGE SQL ------SQL Stored Procedure ------P1: BEGIN DECLARE STMT VARCHAR(200); declare stmt2 varchar(200); declare stmt3 varchar(200); declare stmt4 varchar(200); DECLARE SQLCODE INT DEFAULT 0; DECLARE EXIT HANDLER FOR SQLEXCEPTION SET CODE = SQLCODE; GRANT select on table sysibm.systables to sabi5; SET STMT = 'GRANT select on table sysibm.systables to sabi6' ; prepare s1 from stmt; execute s1; savepoint a on rollback retain cursors; SET STMT2 = 'GRANT select on table sysibm.systables to sabi7' ; prepare s2 from stmt2; execute s2; SET STMT3 = 'GRANT select on table sysibm.systables to sabi9' ; prepare s3 from stmt3; execute s3; SET STMT4 = 'GRANT select on table sysibm.systables to sabi10' ; prepare s4 from stmt4; execute s4; rollback to savepoint a; SET CODE = SQLCODE; END P1

Appendix A. SQL procedures samples 453 A.2.8 SP08LNS.SQL sample

CREATE PROCEDURE DRDARES3.SP08LNS (out v1 double,out v2 double, out v3 integer, out v5 decimal(10), out v7 varchar (27), out v8 integer,out v9 integer, out v10 integer, out v12 char(8), out v13 char(3), out v14 integer, out v15 integer, out v16 integer, out v17 char(12), out v18 integer) LANGUAGE SQL ------SQL Stored Procedure ------P1: BEGIN SELECT STDDEV(SALARY),VAR(SALARY) INTO v1,v2 FROM STAFF; SET v3 = ABS(-4356); SELECT CEIL(MAX(SALARY)/12) INTO v5 FROM EMPLOYEE; SELECT CONCAT(FIRSTNME,LASTNAME) INTO v7 FROM EMPLOYEE WHERE EMPNO = '000140'; SELECT DAYOFWEEK(HIREDATE) INTO v8 FROM EMPLOYEE WHERE EMPNO = '000140'; SELECT AVG(DAYOFYEAR(HIREDATE)) INTO v9 FROM EMPLOYEE; SELECT FLOOR(MAX(SALARY)/12) INTO v10 FROM EMPLOYEE; SET v12 = LCASE('KATHLEEN'); SET v13 = LEFT('JONATHAN',3); SELECT MIDNIGHT_SECONDS('24:00:00'),MIDNIGHT_SECONDS('00:00:00') INTO v14,v15 FROM SYSIBM.SYSTABLES WHERE NAME='EMPLOYEE'; SET v16 = QUARTER('1999-09-09'); SET v17 = REPEAT('KATH',3); SET v18 = SIGN(-1000); END P1

A.2.9 SP09LNS.SQL sample

CREATE PROCEDURE DRDARES3.SP09LNS ( tt CHAR(3) ) LANGUAGE SQL ------SQL Stored Procedure ------BEGIN NOT ATOMIC declare a integer default 0; insert into result(proc,res) values ('exec of I2','Start.'); -- This is a sample of a searched CASE statement. -- Only searched CASE statements allow more then three levels. CASE WHEN tt='AAA' THEN insert into result(proc,res) values ('exec of I2','AAA found.'); CASE WHEN tt='AAA' THEN insert into result(proc,res) values ('exec of I2','AAA found in 2nd case.'); CASE WHEN tt='BBB' THEN insert into result(proc,res) values ('exec of I2','BBB found in 2nd case.');

ELSE insert into result(proc,res) values ('exec of I2', 'default case value=[' || CHAR(tt) || '] in 2nd case');

454 Cross-Platform DB2 Stored Procedures: Building and Debugging END CASE ; END CASE;

WHEN tt='BBB' THEN insert into result(proc,res) values ('exec of I2','BBB found.'); WHEN tt='CCC' THEN insert into result(proc,res) values ('exec of I2','CCC found.'); ELSE insert into result(proc,res) values ('exec of I2','default case value=[' || CHAR(tt) || ']'); END CASE; insert into result(proc,res) values ('exec of I2','End.'); END

A.2.10 SP10LNS.SQL sample

CREATE PROCEDURE DRDARES3.SP10LNS (OUT SHOWGRANTEE CHAR(8) , OUT SHOWGRANTOR CHAR(8) , OUT SHOWGRANTEE1 CHAR(8), OUT SHOWGRANTOR1 CHAR(8), OUT CODE1 INT, OUT CODE2 INT, OUT CODE3 INT, OUT HANDLERCODE INT) LANGUAGE SQL ------SQL Stored Procedure ------P1: BEGIN DECLARE STMT VARCHAR(200); DECLARE SQLCODE INT DEFAULT 0; DECLARE EXIT HANDLER FOR SQLWARNING SET HANDLERCODE = SQLCODE; GRANT select on table sysibm.systables to anyone; SET CODE1=SQLCODE; GRANT select on table sysibm.systables to anyone; SET CODE2=SQLCODE; SELECT GRANTEE, GRANTOR INTO SHOWGRANTEE, SHOWGRANTOR FROM SYSIBM.SYSTABAUTH WHERE TTNAME = 'SYSTABLES' AND GRANTEE = 'ANYONE'; SET CODE3=SQLCODE; -- REVOKE SELECT ON TABLE sysibm.systables FROM anyone; SELECT GRANTEE, GRANTOR INTO SHOWGRANTEE1, SHOWGRANTOR1 FROM SYSIBM.SYSTABAUTH WHERE TTNAME = 'SYSTABLES' AND GRANTEE = 'ANYONE'; END P1

A.2.11 SP11LNS.SQL sample

CREATE PROCEDURE DRDARES3.SP11LNS (out rowcount int) LANGUAGE SQL ------SQL Stored Procedure ------P1: BEGIN

update employee set salary=salary+1 where salary <80000; get diagnostics rowcount = row_count;

Appendix A. SQL procedures samples 455 END P1

A.2.12 SP12LNS.SQL sample

CREATE PROCEDURE DRDARES3.SP12LNS (inout service decimal(8,2) , in v_empno char(6), in rating int, out return_parm decimal(8,2)) LANGUAGE SQL ------SQL Stored Procedure ------begin declare new_salary decimal(9,2); select salary, current date - hiredate into new_salary, service from employee where empno = v_empno ; if service < 600 then goto exit_RTN; end if; if rating = 1 then set new_salary = new_salary*1.1; elseif rating = 2 then set new_salary = new_salary*1.05; end if; update employee set salary = new_salary where empno = v_empno; exit_RTN: set return_parm = service; End

A.2.13 SP13LNS.SQL sample

CREATE PROCEDURE DRDARES3.SP13LNS (IN empnum CHAR(6), INout rating smallint) LANGUAGE SQL ------SQL Stored Procedure ------BEGIN DECLARE not_found CONDITION FOR SQLSTATE '02000'; DECLARE EXIT HANDLER FOR not_found SET rating = -1; IF rating = 1 THEN UPDATE employee SET salary = salary * 1.10, bonus = 1000 WHERE empno = empnum; ELSEIF rating = 2 THEN UPDATE employee SET salary = salary * 1.05, bonus = 500 WHERE empno = empnum; ELSE UPDATE employee SET salary = salary * 1.03, bonus = 0 WHERE empno = empnum; END IF; END

456 Cross-Platform DB2 Stored Procedures: Building and Debugging A.2.14 SP14LNS.SQL sample

CREATE PROCEDURE DRDARES3.SP14LNS ( out code int) LANGUAGE SQL ------SQL Stored Procedure ------BEGIN DECLARE v_dept CHAR(3); DECLARE v_deptname VARCHAR(29); DECLARE v_admdept CHAR(3); DECLARE at_end INT DEFAULT 0; declare SQLCODE int default 0; DECLARE not_found CONDITION FOR SQLSTATE '02000'; DECLARE c1 CURSOR FOR SELECT deptno, deptname, admrdept FROM department ORDER BY deptno; DECLARE CONTINUE HANDLER FOR not_found SET at_end = 1; declare continue handler for sqlexception set code = sqlcode; OPEN c1; ins_loop: LOOP FETCH c1 INTO v_dept, v_deptname, v_admdept; IF at_end = 1 THEN LEAVE ins_loop; END IF; INSERT INTO department (deptno, deptname, admrdept) VALUES ('NEW', v_deptname, v_admdept); END LOOP; CLOSE c1; END

A.2.15 SP15LNS.SQL sample

CREATE PROCEDURE DRDARES3.SP15LNS (inOUT counter INT ) LANGUAGE SQL ------SQL Stored Procedure ------BEGIN DECLARE v_firstnme VARCHAR(12); DECLARE v_midinit CHAR(1); DECLARE v_lastname VARCHAR(15); DECLARE at_end SMALLINT DEFAULT 0; DECLARE not_found CONDITION FOR SQLSTATE '02000'; DECLARE c1 CURSOR FOR SELECT firstnme, midinit, lastname FROM employee; DECLARE CONTINUE HANDLER FOR not_found SET at_end = 1; -- initialize OUT parameter SET counter = 0; OPEN c1; fetch_loop: REPEAT FETCH c1 INTO v_firstnme, v_midinit, v_lastname; SET counter = counter + 1;

Appendix A. SQL procedures samples 457 UNTIL at_end <> 0 END REPEAT fetch_loop; SET counter = counter - 1; -- count is 1 more than actual for repeat CLOSE c1; END

A.2.16 SP16LNS.SQL sample

CREATE PROCEDURE DRDARES3.SP16LNS (IN deptnum char(3) ) LANGUAGE SQL ------SQL Stored Procedure ------BEGIN DECLARE v_salary decimal(9,2); DECLARE v_id char(6); DECLARE at_end INT DEFAULT 0; DECLARE not_found CONDITION FOR SQLSTATE '02000'; -- CAST salary as DOUBLE because SQL procedures do not support -- DECIMAl DECLARE C1 CURSOR FOR SELECT empno, FLOAT(salary) FROM employee WHERE workdept = deptnum; DECLARE CONTINUE HANDLER FOR not_found SET at_end = 1; OPEN C1; FETCH C1 INTO v_id, v_salary; WHILE at_end = 0 DO IF (v_salary < 2000) THEN UPDATE employee SET salary = salary*1.08 WHERE empno = v_id; ELSEIF (v_salary < 5000) THEN IF (v_salary < 3000) THEN UPDATE employee SET salary = 3000 * 1.7 WHERE empno = v_id; ELSE UPDATE employee SET salary = v_salary * 1.5 WHERE empno = v_id; END IF; ELSE UPDATE employee SET job = 'PREZ' WHERE empno = v_id; END IF; FETCH C1 INTO v_id, v_salary; END WHILE; CLOSE C1; END

A.2.17 SP17LNS.SQL sample

CREATE PROCEDURE DRDARES3.SP17LNS (out pid char(6)) LANGUAGE SQL ------SQL Stored Procedure ------P1: BEGIN declare empno char(6);

458 Cross-Platform DB2 Stored Procedures: Building and Debugging set empno = '000010'; select employee.empno into empno from employee where employee.empno=p1.empno; set pid = empno; END P1

A.2.18 CALLEE sample for NT

CREATE PROCEDURE CALLEE (IN parm1 SMALLINT, IN parm2 int, IN parm3 DECIMAL(10,2), IN parm4 real, IN parm5 double, IN parm6 bigint, IN parm7 char(10), IN parm8 varchar(10), IN parm9 date, IN parm10 time, IN parm11 timestamp, OUT out1 SMALLINT, OUT out2 int, OUT out3 DECIMAL(10,2), OUT out4 real, OUT out5 double, OUT out6 bigint, OUT out7 char(15), OUT out8 varchar(15), OUT out9 date, OUT out10 time, OUT out11 timestamp) SPECIFIC CALLEE LANGUAGE SQL BEGIN DECLARE SQLSTATE char(5) default '00000'; DECLARE SQLCODE integer default 0; DECLARE RESULT_SET_END INTEGER default 0; DECLARE CONTINUE HANDLER FOR NOT FOUND, SQLEXCEPTION, SQLWARNING BEGIN insert into result(proc,res) values ('exec CALLEE','Handler fired SQLSTATE='||SQLSTATE||' SQLCODE='||CHAR(SQLCODE)); SET RESULT_SET_END = 1; END;

insert into result(proc,res) values ( 'PARM1', CHAR(parm1)); insert into result(proc,res) values ( 'PARM2', CHAR(parm2)); insert into result(proc,res) values ( 'PARM3', CHAR(parm3)); insert into result(proc,res) values ( 'PARM4', CHAR(parm4)); insert into result(proc,res) values ( 'PARM5', CHAR(parm5)); insert into result(proc,res) values ( 'PARM6', CHAR(parm6)); insert into result(proc,res) values ( 'PARM7', CHAR(parm7)); insert into result(proc,res) values ( 'PARM8', CHAR(parm8)); insert into result(proc,res) values ( 'PARM9', CHAR(parm9)); insert into result(proc,res) values ( 'PARM10', CHAR(parm10)); insert into result(proc,res) values ( 'PARM11', CHAR(parm11));

set out1 = parm1 + 1; set out2 = parm2 + 1; set out3 = parm3 + 1; set out4 = parm4 + 1; set out5 = parm5 + 1; set out6 = parm6 + 1; set out7 = parm7 || 'G'; set out8 = parm8 || 'G'; set out9 = parm9 + 1 day; set out10 = parm10 + 1 minute; set out11 = parm11 + 1 year;

if(1 = 0)then -- This is just to be able to parse the next statements declare global temporary table ttt(c1 SMALLINT, c2 int, c3 DECIMAL(10,2), c4 real, c5 double, c6 bigint, c7 char(18), c8 varchar(18), c9 date, c10 time, c11 timestamp) not logged; end if;

Appendix A. SQL procedures samples 459 insert into session.ttt values (parm1 + 3, parm2 + 3, parm3 + 3, parm4 + 3, parm5 + 3, parm6 + 3, parm7 || 'E', parm8 || 'E', parm9 + 3 days, parm10 + 3 minutes, parm11 + 3 years);

insert into session.ttt values (parm1 + 2, parm2 + 2, parm3 + 2, parm4 + 2, parm5 + 2, parm6 + 2, parm7 || 'F', parm8 || 'F', parm9 + 2 days, parm10 + 2 minutes, parm11 + 2 years);

BEGIN DECLARE cur1 CURSOR WITH RETURN TO CALLER FOR Select * from session.ttt; OPEN cur1 ; END; insert into result(proc,res) values ( 'exec CALLEE','End of proc with cursor cur1 opened.'); END

A.2.19 CF025 sample for NT

CREATE PROCEDURE CF025() SPECIFIC CF025 LANGUAGE SQL BEGIN DECLARE SQLSTATE char(5) default '00000'; DECLARE SQLCODE integer default 0; DECLARE LOC1 RESULT_SET_LOCATOR VARYING; DECLARE RESULT_SET_END integer default 0;

DECLARE temp1 SMALLINT DEFAULT 0; DECLARE temp2 INTEGER DEFAULT 10; DECLARE temp3 DECIMAL(10,2) DEFAULT 100.10; DECLARE temp4 REAL DEFAULT 10.1; DECLARE temp5 DOUBLE DEFAULT 10000.1000; DECLARE temp6 BIGINT DEFAULT 10000; DECLARE temp7 CHAR(10) DEFAULT 'yes'; DECLARE temp8 VARCHAR(10) DEFAULT 'hello'; DECLARE temp9 DATE DEFAULT '1998-12-25'; DECLARE temp10 TIME DEFAULT '1:50 PM'; DECLARE temp11 TIMESTAMP DEFAULT '2001-01-05-12.00.00';

DECLARE out1 SMALLINT; DECLARE out2 INTEGER; DECLARE out3 DECIMAL(10,2); DECLARE out4 REAL; DECLARE out5 DOUBLE; DECLARE out6 BIGINT; DECLARE out7 CHAR(15); DECLARE out8 VARCHAR(15); DECLARE out9 DATE; DECLARE out10 TIME; DECLARE out11 TIMESTAMP;

DECLARE CONTINUE HANDLER FOR NOT FOUND, SQLEXCEPTION, SQLWARNING BEGIN END;

-- Create result table -- CREATE TABLE RESULT(PROC CHAR(30), RES VARCHAR(200));

BEGIN DECLARE CONTINUE HANDLER FOR NOT FOUND, SQLEXCEPTION, SQLWARNING BEGIN insert into result(proc,res) values ('exec from CF025','Handler fired SQLSTATE=' || SQLSTATE || ' SQLCODE=' || CHAR(SQLCODE));

460 Cross-Platform DB2 Stored Procedures: Building and Debugging SET RESULT_SET_END = 1; END;

insert into result(proc,res) values ( 'exec CF025','Start');

declare global temporary table ttt(c1 SMALLINT, c2 int, c3 DECIMAL(10,2), c4 real, c5 double, c6 bigint, c7 char(18), c8 varchar(18), c9 date, c10 time, c11 timestamp) not logged;

insert into session.ttt values (temp1 + 1, temp2 + 1, temp3 + 1, temp4 + 1, temp5 + 1, temp6 + 1, temp7 || 'G', temp8 || 'G', temp9 + 1 day, temp10 + 1 minute, temp11 + 1 year);

insert into session.ttt values (temp1 + 2, temp2 + 2, temp3 + 2, temp4 + 2, temp5 + 2, temp6 + 2, temp7 || 'F', temp8 || 'F', temp9 + 2 days, temp10 + 2 minutes, temp11 + 2 years);

set out1 = temp1 + 1; set out2 = temp2 + 1; set out3 = temp3 + 1; set out4 = temp4 + 1; set out5 = temp5 + 1; set out6 = temp6 + 1; set out7 = temp7 || 'G'; set out8 = temp8 || 'G'; set out9 = temp9 + 1 day; set out10 = temp10 + 1 minute; set out11 = temp11 + 1 year;

insert into result(proc,res) values ( 'OUT1', CHAR(out1)); insert into result(proc,res) values ( 'OUT2', CHAR(out2)); insert into result(proc,res) values ( 'OUT3', CHAR(out3)); insert into result(proc,res) values ( 'OUT4', CHAR(out4)); insert into result(proc,res) values ( 'OUT5', CHAR(out5)); insert into result(proc,res) values ( 'OUT6', CHAR(out6)); insert into result(proc,res) values ( 'OUT7', CHAR(out7)); insert into result(proc,res) values ( 'OUT8', CHAR(out8)); insert into result(proc,res) values ( 'OUT9', CHAR(out9)); insert into result(proc,res) values ( 'OUT10', CHAR(out10)); insert into result(proc,res) values ( 'OUT11', CHAR(out11));

CALL CALLEE(temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8, temp9, temp10, temp11, out1, out2, out3, out4, out5, out6, out7, out8, out9, out10, out11);

insert into result(proc,res) values ( 'OUT1', CHAR(out1)); insert into result(proc,res) values ( 'OUT2', CHAR(out2)); insert into result(proc,res) values ( 'OUT3', CHAR(out3)); insert into result(proc,res) values ( 'OUT4', CHAR(out4)); insert into result(proc,res) values ( 'OUT5', CHAR(out5)); insert into result(proc,res) values ( 'OUT6', CHAR(out6)); insert into result(proc,res) values ( 'OUT7', CHAR(out7)); insert into result(proc,res) values ( 'OUT8', CHAR(out8)); insert into result(proc,res) values ( 'OUT9', CHAR(out9)); insert into result(proc,res) values ( 'OUT10', CHAR(out10)); insert into result(proc,res) values ( 'OUT11', CHAR(out11));

ASSOCIATE RESULT SET LOCATOR( LOC1) WITH PROCEDURE CALLEE; insert into result(proc,res) values ( 'exec CF025','AFTER ASSOC'); ALLOCATE C1 CURSOR FOR RESULT SET LOC1; insert into result(proc,res) values ( 'exec CF025','AFTER ALLOC');

Appendix A. SQL procedures samples 461 insert into session.ttt values (temp1 + 3, temp2 + 3, temp3 + 3, temp4 + 3, temp5 + 3, temp6 + 3, temp7 || 'E', temp8 || 'E', temp9 + 3 days, temp10 + 3 minutes, temp11 + 3 years);

insert into session.ttt values (temp1 + 2, temp2 + 2, temp3 + 2, temp4 + 2, temp5 + 2, temp6 + 2, temp7 || 'F', temp8 || 'F', temp9 + 2 days, temp10 + 2 minutes, temp11 + 2 years);

insert into result(proc,res) values ( 'exec CF025','Before processing result set'); SET RESULT_SET_END = 0; WHILE(RESULT_SET_END = 0) DO insert into result(proc,res) values ( 'exec CF025','INSIDE THE LOOP'); FETCH FROM C1 INTO out1, out2, out3, out4, out5, out6, out7, out8, out9, out10, out11; insert into result(proc,res) values ( 'TEMP1', CHAR(out1)); insert into result(proc,res) values ( 'TEMP2', CHAR(out2)); insert into result(proc,res) values ( 'TEMP3', CHAR(out3)); insert into result(proc,res) values ( 'TEMP4', CHAR(out4)); insert into result(proc,res) values ( 'TEMP5', CHAR(out5)); insert into result(proc,res) values ( 'TEMP6', CHAR(out6)); insert into result(proc,res) values ( 'TEMP7', CHAR(out7)); insert into result(proc,res) values ( 'TEMP8', CHAR(out8)); insert into result(proc,res) values ( 'TEMP9', CHAR(out9)); insert into result(proc,res) values ( 'TEMP10', CHAR(out10)); insert into result(proc,res) values ( 'TEMP11', CHAR(out11)); END WHILE; CLOSE C1; insert into result(proc,res) values ( 'exec CF025','End'); END; END

A.3 OS/390 stored procedures samples Following are the SQL stored procedure samples developed/tested during our project for OS/390 platform.

A.3.1 CALLEE sample for OS/390

CREATE PROCEDURE DB2RES3.CALLEE (IN parm1 SMALLINT, IN parm2 int, IN parm3 DECIMAL(10,2), IN parm4 real, IN parm5 double, IN parm6 int, IN parm7 char(10), IN parm8 varchar(10), IN parm9 date, IN parm10 time, IN parm11 timestamp, OUT out1 SMALLINT, OUT out2 int, OUT out3 DECIMAL(10,2), OUT out4 real, OUT out5 double, OUT out6 int, OUT out7 char(15), OUT out8 varchar(15), OUT out9 date, OUT out10 time, OUT out11 timestamp) LANGUAGE SQL MODIFIES SQL DATA COLLID TEST WLM ENVIRONMENT WLMSQL ASUTIME NO LIMIT RUN OPTIONS 'NOTEST(ALL,*,,VADTCPIP&9.1.151.58:*)' ------

462 Cross-Platform DB2 Stored Procedures: Building and Debugging -- SQL Stored Procedure ------

BEGIN DECLARE SQLSTATE char(5) default '00000'; DECLARE SQLCODE integer default 0; DECLARE RESULT_SET_END INTEGER default 0; DECLARE cur1 CURSOR FOR Select * from session.ttt; DECLARE CONTINUE HANDLER FOR NOT FOUND IF 1=1 THEN insert into result(proc,res) values ('exec CALLEE','Handler fired SQLSTATE='||SQLSTATE||' SQLCODE='||CHAR(SQLCODE)); SET RESULT_SET_END = 1; END IF; DECLARE CONTINUE HANDLER FOR sqlexception IF 1=1 THEN insert into result(proc,res) values ('exec CALLEE','Handler fired SQLSTATE='||SQLSTATE||' SQLCODE='||CHAR(SQLCODE)); SET RESULT_SET_END = 1; END IF; DECLARE CONTINUE HANDLER FOR sqlwarning IF 1=1 THEN insert into result(proc,res) values ('exec CALLEE','Handler fired SQLSTATE='||SQLSTATE||' SQLCODE='||CHAR(SQLCODE)); SET RESULT_SET_END = 1; END IF;

insert into result(proc,res) values ( 'PARM1', CHAR(parm1)); insert into result(proc,res) values ( 'PARM2', CHAR(parm2)); insert into result(proc,res) values ( 'PARM3', CHAR(parm3)); insert into result(proc,res) values ( 'PARM4', CHAR(parm4)); insert into result(proc,res) values ( 'PARM5', CHAR(parm5)); insert into result(proc,res) values ( 'PARM6', CHAR(parm6)); insert into result(proc,res) values ( 'PARM7', CHAR(parm7)); insert into result(proc,res) values ( 'PARM8', CHAR(parm8)); insert into result(proc,res) values ( 'PARM9', CHAR(parm9)); insert into result(proc,res) values ( 'PARM10', CHAR(parm10)); insert into result(proc,res) values ( 'PARM11', CHAR(parm11));

set out1 = parm1 + 1; set out2 = parm2 + 1; set out3 = parm3 + 1; set out4 = parm4 + 1; set out5 = parm5 + 1; set out6 = parm6 + 1; set out7 = parm7 || 'G'; set out8 = parm8 || 'G'; set out9 = parm9 + 1 day; set out10 = parm10 + 1 minute; set out11 = parm11 + 1 year;

if(1 = 0)then -- This is just to be able to parse the next statements declare global temporary table ttt(c1 SMALLINT, c2 int, c3 DECIMAL(10,2), c4 real, c5 double, c6 int, c7 char(18), c8 varchar(18), c9 date, c10 time, c11 timestamp); end if;

insert into session.ttt values (parm1 + 3, parm2 + 3, parm3 + 3, parm4 + 3, parm5 + 3,

Appendix A. SQL procedures samples 463 parm6 + 3, parm7 || 'E', parm8 || 'E', parm9 + 3 days, parm10 + 3 minutes, parm11 + 3 years);

insert into session.ttt values (parm1 + 2, parm2 + 2, parm3 + 2, parm4 + 2, parm5 + 2, parm6 + 2, parm7 || 'F', parm8 || 'F', parm9 + 2 days, parm10 + 2 minutes, parm11 + 2 years);

OPENcur1; insert into result(proc,res) values ( 'exec CALLEE','End of proc with cursor cur1 opened.'); END

CREATE PROCEDURE CALLEE (IN parm1 SMALLINT, IN parm2 int, IN parm3 DECIMAL(10,2), IN parm4 real, IN parm5 double, IN parm6 bigint, IN parm7 char(10), IN parm8 varchar(10), IN parm9 date, IN parm10 time, IN parm11 timestamp, OUT out1 SMALLINT, OUT out2 int, OUT out3 DECIMAL(10,2), OUT out4 real, OUT out5 double, OUT out6 bigint, OUT out7 char(15), OUT out8 varchar(15), OUT out9 date, OUT out10 time, OUT out11 timestamp) SPECIFIC CALLEE LANGUAGE SQL BEGIN DECLARE SQLSTATE char(5) default '00000'; DECLARE SQLCODE integer default 0; DECLARE RESULT_SET_END INTEGER default 0; DECLARE CONTINUE HANDLER FOR NOT FOUND, SQLEXCEPTION, SQLWARNING BEGIN insert into result(proc,res) values ('exec CALLEE','Handler fired SQLSTATE='||SQLSTATE||' SQLCODE='||CHAR(SQLCODE)); SET RESULT_SET_END = 1; END;

insert into result(proc,res) values ( 'PARM1', CHAR(parm1)); insert into result(proc,res) values ( 'PARM2', CHAR(parm2)); insert into result(proc,res) values ( 'PARM3', CHAR(parm3)); insert into result(proc,res) values ( 'PARM4', CHAR(parm4)); insert into result(proc,res) values ( 'PARM5', CHAR(parm5)); insert into result(proc,res) values ( 'PARM6', CHAR(parm6)); insert into result(proc,res) values ( 'PARM7', CHAR(parm7)); insert into result(proc,res) values ( 'PARM8', CHAR(parm8)); insert into result(proc,res) values ( 'PARM9', CHAR(parm9)); insert into result(proc,res) values ( 'PARM10', CHAR(parm10)); insert into result(proc,res) values ( 'PARM11', CHAR(parm11));

set out1 = parm1 + 1; set out2 = parm2 + 1; set out3 = parm3 + 1; set out4 = parm4 + 1; set out5 = parm5 + 1; set out6 = parm6 + 1; set out7 = parm7 || 'G';

464 Cross-Platform DB2 Stored Procedures: Building and Debugging set out8 = parm8 || 'G'; set out9 = parm9 + 1 day; set out10 = parm10 + 1 minute; set out11 = parm11 + 1 year;

if(1 = 0)then -- This is just to be able to parse the next statements declare global temporary table ttt(c1 SMALLINT, c2 int, c3 DECIMAL(10,2), c4 real, c5 double, c6 bigint, c7 char(18), c8 varchar(18), c9 date, c10 time, c11 timestamp) not logged; end if;

insert into session.ttt values (parm1 + 3, parm2 + 3, parm3 + 3, parm4 + 3, parm5 + 3, parm6 + 3, parm7 || 'E', parm8 || 'E', parm9 + 3 days, parm10 + 3 minutes, parm11 + 3 years);

insert into session.ttt values (parm1 + 2, parm2 + 2, parm3 + 2, parm4 + 2, parm5 + 2, parm6 + 2, parm7 || 'F', parm8 || 'F', parm9 + 2 days, parm10 + 2 minutes, parm11 + 2 years);

BEGIN DECLARE cur1 CURSOR WITH RETURN TO CALLER FOR Select * from session.ttt; OPEN cur1 ; END; insert into result(proc,res) values ( 'exec CALLEE','End of proc with cursor cur1 opened.'); END

A.3.2 SP01LMS.SQL sample

CREATE PROCEDURE DB2RES3.SP01LMS ( IN DEPTNO CHAR(3), OUT DEPTSAL DECIMAL(15,2), OUT BONUSCNT INT ) LANGUAGE SQL MODIFIES SQL DATA COLLID SG245485 NO WLM ENVIRONMENT ASUTIME NO LIMIT FENCED RESULT SET 1 NOT DETERMINISTIC NO DBINFO STAY RESIDENT NO PROGRAM TYPE MAIN SECURITY DB2 COMMIT ON RETURN NO RUN OPTIONS 'NOTEST(ALL,*,,VADTCPIP&9.1.151.58:*)' ------SQL Stored Procedure ------P1: BEGIN NOT ATOMIC DECLARE EMPLOYEE_NUMBER CHAR(6); DECLARE EMPLOYEE_FIRSTNME CHAR(12); DECLARE EMPLOYEE_LASTNAME CHAR(15); DECLARE EMPLOYEE_SALARY DECIMAL(15,2) DEFAULT 0; DECLARE EMPLOYEE_BONUS DECIMAL(15,2) DEFAULT 0; DECLARE TOTAL_SALARY DECIMAL(15,2) DEFAULT 0; DECLARE BONUS_COUNTER INT DEFAULT 0; DECLARE ENDTABLE INT DEFAULT 0;

Appendix A. SQL procedures samples 465 -- Cursor for result set of employees who got a bonus DECLARE DSN8ES1_RS_CSR CURSOR WITH RETURN WITH HOLD FOR SELECT SEQUENCE, EMPNO, FIRSTNME, LASTNAME, BONUS FROM db2res2.RS_TBL ORDER BY SEQUENCE; -- Cursor to fetch department employees DECLARE C1 CURSOR FOR SELECT EMPNO, FIRSTNME, LASTNAME, SALARY, BONUS FROM EMP WHERE WORKDEPT = DEPTNO; DECLARE CONTINUE HANDLER FOR NOT FOUND SET ENDTABLE = 1; DECLARE EXIT HANDLER FOR SQLEXCEPTION SET DEPTSAL = NULL; -- Clean residual from the result set table DELETE FROM db2res2.RS_TBL where 1=1; OPEN C1; FETCH C1 INTO EMPLOYEE_NUMBER, EMPLOYEE_FIRSTNME, EMPLOYEE_LASTNAME, EMPLOYEE_SALARY, EMPLOYEE_BONUS; wHILE ENDTABLE = 0 DO SET TOTAL_SALARY = TOTAL_SALARY + EMPLOYEE_SALARY + EMPLOYEE_BONUS; IF EMPLOYEE_BONUS > 0.00 THEN SET BONUS_COUNTER = BONUS_COUNTER + 1; -- Add the employee’s data to the result set INSERT INTO db2res2.RS_TBL ( SEQUENCE, EMPNO, FIRSTNME, LASTNAME, SALARY, BONUS ) VALUES( P1.BONUS_COUNTER, P1.EMPLOYEE_NUMBER, P1.EMPLOYEE_FIRSTNME, P1.EMPLOYEE_LASTNAME, P1.EMPLOYEE_SALARY, P1.EMPLOYEE_BONUS ); END IF; FETCH C1 INTO EMPLOYEE_NUMBER, EMPLOYEE_FIRSTNME, EMPLOYEE_LASTNAME, EMPLOYEE_SALARY, EMPLOYEE_BONUS; END WHILE; CLOSE C1; SET DEPTSAL = TOTAL_SALARY; SET BONUSCNT = BONUS_COUNTER;

466 Cross-Platform DB2 Stored Procedures: Building and Debugging -- Open the cursor to the result set OPEN DSN8ES1_RS_CSR; END P1

A.3.3 SP02LMS.SQL sample

CREATE PROCEDURE DB2RES3.SP02LMS (IN MEDSAL DOUBLE, OUT AVGSAL DOUBLE) LANGUAGE SQL MODIFIES SQL DATA COLLID SG245485 WLM ENVIRONMENT WLMSQL ASUTIME NO LIMIT RESULT SETS 2 RUN OPTIONS 'NOTEST(ALL,*,,VADTCPIP&9.1.151.58:*)' ------SQL Stored Procedure ------

BEGIN --DECLARE AVGSAL DOUBLE; -- USE WITH RETURN IN DECLARE CURSOR TO RETURN A RESULT SET DECLARE C2 CURSOR WITH RETURN FOR SELECT LASTNAME, JOB, INTEGER(SALARY) FROM DB2RES3.STAFF WHERE SALARY > MEDSAL ORDER BY SALARY; -- YOU CAN RETURN AS MANY RESULT SETS AS YOU LIKE, JUST -- ENSURE THAT THE EXACT NUMBER IS DECLARED IN THE RESULT SETS -- CLAUSE OF THE CREATE PROCEDURE STATEMENT -- USE WITH RETURN IN DECLARE CURSOR TO RETURN ANOTHER RESULT SET DECLARE C3 CURSOR WITH RETURN FOR SELECT LASTNAME, JOB, INTEGER(SALARY) FROM DB2RES3.STAFF WHERE SALARY < MEDSAL ORDER BY SALARY DESC; -- SELECT AVG(SALARY) INTO AVGSAL FROM DB2RES3.STAFF; -- RETURN 1ST RESULT SET, DO NOT CLOSE CURSOR OPEN C2; -- RETURN 2ND RESULT SET, DO NOT CLOSE CURSOR OPEN C3; END

A.3.4 SP03LMS.SQL sample

CREATE PROCEDURE DB2RES3.SP03LMS ( out maxnonew char(6), out rc char(2) ) LANGUAGE SQL MODIFIES SQL DATA COLLID SG245485 WLM ENVIRONMENT WLMSQL ASUTIME NO LIMIT RUN OPTIONS 'NOTEST(ALL,*,,VADTCPIP&9.1.151.58:*)' ------SQL Stored Procedure ------BEGIN declare maxno char(6); insert into result(proc,res) values ('CALLER', 'begin'); CALL SP05LMS(MAXNO); if maxno is null then set rc = 'KO'; else

Appendix A. SQL procedures samples 467 set rc = 'OK'; set maxnonew = maxno; end if; insert into result(proc,res) values ('SP03LMS', 'end'); END

A.3.5 SP04LMS.SQL sample

CREATE PROCEDURE DB2RES3.SP04LMS ( ) LANGUAGE SQL MODIFIES SQL DATA COLLID SG245485 WLM ENVIRONMENT wlmsql ASUTIME NO LIMIT RUN OPTIONS 'NOTEST(ALL,*,,VADTCPIP&9.1.151.105:*)' ------SQL Stored Procedure ------begin declare a int; declare SQLSTATE char(5) default '00000';

DECLARE CONTINUE HANDLER FOR NOT FOUND insert into result(proc,res) values ('exec of DDL', 'CONTINUE handler fired. SQLSTATE=' || SQLSTATE);

DECLARE CONTINUE HANDLER FOR SQLEXCEPTION insert into result(proc,res) values ('marian0', 'CONTINUE handler fired. SQLSTATE=' || SQLSTATE);

DECLARE CONTINUE HANDLER FOR SQLWARNING insert into result(proc,res) values ('exec of DDL', 'CONTINUE handler fired. SQLSTATE=' || SQLSTATE);

insert into result(proc,res,dt) values('exec DDL', ' Start', current timestamp); IF (a is null) THEN create table DDLTEST(c1 int); create table t4(c1 int, c2 int, c3 int); create index i1 on t4(c1); comment on table t4 is 'PSM is great'; grant all on t4 to public; grant all on DDLTEST to public; create view v1 as select * from t4; grant update on v1 to newton; END IF; declare global temporary table t3 like t4 ; declare global temporary table t31 like t4 ; drop table t4; drop table DDLTEST; drop view v1;

insert into result(proc,res,dt) values('exec DDL', 'End', current timestamp);

END

A.3.6 SP05LMS.SQL sample

CREATE PROCEDURE DB2RES3.SP05LMS ( OUT MAXNO CHAR(6) ) LANGUAGE SQL MODIFIES SQL DATA

468 Cross-Platform DB2 Stored Procedures: Building and Debugging COLLID SG245485 WLM ENVIRONMENT WLMSQL ASUTIME NO LIMIT RUN OPTIONS 'NOTEST(ALL,*,,VADTCPIP&9.1.151.58:*)' ------SQL Stored Procedure ------P1: BEGIN

CONNECT TO DBZ1;

SELECT MAX(EMPNO) INTO MAXNO FROM EMP;

END P1

A.3.7 SP06LMS.SQL sample

CREATE PROCEDURE DB2RES3.SP06LMS (OUT CODE INT ) LANGUAGE SQL MODIFIES SQL DATA COLLID SG245485 WLM ENVIRONMENT WLMSQL ASUTIME NO LIMIT RESULT SETS 1 RUN OPTIONS 'NOTEST(ALL,*,,VADTCPIP&9.1.151.58:*)' ------SQL Stored Procedure ------

P1: BEGIN DECLARE STMT VARCHAR(200); DECLARE SQLCODE INT DEFAULT 0; DECLARE EXIT HANDLER FOR SQLEXCEPTION SET CODE = SQLCODE; GRANT select on table sysibm.sysvolumes to anyone; SET STMT = 'GRANT select on table sysibm.sysvolumes to someone' ; execute immediate stmt; END P1

A.3.8 SP07LMS.SQL sample

CREATE PROCEDURE DB2RES3.SP07LMS ( OUT CODE INT ) LANGUAGE SQL MODIFIES SQL DATA COLLID SG245485 WLM ENVIRONMENT WLMSQL ASUTIME NO LIMIT RESULT SETS 1 RUN OPTIONS 'NOTEST(ALL,*,,VADTCPIP&9.1.151.58:*)' ------SQL Stored Procedure ------P1: BEGIN DECLARE STMT VARCHAR(200); declare stmt2 varchar(200); declare stmt3 varchar(200); declare stmt4 varchar(200); DECLARE SQLCODE INT DEFAULT 0; DECLARE EXIT HANDLER FOR SQLEXCEPTION SET CODE = SQLCODE;

Appendix A. SQL procedures samples 469 GRANT select on table sysibm.sysvolumes to sabi5; SET STMT = 'GRANT select on table sysibm.sysvolumes to sabi6' ; prepare s1 from stmt; execute s1; savepoint a on rollback retain cursors; SET STMT2 = 'GRANT select on table sysibm.sysvolumes to sabi7' ; prepare s2 from stmt2; execute s2; savepoint b on rollback retain cursors; SET STMT3 = 'GRANT select on table sysibm.sysvolumes to sabi9' ; prepare s3 from stmt3; execute s3; SET STMT4 = 'GRANT select on table sysibm.sysvolumes to sabi10' ; prepare s4 from stmt4; execute s4; savepoint c on rollback retain cursors; rollback to savepoint a; SET CODE = SQLCODE; END P1

A.3.9 SP08LMS.SQL sample

CREATE PROCEDURE DB2RES3.SP08LMS (out v1 double,out v2 double, out v3 integer, out v5 decimal(10), out v7 varchar (27), out v8 integer,out v9 integer, out v10 integer, out v12 char(8), out v13 char(3), out v14 integer, out v15 integer, out v16 integer, out v17 char(12), out v18 integer) LANGUAGE SQL MODIFIES SQL DATA COLLID SG245485 WLM ENVIRONMENT WLMSQL ASUTIME NO LIMIT RUN OPTIONS 'NOTEST(ALL,*,,VADTCPIP&9.1.151.58:*)' ------SQL Stored Procedure ------P1: BEGIN SELECT STDDEV(SALARY),VAR(SALARY) INTO v1,v2 FROM DB2RES3.STAFF; SET v3 = ABS(-4356); SELECT CEIL(MAX(SALARY)/12) INTO v5 FROM DSN8610.EMP; SELECT CONCAT(FIRSTNME,LASTNAME) INTO v7 FROM DSN8610.EMP WHERE EMPNO = '000140'; SELECT DAYOFWEEK(HIREDATE) INTO v8 FROM DSN8610.EMP WHERE EMPNO = '000140'; SELECT AVG(DAYOFYEAR(HIREDATE)) INTO v9 FROM DSN8610.EMP; SELECT FLOOR(MAX(SALARY)/12) INTO v10 FROM DSN8610.EMP; SET v12 = LCASE('KATHLEEN'); SET v13 = LEFT('JONATHAN',3); SELECT MIDNIGHT_SECONDS('24:00:00'),MIDNIGHT_SECONDS('00:00:00') INTO v14,v15 FROM SYSIBM.SYSDUMMY1; SET v16 = QUARTER('1999-09-09'); SET v17 = REPEAT('KATH',3); SET v18 = SIGN(-1000); END P1

A.3.10 SP09LMS.SQL sample

CREATE PROCEDURE DB2RES3.SP09LMS ( INOUT tt CHAR(3) )

470 Cross-Platform DB2 Stored Procedures: Building and Debugging LANGUAGE SQL MODIFIES SQL DATA COLLID SG245485 WLM ENVIRONMENT WLMSQL ASUTIME NO LIMIT ------SQL Stored Procedure ------

BEGIN NOT ATOMIC declare a integer default 0; insert into result(proc,res) values ('exec of I2','Start.'); -- This is a sample of a searched CASE statement. -- Only searched CASE statements allow more then three levels. CASE WHEN tt='AAA' THEN insert into result(proc,res) values ('exec of I2','AAA found.'); CASE WHEN tt='AAA' THEN insert into result(proc,res) values ('exec of I2','AAA found in 2nd case.'); CASE WHEN tt='BBB' THEN insert into result(proc,res) values ('exec of I2','BBB found in 2nd case.'); CASE WHEN tt='CCC' THEN insert into result(proc,res) values ('exec of I2','CCC found in 2nd case.'); ELSE insert into result(proc,res) values ('exec of I2', 'default case value=[' || CHAR(tt) || '] in 2nd case'); end CASE ; END CASE ; END CASE;

WHEN tt='BBB' THEN insert into result(proc,res) values ('exec of I2','BBB found.'); WHEN tt='CCC' THEN insert into result(proc,res) values ('exec of I2','CCC found.'); ELSE insert into result(proc,res) values ('exec of I2','default case value=[' || CHAR(tt) || ']'); END CASE; insert into result(proc,res) values ('exec of I2','End.'); END

A.3.11 SP10LMS.SQL sample

CREATE PROCEDURE DB2RES3.SP10LMS (OUT SHOWGRANTEE CHAR(8) , OUT SHOWGRANTOR CHAR(8) , OUT SHOWGRANTEE1 CHAR(8), OUT SHOWGRANTOR1 CHAR(8), OUT CODE1 INT, OUT CODE2 INT, OUT CODE3 INT, OUT HANDLERCODE INT) LANGUAGE SQL MODIFIES SQL DATA COLLID SG245485 WLM ENVIRONMENT WLMSQL

Appendix A. SQL procedures samples 471 ASUTIME NO LIMIT RUN OPTIONS 'NOTEST(ALL,*,,VADTCPIP&9.1.151.58:*)' ------SQL Stored Procedure ------

P1: BEGIN DECLARE STMT VARCHAR(200); DECLARE SQLCODE INT DEFAULT 0; DECLARE EXIT HANDLER FOR SQLWARNING SET HANDLERCODE = SQLCODE; GRANT select on table sysibm.sysvolumes to ANYONE; SET CODE1=SQLCODE; GRANT select on table sysibm.sysvolumes to ANYONE; SET CODE2=SQLCODE; SELECT GRANTEE, GRANTOR INTO SHOWGRANTEE, SHOWGRANTOR FROM SYSIBM.SYSTABAUTH WHERE STNAME = 'SYSVOLUMES' AND GRANTEE = 'ANYONE'; SET CODE3=SQLCODE; REVOKE SELECT ON TABLE sysibm.sysvolumes FROM ANYONE; SELECT GRANTEE, GRANTOR INTO SHOWGRANTEE1, SHOWGRANTOR1 FROM SYSIBM.SYSTABAUTH WHERE STNAME = 'SYSVOLUMES' AND GRANTEE = 'ANYONE'; END P1

A.3.12 SP11LMS.SQL sample

CREATE PROCEDURE DB2RES3.SP11LMS (out rowcount int) LANGUAGE SQL MODIFIES SQL DATA COLLID TEST WLM ENVIRONMENT wlmpsm ASUTIME NO LIMIT RUN OPTIONS 'NOTEST(ALL,*,,VADTCPIP&9.1.151.105:*)' ------SQL Stored Procedure ------P1: BEGIN

update db2res3.emp set salary=salary+1 where salary <80000; get diagnostics rowcount = row_count;

END P1

A.3.13 SP12LMS.SQL sample

CREATE PROCEDURE DB2RES3.SP12LMS (inout service decimal(8,2) , in v_empno char(6), in rating int, out return_parm decimal(8,2)) LANGUAGE SQL MODIFIES SQL DATA COLLID SG245485 WLM ENVIRONMENT WLMSQL ASUTIME NO LIMIT RUN OPTIONS 'NOTEST(ALL,*,,VADTCPIP&9.1.151.105:*)' ------SQL Stored Procedure ------

472 Cross-Platform DB2 Stored Procedures: Building and Debugging begin declare new_salary decimal(9,2); select salary, current_date - hiredate into new_salary, service from db2res3.emp where empno = v_empno ; if service < 600 then goto exit_RTN; end if; if rating = 1 then set new_salary = new_salary*1.1; elseif rating = 2 then set new_salary = new_salary*1.05; end if; update emp set salary = new_salary where empno = v_empno; exit_RTN: set return_parm = service; End

A.3.14 SP13LMS.SQL sample

CREATE PROCEDURE SP13LMS (IN empnum CHAR(6), INout rating smallint) COLLID SG245485 LANGUAGE SQL WLM ENVIRONMENT WLMsql ------SQL stored procedure SDK2LMS ------BEGIN DECLARE not_found CONDITION FOR SQLSTATE '02000'; DECLARE EXIT HANDLER FOR not_found SET rating = -1; IF rating = 1 THEN UPDATE db2res3.emp SET salary = salary * 1.10, bonus = 1000 WHERE empno = empnum; ELSEIF rating = 2 THEN UPDATE db2res3.emp SET salary = salary * 1.05, bonus = 500 WHERE empno = empnum; ELSE UPDATE db2res3.emp SET salary = salary * 1.03, bonus = 0 WHERE empno = empnum; END IF; END

A.3.15 SP14LMS.SQL sample

CREATE PROCEDURE SP14lms ( out code int) LANGUAGE SQL COLLID SG245485 WLM ENVIRONMENT WLMsql ------SQL stored procedure SP14LMS ------

Appendix A. SQL procedures samples 473 BEGIN DECLARE v_dept CHAR(3); DECLARE v_deptname VARCHAR(29); DECLARE v_admdept CHAR(3); DECLARE at_end INT DEFAULT 0; declare SQLCODE int default 0; DECLARE not_found CONDITION FOR SQLSTATE '02000'; DECLARE c1 CURSOR FOR SELECT deptno, deptname, admrdept FROM db2res3.dept ORDER BY deptno; DECLARE CONTINUE HANDLER FOR not_found SET at_end = 1; declare continue handler for sqlexception set code = sqlcode; OPEN c1; ins_loop: LOOP FETCH c1 INTO v_dept, v_deptname, v_admdept; IF at_end = 1 THEN LEAVE ins_loop; -- ELSEIF v_dept = 'D11' THEN -- ITERATE ins_loop; END IF; INSERT INTO db2res3.dept (deptno, deptname, admrdept) VALUES ('NEW', v_deptname, v_admdept); END LOOP; CLOSE c1; END

A.3.16 SP15LMS.SQL sample

CREATE PROCEDURE SP15LMS (inOUT counter INT ) LANGUAGE SQL COLLID SG245485 WLM ENVIRONMENT WLMsql ------SQL stored procedure ------BEGIN DECLARE v_firstnme VARCHAR(12); DECLARE v_midinit CHAR(1); DECLARE v_lastname VARCHAR(15); DECLARE at_end SMALLINT DEFAULT 0; DECLARE not_found CONDITION FOR SQLSTATE '02000'; DECLARE c1 CURSOR FOR SELECT firstnme, midinit, lastname FROM db2res3.emp; DECLARE CONTINUE HANDLER FOR not_found SET at_end = 1; -- initialize OUT parameter SET counter = 0; OPEN c1; fetch_loop: REPEAT FETCH c1 INTO v_firstnme, v_midinit, v_lastname; SET counter = counter + 1; UNTIL at_end <> 0 END REPEAT fetch_loop; SET counter = counter - 1; -- count is 1 more than actual for repeat

474 Cross-Platform DB2 Stored Procedures: Building and Debugging CLOSE c1; END

A.3.17 SP16LMS.SQL sample

CREATE PROCEDURE SP16LMS (IN deptnum char(3) ) LANGUAGE SQL COLLID SG245485 WLM ENVIRONMENT WLMsql ------SQL stored procedure SDK8LMS ------BEGIN DECLARE v_salary decimal(9,2); DECLARE v_id char(6); DECLARE at_end INT DEFAULT 0; DECLARE not_found CONDITION FOR SQLSTATE '02000'; -- CAST salary as DOUBLE because SQL procedures do not support -- DECIMAl DECLARE C1 CURSOR FOR SELECT empno, FLOAT(salary) FROM db2res3.emp WHERE workdept = deptnum; DECLARE CONTINUE HANDLER FOR not_found SET at_end = 1; OPEN C1; FETCH C1 INTO v_id, v_salary; WHILE at_end = 0 DO IF (v_salary < 2000) THEN UPDATE db2res3.emp SET salary = salary*1.08 WHERE empno = v_id; ELSEIF (v_salary < 5000) THEN IF (v_salary < 3000) THEN UPDATE db2res3.emp SET salary = 3000 * 1.7 WHERE empno = v_id; ELSE UPDATE db2res3.emp SET salary = v_salary * 1.5 WHERE empno = v_id; END IF; ELSE UPDATE db2res3.emp SET job = 'PREZ' WHERE empno = v_id; END IF; FETCH C1 INTO v_id, v_salary; END WHILE; CLOSE C1; END

A.3.18 SP17LMS.SQL sample

CREATE PROCEDURE SP17LMS (out pid char(6)) LANGUAGE SQL COLLID SG245485 wlm environment wlmsql P1: BEGIN declare empno char(6);

Appendix A. SQL procedures samples 475 set empno = '000010'; select staff.empno into empno from db2res3.staff where staff.empno=p1.empno; set pid = empno; END P1

A.4 AS/400 stored procedures samples Following are the SQL stored procedure samples developed/tested during our project for AS/400 platform. Note that some changes had to be done in some samples, as follows: • SP06L4S — There is no SYSVOLUMES on the AS/400, so changed it to SYSTABLES • SP07L4S — No sample — SAVEPOINTS still not supported on the AS/400. • SP08L4S — no midnight_seconds, and repeat scalars on the AS/400, so commented out. • SP10L4S — There is no SYSTABAUTH on the AS/400 • SP14L4S — No ITERATE support on the AS/400, so changed to GOTO.

A.4.1 SP01L4S.SQL sample

CREATE PROCEDURE SAMPLE.SP01L4S ( IN DEPTNO CHAR(3), OUT DEPTSAL DECIMAL(15,2), OUT BONUSCNT INT ) RESULT SETS 1 LANGUAGE SQL MODIFIES SQL DATA FENCED NOT DETERMINISTIC

------SQL Stored Procedure ------P1: BEGIN NOT ATOMIC DECLARE EMPLOYEE_NUMBER CHAR(6); DECLARE EMPLOYEE_FIRSTNME CHAR(12); DECLARE EMPLOYEE_LASTNAME CHAR(15); DECLARE EMPLOYEE_SALARY DECIMAL(15,2) DEFAULT 0; DECLARE EMPLOYEE_BONUS DECIMAL(15,2) DEFAULT 0; DECLARE TOTAL_SALARY DECIMAL(15,2) DEFAULT 0; DECLARE BONUS_COUNTER INT DEFAULT 0; DECLARE ENDTABLE INT DEFAULT 0; -- Cursor for result set of employees who got a bonus DECLARE DSN8ES1_RS_CSR CURSOR WITH RETURN WITH HOLD FOR SELECT SEQUENCE, EMPNO, FIRSTNME, LASTNAME, BONUS FROM sample.RS_TBL

476 Cross-Platform DB2 Stored Procedures: Building and Debugging ORDER BY SEQUENCE; -- Cursor to fetch department employees DECLARE C1 CURSOR FOR SELECT EMPNO, FIRSTNME, LASTNAME, SALARY, BONUS FROM sample.EMPLOYEE WHERE WORKDEPT = DEPTNO; DECLARE CONTINUE HANDLER FOR NOT FOUND SET ENDTABLE = 1; DECLARE EXIT HANDLER FOR SQLEXCEPTION SET DEPTSAL = NULL; -- Clean residual from the result set table DELETE FROM sample.RS_TBL where 1=1; SET endtable = 0; OPEN C1; FETCH C1 INTO EMPLOYEE_NUMBER, EMPLOYEE_FIRSTNME, EMPLOYEE_LASTNAME, EMPLOYEE_SALARY, EMPLOYEE_BONUS; WHILE ENDTABLE = 0 DO SET TOTAL_SALARY = TOTAL_SALARY + EMPLOYEE_SALARY + EMPLOYEE_BONUS; IF EMPLOYEE_BONUS > 0.00 THEN SET BONUS_COUNTER = BONUS_COUNTER + 1; -- Add the employee's data to the result set INSERT INTO sample.RS_TBL ( SEQUENCE, EMPNO, FIRSTNME, LASTNAME, SALARY, BONUS ) VALUES( P1.BONUS_COUNTER, P1.EMPLOYEE_NUMBER, P1.EMPLOYEE_FIRSTNME, P1.EMPLOYEE_LASTNAME, P1.EMPLOYEE_SALARY, P1.EMPLOYEE_BONUS ); END IF; FETCH C1 INTO EMPLOYEE_NUMBER, EMPLOYEE_FIRSTNME, EMPLOYEE_LASTNAME, EMPLOYEE_SALARY, EMPLOYEE_BONUS; END WHILE; CLOSE C1; SET DEPTSAL = TOTAL_SALARY; SET BONUSCNT = BONUS_COUNTER; -- Open the cursor to the result set OPEN DSN8ES1_RS_CSR; ENDP1;

A.4.2 SP02L4S.SQL sample

CREATE PROCEDURE sample.SP02L4S (IN MEDSAL DOUBLE, OUT AVGSAL DOUBLE)

Appendix A. SQL procedures samples 477 RESULT SETS 2 LANGUAGE SQL MODIFIES SQL DATA

------SQL Stored Procedure ------

BEGIN --DECLARE AVGSAL DOUBLE; -- USE WITH RETURN IN DECLARE CURSOR TO RETURN A RESULT SET DECLARE C2 CURSOR WITH RETURN FOR SELECT LASTNAME, JOB, INTEGER(SALARY) AS SALARY FROM sample.employee WHERE SALARY > MEDSAL ORDER BY SALARY; -- YOU CAN RETURN AS MANY RESULT SETS AS YOU LIKE, JUST -- ENSURE THAT THE EXACT NUMBER IS DECLARED IN THE RESULT SETS -- CLAUSE OF THE CREATE PROCEDURE STATEMENT -- USE WITH RETURN IN DECLARE CURSOR TO RETURN ANOTHER RESULT SET DECLARE C3 CURSOR WITH RETURN FOR SELECT LASTNAME, JOB, INTEGER(SALARY) AS SALARY FROM sample.employee WHERE SALARY < MEDSAL ORDER BY SALARY DESC; -- SELECT AVG(SALARY) INTO AVGSAL FROM sample.employee; -- RETURN 1ST RESULT SET, DO NOT CLOSE CURSOR OPEN C2; -- RETURN 2ND RESULT SET, DO NOT CLOSE CURSOR OPEN C3; END ;

A.4.3 SP03L4S.SQL sample

CREATE PROCEDURE SAMPLE.SP03L4S ( out maxnonew char(6), out rc char(2) ) LANGUAGE SQL MODIFIES SQL DATA

------SQL Stored Procedure ------BEGIN declare maxno char(6); insert into sample.result(proc,res) values ('CALLER', 'begin'); CALL SP05LMS(MAXNO); if maxno is null then set rc = 'KO'; else set rc = 'OK'; set maxnonew = maxno; end if; insert into sample.result(proc,res) values ('SP03LMS', 'end'); END ;

A.4.4 SP04L4S.SQL sample

CREATE PROCEDURE sample.SP04L4S ( ) LANGUAGE SQL

478 Cross-Platform DB2 Stored Procedures: Building and Debugging MODIFIES SQL DATA

------SQL Stored Procedure ------begin declare a int DEFAULT NULL; declare SQLSTATE char(5) default '00000';

DECLARE CONTINUE HANDLER FOR NOT FOUND insert into result(proc,res) values ('exec of DDL', 'CONTINUE handler fired. SQLSTATE=' || SQLSTATE);

DECLARE CONTINUE HANDLER FOR SQLEXCEPTION insert into result(proc,res) values ('marian0', 'CONTINUE handler fired. SQLSTATE=' || SQLSTATE);

DECLARE CONTINUE HANDLER FOR SQLWARNING insert into result(proc,res) values ('exec of DDL', 'CONTINUE handler fired. SQLSTATE=' || SQLSTATE);

insert into result(proc,res,dt) values('exec DDL', 'Start', current timestamp); IF a is null THEN create table DDLTEST(c1 int); create table t4(c1 int, c2 int, c3 int); create index i1 on t4(c1); comment on table t4 is 'PSM is great'; grant all on t4 to public; grant all on DDLTEST to public; create view v1 as select * from t4; -- grant update on v1 to dbo; END IF;

-- declare global temporary table t3 like t4 ; -- declare global temporary table t31 like t4 ; -- Object created in QTEMP are temporary create table qtemp.t3 (c1 int, c2 int, c3 int); create table qtemp.t31 (c1 int, c2 int, c3 int);

drop table t4; drop table DDLTEST; drop view v1;

insert into result(proc,res,dt) values('exec DDL', 'End', current timestamp);

END

A.4.5 SP05L4S.SQL sample

CREATE PROCEDURE SAMPLE.SP05L4S ( OUT MAXNO CHAR(6) ) LANGUAGE SQL MODIFIES SQL DATA

------SQL Stored Procedure ------P1: BEGIN

CONNECT TO SAMPLE;

SELECT MAX(EMPNO) INTO MAXNO FROM EMPLOYEE;

Appendix A. SQL procedures samples 479 END P1

A.4.6 SP06L4S.SQL sample

CREATE PROCEDURE Sample.SP06L4S (OUT CODE INT ) RESULT SETS 1 LANGUAGE SQL MODIFIES SQL DATA

------SQL Stored Procedure ------

P1: BEGIN DECLARE STMT VARCHAR(200); DECLARE SQLCODE INT DEFAULT 0; DECLARE EXIT HANDLER FOR SQLEXCEPTION SET CODE = SQLCODE; GRANT select on table qsys2.systables to anyone; SET STMT = 'GRANT select on table qsys2.systables to someone' ; execute immediate stmt; SET CODE = SQLCODE; ENDP1;

A.4.7 SP08L4S.SQL sample

CREATE PROCEDURE sample.SP08L4S (out v1 double,out v2 double, out v3 integer, out v5 decimal(10), out v7 varchar (27), out v8 integer,out v9 integer, out v10 integer, out v12 char(8), out v13 char(3), out v14 integer, out v15 integer, out v16 integer, out v17 char(12), out v18 integer) LANGUAGE SQL MODIFIES SQL DATA

------SQL Stored Procedure ------P1: BEGIN SELECT STDDEV(SALARY),VAR(SALARY) INTO v1,v2 FROM sample.STAFF; SET v3 = ABS(-4356); SELECT CEIL(MAX(SALARY)/12) INTO v5 FROM sample.EMPloyee; SELECT CONCAT(FIRSTNME,LASTNAME) INTO v7 FROM sample.EMPloyee WHERE EMPNO = '000140'; SELECT DAYOFWEEK(HIREDATE) INTO v8 FROM SAMPLE.EMPLOYEE WHERE EMPNO = '000140'; SELECT AVG(DAYOFYEAR(HIREDATE)) INTO v9 FROM SAMPLE.EMPLOYEE; SELECT FLOOR(MAX(SALARY)/12) INTO v10 FROM SAMPLE.EMPLOYEE; SET v12 = LCASE('KATHLEEN'); SET v13 = LEFT('JONATHAN',3); SELECT MIDNIGHT_SECONDS('24:00:00'),MIDNIGHT_SECONDS('00:00:00') INTO v14,v15 FROM SAMPLE.DUMMY; SET v16 = QUARTER(date('1999-09-09')); SET v17 = REPEAT('KATH',3); SET v18 = SIGN(-1000); END P1

480 Cross-Platform DB2 Stored Procedures: Building and Debugging A.4.8 SP09L4S.SQL sample

CREATE PROCEDURE sample.SP09L4S ( tt CHAR(3) ) LANGUAGE SQL MODIFIES SQL DATA

------SQL Stored Procedure ------

BEGIN NOT ATOMIC declare a integer default 0; insert into result(proc,res) values ('exec of I2','Start.'); -- This is a sample of a searched CASE statement. -- Only searched CASE statements allow more then three levels. CASE WHEN tt='AAA' THEN insert into result(proc,res) values ('exec of I2','AAA found.'); CASE WHEN tt='AAA' THEN insert into result(proc,res) values ('exec of I2','AAA found in 2nd case.'); CASE WHEN tt='BBB' THEN insert into result(proc,res) values ('exec of I2','BBB found in 2nd case.'); CASE WHEN tt='CCC' THEN insert into result(proc,res) values ('exec of I2','CCC found in 2nd case.'); ELSE insert into result(proc,res) values ('exec of I2', 'default case value=[' || CHAR(tt) || '] in 2nd case'); end CASE ; END CASE ; END CASE;

WHEN tt='BBB' THEN insert into result(proc,res) values ('exec of I2','BBB found.'); WHEN tt='CCC' THEN insert into result(proc,res) values ('exec of I2','CCC found.'); ELSE insert into result(proc,res) values ('exec of I2','default case value=[' || CHAR(tt) || ']'); END CASE; insert into result(proc,res) values ('exec of I2','End.'); END

A.4.9 SP11L4S.SQL sample

CREATE PROCEDURE sample.SP11L4S (out rowcount int) LANGUAGE SQL MODIFIES SQL DATA

------SQL Stored Procedure ------P1: BEGIN

update sample.employee set salary=salary+1 where salary <80000; get diagnostics rowcount = row_count;

Appendix A. SQL procedures samples 481 END P1

A.4.10 SP12L4S.SQL sample

CREATE PROCEDURE SAMPLE.SP12L4S ( INOUT SERVICE dec(8,2), IN V_EMPNO char(6), IN RATING int, OUT RETURN_PARM dec(8,2) ) LANGUAGE SQL SPECIFIC SAMPLE.SP12LMS

BEGIN DECLARE NEW_SALARY DECIMAL ( 9 , 2 ) ; SELECT SALARY , DAYS ( CURRENT_DATE ) - DAYS ( HIREDATE ) INTO NEW_SALARY , SERVICE FROM SAMPLE . EMPLOYEE WHERE EMPNO = V_EMPNO ; IF SERVICE < 10000 THEN GOTO EXIT_RTN ; ENDIF; IF RATING = 1 THEN SET NEW_SALARY = NEW_SALARY * 1.1 ; ELSEIF RATING = 2 THEN SET NEW_SALARY = NEW_SALARY * 1.05 ; ENDIF; UPDATE EMP SET SALARY = NEW_SALARY WHERE EMPNO = V_EMPNO ; EXIT_RTN : SET RETURN_PARM = SERVICE ; END

A.4.11 SP13L4S.SQL sample

CREATE PROCEDURE sample.SP13L4S (IN empnum CHAR(6), INout rating smallint) LANGUAGE SQL ------SQL stored procedure ------BEGIN DECLARE not_found CONDITION FOR SQLSTATE '02000'; DECLARE EXIT HANDLER FOR not_found SET rating = -1; IF rating = 1 THEN UPDATE SAMPLE.EMPLOYEE SET salary = salary * 1.10, bonus = 1000 WHERE empno = empnum; ELSEIF rating = 2 THEN UPDATE SAMPLE.EMPLOYEE SET salary = salary * 1.05, bonus = 500 WHERE empno = empnum; ELSE UPDATE SAMPLE.EMPLOYEE SET salary = salary * 1.03, bonus = 0 WHERE empno = empnum; END IF; END

A.4.12 SP14L4S.SQL sample

CREATE PROCEDURE SAMPLE.SP14l4s (out code int)

482 Cross-Platform DB2 Stored Procedures: Building and Debugging LANGUAGE SQL ------SQL stored procedure ------BEGIN DECLARE v_dept CHAR(3); DECLARE v_deptname VARCHAR(29); DECLARE v_admdept CHAR(3); DECLARE at_end INT DEFAULT 0; declare SQLCODE int default 0; DECLARE not_found CONDITION FOR SQLSTATE '02000'; DECLARE c1 INSENSITIVE CURSOR FOR SELECT deptno, deptname, admrdept FROM SAMPLE.dept ORDER BY deptno; DECLARE CONTINUE HANDLER FOR not_found SET at_end = 1; declare continue handler for sqlexception set code = sqlcode; OPEN c1; ins_loop: LOOP FETCH c1 INTO v_dept, v_deptname, v_admdept; IF at_end = 1 THEN LEAVE ins_loop; ELSEIF v_dept = 'D11' THEN GOTO ins_loop; END IF; INSERT INTO SAMPLE.dept (deptno, deptname, admrdept) VALUES ('NEW', v_deptname, v_admdept); END LOOP; CLOSE c1; END

A.4.13 SP15L4S.SQL sample

CREATE PROCEDURE SP15L4S (inOUT counter INT ) LANGUAGE SQL ------SQL stored procedure ------BEGIN DECLARE v_firstnme VARCHAR(12); DECLARE v_midinit CHAR(1); DECLARE v_lastname VARCHAR(15); DECLARE at_end SMALLINT DEFAULT 0; DECLARE not_found CONDITION FOR SQLSTATE '02000'; DECLARE c1 CURSOR FOR SELECT firstnme, midinit, lastname FROM sample.employee; DECLARE CONTINUE HANDLER FOR not_found SET at_end = 1; -- initialize OUT parameter SET counter = 0; OPEN c1; fetch_loop: REPEAT FETCH c1 INTO v_firstnme, v_midinit, v_lastname; SET counter = counter + 1; UNTIL at_end <> 0 END REPEAT fetch_loop;

Appendix A. SQL procedures samples 483 SET counter = counter - 1; -- count is 1 more than actual for repeat CLOSE c1; END

A.4.14 SP16L4S.SQL sample

CREATE PROCEDURE SP16L4S (IN deptnum char(3) ) LANGUAGE SQL ------SQL stored procedure ------BEGIN DECLARE v_salary decimal(9,2); DECLARE v_id char(6); DECLARE at_end INT DEFAULT 0; DECLARE not_found CONDITION FOR SQLSTATE '02000'; -- CAST salary as DOUBLE because SQL procedures do not support -- DECIMAl DECLARE C1 CURSOR FOR SELECT empno, salary FROM sample.employee WHERE workdept = deptnum; DECLARE CONTINUE HANDLER FOR not_found SET at_end = 1; OPEN C1; FETCH C1 INTO v_id, v_salary; WHILE at_end = 0 DO IF (v_salary < 20000) THEN UPDATE SAMPLE.EMPLOYEE SET salary = salary*1.08 WHERE empno = v_id; ELSEIF (v_salary < 50000) THEN IF (v_salary < 30000) THEN UPDATE SAMPLE.EMPLOYEE SET salary = 30000 * 1.07 WHERE empno = v_id; ELSE UPDATE SAMPLE.EMPLOYEE SET salary = v_salary * 1.05 WHERE empno = v_id; END IF; ELSE UPDATE SAMPLE.EMPLOYEE SET job = 'PREZ' WHERE empno = v_id; END IF; FETCH C1 INTO v_id, v_salary; END WHILE; CLOSE C1; END

A.4.15 SP17L4S.SQL sample

CREATE PROCEDURE SAMPLE.SP17L4S (out pid char(6)) LANGUAGE SQL ------SQL Stored Procedure ------P1: BEGIN declare empno char(6); set empno = '000010';

484 Cross-Platform DB2 Stored Procedures: Building and Debugging select employee.empno into empno from employee where employee.empno=p1.empno; set pid = empno; END P1

Appendix A. SQL procedures samples 485 486 Cross-Platform DB2 Stored Procedures: Building and Debugging Appendix B. DB2 and IMS ODBA samples

These samples illustrate simple IMS database calls such as GN, ISRT as well as ICMD calls which can be used to issue IMS commands using the DRA callable interface through ODBA. We use the SYSPRINT data set in the WLM-SPAS to display return codes and reason codes. For production use, you will need to implement better error handling and for every successful APSB call, remember to deallocate the PSB even when an error occurs.

These samples are available for downloading from the same panel describing this redbook on the ITSO Web site at: ibm.com/redbooks

See Appendix C, “Using the additional material” on page 493 for detailed information how to download the samples.

B.1 Putting the ODBA samples onto OS/390 Figure 213 shows the attributes of data sets used in our environment.

Our data set name Dsorg Recfm Lrecl Blksz ------SG245485.SAMPLES.DBRMLIB PO FB 80 27920 SG245485.SAMPLES.JCL * PO FB 80 27920 SG245485.SAMPLES.JCLIMS61 * PO FB 80 27920 SG245485.SAMPLES.LOAD PO U 0 6233 SG245485.SAMPLES.OBJ PO FB 80 27920 SG245485.SAMPLES.SOURCE * PO FB 80 27920 SG245485.SAMPLES.SQL * PO FB 80 27920

Figure 213. Data sets used for ODBA samples

Data sets marked with an asterix can be unzipped and uploaded. The remaining data sets will need to be created manually.

To use the samples provided with this redbook, you must perform the following steps: 1. Download the file 5485ODBA.zip to your PC 2. Unzip the file 3. Transfer (upload) in binary to MVS, with the following attributes for the output data set:

© Copyright IBM Corp. 2001 487 DSORG=PS,RECFM=FB,LRECL=80,BLKSIZE=3200 You can pre-allocate each data set on OS/390 and use the FTP put command with (replace option to upload each file from your. These files were created using the TSO TRANSMIT command. 4. Use the TSO RECEIVE INDA( ) command to create the following PDSs shown in Table 26.

Table 26. Sample ODBA data sets Data set name Content description

SG245485.SAMPLES.JCLIMS61 Copies of members used from our IMS.INSTALIB. This is intended as a guide of what we run

SG245485.SAMPLES.JCL Samples to build stored procedures Miscellaneous utilities we found useful JCL to build our IMS database and IMS control blocks

SG245485.SAMPLES.SOURCE Source code for stored procedures, client programs IMS DBD, PSB source IMS DRA startup table source

SG245485.SAMPLES.SQL Contains DB2 UDB v6 SQL statements to define stored procedures

5. Update SG245485.SAMPLES.JCL(@DEFAULT) with your installation defaults. 6. Update JCL for stored procedure address spaces to include the necessary libraries for ODBA.

B.2 IMS DB samples: GN an ISRT calls The following sections describe the contents of the data sets that contain the IMS DB samples.

488 Cross-Platform DB2 Stored Procedures: Building and Debugging B.2.1 Sample source members Table 27 describes the source code delivered in SG245485.SAMPLES.SOURCE Table 27. ODBA sample source Member Type Descripition

DFSIMSD0 DRA startup Use DFSPRP macro to define DRA startup table for IMSD which table is an IMS v6.1 DBCTL environment where most of our testing took place.

OD0BBMC COB Client Renamed from DSN8EC2, calls OD0BBMS

OD0BBMS COB SP Renamed from DSN8EC1, called by OD0BBMC

OD1CPMS PL/I stored Given startup table name, PSB name, and a flag, connect to IMS; procedures, read a segment and write another segment to be OD1DPMS Given startup table name, PSB name, PCBname, segment name executed by and a flag, connect to IMS; read a segment. This sample is the stored generic enough so that you do not need any of the DBD / PSB procedure from this redbook: you can run it against existing PSBs provided builder. 8.8.2, the PCBs are coded using PCBNAME= or using a label in the “Executing PCB macro. the DB2 OD1EPMSODBA stored Given startup table name, PSB name, a flag, connect to IMS and procedure” on issue a command using ICMD. So far all attempts have resulted page 231 in 104 / 1004 because of the way our security has been set up

SJCDB1 DBD DBD based on IVP HDAM DBD sample member DFSIVD2

SJCPSB Allows PROCOPT=A for all our databases PSB SJCPSBL Allows PROCOPT=LS for all initial load of our databases

If you want to use the DBD and PSB from the samples, refer to 8.12, “Defining IMS resources” on page 274.

B.2.2 Sample SQL members The SQL statements should be modified to suit your installation’s naming convention. Table 28 describes the SQL members delivered in SG245485.SAMPLES.SQL Table 28. ODBA sample SQL members SQL member Descripition

OD1CPMS DB2 V6 SQL statement to create stored procedure OD1CPMS

OD1DPMS DB2 V6 SQL statement to create stored procedure OD1DPMS

Appendix B. DB2 and IMS ODBA samples 489 B.2.3 Sample JCL members Refer to Table 9 on page 215 for jobs that correspond to the IMS IVP for building the test environment. By following that table, you will be able to recreate our test environment.

Table 29 describes the JCL members delivered in SG245485.SAMPLES.JCL as part of this redbook. JCL to build stored procedures have matching names as the source members. Table 29. ODBA sample JCL members JCL member Descripition

OD1$GEN Create necessary IMS database for test programs to work

OD1CPMS Build OD1CPMS

OD1DPMS Build OD1DPMS

B.3 ICMD samples Three samples were developed to show how to invoke ICMD calls in BMP, ODBA and SPI stored procedure

To execute the ICMD sample, we have the following setup: 1. ISIS=2 in PROCLIB member DFSPB* 2. AOIS=S in PROCLIB member DFSPB* to skip security checking for AO programs 3. RCF=N in PROCLIB member DFSPB*

B.3.1 AIB ICMD BMP sample This sample in Table 30 was used to make sure we can execute ICMD calls from BMPs.

Table 30. Sample BMP to show ICMD calls Member name Member type Location Description

AIBCMND PL/I BMP SOURCE

#BMPCOMP JCL JCL JCL to compile AIBCMND

#BMPJOB JCL JCL JCL to execute AIBCMND

490 Cross-Platform DB2 Stored Procedures: Building and Debugging B.3.2 AIB ICMD ODBA sample Table 31 shows the sample OBDA programs. Table 31. Sample ODBA stored procedure to show ICMD calls Member name Member type Location Description

ODBACMD PL/I SOURCE

ODBACOMP JCL JCL JCL to build ODBA program

ODBACMD JCL JCL JCL to execute ICMD calls in ODBA program

B.3.3 AIB ICMD ODBA stored procedure sample Table 32 shows the sample SPI stored procedure. Table 32. Sample SPI stored procedure to show ICMD calls Member name Member type Location Description

SPICMD1 PL/I SOURCE Client

SPICMD2 PL/I SOURCE Stored procedure

SPICMD2 JCL JCL JCL to build stored procedure

SPICMD1 JCL JCL JCL to build client and excute client to invoke ODBA stored procedure to issue ICMD commands

Appendix B. DB2 and IMS ODBA samples 491 492 Cross-Platform DB2 Stored Procedures: Building and Debugging Appendix C. Using the additional material

This redbook also contains additional material in Web material. See the appropriate section below for instructions on using or downloading each type of material.

C.1 Locating the additional material on the Internet The Web material associated with this redbook is available in softcopy on the Internet from the IBM Redbooks Web server. Point your Web browser to:

ftp://www.redbooks.ibm.com/redbooks/SG245485

Alternatively, you can go to the IBM Redbooks Web site at:

ibm.com/redbooks

Select the Additional materials and open the directory that corresponds with the redbook form number.

The Zip file that accompanies this redbook contains all of the sample files referenced within the book.

Figure 214 shows the directory structure used for the samples.

Most of the directories include a readme.txt file, which contains a detailed description of the samples contained within that directory.

Figure 214. Samples tree

© Copyright IBM Corp. 2001 493 C.1.1 Non-DB2 resources This folder contains samples related to CICS and IMS.

These files can be found in directory \Samples\Non-DB2-Resources\DB2SPandCICS \Samples\Non-DB2-Resources\DB2SPandCICS\Bounce \Samples\Non-DB2-Resources\DB2SPandCICS\program preparation for EXCI \Samples\Non-DB2-Resources\DB2SPandCICS\XCOBMS

These files can be found in directory \Samples\Non-DB2-Resources\DB2SPandIMS \Samples\Non-DB2-ResourcesDB2SPandIMS\readme.txt \Samples\Non-DB2-ResourcesDB2SPandIMS\sql.unl \Samples\Non-DB2-ResourcesDB2SPandIMS\jclims61.unl \Samples\Non-DB2-ResourcesDB2SPandIMS\source.unl \Samples\Non-DB2-ResourcesDB2SPandIMS\jcl.unl

C.1.2 SQL stored procedures for AS/400 These files can be found in directory \Samples\SQL-AS400 \Samples\SQL-AS400\SP01L4S.SQL \Samples\SQL-AS400\SP02L4S.SQL \Samples\SQL-AS400\SP03L4S.SQL \Samples\SQL-AS400\SP04L4S.SQL \Samples\SQL-AS400\SP05L4S.SQL \Samples\SQL-AS400\SP06L4S.SQL \Samples\SQL-AS400\SP08L4S.SQL \Samples\SQL-AS400\SP09L4S.SQL \Samples\SQL-AS400\SP11L4S.SQL \Samples\SQL-AS400\SP12L4S.SQL \Samples\SQL-AS400\SP13L4S.SQL \Samples\SQL-AS400\SP14L4S.SQL \Samples\SQL-AS400\SP15L4S.SQL \Samples\SQL-AS400\SP16L4S.SQL \Samples\SQL-AS400\SP17L4S.SQL

494 Cross-Platform DB2 Stored Procedures: Building and Debugging C.1.3 SQL stored procedures for Windows/NT These files can be found in directory \Samples\SQL-NT \Samples\SQL-NT\SP01LNS.SQL \Samples\SQL-NT\SP02LNS.SQL \Samples\SQL-NT\SP03LNS.SQL \Samples\SQL-NT\SP04LNS.SQL \Samples\SQL-NT\SP05LNS.SQL \Samples\SQL-NT\SP06LNS.SQL \Samples\SQL-NT\SP07LNS.SQL \Samples\SQL-NT\SP08LNS.SQL \Samples\SQL-NT\SP09LNS.SQL \Samples\SQL-NT\SP10LNS.SQL \Samples\SQL-NT\SP11LNS.SQL \Samples\SQL-NT\SP12LNS.SQL \Samples\SQL-NT\SP13LNS.SQL \Samples\SQL-NT\SP14LNS.SQL \Samples\SQL-NT\SP15LNS.SQL \Samples\SQL-NT\SP16LNS.SQL \Samples\SQL-NT\SP17LNS.SQL

Note: These sample can be easily ported to the UNIX platform.

C.1.4 SQL stored procedures for OS/390 These files can be found in directory \Samples\SQL-OS390 \Samples\SQL-OS390\SP01LMS.SQL \Samples\SQL-OS390\SP02LMS.SQL \Samples\SQL-OS390\SP03LMS.SQL \Samples\SQL-OS390\SP04LMS.SQL \Samples\SQL-OS390\SP05LMS.SQL \Samples\SQL-OS390\SP06LMS.SQL \Samples\SQL-OS390\SP07LMS.SQL \Samples\SQL-OS390\SP08LMS.SQL \Samples\SQL-OS390\SP09LMS.SQL \Samples\SQL-OS390\SP10LMS.SQL \Samples\SQL-OS390\SP11LMS.SQL \Samples\SQL-OS390\SP12LMS.SQL \Samples\SQL-OS390\SP13LMS.SQL \Samples\SQL-OS390\SP14LMS.SQL \Samples\SQL-OS390\SP15LMS.SQL \Samples\SQL-OS390\SP16LMS.SQL \Samples\SQL-OS390\SP17LMS.SQL

Appendix C. Using the additional material 495 C.2 Using the Web material The additional Web material that accompanies this redbook includes the following: File name Description SG245485Samples.zip Zipped Code for all Samples in the book.

C.2.1 How to use the Web material 1. Download the zip file containing the samples from the IBM Redbooks Web server, as described above. 1. Create a subdirectory (folder) on your workstation and copy the contents of the Web material into this folder. 2. Unzip the sample material into this folder, using PKUNZIP or any other ZIP utility. When you unzip the file, ensure that you select the relevant option to retain the directory structure for the sample files. Refer to Section C.1, “Locating the additional material on the Internet” on page 493 for a detailed listing of the sample files.

496 Cross-Platform DB2 Stored Procedures: Building and Debugging Appendix D. Special notices

This publication is intended to help database administrators implement DB2 Stored Procedures and the Stored Procedures Builder 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 IBM DB2 Stored Procedure Builder and the IBM SQL Procedures Languange for more information about what publications are considered to be product documentation.

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, North Castle Drive, Armonk, NY 10504-1785.

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 use of this information or the implementation of any of these techniques is a customer responsibility and 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

© Copyright IBM Corp. 2001 497 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 pointers in this publication to external Web sites are provided for convenience only and do not in any manner serve as an endorsement of these Web sites.

The following terms are trademarks of the International Business Machines Corporation in the United States and/or other countries: IBM â OS/2 AIX OS/390 AS/400 OS/400 BookManager PA L CICS Parallel Sysplex COBOL/370 QMF DATABASE 2 RACF DataGuide Redbooks DataJoiner Redbooks Logo DataPropagator RETAIN DataRefresher RMF DB2 RS/6000 DB2 Connect S/390 DB2 Extenders SecureWay DB2 Universal Database System/390 DFSMS/MVS VisualAge Distributed Relational Database Visual Warehouse Architecture WebSphere DRDA Wizard Enterprise Storage Server XT IBM.COM 400 Intelligent Miner Lotus Language Environment Domino MQSeries eSuite MVS/ESA Notes Net.Data NetView Netfinity

The following terms are trademarks of other companies:

Tivoli, Manage. Anything. Anywhere.,The Power To Manage., Anything. Anywhere.,TME, NetView, Cross-Site, Tivoli Ready, Tivoli Certified, Planet Tivoli, and Tivoli Enterprise are trademarks or registered trademarks of Tivoli Systems Inc., an IBM company, in the United States, other countries, or both. In Denmark, Tivoli is a trademark licensed from Kjøbenhavns Sommer - Tivoli A/S.

498 Cross-Platform DB2 Stored Procedures: Building and Debugging C-bus is a trademark of Corollary, Inc. in the United States and/or other countries.

Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and/or other countries.

Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the United States and/or other countries.

PC Direct is a trademark of Ziff Communications Company in the United States and/or other countries and is used by IBM Corporation under license.

ActionMedia, LANDesk, MMX, Pentium and ProShare are trademarks of Intel Corporation in the United States and/or other countries.

UNIX is a registered trademark in the United States and other countries licensed exclusively through The Open Group.

SET, SET Secure Electronic Transaction, and the SET Logo are trademarks owned by SET Secure Electronic Transaction LLC.

Other company, product, and service names may be trademarks or service marks of others.

Appendix D. Special notices 499 500 Cross-Platform DB2 Stored Procedures: Building and Debugging 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 IBM Redbooks For information on ordering these publications see “How to get IBM Redbooks” on page 505. • Database Recovery Control (DBRC) Examples and Usage Hints, SG24-3333 • DB2 UDB Server for OS/390 Version 6 - Technical Update, SG24-6108 • The IMS Primer, SG24-5352 • DB2 UDB Server for OS/390 Version 6 and Continuous Availability, SG24-5486 • DB2 Java Stored Procedures - Learning by Example, SG24-5945

E.2 IBM Redbooks collections Redbooks are also available on the following CD-ROMs. Click the CD-ROMs button at ibm.com/redbooks for information about all the CD-ROMs offered, updates and formats. CD-ROM Title Collection Kit Number IBM System/390 Redbooks Collection SK2T-2177 IBM Networking Redbooks Collection SK2T-6022 IBM and Data Management Redbooks Collection SK2T-8038 IBM Lotus Redbooks Collection SK2T-8039 Tivoli Redbooks Collection SK2T-8044 IBM AS/400 Redbooks Collection SK2T-2849 IBM Netfinity Hardware and Software Redbooks Collection SK2T-8046 IBM RS/6000 Redbooks Collection SK2T-8043 IBM Application Development Redbooks Collection SK2T-8037 IBM Enterprise Storage and Systems Management Solutions SK3T-3694

E.3 Other resources These publications are also relevant as further information sources: • DB2 UDB for OS/390 Version 6 What’s New, GC26-9017-02

© Copyright IBM Corp. 2001 501 • DB2 UDB for OS/390 Version 6 Application Programming and SQL Guide, SC26-9004 • DB2 UDB for OS/390 Version 6 SQL Reference, SC26-9014-01 • DB2 UDB for OS/390 Version 6 Administration Guide, SC26-9003-01 • DB2 UDB for OS/390 Version 6 Installation Guide, SC26-9008-01 • DB2 UDB for OS/390 Version 6 Command Reference, SC26-9006-01 • DB2 UDB for OS/390 Version 6 Utility Guide and Reference, SC26-9015-01 • DB2 UDB for OS/390 Version 6 ODBC Guide and Reference, SC26-9005-01 • DB2 UDB for OS/390 Version 6 Application Programming and SQL Guide, SC26-9004-01 • DB2 UDB for OS/390 Version 6 Messages and Codes, SC26-9011-01 • OS/390 V2R8.0 MVS Planning: Workload Management, GC28-1761-09 • OS/390 WLM refer to OS/390 MVS Workload Management Services: GC28-1773 • OS/390 V2R8 MVS Programming: Resource Recovery, GC28-1739-07 • DB2 UDB Installation and Configuration Supplement V6, GC09-2857 • DB2 UDB Application Building Guide V6, SC09-2842 • DB2 UDB Version 6 Application Development Guide, SC09-2845 • CICS: Transaction Server for OS/390: CICS External Interfaces Guide, SC33-1944 • Debug Tool User's Guide and Reference, SC09-2137 • IMS/ESA Version 6 Application Programming: Database Manager, SC26-8727 • IMS/ESA Version 6 Application Programming: Design Guide, SC26-8728 • IMS/ESA Version 6 Release Planning Guide, GC26-8744 • IMS/ESA Version 6 Installation Volume 1: Installation and Verification, GC26-8736 • IMS/ESA Version 6 Installation Volume 2: System Definition and Tailoring, GC26-8737 • IMS/ESA Version 6 Operator ‘s Reference, SC26-8742 • IMS/ESA Version 6 Administration Guide: System, SC26-8730

502 Cross-Platform DB2 Stored Procedures: Building and Debugging • IMS Version 7 Application Programming: Database Manager, SC26-9422 • IMS Version 7 Failure Analysis and Structure Tables (FAST) for Dump Analysis, LY37-3739

E.4 Referenced Web sites These Web sites are also relevant as further information sources: • http://www.software.ibm.com/data/db2/ DB2 family • http://www.software.ibm.com/data/db2/os390/ DB2 for OS/390 • http://www.ibm.com/software/db2os390/downloads.html DB2 downloads • http://service.software.ibm.com/db2/support/dbssup.html DB2 software updates • http://www-4.ibm.com/software/data/db2/java/ The most recent material about using Java with DB2 • http://www.s390.ibm.com/oe/ OS/390 Unix System Services home page • http://www.rs6000.ibm.com/cgi-bin/ds_form?config=/usr/share/man/info/ en_US/a_doc_lib/data/base.cfg AIX documentation; many commands also work in UNIX System Services • http://www.sqlj.org SQLJ home page • http://www.ibm.com/s390/corner/ Java on S/390 • http://www.ibm.com/solutions/businessintelligence/teraplex/index.html Teraplex Center • http://java.sun.com/beans/infobus Info on Java

Appendix E. Related publications 503 504 Cross-Platform DB2 Stored Procedures: Building and Debugging How to get IBM Redbooks

This section explains how both customers and IBM employees can find out about IBM Redbooks, redpieces, and CD-ROMs. A form for ordering books and CD-ROMs by fax or e-mail is also provided. • Redbooks Web Site ibm.com/redbooks Search for, view, download, or order hardcopy/CD-ROM Redbooks from the Redbooks Web site. Also read redpieces and download additional materials (code samples or diskette/CD-ROM images) from this Redbooks site. 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. • E-mail Orders Send orders by e-mail including information from the IBM Redbooks fax order form to: e-mail address In United States or Canada [email protected] Outside North America Contact information is in the “How to Order” section at this site: http://www.elink.ibmlink.ibm.com/pbl/pbl • Telephone Orders United States (toll free) 1-800-879-2755 Canada (toll free) 1-800-IBM-4YOU Outside North America Country coordinator phone number is in the “How to Order” section at this site: http://www.elink.ibmlink.ibm.com/pbl/pbl • Fax Orders United States (toll free) 1-800-445-9269 Canada 1-403-267-4455 Outside North America Fax phone number is in the “How to Order” section at this site: http://www.elink.ibmlink.ibm.com/pbl/pbl

This information was current at the time of publication, but is continually subject to change. The latest information may be found at the Redbooks Web site.

IBM Intranet for Employees IBM employees may register for information on workshops, residencies, and Redbooks by accessing the IBM Intranet Web site at http://w3.itso.ibm.com/ and clicking the ITSO Mailing List button. Look in the Materials repository for workshops, presentations, papers, and Web pages developed and written by the ITSO technical professionals; click the Additional Materials button. Employees may access MyNews at http://w3.ibm.com/ for redbook, residency, and workshop announcements.

© Copyright IBM Corp. 2001 505 IBM Redbooks fax order form

Please send me the following: Title Order Number Quantity

First name Last name

Company

Address

City Postal code Country

Telephone number Telefax number VAT number

Invoice to customer number

Credit card number

Credit card expiration date Card issued to Signature

We accept American Express, Diners, Eurocard, Master Card, and Visa. Payment by credit card not available in all countries. Signature mandatory for credit card payment.

506 Cross-Platform DB2 Stored Procedures: Building and Debugging Glossary

The following terms and abbreviations are AFC See Application Foundation Classes. defined as they are used in the DB2 library. If AIB See application interface block. you do not find the term you are looking for, refer to the index or to IBM Dictionary of allied address space. An area of storage Computing. Also, it brings term and external to DB2 that is connected to DB2 and is abbreviations related to Java and other therefore capable of requesting DB2 services. products, mentioned in this book. American National Standards Institute (ANSI). An organization consisting of A producers, consumers, and general interest abstract class A class that provides common groups, that establishes the procedures by information for subclasses, and therefore which accredited organizations create and cannot be instantiated. Abstract classes provide maintain voluntary industry standards in the at least one abstract method. United States. abstract method A method with a signature, ANSI. American National Standards Institute. but no implementation. You provide the API See Application Program Interface. implementation of the method in the subclass of the abstract class that contains the abstract applet A Java program designed to run within method. a Web browser. Contrast with application. abstract window toolkit (AWT) The Abstract application. (1) A program or set of programs Window Toolkit API provides a layer between that perform a task; for example, a payroll the application and the host’s windowing application. (2) In Java programming, a system. It enables programmers to port Java self-contained, stand-alone Java program that applications from one window system to includes a static main method. It does not another. The AWT provides access to basic require an applet viewer. Contrast with applet. interface components such as events, color, Application Foundation Classes (AFCs) fonts, and controls such as button, scroll bars, Microsoft’s version on the Java Foundation text fields, frames, windows, dialogs, panels, Classes (JFCs). AFCs deliver similar functions canvases, and check boxes. to JFCs but only work on Windows 32-bit actual parameter list Parameters specified in platforms. a call to a method. See also formal parameter application interface block (AIB). A control list. block used for IMS DL/I calls. It is allocated by address space. A range of virtual storage the application and passed to AERTDLI. pages identified by a number (ASID) and a Applications which use this are either issuing collection of segment and page tables which calls using a PCB name instead of a PCB map the virtual pages to real pages of the address, or are using calls which are not computer's memory. associated with a PCB. address space connection. The result of application plan. The control structure connecting an allied address space to DB2. produced during the bind process and used by Each address space containing a task DB2 to process SQL statements encountered connected to DB2 has exactly one address during statement execution. space connection, even though more than one application program interface (API). A task control block (TCB) can be present. See functional interface supplied by the operating allied address space and task control block. system or by a separately orderable licensed

© Copyright IBM Corp. 2001 507 program that allows an application program page in the class browser that provides bean written in a high-level language to use specific information. data or functions of the operating system or binary large object (BLOB). See BLOB. licensed program. bind. The process by which the output from the application requester (AR). See requester. DB2 precompiler is converted to a usable control AR. application requester. See requester. structure called a package or an application plan. During the process, access paths to the data are AS. application server. selected and some authorization checking is ASCII (1) American Standard Code for performed. Information Interchange.A standard assignment automatic bind. (More correctly automatic of 7-bit numeric codes to characters. See also rebind). A process by which SQL statements are Unicode. (2) An encoding scheme used to bound automatically (without a user issuing a represent strings in many environments, typically BIND command) when an application process on PCs and workstations. Contrast with begins execution and the bound application plan EBCDIC. or package it requires is not valid. attachment facility. An interface between DB2 dynamic bind. A process by which SQL and TSO, IMS, CICS, or batch address spaces. statements are bound as they are entered. An attachment facility allows application programs to access DB2. incremental bind. A process by which SQL authorization ID. A string that can be verified for statements are bound during the execution of an connection to DB2 and to which a set of application process, because they could not be privileges are allowed. It can represent an bound during the bind process, and individual, an organizational group, or a function, VALIDATE(RUN) was specified. but DB2 does not determine this representation. static bind. A process by which SQL statements AWT See Abstract Window Toolkit. are bound after they have been precompiled. All static SQL statements are prepared for execution B at the same time. Contrast with dynamic bind. base table. (1) A table created by the SQL BLOB. A sequence of bytes, where the size of CREATE TABLE statement that is used to hold the sequence ranges from 0 bytes to 2 GB - 1. persistent data. Contrast with result table and Such a string does not have an associated temporary table. (2) A table containing a LOB CCSID. The size of binary large object values column definition. The actual LOB column data is can be anywhere up to 2 GB - 1. not stored along with the base table. The base browser (1) In VisualAge for Java, a window table contains a row identifier for each row and that provides information on program elements. an indicator column for each of its LOB columns. There are browsers for projects, packages, Contrast with auxiliary table. classes, methods, and interfaces. (2) An base type In Java, a type establishes an Internet-based too that lets users browse Web interface to anything inherited from itself. See sites. type, derived type. built-in function. A function that is supplied by bean A definition or instance of a JavaBeans DB2. Contrast with user-defined function. component. See JavaBeans. business object (1) An object that represents BeanInfo (1) A Java class that provides explicit a business function. Business objects contain information about the properties, events, and attributes that define the state of the object, and methods of a bean class. (2) In the VisualAge for methods that define the behavior of the object. A Java Integrated Development Environment, a business object also has relationships with other

508 Cross-Platform DB2 Stored Procedures: Building and Debugging business objects. Business objects can be used CCTL See coordinator controller in combination to perform a desired task. Typical character large object (CLOB). See CLOB. examples of business objects are Customer, Invoice, or Account. (2) In the Enterprise Access class An encapsulated collection of data and Builder, a class that implements the methods to operate on the data. A class may be IBusinessObject interface. Business objects are instantiated to produce an object that is an used to map interactions with an existing home. instance of the class. bytecode Machine-independent code class hierarchy The relationships between generated by the Java compiler and executed by classes that share a single inheritance. All Java the Java interpreter. classes inherit from the Object class. C class method Methods that apply to the class as a whole rather than its instances (also called a CAF. Call attachment facility. static method). call attachment facility (CAF). A DB2 class path When running a program in attachment facility for application programs VisualAge for Java, a list of directories and JAR running in TSO or MVS batch. The CAF is an files that contain resource files or Java classes alternative to the DSN command processor and that a program can load dynamically at run time. allows greater control over the execution A program's class path is set in its Properties environment. notebook. call level interface (CLI). A callable application CLASSPATH In your deployment environment, program interface (API) for database access, the environment variable keyword that specifies which is an alternative to using embedded SQL. the directories in which to look for class and In contrast to embedded SQL, DB2 CLI does not resource files. require the user to precompile or bind applications, but instead provides a standard set class variable Variables that apply to the class of functions to process SQL statements and as a whole rather than its instances (also called a related services at run time. static field). cast function. A function used to convert CLI. See call level interface. instances of a (source) data type into instances client. (1)A networked computer in which the of a different (target) data type. In general, a cast IDE is connected to a repository on a team function has the name of the target data type. It server. (2) See requester. has one single argument whose type is the source data type; its return type is the target data CLOB. A sequence of bytes representing type. single-byte characters or a mixture of single and double-byte characters where the size can be up casting Explicitly converting an object or to 2 GB - 1. Although the size of character large primitive’s data type. object values can be anywhere up to 2 GB - 1, in catalog. In DB2, a collection of tables that general, they are used whenever a character contains descriptions of objects such as tables, string might exceed the limits of the VARCHAR views, and indexes. type. catalog table. Any table in the DB2 catalog. codebase An attribute of the tag that provides the relative path name for the C++ Access Builder A VisualAge fro Java, classes. Use this attribute when your class files Enterprise Edition tool that generates beans and reside in a different directory than your HTML C++ wrappers that let your Java programs files. access C++ DLLs.

509 column function. An SQL operation that derives components that represents the relationship its result from a collection of values across one or between the components. Each connection has a more rows. Contrast with scalar function. source, a target, and other properties. commit. The operation that ends a unit of work connection handle. The data object that by releasing locks so that the database changes contains information associated with a made by that unit of work can be perceived by connection managed by DB2 CLI. This includes other processes. general status information, transaction status, and diagnostic information. Common Connector Framework In the Enterprise Access Builder, interface and class Console In VisualAge for Java, the window that definitions that provide a consistent means of acts as the standard input (System.in) and interacting with enterprise resources (for standard output (System.out) device for example, CICS and Encina transactions) from programs running in the VisualAge for Java any Java execution environment. environment. constructor A method called to set up a new instance of a class. Common Object Request Broker Architecture (CORBA) Common Object Request Broker constant. A language element that specifies Architecture. A specification produced by the anunchanging value. Constants are classified as Object Management Group (OMG) that presents string constants or numeric constants. Contrast standards for various types of object request with variable. brokers (such as client-resident ORBs, container A component that can hold other server-based ORBs, system-based ORBs, and components. In Java, examples of containers library-based ORBs). Implementation of CORBA include applets, frames, and dialogs. In the standards enables object request brokers from Visual Composition Editor, containers can be different software vendors to interoperate. graphically represented and generated. Common RFC Interface for Java A set of context. The application's logical connection to Java interfaces and classes that defines a the data source and associated internal DB2 middleware-independent layer to access R/3 ODBC connection information that allows the systems from Java. If applications are built on top application to direct its operations to a data of this interface, they can leverage different source. A DB2 ODBC context represents a DB2 middleware at run time without recoding. The thread. generated beans are based on this interface and provide the same flexibility. cookie (1) A small file stored on an individual's computer; this file allows a site to tag the browser common server. Describes the set of DB2 with a unique identification. When a person visits products that run on various platforms and have a site, the site's server requests a unique ID from the same source code. These platforms include the person's browser. If this browser does not OS/2, Windows, and UNIX. have an ID, the server delivers one. On the component model An architecture and an API Wintel platform, the cookie is delivered to a file that allows developers to define reusable called'cookies.txt,' and on a Macintosh platform, segments of code that can be combined to create it is delivered to 'MagicCookie.' Just as someone a program. VisualAge for Java uses the can track the origin of a phone call with Caller ID, JavaBeans component model. companies can use cookies to track information about behavior. (2) Persistent data stored by the composite bean A bean that can contain both client in the Servlet Builder. visual and nonvisual components. A composite bean is composed of embedded beans. coordinator controller (CCTL) A subsystem consisting of the database resource adapter connection In the VisualAge for Java Visual (DRA) and a transaction management Composition Editor, a visual link between two subsystem, such as CICS. A CCTL provides

510 Cross-Platform DB2 Stored Procedures: Building and Debugging communications and transaction management DB2 thread. The DB2 structure that describes services for a DBCTL environment, which has no an application's connection, traces its progress, transaction management facilities of its own. processes resource functions, and delimits its accessibility to DB2 resources. and services. CORBA Common Objects Request Broker Architecture. debugger A component that assists in analyzing and correcting coding errors. Core API Part of the minimal set of APIs that form the standard Java Platform. Core APIs are declaration Statement that creates an available on the Java Platform regardless of the identifier and its attributes, but does not reserve underlying operating system. The Core API storage or provide an implementation. grows with each release of the JDK; the current definition Statement that reserves storage or core API is based on JDK 1.1. Also called core provides an implementation. classes. deprecation An obsolete component that may cursor. A named control structure used by an be deleted from a future version of a product. application program to point to a row of interest within some set of rows, and to retrieve rows from derived type In Java, a type that overrides the the set, possibly making updates or deletions. definitions of a base type to provide unique behavior. The derived type extends the base D type. Data Access Bean In the VisualAge for Java dipping A metaphor, introduced by Visual Composition Editor, a bean that accesses BeanExtender on alphaWorks, for modifying a and manipulates the content of component by hooking a special kind of Java JDBC/ODBC-compliant relational databases. bean onto it. Dipping lets you add new behavior or modify the Java bean's existing behavior Data Access Builder A VisualAge for Java without having to manipulate the Java bean's Enterprise tool that generates beans to access code. A dip is a special kind of Java bean that and manipulate the content of can be hooked on to another Java bean; it is the JDBC/ODBC-compliant relational databases. new feature you want to add to the component. database management system (DBMS). A Software examples of dips include printing and software system that controls the creation, security. Dippable Java beans can have one or organization, and modification of a database and more dips connected to them. Almost any Java access to the data stored within it. bean or class can be made dippable by extending it, a process called morphing. data source. A local or remote relational or non-relational data manager that is capable of dip A special kind of Java bean that can be supporting data access via an ODBC driver which hooked on to another Java bean; the new feature supports the ODBC APIs. In the case of DB2 for you want to add to the component. Software OS/390, the data sources are always relational examples of dips include printing and security. database managers. distributed processing Processing that takes DBCLOB. A sequence of bytes representing place across two or more linked systems. double-byte characters where the size can be up distinct type. A user-defined data type that is to 2 gigabytes. Although the size of double-byte internally represented as an existing type (its character large object values can be anywhere source type), but is considered to be a separate up to 2 gigabytes, in general, they are used and incompatible type for semantic purposes. whenever a double-byte character string might exceed the limits of the VARGRAPHIC type. distributed relational database architecture (DRDA). A connection protocol for distributed DBMS. Database management system. relational database processing that is used by

511 IBM's relational database products. DRDA e-commerce The subset of e-business that includes protocols for communication between an involves the exchange of money for goods or application and a remote relational database services purchased over an electronic medium management system, and for communication such as the Internet. between relational database management EmbeddedJava An API and application systems. environment for high-volume embedded devices, DLL (dynamic link library) A file containing such as mobile phones, pagers, process control, executable code and data bound to a program at instrumentation, office peripherals, network load time or run time, rather than during linking. routers and network switches. EmbeddedJava The code and data in a dynamic link library can applications run on real-time operating systems be shared by several applications simultaneously. and are optimized for the constraints of The DLLs. Enterprise Access Builders also small-memory footprints and diverse visual generate platform-specific DLLs for the displays. workstation and OS/390 platforms. embedded SQL. SQL statements coded within double-byte character large object (DBCLOB). an application program. See static SQL. See DBCLOB. encapsulation The grouping of both data and double precision A floating-point number that operations into neat, manageable units that can contains 64 bits. See also single precision. be developed, tested, and maintained independently of one another. Such grouping is a DRDA. Distributed relational database powerful technique for building better software. architecture. The object manages its own resources and limits dynamic SQL. SQL statements that are their visibility. prepared and executed within an application enclave. In Language Environment for MVS & program while the program is executing. In VM, an independent collection of routines, one of dynamic SQL, the SQL source is contained in which is designated as the main routine. An host language variables rather than being coded enclave is similar to a program or run unit. into the application program. The SQL statement can change several times during the application Enterprise Access Builder (EAB) Feature of program's execution. Visual Age for Java, Enterprise Edition, that creates connectors to enterprise server products E such as CICS, Encina, IMS TOC, and MQSeries. Enterprise Edition See VisualAge for Java, EBCDIC. Extended binary coded decimal Enterprise Edition. interchange code. An encoding scheme used to represent character data in the MVS, VM, VSE, Enterprise Java Includes Enterprise and OS/400Ñ environments. Contrast with JavaBeans as well as open API specifications for: ASCII. database connectivity, naming and directory services, CORBA/IIOP interoperability, pure Java EAB See Enterprise Access Builder. distributed computing, messaging services, e-business Either (a) the transaction of managing system and network resources, and business over an electronic medium such as the transaction services. Internet or (b) a business that uses Internet Enterprise JavaBeans A cross-platform technologies and network computing in their component architecture for the development and internal business processes (via intranets), their deployment of multi-tier, distributed, scalable, business relationships (via extranets), and the object-oriented Java applications. buying and selling of goods, services, and information (via electronic commerce.) Enterprise ToolKit A set of VisualAge for Java Enterprise tools that enable you to develop Java

512 Cross-Platform DB2 Stored Procedures: Building and Debugging code that is targeted to specific platforms, such field A data object in a class; for example, a as AS/400, OS/390, OS/2, AIX, and Windows. variable. Entry Edition See VisualAge for Java, Entry first tier The client; the hardware and software Edition. with which the end user interacts. equi-join. A join operation in which the framework A set of object classes that provide join-condition has the form expression = a collection of related functions for a user or expression. piece of software. event An action by a user, program, or system free-form surface In the VisualAge for Java that may trigger specific behavior. In the JDK, Visual Composition Editor, the large, open area events notify the relevant listener classes to take where you can work with visual and nonvisual appropriate action. beans. You add, remove, and connect beans on the free-form surface. environment. A collection of names of logical and physical resources that are used to support File Transfer Protocol (FTP) In the Internet the performance of a function. suite of protocols, an application layer protocol that uses TCP and Telnet services to transfer environment handle. In DB2 ODBC, the data bulk-data files between machines or hosts. object that contains global information regarding the state of the application. An environment foreign key. A key that is specified in the handle must be allocated before a connection definition of a referential constraint. Because of handle can be allocated. Only one environment the foreign key, the table is a dependent table. handle can be allocated per application. The key must have the same number of columns, with the same descriptions, as the primary key of exception An exception is an object that has the parent table. caused some sort of new condition, such as an error. In Java, throwing an exception means form data A generated class representing the passing that object to an interested party; a HTML form elements in a visual servlet. signal indicates what kind of condition has taken formal parameter list Parameters specified in place. Catching an exception means receiving a method's definition. See also actual parameter the sent object. Handling this exception usually list. means taking care of the problem after receiving the object, although it might mean doing nothing FTP See File Transfer Protocol. (which would be bad programming practice). full outer join. The result of a join operation that executable content Code that runs from within includes the matched rows of both tables being an HTML file (such as an applet). joined and preserves the unmatched rows of both tables. See also join. extends A subclass or interface extends a class or interface if it add fields or methods, or function. A specific purpose of an entity or its overrides its methods. See also derived type. characteristic action such as a column function or scalar function. (See column function and scalar external function. A function for which the body function.). Furthermore, functions can be is written in a programming language that takes user-defined, built-in, or generated by DB2. (See scalar argument values and produces a scalar built-in function, cast function, user-defined result for each invocation. Contrast with sourced function, external function, sourced function.) function and built-in function. F G garbage collection Java's ability to clean up factory A bean that dynamically creates inaccessible unused memory areas ("garbage") instances of beans. on the fly. Garbage collection slows performance,

513 but keeps the machine from running out of development environment. The IDL Development memory. Environment allows you to work with IDL source code in the multipane IDLs page and generate Graphical User Interface (GUI) A type of Java code using an IDL-to-Java compiler. computer interface consisting of a visual metaphor of a real-world scene, often of a IDL group A container used to hold IDL objects desktop. Within that scene are icons, in the IDL Development Environment. It is similar representing actual objects, that the user can to a file system directory. access and manipulate with a pointing device. IIOP (Internet Inter-ORB Protocol) A H communications standard for distributed objects that reside in Web or enterprise computing handle. In DB2 CLI, a variable that refers to a environments. data structure and associated resources. See InfoBus A technology for flexible, statement handle, connection handle, and vendor-independent data exchange which is used environment handle. by eSuite and can be used by other applications hierarchy The order of inheritance in to exchange data with eSuite and other object-oriented languages. Each class in the InfoBus-enabled applications. The 100% Pure hierarchy inherits attributes and behavior from its Java release and the InfoBus specification are superclass, except for the top-level Object class. available for free download from: http://java.sun.com/beans/infobus HotJava A Java-enabled Web and intranet browser developed by Sun Microsystems, Inc. inheritance The ability to create a subclass HotJava is written in Java. (Definition copyright that automatically inherits properties and 1996-1999 Sun Microsystems, Inc. All Rights methods from its superclass. See also hierarchy. Reserved. Used by permission.) initialization file. For DB2 ODBC applications, a Hypertext Markup Language (HTML) A file file containing values that can be set to adjust the format, based on SGML, for hypertext documents performance of the database manager. on the Internet. Allows for the embedding of inner join. The result of a join operation that images, sounds, video streams, form fields and includes only the matched rows of both tables simple text formatting. References to other being joined. See also join. objects are embedded using URLs, enabling readers to jump directly to the referenced Inspector In VisualAge for Java, a window in document. which you can evaluate code fragments in the context of an object, look at the entire contents of Hypertext Transfer Protocol (HTTP) The an object and its class, or access and modify the Internet protocol, based on TCP/IP, used to fetch fields of an object. hypertext objects from remote hosts. instance The specific representation of a I class, also called an object. IDE See Integrated Development Environment. instance method A method that applies and operates on objects (usually called simply a identifier The name of an item in a program. method). Contrast with class method. IDL (Interface Definition Language) In instance variable A variable that defines the CORBA, a declarative language that is used to attributes of an object. The class defines the describe object interfaces, without regard to instance variable's type and identifier, but the object implementation. object sets and changes its values. IDL Development Environment In VisualAge Integrated Development Environment (IDE) for Java, an integrated IDL and Java In VisualAge for Java, the set of windows that

514 Cross-Platform DB2 Stored Procedures: Building and Debugging provide the user with access to development Machines for various platforms, the tools. The primary windows are the Workbench, object-oriented Java programming language, and Log, Console, Debugger, and Repository several class libraries. Explorer. Java Application Environment (JAE) The interface A list of methods that enables a class source code release of the Java (TM) to implement the interface itself by using the Development Kit. (Definition copyright 1996-1999 implements keyword. The Interfaces page in the Sun Microsystems, Inc. All Rights Reserved. Workbench lists all interfaces in the workspace. Used by permission.) Internet Protocol (IP) In the Internet suite of Java Development Kit (JDK) The Java protocols, a connectionless protocol that routes Development Kit is the set of Java technologies data through a network or interconnected made available to licensed developers by Sun networks. IP acts as an intermediary between the Microsystems. Each release of the JDK contains higher protocol layers and the physical network. the following: the Java Compiler, Java Virtual However, this protocol does not provide error Machine, Java Class Libraries, Java Applet recovery and flow control and does not guarantee Viewer, Java Debugger, and other tools. the reliability of the physical network. Java Foundation Classes (JFC) Developed Internet Inter-ORB Protocol (IIOP) Access by Netscape, Sun, and IBM, JFCs are building Builder A tool that edits and generates blocks that are helpful in developing interfaces to CORBA-compliant Java modules. See Common Java applications. They allow Java applications Object Request Broker Architecture (CORBA). to interact more completely with the existing operating systems. Also called Swing Set. interpreter A tool that translates and executes code line-by-line. Java IDL Java IDL is a language-neutral way to specify an interface between an object and its introspection For a JavaBean to be reusable client on a different platform. Provides in development environments, there needs to be interoperability and integration with CORBA, the a way to query what the bean can do in terms of industry standard for distributed computing, the methods it supports and the types of event it allowing developers to build Java applications raises and listens for. Introspection allows a that are integrated with heterogeneous business builder tool to analyze how a bean works. information assets. IP See Internet Protocol. Java Management Application Programming J Interface (JMAPI) A specification proposed by Sun Microsystems that defines a core set of JAE See Java Application Environment. application programming interfaces for JAR file format JAR (Java Archive) is a developing tightly integrated system, network, platform-independent file format that aggregates and service management applications. The many files into one. Multiple Java applets and application programming interfaces could be their requisite components (.class files, images, used in diverse computing environments that sounds and other resource files) can be bundled encompass many operating systems, in a JAR file and subsequently downloaded to a architectures, and network protocols. browser in a single HTTP transaction. Java Media and Communications APIs Java An object-oriented programming Allows developers to integrate a wide range of language for portable, interpretive code that media types into their Web pages, applets, and supports interaction among remote objects. Java applications. Includes: Media, Sound, Animation, was developed and specified by Sun 2D, 3D, Telephony, Speech and Collaboration. Microsystems, Incorporated. The Java Java Media Framework (JMF) Java Media environment consists of the JavaOS, the Virtual Framework API specifies a unified architecture,

515 messaging protocol and programming interface Microsystems, Inc. All Rights Reserved. Used by for media players, capture and conferencing. JMF permission.) provides a set of building blocks useful by other Java Security API A framework for developers areas of the Java Media API suite. For example, to include security functionality in their applets the JMF provides access to audio devices in a and applications. Includes: cryptography with cross-platform, device-independent manner, digital signatures, encryption, and authentication. which is required by both the Java Telephony and An intermediate subset of the Security API known the Java Speech APIs. JMF will be published as as "Security and Signed Applets" is included in three APIs: the Java Media Player, Java Media JDK 1.1. Capture, and Java Media Conference. Java Server An extensible framework that Java Naming and Directory Interface (JNDI) enables and eases the development of A set of APIs that assist with the interfacing to Java-powered Internet and intranet servers. The multiple naming and directory services. APIs provide uniform and consistent access to (Definition copyright 1996-1999 Sun the server and administrative system resources Microsystems, Inc. All Rights Reserved. Used by required for developers to quickly develop their permission.) own Java servers. Java Native Interface (JNI) A native Java Virtual Machine (JVM) A software programming interface that allows Java code implementation of a central processing unit running inside a Java Virtual Machine (VM) to (CPU) that runs compiled Java code (applets and interoperate with applications and libraries written applications). in other programming languages, such as C and C++. JavaBeans Java's component architecture, developed by Sun, IBM, and others. The Java Platform The Java Virtual Machine and components, called Java beans, can be parts of the Java Core classes make up the Java Java programs, or they can exist as Platform. The Java Platform provides a uniform self-contained applications. Java beans can be programming interface to a 100%. Pure Java assembled to create complex applications, and program regardless of the underlying operating they can run within other component system. (Definition copyright 1996-1999 Sun architectures (such as ActiveX and OpenDoc). Microsystems, Inc. All Rights Reserved. Used by permission.) JavaDoc Sun's tool for generating HTML documentation on classes by extracting Java Record Editor An editor that allows you comments from the Java source code files. to construct and refine dynamic record types. JDBC (Java Database Connectivity) In the Java Record Framework A Java framework JDK, the specification that defines an API that that describes and converts record data. enables programs to access databases that Java Remote Method Invocation (RMI) Java comply with this standard. Remote Method Invocation is method invocation JavaObjs In Remote Method Invocation, the between peers, or between client and server, name of the user-defined default file that contains when applications at both ends of the invocation a list of server objects to be instantiated when the are written in Java. Included in JDK 1.1. Remote Object Instance Manager is started. Java Runtime Environment (JRE) A subset of JavaOS A basic, small-footprint operating the Java Development Kit for end-users and system that supports Java. Java OS was developers who want to redistribute the JRE. The originally designed to run in small electronic JRE consists of the Java Virtual Machine, the devices like phones and TV remotes, but it is also Java Core Classes, and supporting files. being targeted for use in network computers (Definition copyright 1996-1999 Sun (NCs).

516 Cross-Platform DB2 Stored Procedures: Building and Debugging JavaScript A scripting language used within an or a mixture of single and double-byte characters. HTML page. Superficially similar to Java but A LOB can be up to 2GB -1 byte in length. See JavaScript scripts appear as text within the HTML also BLOB, CLOB, and DBCLOB. page. Java applets, on the other hand, are LOB locator. A mechanism that allows an programs written in the Java language and are application program to manipulate a large object called from within HTML pages or run as value in the database system. A LOB locator is a stand-alone applications. fullword integer value that represents a single JFC See Java Foundation Classes. LOB value. An application program retrieves a LOB locator into a host variable; it can then apply JIT See Just-In-Time Compiler. SQL operations to the associated LOB value JMF See Java Media Framework. using the locator. JNDI See Java Naming and Directory Interface. local. Refers to any object maintained by the JNI See Java Native Interface. local DB2 subsystem. A local table, for example, is a table maintained by the local DB2 JRE See Java Runtime Environment. subsystem. Contrast with remote. Just-In-Time compiler (JIT) A local variable A variable declared and used platform-specific software compiler often within a method or block. contained within JVMs. JITs compile Java bytecodes on-the-fly into native machine Log In the VisualAge for Java IDE, the window instructions, thereby reducing the need for that displays messages and warnings during interpretation. development. JVM See Java Virtual Machine. M L member In the Java language, an item belonging to a class, such as a field or method. large object (LOB). See LOB. method A fragment of Java code within a class left outer join. The result of a join operation that that can be invoked and passed a set of includes the matched rows of both tables being parameters to perform a specific task. joined, and preserves the unmatched rows of the first table. See also join. middleware A layer of software that sits between a database client and a database link-edit. To create a loadable computer server, making it easier for clients to connect to program using a linkage editor. heterogeneous databases. linker A computer program for creating load middle tier The hardware and software that modules from one or more object modules or load resides between the client and the enterprise modules by resolving cross references among server resources and data. The software includes the modules and, if necessary, adjusting a Web server that receives requests from the addresses. In Java, the linker creates an client and invokes Java servlets to process these executable from compiled classes. requests. The client communicates with the Web listener In the JDK, a class that receives and server via industry standard protocols such as handles events. HTTP and IIOP. load module. A program unit that is suitable for morphing The process of extending a Java loading into main storage for execution. The bean to accept dips. Morphed Java beans are output of a linkage editor. called dippable Java beans and can have one or more dips connected to them. Almost any Java LOB. A sequence of bytes representing bit data, bean or class can be made dippable. See single-byte characters, double-byte characters, dipping.

517 multithreaded A program where different parts null. A special value that indicates the absence can run at the same time without interfering with of information. each other. NUL-terminated host variable. A multithreading. Multiple TCBs executing one varying-length host variable in which the end of copy of DB2 ODBC code concurrently (sharing a the data is indicated by the presence of a NUL processor) or in parallel (on separate central terminator. processors). NUL terminator. In C, the value that indicates mutex. Pthread mutual exclusion; a lock. A the end of a string. For character strings, the NUL Pthread mutex variable is used as a locking terminator is X'00'. mechanism to allow serialization of critical sections of code by temporarily blocking the O execution of all but one thread. object The principal building block of MVS/ESA. Multiple Virtual Storage/Enterprise object-oriented programs. Objects are software Systems Architecture. programming modules. Each object is a programming unit consisting of related data and N methods. native class Machine-dependent C code that ODBC. See Open Database Connectivity. can be invoked from Java. For multi-platform ODBC driver. A dynamically-linked library (DLL) work, the native routines for each platform need that implements ODBC function calls and to be implemented. interacts with a data source. NCF See Network Computing Framework. Open Database Connectivity (ODBC). A Network Computing Framework (NCF) An Microsoft database application programming architecture and programming model created to interface (API) for C that allows access to help customer and industry software database management systems by using callable development teams to design, deploy, and SQL. ODBC does not require the use of an SQL manage e-business solutions across the preprocessor. In addition, ODBC provides an enterprise. architecture that lets users add modules called database drivers that link the application to their Network News Transfer Protocol (NNTP) In choice of database management systems at run the Internet suite of protocols, a protocol for the time. This means that applications no longer distribution, inquiry, retrieval, and posting of news need to be directly linked to the modules of all the articles that are stored in a central database. database management systems that are nonvisual bean A bean that is not visible to the supported. end user in the graphical user interface, but is outer join. The result of a join operation that visually represented on the free-form surface of includes the matched rows of both tables being the Visual Composition Editor during joined and preserves some or all of the development. Developers can manipulate unmatched rows of the tables being joined. See nonvisual beans only as icons; that is, they also join. cannot edit them in the Visual Composition Editor as they can edit visual beans. Examples of ORB (Object Request Broker) In nonvisual beans include beans for business logic, object-oriented programming, software that communication access, and database queries. serves as an intermediary by transparently enabling objects to exchange requests and NNTP See Network News Transfer Protocol. responses. NUL. In C, a single character that denotes the object-oriented design A software design end of the string. method that models the characteristics of

518 Cross-Platform DB2 Stored Procedures: Building and Debugging abstract or real objects using classes and place before compilation. SQL statements are objects. Object-oriented design focuses on the replaced with statements that are recognized by data and on the interfaces to it. For instance, an the host language compiler. Output from this "object-oriented" carpenter would be mostly precompilation includes source code that can be concerned with the chair he was building, and submitted to the compiler and the database secondarily with the tools used to make it; a request module (DBRM) that is input to the bind "non-object-oriented" carpenter would think process. primarily of his tools. Object-oriented design is prepare. The first phase of a two-phase commit also the mechanism for defining how modules process in which all participants are requested to "plug and play." The object-oriented facilities of prepare for commit. Java are essentially those of C++, with extensions from Objective C for more dynamic prepared SQL statement. A named object that method resolution. is the executable form of an SQL statement that has been processed by the PREPARE statement. overloading The ability to have different methods with the same identifier, distinguished primary key. A unique, nonnull key that is part of by their return type, and number and type of the definition of a table. A table cannot be defined arguments. as a parent unless it has a unique key or primary key. overriding Implementing a method in a subclass that replaces a method in a superclass. process A program executing in its own address space, containing one or more threads. P Professional Edition See VisualAge for Java, package A program element that contains Professional Edition. classes and interfaces. program In VisualAge for Java, a term that part An existing, reusable software component. refers to both Java applets and applications. All parts created with the Visual Composition program element In VisualAge for Java, a Editor conform to the JavaBeans component generic term for a project, package, class, model, and are referred to as beans. See visual interface, or method. bean and nonvisual bean. project In VisualAge for Java, the topmost kind persistence In object models, a condition that of program element. A project contains Java allows instances of classes to be stored packages. externally, for example in a relational database. property An initial setting or characteristic of a Persistence Builder In VisualAge for Java, a bean, for example, a name, font, text, or persistence framework for object models, which positional characteristic. enables the mapping of objects to information stored in relational databases and also provides Pthread. The POSIX threading standard model linkages to legacy data on other systems. for splitting an application into subtasks. The Pthread standard includes functions for creating plan. See application plan. threads, terminating threads, synchronizing plan name. The name of an application plan. threads through locking, and other thread control facilities. POSIX. Portable Operating System Interface. The IEEE operating system interface standard R which defines the Pthread standard of threading. See Pthread. RDBMS. Relational database management system. precompilation. A processing of application programs containing SQL statements that takes

519 relational database management system program running on one computer to call the (RDBMS). A relational database manager that services of a program running on another operates consistently across supported IBM computer. systems. repository In VisualAge for Java, the reentrant. Executable code that can reside in permanent storage area containing all open and storage as one shared copy for all threads. versioned editions of all program elements, Reentrant code is not self-modifying and provides regardless of whether they are currently in the separate storage areas for each thread. workspace. The repository contains the source Reentrancy is a compiler and operating system code for classes developed in (and provided with) concept, and reentrancy alone is not enough to VisualAge for Java, and the bytecode for classes guarantee logically consistent results when imported from the file system. Every time you multithreading. See threadsafe. save a method in the IDE, it is automatically updated in the repository. See also SCM reference An object's address. In Java, objects repository and shared repository. are passed by reference rather than by value or by pointers. Repository Explorer In VisualAge for Java, the window from which you can view and remote. Refers to any object maintained by a compare editions of program elements that are in remote DB2 subsystem; that is, by a DB2 the repository. subsystem other than the local one. A remote view, for instance, is a view maintained by a requester. Also application requester (AR). The remote DB2 subsystem. Contrast with local. source of a request to a remote RDBMS, the system that requests the data. remote debugger A debugging tool that debugs code on a remote platform. resource file A non-code file that may be referred to from your Java program in VisualAge Remote Function Call (RFC) SAP's open for Java. Examples include graphic and audio programmable interface. External applications files. and tools can call ABAB/4 functions from the SAP System. You can also call third party applications result set. The set of rows returned to a client from the SAP System using RFC. RFC is a application by a stored procedure. means for communication that allows result set locator. A 4-byte value used by DB2 implementation on all R/3 platforms. to uniquely identify a query result set returned by Remote Method Invocation (RMI) RMI is a a stored procedure. specific instance of the more general term RPC. result table. The set of rows specified by a RMI allows objects to be distributed over the SELECT statement. network; that is, a Java program running on one computer can call the methods of an object right outer join. The result of a join operation running on another computer. RMI and java.net that includes the matched rows of both tables are the only 100% pure Java APIs for controlling being joined and preserves the unmatched rows Java objects in remote systems. of the second join operand. See also join. Remote Object Instance Manager In Remote RMI (Remote Method Invocation) See Method Invocation, a program that creates and Remote Method Invocation. manages instances of server beans through their RMI Access Builder A VisualAge for Java associated server-side server proxies. Enterprise tool that generates proxy beans and Remote Procedure Calls (RPC) RPC is a associated classes and interfaces so you can generic term referring to any of a series of distribute code for remote access, enabling protocols used to execute procedure calls or Java-to-Java solutions. method calls across a network. RPC allows a

520 Cross-Platform DB2 Stored Procedures: Building and Debugging RMI compiler The compiler that generates stub of code without having to define an and skeleton files that facilitate RMI encompassing class or method. communication. This compiler can be Secure Socket Layer (SSL) SSL is a security automatically invoked by the RMI Access Builder, protocol which allows communications between a and can also be invoked from the Tools menu browser and a server to be encrypted and secure. item. SSL prevents eavesdropping, tampering or RMI registry A server program that allows message forgery on your Internet or intranet remote clients to get a reference to a server network. bean. security Features in Java that prevent applets rollback. The process of restoring data changed downloaded off the Web from deliberately or by SQL statements to the state at its last commit inadvertantly doing damage. One such feature is point. All locks are freed. Contrast with commit. the digital signature, which ensures that an applet came unmodified from a reputable source. RPC See Remote Procedure Calls. serialization Turning an object into a stream, runtime system The software environment and back again. where compiled programs run. Each Java runtime system includes an implementation of the server The computer that hosts the Web page Java Virtual Machine. that contains an applet. The .class files that make up the applet, and the HTML files that reference S the applet reside on the server. When someone on the Internet connects to a Web page that sandbox A restricted environment, provided by contains an applet, the server delivers the .class the Web browser, in which Java applets run. The files over the Internet to the client that made the sandbox offers them services and prevents them request. The server is also known as the from doing anything naughty, such as doing file originating host. I/O or talking to strangers (servers other than the one from which the applet was loaded). The server bean The bean that is distributed using analogy of applets to children led to calling the RMI services and is deployed on a server. environment in which they run the "sandbox." servlet Server-side programs that execute on scalar function. An SQL operation that and add function to Web servers. Java servlets produces a single value from another value and allow for the creation of complicated, is expressed as a function name followed by a list high-performance, cross-platform Web of arguments enclosed in parentheses. See also applications. They are highly extensible and column function. flexible, making it easy to expand from client or single-server applications to multi-tier SCM See Software Configuration Management. applications. SCM repository In VisualAge for Java, a SGML See Standardized Generalized Markup generic term for the data store of any external Language. software configuration management (SCM) tool. Some SCM tools refer to this as an archive. single precision A floating-point number that contains 32 bits. See also double precision. scope Determines where an identifier can be used. In Java, instance and class variables have SmartGuide In IBM software products, an a scope that extends to the entire class. All other active form of help that guides you through identifiers are local to the method where they are common tasks. declared. Software Configuration Management (SCM) Scrapbook In VisualAge for Java, the window The tracking and control of software from which you can write, edit, and test fragments

521 development. SCM tools typically offer version static field See class variable. control and team programming features. static method See class method. sourced function. A function that is static SQL. SQL statements, embedded within a implemented by another built-in or user-defined program, that are prepared during the program function already known to the database manager. preparation process (before the program is This function can be a scalar function or a column executed). After being prepared, the SQL (aggregating) function; it returns a single value statement does not change (although values of from a set of values (for example, MAX or AVG). host variables specified by the statement might Contrast with external function and built-in change). function. stored procedure. A user-written application source type. An existing type that is used to program, that can be invoked through the use of internally represent a distinct type. the SQL CALL statement. SQL Structured . A language stream A communication path between a used by database engines and servers for data source of information and its destination. acquisition and definition. Structured Query Language (SQL). A SQL authorization ID (SQL ID). The standardized language for defining and authorization ID that is used for checking manipulating data in a relational database. dynamic SQL statements in some situations. subclass A class that inherits all the methods SQL Communication Area (SQLCA). A and variables of another class (its superclass). Its structure superclass might be a subclass of another class used to provide an application program with in the hierarchy. information about the execution of its SQL subtype A type that extends another type (its statements. supertype). SQL Descriptor Area (SQLDA). A structure that superclass A class that defines the methods describes input variables, output variables, or the and variables inherited by another class (its columns of a result table. subclass). SQLCA. SQL communication area. supertype A type that is extended by another SQLDA. SQL descriptor area. type (its subtype). SQL/DS. SQL/Data System. Also known as DB2 Swing Set A group of lightweight, ready-to-use for VSE & VM. components developed by JavaSoft. The components range from simple buttons to SSL See secure socket layer. full-featured text areas to tree views and tabbed Standardized Generalized Markup Language folders. An ISO/ANSI/ECMA standard that specifies a synchronized This Java keyword specifies that way to annotate text documents with information only one thread can run inside a method at once. about types of sections of a document. statement handle. In DB2 ODBC, the data T object that contains information about an SQL table. A named data object consisting of a statement that is managed by DB2 CLI. This specific number of columns and some number of includes information such as dynamic arguments, unordered rows. Synonymous with base table or bindings for dynamic arguments and columns, temporary table. cursor information, result values and status information. Each statement handle is associated task control block (TCB). A control block used with the connection handle. to communicate information about tasks within an

522 Cross-Platform DB2 Stored Procedures: Building and Debugging address space that are connected to DB2. An a representation of a path of code execution. (3) address space can support many task The code activity necessary to manipulate a connections (as many as one per task), but only persistent object. For example, a bank one address space connection. See address application might have a transaction that updates space connection. a company account. TCB. MVS task control block. transient This Java keyword specifies that a field is not included in the serial representation of TCP/IP See Transmission Control Protocol an object. See serialization. based on IP. Transmission Control Protocol based on IP temporary table. A table created by the SQL (1) A network communication protocol used by CREATE GLOBAL TEMPORARY TABLE computer systems to exchange information statement that is used to hold temporary data. across telecommunication links. (2) An Internet Contrast with result table. protocol that provides for the reliable delivery of thin client Thin client usually refers to a streams of data from one host to another. system that runs on a resource-constrained type In VisualAge for Java, a generic term for a machine or that runs a small operating system. class or interface. Thin clients don't require local system administration, and they execute Java U applications delivered over the network. UDF. User-defined function third tier The third tier, or back end, is the hardware and software that provides database UDT. User-defined data type and transactional services. These back-end Uniform Resource Locator (URL) The unique services are accessed through connectors address that tells a browser how to find a specific between the middle-tier Web server and the Web page or file. third-tier server. Though this conceptual model depicts the second and third tier as two separate Unicode A 16-bit international character set machines, the NCF model supports a logical defined by ISO 10646. See also ASCII. three-tier implementation in which the software user-defined data type (UDT). See distinct on the middle and third tier are on the same box. type. thread A separate flow of control within a user-defined function (UDF). A function program. defined to DB2 using the CREATE FUNCTION threadsafe. Characteristic of code that allows statement that can be referenced thereafter in multithreading both by providing private storage SQL statements. A user-defined function can be areas for each thread, and by properly serializing either an external function or a sourced function. shared (global) storage areas. Contrast with built-in function. timestamp. A seven-part value that consists of a URL See Uniform Resource Locator. date and time expressed in years, months, days, hours, minutes, seconds, and microseconds. V trace. A DB2 facility that provides the ability to variable (1) An identifier that represents a data monitor and collect DB2 monitoring, auditing, item whose value can be changed while the performance, accounting, statistics, and program is running. The values of a variable are serviceability (global) data. restricted to a certain data type. (2)A data element that specifies a value that can be transaction (1) In a CICS program, an event changed. A COBOL elementary data item is an that queries or modifies a database that resides example of a variable. Contrast with constant. on a CICS server. (2) In the Persistence Builder,

523 virtual machine A software or hardware world readable files A permission level on implementation of a central processing unit Web servers specifying that files can be read by (CPU) that manages the resources of a machine any user. and can run compiled code. See Java Virtual World Wide Web A network of servers that Machine. contain programs and files. Many of the files visual bean In the Visual Composition Editor, a contain hypertext links to other documents bean that is visible to the end user in the available through the network. graphical user interface. Workbench In VisualAge for Java, the main Visual Composition Editor In VisualAge for window from which you can manage the Java, the tool you can use to create graphical workspace, create and modify code, and open user interfaces from prefabricated beans, and to browsers and other tools. define relationships (called connections) between workspace The work area that contains the beans. The Visual Composition Editor is a page Java code that you are developing and the class in the class browser. libraries on which your code depends. Program visual servlet A servlet that is designed to be elements must be added to the workspace from built using the VisualAge for Java Visual the repository before they can be modified. Composition Editor. wrapper Code that provides an interface for VisualAge for Java, Enterprise Edition An one program to access the functionality of edition of VisualAge for Java that is designed for another program. building enterprise Java applications, and has all WWW See World Wide Web. of the Professional Edition features plus support for developers working in large teams, X developing high-performance or heterogeneous applications, or needing to connect Java X/Open. An independent, worldwide open systems programs to existing enterprise systems. organization that is supported by most of the VisualAge for Java, Entry Edition An edition world's largest information systems suppliers, user of VisualAge for Java suitable for learning and organizations, and software companies. X/Open's building small projects of 500 classes or less. It is goal is to increase the portability of applications by available as a no-charge download from combining existing and emerging standards. VisualAge for Java and VisualAge Developer Domain Web sites. 100% Pure Java Sun Microsystems initiative to certify that applications and applets are purely VisualAge for Java, Professional Edition A Java-written. complete Java development environment, including easy access to JDBC-enabled databases for building Java applications. W WebSphere WebSphere is the cornerstone of IBM's overall Web strategy, offering customers a comprehensive solution to build, deploy and manage e-business Web sites. The product line provides companies with an open, standards-based, Web server deployment platform and Web site development and management tools to help accelerate the process of moving to e-business.

524 Cross-Platform DB2 Stored Procedures: Building and Debugging Abbreviations and acronyms

ACEE access control CFRM coupling facility environment resource management AER application execution CLI call level interface region CLP command line AIX Advanced Interactive processor eXecutive from IBM CPU central processing unit APAR authorized program CSA common storage area analysis report DASD direct access storage APF authorized program device facility (MVS) DB2 PM DB2 performance API application program monitor interface DBAT database access APPC advanced thread program-to-program communication DBCTL database control subsystem AR application requester DBD database descriptor ARM automatic restart manager DBID database identifier AS application server DBRM database request module ASCII American National Standard Code for DCL Information DDCS Interchange connection services BLOB binary large objects DDF distributed data facility CCSID coded character set DDL data definition identifier language CCA client configuration DLL dynamic load library assistant manipulation language CFCC coupling facility control DML data manipulation code language CGI common gateway DNS domain name server interface DRA database resource CTT created temporary table adapter CEC central electronics DRDA distributed relational complex database architecture CD compact disk DTT declared temporary tables CF coupling facility

© Copyright IBM Corp. 2001 525 EA extended addressability IRLM internal resource lock manager EBCDIC extended binary coded decimal interchange ISPF interactive system code productivity facility ECS enhanced catalog ISV independent software sharing vendor ECSA extended common I/O input/output storage area ITSO International Technical EDM environment descriptor Support Organization management IVP installation verification ERP enterprise resource process planning JDBC Java Database ESA Enterprise Systems Connectivity Architecture JFS journaled file systems EXCI external CICS interface JVM Java Virtual Machine FDT functional track KB kilobyte (1,024 bytes) directory LPAR logically partitioned FTP File Transfer Program mode GB gigabyte LOB large object (1,073,741,824 bytes) LPL logical page list GBP group buffer pool LRSN log record sequence GRS global resource number serialization LV M logical volume manager GUI graphical user interface MB megabyte (1,048,576 HPJ high performance Java bytes) or the high performance Java MQ message and queueing compiler (IBM software) IBM International Business MQA message queue agent Machines Corporation MQI message queue ICF integrated catalog interface facility OBD object descriptor in ICF integrated coupling DBD facility ODBC Open Data Base ICMF internal coupling Connectivity migration facility OS/390 Operating System/390 IFCID instrumentation facility PAV parallel access volume component identifier PDS partioned data set IFI instrumentation facility interface PSID pageset identifier

526 Cross-Platform DB2 Stored Procedures: Building and Debugging PSP preventive service planning PTF program temporary fix PUNC possibly uncommitted QMF Query Management Facility RACF Resource Access Control Facility RBA relative byte address RID record identifier RRS resource recovery services RRSAF resource recovery services attach facility RS read stability RR repeatable read SDK software developers kit SMIT System Management Interface Tool SNA systems network architecture SP stored procedure SRB system resource block STC started task TCB task control block WLM workload manager

527 528 Cross-Platform DB2 Stored Procedures: Building and Debugging Index Authorization behavior 123 Symbols OS/390 355 &IWMSSNM 140 B Numerics BASIC 65 batch message processing 206 5250 emulation 392 Bind 229 5250 tools 392 BMP 206 Build 14, 360 A ADC 11 Add Database 307 C C 57 58 61 62 63 64 65 74 172 ADO 389 , , , , , , , , comment 124 AER 209 C++ 64, 66 AERTDLI 207 CALL 72 ALLOCATE CURSOR 67 CALL statement 66 67 104 ALLOCATE statement 104 , , definition 74 definition 70 sample 74 sample 72 CALLED ON NULL INPUT 336 Alter LE Run Options 360 CASE statement 67 AMODE 171 definition 75 APAR/PTF sample 75 76 PQ43397 319 , CCTL 209 PQ43437 350 checklist 230 UQ39824 317, 319 CICS UQ41205 317, 318 APPC 184 UQ43183 318 Connection 186 UQ48752 319 CONNTYPE(GENERIC) 186 APPC 183, 207 SINGLESESS(NO) 186 Application Development Client 11 DFH$EXCI 185 Application Environment 140 DFHIR000 196 application environment 137 Program 192 application execution region 209 PROTOCOL(EXCI) 185 assembler 172 RECEIVECount 185 ASSIGNMENT statement 67 RRS 184 Assignment statement SDFHEXCI 192 193 203 definition 73 , , Sessions 188 sample 74 stored procedures 192 ASSOCIATE 70 SYNCLVL=SYNCPT 184 ASSOCIATE LOCATOR statement 67 SYNCONRETURN option 184 ASSOCIATE statement 104 Sysplex exploitation 195 definition 72 table definitions 185 sample 73 Transaction 190 ATOMIC 344 XCF/MRO 184 ATOMIC compound statement 77 XCI CALL 184 sample 77 CIMS INIT 210 AUTH SIGNON 174, 177

© Copyright IBM Corp. 2001 529 CLI 58, 104, 123 DB2ADMIN 288 Client Configuration Assistant 291, 305 DB2-established stored procedures 131 CLOSE 104 DB2SPB.INI file 12 COBOL 57, 61, 62, 63, 64, 66, 74, 172 DBCTL control region 210 Columns panel, 43 DBINFO 336 Commit 173 DBRM 355, 362, 363, 364, 366, 375, 386 Compatibility mode 141 DBRMLIB 350 compatibility mode 132, 232 DCS 298 Compile 227 DDF communication record 296 compile 346 debugging 218 COMPOUND statement 67 DECLARE RESULT SET LOCATOR 104 Compound statement Declaring SQL local variables 68 ATOMIC DEDB 207, 209 definition 77 Define SP to DB2 229 sample 77 Destroy 360 definition 76 DETERMINISTIC 336 NOT ATOMIC DFSPRP 209 definition 77 DFSPZP00 218 sample 77 DFSRESLB 210 order of statements 76 dirty procedure 49 condition handler 76 Dirty Procedures 15 CONTINUE DL/I services 210 definition 93 DRA 206 EXIT DRDA 10 definition 97 DROP PROCEDURE RESIGNAL statement 86 AS/400 404, 405 UNDO DSN@SPM 357 definition 98 DSN8EC1 212 Conditions panel 41 DSN8ED4 373 coordinator controllers 209 DSN8ED5 373 CPIC 173 DSN8ED6 160 Create 13 DSN8ES2 373 CREATE PROCEDURE 352, 355, 361, 374, 375 DSN8WLMP 318 AS/400 389, 392, 400, 403, 404 DSNALI 380 CREATE THREAD 174, 177 DSNDPSM 317 DSNHSQL 317, 354, 373, 377 D DSNRLI 174, 376, 380 DSNSPSM 317 Data Entry Databases 207 DSNTEJ0 318 data entry databases 209 DSNTEJ62 213 database alias 297, 313 DSNTEJ63 318 Database Connection 15 DSNTEJ65 317, 373 database name 297 DSNTEJ6W 159 database resource adapter 206 DSNTEJ71 318 DATE arithmetic 124 DSNTIJFV 317 DB2 Connect 10, 11 DSNTIJMV 317 DB2 ODBA stored procedure address space 232 DSNTIJRX 316 DB2 SDK 11, 22 DSNTIJSG 317 DB2 Software Devloper’s Kit 11 DSNTIJSQ 317

530 Cross-Platform DB2 Stored Procedures: Building and Debugging DSNTIJVC 317 G DSNTINS1 317 Generate 13 DSNTINS2 317 GET DIAGNOSTICS statement 67, 79 DSNTPSMP 316, 319, 350, 353 Get Source 14 BUILD 364 goal DESTROY 365 discretionary 135 input parameters 361 execution velocity 135 PL/1 client program 366 response time 134 sample 367 Goal Mode 142 REBIND 366 goal mode 132, 232 REBUILD 366 GOTO statement 67 REXX 381 DSNWSPM 356, 358, 359 Create Procedure 357 H Handling errors DSNX9WLM 210 definition 92 NOT FOUND 93 E sample 102 EIB 175 SQLEXCEPTION 92 ESTAE 171 SQLWARNING 93 ESTAI 171 Handling result sets 103 EXCI 183 DECLARE CURSOR 103 EXCI CALL interface 184 sample 103 EXCI interface 206 WITH RETURN TO CALLER clause 103 Execute 228 WITH RETURN TO CLIENT clause 103 Execute DB2 ODBA stored procedure 231 host name 295, 309 EXIT handler 97 host variables 68 EXTERNAL 336 External CICS Interface 183 external stored procedure 57, 58, 61, 62, 64, 65, I IBM VisualAge for Java 11 66 ICMD sample See also Open Database Access (ODBA) F sample FENCED 336 IDENTIFY 174 fenced procedures 56 IF statement 67 FETCH 104 definition 83 Field Sensitive Help 18 sample 83, 84 Filter 22, 26 IFP 206 filter 26 IMPLICIT_SCHEMA 348 filter dialog 26 IMS Fast Path 206 fixpack 314 Insert SQL Procedure 28 FOR statement 67 INVSDK2LMS 421, 422 definition 78 ISO/ANSI 56, 57 sample 78, 79 ITERATE statement 67, 91 FORTRAN 172 definition 84 Fortran 64 FRR 171 J JAVA 8

531 Java 57, 64, 74, 123 ODBC driver 413 stored procedure 66 Open Database Access 205 JDBC 123, 389, 397, 423, 427 Open Database Access (ODBA) Open Source driver 413 sample Joins panel 40 AIBCMND 490 OD0BBMC 489 L OD0BBMS 489 OD1CPMS 489 Language elements 70 OD1DPMS 489 Language Environment (LE)/370 192 OD1EPMS 489 LE/370 192, 193 ODBACMD 491 LEAVE statement 67 SPICMD1 491 definition 85, 86 SPICMD2 491 sample 85 Open Transaction Manager Access 205 Link 227 Oracle 57 linkedit 346 OS/390 SQL Procedure Processor 349 LOB locator 124 OTMA 205 local variables overloaded stored procedures 405, 406 declaration 68 LOOP statement 67 P M package 347 PARAMETER STYLE 336 message processing program 206 parameters 338 Message Queue Interface 183 PASCAL 65 Microsoft Visual Basic 11 Paste Procedure 50 Microsoft Visual Studio 11 Pattern 28 Modular programming 58 Persistent Stored Module 56 module 67 PL/I 172 MPP 206 PL/SQL 57, 63 MQI 183 PQ15784 211 multi-rowed result sets 123 PQ24891 357 PQ37325 212 N PQ38316 212 NetBIOS adapter 302 PQ38545 212 Network traffic reduction 58 precompile 346 New line markers 124 Procedure Processor 47, 319 New Project window 21 Processing result sets 105 NO DBINFO 336 PROGRAM TYPE 336 NO SQL 336 Project 13 NOT ATOMIC compound statement 77 sharing SPB projects 23 sample 77 Project name 21 NOT DETERMINISTIC 336 Project path 22 NOT FENCED 336 Project Properties 23 NUMTCB 154, 213 projects 20

O Q ODBA 205, 207 QSQLSRC 392 ODBC 123, 389, 397 QUIESCE option 144

532 Cross-Platform DB2 Stored Procedures: Building and Debugging R service policies 132 Rebind 360 SIGNAL statement 67 Rebuild 360 signature of stored procedure 403 Recommended Maintenance Level 316 SIGNON 174, 176 Recoverable Resource Manager attachment facility simple-case-statement-when-clause 75 147 Single statement procedure 123 Recoverable Resource Manager Services attach- Smart Fields 18 ment facility 171 SmartGuide 18, 19, 27, 28 REFRESH option 144 Sort panel 44 Register 14 SPB 7 REPEAT statement 67 authorization 13 sample 86 concepts and terminology RESIGNAL statement 67 Build 14 definition 86 Create 13 RESLIB 217, 218 Database Connection 15 Resource Recovery Services 131 Dirty Procedures 15 Response time goal 134 Generate 13 RESULT SET LOCATOR 70 Get Source 14 result sets 123 Modify 15 RESUME option 144 Project 13 Retrieving result sets 104 Register 14 sample 104, 105 Run 14 RETURN statement 67 configuring your environment 11 Review panel 45 CREATE PROCEDURE 24, 31, 34, 35 REXX 64 destroy 13 DSNTPSMP 381 DRDA 10 Rexx support 316 DSNTPSMP 36, 37, 47 RMODE 171 managing projects 23 rollback 173 pre-requisites 10 RRS 131, 160, 171, 206, 207, 211 programming languages supported 9 starting 168 rebuild 13 RRS Error samples 168 sharing projects 23 RRS JCL procedure 166 tasks RRSAF 147, 171 actual costs 32 Sample JCL 179 building stored procedures 47 Run 14 copying and pasting stored procedures 49 RUNSQLSTM 391, 392, 393, 394, 396, 417 creating new stored procedures 27 debugging stored procedures 435 modifying existing stored procedures 47 S viewing existing stored procedures 24 SAVEPOINT 344 specific name 347 scope name 68 SPP file extension 13 SDFSRESL 217 SQC file 347 SDK 11 SQL Assistant 18, 19, 28, 38, 41, 43, 45, 46 SDK2LMS 392, 394, 397, 401, 402, 403, 404, 418, SQL Costing Information 356 421, 423 SQL local variables searched-case-statement-when-clause 76 declaration 68 security/shield mechanism 60 sample 69 service definition 132 SQL Procedure language 8

533 SQL Procedures SQLSTATE 412 SPB 124 WLM established 131 stored procedure builder 66, 67 STRSEU 392 SQL Script 391, 399, 400, 401, 402, 404 Sybase 57 SQL statements 67 syncpoint 211 SQL stored procedure Syncpoint coordinator 206 AS/400 SYSIBM.DSNPSMOX1 317 Operations Navigator GUI 391 SYSIBM.DSNPSMX1 317 Operations Navigator SQL 391 SYSIBM.SYSPARMS 355, 364, 366, 374, 375 Traditional 5250 391 SYSIBM.SYSPROCEDURES 48, 131, 331, 346, creating result sets 103 352, 366, 373, 375, 445 declaring SQL local variables 68 SYSIBM.SYSPROCOPTIONS 331 handling errors 92 SYSIBM.SYSPROCPARMS 331, 346 OS/390 SYSIBM.SYSPROCPARMSOPTIONS 331 Method 1 349 SYSIBM.SYSPSM 48, 317, 355, 376, 381 Method 2 349 SYSIBM.SYSPSMOPTS 317, 355, 364, 366, 376, Method 3 349 381 SPB 349 SYSIBM.SYSPSMOUT 317, 355 processing result sets 105 SYSIBM.SYSPSMPOPTS 350 retrieving result sets 104 SYSIBM.SYSROUTINE 319 SQL stored procedure source code 57 SYSIBM.SYSROUTINES 138, 183, 355, 364, 366, SQL stored procedures 374, 375 Development 64 SYSMSGS 362 SQL/PSM 56, 62 SYSPARMS 396, 405 SQL3 56, 57 SYSPARMS system catalog 391 SQLCODE 31, 81, 123, 342 SYSROUTINES 396, 405 in SQL stored procedures 412 SYSROUTINES system catalog 390 SQLCSRC 362 system catalogs SQLDBRM 362 SYSPARMS 391 SQLLIBC 362 SYSROUTINES 390 SQLLIBL 362 SQLLMOD 362 T SQLPROCS 392 T/SQL 57, 63 SQLSTATE 31, 81, 92, 123, 342 Tables panel 38 in SQL stored procedures 412 TCB 172, 212 SRRBACK 171 TCP/IP port 296, 309 SRRCMIT 171 Terminate 232 stored procedure TERMINATE IDENTIFY 174, 178 returning result sets 123 TERMINATE THREAD 174, 178 stored procedure address space 210 Test Connection 299, 313 stored procedure wizard 29 TRANSLATE 174, 179 stored procedure wizards 16 tree view 25 stored procedures DB2 established 131 dropping overloaded procedures 406 U overloading 405 U0113 232 signatures 403 UNDO handler 99 SQL unfenced procedures 56 SQLCODE 412 UQ22097 212

534 Cross-Platform DB2 Stored Procedures: Building and Debugging UQ22187 212 UQ26690 212 UQ28282 357 UQ28826 212 UQ30900 212 UQ30901 212 UQ31515 212 UQ38712 212 UQ40575 212 UQ42850 212 UQ44482 212 UQ46670 212 UQ47799 211 UQ47800 211 UWO 10

V variables 338 declaration order 68 Visual Basic 63 VisualAge for Java 11 VisualAge Remote Debugger 19

W WHILE statement definition 91 sample 91 WHILE statement SQL statements 67 WLM 131 DDNAMES 362 WLM application environments 211 quiesce 211 refresh 211 resume 211 WLM Compatibility mode 155 WLM DB2 stored procedure address space 210 WLM ENVIRONMENT 322 WLM environment change default 385 choose default 385 WLM Goal mode 153 WLM_ENV 140 WLM_REFRESH 157, 211 WLM-established address space 147 WLM-established stored procedures 131

535 536 Cross-Platform DB2 Stored Procedures: Building and Debugging IBM Redbooks review

Your feedback is valued by the Redbook authors. In particular we are interested in situations where a Redbook "made the difference" in a task or problem you encountered. Using one of the following methods, please review the Redbook, addressing value, subject matter, structure, depth and quality as appropriate. • Use the online Contact us review redbook form found at ibm.com/redbooks • Fax this form to: USA International Access Code + 1 914 432 8264 • Send your comments in an Internet note to [email protected]

Document Number SG24-5485-01 Redbook Title Cross-Platform DB2 Stored Procedures: Building and Debugging

Review

What other subjects would you like to see IBM Redbooks address?

Please rate your overall O Very Good O Good O Average O Poor satisfaction:

Please identify yourself as O Customer O Business Partner O Solution Developer belonging to one of the O IBM, Lotus or Tivoli Employee following groups: O None of the above

Your email address: The data you provide here may be used to provide you with O Please do not use the information collected here for future information from IBM or our marketing or promotional contacts or other communications beyond business partners about our the scope of this transaction. products, services or activities.

Questions about IBM’s privacy The following link explains how we protect your personal information. policy? ibm.com/privacy/yourprivacy/

© Copyright IBM Corp. 2001 537

Building and Debugging Stored Procedures: DB2 Cross-Platform

(1.0” spine) 0.875”<->1.498” 460 <-> 788 pages

® Cross-Platform DB2 Stored Procedures: Building and Debugging

Setting up the This IBM Redbook documents a residency project conducted INTERNATIONAL environment for DB2 at the IBM International Technical Support Organization, San Jose Center. The project tested and implemented stored TECHNICAL Building DB2 stored procedures executing in DB2 for OS/390, DB2 for Windows SUPPORT procedures NT, DB2 UDB for AIX, and DB2 for AS/400 servers. ORGANIZATION

This book covers the SQL Procedures language (which allows Debugging DB2 the customer to develop stored procedures in a standard and stored procedures portable language across the DB2 family and OEM DBMSs), BUILDING TECHNICAL the IBM Stored Procedure Builder, and the IBM Distributed INFORMATION BASED ON PRACTICAL EXPERIENCE Debugger. It also explains how to implement DB2 stored procedures accessing non-DB2 resources. IBM Redbooks are developed by We developed and documented several sample stored the IBM International Technical procedure programs (available for downloading) to illustrate Support Organization. Experts from IBM, Customers and the theory discussed in this book. These programs are useful Partners from around the world for getting started with the SQL Procedures language in your create timely technical own environment and gaining some hands-on experience. information based on realistic scenarios. Specific This book is written for IBM technical professionals and recommendations are provided to help you implement IT customer technical personnel responsible for implementing solutions more effectively in stored procedures locally or in a client/server environment. A your environment. background in programming and Distributed Relational Database Architecture connectivity among IBM relational database products, and their associated operating systems, is assumed. For more information: ibm.com/redbooks

SG24-5485-01 ISBN 0738419036