SG 247604
SG 247604
SG 247604
Paolo Bruni
Sabine Kaschta
Marcel Kutsch
Glenn McGeoch
Marichu Scanlon
Jan Vandensande
ibm.com/redbooks
International Technical Support Organization
March 2008
SG24-7604-00
Note: Before using this information and the product it supports, read the information in “Notices” on
page xxxv.
This edition applies to IBM DB2 Version 9.1 for z/OS (program number 5635-DB2).
Figures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv
Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi
Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxv
Notices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxxv
Trademarks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxxvi
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxxix
The team that wrote this book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxxix
Become a published author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xliii
Comments welcome. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xliv
Part 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Chapter 6. RRSAF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
6.1 RRSAF overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
6.2 RRSAF and DB2 stored procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
6.3 Implementing RRSAF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
6.3.1 RRS log streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
6.3.2 Activating the CFRM policy to support RRS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
6.3.3 Making the RRS JCL procedure available . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
6.3.4 Adding RRS subsystem name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
6.3.5 Starting and stopping RRS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
6.3.6 RRS error samples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
6.4 DB2 restart and recovery with RRS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
6.4.1 DB2 restart if RRS is unavailable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
6.4.2 Navigate the RRS ISPF panels. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
iv DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Chapter 8. Operational issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
8.1 Refreshing the stored procedure environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
8.2 Handling error conditions in the application environment . . . . . . . . . . . . . . . . . . . . . . . 85
8.3 Preventing hanging or looping stored procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
8.4 Terminating hanging or looping stored procedures. . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
8.5 Handling application failures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
Contents v
10.4 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
vi DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
13.10 Java sample JDBC stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
13.10.1 Sample Java stored procedure code: EmpDtlsJ using JDBC . . . . . . . . . . . . . 211
13.10.2 DDL for Java stored procedure EmpDtlsJ. . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
13.10.3 Deploying JDBC stored procedures on z/OS . . . . . . . . . . . . . . . . . . . . . . . . . 213
13.10.4 Sample Java stored procedure returning a result set - EmpRsetJ . . . . . . . . . 213
13.10.5 Calling the Java stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
13.11 Java sample SQLJ stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
13.11.1 Sample code for SQLJ stored procedure - EmpDtl1J.sqlj. . . . . . . . . . . . . . . . 215
13.11.2 Result sets and position updates in SQLJ stored procedures . . . . . . . . . . . . 217
13.12 Migrating stored procedures to use the new JCC driver . . . . . . . . . . . . . . . . . . . . . 220
13.12.1 Migrating JDBC stored procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
13.12.2 Migrating SQLJ stored procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
13.12.3 Extracting a .ser file from a jar file defined to DB2 . . . . . . . . . . . . . . . . . . . . . 225
13.13 Common problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
13.13.1 WLM-related errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
13.13.2 Runtime problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
Contents vii
15.3.6 Dropping an existing version. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
15.3.7 ALTER PROCEDURE syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
15.4 Execution of a native SQL procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
15.4.1 Which procedure is executed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
15.5 Deployment of a native SQL procedure to another server . . . . . . . . . . . . . . . . . . . . 301
15.6 DB2/DSN/SQL command changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
15.6.1 START/STOP PROCEDURE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
15.6.2 -DISPLAY PROCEDURE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
15.6.3 REBIND PACKAGE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
15.6.4 Impact on other SQL statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
15.6.5 New stored procedure-related special registers . . . . . . . . . . . . . . . . . . . . . . . . 306
15.7 Error handling and debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
15.7.1 Compound statements within condition handlers . . . . . . . . . . . . . . . . . . . . . . . 309
15.7.2 GET DIAGNOSTICS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310
15.7.3 Unified Debugger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311
15.8 Migrating external to native SQL procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311
viii DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Chapter 18. Code level management. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369
18.1 Environments and code levels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
18.2 Versioning of stored procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373
18.2.1 Four release levels: Sample scenario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374
18.2.2 Versioning of native SQL language stored procedures. . . . . . . . . . . . . . . . . . . 377
18.3 Promotion of stored procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377
18.3.1 Compile just once . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
18.3.2 Compile every time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381
18.4 Notes on REXX execs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384
18.4.1 DDLMOD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384
Contents ix
Chapter 21. I/O performance management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 435
21.1 Stored procedures I/O and ENQs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436
21.2 Managing stored procedures I/O and ENQs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436
x DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
25.4.2 Invoking the EmpPhotJ stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 613
25.4.3 Invoking the servlet EmpPhotoSpServlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 614
25.4.4 Handling large BLOB columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 614
25.5 Stored procedure returning a CLOB column . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 617
25.5.1 Invoking the EmpClobJ stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 618
25.6 Introduction to XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 619
25.6.1 Using the XML data type. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 620
25.6.2 Setting up the environment for sample XML tables . . . . . . . . . . . . . . . . . . . . . 621
25.6.3 Use of the XML data type in stored procedure parameters . . . . . . . . . . . . . . . 622
25.6.4 Use of the XML data type in stored procedure result sets . . . . . . . . . . . . . . . . 627
Contents xi
27.6.4 Deploying nested or dependent stored procedures . . . . . . . . . . . . . . . . . . . . . 707
27.6.5 Setting the JDK level for Java stored procedures . . . . . . . . . . . . . . . . . . . . . . . 707
27.6.6 Executing a stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 709
27.7 Advanced IBM Data Studio topics. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 710
27.7.1 Modifying an existing stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 710
27.7.2 Using code fragments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 712
27.7.3 Generating multiple results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 712
27.7.4 Drag and Drop or Copy and Paste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 715
27.7.5 Behavior when setting the Current Schema project property . . . . . . . . . . . . . . 717
27.7.6 Package owner and Build owner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 717
27.7.7 Export and ant deploy of stored procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . 718
27.7.8 Deploying SQL or Java stored procedures without recompiling . . . . . . . . . . . . 722
27.7.9 Creating package variations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 725
27.7.10 Multiple Jar support for Java stored procedures . . . . . . . . . . . . . . . . . . . . . . . 726
27.7.11 Migrating DC projects to IBM Data Studio . . . . . . . . . . . . . . . . . . . . . . . . . . . 729
27.7.12 Creating a Web Service from a stored procedure. . . . . . . . . . . . . . . . . . . . . . 731
Chapter 29. Debugging DB2 V8 Java procedures with Data Studio. . . . . . . . . . . . . . 785
29.1 Debugging JDBC procedures converted to JDBC applications . . . . . . . . . . . . . . . . 786
29.1.1 Switch to the Java Perspective . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 786
29.1.2 Create a Java Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 787
29.1.3 Copy EmpDtlsJ.java to JAVASPDEBUG project . . . . . . . . . . . . . . . . . . . . . . . 790
29.1.4 Modify the Java stored procedure code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 790
29.1.5 Set breakpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 792
xii DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
29.1.6 Configure the Debug Launch Settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 793
29.1.7 Debugging the application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 796
29.2 Debugging SQLJ procedures converted to SQLJ applications . . . . . . . . . . . . . . . . . 797
29.2.1 Create the SQLJSPDEBUG project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 797
29.2.2 Copy SQLJ stored procedure source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 797
29.2.3 Paste into the SQLJSPDebug project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 798
29.2.4 Add SQLJ support. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 798
29.2.5 Modify the source code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 800
29.2.6 Set breakpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 800
29.2.7 Configure the debug session . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 800
Contents xiii
Abbreviations and acronyms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 895
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 901
xiv DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figures
xvi DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
24-7 CALL ADMIN_JOB_QUERY stored procedure. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 533
24-8 CALL ADMIN_JOB_CANCEL stored procedure. . . . . . . . . . . . . . . . . . . . . . . . . . . . 535
24-9 CALL ADMIN_DS_BROWSE stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . 536
24-10 CALL ADMIN_DS_WRITE stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538
24-11 CALL ADMIN_DS_LIST stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 540
24-12 CALL ADMIN_DS_RENAME stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . 543
24-13 CALL ADMIN_DS_DELETE stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545
24-14 CALL ADMIN_DS_SEARCH stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . 547
24-15 CALL ADMIN_INFO_HOST stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . 549
24-16 CALL ADMIN_INFO_SSID stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 550
24-17 CALL DSNACICS stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 552
24-18 CALL DSNLEUSR stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 555
24-19 CALL DSNAIMS stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 557
24-20 CALL ADMIN_UTL_SCHEDULE stored procedure . . . . . . . . . . . . . . . . . . . . . . . . 560
24-21 CALL ADMIN_UTL_SORT stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 566
24-22 Schedule/Remove a task with the DB2 provided scheduler . . . . . . . . . . . . . . . . . . 571
24-23 List the scheduled tasks and task status . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 573
24-24 Executing a scheduled stored procedure task . . . . . . . . . . . . . . . . . . . . . . . . . . . . 574
24-25 CALL ADMIN_TASK_ADD stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 584
24-26 CALL ADMIN_TASK_REMOVE stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . 588
24-27 Common SQL API signature. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591
24-28 Complete Mode vs. non-Complete Mode work flow . . . . . . . . . . . . . . . . . . . . . . . . 595
25-1 CREATE TABLE with XML column. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 620
25-2 SQLCODE -20060 error message . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 622
25-3 Assignment of XML data type to CHAR OUT parameter fails. . . . . . . . . . . . . . . . . . 623
25-4 XMLSERIALIZE function to cast to CLOB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623
25-5 Sample XML document from PORDER column . . . . . . . . . . . . . . . . . . . . . . . . . . . . 624
25-6 Failing attempt to assign XMLQUERY result to parameter. . . . . . . . . . . . . . . . . . . . 624
25-7 XMLSERIALIZE around XMLQUERY scalar function. . . . . . . . . . . . . . . . . . . . . . . . 625
25-8 Simple stored procedures passing an XML document through the IN parameter . . 625
25-9 Parameter input panel of Data Studio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 626
25-10 Specified values in Data Studio for IN parameters . . . . . . . . . . . . . . . . . . . . . . . . . 627
25-11 Create procedure with cursor and result set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 627
25-12 Data Studio output of returned result set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 628
26-1 Messages tab in IBM Data Studio Data Output View showing trigger test results . . 631
26-2 SDSF output showing DISPLAY results for stored procedure invoked by trigger. . . 631
26-3 SDSF output showing DISPLAY results for stored procedure with transition tables. 635
26-4 Data validation using a trigger and a user-defined function . . . . . . . . . . . . . . . . . . . 637
26-5 Data propagation using a trigger and a stored procedure . . . . . . . . . . . . . . . . . . . . 639
27-1 IBM Data Studio V1.1 Support features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 644
27-2 DSNTPSMP setting with different schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 658
27-3 Multiple versions of schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 659
27-4 Overriding the default JDK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 662
27-5 Starting IBM Data Studio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 664
27-6 How IBM Data Studio creates SQL stored procedures. . . . . . . . . . . . . . . . . . . . . . . 666
27-7 How IBM Data Studio creates Java stored procedures . . . . . . . . . . . . . . . . . . . . . . 667
27-8 Database Explorer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 668
27-9 Filtering option . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 669
27-10 Deploy Wizard. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 670
27-11 Generated DDL for a stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 671
27-12 Data Project Explorer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 672
27-13 Setting current schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 673
27-14 Setting package and build owner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 673
Figures xvii
27-15 Property Browser for stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 674
27-16 Data Output view . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 675
27-17 Routine Editor - source tab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 676
27-18 Routine Editor - Configuration tab. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 677
27-19 Import Wizard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 679
27-20 Menu and Task Bar. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 680
27-21 Select a workspace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 681
27-22 New Connection wizard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 682
27-23 Display DDF output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 682
27-24 New Data Development Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 684
27-25 New SQL or XQuery Script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 686
27-26 SQL Builder. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 686
27-27 SELECT template with two columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 688
27-28 New Stored Procedure wizard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 690
27-29 SQL Statements page. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 691
27-30 Parameters page and Add Parameter dialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 692
27-31 Deploy options page and z/OS Options dialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . 693
27-32 Native SQL stored procedure summary info including procedure definition . . . . . . 694
27-33 Stored Procedure options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 695
27-34 External SQL deploy options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 696
27-35 New Java stored procedure (SQLJ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 697
27-36 Error Handling code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 697
27-37 Java stored procedure deploy options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 698
27-38 SQLJ stored procedure root package and compile options . . . . . . . . . . . . . . . . . . 698
27-39 Specifying code fragments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 699
27-40 Import Wizard, Source page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 701
27-41 Import Wizard, Entry points. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 702
27-42 Import Wizard, Parameters page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 702
27-43 Routine Editor, Configuration page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 704
27-44 Deploy wizard, Deploy Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 705
27-45 Deploy Wizard, changing the JDK and JRE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 706
27-46 Deploying nested stored procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 707
27-47 Changing the JDK level . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 708
27-48 Native SQL z/OS Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 708
27-49 Specify parameter values at SP execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 709
27-50 Run Settings dialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 709
27-51 Parameter section in Routine Editor’s Configuration tab . . . . . . . . . . . . . . . . . . . . 711
27-52 Generate multiple SQL statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 713
27-53 Specify a new or existing project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 716
27-54 Copy a Java or SQL stored procedure to another project . . . . . . . . . . . . . . . . . . . 716
27-55 Export Wizard Selection page. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 718
27-56 Export Wizard Target File name and location . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 719
27-57 Export wizard, Output View Status table. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 719
27-58 Deploy using binaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 723
27-59 Generate privileges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 724
27-60 New Package Variation wizard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 725
27-61 Import a jar file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 727
27-62 Add supporting jar for Java stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 728
27-63 Routine Editor Configuration tab Files shows supporting jars . . . . . . . . . . . . 728
27-64 Installing the DC Project Migration feature in Installation Manager . . . . . . . . . . . . 729
27-65 Launch the DC Project Migration wizard. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 730
27-66 DC Project .dcp file and connections. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 730
27-67 Migrate DC projects, select connection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 731
xviii DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
27-68 Create a new Web service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 731
27-69 Define a new Web Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 732
27-70 Add a stored procedure call to a Web service . . . . . . . . . . . . . . . . . . . . . . . . . . . . 732
27-71 Select the Web Service to add this stored procedure to . . . . . . . . . . . . . . . . . . . . . 733
27-72 Generate XML Schema for stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 733
27-73 Specify options for deploying the Web service . . . . . . . . . . . . . . . . . . . . . . . . . . . . 734
27-74 Generated WSDL file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 734
28-1 Processing overview - Unified Debugger with DB2 9 for z/OS . . . . . . . . . . . . . . . . . 739
28-2 Example of a successful output from the Session Manager . . . . . . . . . . . . . . . . . . . 746
28-3 Debug Session Manager startup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 747
28-4 Preferences for using the client Session Manager . . . . . . . . . . . . . . . . . . . . . . . . . . 748
28-5 Starting the Debugger from the Routine Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 749
28-6 Import a stored procedure into the project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 750
28-7 Import wizard start page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 750
28-8 Create the procedure EMPDTLSS using the editor . . . . . . . . . . . . . . . . . . . . . . . . . 753
28-9 The Debug Perspective . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 754
28-10 Debug and Run toolbar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 755
28-11 Breakpoints view . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 756
28-12 Start debugging for EMPDTLSS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 758
28-13 Specify Parameter Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 758
28-14 Confirm switch to Debug Perspective . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 759
28-15 Unified Debugger Variables display . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 759
28-16 Unified Debugger Data Output view’s Parameters tab . . . . . . . . . . . . . . . . . . . . . . 760
28-17 Processing overview - RDz and Debug Tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 761
28-18 RDz V7 Workspace launcher . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 764
28-19 RDz - New Database connection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 765
28-20 RDz - new remote connection. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 765
28-21 RDz - New stored procedure, Name and Language . . . . . . . . . . . . . . . . . . . . . . . . 766
28-22 RDz - target name for stored procedure PDS member names . . . . . . . . . . . . . . . . 766
28-23 RDz - Source Location . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 767
28-24 RDz - Select data sets for Source. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 767
28-25 RDz - SQL wizard’s Tables tab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 768
28-26 RDz - SQL wizard, Columns tab, selecting result columns. . . . . . . . . . . . . . . . . . . 768
28-27 RDz - SQL wizard, Conditions tab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 769
28-28 COBOL stored procedure source listing in the Editor View . . . . . . . . . . . . . . . . . . 770
28-29 RDz Remote Systems view, MVS files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 774
28-30 RDz Remote Error list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 775
28-31 Open the RDz Data Perspective . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 777
28-32 RDz Debug Perspective . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 778
28-33 Drag and drop stored procedure from z/OS to Windows . . . . . . . . . . . . . . . . . . . . 781
28-34 Unified Debugger debugging a Java stored procedure on Windows . . . . . . . . . . . 784
29-1 Switching perspective to Java Perspective . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 786
29-2 The Java Perspective in IBM Data Studio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 787
29-3 Creating a New Java Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 787
29-4 New Java Project wizard, Create a Java project. . . . . . . . . . . . . . . . . . . . . . . . . . . . 788
29-5 Define the Java build settings - Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 789
29-6 Define the Java build settings - Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 789
29-7 Java Perspective, Package Explorer, Copy EmpRsetJ.java. . . . . . . . . . . . . . . . . . . 790
29-8 Java Perspective, Package Explorer, Paste EmpDtlsJ.java . . . . . . . . . . . . . . . . . . . 790
29-9 Connection Properties ->Connection URL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 791
29-10 System.out.println statements. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 792
29-11 Add breakpoint for Java applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 793
29-12 Select Debug configuration option . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 793
Figures xix
29-13 Configure Java Application for debug . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 794
29-14 Java application Debug Main window definition . . . . . . . . . . . . . . . . . . . . . . . . . . . 795
29-15 Java application Debug Arguments window definition . . . . . . . . . . . . . . . . . . . . . . 796
29-16 Console output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 796
29-17 Debug Perspective at a breakpoint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 797
29-18 Copy SQLJ source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 798
29-19 Paste into the SQLJSPDebug project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 798
29-20 Add SQLJ Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 799
29-21 Select projects for SQLJ support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 799
29-22 SQLJ support added to project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 800
29-23 SQLJ application source with breakpoint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 800
29-24 Launch the Debug configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 801
29-25 Define a new SQLJ Debug configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 802
29-26 Confirm Perspective Switch, Remember my decision . . . . . . . . . . . . . . . . . . . . . . 802
29-27 Debug Perspective launched for an SQLJ application . . . . . . . . . . . . . . . . . . . . . . 803
A-1 Output from DIAGNOSE DISPLAY AVAILABLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . 813
xx DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Tables
xxii DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
27-5 DB2 system catalog tables accessed when creating SQL stored procedures . . . . . 653
27-6 DB2 system catalog tables accessed when creating Java stored procedures . . . . . 653
27-7 WLM commands entered from SDSF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 655
27-8 Activate Class DSNR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 655
27-9 DSNTPSMP supported functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 664
27-10 Deploy source and target server combinations. . . . . . . . . . . . . . . . . . . . . . . . . . . . 706
27-11 Current schema behavior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 717
28-1 DB2 debugging options for z/OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 736
28-2 DB2 debugging options for the distributed platforms . . . . . . . . . . . . . . . . . . . . . . . . 737
28-3 Execution toolbar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 755
28-4 Breakpoints view toolbar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 756
28-5 Valid SQL Debugger breakpoint and change variable statements . . . . . . . . . . . . . . 757
28-6 Parameter names and values for EMPDTLC COBOL stored procedure . . . . . . . . . 769
28-7 Summary of changes to the generated COBOL stored procedure . . . . . . . . . . . . . . 770
28-8 Data sets for Deploy in RDz v7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 775
29-1 Converting the stored procedure method to a main method. . . . . . . . . . . . . . . . . . . 791
29-2 Changes to the connection string . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 792
29-3 Debug settings for Java application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 794
29-4 Debug settings for SQLJ applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 801
Tables xxiii
xxiv DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Examples
xxvi DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
13-10 DB2Binder command from a DB2 command window . . . . . . . . . . . . . . . . . . . . . . . 191
13-11 Sample Job to bind the packages for JCC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
13-12 /u/paolor5/.profile data set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
13-13 Using the javac command. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
13-14 Compiling the Java program using AOPBATCH. . . . . . . . . . . . . . . . . . . . . . . . . . . 197
13-15 File produced by SQLJ preparation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
13-16 Sample db2sqljcustomize command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
13-17 Output of the db2sqljcustomize command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
13-18 Binding the DBRM packages for SQLJ stored procedure. using db2sqljbind . . . . . 200
13-19 Output of the db2sqljbind command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
13-20 Sample Job to prepare an SQLJ stored procedure . . . . . . . . . . . . . . . . . . . . . . . . 200
13-21 Employee.jar containing files for sqlj stored procedure EmpDtl1J . . . . . . . . . . . . . 202
13-22 SimpleInstallJar code (simplified) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
13-23 Sample DDL for registering the stored procedure EmpDtlsJ . . . . . . . . . . . . . . . . . 205
13-24 Commands to create the Employee.jar file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
13-25 DD cards for Java in WLM procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
13-26 EmpDtlsJ - Using JDBC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
13-27 DDL for EMPDTLSJ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
13-28 FTP the Java source code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
13-29 DDL for Java stored procedure EmpRsetJ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
13-30 Sample code for Java stored procedure EmpRsetJ . . . . . . . . . . . . . . . . . . . . . . . . 214
13-31 Sample Java application that calls DB2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
13-32 Host variable declarations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
13-33 SQL statement with host variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
13-34 EmpDtl1J.sqlj . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
13-35 EmpRst2J_UpdByPos.sqlj file - external file declaration . . . . . . . . . . . . . . . . . . . . 218
13-36 EmpRst2J.sqlj - Sample stored procedure - updating using positioned iterator . . . 218
13-37 Sample JCL for preparing the application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
13-38 DDL definition for the stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
13-39 db2sqljupgrade utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
13-40 Output listing of the upgrade utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
13-41 Error listing - Trying to run a sqlj stored procedure without upgrade . . . . . . . . . . . 225
13-42 Java application ExtractJar to extract a BLOB . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
13-43 Command to execute the ExtractJar java application . . . . . . . . . . . . . . . . . . . . . . . 227
14-1 Comment lines not allowed in SPUFI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
14-2 Assignment statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
14-3 CALL statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
14-4 CASE statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
14-5 GOTO statement. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
14-6 IF statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
14-7 LEAVE statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
14-8 LOOP statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
14-9 REPEAT statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
14-10 WHILE statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
14-11 Compound statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
14-12 GET DIAGNOSTICS statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
14-13 ITERATE statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
14-14 SIGNAL statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
14-15 RESIGNAL statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
14-16 RETURN statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
14-17 Qualifying a parameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
14-18 Qualifying a SQL variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
14-19 Qualifying a column name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
Examples xxvii
14-20 Parameter list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
14-21 Calling application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
14-22 MESSAGE_TEXT statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
14-23 Using SIGNAL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
14-24 Using RESIGNAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
14-25 Error received by the trigger when called stored procedure issues a rollback . . . . 250
15-1 Median_Result_Set SQL procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
15-2 STAFF table DDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
15-3 Insert into STAFF table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
15-4 Median_Result_Set SQL procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
15-5 SQLFORMAT parameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
15-6 Usage of functional comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
15-7 total staff salary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
15-8 Native SQL procedure: CALC_SALARY. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
15-9 Native SQL procedure: REBIND_PACKAGES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
15-10 Native SQL procedure: NODIFF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
15-11 GOTO sample . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
15-12 Another GOTO sample . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
15-13 Scoping label names (1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
15-14 Scoping label names (3) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
15-15 Scoping variable declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
15-16 Scoping cursor definitions (1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
15-17 Scoping cursor definitions (2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
15-18 Scoping condition names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284
15-19 Using compound statements in a condition handler . . . . . . . . . . . . . . . . . . . . . . . . 284
15-20 Scoping of condition handler declarations (1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
15-21 Empty compound statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
15-22 New data types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
15-23 Alter of active version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
15-24 Version ID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
15-25 Add new version: MEDIAN_V2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
15-26 Replace version MEDIAN_V2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
15-27 Drop Version MEDIAN_V1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
15-28 Sample Java invocation (1). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
15-29 Sample Java invocation (2). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
15-30 DISPLAY output - specific procedures have been stopped . . . . . . . . . . . . . . . . . . 304
15-31 DISPLAY output - all procedures in a schema have been stopped . . . . . . . . . . . . 305
15-32 DISPLAY output - procedures started. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
15-33 Debugged procedure (DISPLAY output). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
15-34 Comment on procedure MEDIAN_RESULT_SET . . . . . . . . . . . . . . . . . . . . . . . . . 306
15-35 DEBUG MODE ALLOW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 308
15-36 Error handling with compound statement in condition handlers . . . . . . . . . . . . . . . 309
15-37 Simulation of a compound block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310
15-38 GET STACKED DIAGNOSTICS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311
16-1 Sample referencing the additional parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
16-2 Program produced displays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329
16-3 Sample CREATE with LE runtime options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329
16-4 SDSF ST display. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
16-5 Job Data Set Display . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
16-6 Message in SYSDBOUT data set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
16-7 CEEDUMP output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
16-8 Compile SYSPRINT information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
16-9 LINKAGE SECTION of PRGTYPE1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
xxviii DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
17-1 Explicit CONNECT statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358
17-2 Implicit CONNECT due to qualified three-part name . . . . . . . . . . . . . . . . . . . . . . . . 359
17-3 Client program invoking local stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363
17-4 Client program invoking a remote stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . 364
17-5 Client program with local SQL and invoking remote stored procedure . . . . . . . . . . . 365
17-6 Stored procedures at multiple remote servers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365
18-1 DDL to create four code levels of the same stored procedure . . . . . . . . . . . . . . . . . 375
18-2 Sample contents of the configuration file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384
18-3 Sample job to invoke DDLMOD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385
18-4 SYSOUT produced from running DDLMOD REXX exec . . . . . . . . . . . . . . . . . . . . . 386
18-5 CREATE PROCEDURE statement before running DDLMOD . . . . . . . . . . . . . . . . . 386
18-6 CREATE PROCEDURE statement after running DDLMOD . . . . . . . . . . . . . . . . . . . 387
19-1 START TRACE command to monitor stored procedures . . . . . . . . . . . . . . . . . . . . . 403
19-2 Stored procedures trace block of DB2 PM Accounting Long Report . . . . . . . . . . . . 403
19-3 Package identification trace block of DB2 PM Accounting Long Report. . . . . . . . . . 404
19-4 Accounting Long Report showing stored procedure suspend time. . . . . . . . . . . . . . 404
19-5 Stored procedures trace block of DB2 PM Statistics Long Report . . . . . . . . . . . . . . 410
19-6 Sample JCL to produce RMF monitor 1 report . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411
19-7 Authorization Management section of a DB2 PM Statistics Report . . . . . . . . . . . . . 416
20-1 Portion of sample RMF Workload Activity report . . . . . . . . . . . . . . . . . . . . . . . . . . . 430
20-2 Sample DB2 Performance Monitor Accounting Report listing. . . . . . . . . . . . . . . . . . 431
21-1 Sample top 10 data set impact report . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437
21-2 Sample LLA definition to VLF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 438
22-1 CREATE global temporary table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443
22-2 CREATE RUNSTATP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443
22-3 Creating a global temporary table for SYSPRINT. . . . . . . . . . . . . . . . . . . . . . . . . . . 444
22-4 Handling the parameters. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444
22-5 Error checking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445
22-6 Includes and defines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445
22-7 Constants and messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 446
22-8 Data types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447
22-9 Defining error functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 450
22-10 Declaring variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 450
22-11 Declaring cursors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451
22-12 Initializing variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451
22-13 Allocating data structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452
22-14 Determining the subsystem ID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452
22-15 Input table spaces and thread IDs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452
22-16 Combining the output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453
22-17 Returning results and control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454
22-18 Function that calls DSNUTILS in a secondary thread. . . . . . . . . . . . . . . . . . . . . . . 455
22-19 Initializing local variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456
22-20 RRS IDENTIFY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456
22-21 RRS SIGNON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 457
22-22 RRS CREATE THREAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 457
22-23 Calling DSNUTILS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 458
22-24 Counting the SYSPRINT lines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 458
22-25 Disconnecting from the subsystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 460
22-26 Including DSN.SDSNC.H in the search path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 461
22-27 Unsuccessful call to DSNUTILS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463
22-28 RUNSTATP definition with SECURITY DEFINER . . . . . . . . . . . . . . . . . . . . . . . . . 464
22-29 Successful call to DSNUTILS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465
22-30 RRSAF function calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466
Examples xxix
22-31 AUTH SIGNON call. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466
22-32 Contexts for semaphore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467
23-1 CEMT command used to refresh a CICS program . . . . . . . . . . . . . . . . . . . . . . . . . 473
23-2 Sample EXCI call from stored procedure to CICS . . . . . . . . . . . . . . . . . . . . . . . . . . 473
23-3 Diagnostic field definition for stored procedure with EXCI call . . . . . . . . . . . . . . . . . 474
23-4 Result of EXCI call to EMPEXC2C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474
23-5 DDL to create sample stored procedure DSNACICS . . . . . . . . . . . . . . . . . . . . . . . . 475
23-6 Sample CALL to DSNACICS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476
23-7 Result of calling DSNACICS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477
23-8 IMS Stage 1 gen macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479
23-9 IMS DBDGEN source to define the DEPT database . . . . . . . . . . . . . . . . . . . . . . . . 479
23-10 IMS PSBGEN source for the load PSB, DEPTPSBL . . . . . . . . . . . . . . . . . . . . . . . 479
23-11 IMS PSBGEN source for the application PSB, DEPTPSB . . . . . . . . . . . . . . . . . . . 479
23-12 ACBGEN for the DEPT DBD and PSBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 480
23-13 IDCAMS defines for DEPT VSAM data set. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 480
23-14 Dynamic allocation definition for the DEPT database . . . . . . . . . . . . . . . . . . . . . . . 480
23-15 DBRC registration for the DEPT database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481
23-16 Load JCL and data for DEPT database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481
23-17 DFSPRP macro that creates the DRA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 482
23-18 Assembly JCL for the DFSPRP macro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 482
23-19 IMS online change input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 482
23-20 IMS commands to activate IMS gen changes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483
23-21 WLM environment for our DB2 COBOL ODBA case study. . . . . . . . . . . . . . . . . . . 483
23-22 WLM procedure for executing our DB2 COBOL stored procedure . . . . . . . . . . . . . 483
23-23 Sample logic for ODBA call to schedule a PSB . . . . . . . . . . . . . . . . . . . . . . . . . . . 483
23-24 Sample logic for ODBA call to read an IMS database record . . . . . . . . . . . . . . . . . 484
23-25 Sample logic for ODBA call to deallocate a PSB . . . . . . . . . . . . . . . . . . . . . . . . . . 484
23-26 Sample link edit step for stored procedure with ODBA call. . . . . . . . . . . . . . . . . . . 485
23-27 Parameter list EMPODB1C. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485
23-28 Sample CALL to DSNAIMS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485
23-29 DSNAIMS format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 486
23-30 PART transaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487
23-31 DSNAIMS execution in IBM DATA Studio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487
23-32 IMS command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488
23-33 IMS transaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488
23-34 Send only transaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488
23-35 Receive only transaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488
23-36 DSNAIMS2 DDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 489
23-37 Multi segment transaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 490
23-38 Single segment transaction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 490
23-39 Sample SQL CALL statement in a CICS program . . . . . . . . . . . . . . . . . . . . . . . . . 491
23-40 Sample SQL CALL statement in an IMS program . . . . . . . . . . . . . . . . . . . . . . . . . 492
24-1 Sample startup procedure for DSNWLM_UTILS . . . . . . . . . . . . . . . . . . . . . . . . . . . 507
24-2 Sample startup procedure for DSNWLM_GENERAL . . . . . . . . . . . . . . . . . . . . . . . . 508
24-3 Sample startup procedure for DSNWLM_REXX. . . . . . . . . . . . . . . . . . . . . . . . . . . . 508
24-4 Sample startup procedure for DSNWLM_CICS . . . . . . . . . . . . . . . . . . . . . . . . . . . . 511
24-5 Sample startup procedure for DSNWLM_JAVA . . . . . . . . . . . . . . . . . . . . . . . . . . . . 511
24-6 Sample startup procedure for DSNWLM_XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512
24-7 Sample startup procedure for DSNWLM_PROGRAM_CONTROL . . . . . . . . . . . . . 513
24-8 Sample startup procedure for DSNWLM_DEBUGGER . . . . . . . . . . . . . . . . . . . . . . 513
24-9 Sample startup procedure for DSNWLM_JAVA_LARGEMEM . . . . . . . . . . . . . . . . . 514
24-10 Sample startup procedure for DSNWLM_MQSERIES . . . . . . . . . . . . . . . . . . . . . . 515
24-11 Sample startup procedure for DSNWLM_WEB_SERIES . . . . . . . . . . . . . . . . . . . . 516
xxx DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
24-12 RACF program control JCL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520
24-13 SPUFI output for ADMIN_TASK_LIST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 572
24-14 Partial ADMIN_TASK_STATUS output. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 574
24-15 List all active tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 575
24-16 Typical grouping of key or value pairs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 593
24-17 XML_INPUT excerpt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 593
24-18 Complete Mode input document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 594
24-19 XML_OUTPUT excerpt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 596
24-20 XML_MESSAGE sample . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 596
24-21 Short Message Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 597
24-22 Key or value pairs for the version of the XML_OUTPUT or XML_MESSAGE
document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 599
24-23 Requested Locale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 599
24-24 Security level. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 600
24-25 XLM input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 600
24-26 XML output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 600
24-27 Complete Mode’ XML input. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 600
24-28 GET_MESSAGE XML_INPUT document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 601
24-29 GET_MESSAGE XML_OUTPUT document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 601
24-30 XML input documents associated with the GET_SYSTEM_INFO . . . . . . . . . . . . . 602
24-31 XML output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 602
24-32 Complete Mode’ document passed in the XML_INPUT . . . . . . . . . . . . . . . . . . . . . 602
24-33 GET_SYSTEM_INFO XML_INPUT document . . . . . . . . . . . . . . . . . . . . . . . . . . . . 603
24-34 GET_SYSTEM_INFO XML_OUTPUT document . . . . . . . . . . . . . . . . . . . . . . . . . . 604
24-35 XML output documents associated with the GET_CONFI . . . . . . . . . . . . . . . . . . . 604
24-36 GET_CONFIG XML_OUTPUT document. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 605
25-1 LOB table used in the case study . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 611
25-2 Sample CREATE PROCEDURE with BLOB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 611
25-3 EmpPhotJ.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 612
25-4 EmpPhotoSpServlet.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 613
25-5 Type4 Connection in a java Universal Driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 614
25-6 Java stored procedure handling large BLOBs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 615
25-7 DDL for EXTRACT_JAR stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 617
25-8 DDL for EMPCLOB stored procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 617
25-9 EmpClobJ java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 617
25-10 EmpClobSpServlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 618
25-11 DSN8910.PRODUCT sample table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 621
25-12 DSN8910.CUSTOMER sample table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 621
25-13 DSN8910.PURCHASEORDER sample table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 621
25-14 DSN8910.CATALOG sample table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 621
25-15 DSN8910.SUPPLIERS sample table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 622
26-1 Trigger invoking a UDF with a VALUES clause . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630
26-2 Trigger invoking a stored procedure with a CALL statement . . . . . . . . . . . . . . . . . . 631
26-3 Trigger invoking a stored procedure with transition variables . . . . . . . . . . . . . . . . . . 633
26-4 Trigger invoking a stored procedure with transition tables . . . . . . . . . . . . . . . . . . . . 634
26-5 Declaring input variables for table locators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 634
26-6 Declaring table locators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 634
26-7 Declaring a cursor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 634
26-8 Setting values of table locators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 635
26-9 Accessing the transition tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 635
26-10 Setting parameters in a user-defined function . . . . . . . . . . . . . . . . . . . . . . . . . . . . 637
26-11 Generating error messages in a trigger that invokes a UDF. . . . . . . . . . . . . . . . . . 638
27-1 How to verify the JCC version. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 649
Examples xxxi
27-2 Connecting and binding DC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 650
27-3 Sample CFGTPSMP configuration data set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 656
27-4 Register the procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 659
27-5 Bind the package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 660
27-6 Legacy JDBC Driver - SDK 1.3.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 663
27-7 Legacy JDBC Driver - SDK 1.4.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 663
27-8 Universal JDBC driver - SDK 1.3.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 663
27-9 Universal JDBC driver - SDK 1.4.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 663
27-10 Example of generated SQLJ code using fragments . . . . . . . . . . . . . . . . . . . . . . . . 699
27-11 Adding a parameter to a Java stored procedure. . . . . . . . . . . . . . . . . . . . . . . . . . . 711
27-12 Java stored procedure with multiple SQL statements and one result set. . . . . . . . 713
27-13 SQL stored procedure with multiple SQL statements and multiple result sets . . . . 714
27-14 Output of ant deploy of stored procedure EMPDTLSS . . . . . . . . . . . . . . . . . . . . . . 720
27-15 Output of ant deploy of SQLJTEST and JDBCTEST . . . . . . . . . . . . . . . . . . . . . . . 721
28-1 Define DB2UDSMD to RACF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 741
28-2 Job to create a file in HFS to hold the environment settings. . . . . . . . . . . . . . . . . . . 742
28-3 Sample started task JCL for the Session Manager on z/OS. . . . . . . . . . . . . . . . . . . 743
28-4 Coding long PARM field into next line. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 744
28-5 DB2UDSMD procedure with STDPARM. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 745
28-6 Authorization error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 745
28-7 BUILD_DEBUG function was completed successfully . . . . . . . . . . . . . . . . . . . . . . . 749
28-8 Modified EMPTDTLSS source for IBM Data Studio to build/debug on DB9A. . . . . . 751
28-9 WLM AE procedure for running DB2 COBOL stored procedures . . . . . . . . . . . . . . . 763
28-10 WLM AE sample procedure for ELAXMREX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 763
28-11 Modified Cobol stored procedure source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 771
28-12 COBOL compile procedure example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 774
28-13 Determine workstation IP address . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 776
28-14 CREATE PROCEDURE definition showing the IP address and port . . . . . . . . . . . 776
28-15 ALTER PROCEDURE for TCP/IP address . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 776
28-16 Deploy Java stored procedure in debug mode on Windows. . . . . . . . . . . . . . . . . . 782
28-17 Start the Session Manager on the client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 783
A-1 AdminSystemInformation class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 808
A-2 Defining a bitmask for each utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 809
A-3 Errors on argument verification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 809
A-4 Load and connect with type 2 driver for COM.ibm.db2.jdbc.app.DB2Driver . . . . . . . 810
A-5 Preparing the CallableStatement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 810
A-6 Error handling in the procedure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 811
A-7 Retrieving the domain name. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 811
A-8 Calling DSNWZP and handling the output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 812
A-9 Running DIAGNOSE through DSNUTILU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 812
A-10 Parsing DSNU8621 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 813
A-11 Displaying the installed utilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 814
A-12 The finally block code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 814
A-13 Setting and getting the return code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 815
A-14 Output from AdminSystemInformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 816
A-15 AdminWLMRefresh source code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 817
A-16 AdminDB2Command class. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 820
A-17 Response to AdminDB2Command. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 826
A-18 AdminUtilityExecution Invoking RUNSTATS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 828
A-19 AdminUtilityExecution output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 836
A-20 AdminDataSet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 838
A-21 Response to AdminDataSet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 844
A-22 AdminJob . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 845
xxxii DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
A-23 Response to AdminJob . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 850
A-24 AdminUNIXCommand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 852
A-25 Response to AdminUNIXCommand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 854
A-26 AdminDSNSubcommand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 855
A-27 Response to AdminDSNSubcommand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 857
A-28 ADMIN_TASK_ADD parm initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 858
A-29 DDL for the table for the trigger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 862
A-30 Scheduling trigger. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 862
A-31 Trigger calling ADMIN_TAK_REMOVE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 863
A-32 Sample invocation of non-regularly recurring procedure with dynamic parameters . 864
A-33 initialization of the ADMIN_TASK_ADD stored procedure . . . . . . . . . . . . . . . . . . . . 865
A-34 Task scheduler housekeeping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 866
A-35 ADMIN_TASK_LIST output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 869
A-36 CompleteMode.xml document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 870
A-37 SPDriver.java - part 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 870
A-38 SPDriver.java - part 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 872
A-39 SPWrapper.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 875
A-40 SPDriver.java output traces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 882
A-41 GetConfigDriver.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 883
Examples xxxiii
xxxiv DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Notices
This information was developed for products and services offered in the U.S.A.
IBM may not offer the products, services, or features discussed in this document in other countries. Consult
your local IBM representative for information on the products and services currently available in your area. Any
reference to an IBM product, program, or service is not intended to state or imply that only that IBM product,
program, or service may be used. Any functionally equivalent product, program, or service that does not
infringe any IBM intellectual property right may be used instead. However, it is the user's responsibility to
evaluate and verify the operation of any non-IBM product, program, or service.
IBM may have patents or pending patent applications covering subject matter described 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:
IBM Director of Licensing, IBM Corporation, North Castle Drive, Armonk, NY 10504-1785 U.S.A.
The following paragraph does not apply to the United Kingdom or any other country where such
provisions are inconsistent with local law: INTERNATIONAL BUSINESS MACHINES CORPORATION
PROVIDES THIS PUBLICATION "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR
IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Some states do not allow disclaimer of
express or implied warranties in certain transactions, therefore, this statement may not apply to you.
This information could include technical inaccuracies or typographical errors. Changes are periodically made
to the information herein; these changes will be incorporated in new editions of the publication. IBM may make
improvements and/or changes in the product(s) and/or the program(s) described in this publication at any time
without notice.
Any references in this information to non-IBM Web sites are provided for convenience only and do not in any
manner serve as an endorsement of those Web sites. The materials at those Web sites are not part of the
materials for this IBM product and use of those Web sites is at your own risk.
IBM may use or distribute any of the information you supply in any way it believes appropriate without incurring
any obligation to you.
Information concerning non-IBM products was obtained from the suppliers of those products, their published
announcements or other publicly available sources. IBM has not tested those products and cannot confirm the
accuracy of performance, compatibility or any other claims related to non-IBM products. Questions on the
capabilities of non-IBM products should be addressed to the suppliers of those products.
This information contains examples of data and reports used in daily business operations. To illustrate them
as completely as possible, the examples include the names of individuals, companies, brands, and products.
All of these names are fictitious and any similarity to the names and addresses used by an actual business
enterprise is entirely coincidental.
COPYRIGHT LICENSE:
This information contains sample application programs in source language, which illustrate programming
techniques on various operating platforms. You may copy, modify, and distribute these sample programs in
any form without payment to IBM, for the purposes of developing, using, marketing or distributing application
programs conforming to the application programming interface for the operating platform for which the sample
programs are written. These examples have not been thoroughly tested under all conditions. IBM, therefore,
cannot guarantee or imply reliability, serviceability, or function of these programs.
The following terms are trademarks of the International Business Machines Corporation in the United States,
other countries, or both:
Redbooks (logo) ® DB2 Connect™ OS/2®
developerWorks® DB2 Universal Database™ OS/390®
iSeries® DB2® QMF™
i5/OS® DFS™ Rational®
pureXML™ DFSMS™ Redbooks®
z/Architecture® DFSORT™ RACF®
z/OS® DRDA® REXX™
zSeries® DYNIX/ptx® RMF™
z9™ Informix® S/390®
AD/Cycle® IBM® System z™
AIX® IMS™ System z9®
C/370™ Language Environment® System/390®
CICS® MQSeries® Tivoli®
COBOL/370™ MVS™ VisualAge®
Distributed Relational Database MVS/ESA™ VTAM®
Architecture™ OMEGAMON® WebSphere®
SAP, and SAP logos are trademarks or registered trademarks of SAP AG in Germany and in several other
countries.
Oracle, JD Edwards, PeopleSoft, Siebel, and TopLink are registered trademarks of Oracle Corporation and/or
its affiliates.
Java, JDBC, JDK, JNI, JRE, JVM, Solaris, and all Java-based trademarks are trademarks of Sun
Microsystems, Inc. in the United States, other countries, or both.
ESP, Microsoft, Windows NT, Windows Vista, Windows, and the Windows logo are trademarks of Microsoft
Corporation in the United States, other countries, or both.
Intel, Intel logo, Intel Inside logo, and Intel Centrino logo are trademarks or registered trademarks of Intel
Corporation or its subsidiaries in the United States, other countries, or both.
UNIX is a registered trademark of The Open Group in the United States and other countries.
Linux is a trademark of Linus Torvalds in the United States, other countries, or both.
Other company, product, or service names may be trademarks or service marks of others.
xxxvi DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Summary of changes
This section describes the technical changes made in this edition of the book and in previous
editions. This edition may also include minor corrections and editorial changes that are not
identified.
Summary of Changes
for SG24-7604-00
for DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
as created or updated on February 17, 2011.
New information
Added a sentence at 3.3, “Sample application components” on page 24.
Added a sentence at 9.1.12, “Stored procedure load module in memory” on page 104.
Added UK33845 for PK57235 in Table 24-12 on page 503.
Added a note on APAR PK64298 at page 605.
Added “Some considerations when coding the DB2UDSMD started task” on page 744.
Changed information
Corrections for GET_SYSTEM_INFO in Table 24-13 on page 504.
Corrections in Chapter 22, “Multi-threaded stored procedures in the C language” on
page 441.
New information
Added a reference to Data Studio and DB2 for z/OS Stored Procedures, REDP-4717, in
preface and back cover.
Added considerations on closing cursors as follows::
– Added text in bullet 9 on page 16.
– Added bullet 13 on page 130.
– Added text in Table 10-4 on page 137.
– Added bullet 8 on page 166.
– Added text in 19.1.2, “The execution life cycle of a stored procedure” on page 394.
xxxviii DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Preface
This IBM® Redbooks® publication helps you design, install, manage, and tune stored
procedures with DB2® 9 for z/OS®. Stored procedures can provide major benefits in the
areas of application performance, code re-use, security, and integrity. DB2 has offered
ever-improving support for developing and operating stored procedures.
In these days, three years is a generation in the software business; if you have DB2 9 for
z/OS, this book replaces the previous DB2 for z/OS Stored Procedures: Through the CALL
and Beyond, SG24-7083; it reflects the changes that have been made to DB2 stored
procedures and related tools from V8 to V9.
We talk about the external and native SQL procedures, the debugging options, the special
registers, the deployment, and diagnostics.
A chapter is devoted to the increasing number of DB2-supplied stored procedures. They can
be used for almost all of a DBA’s tasks.
We also devote a part to tools that can be used for accelerating the development process and
go into some detail about the stored procedure support provided by the latest IBM product:
Data Studio. For recent information on Data Studio, refer to Data Studio and DB2 for z/OS
Stored Procedures, REDP-4717.
Paolo Bruni is a DB2 Information Management Project Leader at the International Technical
Support Organization, San Jose Center. He has authored several Redbooks about DB2 for
z/OS and related tools, and has conducted workshops and seminars worldwide. During
Paolo's many years with IBM, in development, and in the field, his 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 14 years of experience working with DB2. Before joining
IBM in 1998, she worked for a third-party vendor providing second-level support for DB2
utilities. She is experienced in DB2 system programming and client/server implementations in
the insurance industry in Germany. She is also a co-author of the IBM Redbooks DB2 UDB
for OS/390 and Continuous Availability, SG24-54866; Cross-Platform DB2 Distributed Stored
Procedures: Building and Debugging, SG24-5485-01; DB2 UDB for z/OS Version 8:
Everything You Ever Wanted to Know, ... and More, SG24-6079; and DB2 9 for z/OS
Technical Overview, SG24-7330.
Glenn McGeoch is a Senior DB2 Consultant for IBM's DB2 for z/OS Lab Services
organization in the United States, working out of San Francisco, CA. He has 30 years of
experience in the software industry, with 22 years of experience working with DB2 for z/OS.
He holds a degree in Business Administration from the University of Massachusetts and an
MBA from Rensselaer Polytechnic Institute. Glenn worked for 19 years as an IBM customer
with a focus on CICS® and DB2 application development, and has spent the last 11 years
with IBM assisting DB2 customers. His areas of expertise include application design and
performance, stored procedures and DB2 migration planning. He has presented to regional
DB2 User Groups and to customers on various DB2 topics. Glenn co-authored the previous
edition DB2 for z/OS Stored Procedures: Through the CALL and Beyond, SG24-7083.
xl DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
The authors from left to right: Jan Vandensande, Marichu Scanlon, Sabine Kaschta, Marcel Kutsch,
Glenn McGeoch, and Paolo Bruni
Rich Conway
Emma Jacobs
Bob Haimowitz
Yvonne Lyon
Deanna Polm
Sangam Racherla
International Technical Support Organization
Debra Eaton
DB2 Migration Team, Chicago
Paul Wirth
IBM Grand Rapids, MI
George M. Young
IBM Lexington, KY
Melissa Biggs
Ben Budiman
Moira Casey
Steve Chen
Clifford Chu
Preface xli
Zeus Courtois
Thanh Dao
Larry England
Marion Farber
Christopher Farrar
Mel Fowler
Gary Hochmuth
Grant Hutchison
Terrie Jacopi
Gopal Krishnan
Gary Lazzotti
Hung P Le
Ellen Livengood
Adrian Lobo
Vikram Manchala|
Bruce McAlister
Claire McFeely
Robert T. Miller
Tom MIller
Todd Munk
Roger Miller
Tom Miller
Barbara Nardi
Brian Payton
Jim Pickel
Akira Shibamiya
Manogari Simanjuntak
Hugh Smith
Marc Terwagne
Yumi Tsuji
Rich Vivenza
Limin Yang
Joseph Yeh
Peter Wansch
Eva Wu
Jay Yothers
Xavier Yuen
Peggy Zagelow
Emily Zhang
Liyan Zhou
Ruiming Zhou
IBM Silicon Valley Lab
Peter Aarnoutse
Jan Panneels
Sogeti Belgium
Michel Castelein
ARCIS Services Belgium
Rick Butler
BMO Canada
Glenn Anderson
IBM USA
xlii DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Martin Packer
IBM UK
Leif Pedersen
IBM Denmark
Marc Terwagne
IBM Belgium
Willi Jorg
Johannes Schuetzner
IBM Germany
Boris Charpiot
Knut Stolze
Wolfgang Dunz
Benno Staebler
IBM Boeblingen Lab
Debbie Yu
Yves Tolod
Serge Rielau
IBM Toronto Lab
Fang Xing
Yong Hua (Henry) Zeng
China Software Development Lab
Bhaskar Achanti
Suneel Konidala
Glenn McGeoch
Martin Packer
Peggy Rader
Suresh Sane
Bonni Taylor
Peter Wansch
Your efforts will help increase product acceptance and customer satisfaction. As a bonus, you
will develop a network of contacts in IBM development labs, and increase your productivity
and marketability.
Find out more about the residency program, browse the residency index, and apply online at:
ibm.com/redbooks/residencies.html
Preface xliii
Comments welcome
Your comments are important to us!
We want our books to be as helpful as possible. Send us your comments about this book or
other IBM Redbooks in one of the following ways:
Use the online Contact us review Redbooks form found at:
ibm.com/redbooks
Send your comments in an e-mail to:
[email protected]
Mail your comments to:
IBM Corporation, International Technical Support Organization
Dept. HYTD Mail Station P099
2455 South Road
Poughkeepsie, NY 12601-5400
xliv DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Part 1
Part 1 Introduction
In this part we introduce the stored procedures and the contents of the book:
Chapter 1, “Importance of stored procedures” on page 3 introduces the stored procedures
and explains the reasons for their importance.
Chapter 2, “Stored procedures overview” on page 9 summarizes the main building blocks
for stored procedures.
Chapter 3, “Our case study” on page 23 defines the environment and the case study that
were implemented during this project.
Stored procedures can be called locally (on the same system where the application runs) and
remotely (from a different system). However, stored procedures are particularly useful in a
distributed environment since they considerably improve the performance of distributed
applications by:
Reducing the traffic of information across the communication network
Splitting the application logic and encouraging an even distribution of the computational
workload
Providing an easy way to call a remote program
The advantages provided by stored procedures are clear when comparing them to a standard
distributed application where the client may be a workstation or a Java client as shown in
Figure 1-1. We see that the client communicates with the server separately for each
embedded SQL request.
R e m o te
C lie n t DB2
A p p lic a tio n fo r z /O S
D B 2 fo r z /O S D B 2 O b je c ts
Exec SQ L P e r fo r m S Q L p r o c e s s in g
Ta b le
SELECT ....
. . .
Exec SQ L P e r fo r m S Q L p r o c e s s in g
UPDATE ... Ta b le
. . .
Exec SQ L P e r fo r m S Q L p r o c e s s in g
IN S E R T Ta b le
. . .
The client communicates with the server with a send and receive operation through the
network for each SQL statement embedded in the program. As a consequence, the elapsed
time is increased by network transmission time or Java overhead, the remote CPU path
length is higher than for a local SQL cost, and DB2 locks are held until commit.
Figure 1-2 shows the stored procedure solution. We have moved the embedded SQL to the
server, reducing the network traffic to a single call and return.
4 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
R e m o te
C lie n t A p p lic a t io n D B 2 fo r z /O S
D a ta b a s e DB2
REMSP S e r v ic e s O b je c ts
GOBACK
The same SQL previously executed by the client has been stored on the server and is called
by the client whenever necessary. The invocation is treated as a regular external call:
The application waits for the stored procedure to terminate.
Parameters can be passed back and forth.
6 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
– Utilize Recoverable Resource Services (RRS) to coordinate two-phase commit
processing of recoverable resources
When the details of trigger and User Defined Function (UDF) processing go beyond the
scope of SQL statements, stored procedures can be called for the application logic.
To transport messages using MQSeries® functions that:
– Notify other business processes that an event has taken place
– Forward information from one process to many other processes
– Aggregate information from multiple sources to create warehouses and Operational
Data Stores (ODSs). See Building the Operational Data Store on DB2 UDB Using IBM
Data Replicator, WebSphere MQ Family, and DB2 Warehouse Manager, SG24-6513
for more details.
Stored procedures provide the easiest way to perform a remote call and distribute the
execution logic of an application. Because stored procedures reside on the data base server
and therefore can access programs and features of the server, a myriad of application
solutions are available.
Stored procedures should be considered for a client/server application when the procedure
does at least one of the following:
Executes two or more SQL statements
Remote SQL statements can create many network send and receive operations, which
results in increased processor costs.
Contains manipulative and or logical processing that must be consistent across multiple
processes, and the goal is to provide coding that is reusable and therefore requires
minimal maintenance efforts.
Accesses host variables or table columns for which you want to guarantee security and
integrity.
Multi-tiered (three or more tiers) client/server applications greatly reduce the deployment
issues because DB2 enablers and business logic are kept on the lower tiers. The client has
the presentation layer of the system while the business logic is on the middle tier and the
database access on the server tier.
Because stored procedures reside and execute on the database server (or the server tier),
they can be developed and installed with minimal maintenance activity. Stored procedures
support and encourage what is, by far, the most pervasive of current computing trends.
8 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
2
There are different types of stored procedures, as well as operating environments. Because
stored procedures are DB2 objects, they must be defined to the DB2 catalog and then the
integrity of the parameters to be passed is protected.
The first two types of stored procedures result in an external load module being created and
they run in Workload Manager (WLM) address spaces. The third type of procedure does not
result in a load module being created and they run in the DBM1 address space. For each of
the last two types of stored procedures the source code is written entirely in SQL, with the
program logic being part of the stored procedure definition (within the CREATE PROCEDURE
statement itself). For external high-level language stored procedures, the stored procedure
definition and the program logic are two separate components.
In the next few sections we provide a more detailed description of each type of stored
procedure.
The source code for an external high-level language stored procedure is separate from the
definition of the stored procedure. A stored procedure is only bound to a package and not a
plan because it utilizes the invoking plan’s thread. The stored procedure load module must be
placed in a load library that is included in the STEPLIB DD concatenation in the WLM startup
JCL (except for Java stored procedures). See Part 3, “Developing stored procedures” on
10 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
page 89 for programming details, and Part 2, “Operating environment” on page 37 for setting
up the stored procedure environment.
The CREATE PROCEDURE statement is used to inform the system of the name of the load
module and what parameters are expected when the procedure is called, as well as other
execution and environment options. See Chapter 9, “Defining stored procedures” on page 91
for details.
Example 2-2 shows the information from a CREATE PROCEDURE statement that DB2
needs to locate the load module and to know what source language will be used to create the
stored procedure.
The ISO/ANSI SQL:2003 is an open solution for SQL among database management system
vendors that support the SQL ISO/ANSI standard. Because this approach is widely used by
other RDBMS providers, this support makes it possible to port stored procedures from the
other vendors to DB2 and vice versa.
The SQL Procedures language implementation supports constructs that are common to most
programming languages. It supports the declaration of local variables, assignment of
expression results to variables, statements to control the flow of the procedure, receiving and
returning of parameters from and to the invoker, returning result sets and error handling.
Like an external high-level language stored procedure, an external SQL language procedure
consists of a stored procedure definition, source code for the stored procedure program and a
load module (which will be a C language module for external SQL language procedures).
Most of the CREATE PROCEDURE options are the same. In both cases you specify the
name of the external load module and your input and output parameters the same way. The
Example 2-3 shows the statement to CREATE an external SQL language procedure to
update employees’ salaries.
Example 2-3 CREATE PROCEDURE sample for external SQL language procedures
CREATE PROCEDURE UPDATE_SAL
( IN INRATE DECIMAL (7,2), IN INEMPNO CHAR(6))
LANGUAGE SQL
UPDATE EMP
SET SALARY = SALARY * INRATE
WHERE EMPNO = INEMPNO
For the details on creating external SQL language procedures, see Chapter 14, “External
SQL procedures” on page 233.
No external load module is created for native SQL language procedures. The entire
executable is contained within DB2. When you create a native SQL stored procedure, the
procedural SQL statements are stored in the DB2 catalog and directory, as are the SQL
statements that are used for accessing your DB2 data. As a result, when you prepare a native
SQL procedure, the entire executable is contained within DB2. This simplifies the deploy
process since you don’t have to worry about code level management in load libraries and in
WLM application environments.
The advantage of this approach is that DB2 can manage these stored procedures directly.
The stored procedures run in the DBM1 address space, so there is no need to create a WLM
environment to manage the procedures. Since native SQL procedures run under an enclave
SRB instead of a TCB, if they are remote, they are also eligible to be run in a System z9™
Integrated Information Processor (zIIP) if one is available.
A zIIP is a specialty engine for System z9 mainframes. z/OS manages and directs work
between the general purpose processor (the portion of the mainframe that traditionally has
handled the z/OS workload) and the zIIP. Work that runs on the zIIP does not incur software
charges based on the service units consumed, therefore it is a very attractive lower-cost
alternative to running workloads on a general purpose processor.
Figure 2-1 shows how work is redirected from the z/OS general purpose processor to the zIIP
specialty engine. On the left side of the picture you can see that all the DRDA work is
executing on the general purpose processor (the CP). On the right side of the picture, with the
zIIP specialty engine available, some of the DRDA work is executing on the zIIP, thus
reducing the software costs of work running on the CP and also reducing the workload on the
CP so you can now run additional work there if needed.
12 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
z/OS Redirect of Native SQL Procedures to zIIP Specialty Engine
Enterprise Applications that access DB2 for z/OS V8 via DRDA, including DB2 9 Native SQL Stored
Procedures, over a TCP/IP connection will have portions of these SQL requests directed to the zIIP.
CP zIIP
CP
High utilization
DB2/DRDA
DB2/DRDA Portions of
eligible DB2
Enterprise DB2/DRDA
Reduced utilization enclave SRB
Application DB2/DRDA DB2/DRDA workload
(including
DB2/DRDA DB2/DRDA
TCP/IP native SQL
(via Network DB2/DRDA DB2/DRDA procedures)
or
HiperSockets) DB2/DRDA DB2/DRDA DB2/DRDA executed on
zIIP
DB2/DRDA DB2/DRDA DB2/DRDA
Figure 2-1 z/OS redirect of native SQL procedures to the zIIP specialty engine
For more information on the zIIP specialty engine and what portion of your DB2 workload is
eligible to be redirected to a zIIP, see Chapter 4 of DB2 9 for z/OS Performance Topics,
SG24-7473. For the details on creating native SQL procedures, see Chapter 15, “Native SQL
procedures” on page 253.
An employee is transferred to another department and, optionally, may also become the new
department manager. The stored procedure XREFEMP first inserts into the XFER_EMPPA
table any existing project activities that the employee has affiliations with, and removes the
corresponding rows from the EMPPROJACT table. If any rows were deleted, a project
management process needs to be informed. This process will handle any project activities
that are incomplete because of an employee transfer. We chose to use the MQSeries
functions of DB2 to notify the process from a performed routine, SEND-MSG-TO-PROJ. The
details of using MQSeries functions can be found in DB2 Version 9.1 for z/OS Application
Programming and SQL Guide, SC18-9841.
Be assured that this stored procedure will do the rest, or report any errors that are
encountered.
Throughout this book, we examine the components, services and considerations that must be
integrated to ensure success.
CLIENT
Database Services
EXEC SQL
CONNECT TO
:LOCATION; 1
Create Thread
DB2 for z/OS
SPAS
EXEC SQL 2 3
CALL XFEREMP
Get information from XREFEMP
SYSIBM.SYSROUTINES
(:EMPNO AND SYSIBM.SYSPARMS
,:EMPDEPT
Schedule, 4 5 6
prepare parameters, and
,:NEWMGR pass control to the stored
,:PRETCODE procedure
INSERT INTO XFER_EMPPA
,:PMESSAGE); Process SQL
7 SELECT *
FROM EMPPROJACT
WHERE EMPNO = :EMPNO
IF SQLERRD(3) > 0
PERFORM SEND-MSG-TO-PROJ
END-IF
IF NEWMGR = 'Y'
UPDATE DEPT
Process SQL 7 SET MGRNO = :EMPNO
WHERE DEPTNO = :EMPDEPT
END-IF
MOVE 0 TO PRETCODE 8
MOVE 'SUCCESSFUL XFER' TO
10 Control passed
PMESSAGE
1. A thread must be created for each application that needs DB2 services. If the stored
procedure is called from a remote client, the thread is created when the client application
issues the SQL CONNECT statement. If the application is local, the thread is created
when the first SQL statement is executed. After the thread is created, SQL statements can
be executed.
2. When a client application issues an SQL CALL statement, the stored procedure name and
the I/O parameters are passed to DB2.
14 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
3. When DB2 receives the SQL CALL statement, it searches in the SYSIBM.SYSROUTINES
catalog table for a row associated with the stored procedure name. From this table, DB2
obtains the load module associated with the stored procedure and the run environment
information. It also searches SYSIBM.SYSPARMS to gather the parameter information,
such as whether a parameter is input, output or input/output, and the data type of each
expected parameter. Notice that catalog information is cached to avoid I/O.
For details on the search of SYSIBM.SYSROUTINES and how DB2 determines which
version of the stored procedure to execute, see 18.2, “Versioning of stored procedures” on
page 373.
4. With the exception of native SQL language procedures, stored procedures are executed in
address spaces that run fenced away from the DB2 code. Multiple Workload Manager
(WLM) address spaces may be made available for stored procedures. Starting with DB2
for z/OS V8, all newly created stored procedures must use the WLM-established stored
procedure address spaces. Those stored procedures that existed prior to Version 8 and
were created to run in the DB2-managed address space will continue to run, but all new
stored procedures must run in a WLM-managed stored procedure address space. In DB2
9 for z/OS all stored procedures, except for native SQL procedures, are WLM-managed.
WLM goal mode is mandatory. You can specify a number of task control blocks (TCBs) in
this address space available for stored procedures. Each stored procedure is executed
under one TCB. After DB2 has searched the SYSIBM.SYSROUTINES table, an available
TCB to be used by the stored procedure is selected, and the stored procedure address
space is notified to execute the stored procedure.
5. When the stored procedure address space executes a stored procedure, the thread that
was created for the client application is reused for the execution. This has the following
implications:
– CPU cost is low because DB2 does not create a new thread.
– Accounting is on behalf of the client application.
– For static SQL, the OWNER of the client program must have execute privilege on the
stored procedure package. For dynamic SQL issued by the stored procedure, security
is checked against the user of the client program, unless the DYNAMICRULES(BIND)
option was specified when binding the package for the stored procedure. No sign-on or
connection processing is required.
– The stored procedure address space uses the LE/370 product libraries to load and
execute the stored procedure. Through SYSIBM.SYSROUTINES, you can pass
runtime information for LE/370 when the stored procedure is executed.
6. Control is passed to the stored procedure along with the input and output parameters.
– The stored procedure can issue most SQL statements. It also can have access to
non-DB2 resources.
– The stored procedure can either perform all the database access and return the output
to the calling program as output parameters (see the next step) or it can open a cursor
to build a result set and let the calling program fetch from the result set.
– Any processing done by the stored procedure is considered a logical continuation of
the client application's unit of work. Thus, locks acquired by the stored procedure are
released when the unit of work terminates. If DB2 has been so instructed, through the
definition of the stored procedure, it can commit the logical unit of work upon return to
the caller.
7. Before terminating, the stored procedure assigns values to any output parameters and
returns control to DB2.
SYSIBM.SYSROUTINES contains one row for each created stored procedure. The
information contained in this table is from the CREATE PROCEDURE statement. There are
columns in this catalog table describing the runtime environment, language, number of
parameters, parameter style, whether or not result sets can be returned, whether DB2 should
execute a commit when returning to the caller, and so on.
Example 2-4 is a query that you can use to retrieve information about the runtime
environment of a stored procedure.
Example 2-5 QMF output for query to retrieve stored procedure runtime information
PROCEDURE NAME: DEVL7083.PAOLOR1.EMPDTL2C
*****************************************************************
COLLECTION ID: DEVL7083 LANGUAGE: COBOL EXT. NAME: EMPDTL2C
RUN OPTIONS: ()
16 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
SQL DATA ACCESS: M RESULT SETS RETURNED: 0
COMMIT ON RETURN: N
For details on producing the QMF report, refer to DB2 QMF Reference Version 9 Release 1,
SC18-9685.
SYSIBM.SYSPARMS contains one row for each parameter defined in stored procedures. The
parameter information comes from the CREATE PROCEDURE statement. The columns in
this catalog table describe the parameter definitions: name, data types, input (notated with a
P), output, input/output (notated with a B), and optionally whether the parameter row is
associated with a locator or table.
SYSIBM.SYSROUTINES SYSIBM.SYSPARMS
A query can then be created to gather information from the catalog about a stored procedure
and its expected parameters. Example 2-6 shows such a query.
Example 2-6 Query to retrieve information about expected parameters of a stored procedure
SELECT RTRIM("SCHEMA")||'.'||RTRIM(OWNER)||'.'||RTRIM("NAME")
, ' '||STRIP(DIGITS(PARM_COUNT),L,'0')||' PARMS'||'/'||PARAMETER_STYLE,' '
,' ' , "DBINFO"||' ',SQL_DATA_ACCESS||' '
Note: The QMF queries and forms used in this chapter can be downloaded from the ITSO
Web site as additional material. Download instructions are in Appendix B, “Additional
material” on page 887.
Additional catalog tables are used for Java stored procedures and for SQL language stored
procedures, both external and native. Information about Java stored procedures is contained
in the following tables:
SYSIBM.SYSJARCLASS_SOURCE
SYSIBM.SYSJARCONTENTS
SYSIBM.SYSJARDATA
18 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
SYSIBM.SYSJAROBJECTS
SYSIBM.SYSJAVAOPTS
SYSIBM.JAVAPATHS
Information about external SQL language and native SQL language stored procedures is
contained in the following tables:
SYSIBM.SYSENVIRONMENT
SYSIBM.SYSROUTINES_OPTS
SYSIBM.SYSROUTINES_SRC
SYSIBM.SYSROUTINESTEXT
SYSIBM.SYSROUTINESAUTH
For more details about creating Java, external SQL language and native SQL language
procedures, see Chapter 13, “Java stored procedures” on page 181, Chapter 14, “External
SQL procedures” on page 233 and Chapter 15, “Native SQL procedures” on page 253.
Distributed
Distributed
Application
Application
1
CALL sp
z/OS
z/OS
DB2 WLM WLMAE
Batch Application
DDF Work Queues
8 2 3
4 4 4
1 2
CALL sp SYSROUTINES
R
2 8 7 6 5 5 5
R
CICS application
WLM SPAS WLM SPAS
WLM SPASs S
9
1 Select * from ....
CALL sp
20 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
7. When the stored procedure reaches the return statement, it passes control back to DB2
with or without results, depending on the logic.
8. DB2 passes control back to the calling program with or without results, depending on the
logic.
9. Since the transactions involving stored procedures can span multiple address spaces,
RRS plays the role of coordinator for all the resources between all address spaces
involved in the transaction.
Steps 1 to 8 are repeated for each execution of a stored procedure. If a stored procedure calls
another stored procedure, all these steps are again repeated.
All the files required to reconstruct the sample applications can be downloaded from the IBM
Redbooks Web site:
http://www.ibm.com/redbooks
z9 (2094-S18) processor in an LPAR with 4 GB central storage and six logical processors:
Two general processors
Two Integrated Information Processors (zIIP)
Two Application Assist Processors (zAAP)
The second set of stored procedures selects the department name from the DEPT sample
table, using a department number value (column DEPTNO) supplied by the calling program,
then selects all rows from the EMP sample table where the WORKDEPT column matches the
department number supplied. The EMP table rows are returned in a result set to the calling
program. Variations are shown for Java stored procedures to show use of a positioned iterator
and use of a named iterator.
24 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Some additional samples are provided to show how to do the following:
Write multi-threaded stored procedures in C
Write stored procedures that interact with CICS and IMS
Write applications to call DB2-supplied stored procedures
Call stored procedures from triggers and user defined functions
Access XML data
Some of the Java and SQL language stored procedures were imported into IBM Data Studio
in our DB2 9 for z/OS system to show you how to create and debug stored procedures using
the GUI capabilities of IBM Data Studio. See 27.5.1, “Creating a new native stored procedure
using the wizard” on page 689, 27.5.2, “Creating an external SQL stored procedure from the
wizard” on page 694 and 27.5.3, “Creating a Java stored procedure from the wizard” on
page 696 for details on creating native SQL, external SQL and Java language stored
procedures within the IBM Data Studio product. See 28.3, “Debugging SQL procedures on
z/OS, Linux, UNIX, and Windows” on page 746 for details on debugging sample SQL stored
procedure EMPDTLSS.
We did not code and test any Assembler language stored procedures. If you would like to see
a sample Assembler language stored procedure, refer to SDSNSAMP library member
DSNTWR, which is the load module for the WLM_REFRESH stored procedure. Instructions
to prepare this stored procedure can be found in the DB2 Version 9.1 for z/OS Installation
Guide, GC18-9846.
Our sample stored procedures were run on DB2 9 for z/OS, except where noted, using copies
of the sample tables provided with DB2. Table 3-1 lists the sample tables.
a.This table contains XML data. Refer to 3.4, “Populating the tables with XML
data” on page 34 for details on how to populate this table.
Table 3-2 on page 26 lists the objects that were used for the COBOL programming examples.
Stored EMPDTL1C COBOL stored procedure that returns employee data for a supplied
procedure employee number, using parameter style GENERAL
EMPDTL2C COBOL stored procedure that returns employee data for a supplied
employee number, using parameter style GENERAL WITH NULLS
EMPDTL3C COBOL stored procedure that returns employee data for a supplied
employee number, using parameter style DB2SQL with NO DBINFO
EMPDTL4C COBOL stored procedure that returns employee data for a supplied
employee number, using parameter style DB2SQL with DBINFO
Called EMPEXC2C COBOL CICS program invoked through EXCI by stored procedure
program EMPEXC1C
User- EMPAUDTU COBOL user-defined function invoked by a trigger for data validation
defined
function
Table 3-3 on page 27 lists the objects that were used for the C programming examples.
26 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Table 3-3 Objects for C programming examples
Object Name Description
Type
Stored EMPDTL1P C stored procedure that returns employee data for a supplied
procedure employee number, using parameter style GENERAL
Table 3-4 lists the objects that were used for the Java programming examples.
Stored EMPDTLSJ JDBC stored procedure that returns employee data for a supplied
procedure employee number - EmpDtlsJ.java
EMPDTLSMJ JDBC stored procedure used to illustrate using Multiple Jars (MJ) for
V9 Java stored procedures - EmpDtlsMJ.java
EMPRSETJ JDBC stored procedure to return a result set of employees for a given
department - EmpRsetJ.java
EMPDTL1J SQLJ stored procedure that returns employee data for a supplied
employee number - EmpDtl1J.sqlj
EMPRST1J SQLJ stored procedure to return a result set of employees for a given
department - EmpRst1J.sqlj
EMPRST2J SQLJ stored procedure that updates the employee salary for a given
department using a result set and positioned iterator
EmpRst2J.sqlj & EmpRst2J_UpdByPos.sqlj
EXTRACT JDBC stored procedure to extract a jar (BLOB of 100 MB) from DB2.
_JAR ExtractJarSp.java
Calling CALDTLSJ Java application program that calls the EMPDTLSJ stored procedure.
program CalDtlsJ.java
EmpClobSpSe Java servlet that calls the stored procedure EMPCLOBJ and writes
rvlet out the output to a Web page. EmpClobSpServlet.java
EmphotoSpSe Java servlet calls the stored procedure EMPPHOTJ and writes out an
rvlet Image to the Web browser. EmpPhotoSpServlet.java
Java ExtractJar Java application that extracts a jar from DB2. ExtractJar.java
program
Getters_staff The Java class that has the methods called/used in EMPDTLSMJ
Iterator EmpRst2J_Up Iterator declaration file for Java stored procedure EMPRST2J
dByPos.sqlj
Table 3-5 lists the objects that were used for the REXX programming examples.
Stored EMPDTLSR REXX stored procedure that returns employee data for a supplied
procedure employee number
EMPRSETR REXX stored procedure to return a result set of employees for a given
department
Table 3-6 lists the objects that were used for the External SQL language programming
examples.
Stored EMPDTLSS SQL stored procedure that returns employee data for a supplied
procedure employee number
EMPRSETS SQL stored procedure to return a result set of employees for a given
department
JCL SQLSPCUS JCL to promote an SQL language stored procedure from a test
environment to a production environment
Table 3-7 lists the objects that were used for the Native SQL language programming
examples.
Calling Median_RS Sample java program that calls a specific version of the
program MEDIAN_RESULT_SET SQL procedure
28 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Object Name Description
Type
Stored CALC_SALAR SQL procedure that calculates the sum of all salaries in a table “staff”
procedure Y with the FOR loop construct
GOTO SQL procedure that employs the GOTO construct to branch to a label
defined at a higher level
MEDIAN_RES SQL procedure that calculates the median value of all salaries stored
ULT_SET in a table “staff” and returns a result set containing all rows with a
higher salary than the calculated median value. Two samples are
provided, MEDIANV1 and MEDIANV2, to demonstrate the capability
to ALTER an SQL procedure to create a new version.
NODIFF SQL procedure that employs the FOR loop construct to check if all
values in a column of type integer feature the same value
SCOPELA2 SQL procedure that illustrates the scoping of label names and how to
avoid ambiguity problems with referenced column names
TYPES SQL procedure that creates variables of data type BIGINT, BINARY,
VARBINARY and DECFLOAT
Table 3-8 lists the objects that were used for the examples of developing multi-threaded
stored procedures in the C language.
30 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Table 3-10 lists the objects that were used for the examples of applications that use the
DB2-supplied task scheduler. For each application component we describe to which use case
it applies.
Table 3-11 lists the objects that were used for the examples to invoke the Common SQL API
stored procedures.
Table 3-11 Objects for invoking the Common SQL API stored procedures
Object Name Description
Type
Java SPDriver Java class that contains the main method and instantiates an
program object of the class SPWrapper.java
SPWrapper Java class that provides the service routines to eventually CALL
the Common SQL API stored procedures
SYSPROC.GET_SYSTEM_INFO, GET_CONFIG, and
GET_MESSAGE
Table 3-12 lists QMF queries and forms that display catalog information about the stored
procedures used in our case studies. See 2.3, “DB2 catalog tables” on page 16 for details on
the queries and their respective reports. Query QRPARMER and the associated form
FRPARMER are not discussed in the book, but variations of query QRPARM70 and form
FRPARM70 are discussed.
QRPARMER QMF query that retrieves information about a stored procedure and associated
parameters as well as external name and runtime options
QRPARM70 QMF query that retrieves information about a stored procedure and associated
parameters
32 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Object Name Description
Table 3-13 lists the triggers that are used in our examples to show their interaction with stored
procedures and user defined functions.
Table 3-14 lists a REXX exec that we used for configuration management and change
management purposes. See 18.4, “Notes on REXX execs” on page 384 for more details.
DDLMOD REXX exec that modifies the DDL for a CREATE PROCEDURE statement so that it
can be promoted to a different DB2 environment, based on the values specified in a
configuration file, and generates SYSIN cards which can be used for WLM refresh,
DROP stored procedure and SET CURRENT SQLID.
Table 3-15 lists the jobs that we used to set up the IMS environment for our ODBA example.
See 23.2.1, “Accessing IMS databases through the ODBA interface” on page 478 for a
detailed description of the ODBA setup process.
IMS01 Jobs that coincide with examples about accessing IMS from stored procedures
through
IMS13
DB9AODBA JCL to define WLM application environment for stored procedures that access IMS
Table 3-16 lists the objects that were used in the examples of developing a stored procedure
using Data Studio.
Table 3-17 lists sample JCL that can be used for setting up the Session Manager for the
Unified Debugger.
SESSMGR1 Job to define the Unified Debugger Session Manager Started Task to RACF®
SESSMGR2 Job to create a file in the HFS to hold the Environment settings used when the
Unified Debugger Session Manager runs as a Started Task on z/OS
SESSMGR3 Job to create the Started Task JCL for DB2UDSMD. This is used to launch the
Unified Debugger Session Manager on z/OS.
Figure 3-1 Data Studio, Database Explorer, Load data into a table
34 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 3-2 Load Data dialog, input file specified
In the Output View, note that 6 rows were inserted into the CUSTOMER table.
3.5.1 Table qualifiers, schema names, collection IDs and package owners
Since we show examples of how to migrate a stored procedure from a development
environment to a production environment, we developed the following conventions for table
qualifiers, schema names, collection IDs, and package owners:
DEVL7083 is used for all DB2 objects in our development environment.
PROD7083 is used for all DB2 objects in our production environment.
We chose this naming scheme for ease of development. We do not recommend that you
combine stored procedures of different languages in the same application environment. See
36 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Part 2
Part 2 Operating
environment
In this part we describe the setup of the operating environment that hosts the stored
procedures. The topics discussed here will interest primarily the MVS™ system
programmers, but the DBA will need to have at least some general understanding of the
terminology and definition criteria.
We also look at how to diagnose SQLCODE -471/-00E79002, which means that WLM could
not get a task to run the stored procedure. WLM service classes where stored procedures run
need to be examined, and how to obtain and read the reports. We also look at:
WLM service classes where stored procedures run need to be examined, and how to
obtain and read the reports.
And provide a little insight into the WLM algorithms for starting another address space.
DB2 uses WLM to allocate workload requests for DB2 stored procedures. As requests for
stored procedures come into DB2, WLM determines whether additional resources such as a
new WLM-managed address space are needed in order to process the requests. WLM
manages the number of tasks (TCBs) that can run in each address space, and starts
additional address spaces as needed. Starting with DB2 for z/OS Version 8, all new external
stored procedures must run in WLM-managed address spaces.
The setting of the WLM environments is dependent upon the routines that are being executed
under the same DB2 subsystem.
There are many DB2-supplied stored procedures invoked directly or through various tools. It
is very convenient to group them based on their characteristics. This information is provided
in Table 24-13 on page 504.
Table 4-1 on page 41 summarizes the possible aggregations into WLM Application
Environments for user-defined procedures.
COBOL, C/C++ and PL/I-related stored procedures
One or more WLM Application Environments are recommended for executing COBOL,
C/C++, and PL/I user stored procedures. The same WLM Application Environment can be
used when the same STEPLIB requirements and same runtime LE options apply to all
languages. When different STEPLIB data sets or options are required, then additional
WLM Application Environments need to be created to support the processing of the
different STEPLIB data sets.
You might also want to aggregate or separate these stored procedures to take into
account nesting (see 10.3.1, “Nested stored procedures” on page 130), or performance
(see Chapter 20, “Server address space management” on page 423), or operational
considerations.
Debugging COBOL, C/C++ and PL/I-related stored procedures
When Debug Tool is used to debug COBOL, C/C++, or PL/I stored procedures, the stored
procedure is compiled with the TEST option. This option, along with the presence of
Debug Tool either in the WLM Application Environment STEPLIB or LINKLST, causes
Debug Tool modules to be loaded during execution. It is recommended to separate these
language stored procedures into a separate WLM Application Environment to be used
when executing in DEBUG mode.
REXX-related stored procedures
The TCB setting is required to be 1 for REXX stored procedures.
40 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Java related stored procedures (resettable or unresettable mode)
A separate WLM Application Environment is recommended for executing the users’ Java
stored procedures.
The max NUMTCB setting for resettable Java stored procedures should be no more than
8, since a Java Virtual Machine (JVM™) is loaded for each NUMTCB value.
External SQL stored procedures are similar to COBOL, C/C++, and PL/I stored
procedures.
Native SQL stored procedures are executed in the DBM1 address space.
External SQL stored procedures 10-40 Must have one unauthorized data
set. COBOL, C/C++, PL/I stored
procedures can share if the JCL
is comparable
The NUMTCB value that you choose for each application environment will vary by language.
Table 4-1 provides general recommendations for the WLM procedure NUMTCB setting for the
different language stored procedures. These recommendations are based on available
resources and should be tuned accordingly.
When you want to be able to easily change the NUMTCB value, we recommend that you
leave this parameter off the WLM Application Environment definition, and specify it on the
procedure that executes in the WLM Application Environment. If the NUMTCB parameter is
specified on both the WLM Application Environment and the procedure that executes in the
WLM Application Environment, the value in the WLM Application Environment overrides the
value in the procedure.
Example 4-1 WLM Application Environment definition for general DB2 stored procedures
Application-Environment Notes Options Help
--------------------------------------------------------------------------
Modify an Application Environment
Command ===> ____________________________________________________________
Example 4-2 shows the procedure definition we used for executing many of our DB2 system
stored procedures including DSNTJSPP. This WLM environment contains all APF authorized
STEPLIB data sets, so that we can run the DB2 system WLM_REFRESH stored procedure
here as well, which requires all APF-authorized STEPLIB data sets. We specify the NUMTCB
value on the procedure, and not the WLM Application Environment definition, due to ease of
maintenance. Changes to JCL procs can be made available by refreshing WLM Application
Environment, while changes to WLM Application Environment definitions need re-installing
z/OS service policy at an LPAR or sysplex level. If the LE runtime SCEERUN library is not
included in your system LINKLIST, you need to uncomment the STEPLIB DD for SCEERUN.
Example 4-2 Our procedure for executing many DB2-supplied stored procedures
//*************************************************************
//* JCL FOR RUNNING THE WLM-ESTABLISHED STORED PROCEDURES
//* ADDRESS SPACE
//* RGN -- THE MVS REGION SIZE FOR THE ADDRESS SPACE.
//* DB2SSN -- THE DB2 SUBSYSTEM NAME.
//* NUMTCB -- THE NUMBER OF TCBS USED TO PROCESS
//* END USER REQUESTS.
//* APPLENV -- THE MVS WLM APPLICATION ENVIRONMENT
//* SUPPORTED BY THIS JCL PROCEDURE.
//*
//*************************************************************
42 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
//DB9AWLM PROC RGN=0K,APPLENV=XXXXXXXX,DB2SSN=DB9A,NUMTCB=40
//IEFPROC EXEC PGM=DSNX9WLM,REGION=&RGN,TIME=NOLIMIT,
// PARM='&DB2SSN,&NUMTCB,&APPLENV'
//STEPLIB DD DISP=SHR,DSN=CEE.SCEERUN
// DD DISP=SHR,DSN=DB9A9.SDSNEXIT
// DD DISP=SHR,DSN=DB9A9.SDSNLOAD
Example 4-3 is a sample procedure for executing DSNTPSMP and DSNTBIND stored
procedures that are used by the Development Center. The JCL needed for DSNTPSMP is
included in <hlq>.SDSNSAMP(DSN8WLMP). Since both DSNTPSMP and DSNTBIND are
REXX stored procedures, we set NUMTCB equal to 1.
Example 4-4 is a sample procedure for executing the user external SQL, COBOL, or C/C++
stored procedures. This user procedure for external SQL stored procedures needs one
unauthorized data set included in STEPLIB.
Example 4-4 Sample user procedure for SQL, COBOL, C/C++ stored procedures
//*************************************************************
//* JCL FOR RUNNING THE WLM-ESTABLISHED STORED PROCEDURES
//* ADDRESS SPACE
//* RGN -- THE MVS REGION SIZE FOR THE ADDRESS SPACE.
//* DB2SSN -- THE DB2 SUBSYSTEM NAME.
//* NUMTCB -- THE NUMBER OF TCBS USED TO PROCESS
//* END USER REQUESTS.
//* APPLENV -- THE MVS WLM APPLICATION ENVIRONMENT
//* SUPPORTED BY THIS JCL PROCEDURE.
//*
//*************************************************************
//DB9AWLM PROC RGN=0K,APPLENV=XXXXXXXX,DB2SSN=DB9A,NUMTCB=40
//IEFPROC EXEC PGM=DSNX9WLM,REGION=&RGN,TIME=NOLIMIT,
// PARM='&DB2SSN,&NUMTCB,&APPLENV'
//STEPLIB DD DISP=SHR,DSN=DB9AU.RUNLIB.LOAD
// DD DISP=SHR,DSN=CEE.SCEERUN
// DD DISP=SHR,DSN=DB9A9.SDSNEXIT
// DD DISP=SHR,DSN=DB9A9.SDSNLOAD
Example 4-5 is a sample procedure for executing user Java stored procedures. Only the WLM
Application Environment that executes Java stored procedures should include a //JAVAENV
DD. The presence of this DD causes a JVM to be loaded, one for each NUMTCB. We set the
NUMTCB to 1 for our test environment, so the refresh to the WLM environment went quickly
while we were developing our code and making changes. We set NUMTCB to 5 in our
production user procedure for Java stored procedures.
This user procedure for Java stored procedures needs one unauthorized data set included in
STEPLIB.
44 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
//* ADDRESS SPACE
//* RGN -- THE MVS REGION SIZE FOR THE ADDRESS SPACE.
//* DB2SSN -- THE DB2 SUBSYSTEM NAME.
//* NUMTCB -- THE NUMBER OF TCBS USED TO PROCESS
//* END USER REQUESTS.
//* APPLENV -- THE MVS WLM APPLICATION ENVIRONMENT
//* SUPPORTED BY THIS JCL PROCEDURE.
//*
//*************************************************************
//DB9AWLM PROC RGN=0K,APPLENV=WLMENVJ,DB2SSN=DB9A,NUMTCB=5
//IEFPROC EXEC PGM=DSNX9WLM,REGION=&RGN,TIME=NOLIMIT,
// PARM='&DB2SSN,&NUMTCB,&APPLENV'
//STEPLIB DD DISP=SHR,DSN=DB9AU.RUNLIB.LOAD
// DD DISP=SHR,DSN=CEE.SCEERUN
// DD DISP=SHR,DSN=DB9A9.SDSNEXIT
// DD DISP=SHR,DSN=DB9A9.SDSNLOAD
// DD DISP=SHR,DSN=DB9A9.SDSNLOD2
//JAVAENV DD DISP=SHR,DSN=DB9AU.JSPENV
//JSPDEBUG DD SYSOUT=*
DB2 uses LE to provide a runtime environment for stored procedures written in high-level
languages such as COBOL, PL/I, and C. Stored procedures written in each of these
languages can execute in the same stored procedure address space, though you may wish to
separate them for various resource management reasons, as discussed in Chapter 4,
“Setting up and managing Workload Manager” on page 39. Since multiple languages can
share the same LE runtime library, you do not have to specify the language-specific libraries
in the JCL procedure of each stored procedure address space.
A LE runtime library is required for WLM-managed stored procedure address spaces, and it
must be the only runtime library available. You must not reference any other language runtime
libraries within the system link list or within the joblib or steplib for the stored procedure
started task. If other language runtime libraries are defined in the system link list, then you
must use joblib or steplib overrides to exclude them. Old OS/VS COBOL, COBOL II, PL/I, and
C runtime libraries (which are no longer supported by IBM) are not thread-safe and may
cause logically inconsistent behavior if used in multi-threaded environments such as
WLM-managed stored procedure address spaces. Depending upon the compile and link
options that are used when your programs are prepared, some of those old runtime routines
may be linkedited into your program load modules, and can cause inconsistencies at
execution time.
LE performs several functions for DB2. It hides the differences between programming
languages, provides the ability to make a stored procedure resident in the stored procedure
address spaces, and supports a large number of runtime options, including those options
needed to use tools to debug your stored procedures.
DB2 stored procedures can use many of your existing values for LE runtime options, either
the defaults provided with z/OS, or those values you overrode when you set up Language
Environment. There are some options that you may wish to override for the purposes of
improved debugging capabilities and better management of storage below the 16 MB line.
Default values for LE runtime options can be overridden by specifying new values for the
options on the RUN OPTIONS parameter of the CREATE PROCEDURE or ALTER
PROCEDURE statement. The following runtime options are those that are most frequently
overridden for DB2 stored procedure.
48 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
5.2.1 MSGFILE
The MSGFILE runtime option specifies the ddname of the file that contains runtime
diagnostics for the stored procedure. The format of the RUN OPTIONS parameter to specify a
MSGFILE is as follows:
RUN OPTIONS ‘MSGFILE(ddname,,,,ENQ | NOENQ)’
The purpose of the MSGFILE option is to provide a destination file for diagnostic messages. If
a stored procedure also contains host language statements that display informational
messages, then those messages will also be written to the MSGFILE data set. Care should
be taken when managing diagnostics messages to avoid a situation where many stored
procedures write to the same MSGFILE data set, otherwise, you could experience a JES
spool serialization error, resulting in an S02A abend with reason C. There are two alternatives
for managing message files to avoid serialization errors:
Specify a different MSGFILE ddname for each common set of applications running in an
application environment. For example, you could define message files using ddnames of
SYSOUT1, SYSOUT2, etc., and direct messages from one set of applications to
SYSOUT1, messages from a second set of applications to SYSOUT2, and so forth.
Ideally, the MSGFILE data set should be used for diagnostics only, and you should not
experience contention when your stored procedures are behaving well. If you do need to
manage many diagnostic messages from many stored procedures, then maintaining
multiple message files may be a challenge. In that situation you may prefer the second
alternative.
An alternative to maintaining multiple MSGFILE data sets is to maintain one MSGFILE
data set and specify the ENQ sub-option in your MSGFILE runtime option on your stored
procedure DDL. Specifying the ENQ sub-option resolves the JES spool serialization error
without requiring you to maintain multiple MSGFILE data sets. See “Chapter 6” of z/OS
V1R9.0 Language Environment Customization, SA22-7564-09 for details on when the
ENQ option should be used.
5.2.2 RPTOPTS
The RPTOPTS runtime option generates a report of the runtime options in effect while the
application was running. The report is directed to the ddname specified in the MSGFILE
runtime option. This information can be useful when debugging a stored procedure, because
the resulting report will display the default options specified in the LE environment as well as
any options that have been overridden at the stored procedure level. The format of the RUN
OPTIONS parameter to specify RPTOPTS is as follows:
RUN OPTIONS ‘RPTOPTS(ON)’
Specify RPTOPTS only when you need to understand what runtime options are in effect while
testing a stored procedure. You should ensure that RPTOPTS is set to OFF when running in
production as the report generation process increases the time it takes to run the stored
procedure.
The information other than the IP address and the listening port is fixed, and should not be
changed. See Chapter 28, “Tools for debugging DB2 stored procedures” on page 735 for
more details on debugging stored procedures with DB2 Development Center.
You can also debug stored procedures that run on z/OS by using the 3270 MVS MFI VTAM®
option. This feature allows you to run a debugging session on the mainframe for your z/OS
stored procedures. The TEST options for MFI debugging are different than for Development
Center debugging. See Chapter 28, “Tools for debugging DB2 stored procedures” on
page 735 for more details.
50 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Note that stored procedures EMPDTLSC, EMPDTLSJ, and EMPRSETJ will use the
installation default values for the LE runtime options, while the remainder of the stored
procedures will use the defaults plus the additional options shown in the report.
If your stored procedures will be executing Assembler language code, they must be LE
compliant, meaning they must comply with LE rules, but need not be LE conforming, meaning
they need not take advantage of LE features. LE is aware of resources allocated through LE
services, and will free them at the appropriate times. LE is not aware of resources allocated
through non-LE services, and cannot free them at the appropriate times. For example, an
Assembler routine that does a GETMAIN must always do its own FREEMAIN. However,
memory acquired through LE’s callable memory allocation routine is automatically freed.
If your stored procedures will be executing third party software, it may be difficult to determine
which routines are multi-thread safe and which are not. You may have to add your own
serialization method around those routines.
Chapter 6. RRSAF
In this chapter we provide a brief overview of the Resource Recovery Services Attach Facility
(RRSAF), a description of how it is used by DB2 for WLM stored procedures, and a list of the
steps required to implement RRSAF.
Resource recovery is the protection of these critical resources. Resource recovery consists of
the protocols and program interfaces that allow an application program, such as a DB2 stored
procedure, to make consistent changes to multiple protected resources of different types,
such as DB2 data and IMS data. z/OS, when requested, can coordinate changes to one or
more protected resources, which can be accessed through different resource managers and
reside on different systems. z/OS ensures that all changes are made or no changes are
made. In other words, all data is committed or all data is rolled back. Resources that z/OS can
protect include:
A hierarchical database, such as IMS
A relational database, such as DB2
A product-specific resource
There are three types of programs that work together to protect resources within a z/OS
environment:
Application program - The application program accesses protected resources and
requests changes to the resources. For our purposes the application is a DB2 stored
procedure.
Resource Manager - A resource manager controls and manages access to a resource. A
resource manager is an authorized program that provides an application programming
interface (API) that allows the application program to read and change a protected
resource. The resource manager, through exit routines that get control in response to
events, takes actions that commit or back out changes to a resource it manages. Often an
application changes more than one protected resource, so that more than one resource
manager is involved. A resource manager may be an IBM product, such as DB2 or IMS,
part of an IBM product, or a product from another vendor.
Syncpoint manager - Resource Recovery Services (RRS) is the syncpoint manager
program. It uses a two-phase commit protocol to coordinate changes to protected
resources, so that all changes are made or no changes are made. During its processing,
RRS drives exit routines for each resource manager. For example, if a DB2 application
issues a commit, RRS drives the commit exit routine for each resource manager involved.
If the DB2 application is executing under CICS, then RRS drives the commit exit routine for
both DB2 and CICS.
RRSAF works in conjunction with the application program, the resource manager and the
syncpoint manager to ensure that updates to DB2 resources and other protected resources
are synchronized across a unit of work. Either all work is committed, or all work is backed out.
54 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Preparing an application to run in RRSAF is similar to preparing it to run in other
environments such as CICS, IMS, or TSO, except that WLM-established stored procedures
have to be linkedited with the DSNRLI language interface module. You can prepare an
RRSAF application by executing program preparation JCL in batch, or by using the DB2
program preparation panels. For more details on preparing a DB2 program to run in RRSAF
see, “Chapter 32” of DB2 Version 9.1 for z/OS Application Programming and SQL Guide,
SC18-9841.
There are no special coding techniques that you need to follow to invoke RRSAF within a
stored procedure once you have prepared your stored procedure using the DSNRLI language
interface module. DSNRLI takes care of executing the appropriate exit routines to manage the
two-phase commit processing. DB2 Version 7 was the last version of DB2 to support
definition of DB2-established stored procedure address spaces. With DB2 Version 9, all new
stored procedures must be defined in a WLM-established address space; therefore, all stored
procedures need to be linkedited with DSNRLI.
DB2 requires that RRS be active, because WLM-established stored procedure address
spaces use the RRS attachment facility (RRSAF), not the call attachment facility (CAF) which
was used for DB2-established stored procedure address space. You cannot use the CAF in
WLM-established stored procedure address spaces.
For documentation purposes the following message is included in the MSTR address space
upon restart of your DB2 subsystem:
DSN3029I -DB9A DSN3RRSR RRS ATTACH PROCESSING IS AVAILABLE
You cannot explicitly code any call to DSNRLI for WLM-established address spaces.
RRS is an MVS system logger application that records events related to protected resources.
RRS records these events in five log streams. In a sysplex environment, these log streams
are shared by the systems of the sysplex. Before you can start RRS, you must:
1. Define RRS’s log streams. The log streams can be placed on disk or in the Coupling
Facility. In our test case, the log streams were placed in the Coupling Facility. To do this,
you must:
– Add definitions for the structure in the CFRM policy.
– Define the log streams.
– Activate the new definitions.
2. Establish the priority for the RRS address space.
3. Set up the RRS procedure in SYS1.PROCLIB.
4. Define the RRS subsystem to MVS.
Chapter 6. RRSAF 55
The five log stream names used by RRS are (where gname can be your sysplex name or any
name in a non-sysplex environment):
Main unit-of-recovery log state stream:
ATR.gname.MAIN.UR´
The state of active URs. RRS periodically moves this information into the RRS delayed UR
state log when UR completion is delayed.
Delayed unit-of-recovery log state stream:
ATR.gname.DELAYED.UR
The state of active URs, when UR completion is delayed.
Resource manager data log stream:
ATR.gname.RM.DATA
Information about the resource managers using RRS services.
Restart log stream:
ATR.gname.RESTART
Information about incomplete URs needed during restart. This information enables a
functioning RRS instance to take over incomplete work left over from an RRS instance that
failed.
Archive log stream (this log is recommended but optional):
ATR.gname.ARCHIVE
Information about completed URs.
To define the RRS log streams, use IXCMIAPU, which is a utility program provided in the
SYS1.MIGLIB system library.
56 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
................
STRUCTURE NAME(RRS_ARCHIVE_1)
INITSIZE(8000)
SIZE(16000)
PREFLIST(CF1,CF2)
REBUILDPERCENT(5)
STRUCTURE NAME(RRS_RMDATA_1)
INITSIZE(8000)
SIZE(16000)
PREFLIST(CF1,CF2)
REBUILDPERCENT(5)
STRUCTURE NAME(RRS_MAINUR_1)
INITSIZE(8000)
SIZE(16000)
PREFLIST(CF1,CF2)
REBUILDPERCENT(5)
STRUCTURE NAME(RRS_DELAYEDUR_1)
INITSIZE(8000)
SIZE(16000)
PREFLIST(CF1,CF2)
REBUILDPERCENT(5)
STRUCTURE NAME(RRS_RESTART_1)
INITSIZE(8000)
SIZE(16000)
PREFLIST(CF1,CF2)
REBUILDPERCENT(5)
Note that:
gname can be any name of your choice. In our test case we used SANDBOX. When you
start RRS, you must specify for the gname parameter of the JCL procedure the same
gname specified when you created your log streams. If you do not specify the name when
starting RRS, the default is the sysplex name.
vsamls is an SMS class defined for linear VSAM files. You can set up a new SMS class, or
use an existing SMS class for VSAM linear data sets.
To verify the data classes already defined in SMS, you can invoke the SMS ISPF
application, choose option 4, and list all defined SMS classes.
The log stream (LS) VSAM data sets will be allocated at the time the RRS log streams are
defined. Each data set is prefixed with IXGLOGR and suffixed with A0000000. They are
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
You can map each log stream to a single structure or you can map log streams of like data
types to the same structure. Example 6-2 shows the JCL to map each RRS log stream to a
structure.
Chapter 6. RRSAF 57
DATA TYPE(LOGR) REPORT(YES)
DEFINE LOGSTREAM
NAME(ATR.SANDBOX.ARCHIVE) STRUCTNAME(RRS_ARCHIVE_1)
LS_DATACLAS(SHARE33)
HLQ(LOGR) MODEL(NO) LS_SIZE(1024)
LOWOFFLOAD(0) HIGHOFFLOAD(80) STG_DUPLEX(NO)
RETPD(15) AUTODELETE(YES)
DEFINE LOGSTREAM
NAME(ATR.SANDBOX.RM.DATA) STRUCTNAME(RRS_RMDATA_1)
LS_DATACLAS(SHARE33)
HLQ(LOGR) MODEL(NO) LS_SIZE(1024)
LOWOFFLOAD(0) HIGHOFFLOAD(80) STG_DUPLEX(NO)
RETPD(15) AUTODELETE(YES)
DEFINE LOGSTREAM
NAME(ATR.SANDBOX.MAIN.UR) STRUCTNAME(RRS_MAINUR_1)
LS_DATACLAS(SHARE33)
HLQ(LOGR) MODEL(NO) LS_SIZE(1024)
LOWOFFLOAD(0) HIGHOFFLOAD(80) STG_DUPLEX(NO)
RETPD(15) AUTODELETE(YES)
DEFINE LOGSTREAM
NAME(ATR.SANDBOX.DELAYED.UR) STRUCTNAME(RRS_DELAYEDUR_1)
LS_DATACLAS(SHARE33)
HLQ(LOGR) MODEL(NO) LS_SIZE(1024)
LOWOFFLOAD(0) HIGHOFFLOAD(80) STG_DUPLEX(NO)
RETPD(15) AUTODELETE(YES)
DEFINE LOGSTREAM
NAME(ATR.SANDBOX.RESTART) STRUCTNAME(RRS_RESTART_1)
LS_DATACLAS(SHARE33)
HLQ(LOGR) MODEL(NO) LS_SIZE(1024)
LOWOFFLOAD(0) HIGHOFFLOAD(80) STG_DUPLEX(NO)
RETPD(15) AUTODELETE(YES)
/*
If you need to delete the log streams and the structures from the Coupling Facility, you can
use the JCL in Example 6-3 as a model for your JCL.
58 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
//SYSIN DD *
DATA TYPE(LOGR) REPORT(YES)
DELETE LOGSTREAM
NAME(ATR.SANDBOX.ARCHIVE)
DELETE LOGSTREAM
NAME(ATR.SANDBOX.RM.DATA)
DELETE LOGSTREAM
NAME(ATR.SANDBOX.MAIN.UR)
DELETE LOGSTREAM
NAME(ATR.SANDBOX.DELAYED.UR)
DELETE LOGSTREAM
NAME(ATR.SANDBOX.RESTART)
/*
The GNAME must match the gname specified when defining the log streams.
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 6. RRSAF 59
You can stop RRS with the following operator command:
SETRRS CANCEL
or
SETRRS SHUTDOWN
If SETRRS CANCEL or SETRRS SHUTDOWN does not stop RRS, you can use the FORCE
RRS,ARM command. In this command, RRS is the subsystem name your installation
assigned to RRS in PARMLIB member IEFSSNxx.
Here are the messages you receive when you issue this command:
SETRRS CANCEL
...
ATR101I CANCEL REQUEST WAS RECEIVED FOR RRS.
ATR143I RRS HAS BEEN DEREGISTERED FROM ARM.
...
ASA2960I RRS SUBSYSTEM FUNCTIONS DISABLED. COMPONENT ID=SCRRS
ATR167I RRS RESMGR PROCESSING COMPLETED.
60 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
look at scenarios that may force manual intervention to resolve in-doubt URs with RRS. For
detailed information, see Systems Programmer’s Guide to Resource Recovery Services
(RRS), SG24-6980.
The normal restart and recovery phases that DB2 goes through are:
Phase 1: Log initialization
DB2 identifies the last LOG RBA used before termination so that it can start logging at the
next RBA.
Phase 2: Current status rebuild.
DB2 determines what URs are outstanding and the status of each UR (in-flight, in-commit,
in-abort or in-doubt). DB2 also recovers information about coordinator and participants for
all outstanding URs.
Phase 3: Forward Log Recovery
Having determined the outstanding URs in Phase 2, DB2 makes all the database changes
for committed work as well as for in-flight, in-doubt and in-abort URs. For in-flight, in-doubt
and in-abort URs, DB2 locks the changed data to make it unavailable.
Phase 4: Backward Log Recovery
In this phase, DB2 reverses out changes by in-flight or in-abort URs and releases locks for
those URs.
During Phase 2 of DB2 restart processing, DB2 retrieves any outstanding URs from RRS.
Any in-doubt URs may result in retained locks for affected data. If there are in-doubt URs,
DB2 will issue messages DSN3010I or DSN3011I to indicate that RRS cannot be contacted
to resolve these in-doubt URs.
DB2 will resync with RRS once RRS is restarted on the z/OS image. At that stage it can
resolve any in-doubt URs according to the final state that RRS supplies.
Note that when DB2 starts and RRS is unavailable, any DB2 facilities that require RRS will
also be unavailable. That means any attempt to use RRSAF or WLM managed stored
procedures will result in an error. For example, an attempt to start a WLM stored procedure
results in the error message shown in Example 6-5.
Once RRS restart processing is complete, a message is displays in the DB2 MSTR log; see
Example 6-6 on page 62.
Chapter 6. RRSAF 61
Example 6-6 DB2 message after RRS start/restart
DSN3029I -DB9A DSN3RRRS RRS ATTACH PROCESSING IS AVAILABLE
RRS
Option ===> 2
We look at the status of the DB2 resource managers by looking at the RRS ISPF resource
manager list panel; see Example 6-8.
We are interested in resource manager DSN.RRSATF.IBM.DB9A. The RRS state is Run which
means that DB9A has registered to RRS on system SC63 and has completed restart
processing. We ran batch job PAOLOR15 that executes program RRSDTL1C that uses the
RRSAF attachment and calls stored procedure EMPDTL1C
Type u next to DSN.RRSATF.IBM.DB9A to enter the UR detail view; see Example 6-9 on
page 63.
62 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Example 6-9 UR detail view
RRS Unit of Recovery Details
Command ===>
UR identifier : C180BF5D7E0860000000001601040000
Create time : 2007/11/15 18:16:08.672508 GMT Comments :
UR state : InFlight UR type : Unpr
System : SC63 Logging Group : SANDBOX
SURID : N/A
Work Manager Name : SC63.PAOLOR15.0038
Display Work IDs Display IDs formatted
Luwid . : Not Present
Eid . . : Not Present
Xid . . : Not Present
Expressions of Interest:
S RM Name Type Role
DSN.RRSATF.IBM.DB9A Unpr Participant
We can relate the RRS URid to a DB2 thread by means of the DB2 command DISPLAY
THREAD(*) RRSURID(*); see Example 6-10.
Chapter 6. RRSAF 63
64 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
7
In this chapter we describe the privileges required for creating and executing DB2 stored
procedures, along with the security administration tasks to set up those privileges. For details
on security requirements to use IBM Data Studio, see “IBM Data Studio authorization setup”
on page 651.
See the Security section of DB2 Version 9.1 for z/OS Administration Guide, SC18-9840 for
more information on these topics.
There are two external levels of security that have to be set up for WLM stored procedures:
Each authid that attempts to create a stored procedure needs the authority to create
stored procedures in the WLM environment where the procedure will be run.
Application developers or DBAs that need to refresh WLM application environments must
be permitted access to the DB2-supplied stored procedure WLM_REFRESH to refresh
the address spaces.
Issuing this command ensures that universal access is NONE on the application
environment. To allow individual developers or groups access to the application environment
we issue the following command, which permits users in RACF group DEVL7083 to create
stored procedures in address space DB9AWLM:
PERMIT DB9A.WLMENV.DB9AWLM CLASS(DSNR) ID(DEVL7083) ACCESS(READ)
In case of data sharing, the first node can be the group ID of the data sharing group.
66 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
7.1.3 Permitting access to WLM REFRESH command
When you prepare a new version of a stored procedure in a WLM application environment,
you need to refresh the application environment to activate the new version of the program.
You do this by issuing a VARY REFRESH command, which can be done on a z/OS command
line, or by executing the DB2-supplied WLM_REFRESH stored procedure. We issued the
following command to refresh application environment DB9AWLM, which contained the
majority of the COBOL stored procedures in our test cases:
/V WLM,APPLENV=DB9AWLM,REFRESH
First you must permit access to the WLM_REFRESH RACF resource profile for each
application environment. The RACF RDEFINE command to permit RACF group DEVL7083
access to the WLM_REFRESH resource profile for application environment DB9AWLM on
subsystem DB9A is shown in Example 7-1.
After issuing the above RDEFINE command for each environment for which you need to
refresh, you then need to grant EXECUTE authority on the WLM_REFRESH stored
procedure to the authids or groups who will be refreshing the environment. You only need to
grant EXECUTE authority once since you supply the application environment name as a
variable when you execute WLM_REFRESH. A sample GRANT statement for
WLM_REFRESH is as follows:
GRANT EXECUTE ON PROCEDURE SYSPROC.WLM_REFRESH TO DEVL7083;
The DB2-supplied installation verification job DSNTEJ6W contains the steps to create the
resource profile for refreshing WLM, and to prepare the WLM_REFRESH stored procedure.
See Chapter 13, “Verifying installation with the sample applications” in DB2 Version 9.1 for
z/OS Installation Guide, SC18-9846 for details on job DSNTEJ6W. See A.2, “Refresh a WLM
environment with AdminWLMRefresh” on page 817 in this book for more details on
WLM_REFRESH.
The second part of the name is the schema name, which also can be implicitly or explicitly
specified. If the schema is left blank, it defaults to the value in CURRENT SCHEMA
(assuming dynamic SQL) for the person issuing the CREATE PROCEDURE statement.
Most stored procedures are created into one or more common schemas that are defined at
an application level. For our case study, we used schema DEVL7083 for all stored procedures
created in our development environment, while we used schema PROD7083 for our
production environment. The following SQL statement was issued during our case study to
allow authid PAOLORW to create stored procedures in our development environment:
GRANT CREATEIN ON SCHEMA DEVL7083 TO PAOLORW
Since you may have many application developers or DBAs creating stored procedures into
the same schema, you may wish to grant the CREATEIN privilege on the schema to a
secondary authid that represents a group of users who create stored procedures. Each
application developer could then issue a SET CURRENT SQLID statement to the secondary
authid prior to creating the stored procedure in the desired schema.
Users who attempt to create a stored procedure by issuing the CREATE PROCEDURE
statement without having the CREATEIN privilege on the schema receive an SQLCODE of
-552 with an SQLSTATE of 42502. Here is the error message we received when authid
PAOLORW attempted to create stored procedure EMPDTLSC without having been granted
CREATEIN on schema DEVL7083:
DSNT408I SQLCODE = -552, ERROR: PAOLORW DOES NOT HAVE THE PRIVILEGE TO PERFORM
OPERATION CREATE PROCEDURE
DSNT418I SQLSTATE = 42502 SQLSTATE RETURN CODE
The CREATEIN privilege is always required to create a stored procedure in a given schema.
Note, however, that there are some considerations in how the qualifier is determined when a
CREATE PROCEDURE statement is unqualified. See 7.5.7, “Resolution of unqualified stored
procedure names at create time” on page 79 for details on the behaviors for handling
unqualified stored procedure names in DB2 for z/OS V8 and DB2 9 for z/OS.
Since the BINDADD privilege is a system-level privilege, the GRANT statement only needs to
be issued once per authid for a subsystem. Rather than grant BINDADD to every individual
who can create stored procedures, you can grant the privilege to a new authid, which is used
by a group of users who create stored procedures. Each application developer in the group
could then issue a SET CURRENT SQLID statement to the new authid prior to creating the
stored procedure in the desired schema.
68 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Users who attempt to create a stored procedure by issuing the CREATE PROCEDURE
statement without having the BINDADD privilege on the system where the stored procedure
will reside receive an SQLCODE of -567 with an SQLSTATE of 42501. Here is the error
message we received when authid PAOLORW attempted to bind the package for stored
procedure EMPDTLSC without having been granted BINDADD on the subsystem:
BIND AUTHORIZATION ERROR USING PAOLORW AUTHORITY
PACKAGE = EMPDTLSC PRIVILEGE = BINDADD
In places where we mention “authid” in this chapter, we are referring to the value of
CURRENT SQLID. This is usually the authid of the process, meaning the authid being passed
from the client in the case of a distributed call, or the authid associated with a CICS
transaction or batch job if the stored procedure is called from CICS or batch. The authid may
be changed if the calling application issues a SET CURRENT SQLID statement prior to
issuing the CALL to the stored procedure.
With DB2 9, the GRANT EXECUTE statement allows for the privilege on a stored procedure
to be granted to a ROLE. ROLE privileges or executing stored procedures are considered in
addition to the value of CURRENT SQLID for batch, local and remote applications. Trusted
contexts cannot be defined for CICS and IMS.
In our example in 7.2, “Privileges required to create stored procedures” on page 67, we
granted user ID PAOLORW the privileges required to create stored procedure EMPDTLSC in
1
The DYNAMICRULES behavior for the plan or package that contains the CALL statement determines both the
authorization ID and the privilege set that is held by that authorization ID.
To test what happens when a client authid does not have EXECUTE authority on a procedure
that is called by the client application, we developed a stub client application on Windows that
issues a CALL to stored procedure EMPDTLSC. We attempted to call the stored procedure
while using authid PAOLORW, which this time did not have EXECUTE authority on the stored
procedure. Figure 7-1 shows the error message that was returned to the Windows client.
Figure 7-1 Sample error message on Windows client when EXECUTE privilege does not exist
Subsequently, we issued the following SQL statement to grant the EXECUTE privilege on the
stored procedure to the client authid:
GRANT EXECUTE ON PROCEDURE DEVL7083.EMPDTLSC TO PAOLORW
We ran the stub client application again and were able to successfully execute stored
procedure EMPDTLSC.
For details, refer to DB2 Version 9.1 for z/OS SQL Reference, SC18-9854.
It does not matter whether the current authid at execution time has the EXECUTE privilege on
the stored procedure. As long as the authid has EXECUTE authority on the plan or package
of the calling application, it will be able to execute any CALL statements within the calling
application. This privilege is checked at the time the plan or package for the calling application
is bound, unless VALIDATE(RUN) is used.
In our test case we used authid PAOLORW, which for this test scenario had been granted no
access to any DB2 packages or plans and had been granted no privileges to create stored
procedures, so could therefore not be the owner of a stored procedure. We ran a batch job,
using an authid of PAOLORW, that executed program CALDTLSC, which is a COBOL
program that calls stored procedure EMPDTLSC. Since PAOLORW had no privileges on
CALDTLSC, we received the error messages shown in Example 7-2.
Example 7-2 Sample error messages on z/OS caller when EXECUTE privilege does not exist
PLAN CALDTLSC NOT AUTHORIZED FOR SUBSYSTEM DB9A AND AUTH ID PAOLORW
DSNT408I SQLCODE = -924, ERROR: DB2 CONNECTION INTERNAL ERROR, 0001, 0100,
70 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
00F30016
DSNT418I SQLSTATE = 58006 SQLSTATE RETURN CODE
DSNT415I SQLERRP = DSNAET03 SQL PROCEDURE DETECTING ERROR
We then issued the following SQL statement to grant the EXECUTE privilege on the package
for the calling application to authid PAOLORW:
GRANT EXECUTE ON PLAN DEVL7083.CALDTLSC TO PAOLORW
We ran the batch job again and were able to successfully execute stored procedure
EMPDTLSC.
The privilege required to run the stored procedure package and any packages that are used
under the stored procedure is any of the following:
The EXECUTE privilege on the package
Ownership of the package
PACKADM authority for the package’s collection
SYSADM authority
In case of stored procedures invoking triggers and UDF, additional authorizations are
required. See DB2 Version 9.1 for z/OS SQL Reference, SC18-9854.
For the case of a remote stored procedure CALL from a middleware server, the ADDRESS
attribute would be the IP address of the server. An example of a server used for remote stored
procedure CALLs in a three-tiered architecture is an IBM WebSphere Application Server.
Let’s look at an example of how a network trusted context could be used to control access to
one of the stored procedures in our case study.
COBOL stored procedure DEVL7083.EMPDTL1C resides on our DB2 9 for z/OS system
DB9A. In our original case study we called EMPDTL1C from COBOL program CALDTL1C
running on DB2 for z/OS. For the testing in the above mentioned security redbook an IBM
WebSphere Application Server (WAS) was established. We modified our case study to call
stored procedure EMPDTL1C on a DB2 9 for z/OS subsystem from the Database Explorer
view in Data Studio. We executed the call from one IP address for which a trusted connection
was defined and then from another IP address for which no trusted connection was defined.
We used IP addresses for Windows workstations to perform the test.
72 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Example 7-4 DDL to create a role
---------+---------+---------+---------+---------+---------+
CREATE ROLE SP_CALLER;
---------+---------+---------+---------+---------+---------+
DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 0
---------+---------+---------+---------+---------+---------+
2. The second step is to grant the EXECUTE privilege on the stored procedure to the role. In
our test case we granted execute on stored procedure EMPDTL1C to the role we just
created, SP_CALLER, as shown in Example 7-5.
3. The third and final step is to define the trusted context. In our test case we created a
trusted context called TRUSTED_EMPDTL1C using the authid of PAOLORW, a default
role of SP_CALLER, and a specific IP address. The DDL we executed is shown in
Example 7-6.
At this point we are ready to run our trusted context test. Based on the above definition, authid
PAOLORW should only be able to execute stored procedure DEVL7083.EMPDTL1C if it is
invoked from an IP address of 9.30.28.113. The results of our test from a workstation with this
IP address is shown in Example 7-7.
Example 7-7 Results of a stored procedure call from an IP address defined in trusted context
DEVL7083.EMPDTL1C - Run started.
Data returned in result sets is limited to the first 50 rows.
Data returned in result set columns is limited to the first 100 bytes or characters.
DEVL7083.EMPDTL1C - Calling the stored procedure.
DEVL7083.EMPDTL1C - Run completed.
In order to determine whether the trusted context is really working, we needed to run a test
from a workstation with a different IP address. We ran the same test, without changing any of
the privileges granted, on a different workstation that had a different IP address. Our results
are shown in Example 7-8.
Example 7-8 Results of stored procedure call from IP address not defined in trusted context
DEVL7083.EMPDTL1C - Run started.
Data returned in result sets is limited to the first 50 rows.
Data returned in result set columns is limited to the first 100 bytes or characters.
You can see that the trusted context definition prevented user PAOLORW from executing
stored procedure EMPDTL1C from any workstation other than the one associated with the IP
address for that user.
When you define a trusted context you will most likely use a domain name instead of an IP
address for the ADDRESS attribute of the trusted context. We used IP addresses in our tests
to be able to more easily distinguish between the two workstations executing the stored
procedure.
Note: Trusted contexts cannot be defined for CICS or IMS. Therefore, if your stored
procedure can be executed from CICS or IMS as well as from a DRDA connection, you
should not use a trusted context to control access to the stored procedure.
Here are some design points to keep in mind when considering trusted context and roles for
securing your stored procedures:
A stored procedure can be created by a role within a trusted connection.
A stored procedure can be owned by a role.
You can restrict access to a stored procedure by only allowing it to be exercised via a role
within a trusted connection.
You can control who can create stored procedures by defining a role and a trusted
connection.
The role privileges are in addition to the privileges held by the allowed user of the trusted
context.
For more details on the network trusted context enhancement in DB2 9 for z/OS, see Chapter
8, “Network trusted contexts and roles” in Securing DB2 and Implementing MLS on z/OS,
SG24-6480.
74 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
7.5.1 Privileges required when owner and binder are different
In some cases the owner of the stored procedure may be different than the authid used to
bind the stored procedure package. This may occur when a DBA is responsible for creating
the procedure (issuing the CREATE PROCEDURE statement) and an application developer
is responsible for program preparation, including binding the stored procedure package. In
that case granting the EXECUTE privilege on the stored procedure to the authid who will be
executing the procedure will not be sufficient. The owner of the stored procedure package will
need to grant the EXECUTE privilege on the stored procedure package to the executing
authid.
DB2 generates two functions associated with the distinct type: one to cast between the
distinct type and its’ source data type; and one to cast between the source data type and the
distinct type. When the distinct type is created the owner of the type implicitly has the USAGE
privilege on the type and the functions associated with the type.
Stored procedures can pass parameters that have a distinct type as a data type. The creator
of the stored procedure must have the USAGE privilege on a distinct data type if that type is
to be used as a parameter in the stored procedure. No additional USAGE privilege is required
to any authid that is granted the EXECUTE privilege on the procedure. For example, if a
distinct type of US_DOLLARS was created by authid PAOLORX, and authid PAOLORW
wanted to create a stored procedure that passed a parameter with a data type of
US_DOLLARS, then PAOLORX would have to issue the following SQL statement to allow
PAOLRW to create the procedure:
GRANT USAGE ON DISTINCT TYPE US_DOLLARS TO PAOLORW
Note that the jar name is case sensitive. Make sure that you set caps off prior to issuing the
GRANT statement.
See 13.6, “Preparing Java stored procedures” on page 195 for more details on preparing jar
files and using the DB2-supplied INSTALL_JAR stored procedure.
Stored procedures with dynamic SQL are also good for security reasons, but they require a
bit more effort to plan the security configuration.
All of the security topics we have discussed so far are applicable to stored procedures that
are created with and contain static SQL. Stored procedures that contain dynamic SQL are
influenced by the DYNAMICRULES option in effect at the time that the stored procedure
package is bound.
The DYNAMICRULES option, in combination with the runtime environment, determines what
values apply at runtime for dynamic SQL attributes such as authid for authorization checking,
and qualifier for unqualified objects, as well as some other attributes. The set of attribute
values is called the dynamic SQL statement behavior. The four dynamic SQL statement
behaviors are:
Run behavior
Bind behavior
Define behavior
Invoke behavior
Each behavior represents a different set of attribute values that impact how authorizations are
handled for dynamic SQL. The authorization processing for dynamic SQL in a stored
procedure is impacted by the value of the DYNAMICRULES parameter when binding the
stored procedure package. There are six possible options for the DYNAMICRULES
parameter:
BIND
RUN
DEFINEBIND
DEFINERUN
INVOKEBIND
INVOKERUN
If you bind the package for the stored procedure with DYNAMICRULES(BIND) then the
dynamic SQL in the stored procedure will also be authorized against the package owner for
the dynamic SQL program.
76 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
For each of the other values, the authorization for dynamic SQL in a stored procedure is
checked against an auth ID other than the package owner.
Table 7-1 shows how DYNAMICRULES and the runtime environment affect dynamic SQL
statement behavior when the statement is in a package that is invoked from a stored
procedure (or user-defined function).
Table 7-1 How is runtime behavior determined?
DYNAMICRULES value Stored procedure or user-defined Authorization ID
function environment
The DYNAMICRULES option along with the runtime environment of a package (whether the
package is run stand-alone or under the control of a stored procedure or user-defined
function) determines the authorization ID used to check authorization, the qualifier for
unqualified objects, the source of application programming options for SQL syntax, and
whether or not the SQL statements can include GRANT, REVOKE, ALTER, CREATE, DROP,
and RENAME statements.
Table 7-2 shows the implications of each dynamic SQL statement behavior.
Use the value appropriate for your environment. In a z/OS server-only environment,
DYNAMICRULE(BIND) makes embedded dynamic SQL behave similar to embedded static
SQL, and is probably the best option for most users if the users are not allowed to use “free
form SQL.” In a distributed environment, binding multiple packages using different levels of
authorization may provide the best granularity. Figure 7-2 shows how complex the choices
can be when invoking a stored procedure.
Consider a user, Suresh, using a current SQLID of Bonni, who executes a package bound by
Glenn. This package calls a stored procedure created and bound by Peggy. Whose authority
is checked at runtime? Depending on the option chosen, the authorization ID used to
determine whether or not the execution of dynamic SQL within this stored procedure is
permitted could be:
Suresh (invoker)
Bonni (current SQLID)
Glenn (owner of package) or
Peggy (owner of stored procedure)
Due to the variety of options available, it is difficult to make a general recommendation that
applies to all situations. See Chapter 9 “Controlling access to DB2 objects” in DB2 UDB for
z/OS Version 8 Administration Guide, SC18-7413 for more details on the DYNAMICRULES
option of the BIND command to help you determine which value is appropriate for your
application.
This option can be used to control the types of SQL statements that may be executed within
the stored procedure. For example, a stored procedure created with the option READS SQL
DATA cannot include an INSERT, UPDATE, or DELETE statement. For complete details on
78 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
which types of SQL statements are allowed for each option value, refer to the description of
the CREATE PROCEDURE (external) statement in DB2 Version 9.1 for z/OS SQL Reference,
SC18-9854.
If you defined a stored procedure in DB2 V7 or DB2 V8, but did not qualify the stored
procedure name on the CREATE PROCEDURE statement, the stored procedure would be
created under the schema of the CURRENT SQLID. An example of creating an unqualified
stored procedure in DB2 for z/OS V7 or V8 is shown in Example 7-9. The GRANT statement
shows that the procedure does exist under the schema that was set via the SET CURRENT
SQLID statement.
DB2 for z/OS V8 New Function Mode introduced the new special register CURRENT
SCHEMA, which specifies the schema name used to qualify unqualified database object
references in SQL statements. You could set CURRENT SCHEMA to a different value than
CURRENT SQLID, but you could only use the CURRENT SCHEMA value to reference
existing database objects. You could not create any database objects using a different
schema than the CURRENT SQLID. If you attempted to do this you would receive an
SQLCODE of -20283, as shown in Example 7-10.
DB2 9 for z/OS has been enhanced to look at the CURRENT SCHEMA value and to use it, if
supplied, to resolve unqualified stored procedure names on a CREATE statement. If the
CURRENT SCHEMA is not supplied, then the value of the CURRENT SQLID special register
will be used, whether it was set implicitly or explicitly. Example 7-11 shows the successful
SQLCODE received for the CREATE PROCEDURE statement using the CURRENT
SCHEMA value. The GRANT statement shows that the procedure does exist under the
schema that was set via the SET SCHEMA statement.
Example 7-11 DB2 V9 CREATE PROCEDURE with SET SCHEMA and no qualifier
---------+---------+---------+---------+---------+---------+
SET CURRENT SQLID = 'PAOLOR4';
---------+---------+---------+---------+---------+---------+
DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 0
---------+---------+---------+---------+---------+---------+
SET SCHEMA = 'DEVL7083';
---------+---------+---------+---------+---------+---------+
DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 0
---------+---------+---------+---------+---------+---------+
80 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
CREATE PROCEDURE EMPDTL1C
(
IN PEMPNO CHAR(6)
,OUT PFIRSTNME VARCHAR(12)
,OUT PMIDINIT CHAR(1)
,OUT PLASTNAME VARCHAR(15)
)
RESULT SETS 0
EXTERNAL NAME EMPDTL1C
LANGUAGE COBOL
PARAMETER STYLE GENERAL
MODIFIES SQL DATA
NO DBINFO
WLM ENVIRONMENT DB9AWLM
STAY RESIDENT YES
COLLID DEVL7083
PROGRAM TYPE SUB
COMMIT ON RETURN NO ;
---------+---------+---------+---------+---------+---------+
DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 0
---------+---------+---------+---------+---------+---------+
GRANT EXECUTE ON PROCEDURE DEVL7083.EMPDTL1C TO PUBLIC ;
---------+---------+---------+---------+---------+---------+
DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 0
This DB2 9 for z/OS enhancement allows you to create stored procedures with a schema that
is different from the CURRENT SQLID. DB2 will use the value of the CURRENT SCHEMA
special register if supplied. If no CURRENT SCHEMA value is supplied, then DB2 will use the
value of the CURRENT SQLID special register and the CURRENT SCHEMA special register
will also contain that value. Note that the developer still needs to have the CREATEIN
privilege on the schema in which they are creating the stored procedure.
APAR PK49647 provides this functionality within the stored procedure application
development tools for external SQL Language procedures. For details on this behavior in the
development tools, see 27.7.5, “Behavior when setting the Current Schema project property”
on page 717.
If DB2 can determine whether an auth ID has a privilege by searching an authorization cache,
then it can perform that operation much faster than if it has to go to the DB2 catalog to make
that determination. Privileges for stored procedures and user-defined functions are stored in
the routine authorization cache. The size of the cache is determined by DB2 system
parameter CACHERAC.
82 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
8
Update the environment by using either the REFRESH option or the QUIESCE option
followed by the RESUME option. REFRESH is the preferred method (instead of QUIESCE
and RESUME) for all changes (such as changed load modules) that do not involve a change
in the startup JCL, since it causes minimal interruption in processing of requests.
After a REFRESH, all new address spaces will use the new JCL, but any address space
currently running will continue with the old JCL unless you do the QUIESCE/RESUME. So, in
a busy and stable environment the old JCL may remain active for a while, unless the
REFRESH/QUIESCE is issued. The REFRESH and QUIESCE options should be used as
follows:
Use the REFRESH option of the VARY z/OS command to refresh a WLM environment.
Refreshing the WLM environment starts a new instance of each address space that is
active for this WLM environment. Existing address spaces stop when the current requests
that are executing in those address spaces complete. The following example shows the
refreshing of the environment DB2GDEC1:
/VARY WLM,APPLENV=DB2GDEC1,REFRESH
When you execute this command, it is an application environment that is refreshed, not
just a stored procedure. Therefore, all stored procedures that are associated with the
application environment DB2GDEC1 are refreshed, and new invocations of each stored
procedure will automatically execute in the new instance of the address space.
You can also call the DB2-supplied stored procedure WLM_REFRESH for this purpose.
See Appendix A.2, “Refresh a WLM environment with AdminWLMRefresh” on page 817
for details.
Use the QUIESCE option of the VARY z/OS command to stop all stored procedure
address spaces that are associated with the WLM application environment. The address
spaces stop when the current requests that are executing in those address spaces
complete. The following example shows the quiesce of the environment DB2GDEC1:
/VARY WLM,APPLENV=DB2GDEC1,QUIESCE
When you execute this command, you affect all stored procedures that are associated with
the application environment DB2GDEC1.
You follow this with the RESUME option of the VARY z/OS command to start all stored
procedure address spaces that are associated with the WLM application environment. In
general, you use this option for changes to the startup JCL only and new address spaces
start when the JCL changes are complete. The following example shows the restart of
environment DB2GDEC1:
/VARY WLM,APPLENV=DB2GDEC1,RESUME
See z/OS V1R8.0 MVS Planning: Workload Management, SA22-7602-13 for more
information about the command VARY WLM.
84 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
There are very few instances where you need to STOP or START an individual stored
procedure. If the stored procedure abends a specified number of times (see 8.5, “Handling
application failures” on page 87 for details), DB2 places it in a STOPABN status and you must
issue a START command as shown below to make it operational again:
-START PROCEDURE(DEVL7083.EMPDTLSC)
Note that for native SQL procedures you can only STOP or START the current version of a
procedure. There is no way to stop or start a specific version. For more details on native SQL
procedures see Chapter 15, “Native SQL procedures” on page 253.
If you want to temporarily queue requests while you quickly change something, you can find
useful the command STOP PROC ACTION(QUEUE).
STOP PROC ACTION(REJECT) can be used in case you believe too many requests are
queuing up or a flood of stored procedure invocations is causing too many WLM stored
procedure address space instances to start. In either of these cases you should be open a
problem to IBM.
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,
the 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.
Additionally, when WLM stops an application environment, it sends the following message to
the console and system log.
IWM032I Internal stop for xxxxx completed
The message on the console will not be highlighted. So the effect may not be known
immediately as long as you have active address spaces serving the requests. The clients will
If the execution profile of the stored procedure is predictable (that is, it does a fixed amount of
work), you can set this limit quite easily. For example, for a stored procedure that generally
consumes less than 1 CPU second, you can set this limit to a small reasonable number (say
30 CPU seconds). This prevents any run-away queries without causing any accidental cancel
of a stored procedure that should have been allowed to run.
If the execution profile of the stored procedure is unpredictable (that is, the work it does varies
and can be impacted by the data), ASUTIME is a little harder to set. However, we recommend
that a reasonable upper limit be set for all stored procedures, and that no stored procedure
should be allowed to run with the NO LIMIT option (which again, is the dangerous default).
Since accidental looping is more likely in the development environments, you may consider
placing a smaller limit in the development environment and a higher limit in a production
environment.
86 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
8.5 Handling application failures
When a stored procedure abends continually, it can have a negative impact on the other
stored procedures that execute in the same application environment. DB2 provides you with
two options to manage these stored procedures, one at the DB2 subsystem level and one at
the individual stored procedure level.
At the subsystem level you can specify the maximum number of failures of a stored procedure
before it is placed in a stopped status. This is controlled by the zparm STORMXAB on
installation panel DSNTIPX.
There are options on the CREATE PROCEDURE statement that allow you to control this
behavior at the individual stored procedure level. The possible choices are discussed below:
STOP AFTER SYSTEM DEFAULT FAILURES
This specifies that the stored procedure should be placed in a stopped status after the
number of failures reaches the value of MAX ABEND COUNT (STORMXAB) on
installation panel DSNTIPX. This is the default and the only behavior allowed in V7.
STOP AFTER n FAILURES
This specifies that the stored procedure should be placed in a stopped status after n
failures. The value of n can be an integer between 1 and 32767.
CONTINUE AFTER FAILURE
This specifies that the stored procedure should not be placed in a stopped status after any
number of failures.
The option you should choose for this parameter is based on various factors including the
following:
Frequency of execution
Monitoring and early detection of failures
Criticality of the stored procedure
Most likely cause of failure (program logic, resources, data)
You may also want to configure the test environment different from the production
environment. For example, a large number of failures can be tolerated in test to eliminate
frequent DBA intervention, but a lower limit can be specified in a production environment.
The ability to set this limit at the stored procedure level gives you complete control over the
environment, and can eliminate repeated resource-intensive failures of a stored procedure for
the same reason until the problem is resolved.
Note that when a stored procedure is called by a trigger (see Chapter 26, “Using triggers and
UDFs” on page 629 for details), the stored procedure must be defined first—that is, CREATE
PROCEDURE must be issued before CREATE TRIGGER. Similarly, an attempt to drop the
stored procedure used by a trigger will result in an error; instead, you must drop the trigger
first. For an external stored procedure, the DB2 package does not need to exist until the
trigger is executed.
The list of options discussed here is not exhaustive. See DB2 Version 9.1 SQL Reference,
SC18-9854 for details.
First, we look at some stored procedures-related subsystem default values, which are defined
at install time.
* 1 WLM PROC NAME ===> DB8RWLM WLM-established stored procedure JCL PROC
2 NUMBER OF TCBS ===> 8 Number of concurrent TCBs (1-100)
3 MAX ABEND COUNT ===> 0 Allowable ABENDs for a procedure (0-255)
4 TIMEOUT VALUE ===> 180 Seconds to wait before SQL CALL or
function invocation fails (5-1800,NOLIMIT)
5 WLM ENVIRONMENT ===> Default WLM env name
6 MAX OPEN CURSORS ===> 500 Maximum open cursors per thread
7 MAX STORED PROCS ===> 2000 Maximum active stored procs per thread
1 WLM PROC NAME - It specifies a name for the stored procedures JCL procedure that is
generated during installation. This procedure is used for a WLM-established stored
procedures’ address space. If this field has a blank, the JCL procedure is still generated.
The default procedure will be named by appending the string WLM to the DB2 subsystem
name.
2 NUMBER OF TCBS - It specifies how many SQL CALL statements or invocations of
user-defined functions can be processed concurrently in one address space. This value is
limited by the USS MAXPROCUSER (maximum number of processes for the user) value.
As of V8, the value specified in NUMTCB is sent to WLM as a maximum task limit.
92 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
3 MAX ABEND COUNT - The DSNZPARM parameter is STORMXAB. It specifies the number
of times a stored procedure or an invocation of a user-defined function is allowed to
terminate abnormally, after which SQL CALL statements for the stored procedure or
user-defined function are rejected. The default of 0 (recommended for production) means
that the first abend of a stored procedure causes SQL CALLs to that procedure to be
rejected. This parameter is subsystem wide, which means that you have to treat all stored
procedures and UDFs equally. However, as of DB2 V8, you can specify a value for each
stored procedure or UDF.
4 TIMEOUT VALUE - The DSNZPARM parameter is STORTIME. It specifies the number of
seconds DB2 waits for an SQL CALL to be assigned to one TCB in a DB2 stored
procedures address space. If the time interval expires, the SQL statement fails.
Recommendation: Do not select the NOLIMIT value. If the stored procedure address
space is down for some reason or the user-defined function does not complete, your
SQL request hangs until the request is satisfied or the thread is canceled.
5 WLM ENVIRONMENT - The DSNZPARM parameter is WLMENV. It specifies the name of the
WLM_ENVIRONMENT to use for a stored procedure when a value is not given for the
WLM_ENVIRONMENT option on the CREATE FUNCTION or CREATE PROCEDURE
statements. Specify a default WLM environment even if you do not plan to use external
stored procedures. You need a WLM environment for debugging native SQL procedures
using the DB2 Unified Debugger.
6 MAX OPEN CURSORS - The DSNZPARM parameter is MAX_NUM_CUR. It specifies the
maximum number of cursors, including allocated cursors, open per thread. If an
application attempts to open a thread after the maximum is reached, the statement will fail.
This option is applicable as of DB2 V8.
7 MAX STORED PROCS - The DSNZPARM parameter is MAX_ST_PROC. It specifies the
maximum number of stored procedures per thread. If an application attempts to call a
stored procedure after the maximum is reached, the statement will fail. This count is
cleared at commit time. This option is applicable as of DB2 V8.
Figure 9-2 on page 94 shows the DB2 Protection install panel DSNTIPP for DB2 V9. Specify
how much storage to allocate for the caching of routine authorization information for all
routines on this DB2 member. Routines include stored procedures, CAST functions and
user-defined functions. For details on setting the routine authorization cache, see 7.5.8,
“Authorization caching” on page 81.
1 ARCHIVE LOG RACF ===> NO RACF protect archive log data sets
2 USE PROTECTION ===> YES DB2 authorization enabled. YES or NO
3 SYSTEM ADMIN 1 ===> SYSADM Authid of system administrator
4 SYSTEM ADMIN 2 ===> SYSADM Authid of system administrator
5 SYSTEM OPERATOR 1 ===> SYSOPR Authid of system operator
6 SYSTEM OPERATOR 2 ===> SYSOPR Authid of system operator
7 UNKNOWN AUTHID ===> IBMUSER Authid of default (unknown) user
8 RESOURCE AUTHID ===> SYSIBM Authid of Resource Limit Table creator
9 BIND NEW PACKAGE ===> BINDADD Authority required: BINDADD or BIND
10 PLAN AUTH CACHE ===> 3072 Size in bytes per plan (0 - 4096)
11 PACKAGE AUTH CACHE===> 100K Global - size in bytes (0-5M)
12 ROUTINE AUTH CACHE===> 100K Global - size in bytes (0-5M)
13 DBADM CREATE AUTH ===> NO DBA can create views/aliases for others
14 AUTH EXIT LIMIT ===> 10 Access control exit shutdown threshold
The option lists contain the definition of the characteristics of the stored procedure.
94 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
DYNAMIC RESULT SETS 0
VARCHAR NULTERM
STRUCTURE
JAVA NO SQL
PLI
REXX
( name , * )
COMMIT ON RETURN NO
Figure 9-4 The option list for CREATE and ALTER PROCEDURE EXTERNAL
96 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 9-6 The option list for CREATE and ALTER PROCEDURE SQL - native
In comparison to what we have for external SQL procedures, most of the parameters are
basically the same as those used in BIND and REBIND. See 15.2.2, “CREATE PROCEDURE
syntax” on page 265 for a discussion of these parameters.
The maximum number of result sets that can be returned by the stored procedure is
controlled by the DYNAMIC RESULT SETS parameter. The possible choices are any number
between 0 and 32767, with 0 being the default. Specifying a number other than 0 does not
mean that the stored procedure must return that many result sets, it simply specifies the
upper boundary.
When LANGUAGE Java is specified, the EXTERNAL NAME clause must be specified with a
valid external Java routine name and PARAMETER STYLE must be Java. The procedure
must be a public static method of the specified Java class. DBINFO, PROGRAM TYPE MAIN,
and RUN OPTIONS are not permissible parameters.
When LANGUAGE REXX is specified, PARAMETER STYLE of SQL is not permissible (must
specify GENERAL or GENERAL WITH NULLS).
See “Appendix C” of DB2 Version 9.1 for z/OS SQL Reference, SC18-9854 for details on
which statements are allowed depending on the value of this parameter.
98 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
There are no known performance implications in using the most general form—MODIFIES
SQL DATA. This eliminates the need to change the parameters later if the functionality of the
stored procedure changes. You may want to specify a more restrictive parameter to ensure,
for example, that updates do not happen within the scope of a stored procedure.
For REXX stored procedures, GENERAL and GENERAL WITH NULLS are the only valid
values, so do not use the default value of SQL for REXX stored procedures.
Figure 9-7 shows the structure of the parameter list of the external procedure when
PARAMETER STYLE GENERAL is used. As a general rule the PARAMETER STYLE has no
impact on the calling application.
Figure 9-8 shows the structure of the parameter list when PARAMETER STYLE GENERAL
WITH NULLS is used.
Indicator
Indicator 1 data
array
Indicator 2 data
Indicator n
Figure 9-8 Parameter convention GENERAL WITH NULLS for a stored procedure
Figure 9-9 on page 101 shows the structure of the parameter list when PARAMETER STYLE
SQL is used.
Important: Remember that when using parameter style SQL, an array of indicator
variables is not supported; you must specify an elementary item for each indicator variable.
100 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Register 1 Address of: Data:
Parameter 1
Parameter 1 data
Parameter n
Parameter n data
Indicator
parameter 1 Indicator 1
Indicator Indicator 2
parameter 2
Indicator
parameter n Indicator n
SQLSTATE SQLSTATE
Diagnostic
Diagnostic Data
data
DBINFO DBINFO
Figure 9-10 shows the structure of the parameter list when PARAMETER STYLE JAVA is
used. The list of ResultSet parameters is optional.
ResultSet
parameter list ResultSet 1
ResultSet 2
ResultSet n
A stored procedure that contains SQL can by definition return a different result for each call.
Another such example is one where a random number is generated within the stored
procedure. In such cases, it should be specified as NOT DETERMINISTIC. Only if you are certain
that the result will be the same, should you specify DETERMINISTIC.
Note that DB2 does not verify that the stored procedure code is consistent with the
specification of DETERMINISTIC or NOT DETERMINISTIC. For example, you can define the stored
procedure as DETERMINISTIC when in reality its behavior is such that it returns different values
when called with a set of identical values as input, and DB2 does not check the logic.
or
PACKAGE PATH package-path
NO PACKAGE PATH specifies that the list of package collections for the procedure is the
same as the list of package collection IDs for the calling program. If the calling program does
not use a package, DB2 resolves the package by using the CURRENT PACKAGE PATH
special register, the CURRENT PACKAGESET special register, or the PKLIST bind option (in
this order).
PACKAGE PATH specifies a list of package collections, in the same format as the SET
CURRENT PACKAGE PATH special register. If the COLLID clause is specified with
PACKAGE PATH, the COLLID clause is ignored when the routine is invoked.
DBINFO can only be specified if the PARAMETER STYLE SQL is specified. NO DBINFO is the default.
102 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
9.1.10 Collection ID the stored procedure runs in
If the stored procedure contains SQL, DB2 needs to know the collection ID of the package for
the stored procedure. You may explicitly specify it in the CREATE PROCEDURE, for example:
COLLID DEVL7083
In any case, DB2 uses the following method to determine the collection ID in this order:
1. For DB2 V8 onwards, DB2 examines the CURRENT PACKAGE PATH special register if
set by a stored procedure program. If it contains a value, DB2 uses this as the collection
ID for the stored procedure.
2. DB2 examines the CURRENT PACKAGESET special register. If it contains a value set by
the stored procedure program, DB2 uses this as the collection for the stored procedure.
3. If there is an explicit package associated with the CREATE PROCEDURE COLLID option,
DB2 uses this collection ID for the stored procedure.
4. If the calling application has set the CURRENT PACKAGESET special register, DB2 uses
this as the collection ID for the stored procedure. This is new with V8 and it allows a
remote caller to determine the search path.
5. If the calling application has a package collection associated with it, DB2 uses it for the
stored procedure.
6. DB2 examines the plan of the calling application and uses the list of collection IDs
specified in the PKLIST in the specified order. This process is especially
resource-intensive for distributed applications where the PKLIST consists of multiple
collection IDs since a network request to locate the package in each collection is sent until
the package is found. SET CURRENT PACKAGESET eliminates this search.
DB2 keeps track of the collection ID of the caller. Once the control is returned from the stored
procedure to the client, DB2 resets the CURRENT PACKAGESET value to the collection ID of
the caller. This is particularly useful where application programs are divided into two
collections such as ONLINE and BATCH, and stored procedures will be called from both
ONLINE and BATCH programs. If NO COLLID is specified, then the stored procedure packages
need to be bound to both ONLINE and BATCH collection IDs. When you specify COLLID
xxxxx, the stored procedures can be bound to their own collection ID, independent of the
caller.
We recommend that a reasonable limit be established to handle a stored procedure that loops
during testing. In addition, such a limit helps any accidental run-away stored procedures in a
production environment.
This limit is independent of the ASUTIME specified in the resource limit facility (RLF), which
applies to dynamic SQL only, and is at the statement level. In general, the lower limit applies.
Exceeding this limit causes an SQLCODE -905 also, as shown in Example 9-2.
Important: The ASUTIME limit for a stored procedure applies to all users, including those
with a SYSADM authority. You cannot have a different limit for different authids. RLF limit
does not apply to users with SYSADM authority, and you can specify different limits for
different authids.
To make a reentrant stored procedure remain resident in storage, specify STAY RESIDENT
YES in the CREATE PROCEDURE or ALTER PROCEDURE statement for the stored
procedure.
A stored procedure that is compiled and link-edited as reentrant may be defined with either
STAY RESIDENT YES or NO. If you plan to have your stored procedure remain resident in
storage after execution by specifying STAY RESIDENT YES, then you must also prepare the
104 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
stored procedure module as reentrant. If you prepare your stored procedure module as
non-reentrant, then you must specify STAY RESIDENT NO. You cannot prepare a stored
procedure module as non-reentrant and specify STAY RESIDENT YES. Table 9-1
summarizes the residency and re-entrancy characteristics.
The default program type depends on the language and/or the CURRENT RULES special
register as shown here:
For REXX, the default program type is MAIN.
For Java, the default program type is SUB.
For other languages:
– If CURRENT RULES is DB2, default is MAIN.
– If CURRENT RULES is STD, default is SUB.
We recommend using PROGRAM TYPE SUB for all languages except REXX, where it is not
possible. This eliminates the need for the stored procedure to carry out the initial
housekeeping routines at each invocation.
Specifying SECURITY DB2 leads to ease of implementation, and may in general be the best
option for you.
The option you should choose for this parameter is based on various factors, including the
following:
Frequency of execution
Monitoring and early detection of failures
Criticality of the stored procedure
Most likely cause of failure (program logic, resources, data)
You may also want to configure the test environment different from production. For example, a
large number of failures can be tolerated in test to eliminate frequent DBA intervention, but a
lower limit can be specified in a production environment.
The additional option RPTOPTS(ON) causes I/O to the JES spool and should be used only for
debugging purposes.
Note: Avoid grouping PROGRAM TYPE SUB stored procedures with different runtime
options in the same WLM application environment because this can make those stored
procedures behave like PROGRAM TYPE MAIN.
The advantage of COMMIT ON RETURN YES occurs primarily in the distributed environment
where a client application can otherwise continue to hold locks on the updated DB2 objects.
By committing early, you can release the locks earlier. However, be aware of the fact that all
work in the unit of work (including work done by the calling program) is committed.
If you specify COMMIT ON RETURN YES, and the stored procedure returns result sets, the cursors
associated with the result sets must be declared using the WITH HOLD option to be usable
after the commit.
106 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
We recommend COMMIT ON RETURN YES for distributed applications. Nevertheless, we also
recommend to always commit at the client application. See Chapter 19, “General
performance considerations” on page 391 for details.
The COMMIT ON RETURN should be NO for nested stored procedures also. A stored procedure
cannot call other stored procedures defined with COMMIT ON RETURN YES.
The section “Using special registers in a stored procedure” in Chapter 25 of DB2 Version 9.1
for z/OS Application Programming and SQL Guide, SC18-9841 shows the values for each
register when using each of these options. Note that in some cases, the default is the same
as the value received from the invoker.
This parameter should not be confused with the PARAMETER STYLE parameter discussed
in 9.1.6, “Passing parameters” on page 99.
Currently, CALLED ON NULL INPUT is the only option, so you do not really have a choice.
We recommend specifying it for documentation and to prepare you for any future changes.
If the EXTERNAL NAME is specified or defaulted (to the full procedure name), it is checked
for a valid MVS load module name, and if invalid SQLCODE -449 is issued.
C stored procedure
See Example 9-4.
108 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
, OUT LASTNAME VARCHAR(15) CCSID EBCDIC
, OUT WORKDEPT CHAR(3) CCSID EBCDIC
, OUT HIREDATE DATE
, OUT SALARY DEC(9,2)
, OUT RETCODE INTEGER
, OUT MESSAGE VARCHAR(1331) CCSID EBCDIC
)
RESULT SETS 0
EXTERNAL NAME EMPDTL1P
LANGUAGE C
PARAMETER STYLE GENERAL
MODIFIES SQL DATA
WLM ENVIRONMENT DB9AWLM
STAY RESIDENT NO
COLLID DEVL7083
PROGRAM TYPE MAIN
RUN OPTIONS 'TRAP(OFF),STACK(,,ANY,)'
COMMIT ON RETURN NO
ASUTIME NO LIMIT;
Example 9-7 Parameters for SQL language external stored procedure CREATE
CREATE PROCEDURE DEVL7083.EMPDTLSS
(
IN PEMPNO CHAR(6)
,OUT PFIRSTNME VARCHAR(12)
,OUT PMIDINIT CHAR(1)
,OUT PLASTNAME VARCHAR(15)
,OUT PWORKDEPT CHAR(3)
,OUT PHIREDATE DATE
,OUT PSALARY DEC(9,2)
,OUT PSQLCODE INTEGER
,OUT PSQLSTATE CHAR(5)
,OUT PSQLERRMC VARCHAR(250)
)
DYNAMIC RESULT SETS 0
PARAMETER STYLE GENERAL WITH NULLS
MODIFIES SQL DATA
NO DBINFO
WLM ENVIRONMENT DB9AWLM
STAY RESIDENT NO
COLLID DEVL7083
PROGRAM TYPE MAIN
RUN OPTIONS 'TRAP(OFF),RPTOPTS(OFF)'
COMMIT ON RETURN NO
LANGUAGE SQL
...
Attention: Even though DB2 builds external SQL procedures as external C load modules,
you must always specify LANGUAGE SQL in the CREATE PROCEDURE statement.
Never redeploy externally the module as a LANGUAGE C stored procedure. Unpredictable
errors will happen.
110 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
INTO CUSTOMER_NAME
FROM ACCOUNTS
WHERE CUSTNO = CUSTOMER_NO;
END
For versioning in native SQL procedures, see Section 15.3, “Versioning” on page 291.
PARAMETER STYLE For Java, use Java (required), for SQL it cannot be specified,
for REXX use GENERAL unless the stored procedure has
many large parameters that can contain nulls, in which case
use GENERAL WITH NULLS; for all other languages use SQL
DETERMINISTIC/ Currently DB2 does not use this information but may in the
NOT DETERMINISTIC future. If you know for certain that same result will be returned,
use DETERMINISTIC. In all other cases, use NOT
DETERMINISTIC
STAY RESIDENT YES/ STAY RESIDENT YES for better performance (production).
STAY RESIDENT NO STAY RESIDENT NO eliminates need to issue refresh when
there is one user only (development).
PROGRAM TYPE SUB/ PROGRAM TYPE SUB for all except REXX which requires
PROGRAM TYPE MAIN MAIN.
STOP AFTER SYSTEM DEFAULT Depends on the application. If you specify CONTINUE AFTER
FAILURES/ FAILURE, make sure you have a monitoring system in place to
STOP AFTER n FAILURES/ detect any repeated failures that could impact the system.
CONTINUE AFTER FAILURE
CALLED ON NULL INPUT Currently DB2 allows this as the only choice (not specifying this
option uses the default, which is again CALLED ON NULL
INPUT). We still recommend specifying it for documentation
and to prepare for any future changes.
112 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
10
Note: Complete sample programs can be downloaded from the ITSO Web site as
additional material. Download instructions can be found in Appendix B, “Additional
material” on page 887.
Before downloading, we strongly suggest that you first read 3.3, “Sample application
components” on page 24 to decide what components are applicable to your environment.
A stored procedure can receive and send back parameters to the calling application. When
the calling application issues an SQL CALL to the stored procedure, DB2 builds a parameter
list based on the parameters coded in the SQL call, and the information specified when the
stored procedure is initially defined. One of the options on the CREATE PROCEDURE
statement is PARAMETER STYLE, which specifies whether or not nulls can be passed as
parameters. This is discussed in detail in 9.1, “CREATE or ALTER PROCEDURE parameters”
on page 92. When nulls are permitted, the stored procedure and the calling program must
take some additional steps. This is discussed in 10.2.5, “Handling null values in parameters”
on page 117. In this section we assume that nulls are not permitted.
114 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
For a COBOL stored procedure retrieving information about a specific employee, the
parameter list specified when defining the stored procedure looks like the contents of
Example 10-1.
This definition specifies whether the parameter is IN (input to the stored procedure), OUT
(output from the stored procedure) or INOUT (input to and output from the stored procedure).
It also specifies the data type and size of each parameter. This list must be compatible with
the parameter list in the calling application and is shown in Example 10-2.
The defined variables must also be compatible with the parameter list defined in the linkage
section of the stored procedure, the procedure division using statement and with their
definition of parameters in the CREATE PROCEDURE statement. For our sample procedure
it looks like Example 10-3.
116 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Use GRANT EXECUTE to authorize the appropriate users to use the stored procedure.
If the stored procedure returns a result set, additional processing is required; this is discussed
in 10.2.8, “Handling result sets in the calling program” on page 128.
In the calling program, you must define an additional set of indicator variables with one for
each nullable parameter. In our example, when each parameter is nullable, the working
storage of the calling application looks something like Example 10-6.
Example 10-6 Parameter list of calling application when nulls are allowed
01 PEMPNO PIC X(6).
01 PFIRSTNME.
49 PFIRSTNME-LEN PIC S9(4) COMP.
49 PFIRSTNME-TEXT PIC X(12).
01 PMIDINIT PIC X(1).
01 PLASTNAME.
The grouping of all null indicator variables shown in NULL-IND-VARS is a good programming
practice, although the only requirement is that they be defined in the LINKAGE SECTION.
This is not a requirement of the calling program, only of the stored procedure.
The parameter list in the linkage section of the stored procedure must also include the null
indicator variables as shown in Example 10-7.
Example 10-7 Parameter list in the linkage section when nulls are allowed
LINKAGE SECTION.
01 PEMPNO PIC X(6).
01 PFIRSTNME.
49 PFIRSTNME-LEN PIC S9(4) COMP.
49 PFIRSTNME-TEXT PIC X(12).
01 PMIDINIT PIC X(1).
01 PLASTNAME.
49 PLASTNAME-LEN PIC S9(4) COMP.
49 PLASTNAME-TEXT PIC X(15).
01 PWORKDEPT PIC X(3).
01 PHIREDATE PIC X(10).
01 PSALARY PIC S9(7)V9(2) COMP-3.
01 PSQLCODE PIC S9(9) COMP.
01 PSQLSTATE PIC X(5).
01 PSQLERRMC.
49 PSQLERRMC-LEN PIC S9(4) COMP.
49 PSQLERRMC-TEXT PIC X(250).
01 NULL-IND-VARS.
05 PEMPNO-IV PIC S9(4) COMP.
05 PFIRSTNME-IV PIC S9(4) COMP.
05 PMIDINIT-IV PIC S9(4) COMP.
05 PLASTNAME-IV PIC S9(4) COMP.
05 PWORKDEPT-IV PIC S9(4) COMP.
05 PHIREDATE-IV PIC S9(4) COMP.
05 PSALARY-IV PIC S9(4) COMP.
05 PSQLCODE-IV PIC S9(4) COMP.
05 PSQLSTATE-IV PIC S9(4) COMP.
05 PSQLERRMC-IV PIC S9(4) COMP.
118 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Unlike the definition in the calling application, the grouping of all null indicator variables shown
in NULL-IND-VARS is not only good programming practice; it is a requirement that they be
defined as a group in the LINKAGE SECTION. There must be one null indicator per
parameter.
The procedure division for the stored procedure must receive the additional parameters
shown in Example 10-8.
Example 10-8 Procedure division using the parameters when nulls are allowed
PROCEDURE DIVISION USING PEMPNO, PFIRSTNME, PMIDINIT, PLASTNAME
PWORKDEPT, PHIREDATE, PSALARY, PSQLCODE,
PSQLSTATE, PSQLERRMC, NULL-IND-VARS.
The calling program must include the indicator variables in the CALL shown in Example 10-9.
The indicators are matched with parameters strictly on a positional basis, not by names.
Example 10-9 SQL CALL COBOL example when nulls are allowed
EXEC SQL
CALL EMPDTLSC( :PEMPNO :PEMPNO-IV
,:PFIRSTNME :PFIRSTNME-IV
,:PMIDINIT :PMIDINIT-IV
,:PLASTNAME :PLASTNAME-IV
,:PWORKDEPT :PWORKDEPT-IV
,:PHIREDATE :PHIREDATE-IV
,:PSALARY :PSALARY-IV
,:PSQLCODE :PSQLCODE-IV
,:PSQLSTATE :PSQLSTATE-IV
,:PSQLERRMC :PSQLERRMC-IV
)
END-EXEC.
Important: When you use PARAMETER STYLE SQL, be aware of three important code
requirements:
The CREATE PROCEDURE ddl must not specify these additional parameters:
,OUT DSQLSTATE CHAR(5)
,OUT DSPNAME VARCHAR(517)
,OUT DSPECNAME VARCHAR(128)
,OUT DDIAGMSG VARCHAR(70)
Define the additional variables in the linkage section of the stored procedure.
Define the indicator variables as elementary items (when using parameter style
GENERAL WITH NULLS they must be part of a group item).
In this case, the working storage of the calling application looks like Example 10-11. Note that
this is exactly the same as for parameter style GENERAL WITH NULLS.
Example 10-11 Parameter list of calling application using PARAMETER STYLE SQL
01 PEMPNO PIC X(6).
01 PFIRSTNME.
49 PFIRSTNME-LEN PIC S9(4) COMP.
49 PFIRSTNME-TEXT PIC X(12).
01 PMIDINIT PIC X(1).
01 PLASTNAME.
49 PLASTNAME-LEN PIC S9(4) COMP.
49 PLASTNAME-TEXT PIC X(15).
01 PWORKDEPT PIC X(3).
01 PHIREDATE PIC X(10).
01 PSALARY PIC S9(7)V9(2) COMP-3.
01 PSQLCODE PIC S9(9) COMP.
01 PSQLSTATE PIC X(5).
01 PSQLERRMC.
49 PSQLERRMC-LEN PIC S9(4) COMP.
120 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
49 PSQLERRMC-TEXT PIC X(250).
01 NULL-IND-VARS.
05 PEMPNO-IV PIC S9(4) COMP.
05 PFIRSTNME-IV PIC S9(4) COMP.
05 PMIDINIT-IV PIC S9(4) COMP.
05 PLASTNAME-IV PIC S9(4) COMP.
05 PWORKDEPT-IV PIC S9(4) COMP.
05 PHIREDATE-IV PIC S9(4) COMP.
05 PSALARY-IV PIC S9(4) COMP.
05 PSQLCODE-IV PIC S9(4) COMP.
05 PSQLSTATE-IV PIC S9(4) COMP.
05 PSQLERRMC-IV PIC S9(4) COMP.
The parameter list in the linkage section of the stored procedure must also include the
indicator variables as level 01 (highlighted in the example) shown in Example 10-12.
Example 10-12 Parameter list in the linkage section using PARAMETER STYLE SQL
LINKAGE SECTION.
01 PEMPNO PIC X(6).
01 PFIRSTNME.
49 PFIRSTNME-LEN PIC S9(4) COMP.
49 PFIRSTNME-TEXT PIC X(12).
01 PMIDINIT PIC X(1).
01 PLASTNAME.
49 PLASTNAME-LEN PIC S9(4) COMP.
49 PLASTNAME-TEXT PIC X(15).
01 PWORKDEPT PIC X(3).
01 PHIREDATE PIC X(10).
01 PSALARY PIC S9(7)V9(2) COMP-3.
01 PSQLCODE PIC S9(9) COMP.
01 PSQLSTATE PIC X(5).
01 PSQLERRMC.
49 PSQLERRMC-LEN PIC S9(4) COMP.
49 PSQLERRMC-TEXT PIC X(250).
01 PEMPNO-IV PIC S9(4) COMP.
01 PFIRSTNME-IV PIC S9(4) COMP.
01 PMIDINIT-IV PIC S9(4) COMP.
01 PLASTNAME-IV PIC S9(4) COMP.
01 PWORKDEPT-IV PIC S9(4) COMP.
01 PHIREDATE-IV PIC S9(4) COMP.
01 PSALARY-IV PIC S9(4) COMP.
01 PSQLCODE-IV PIC S9(4) COMP.
01 PSQLSTATE-IV PIC S9(4) COMP.
01 PSQLERRMC-IV PIC S9(4) COMP.
01 DSQLSTATE PIC X(5).
01 DSPNAME.
49 DSPNAME-LEN PIC S9(4) COMP.
49 DSPNAME-TEXT PIC X(517).
01 DSPECNAME.
49 DSPECNAME-LEN PIC S9(4) COMP.
49 DSPECNAME-TEXT PIC X(128).
01 DDIAGMSG.
49 DDIAGMSG-LEN PIC S9(4) COMP.
49 DDIAGMSG-TEXT PIC X(70).
The procedure division for the stored procedure must receive the additional parameters
shown in Example 10-13.
The calling program must include the indicator variables for all defined parameters, but must
not include the parameters associated with parameter style SQL, as shown in
Example 10-14.
Example 10-14 SQL CALL COBOL example using PARAMETER STYLE SQL
EXEC SQL
CALL EMPDTLSC( :PEMPNO :PEMPNO-IV
,:PFIRSTNME :PFIRSTNME-IV
,:PMIDINIT :PMIDINIT-IV
,:PLASTNAME :PLASTNAME-IV
,:PWORKDEPT :PWORKDEPT-IV
,:PHIREDATE :PHIREDATE-IV
,:PSALARY :PSALARY-IV
,:PSQLCODE :PSQLCODE-IV
,:PSQLSTATE :PSQLSTATE-IV
,:PSQLERRMC :PSQLERRMC-IV
)
END-EXEC.
When using parameter style SQL, the SQLSTATE value you set in the stored procedure
before returning to the caller affects the SQLCODE, SQLSTATE, and the diagnostic string
passed back to the caller. If DB2 sets the SQLSTATE value (for example, in case of a timeout
or deadlock), this value overrides the value set by the stored procedure, and is unconditionally
returned to the caller. Table 10-1 shows, for each value or range of values, the corresponding
data received by the caller. In these examples the output ERRMC was set to the string
+++ANY MESSAGE+++. The entries for 38yxx and 385xx are the same.
Table 10-1 Impact of SQLSTATE values set by the stored procedure
Stored Caller Caller Sample SQLCA output
procedure receives receives
sets this this this
SQLSTATE SQLCODE SQLSTATE
01Hxy (e.g. +462 01Hxy (e.g. DSNT404I SQLCODE = 462, WARNING: EXTERNAL FUNCTION OR
01H12) 01H12) PROCEDURE EMPDTLSC (SPECIFIC NAME EMPDTLSC) HAS
RETURNED A WARNING SQLSTATE, WITH
DIAGNOSTIC TEXT +++ ANY MESSAGE +++
DSNT418I SQLSTATE = 01H12 SQLSTATE RETURN CODE
DSNT415I SQLERRP = DSNXRRTN SQL PROCEDURE DETECTING
ERROR
DSNT416I SQLERRD = -821 0 0 -1 0 0 SQL DIAGNOSTIC
INFORMATION
DSNT416I SQLERRD = X'FFFFFCCB' X'00000000' X'00000000'
X'FFFFFFFF'
X'00000000' X'00000000' SQL DIAGNOSTIC INFORMATION
122 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Stored Caller Caller Sample SQLCA output
procedure receives receives
sets this this this
SQLSTATE SQLCODE SQLSTATE
38yxx (y <> -443 38yxx (e.g. DSNT408I SQLCODE = -443, ERROR: EXTERNAL FUNCTION
5) (e.g. 38999) EMPDTLSC (SPECIFIC NAME EMPDTLSC) HAS RETURNED AN
38999) ERROR SQLSTATE WITH DIAGNOSTIC TEXT +++
ANY MESSAGE +++
DSNT418I SQLSTATE = 38999 SQLSTATE RETURN CODE
DSNT415I SQLERRP = DSNXRRTN SQL PROCEDURE DETECTING
ERROR
DSNT416I SQLERRD = -891 0 0 -1 0 0 SQL DIAGNOSTIC
INFORMATION
DSNT416I SQLERRD = X'FFFFFC85' X'00000000' X'00000000'
X'FFFFFFFF'
X'00000000' X'00000000' SQL DIAGNOSTIC INFORMATION
385xx (e.g. -443 385xx (e.g. DSNT408I SQLCODE = -443, ERROR: EXTERNAL FUNCTION
38555) 38555) EMPDTLSC (SPECIFIC NAME EMPDTLSC) HAS RETURNED AN
ERROR SQLSTATE WITH DIAGNOSTIC TEXT +++
ANY MESSAGE +++
DSNT418I SQLSTATE = 38555 SQLSTATE RETURN CODE
DSNT415I SQLERRP = DSNXRRTN SQL PROCEDURE DETECTING
ERROR
DSNT416I SQLERRD = -891 0 0 -1 0 0 SQL DIAGNOSTIC
INFORMATION
DSNT416I SQLERRD = X'FFFFFC85' X'00000000' X'00000000'
X'FFFFFFFF'
X'00000000' X'00000000' SQL DIAGNOSTIC INFORMATION
Other (e.g. -463 39001 DSNT408I SQLCODE = -463, ERROR: EXTERNAL FUNCTION
21000) EMPDTLSC (SPECIFIC NAME EMPDTLSC) HAS RETURNED AN
INVALID SQLSTATE 21000, WITH DIAGNOSTIC TEXT
+++ ANY MESSAGE +++
DSNT418I SQLSTATE = 39001 SQLSTATE RETURN CODE
DSNT415I SQLERRP = DSNXRRTN SQL PROCEDURE DETECTING
ERROR
DSNT416I SQLERRD = -881 0 0 -1 0 0 SQL DIAGNOSTIC
INFORMATION
DSNT416I SQLERRD = X'FFFFFC8F' X'00000000' X'00000000'
X'FFFFFFFF'
X'00000000' X'00000000' SQL DIAGNOSTIC INFORMATION
While you have a great amount of flexibility in terms of what SQLSTATE should be set by the
stored procedures, we recommend that you keep these things in mind:
In general you should not set SQLSTATE to a value that can be misinterpreted by the
calling application since it may not be aware of the fact that it was set manually instead of
by DB2. For example, setting a value to 38002 causes the error text to be:
124 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
PROCEDURE EMPDTLSC ATTEMPTED TO MODIFY DATA
WHEN THE DEFINITION OF THE FUNCTION OR PROCEDURE DID NOT SPECIFY THIS
ACTION
You may then spend valuable resources tracking down the update statements that never
existed. We strongly suggest that you report back only the SQLSTATEs you encounter.
Except for the special cases noted in Table 10-1 above, the SQLCODE returned is -443 or
-463 for all cases where you specify the SQLSTATE value. Your calling application must be
coded to handle these SQLCODEs and interpret the SQLSTATEs.
The rules are different as of DB2 V8: SQLCODE-463 is replaced for Java by SQLCODE
-4302, SQLSTATE 38000.
The stored procedure definition must include these parameters shown below:
PARAMETER STYLE SQL
...
126 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
DBINFO
The parameter list in the linkage section of the stored procedure must also include these
additional variables, as shown in Example 10-15.
Handling the first case is simpler to develop, but the second case is more general and
requires minimal modifications if the calling program or stored procedure happens to change.
We discuss the two alternatives in this section.
128 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
using the COMMIT ON RETURN option (see 9.1.17, “Use of commit before returning” on
page 106 for details), the cursor must also be declared using the WITH HOLD clause to
prevent it from being closed when control returns to the calling program.
3. In the calling program, declare a locator variable for each result set that will be returned. If
you do not know how many result sets will be returned, declare enough result set locators
for the maximum number possible. An example follows:
01 LOC-EMPRSETC USAGE SQL TYPE IS
RESULT-SET-LOCATOR VARYING.
4. In the calling program, call the stored procedure and check the return code. If the
SQLCODE is +466 (SQLSTATE is 0100C), the stored procedure has returned result sets.
5. If you already know how many result sets the stored procedure returns, go to step 6.
Otherwise, issue a DECRIBE PROCEDURE statement as the following example shows.
Note that SQLDA is a structure that contains a set of variables, each set corresponding to
a cursor that returned a result set. For more information on the SQLDA structure and use,
refer to DB2 Version 9.1 for z/OS Application Programming and SQL Guide, SC18-9841.
EXEC SQL
DESCRIBE PROCEDURE EMPRSETC INTO :PSQLDA
END-EXEC.
At this point, assuming the stored procedure has opened two cursors called C1 and
MYCURSOR with the return, the SQLDA looks like what is shown in Figure 10-1.
Header
16 + 44*100
SQLVAR
6. SQLD contains the number of result sets returned by the stored procedure.
7. SQLNAMEL specifies the length of the cursor name field SQLNAMEC. SQLNAMEC
contains the name of the cursor in the stored procedure that returned the result set.
Note: The description of nested stored procedures in this section is applicable to most
languages, not just COBOL.
130 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
If a stored procedure returns any query result sets, the result sets are returned to the caller of
the stored procedure. If the SQL CALL statement is nested, the result sets are visible only to
the program that is at the previous nesting level. For example, Figure 10-2 illustrates a
scenario in which a client program calls stored procedure PROCA, which in turn calls stored
procedure PROCB. Only PROCA can access any result sets that PROCB returns; the client
program has no access to the query result sets. The number of query result sets that PROCB
returns does not count toward the maximum number of query results that PROCA can return.
C lie n t
CALL PRO C A
PR O C A
CALL PRO CB
PROCB
S e le c t * fro m ...
If the server and requester are both Version 8 of DB2 UDB for z/OS (running in
new-function mode), you can call a stored procedure multiple times within an application
and at the same nesting level. DB2 is now capable of distinguishing each running instance
created by each call to the same stored procedure. If the stored procedure returns result
sets, each instance of the stored procedure opens its own set of result set cursors.
The application might receive a resource unavailable message if the CALL statement
causes the values of the maximum number of active stored procedures or maximum
number open cursors to be exceeded. The value of field MAX STORED PROCEDURES
(on installation panel DSNTIPX) defines the maximum number of active stored procedures
that are allowed per thread (reset at commit). The value of field MAX OPEN CURSORS
(on installation panel DSNTIPX) defines the maximum number of open cursors (both result
set cursors and regular cursors) that are allowed per thread.
If you make multiple calls to the same stored procedure within an application, be aware of
the following considerations:
A DESCRIBE PROCEDURE statement describes the last instance of the stored
procedure.
The ASSOCIATE LOCATOR statement works on the last instance of the stored
procedure. You should issue an ASSOCIATE LOCATOR statement after each call to the
stored procedure to provide a unique locator value for each result set.
The ALLOCATE CURSOR statement must specify a unique cursor name for the result
set of each instance of the stored procedure. Otherwise, you will lose the data from the
results sets that are returned from prior instances or calls to the stored procedure.
One of the benefits of stored procedures is their reusability. Stored procedures, once
developed, can be called from anywhere and hence contributes to the reusability. Nested
stored procedures still increase this benefit. Nested stored procedures are available at no
extra network cost, but extra cost in terms of CPU. This is not an abnormal behavior. Each
execution of stored procedure involves some amount of CPU cost for the scheduling. If a
transaction contains multiple stored procedures at same level or nested stored procedures,
this extra cost may become significant especially if the actual cost to execute SQL inside the
stored procedure is less.
Another bottleneck with nested procedures is “queuing.” As explained earlier, every request to
execute a stored procedure should go through the WLM queue and wait for its turn. So, for a
multi-level nested stored procedure, the elapsed time to complete a transaction increases.
So, simple nested stored procedures may cause some CPU overhead and elongated
response time. This may be an issue for few organizations but not too many as it depends on
the service level agreement (SLA) of the application between you and your customer. Your
organization should take into consideration the benefits of the nested stored procedure, and
the slight overhead associated with them while designing the application and levels of
nesting. The queuing can be tuned by setting proper performance goals and/or assigning the
“right” number of TCBs to each WLM application environments.
Currently, there are no hard and fast rules for setting the NUMTCB parameter. In this book we
provide some guidelines based on the experience of different customers. See 20.1.2,
“NUMTCB” on page 425 for details.
132 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
In an informal test, we prepared a non-DB2 stored procedure and non-DB2 subprogram. We
ran tests to compare the cost of executing an SQL CALL statement with the COBOL CALL
statement, and it is approximately 90% more. But this case is purely an ideal one. In more
practical situations, the stored procedures contain some SQL statements, and when you
compare the cost of the total transaction with the cost of just the CALL statement, the cost of
the CALL might be negligible.
For more information on instrumentation, refer to 20.2, “Managing server address spaces” on
page 429.
The discussion so far in this section applies to all types of stored procedures. For users of
COBOL stored procedures, there is an alternative for nested stored procedures. As most of
the legacy applications on z/OS are built with the COBOL language, the following sections
provide a discussion on alternatives available for COBOL users.
How can COBOL subprograms solve the performance issues with stored procedures?
As explained earlier, SQL CALL incurs some overhead associated with the scheduling of
stored procedures. It may also experience elongated response time due to the queuing within
WLM. The COBOL CALL statement overcomes these two issues without compromising
functionality and performance.
Table 10-2 Main differences between COBOL stored procedures and subprograms
Criteria Stored procedures Subprograms
Ability to call from Possible. Generally should not be Not possible to call from distributed or
anywhere invoked by batch programs instead of remote applications. But possible to
local subroutines, as this causes call from local subsystems like CICS
large overhead. or batch.
Nested activity 16 levels are allowed. Each level of Allowed without additional cost.
nested activity requires some There is no imposed limit on the
additional cost in scheduling. number of CALLs or CALL levels
using the COBOL CALL statement.
Execution All stored procedures execute from Executes in native address space like
environment WLM established stored procedure TSO or CICS or WLM SPAS
address spaces (WLM SPAS). depending on where the call to
subprogram is originated.
TCB consumption More, as each execution of a stored All subprograms within a run unit
procedure in a run unit requires a require just one TCB.
TCB. So a nested stored procedure
requires more than one TCB
depending on the levels of nesting.
Result sets Supports, the caller can fetch result Not supported; the caller cannot fetch
sets from stored procedures. result sets from a subprograma.
a. See the discussion on using temporary tables to overcome this in the following sections.
As shown in Table 10-2, the program preparation part of COBOL subprograms will be more or
less the same as COBOL stored procedures. They exhibit different behavior during runtime
due to the underlying architecture. COBOL subprograms provide an alternative to nested
stored procedures. An SQL CALL within a stored procedure can be replaced by a COBOL
CALL to provide the benefits of reusability. This technique improves the performance of
nested stored procedures by eliminating the wait time in scheduling.
Example 10-16 shows the differences in the way subprograms are invoked compared to
stored procedures.
Replacing the SQL call with the COBOL call is not a solution for every performance issue
associated with nested stored procedures. However, under certain conditions it improves the
performance by eliminating wait time with scheduling. There are some exceptions and some
special considerations to be followed to replace an SQL call with a COBOL call, which are
described in 10.3.3, “Hybrid approach for optimization” on page 135.
EXEC SQL
CALL PROC1 (parameter_list)
END-EXEC.
134 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Subprogram: Dynamic call
The main differences between dynamic call and static call are summarized in Table 10-3.
Table 10-3 Main differences between COBOL static call versus dynamic call
Feature Program with static call Program with dynamic call
As shown above, it is recommended to use dynamic calls because these allow flexibility and
provide similar benefits as stored procedures in terms of maintenance.
If your application experiences lengthened response times and more wait time in scheduling
stored procedures (long accounting report will show this), then the following
recommendations can be implemented:
Use COBOL CALL instead of SQL CALL in all stored procedures to avoid nested stored
procedure activity.
Use stored procedures (SQL CALL) only in distributed applications. For local applications
(CICS, batch) use subprograms (COBOL CALL).
When we recommend to use stored procedures for remote applications and subprograms for
local applications, we do not mean to maintain two versions of the same program, one as a
stored procedure and another as a subprogram. Our intention is to maintain one single
program and invoke it differently. Detailed program preparation and invocation examples are
shown in the following sections on this topic.
Client Client
EXEC SQL
CALL PROC1 (.....) EXEC SQL
END-EXEC CALL PROC1 (.....)
END-EXEC
PROC1 PROC1
EXEC SQL CALL PROC2 using
CALL PROC2 (.....) .......
END-EXEC
PROC2
PROC2
EXEC SQL
CALL PROC3 using .......
CALL PROC3 (.....)
END-EXEC
PROC3
PROC3
CALL PROC4 using .......
EXEC SQL
CALL PROC4 (.....)
END-EXEC
PROC4
PROC4
Remote application ABC has a requirement to invoke PROC1 and go through the nested
activity until PROC4. As per our recommendation, PROC1 will be called as a stored
procedure, and all other inner level calls will be subprograms. After few months, let us say
some other remote application DEF has a requirement to invoke PROC3, it still can call
PROC3 as a stored procedure. Since application ABC accessed PROC3 as a subprogram
through PROC2, DEF does not have to invoke PROC3 as a subprogram. It still can be
accessed as a stored procedure. This is the advantage of this technique: No compromise of
reusability. The same rule applies to all programs. The way you invoke matters, not the way
you prepared the stored procedure or subprogram.
Preparation
These are the steps:
1. Develop the programs and ensure that subprogram calls are made to PROC2, PROC3,
and PROC4 from their higher level programs. For example:
PROC1 code contains
CALL PROC2 using .........
PROC2 code contains
CALL PROC3 using .........
PROC3 code contains
CALL PROC4 using .........
2. Precompile and compile the programs.
3. Link-edit with DSNRLI.
136 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
4. Bind the DBRMs to produce DB2 packages.
5. Refresh WLM SPAS.
6. Define PROC1, PROC2, PROC3, and PROC4 as stored procedures.
Invocation
From application ABC, invoke PROC1:
EXEC SQL
CALL PROC1 (..............)
END-EXEC.
Special considerations
However, as shown in Table 10-2, COBOL subprograms cannot return result sets. So, if you
design your stored procedure to return the result, the same stored procedure cannot be
replaced with the subprogram. This is a known restriction.
To overcome the restriction of result sets with subprograms, DB2 temporary tables can be
used. Throughout this chapter, our intention is to provide alternatives to nested stored
procedures without compromising the benefits of their reusability. Table 10-4 shows how
result sets can be used with subprograms.
Table 10-4 Handling result sets, COBOL stored procedures versus subprograms
Stored procedure Subprogram
Note: As you see from Table 10-4, handling result sets with subprograms may be costlier
because it involves the opening of two cursors on the same table for the same purpose,
once in the subprogram and once in the caller. The cost of opening a cursor depends on
the number of qualifying rows. The approach above can be used when the result sets are
intended to handle a small number of rows.
For more information on temporary tables, refer to DB2 Version 9.1 for z/OS Application
Programming and SQL Guide, SC18-9841.
Important: Using created temporary tables instead of declared temporary tables for
handling result sets in subprograms typically provides significant performance
improvements.
This scenario poses a challenge in reusing a COBOL subprogram in local applications (CICS
and batch) and remote applications due to the requirement of different language interface
modules. The COBOL-DB2 subprogram requires the following language interface modules:
DSNELI for TSO
DFSLI000 for IMS
DSNCLI for CICS
DSNALI for CAF
DSNRLI for WLM-based stored procedure address spaces
Let us consider a sample scenario where your business application ABC contains four levels
of nesting:
PROC1 --> PROC2 --> PROC3 --> PROC4
All of the programs (PROC1, PROC2, PROC3, and PROC4) are required in CICS, batch,
remote, and IMS components of the applications. Since the same program has to execute
under different address spaces (CICS, TSO, WLM, and IMS) the program needs to have an
appropriate language interface module. Let us study step-by-step the program preparation
and setting up of the runtime environment with respect to both solutions mentioned above.
138 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Program preparation
These are the steps:
1. Develop the programs and ensure that subprogram calls are made to PROC2, PROC3,
and PROC4 from their higher level programs. For example:
2. Pre-compile and compile the programs. Ensure that the following compile options are
specified:
RENT, NODYNAM
3. Have three link-edit steps each with different interface modules, as shown in
Example 10-17. Ensure that the following link-edit options are specified:
RENT, REUS, AMODE(31), RMODE(ANY)
140 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
// COND=((4,LT,PC),(4,LT,COB),(4,LT,PLKED))
//SYSLIB DD DISP=SHR,DSN=CEE.SCEELKED
// DD DISP=SHR,DSN=<< sdsnload >>
//SYSLIN DD DDNAME=SYSIN
// DD DSN=&&PLKSET,DISP=(OLD,DELETE)
//SYSLMOD DD DSN=<<hlq.LOAD.RLI >> <== Load library for WLM SPAs
// DISP=SHR
//SYSPRINT DD SYSOUT=*
//SYSUT1 DD SPACE=(1024,(50,50)),UNIT=SYSDA
//SYSIN DD *
INCLUDE SYSLIB(DSNRLI)
NAME PROC1(R)
/*
//********************************************************************
Each of the programs that can be potentially executed across environments should undergo
the process above.
Program preparation
These are the steps:
1. Develop the programs and ensure that subprogram calls are made to PROC2, PROC3,
and PROC4 from their higher level programs. For example:
142 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Compile and link-edit the JCL as shown in Example 10-20.
With this approach, it is possible to maintain one single load module for a program and use it
across environments. The program can be invoked as a stored procedure as well as a
subprogram.
Special considerations
Because the same program has to execute in different address spaces, environment-specific
restrictions will apply. For example, there are programming restrictions in CICS, such as no
native COBOL READ and WRITE statements, which do not apply in batch and WLM SPAS.
For further information, refer to CICS Transaction Server for z/OS Version 3.2 CICS
Application Programming Guide, SC34-6818, and to the appropriate reference manual for
your language to determine which syntax to use.
10.4 Summary
This is a summary of the chapter:
Use stored procedures to reduce and avoid network traffic, and to create reusable
components.
Nested stored procedures enhance the benefit of reusability.
144 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
If the elapsed time of COBOL nested stored procedures is not acceptable, use the
COBOL subprogram calls for inner levels of nesting.
If the overhead of scheduling is increased, use the subprogram calls instead of stored
procedure calls in local applications.
We refer to two simple applications developed in C that access sample tables. The first one
32aAretrieves employee information for a specific employee number, while the second
retrieves a list of employees for a specific department.
Note: Complete sample programs in C can be downloaded from the Web as additional
material. Download instructions can be found in Appendix B, “Additional material” on
page 887.
In addition, C allows inter-language calls that enable you to call Assembler functions when
needed if an equivalent runtime library function does not exist (such as for managing the
Extended Console). C allows you to write programs for the DB2 Instrumentation Facility
Interface (IFI) that issue READS, READA and COMMAND functions. Hence, if the function
your stored procedure has to perform requires the use of the above-mentioned functions or
facilities, C is a good choice. Most of the DB2-supplied stored procedures (see Chapter 26,
“DB2-supplied stored procedures” for details) are written in C for that reason.
148 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
A stored procedure can receive parameters from and send back parameters to the calling
application. When the calling application issues an SQL CALL to the stored procedure, DB2
builds a parameter list based on the parameters coded in the SQL call and the information
specified when the stored procedure is initially defined. One of the options on the CREATE
PROCEDURE statement is PARAMETER STYLE, which specifies whether or not NULL
values can be passed as parameters. This is discussed in detail in 9.1, “CREATE or ALTER
PROCEDURE parameters” on page 92. When NULL values are permitted, the stored
procedure and the calling program must take some additional steps. This is discussed in
11.6, “Handling NULL values in parameters” on page 161. In this section we use the
parameter style GENERAL that does not permit NULL values.
Both parameter style SQL and DBINFO are valid for C stored procedures. However,
GENERAL and GENERAL WITH NULLS are most commonly used, hence they will be
discussed in this chapter.
For a C stored procedure retrieving information about a specific employee, the parameter list
is specified when defining the stored procedure. Example 11-1 shows the CREATE
PROCEDURE statement for the C example.
This definition specifies whether the parameter is IN (input to the stored procedure), OUT
(output from the stored procedure) or INOUT (input to and output from the stored procedure).
It also specifies the data type and size of each parameter. This list must be compatible with
the parameter declarations in the calling application, which is shown in Example 11-2.
In general, a subprogram must do the following extra tasks that Language Environment
performs for a main program:
A C program written as main contains a main() function. Parameters are passed to it through
argc and argv. DB2 sets the value of the first element in the argv array, (argv[0]), to the name
of the procedure. The remaining elements of the argv array correspond to the parameters as
defined by the PARAMETER STYLE of the procedure
All the stored procedures in this chapter are written as main programs.
150 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
11.3 Elements of a C stored procedure
Every C stored procedure should contain the following elements:
Includes and compiler defines
Constants defines
Messages defines
Structures, enums and types defines
Global variables declarations
Functions defines
SQLCA include
DB2 host variables declarations
Cursors declarations
Main routine of the stored procedure
Helper functions
As in any C program, you have to make all the required defines and include the required
header files as documented in the z/OS V1R9.0 XL C/C++ Run-Time Library Reference,
SA22-7821-09. If you use the GENERAL or GENERAL WITH NULLS parameter style, you
have to indicate that the format of the argument list passed to the stored procedure on
initialization is in MVS linkage format using the C #pragma runopts(plist(os)). Use the
#pragma CSECT directive, if you will be using SMP/E to service your product, and to aid in
debugging your program. Example 11-4 shows includes and compiler defines.
It is good practice to define all constants that you use in the stored procedure before your
main function, so that they can be easily changed if required without having to change the
actual source code statements. Example 11-5 shows constants defines.
It is good practice to define all the messages your stored procedure uses before your main
function for easier maintenance. Example 11-6 shows the message defines.
typedef struct
{
char empno[7];
char firstnme[13];
char midinit[2];
char lastname[15];
char workdept[4];
char hiredate[11];
decimal(9,2) salary;
} EMPLOYEE;
As in any C program, you should avoid the use of global variables to reduce program
complexity and unwanted side-effects. We use only two global variables for error-handling
and flow control. rc is the return code that indicates if the stored procedure completed
successfully (RC=0) or if there was an error (RC=12). If there was a SQL error, we use
DSNTIAR to obtain a formatted form of the SQLCA and a text message based on the
SQLCODE field of the SQLCA. If there was a problem using a C runtime library function, we
return a formatted error message indicating the location in the program where the error
occurred. Both the return code and the message are returned as OUT parameters to the
calling program. Example 11-8 shows the global variable declarations.
In addition to the main function, our stored procedure contains helper functions for better
modularity and to avoid duplicating code. We discuss each function in this chapter.
Example 11-9 on page 153 shows the definitions for these functions.
152 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Example 11-9 Functions defines
void sql_error(char[]);
char * rtrim(char *);
void query_info(EMPLOYEE *);
Our stored procedure contains SQL statements, and must include a definition of the SQLCA
and a declaration of all host variables used in SQL statements. Example 11-10 shows the
SQLCA include and the DB2 host variable declarations.
We have to trim trailing blanks from parameters passed to the stored procedure.
Unfortunately, there is no runtime library function to do that, so we have to provide one as
shown in Example 11-11.
if (pstring == NULL)
return NULL;
return pstring;
}
Next we look at the main function. It is important to initialize all used variables first, and clear
all OUT parameters. It is a good idea to check the syntax of the IN parameters first, such as
the correct length for a character string or the range for a numerical value, and return an error
if the check fails. Example 11-13 shows how to do this.
/******************************************************************/
/* Initialize variables and OUT parameters. */
/******************************************************************/
rc = RETOK;
memset(errmsg, NULLCHAR, sizeof(errmsg)); /* Clear message buffer */
memset((void *)&employee, NULLCHAR, sizeof(employee));
/******************************************************************/
154 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
/* Check and get IN parameters. */
/******************************************************************/
strcpy(employee.empno, rtrim((char *)argv[1]));
if (strlen(employee.empno) < MIN_EMPNO_LEN || /* Syntax check */
strlen(employee.empno) > MAX_EMPNO_LEN)
{
strcpy(errmsg[0], ERR_EMPNO_LEN);
rc = RETSEV;
}
After we have verified that the employee number has the required length, we can query the
employee information and return the results. Since we have defined the parameter style as
GENERAL, we cannot return NULLs, and must return default values instead. It is important
that the calling application checks the return code in any case, and does not rely on logic that
depends on certain values of the output parameters. Before we return the errmsg lines, we
add an ASCII line feed character after each line, so that the message will display nicely in a
calling application running on Linux, UNIX, or Windows. See Example 11-14.
Example 11-14 Main function database employee data query and returning results
/******************************************************************/
/* Query information. */
/******************************************************************/
if (rc < RETSEV)
query_info(&employee);
/******************************************************************/
/* Return results. */
/******************************************************************/
if (rc < RETSEV)
{
strcpy((char *)argv[2], employee.firstnme);
strcpy((char *)argv[3], employee.midinit);
strcpy((char *)argv[4], employee.lastname);
strcpy((char *)argv[5], employee.workdept);
strcpy((char *)argv[6], employee.hiredate);
*(decimal(9,2) *)argv[7] = employee.salary;
}
else
{
strcpy((char *)argv[2], ""); /* We cannot return NULL */
*(char *)argv[3] = NULLCHAR;
strcpy((char *)argv[4], "");
strcpy((char *)argv[5], "");
strcpy((char *)argv[6], "0001-01-01");
*(decimal(9,2) *)argv[7] = 0.00;
}
if (rc == RETOK)
strcpy(errmsg[0], INF_COMP);
*(int *)argv[8] = rc;
if (errmsg[0][0] != BLANK) /* If error message exists */
{
pcurbyte = argv[9];
for (i = 0; i < DATA_DIM + 1; i++)
{
for (j = 0; (errmsg[i][j] != NULLCHAR && j < MSGROWLEN); j++)
*pcurbyte++ = errmsg[i][j];
if (j > 0)
The function query_info has a single parameter, which is a pointer to an EMPLOYEE variable
where it expects the employee number empno to be filled in. It then selects the missing
information from the database, and sets the other fields of the employee variable. The
EMPLOYEE table allows NULL values for WORKDEPT, HIREDATE and SALARY. If we
receive a NULL value for any of these fields, we return an error since we cannot pass a valid
NULL value back as an output parameter. See Example 11-15.
#ifdef DEBUG
fprintf(OUT,"query_info: select from EMP \
SQLCODE=%ld\n", SQLCODE);
#endif
if (SQLCODE != 0)
sql_error(ERR_QUERY_INFO);
else
{
strcpy(pemployee->firstnme, h_firstnme);
strcpy(pemployee->midinit, h_midinit);
strcpy(pemployee->lastname, h_lastname);
if (i_workdept < 0)
{
strcpy(errmsg[0], ERR_INVALID_WORKDEPT);
rc = RETSEV;
return;
}
else
strcpy(pemployee->workdept, h_workdept);
if (i_hiredate < 0)
{
strcpy(errmsg[0], ERR_INVALID_HIREDATE);
rc = RETSEV;
return;
}
else
strcpy(pemployee->hiredate, h_hiredate);
if (i_salary < 0)
{
strcpy(errmsg[0], ERR_INVALID_SALARY);
rc = RETSEV;
156 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
return;
}
else
pemployee->salary = h_salary;
}
}
Although CEESTART is the default main entry point for C applications, it is good practice to
explicitly specify it in your link-edit SYSIN. You also must link-edit it with the RRSAF language
interface module DSNRLI. In our example we also include the DSNTIAR Assembler routine
because we use it in our sql_error function.
If the stored procedure contains SQL statements as in our example, you will get a DBRM that
you must bind into a package. It does not require a plan since it runs under the thread for the
calling application. The following special processing is needed for binding a stored
procedure.
Bind the DBRM to DB2 using the command BIND PACKAGE. If you use the ENABLE option
of the BIND PACKAGE command to control access to the stored procedure package, you
must enable the system connection type of the calling application.
The package for the stored procedure need not be bound with the plan for the program that
calls it since it runs under the thread for the calling application.
The owner of the package that contains the SQL CALL must have the EXECUTE authority on
the procedure. See Chapter 7, “Security and authorization (Glenn)” on page 57 for details.
The collection ID associated with the stored procedure package must be based on the
following rules:
If you specify NO PACKAGE PATH and NO COLLID when creating the stored procedure,
the package must use the same collection ID as the calling program.
If you specify PACKAGE PATH collection_id1, collection_id2,... when creating the stored
procedure, the stored procedure must use one of these collections.
If you specify NO PACKAGE PATH and COLLID collection_id when creating the stored
procedure, the stored procedure must use this collection_id.
Also, see 9.1.8, “Package path” on page 102 for details on the definition of the collection ID
and 9.1.10, “Collection ID the stored procedure runs in” on page 103.
Choosing the right isolation level is very important. Many clients may concurrently call a
stored procedure, and an incorrectly chosen isolation level can cause serious contention. If
158 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
you only have read-only operations in your stored procedure, UNCOMITTED READ (UR) may
be a good choice. UR allows your application to read any row that another process has
changed, even if the process has not committed the row.
/********************************************************************/
/* Main routine. */
/********************************************************************/
main(int argc, char *argv[])
{
int i;
char line[MAX_LINE_LEN + 2]; /* SYSIN line buffer */
char * pline;
char * ptoken;
/******************************************************************/
/* Initialize variables. */
/******************************************************************/
rc = RETOK;
memset(errmsg, NULLCHAR, sizeof(errmsg)); /* Clear message buffer */
/******************************************************************/
/* Check and get parameters from SYSIN. */
/******************************************************************/
if ((pline = gets(line)) == NULL)
{
strcpy(errmsg[0], ERR_READ_STDIN);
rc = RETSEV;
}
/******************************************************************/
/* Call EMPDTL1P. */
/******************************************************************/
if (rc < RETSEV)
{
EXEC SQL CALL EMPDTL1P(:h_empno, :h_firstnme, :h_midinit,
:h_lastname, :h_workdept,
:h_hiredate, :h_salary,
:h_retcode, :h_message);
if (SQLCODE != 0)
sql_error(ERR_CALL_EMPDTL1P);
}
/******************************************************************/
/* Print results. */
/******************************************************************/
if (rc < RETSEV)
{
if (h_retcode > RETOK) /* Check for internal SP err.*/
{
rc = h_retcode;
memcpy(errmsg, h_message, sizeof(h_message));
}
else
{
printf("**** EMPLOYEE REPORT FOR EMPNO %s ****\n", h_empno);
printf(" FIRSTNAME: %s\n", h_firstnme);
printf(" MIDDLE INITIAL: %s\n", h_midinit);
printf(" LASTNAME: %s\n", h_lastname);
printf(" DEPARTMENT: %s\n", h_workdept);
printf(" HIRE DATE: %s\n", h_hiredate);
printf(" SALARY: $ %D(9,2)\n", h_salary);
}
}
return rc;
}
After we have verified that the SQLCODE of the SQL CALL statement is 0, we check the OUT
return code parameter to determine whether the OUT parameters are valid. We will use them
only if the stored procedure completed successfully with RC=0.
160 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
11.6 Handling NULL values in parameters
When the number and size of parameters passed is large, or when it makes sense from a
semantic point of view, you should consider allowing NULL values. In our example it makes
semantic sense because some of the database columns that correspond to the OUT
parameters allow NULL values. Example 11-18 lists the new structures. Notice the
differences from Example 11-7 on page 152 because of the isxxxNull definitions.
Example 11-19 contains the main function of our sample application with NULL values
allowed. When the parameter style GENERAL WITH NULLS is specified, an array of short
indicator variables of the length of the number of parameters is passed as an additional
parameter. For easier use, we copy this array to a local array before we check the IN
parameters. The check for unexpected NULL values should be included as part of our
parameter syntax check. A NULL value as an input parameter may not mean an error, but it
can mean that a default value should be used instead.
Example 11-19 Main function initialization and handling IN parameters with NULLS
main(int argc, char *argv[])
{
EMPLOYEE employee;
char * pcurbyte;
short int locind[9]; /* Indicator variables */
short int *pind; /* Pointer to indicator vars */
int i, j;
/******************************************************************/
/* Initialize local variables and OUT parameters. */
/******************************************************************/
rc = RETOK;
memset(errmsg, NULLCHAR, sizeof(errmsg)); /* Clear message buffer */
memset((void *)&employee, NULLCHAR, sizeof(employee));
pind = (short int *)argv[10]; /* Locate and recast arg */
for (i = 0; i < 9; i++) /* Copy null-ind array */
{
locind[i] = *pind;
pind++;
}
/******************************************************************/
/* Check and get IN parameters. */
When we return OUT parameters, we need to make sure that we also set the indicator
variables accordingly, as shown in Example 11-20.
Example 11-20 Main function database employee data query and returning results
/******************************************************************/
/* Query information. */
/******************************************************************/
if (rc < RETSEV)
query_info(&employee);
/******************************************************************/
/* Return results. */
/******************************************************************/
for (i = 0; i < 9; i++) /* Set all output params NULL */
locind[i] = -1;
162 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
if (rc == RETOK)
strcpy(errmsg[0], INF_COMP);
*(int *)argv[8] = rc;
locind[7] = 0;
#ifdef DEBUG
fprintf(OUT,"query_info: select from EMP \
SQLCODE=%ld\n", SQLCODE);
#endif
if (SQLCODE != 0)
sql_error(ERR_QUERY_INFO);
else
{
strcpy(pemployee->firstnme, h_firstnme);
strcpy(pemployee->midinit, h_midinit);
strcpy(pemployee->lastname, h_lastname);
if (i_workdept < 0)
pemployee->isWorkdeptNull = TRUE;
else
The calling program needs to include indicator variables in the CALL statement and
defensively check whether any output parameters contain an unexpected NULL value as
shown in Example 11-22, which also shows the modified DECLARE section, which is
different from Example 11-17 on page 159.
Example 11-22 Calling a stored procedure with PARAMETER STYLE GENERAL WITH NULL
/********************************************************************/
/* Declare DB2 host variables. */
/********************************************************************/
EXEC SQL BEGIN DECLARE SECTION;
char h_empno[7];
short int i_empno;
char h_firstnme[13];
short int i_firstnme;
char h_midinit[2];
short int i_midinit;
char h_lastname[15];
short int i_lastname;
char h_workdept[4];
short int i_workdept;
char h_hiredate[11];
short int i_hiredate;
decimal(9,2) h_salary;
short int i_salary;
long int h_retcode;
short int i_retcode;
char h_message[1332];
short int i_message;
EXEC SQL END DECLARE SECTION;
/********************************************************************/
164 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
/******************************************************************/
/* Print results. */
/******************************************************************/
if (rc < RETSEV)
{
if (i_retcode < 0) /* Check for internal SP err.*/
{
rc = RETSEV;
strcpy(errmsg[0], ERR_NULL_RETCODE);
}
else if (h_retcode > RETOK)
{
rc = h_retcode;
if (i_message >= 0)
memcpy(errmsg, h_message, sizeof(h_message));
}
else
{
printf("**** EMPLOYEE REPORT FOR EMPNO %s ****\n", h_empno);
printf(" FIRSTNAME: %s\n",
(i_firstnme < 0) ? "-" : h_firstnme);
printf(" MIDDLE INITIAL: %s\n",
(i_midinit < 0) ? "-" : h_midinit);
printf(" LASTNAME: %s\n",
(i_lastname < 0) ? "-" : h_lastname);
printf(" DEPARTMENT: %s\n",
(i_workdept < 0) ? "-" : h_workdept);
printf(" HIRE DATE: %s\n",
(i_hiredate < 0) ? "-" : h_hiredate);
if (i_salary < 0)
printf(" SALARY: $ %D(9,2)\n", 0.00);
else
printf(" SALARY: $ %D(9,2)\n", h_salary);
}
}
return rc;
}
In summary, you must do the following to handle parameters that allow NULL values:
Make sure the stored procedure definition allows NULL parameters.
In the calling program, declare indicator variables and set their value to 0 if the parameter
is not NULL and -1 if parameter is NULL.
Include the indicator variables in the CALL statement.
In the stored procedure, declare the indicator variables.
In the stored procedure, check for the value of the null indicator to determine whether the
parameter is null and take appropriate action.
Handling the first case is easier to develop, but the second case is more general, and requires
minimal modifications if the calling program or stored procedure happens to change. Our
sample stored procedure always returns only one result set, and we know the contents.
166 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
11.8 Handling result sets using Global Temporary Tables
If you need to pass results back that are not the result of an SQL query, such as the contents
of a data set or messages from a command execution, and you do not want to store that data
permanently, you can return the result set in a created temporary table. See “Special
considerations” on page 144 why we recommend usage of created temporary tables (CTT)
over declared temporary tables (DTT).
An instance of a created temporary table exists for the lifetime of a unit of work, and only the
calling application and the stored procedure can access the instance. An instance is created
when a temporary table is first referenced in an OPEN, SELECT, INSERT, or DELETE SQL
statement. This eliminates the need for logging and locking, and makes SQL statements that
use temporary tables very fast.
In order to use a created temporary table to pass back a result set, you have to define it first.
Example 11-23 shows how to define a created temporary table to pass back a list of
employees for a specific department.
Example 11-24 shows the function query_dept that queries all the employees from a
department and inserts the rows into a created temporary table.
while (TRUE)
return h_deptname;
}
The result cursor was defined as shown in Example 11-25. The above example can be
greatly simplified by just opening a cursor on the department table and not even bothering
with a global temporary table. However, in most cases you will process data between fetching
the data from the cursor, and inserting rows into the output table, which requires your
application to be structured as in the example.
168 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
After calling the function query_dept to insert rows into the global temporary table, the result
set cursor needs to be opened as shown in Example 11-26.
/******************************************************************/
/* Query information. */
/******************************************************************/
if (rc < RETSEV)
pdeptname = query_dept(pdeptno);
/******************************************************************/
/* Return results. */
/******************************************************************/
for (i = 0; i < 4; i++) /* Set all output params NULL */
locind[i] = -1;
Stored procedures that use the __login function to switch users require daemon authority.
Also, if the BPX.DAEMON facility class is active, the stored procedure loaded into the WLM
address space must have been defined to RACF program control. The new user ID also has
to have an OMVS segment defined. When you specify __LOGIN_CREATE, a process level
security environment is established for the calling process and changed to the user ID and
password provided.
#define _OPEN_SYS
#include <unistd.h>
#define __LOGIN_CREATE 1
#define __LOGIN_USERID 1
change_user()
{
int userIDlen = strlen(user_id);
int pswdlen = strlen(user_pswd);
rc =__login(__LOGIN_CREATE
,__LOGIN_USERID
,userIDlen /* identity_length */
,user_id /* identity */
,pswdlen /* pass_length */
,user_pswd /* pass */
,0 /* Not used presently */
,NULL /* Not used presently */
,0 /* Not used presently */
);
if ( rc != 0)
{
strcpy(errmsg[0], ERR_LOGIN);
sprintf(errmsg[1], " %s", strerror(errno));
rc = RETSEV;
}
}
You need to provide a secure method of transmitting a user ID and password to the stored
procedure. DB2 UDB for z/OS Version 8 supports clients using data stream encryption, which
is one way to securely transmit a user ID and password. You can also insert a user ID and
password into a control table on the server where your stored procedure is running, and only
give certain users SELECT authority on that table. This method is probably a more flexible
design choice that ensures that users can interact with only the external resource through the
stored procedure.
170 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
11.10 Summary
In this chapter, we have discussed when to use C for writing stored procedures. By providing
sample code, we have highlighted the following important points:
The elements that a well written and maintainable C stored procedure should contain
How to handle parameters that allow NULL values
How to handle result sets in the stored procedure and in the calling program
How to use created temporary tables to return result sets
The sample code is available as described in B.1.3, “Sample C programs” on page 889.
The performance of REXX programs accessing DB2 tables is improved in V8 in the case of
programs issuing large numbers of SQL statements.
If you are not familiar with the REXX/DB2 interface, refer to “Coding SQL statements in a
REXX application” in Chapter 9 of DB2 Version 9.1 for z/OS Application Programming and
SQL Guide, SC18-9841 for details.
Note: Complete sample programs can be downloaded from the ITSO Web site as
additional material. Download instructions can be found in Appendix B, “Additional
material” on page 887.
Before downloading, we strongly suggest that you first read 3.3, “Sample application
components” on page 24 to decide what components are applicable to your environment.
174 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
12.1 Verify the REXX environment
Before developing the stored procedure, it is important to have a clear understanding of the
various steps that must be completed for a stored procedure to execute successfully. These
steps are covered in detail in the rest of the book; we will simply list them here for
convenience. They are:
1. The WLM environment must be set up. See Chapter 4, “Setting up and managing
Workload Manager” on page 39 for details. This environment must allow only one
concurrent execution of tasks by specifying NUMTCB=1. If you attempt to run multiple
REXX stored procedures in a WLM environment, you will receive a message:
+DSNX993I DSNX9REX CALL TO REXX PROCEDURE WITH EXTERNAL NAME ... FAILED,FUNCTION =
IRXEXEC RC = 00000064 RSN = 00000000
In addition, the calling application receives an error code 00E79106 and an SQLCODE
-471.
2. In addition, the JCL must contain a DD statement for ddname SYSEXEC:
SYSEXEC DD DISP=SHR,DSN=SG247083.DEVL.CLIST
3. The LE environment must be set up. See Chapter 5, “Language Environment setup” on
page 47 for details.
4. The stored procedure must be defined to DB2. Note in particular that if the stored
procedure is designed to return result sets, the maximum number of result sets that can
be returned is specified in the definition. See Chapter 9, “Defining stored procedures” on
page 91 for details.
5. Develop the stored procedure. Note that for REXX, you do not prepare the stored
procedure and bind a package even when it has SQL. See 12.3, “Preparing and binding a
REXX stored procedure” on page 177 for details.
6. Grant the necessary privileges to the authorization ID of the user that executes the stored
procedure. See Chapter 7, “Security and authorization” on page 65 for details.
7. Develop the calling application if needed or use IBM Data Studio to call and test your
stored procedure.
Also, see Chapter 16, “Debugging” on page 313 for details on testing and debugging.
A stored procedure can receive and send back parameters to the calling application. When
the calling application issues an SQL CALL to the stored procedure, DB2 builds a parameter
list based on the parameters passed in the SQL call, and the information specified when the
stored procedure is initially defined. For a REXX stored procedure retrieving information
about a specific employee, the parameter list specified when defining the stored procedure is
shown in bold in Example 12-1.
Restriction: Note that a REXX stored procedure can have at most one parameter defined
as OUT or INOUT and the definition below would be invalid:
CREATE PROCEDURE DEVL7083.EMPDTLSR
(
IN PEMPNO CHAR(6)
,OUT PFIRSTNME VARCHAR(12)
,OUT PMIDINIT CHAR(1)
,OUT PLASTNAME VARCHAR(15)
,OUT PWORKDEPT CHAR(3)
,OUT PHIREDATE DATE
,OUT PSALARY DEC(9,2)
,OUT PSQLCODE INTEGER
,OUT PSQLSTATE CHAR(5)
,OUT PSQLERRMC VARCHAR(250)
)
This definition specifies whether the parameter is IN (input to the stored procedure), OUT
(output from the stored procedure), or INOUT (input to and output from the stored procedure).
It also specifies the data type and size of each parameter. This list must be compatible with
the parameter list in the calling application.
Note that the single OUT/INOUT parameter must be the last one in the list.
REXX stored procedures have no explicit LINKAGE section and the passing of arguments is
accomplished using the normal REXX conventions. For example, an input parameter is
received as:
PARSE UPPER ARG PEMPNO
Note also that PARAMETER STYLE SQL is not allowed, and hence neither is DBINFO in
REXX stored procedures.
176 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
12.3 Preparing and binding a REXX stored procedure
No special processing is needed for preparing a REXX stored procedure except to note the
following requirements:
You cannot execute the ADDRESS DSNREXX CONNECT and ADDRESS DSNREXX
DISCONNECT commands. This is because DB2 establishes the connection for you when
you execute an SQL statement.
Just like any other REXX EXEC procedures, no precompile or compile is needed.
REXX stored procedures do not require a package or plan to execute. REXX stored
procedures are not precompiled nor does any package have to be bound. They are executed
using one of four packages that are bound during the installation of DB2 REXX Language
Support. The package that DB2 uses when the stored procedure executes depends on the
isolation level at which the stored procedure runs. See Table 12-1.
The isolation level depends on the PACKAGE PATH or COLLID value specified in the CREATE
PROCEDURE statement. If NO COLLID is specified then an appropriate DSNREXX package
should be included in the collection ID of the caller or you can set the special registers
CURRENT PACKAGE PATH or CURRENT PACKAGESET to the collection(s) you want to use.
Notice that when the REXX stored procedure parameters include a nullable field, an indicator
variable must be passed. In this case notice that there is no comma between the host variable
and the variable indicator.
The first alternative is simpler to develop, but the second alternative is more general and
requires minimal modifications if the calling program or stored procedure changes.
ADDRESS DSNREXX
"EXECSQL ASSOCIATE LOCATOR (:RESULT) WITH PROCEDURE :PROC"
If SQLCODE <> 0 Then Call SQLCA
178 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
say sqlca
ADDRESS DSNREXX
"EXECSQL ALLOCATE C101 CURSOR FOR RESULT SET :RESULT"
If SQLCODE <> 0 Then Call SQLCA
Do Until(SQLCODE <> 0)
ADDRESS DSNREXX
"EXECSQL FETCH C101 INTO :ZONE"
say zone
End
If SQLCODE <> 0 Then Call SQLCA
ADDRESS DSNREXX
"EXECSQL CLOSE C101”
If SQLCODE <> 0 Then Call SQLCA
RETURN
SQLCA:
TRACE O
SAY 'SQLCODE ='SQLCODE
SAY 'SQLERRM ='SQLERRMC
SAY 'SQLERRP ='SQLERRP
SAY 'SQLERRD ='SQLERRD.1',',
|| SQLERRD.2',',
|| SQLERRD.3',',
|| SQLERRD.4',',
|| SQLERRD.5',',
|| SQLERRD.6
In this chapter we describe how to set up the environment for Java stored procedures, and the
steps to develop and debug them. We assume that you have a basic understanding of the
Java language.
We will then look at the steps for creating a new Java stored procedure:
Preparing Java stored procedures
DDL for defining a Java stored procedure
Once created, we can execute the stored procedure. The next sections will assist you in
debugging the stored procedure and show a completed Java stored procedure as well.
Debugging JDBC and SQLJ
Java sample JDBC stored procedure
Java sample SQLJ stored procedure
Finally, we will give steps for migrating your Java stored procedures from the Legacy Driver to
the IBM Universal driver in:
Migrating stored procedures to use the new JCC driver
Details on how Java and DB2 for z/OS can work together and form a strong combination that
can run your mission critical applications are reported in DB2 for z/OS and OS/390: Ready for
Java, SG24-6435. That book starts from the basics and covers the new IBM Universal Driver
for SQLJ and JDBC, IBM’s new JDBC driver implementation, supporting both Type 2 and
Type 4 driver connectivity to the members of the DB2 family, including DB2 for z/OS, and DB2
for Linux, UNIX and Windows. Another source of reference information is DB2 Version 9.1 for
z/OS Application Programming Guide and Reference for Java, SC18-9842-01. In this book
we concentrate on V9 Java stored procedures.
DB2 V9 supports the development of interpreted Java stored procedures. The IBM Data
Studio application development tool only supports creating interpreted Java stored
procedures on DB2 V8 and DB2 V9. You can develop interpreted Java stored procedures
using both JDBC or SQLJ methods. We recommend getting started by developing stored
procedures using JDBC methods. The setup and application preparation process for an SQLJ
stored procedure includes more steps than those for JDBC stored procedures. Once you
become familiar with JDBC stored procedures you can expand to using SQLJ procedures.
SQLJ stored procedures provide better performance since they use static SQL, unlike JDBC
stored procedures, which make dynamic SQL calls.
We developed several JDBC and SQLJ Java stored procedures. Refer to Chapter 3, “Our
case study” on page 23 for a comprehensive list of JDBC and SQLJ stored procedures.
182 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
For more information about resettable JVMs and for a full list of actions that are prevented,
see the “Unresettable actions” topic of Persistent Reusable Java Virtual Machine User’s
Guide, SC34-6201.
Note: This feature is also available for DB2 V8 with APAR PK09213. See 13.4,
“Persistent Reusable JVM” on page 193 for more information.
For information on installing the Java SDK, refer to the following URL:
http://www-1.ibm.com/servers/eserver/zseries/software/java/
Alternatively, you can check the JDK version from the workstation client by creating and using
the following UDF in SPUFI on DB2 for z/OS.
Then, issuing the following command in a DB2 9 command line window shows the result; see
Example 13-1:
SELECT SYSADM.JVMVERS('java.vm.name') FROM SYSIBM.SYSDUMMY1;
SELECT SYSADM.JVMVERS('java.version') FROM SYSIBM.SYSDUMMY1;
Example 13-1 Verifying the JVM version and name from your workstation
C:\>DB2 CONNECT TO DB9A USER PAOLOR5 USING PUP4SALE
184 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
C:\>db2 select sysadm.jvmvers('java.vm.name') from sysibm.sysdummy1
--------------------------------------------------------------------
IBM J9 VM
1 record(s) selected.
C:\>db2 select sysadm.jvmvers('java.version') from sysibm.sysdummy1
--------------------------------------------------------------------
1.5.0
1 record(s) selected.
13.3.3 Checking the DB2 JDBC and SQLJ libraries for USS
When you install DB2, include the steps for allocating the HFS directory structure and using
SMP/E to load the JDBC and SQLJ libraries. See DB2 9 for z/OS Program Directory,
GI10-8737-00 for information on allocating and loading DB2 data sets. To check for the DB2
libraries, you need to change your working directory to the DB2 home directory,
/usr/lpp/db2/db2910, and issue the list directory command. In our case the DB2 home
directory was /usr/lpp/db2/db9a. However, the JDBC and SQLJ libraries are installed in
db2910_jdbc:
=> cd /usr/lpp/db2/db9a/db2910_jdbc
=> ls
Example 13-2 UDFs to determine the driver name and version of the IBM Universal driver
CREATE FUNCTION SYSADM.JAVDRVV ()
RETURNS VARCHAR(100)
FENCED NO SQL
LANGUAGE JAVA
SPECIFIC JAVDRVV
EXTERNAL NAME 'com.ibm.db2.jcc.DB2Version.getVersion'
WLM ENVIRONMENT DB9AWLMJ
NO EXTERNAL ACTION
NO FINAL CALL
PROGRAM TYPE SUB
PARAMETER STYLE JAVA;
Then issue these queries to determine the JCC Driver name and version:
SELECT SYSADM.JAVDRVN() FROM SYSIBM.SYSDUMMY1;
SELECT SYSADM.JAVDRVV() FROM SYSIBM.SYSDUMMY1;
1 record(s) selected.
1 record(s) selected.
13.3.5 DESCSTAT
On DB2 for z/OS, set subsystem parameter DESCSTAT to YES. DESCSTAT corresponds to
installation field DESCRIBE FOR STATIC on panel DSNTIPF. See Part 2 of the DB2
Installation Guide for information on setting DESCSTAT. This step is necessary for SQLJ
support.
186 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
//IEFPROC EXEC PGM=DSNX9WLM,REGION=&RGN,TIME=NOLIMIT,
// PARM='&DB2SSN,&NUMTCB,&APPLENV'
//STEPLIB DD DISP=SHR,DSN=DB9AU.RUNLIB.LOAD
// DD DISP=SHR,DSN=CEE.SCEERUN
// DD DISP=SHR,DSN=DB9A9.SDSNEXIT
// DD DISP=SHR,DSN=DB9A9.SDSNLOAD
// DD DISP=SHR,DSN=DB9A9.SDSNLOD2
//JAVAENV DD DISP=SHR,DSN=DB9AU.JSPENV
//JSPDEBUG DD SYSOUT=*
//CEEDUMP DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//JAVAOUT DD PATH='/SC63/sg247083/JAVAOUT.TXT',
// PATHOPTS=(ORDWR,OCREAT,OAPPEND),
// PATHMODE=(SIRUSR,SIWUSR,SIRGRP,SIWGRP,SIROTH,SIWOTH)
//JAVAERR DD PATH='/SC63/sg247083/JAVAERR.TXT',
// PATHOPTS=(ORDWR,OCREAT,OAPPEND),
// PATHMODE=(SIRUSR,SIWUSR,SIRGRP,SIWGRP,SIROTH,SIWOTH)
Be aware of the following points while defining the WLM procedure for Java:
For every NUMTCB, WLM would create a JVM in the WLM address space. In resettable
mode, with JDK 1.4.2, we limited this to a low number, an optimum of 6 or 7 for running
Java stored procedures in production. In non-resettable mode with JDK 1.5, we can now
set the NUMTCB to a higher number. The recommended number is between 20 and 40.
The WLM address space for running Java stored procedures should be solely dedicated
for Java stored procedures. You should not allow stored procedures of other languages
such as COBOL, SQL etc., to use the Java application environment and address space.
You want stored procedures with similar performance and resource usage characteristics
running in the same WLM environment.
If the LE runtime SCEERUN library is not included in your system LINKLIST, you need to
uncomment the STEPLIB DD for SCEERUN. In this case you might consider putting it in
Library Lookaside (LLA) to reduce I/O.
Apart from including SDSNEXIT, SDSNLOAD libraries in the STEPLIB, do not forget to
include the SDSNLOD2 library (it contains the DLLs for the Java drivers). Also, ensure that
you have one non APF authorized data set in your STEPLIB. In our case we included
CBC.SCBCOMP lib; it can be any library of your choice.
The JAVAENV DD statement specifies a data set that contains environment variables that
define system properties for the execution environment. The presence of this DD
statement indicates to DB2 that the WLM environment is for Java stored procedures. For
an interpreted Java routine, this data set must contain the environment variable
JAVA_HOME. This environment variable indicates to DB2 that the WLM environment is for
interpreted Java routines. A detailed discussion of the contents of JAVAENV is in 13.3.7,
“Setting up the JAVAENV data set for Java stored procedure execution” on page 188.
The JAVAOUT and JAVAERR DD statements are optional, and are helpful for debugging
Java stored procedures. Specify a data set in your Unix System Services (USS) to capture
the output from your SYSOUT and SYSERR. If the file does not exist, USS will create it.
Otherwise, the new output will be appended to the existing file. The PATHOPTS and
PATHMODE specify the permissions for this data set. More information about these
keywords can be found in z/OS V1R7.0 MVS JCL Reference, SA22-7597-09.
JSPDEBUG DD statement specifies a data set into which DB2 puts information that you
can use to debug your stored procedures. The information that DB2 collects can be very
helpful in debugging setup problems, and also contains key information that you need to
Important: You should comment out the JSPDEBUG DD statement during production
in order not to degrade the performance of your stored procedure. Information
regarding each invocation of a Java stored procedure is written to the JSPDEBUG data
set by DB2.
For debugging purposes, or in general for gathering information from the stack trace in the
event of unhandled Java exceptions, specify data sets for JAVAOUT and the JAVAERR DD
cards. These data sets are explained in 13.9, “Debugging JDBC and SQLJ” on page 209.
They are only required if you plan to debug your Java stored procedures using the
System.out.println method.
13.3.7 Setting up the JAVAENV data set for Java stored procedure execution
The WLM procedure where Java stored procedures execute requires a JAVAENV DD. This
data set defines the Java environment variables that will be used.
This JAVAENV data set should have the characteristics shown in Table 13-1.
RECFM VB
ORGANIZATION PS
The contents of the JAVAENV data set that was used in our lab is shown in Example 13-6.
188 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Example 13-6 Contents of JAVAENV - DB9AU.JAVAENV file
ENVAR("JAVA_HOME=/usr/lpp/java/J5.0",
"JCC_HOME=/usr/lpp/db2/db9a/db2910_jdbc",
"CLASSPATH=/usr/lpp/db2/db9a/db2910_jdbc/userproc",
"DB2_BASE=/usr/lpp/db2/db9a/db2910_base",
"RESET_FREQ=-1"),
XPLINK(ON)
All the environment variables need to be included in this file. Ensure that the total length of all
the entries does not exceed 245 bytes (exclude the blanks)2. In case your entries exceed the
245 byte limit, you need to take a different approach, as shown in Example 13-7. Here we
show an alternate form of JAVAENV definitions.
The _CEE_ENVFILE variable points to an HFS file that contains most of the environment
variables, because this file has no limitation of size. The JAVA_HOME variable must be
defined in the JAVAENV data set, and not in the HFS file corresponding to _CEE_ENVFILE.
The contents of _CEE_ENVFILE file are shown in Example 13-8. This is a standard UNIX file
where each line must start in column 1 and the continuation character is a \.
You can use _CEE_ENVFILE for overcoming the 245 limit when specifying other
environmental variables that tend to be long or transitory in nature, such as
JITC_COMPILING and JITC_COMPILEOPT.
JCC_HOMEa This environment variable is set to the location of the JCC driver.
For example: JCC_HOME=/usr/lpp/db2/db9a/db2910_jdbc
CLASSPATH The directory where you place your compiled stored procedures. A
detailed discussion of CLASSPATH can be found in 13.7, “Making
the stored procedure class files available to DB2” on page 201
JVMPROPS You can optionally specify here, the name of a USS file which
contains JVM startup options. See “JVMPROPS” on page 190.
Important: When using JVM 1.4.2, the default native heap size is insufficient for debugging Java
stored procedures with the IBM Data Studio. The JVM 1.5 default native heap size is sufficient.
JDK1.4.2 heap size therefore has to be increased to (8M,2M,ANYWHERE,KEEP). Do not put this
environment variable in the _CEE_ENVFILE. For example, in your JAVAENV file, you can code:
MSGFILE(JSPDEBUG,,,,ENQ),
XPLINK(ON),
HEAP(8M,2M,ANYWHERE,KEEP),
ENVAR("_CEE_ENVFILE=/u/oeusr05/CEEOPTIONS.txt")
DB2 for z/OS V9 flags the presence of the environment variable DB2_HOME as an error. DB2
for z/OS V8 ignores this variable.
JVMPROPS
JVMPROPS is the environment variable that specifies the name of a z/OS UNIX System
Services file that contains startup options for the JVM in which the stored procedure runs.
JVMPROPS is the Java stored procedures environment mechanism to set the -Xoptionsfile
option.
For information about JVM startup options, see “IBM 31-bit and 64-bit SDKs for z/OS, Java 2
Technology Edition, Version 5 SDK and Runtime Environment User Guide”, available at:
http://www.ibm.com/servers/eserver/zseries/software/java/pdf/sdkguide.zos.pdf
190 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Note: To enable class sharing in JDK 1.5, code the -Xshareclasses option in this file.
DB2Binder utility
You can run the DB2Binder from the USS shell or from a workstation DB2 command line
prompt connected to the target server.
Before running the utility, ensure that you have the file db2jcc.jar defined in your CLASSPATH.
For example, in our environment, we have /usr/lpp/db2/db9a/ db2910_jdbc/classes/db2jcc.jar
defined to the CLASSPATH.
You can use the backslash (\ ) continuation character at the end of the first line in the above
command. When you press Enter, the command line is cleared so that you can continue
typing. The line you typed prior to the backslash is displayed in the output area, and the shell
prompt changes to > beneath it to indicate that you are continuing a command.
If you have a DB2 client installed, you can code the DB2Binder command in a .bat file and call
it from the workstation through a DB2 command window as shown in Example 13-10.
C:\$WorkDocuments\ZOS_Related>set CLASSPATH=c:\sqllib\java\db2jcc.jar;c:\sqllib\
java\db2jcc_license_cisuz.jar;c:\sqllib\java\db2jcc_license_cu.jar;
Collection name
The binder binds the packages into the collection specified. If you do not specify the collection
name, the binder puts the packages in the NULLID collection. When you define the stored
procedure (DDL), the collection name that you specify should have the Universal Driver JDBC
packages defined in it.
These tables ensure that character conversion does not occur when Unicode data is stored in
DBCLOB or CLOB columns.
The installation job DSNTIJSG creates these stored procedures and tables as part of a new
installation or migration, or by job DSNTIJMS, for installations that were installed or migrated
192 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
before the procedures were introduced into Version 8. These jobs must be customized before
execution, as described in the job prologs.
Prior to running these jobs, you should set the subsystem parameter named DESCSTAT to
YES. DESCSTAT corresponds to installation field DESCRIBE FOR STATIC on panel
DSNTIPF.
See Chapter 7, “Installing the IBM DB2 Driver for JDBC and SQLJ” in DB2 Version 9.1 for
z/OS Installation Guide, GC18-9846-01, for more information.
Persistent Reusable Java Virtual Machines speed up the processing of Java applications in
transaction processing environments on z/OS systems. Transaction processing in a z/OS
environment is characterized by short, repetitive transactions that run in subsystems such as
CICS Transaction Servers or DB2 Database Management Systems.
To ensure isolation between transactions, each JVM processes only one transaction at a
time, and each JVM is created in its own Language Environment (LE) enclave to ensure
isolation between JVMs running in parallel. The set of JVMs within an address space is called
a JVMSet.
The model of one transaction per JVM implies the recycling of the JVM; that is, create a JVM,
run the transaction, and destroy the JVM. However, the startup overhead for a traditional JVM
is very high; high-volume transaction processing requires a model that allows serial reuse of a
JVM by many transactions, and that destroys and creates a new JVM only when absolutely
necessary.
However, executing Java routines in a JVM that is started in resettable mode has its
limitations, namely:
The Java stored procedures were limited in what they can do so as not to corrupt the JVM
for subsequent users.
The number of stored procedures you can run in an address space is limited.
Once every 10 JVM resets, a request is made to the JVM to perform Garbage Collection.
This impacts performance.
The Java environment variable, RESET_FREQ, determines whether the JVM is started in a
resettable or non-resettable mode. When RESET_FREQ specifies a value less than zero, that
will indicate that the JVM is to be started in its non-resettable mode, and never reset.
The advice against using static variables is given for the following reasons:
Supporting the use of static variables is explicitly not required by the applicable ANSI/ISO
standard.
It is difficult to guarantee that a sequence of CALLs will be processed by the same JVM.
For example, suppose that two stored procedures, INITIALIZE and PROCESS, use the
same static variable, sv1. INITIALIZE sets the value of sv1, and PROCESS depends on
the value of sv1.
– CALL INITIALIZE. This runs in one JVM and sets the static variable, sv1, to a known
state or value.
– CALL PROCESS goes to a different JVM and finds the value of the static variable to be
un-initialized.
While for Java applications, the static variables are initialized or reset whenever the class
is loaded, for Java stored procedures and UDFs the programmer can't control which JVM
a subsequent stored procedure or UDF will run in. So invoking a stored procedure twice
does not guarantee that static variables will have the value set from the previous
invocation.
194 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
For more information on static variables and other Java programming tips, refer to Chapter 5
of DB2 Version 9.1 for z/OS, Application Programming Guide and Reference for Java,
SC18-9842-01.
In this section we limit our discussion to preparing Java stored procedures without the IBM
Data Studio tooling. We also limit our discussion to using UNIX System Services (USS). You
need USS because that is where the Java SDK and JDBC drivers reside.
The names of the directory path could vary across installations. Refer to Table 13-3 for a
general description of various environment variables. Be aware that the contents of the profile
data set are used while preparing a stored procedure or running a Java DB2 application in
USS. The profile data set is not used for setting up the stored procedure runtime environment
and properties. The JAVAENV data set controls the runtime environment and behavior of
Java stored procedures.
You can also combine SQLJ and JDBC in the same stored procedure. Chapter 4 of DB2
Version 9.1 for z/OS, Application Programming Guide and Reference for Java,
SC18-9842-01, discusses how you do this.
196 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
13.6.3 Preparing stored procedures with only JDBC Methods
If your stored procedure uses only JDBC Methods then all you need to do is to compile the
stored procedure using the javac command. The javac command can either be invoked as a
foreground command or submitted as a batch job.
Tip: The Java Diagnostics Guide recommends a minimum region size of 128 MB. This
gives enough storage to accommodate a (default) 64 MB maximum heap size, the 40+ MB
for the JIT, and leaves 24 MB for application and system storage requirements.
db2sqljbind
-automaticbind NO
Serialized
db2sqljcustomize DBRM*
Profile
.ser
Issue the following command to translate and compile the sqlj stored procedure:
/SC63/sg247083/spjava:>sqlj -compile=true EmpDtl1J.sqlj
You can issue the sqlj command from any directory as long as the $PATH variable is defined
to include the path where the sqlj executable resides (that is, /usr/lpp/db2/db9a/jcc/lib).
When you issue the sqlj command, the translator creates a modified Java source code,
EmpDtl1J.java. The compile=true option forces the translator to compile the modified Java
code into bytecode and produce corresponding class files.
A number of files are produced as a result of SQLJ program preparation. They are shown in
Example 13-15.
198 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
mentioned in the sqlj source code.
The no. of Connection context classes produced
depends upon the number of context classes
defined in the sqlj source code.
EmpDtl1J_SJProfileKeys.class
If the db2sqljcustomize fails, or if you want to create identical packages in another server,
you can issue db2sqljbind to bind the packages manually.
Note: You may opt to create a script file that contains the db2sqljcustomize command
because in OMVS, you may not be able to enter all options in one line.
Example 13-17 shows the output of the db2sqljcustomize command. Notice the names of
the four DBRM members that the db2sqljcustomize command produces. For more
information about db2sqljcustomize, consult the section “Commands for SQLJ Preparation”
in DB2 for z/OS V9.1, Application and Programming Guide and Reference for Java,
SC18-9842-01.
3 the -longpkgname option allows you to specify package names of up to 127 characters.
In Example 13-18 we show the command to bind the packages created in DB9A to server
DB9B.
Example 13-18 Binding the DBRM packages for SQLJ stored procedure. using db2sqljbind
db2sqljbind -url jdbc:db2://wtsc63.itso.ibm.com:12350/DB9B \
-user paolor5 -password pup4sale \
-bindoptions "QUALIFIER DEVL7083" \
EmpDtl1J_SJProfile0.ser
200 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
//JCOMP EXEC PGM=AOPBATCH,PARM='sh -L'
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//STDERR DD SYSOUT=*
//STDOUT DD SYSOUT=*
//STDIN DD *
cd /SC63/sg247083/spjava
db2sqljcustomize -url jdbc:db2://wtsc63.itso.ibm.com:12347/DB9A \
-user paolor5 -password pup4sale \
-rootPkgName EMPDTL1 -qualifier DEVL7083 -collection DEVL7083
-bindoptions "CURRENTDATA NO QUALIFIER DEVL7083" \
EmpDtl1J_SJProfile0.ser
/*
From our additional materials link, download and browse the following files:
EmpDtljJ.java
EmpDtlsJ.ddl
EmpDtl1J.sqlj
EmpDtl1J.ddl
If your stored procedure is using JDBC methods only, you only need to place the .class files in
the CLASSPATH directory. In case of SQLJ stored procedures, you also need to place the
.ser files and the context classes in the CLASSPATH directory.
Table 13-4 shows the relationship between classpath and the location of the class files. It has
two examples, one each for JDBC and SQLJ stored procedures.
Table 13-4 Relation between CLASSPATH and the location of the class files
JDBC Stored Procedure: EMPDTLSJ
LOCATION for the Class files The class files along with the .ser files should be
placed in directory /SC63/sg247083/spjava/.
If you define the jar to DB2, you should not have the class files in the CLASSPATH. In case
the class files appear in both places, the DB2 catalog and the CLASSPATH directory, you may
get unpredictable results.
Example 13-21 shows the commands for creating the jar file for the SQLJ stored procedure.
Notice that the jar file contains the classes, context classes, and serialized profiles
corresponding to the stored procedure. You create a jar file for a JDBC stored procedure in
the same manner, listing the classes, and other jar files if needed.
Example 13-21 Employee.jar containing files for sqlj stored procedure EmpDtl1J
/u/paolor7:>cd /SC63/sg247083/spjava
/SC63/sg247083/spjava:>jar -cvf Employee.jar EmpDtl1*.class EmpDtl1*.ser
added manifest
202 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
adding: EmpDtl1J.class(in = 2481) (out= 1358)(deflated 45%)
adding: EmpDtl1J_Ctx.class(in = 2044) (out= 807)(deflated 60%)
adding: EmpDtl1J_SJProfileKeys.class(in = 991) (out= 560)(deflated 43%)
adding: EmpDtl1J_SJProfile0.ser(in = 3309) (out= 1442)(deflated 56%)
/SC63/sg247083/spjava:>
The first argument, known as AJAR, specifies a Large Binary object or BLOB.
The second argument is the SCHEMANAME.JARNAME. The JARNAME that you specify can
be anything.
Figure 13-2 on page 204 shows the two dialogs when running SQLJ.DB2_INSTALL_JAR
from IBM Data Studio.
class SimpleInstallJar
{
public static void main (String argv[])
{
// *** change this to your target URL ***
String url = "jdbc:db2://wtsc63.itso.ibm.com:12347/DB9A";
//*** change this to the jarname you want defined in DB2 ***
String jarname = "PAOLOR5.EMPLJAR";
//*** change this to the Java SP's classname ***
String classid = "EmpDtlsJ";
// *** change this ***
String jarfile = "C:\\SG247083\\SG247083_01-JAVA\\Employee.jar";
// *** optional: change this ***
String jarsourcefile = "C:\\SG247083\\SG247083_01-JAVA\\EmpDtlsJ.java";
try
{
Class.forName ("com.ibm.db2.jcc.DB2Driver").newInstance ();
// *** change this ***
Connection con = DriverManager.getConnection(url, "PAOLOR5", "PUP4SALE");
204 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
stmt = con.prepareCall (sql);
stmt.setBinaryStream(1,inputStream, (int)aFile.length());
stmt.setString( 2, jarname );
stmt.setInt( 3, 0 );
boolean isrs = stmt.execute();
stmt.close ();
System.out.println("install jar completed");
con.commit();
con.close ();
}
catch (Exception e)
{
System.out.println("install jar failed");
e.printStackTrace ();
}
}
}
If the user who creates the stored procedure is different from the user who defines the jar to
DB2, you need to give authority to use the jar:
GRANT USAGE ON JAR DEVL7083.EMPDTL TO PUBLIC
After defining the jar to DB2, you can create a stored procedure that can reference the jar file
as:
EXTERNAL NAME ‘DEVL7083.EMPDTL:EmpDtl1J.GetEmpDtls’
Where:
DEVL7083 is the schema name.
EMPDTL is the jar name as defined to DB2 (it is not the jar file!).
EmpDtl1J is the stored procedure class name.
GetEmpDtls is the method name.
There is no package name since we did not code package name in the sqlj source code.
Example 13-23 Sample DDL for registering the stored procedure EmpDtlsJ
CREATE PROCEDURE DEVL7083.EMPDTLSJ
( IN EMPNO CHARACTER(6),
OUT FIRSTNAME VARCHAR(12),
OUT MIDINIT CHAR(1),
OUT LASTNAME VARCHAR(15),
OUT WORKDEPT CHAR(3),
OUT SALARY DECIMAL(9,2),
OUT HIREDATE DATE,
OUT OUTPUTMESSAGE VARCHAR(250))
EXTERNAL NAME 'EmpDtlsJ.GetEmpDtls'
LANGUAGE JAVA
PARAMETER STYLE JAVA
COLLID DSNJDBC
PROGRAM TYPE SUB
Refer to Table 13-5 for a detailed discussion on the various options when defining a DB2
stored procedure.
PARAMETER STYLE The only parameter style supported is Java. A discussion about the
parameters can be found in 13.8.1, “INPUT/OUTPUT parameters” on
page 206.
COLLID Collection name that has the JDBC packages bound in it. In case of
SQLJ stored procedures the collection should also have the stored
procedure packages bound in it.
PROGRAM TYPE SUB. For Java stored procedures, PROGRAM TYPE should always
be SUB. See “Why is the program type SUB for a Java stored
procedure”.
WLM ENVIRONMENT Java stored procedures can only run in a WLM Environment. We used
a WLM Environment DB9AWLMJ. Steps for defining the environment
can be found in Chapter 4, “Setting up and managing Workload
Manager” on page 39.
Note: Using JDK 1.4.1 and up JVM requires adding XPLINK(ON) to JAVAENV
206 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Table 13-6, FIRSTNAME is defined as an output variable, and the Java program declares it as
a String[] array.
Things are a bit different when the stored procedure returns a result set. For each result set,
include an object of type java.sql.ResultSet[] in the parameter list for the stored procedure
method. Table 13-7 shows a stored procedure returning a result set.
There are no package statements specified in the Java code. The name of the static method
is GetEmpDtls. The CLASSPATH variable in the JAVAENV data set has been set to
/SC63/sg247083/spjava/. The CREATE PROCEDURE DDL contains the clause,
In USS, the LOCATION for EmpDtlsJ.class file should be in the same directory as defined by
the CLASSPATH, such as /SC63/sg247083/spjava/.
Notice that we need to create the subdirectories com, ibm, and itso and place the stored
procedure class file in the lowermost subdirectory in the hierarchy, and the EXTERNAL
NAME clause has a mention of the package name.
The Employee.jar file needs to be added to the CLASSPATH. The CLASSPATH environment
variable needs to be set to CLASSPATH=/SC63/Employee.jar.
Notice that the EXTERNAL NAME clause has no mention of the jar file. You need to mention
the jar file only if you define the jar to DB2. At runtime, the class file EmpDtlsJ.class is no
longer required. Instead, the Employee.jar file is used by the system to pick up the relevant
class files.
208 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Once the jar file is registered to DB2, you must remove the jar file from the CLASSPATH
Environment variable. Failure to do so may cause unpredictable errors.
In the CREATE PROCEDURE DDL, the external name clause should be defined as follows:
EXTERNAL NAME 'DEVL7083.EMPLJAR:abc.pqr.xyz.EmpDtlsJ.GetEmpDtls'
Where:
DEVL7083 is the jar schema name.
EMPLJAR is the jar name as defined to DB2 (it is not the jar file!).
abc.pqr.xyz is the package name.
EmpDtlsJ is the stored procedure class name.
GetEmpDtls is the method name.
Another way to debug a Java stored procedure is to convert it into a Java application and then
use an Integrated Development Environment such as Eclipse to debug the Java application.
The steps of converting a Java stored procedure to a Java application with minimal effort are
documented in 13.9.1, “Changing Java stored procedure to enable debugging in Eclipse” on
page 209. This methodology leverages the Java Debugger within Eclipse. The Eclipse Debug
Perspective is the same perspective used by Data Studio's Unified Debugger. See 28.3.4,
“Defining the EMPDTLSS SQL case study for debugging” on page 749 for details about the
Debug Perspective.
public static void GetEmpDtls( public static void main (String args[])
String empno, {
String[] firstName, String empno;
String[] midInit, empno=args[0];
String[] lastName, String[] firstName = new String[1];
String[] workDept, String[] midInit = new String[1];
java.math.BigDecima[] salary, String[] lastName = new String[1];
String[] outputMessage) String[] workDept = new String[1];
java.math.BigDecimal[] salary = new java.math.BigDecimal[1];
String[] outputMessage = new String[1];
Points to note:
You can debug the Java application from the RAD or any Java
Development tool.
The Java application can be invoked from the command line:
Once the above changes are made to your application, the Java application code needs to be
copied into a Java project in Eclipse. You can obtain a free copy of Eclipse from the web site:
210 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/galile
o/SR1/eclipse-java-galileo-SR1-win32.zip
The site includes several versions of Eclipse. The version that the current release of Data
Studio uses is Eclipse 3.4.
Once you've downloaded Eclipse, you can launch the Eclipse Help Contents, which will walk
you through:
Opening the Java Perspective,
Creating a Java Project,
Importing your converted Java stored procedure into the Java project,
Creating a Java application runtime configuration
Debugging the Java application
You can code System.out.println and System.err.println lines in your Java code. The output is
directed to JAVAOUT and JAVAERR DD cards in the WLM address space.
Example 13-25 shows the DD cards that you need to include in your WLM address space.
JAVAOUT maps to STDOUT and JAVAERR maps to STDERR. This example uses the data
sets in an append fashion. This data set should be deleted occasionally to keep it from
growing without bounds.
conndb2 = DriverManager.getConnection("jdbc:default:connection"); 2
Statement stmtdb2 = conndb2.createStatement();
212 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
OUT FIRSTNAME VARCHAR(12),
OUT MIDINIT CHAR(1),
OUT LASTNAME VARCHAR(15),
OUT WORKDEPT CHAR(3),
OUT SALARY DECIMAL(9,2),
OUT HIREDATE DATE,
OUT OUTPUTMESSAGE VARCHAR(250))
EXTERNAL NAME 'EmpDtlsJ.GetEmpDtls'
LANGUAGE JAVA
PARAMETER STYLE JAVA
COLLID DSNJDBC
PROGRAM TYPE SUB
WLM ENVIRONMENT DB2GWEJ1
Example 13-30 shows the code for Java stored procedure EmpRsetJ. Notice that a result set
argument is included in the method signature for GetEmpResult.
conndb2 = DriverManager.getConnection("jdbc:default:connection");
sql = "SELECT * FROM DSN8710.EMP "
+ " WHERE WORKDEPT = "
+ "'" + workDept + "'" ;
stmtdb2 = conndb2.createStatement();
rs[0] = stmtdb2.executeQuery(sql) ;
}
catch (SQLException e)
{
outputMessage[0] = "SQLException raised, SQLState = "
+ e.getSQLState() + " SQLCODE = " + e.getErrorCode()
+ " :" + e.getMessage();
}
catch (Exception e) {
outputMessage[0] = e.toString();
}
try {
Class.forName("com.ibm.db2.jcc.DB2Driver");
214 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Connection conndb2 =
DriverManager.getConnection(
url,
"PAOLOR5",
"PUP4SALE");
cstmt =
conndb2.prepareCall("CALL DEVL7083.EMPDTLSJ(?,?,?,?,?,?,?,?)");
cstmt.setString(1, args[0]);
cstmt.registerOutParameter(2, Types.VARCHAR);
cstmt.registerOutParameter(3, Types.CHAR);
cstmt.registerOutParameter(4, Types.VARCHAR);
cstmt.registerOutParameter(5, Types.CHAR);
cstmt.registerOutParameter(6, Types.DECIMAL);
cstmt.registerOutParameter(7, Types.DATE);
cstmt.registerOutParameter(8, Types.VARCHAR);
cstmt.execute();
cstmt.close();
conndb2.commit();
conndb2.close();
System.out.println("I am done");
} catch (SQLException e) {
System.out.println(
"SQLException raised, SQLState = "
+ e.getSQLState()
+ " SQLCODE = "
+ e.getErrorCode()
+ " :"
+ e.getMessage());
} catch (Exception e) {
System.out.println("Error" + e.toString());
}
}
}
Host variables
In SQLJ stored procedures or applications, you need to use host variables just as in any other
3-GL language such as COBOL, C, etc. You need to declare your host variables before you
can use them in an SQL statement. Example 13-32 shows the host variable declarations that
were used in the example.
You can directly select the contents of a DB2 column into a host variable. Example 13-33
shows a sample SQL statement that was used.
Example 13-34 shows the sample code for an SQLJ stored procedure.
216 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
public static void GetEmpDtls(
String empno,
String[] firstName,
String[] midInit,
String[] lastName,
String[] workDept,
java.math.BigDecimal[] salary,
String[] outputMessage)
{
String hfirstName;
String hmidInit;
String hlastName;
String hworkDept;
java.math.BigDecimal hsalary;
Connection conndb2 = null;
outputMessage[0] = " ";
EmpDtl1J_Ctx myConCtx = null;
try {
// Use an existing connection to DB2
conndb2 = DriverManager.getConnection("jdbc:default:connection");
myConCtx = new EmpDtl1J_Ctx(conndb2);
}
}
}
There are two types of iterators: positioned iterators and named iterators. Positioned iterators
identify the columns of a result table by their position in the result table. Named iterators
identify the columns of the result table by table column names.
Example 13-36 shows a stored procedure that does a positioned update. The stored
procedure receives two input parameters: Department Code and Salary-Increase-Factor. We
open cursor and fetch records belonging to a specified department. While fetching each
record we update the salary of the employee by the given factor. In our example we use a
positioned iterator.
The stored procedure sample code in Example 13-36 illustrates the use of a positioned
update.
Example 13-36 EmpRst2J.sqlj - Sample stored procedure - updating using positioned iterator
218 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
//this stored proc takes two input parameters
//workdept and salary-increase-factor and
//updates the salary of all employees
//belonging to the dept by using a positioned
//iterator.
import java.sql.*;
import java.math.*;
import sqlj.runtime.*;
import EmpRst2J_UpdByPos; //Import the generated iterator class that was
//created by the iterator declaration clause
//Make make sure that the external file
EmpRst2J_UpdByPos.sqlj //is defined and translated using the sqlj
//translator.
#sql context EmpRst2Ctx; //Create the connection context
public class EmpRst2J {
{
outputMessage[0] = "SQLException raised, SQLState = "
+ e.getSQLState() + " SQLCODE = " + e.getErrorCode()
+ " :" + e.getMessage();
}
catch (Exception e) {
outputMessage[0] = e.toString();
}
}
}
4
The same procedure can be used if you were running your stored procedures in DB2 V7, and wish to migrate to
JCC driver in DB2 V7.
220 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
1. Create a new WLM application environment for the JCC environment. The JAVAENV data
set should have the JCC_HOME variable pointing to the JCC directory. You should not
have any reference to the DB2_HOME directory. Refer to 13.3.7, “Setting up the JAVAENV
data set for Java stored procedure execution” on page 188 for further details on setting up
the WLM procedure for JCC support.
2. It is advisable to create a separate directory to keep your stored procedure class files that
will run under the new JCC driver.
For stored procedures making JDBC calls, the migration is simple. You need to alter the
stored procedure to the new WLM environment and copy the stored procedure class files
to the new CLASSPATH directory (as specified in the JAVAENV of the new JCC WLM
address space). Our existing stored procedures running the Legacy Driver were residing
in the directory /SC63/sg247083/DB8AU/spjava; we created a new directory named
/SC63/sg247083/DB8AU/spjava/jcc. Table 13-9 shows the various setup steps that you
need to perform to move to the JCC driver.
Table 13-9 DB2 V8 migrating JDBC stored procedure from Legacy Driver to JCC
DB2 V8 using Legacy Driver DB2 V8 using Universal Driver (JCC)
The above names could be different at each site, Notice that the DB2_HOME does not appear, instead
depending upon where the HFS libraries for the JCC_HOME is mentioned.
Java and DB2 are loaded by the system
programer. The JCC_HOME has a jcc subdirectory.
Typically, the Java libraries are in:
/usr/lpp/java/IBM/J1.4 Typically, the Java libraries are in:
and the db2 libraries in /usr/lpp/java/IBM/J1.4
/usr/lpp/db2/db2810. and the db2 libraries in
/usr/lpp/db2/jcc/db2810/jcc.
All the stored procedure class files that are
developed by programers are kept in the All the stored procedure class files need to be copied
CLASSPATH Library: to the new CLASSPATH directory:
/SC63/sg247083/DB8AU/spjava /SC63/sg247083/DB8AU/jcc/spjava
DDL CREATEPROCEDUREDEVL7083.EMPDTLSJ In order to use the driver alter the stored procedure to
( IN EMPNO CHARACTER(6), the new WLM ENVIRONMENT.
OUT FIRSTNAME VARCHAR(12),
OUT MIDINIT CHAR(1), ALTER PROCEDURE DEVL7083.EMPDTLSJ
OUT LASTNAME VARCHAR(15), WLM ENVIRONMENT DB8ADJC2;
OUT WORKDEPT CHAR(3),
OUT SALARY DECIMAL(9,2), After the ALTER copy the class file EmpDtlsJ.class to
OUT OUTPUTMESSAGE VARCHAR(250)) the new directory:
EXTERNAL NAME 'EmpDtlsJ.GetEmpDtls' /SC63/sg247083/jcc/spjava
LANGUAGE JAVA
PARAMETER STYLE JAVA
COLLID DSNJDBC
PROGRAM TYPE SUB
WLM ENVIRONMENT DB8ADJ1
Profile Depending on what environment you are running, JCC or Legacy Driver, you need to have an appropriate
profile. A profile comes into play whenever you prepare a Java stored procedure or application.
When you run any Java applications in USS, the profile is used to set the appropriate environment.
For Java stored procedures, the runtime environment is not controlled by the contents of the profile data
set, instead it is controlled by the contents of JAVAENV. However, when you prepare a Java stored
procedure, the profile contents are used.
222 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
4 - We need to assign the classes of the Legacy Driver to the CLASSPATH. The
JCC driver classes should always be ahead of the classes belonging to the
Legacy Driver.
5,6 - Set the PATH variable so that we could execute the db2sqljupgrade utility.
7 - Change to the directory that has the serialized profile.
8 - Command to run the db2sqljupgrade utility. Notice that the upgrade utility only
upgrades the .ser files. It does not touch any other class files or DB2 packages.
4. If you do not upgrade the .ser file and try to execute the sqlj stored procedure in a JCC
environment, your application will fail with the message shown in Example 13-41 on
page 225.
Example 13-40 shows the output listing of the upgrade utility. The upgrade utility renames the
existing .ser profile as _old.ser and creates a new one with the original name.
Table 13-10 summarizes the changes for migrating to the JCC driver.
DDL CREATE PROCEDURE DEVL7083.EMPDTL1J In order to use the driver alter the stored
( IN EMPNO CHARACTER(6), procedure to the new WLM ENVIRONMENT.
OUT FIRSTNAME VARCHAR(12),
OUT MIDINIT CHAR(1), a) ALTER PROCEDURE DEVL7083.EMPDTL1J
OUT LASTNAME VARCHAR(15), WLM ENVIRONMENT DB8ADJC2;
OUT WORKDEPT CHAR(3),
OUT SALARY DECIMAL(9,2), b) After the ALTER DDL , copy the following class
OUT OUTPUTMESSAGE VARCHAR(250)) files to the newCLASSPATH directory:
EXTERNAL NAME 'EmpDtl1J.GetEmpDtls' /SC63/sg247083/jcc/spjava
LANGUAGE JAVA
PARAMETER STYLE JAVA EmpDtl1J.class
COLLID DEVL7083 EmpDtl1J.java
PROGRAM TYPE SUB EmpDtl1J.sqlj
WLM ENVIRONMENT DB8ADJ1 EmpDtl1J_Ctx.class
EmpDtl1J_SJProfile0.ser
EmpDtl1J_SJProfileKeys.class
Profile Depending on what environment you are running, JCC or legacy driver, you need to have an
appropriate profile. A profile comes into play whenever you prepare a Java stored procedure or
application.
When you run any Java applications in USS, the profile is used to set the appropriate environment.
For Java stored procedures, the runtime environment is not controlled by the contents of the profile
data set, instead it is controlled by the contents of JAVAENV. However, when you prepare a Java
stored procedure, the profile contents are used.
224 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
DB2 V8 using Legacy Driver DB2 V8 using Universal Driver (JCC)
Example 13-41 Error listing - Trying to run a sqlj stored procedure without upgrade
'SQLException raised, SQLState = 46130 SQLCODE = 0 :profile EmpDtl1J_SJProfile0 not found:
java.lang.ClassNotFoundException: COM.ibm.db2os390.sqlj.custom.DB2SQLJProfile' CCSID: 37
try {
FileOutputStream outFile = new FileOutputStream(fileName);
Class.forName("com.ibm.db2.jcc.DB2Driver");
Connection con =
DriverManager.getConnection(
"jdbc:db2://wtsc63.itso.ibm.com:12345/DB8A",
"paolor7",
"bhas11");
Statement stmt = con.createStatement();
sqltxt = "SELECT JAR_DATA FROM SYSIBM.SYSJAROBJECTS WHERE JAR_ID = "
+ "'" + jarID + "'"
+ "and JARSCHEMA = '" + schemaName + "'" ;
ResultSet rs =
stmt.executeQuery(sqltxt);
if (rs.next())
{
jarBlob = rs.getBlob("JAR_DATA") ;
inpStream = jarBlob.getBinaryStream() ;
}
}
}
}
Example 13-43 shows the sample JCL to invoke the Java application ExtractJar. Before
compiling and running the Java JDBC application, ensure that the profile is set to point to
the JCC setup.
We also developed a stored procedure, EXTRACT_JAR, that extracts a jar file from DB2
and writes the file to an HFS file. A detailed description of the Extract_jar stored procedure
is in 25.4.4, “Handling large BLOB columns” on page 614.
226 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
The Java application shown in Example 13-42 used a JCC Type 4 Driver. Notice the
connection string; we specify the domain name and port number of the target DB2
subsystem.
3. Once we download the BLOB to an HFS file, Employee.jar, we need to extract the .ser file
from the jar. Issue the following commands to do the extraction:
jar -tf Employee.jar This command lists the contents of the jar file
indicates that your JAVENV data set has the wrong record length. See 13.3.7, “Setting up the
JAVAENV data set for Java stored procedure execution” on page 188, for the DCB
information of the JAVAENV data set. WLM will stop, and will need to be resumed.
indicates that your ENVAR has wrong specifications. In DB2 9 for z/OS only one parameter is
allowed. It should be JCC_HOME. See 13.3.8, “Environment variables in the JAVAENV data
set” on page 189 for details on how to set up these environment variables. WLM will stop and
will need to be restarted.
Abend U4038
When the XPLINK(ON) parameter is not included in the JAVAENV data set, the WLM address
space will not initialize, and you may get the following Abend in the console log and WLM job
log:
IDI0001I Fault Analyzer V7R1M0 (HAC4710 2006/09/18) invoked by IDIXDCAP using
SYS1.IFA.PARMLIB(IDICNF00)
IDI0044I Current fault is a duplicate of fault ID F00197 in history file SYSU.IFA.HIST -
the duplicate
count is 5
IDI0053I Fault history file entry suppressed
IDI0002I Module DSNX9JVM, program DSNX9JVM, offset X'1CF8': Abend U4038
IEA995I SYMPTOM DUMP OUTPUT 414
USER COMPLETION CODE=4039 REASON CODE=00000000.
The XPLINK(ON) parameter is required with JDK 1.4.1 and up. The importance of this
parameter is also discussed in 27.2.7, “Java SDKs used by IBM Data Studio” on page 661.
228 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Make sure that you grant the necessary authorizations to execute the procedure and package
to the authorization ID calling the stored procedure. See Chapter 10 of DB2 Version 9.1 for
z/OS Application Programming Guide and Reference for Java, SC18-9842-01 for details
about authorization.
indicates that your ENVAR’s JCC_HOME is pointing to an invalid directory. Verify the
directory where the IBM DB2 Universal Driver files are installed. It could also mean that your
JCC_HOME is pointing to an old version of the JDBC Drivers rather than the Universal Driver.
- ADMF001.SQL6052402405858 java.lang.UnsupportedClassVersionError: -
PKG60424024051890/J_v82jars (Unsupported major.minor version 49.0)
Either build your Java stored procedure using JDK 1.4, or upgrade the server JDK to 1.5. The
server JDK is set up in the JAVAENV variable, JAVA_HOME. See 13.3.2, “Ensuring that the
Java SDK is at the right level” on page 183 for details on setting up this variable.
Determine whether the jar file is complete or not corrupt. It may not have been uploaded in
binary mode. Use the TSO OMVS jar command to expand the jar and see its contents:
jar -tvf <jar filename>”
The jar file in OMVS is read protected. Change the attributes to 755 using the following
command:
chmod 755 <jar filename>
The problem may be resolved by the following changes to your Java code:
Use .equals instead of == for example (Country.equals("668"))
Use != null instead of != " " for example (timeZoneID != null)
-450
The length of the variable assigned to an output parameter in the CREATE PROCEDURE
statement is not sufficient to receive the data from DB2. Make sure the lengths are
compatible. Consult Table 18 in DB2 Version 9.1 for z/OS Application Programming Guide
and Reference for Java, SC18-9842-01, for more information on data type and SQL type
mappings.
-805
A -805 is usually indicative of an inconsistency between the COLLID used in the CREATE
PROCEDURE statement and the COLLID used when the Java package was bound.
To solve this problem, check the routine definitions in the DB2 catalog and make sure that the
COLLID in the CREATE PROCEDURE statement matches the COLLID you specified in the
DB2Binder utility.
230 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
If the COLLID in the CREATE PROCEDURE statement is blank, the collection ID of the
stored procedure is the same as the collection ID of the program that calls it. Redefine the
routine or the calling program so that the COLLIDs match.
For more details on this, see Chapter 9 of DB2 Version 9.1 for z/OS Application Programming
Guide and Reference for Java, SC18-9842-01, including the discussion on how to use the
CURRENT PACKAGESET special register for setting the COLLID.
Ensure that the EXTERNAL NAME follows the syntax for using jars and packages as
explained in 13.7, “Making the stored procedure class files available to DB2” on page 201.
The problem is that the user's authorization ID (MINSK03) is used as implicit qualifier for the
table (RGEVTZCS) and not the schema (VGWSFD) under which the table was created and
the plan of the calling program was bound.
See JVMPROPS in 13.3.8, “Environment variables in the JAVAENV data set” on page 189 for
other applications of the JVMPROPS environment variable.
If you are not familiar with the SQL Procedures language capabilities, refer to Appendix D.
“SQL control statements for external SQL procedures” in DB2 Version 9.1 for z/OS SQL
Reference, SC18-9854 for details.
Note: Complete sample programs can be downloaded from the ITSO Web site as
additional material. Download instructions are in Appendix B, “Additional material” on
page 887.
Before downloading, we strongly suggest that you first read 3.3, “Sample application
components” on page 24 to decide what components are applicable to your environment.
SQL stored procedures were introduced to DB2 with Version 5. Before V9, only one kind of
SQL stored procedure existed. DB2 9 for z/OS introduced a new kind of SQL stored
procedures, the Native SQL stored procedures. Refer to Chapter 15, “Native SQL procedures”
on page 253 if you want to learn more about the new kind of SQL procedures in DB2 for z/OS.
The way SQL stored procedures have been implemented before V9 is today referred to as
External SQL stored procedures.
Tip: If you have not yet started using SQL stored procedures, we recommend that you
start with Native stored procedures provide more features and are easier to handle than
external stored procedures. If you are already using SQL stored procedures, you might
want to migrate them to Native stored procedures in order to be able to make use of the
enhancements that Native stored procedures provide in comparison to External SQL
stored procedures.
234 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
14.1 Verifying the environment
Before developing the stored procedure, it is important to have a clear understanding of the
various steps that must be completed for a stored procedure to execute successfully. These
steps are covered in detail in the rest of the book and we simply list them here for
convenience. They are:
1. The WLM environment must be set up. See Chapter 4, “Setting up and managing
Workload Manager” on page 39 for details.
2. The LE environment must be set up. See Chapter 5, “Language Environment setup” on
page 47 for details.
3. The stored procedure must be defined to DB2. Note in particular that if the stored
procedure is designed to return result sets, the maximum number of result sets that can
be returned is specified in the definition. See Chapter 9, “Defining stored procedures” on
page 91 for details.
4. Develop the stored procedure. See 14.2.1, “Preparing and binding an SQL procedure” on
page 236 for details.
5. Grant the necessary privileges to the authorization ID of the user that executes the stored
procedure. See Chapter 7, “Security and authorization” on page 65 for details.
6. Develop the calling application if needed.
7. Also see Chapter 16, “Debugging” on page 313 for details on testing and debugging.
There is one important difference between external SQL stored procedures and other
external stored procedures, which is the manner in which errors are handled. In general, DB2
automatically returns the SQL conditions through the SQLCA for SQL procedures. This
When you use the client-based IBM DB2 Developer Workbench or newer Data Studio to
define the SQL procedure to DB2, the preparing and binding is automatically done for you by
the SQL procedure build utility. If you do not use the Developer Workbench or Data Studio,
you must do the following:
Use the DB2 SQL precompiler to convert the SQL procedure source statements into a C
language program.
Process the resulting C program as if they are in any other SQL application program
through the DB2 precompiler or the SQL statement coprocessor.
Bind the resulting DBRM into a package.
For the first two steps mentioned above the installation process provides you with JCL
procedure DSNHSQL.
If you decide to change the SQL statement terminator, for example to the percent sign (%),
you can do this as follows for each of the four mentioned SQL user interfaces:
For DSNTEP2: Add PARMS('/SQLTERM(%)') keyword of DSN RUN command.
For DSNTEP4: Add PARMS(’/SQLTERM(%)’) keyword of DSN RUN command.
For DSNTIAD: Add PARMS('SQLTERM(%)') keyword of DSN RUN command.
236 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Important: Note that DSNTEP2 and DSNTEP4 are PL/I programs. For PL/I programs
you specify the parameter list of the form A/B, where A represents a list of runtime
options and B represents a list of parameters for the PL/I application program. If runtime
options are not needed, write the list in the form /B.
Options such as SQLTERM belong to the parameters for the PL/I application program.
As a consequence you must make sure that they are specified after the slash (/).
For SPUFI: Choose Change defaults in the SPUFI input panel, and change the SQL
terminator to some special character other than semicolon (;), such as percent (%).
You can also change the SQL terminator by specifying --#SET TERMINATOR symbol just
before your SQL statement. So if you intended to change the symbol to ampersand (&), you
could do so by coding the following statement in your SPUFI editor:
--#SET TERMINATOR &
SELECT * FROM SYSIBM.SYSROUTINES &
CREATE PROCEDURE .....
Refer to Table 14-1 for a list of invalid characters for use as SQL statement terminator.
blank X'40'
comma , X'5E'
underscore _ X'6D'
Assignment
The assignment statement assigns a value to an output parameter or to an SQL variable. See
Example 14-2.
CALL
The CALL statement invokes a stored procedure. This procedure can be an authorized
procedure written in any language (for example, COBOL, Java, etc.). See Example 14-3.
CASE
The CASE statement selects an execution path based on the evaluation of one or more
conditions. See Example 14-4.
238 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
INTO TOTSAL
FROM EMP
WHERE SALARY < 30000;
END CASE;
GOTO
The GOTO statement causes a branch to a user-defined label within an SQL procedure. See
Example 14-5.
IF
The IF statement selects an execution path based on the evaluation of a condition. See
Example 14-6.
LEAVE
The LEAVE statement transfers program control out of a loop or a compound statement. See
Example 14-7.
LOOP
The LOOP statement executes a statement or a group of statements multiple times. See
Example 14-8.
WHILE
The WHILE statement executes a statement or a group of statements while a search
condition is true. See Example 14-10.
240 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
END
GET DIAGNOSTICS
The GET DIAGNOSTICS statement obtains information about the execution status of the
previous SQL statement that was executed. See Example 14-12.
ITERATE
The ITERATE statement causes the flow of control to return to the beginning of a loop.
ITERATE is only allowed in looping statements such as LOOP, REPEAT, WHILE. See
Example 14-13.
SIGNAL
The SIGNAL statement is used to return an error or warning condition to the calling program.
It causes an error or warning to be returned with the specified SQLSTATE along with an
optional message text. See Example 14-14.
RETURN
The RETURN statement is used to return from the routine. Optionally, it can return an integer
status value (the return code).
242 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
When you use a parameter in an assignment statement, all parameters, not just those
declared as OUT or INOUT, can be modified.
The restriction not to use an SQL reserved word as an SQL variable name was removed in
DB2 V8.l
Variable names are implicitly or explicitly qualified and we suggest the following guidelines:
When you use an SQL procedure parameter, variable or column name in the procedure
body, qualify them with the procedure name as shown in Example 14-17 in the cases
where they might be ambiguous. For instance, a column name with the same name as a
variable.
Specify a label for each compound statement and qualify SQL variable names in the
compound statement with that label as shown in Example 14-18.
Qualify column names with the associated table or view names as shown in
Example 14-19.
A stored procedure can receive and send back parameters to the calling application. When
the calling application issues an SQL CALL to the stored procedure, DB2 builds a parameter
list based on the parameters passed in the SQL call and the information specified when the
stored procedure is initially defined. For an SQL procedure retrieving information about a
specific employee, the parameter list specified when defining the stored procedure is shown
in Example 14-20.
This definition specifies whether the parameter is IN (input to the stored procedure), OUT
(output from the stored procedure), or INOUT (input to and output from the stored procedure).
It also specifies the data type and size of each parameter. This list must be compatible with
the parameter list in the calling application.
SQL procedures have no explicit LINKAGE section and the passing of arguments is
accomplished using the normal conventions. For example, an input parameter is received
based on the call sequence when it is invoked.
An output parameter value is returned as set by the stored procedure. There is no explicit
RETURN statement needed.
If the stored procedure must return a result set, additional processing is required. This is
discussed in 14.2.9, “Handling result sets” on page 245.
244 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
14.2.9 Handling result sets
When the stored procedure returns a small number of parameters, it is much simpler to avoid
result sets altogether, returning them as parameters as discussed above. When the stored
procedure must return result sets, each consisting of multiple rows, there are two alternatives:
Handling a fixed number of result sets for which you know the contents
Handling a variable number of result sets, for which you do not know the contents
The first alternative is simpler to develop, but the second alternative is more general and
requires minimal modifications if the calling program or stored procedure changes. We will
now discuss each of these alternatives in detail.
You can redeploy the SQL procedures without carrying over and redefining the possibly large
source SQL by moving the C module and DBRM, but the stored procedure must continue to
be defined to DB2 as LANGUAGE SQL on the CREATE PROCEDURE statement, which
should be invoked as any other DDL statement. The procedure body on this CREATE
PROCEDURE... LANGUAGE SQL can be any valid simple SQL statement, such as SET
CURRENT DEGREE = 'ANY', as DB2 will not use this procedure body when the re-deployed
SQL procedure referencing the C load module is invoked.
Handlers are similar to WHENEVER statements in an external SQL application program. You
can handle the following:
SQL errors
SQL warnings
Not found/no more rows conditions
Specific SQLSTATEs
After the statement completes, DB2 performs the action indicated by the handler-type
(CONTINUE or EXIT). For CONTINUE, the execution continues with the statement after the
statement that caused the handler to be activated. For EXIT, execution skips to the end of the
compound statement that contains the handler.
Example 1
The sample in Figure 14-1 on page 247 shows a CONTINUE handler that 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 reaches the END statement.
246 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Begin
....
DECLARE CONTINUE HANDLER FOR SQLWARNING
SET CODE = SQLCODE;
.....
statement1;
1 2
statement2; results in SQLCODE +562 CODE = +562
HANDLER fired!
next statement
4 statement3; ntinues with
Execution co
3
statement4
END
Example 2
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 that if the evaluation of the search-condition in an IF statement raises a condition,
and the condition invokes a continue handler, then processing will continue with the statement
following the IF statement. However, if a statement within the IF statement raises a condition
which invokes a continue handler, processing continues with the next statement following the
one that raised the condition.
In Example 14-2, the procedure does not continue after the END IF although the CONTINUE
handler is fired, because the error occurred inside the IF ... END IF block. (Actually, it works
exactly the same way as it does in the sample described in Figure 14-1.)
Begin
....
DECLARE CONTINUE HANDLER FOR SQLWARNING
SET CODE = SQLCODE;
.....
statement1;
IF ....THEN 1 2
results in SQLCODE +562
statement2;
HANDLER fired! CODE = +562
statement3; 3
ELSE
statement4
END IF;
statement 5
END
Example 3
If the error occurs in the IF statement as shown in Figure 14-3, 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).
statement3;
ELSE
statement4
END IF; 3
statement 5
4
END
Example 4
The following handler sets the END_OF_C1 flag to Y and continues after the statement that
returned no rows (such as FETCH C1):
DECLARE CONTINUE HANDLER FOR NOT FOUND SET END_OF_C1 = ‘Y’;
Example 1
As shown in Figure 14-4, 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.
Begin
....
DECLARE EXIT HANDLER FOR SQLEXCEPTION
SET CODE = SQLCODE;
.....
statement1;
1 2
results in SQLCODE -601
statement2;
HANDLER fired!
CODE = -601
the
statement3;
the end of
re tu rned to 3
l is
END Contro d statement
4 m po un
co
Example 2
The following handler sets the OUTMSG variable to Authorization Error and exits the
compound statement that generated the condition:
248 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
DECLARE AUTH_ERROR CONDITION FOR ‘42501’;
...
DECLARE EXIT HANDLER FOR AUTH_ERROR
SET OUTMSG = ‘AUTHORIZATION ERROR’;
The following code fragment shows the declaration and how it is used:
DECLARE SQLCODE INTEGER;
...
DECLARE EXIT HANDLER FOR SQLEXCEPTION
SET OUTSQLCODE = SQLCODE;
Example 14-22 shows how one of the parameters, MESSAGE_TEXT, can be used.
MESSAGE_TEXT identifies the message text of the error or warning returned from the SQL
statement that invoked the handler.
14.3.2 Using the RETURN statement for the SQL procedure status
You can use the RETURN statement in an SQL procedure to return an integer status value. If
you include a RETURN statement, DB2 sets the SQLCODE in the SQLCA to 0 and the caller
must retrieve the return status of the procedure in either of the following ways:
By using the RETURN_STATUS item of GET DIAGNOSTICS to retrieve the return value of
the RETURN statement
By retrieving SQLERRD(0) of the SQLCA, which contains the return value of the RETURN
statement
Note: This is the first occurrence of the SQLERRD fields. The SQLERRD fields are
numbered from 0 - 5 in the C language and from 1 - 6 in other high-level languages.
If you do not include a RETURN statement in an SQL procedure, then by default DB2 sets the
return status to 0 for an SQLCODE that is 0 or positive and sets it to -1 for a negative
SQLCODE.
The capability to set a specific SQLSTATE in case of an error is useful for packaged
applications such as extenders which have their own SQLSTATEs that they want to return to
the invoking application. You can achieve this by using the RESIGNAL command within the
body of a handler as shown in Example 14-24.
Note that when you use SIGNAL or RESIGNAL to set the SQLSTATE, the value of SQLCODE
returned to the invoking application is a constant (you cannot set it) based on the class code
(first 2 bytes) of the SQLSTATE:
Class code 00 is not allowed.
Class code 00 or 01 causes SQLCODE +438.
All other class codes cause SQLCODE -438.
Example 14-25 Error received by the trigger when called stored procedure issues a rollback
DSNT408I SQLCODE = -723, ERROR: AN ERROR OCCURRED IN A TRIGGERED SQL STATEMENT
IN TRIGGER DEVL7083.EMPTRIG1, SECTION NUMBER 2.
INFORMATION RETURNED: SQLCODE -751, SQLSTATE 38003, AND MESSAGE TOKENS
STORED PROCEDURE,DEVL7083.EMPAUDTS
DSNT418I SQLSTATE = 09000 SQLSTATE RETURN CODE
DSNT415I SQLERRP = DSNX9CAC SQL PROCEDURE DETECTING ERROR
DSNT416I SQLERRD = 0 0 0 -1 0 0 SQL DIAGNOSTIC INFORMATION
DSNT416I SQLERRD = X'00000000' X'00000000' X'00000000' X'FFFFFFFF'
X'00000000' X'00000000' SQL DIAGNOSTIC INFORMATION
250 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
This technique is especially useful in cases where the situation would otherwise return a zero
or positive SQLCODE allowing the trigger to continue and commit the changes when you do
not want it to do so.
See Chapter 26, “Using triggers and UDFs” on page 629 for details on triggers invoking a
stored procedure.
Chapter 15, “Native SQL procedures” on page 253 introduces the advantages and great new
possibilities that are offered with native SQL procedures. Future investments regarding the
improvements for stored procedure handling and coding are likely to occur mostly to native
SQL procedures.
For migrating external SQL stored procedures to native SQL procedures, you need to drop
and recreate the stored procedure. If your external SQL procedure was created in DB2 V8, it
is possible that you did not specify the FENCED or EXTERNAL keyword at creation time,
since it was implied. If this is the case, you simply must drop the existing stored procedure
from DB2 and re-run the CREATE PROCEDURE statement omitting both keywords once
again.
However, since a different SQL dialect is used in the two types of procedures you need to
provide three other significant source language adjustments beyond just enabling native SQL
procedure creation:
Adding new source option values for native procedures which reflect other critical options
used during the production steps for external (the separate steps of precompile and bind
package).
Adjusting the source coding practices for SQLPL error handling, to keep the semantics
intact given the various incompatibilities listed for the release between external and native.
Qualifying unqualified SQL parameter and SQL variable references to avoid adverse
impact due to the different name resolution rules that apply between native and external.
Be aware that the processes to produce and maintain a callable native SQL procedure
(dynamic DDL) are different than the processes used to produce and maintain a callable
external SQL procedure (stored procedure DSNTPSMP or JCL). To get the most benefit from
the conversion, devote some of the effort to becoming familiar with and comfortable using the
lifecycle processes for native SQL procedures.
The technote “Converting an external SQL procedure to a native SQL procedure” can be of
help. It is available from the Web site:
http://www-01.ibm.com/support/docview.wss?rs=64&context=SSEPEK&uid=swg21297948&loc=en_US&cs
=utf-8&lang=en
Tip: Consider making SQL Format SQLPL your default setting in SPUFI. This mode is
suitable for all of SQL, but it is intended primarily for SQL procedural language processing.
When this option is in effect, SPUFI retains SQL comments and terminates each line of an
SQL statement with a line feed character (hex 25) before passing the statement to DB2.
Lines that end with a split token are not terminated with a line feed character. Use this
mode to obtain improved diagnostics and debugging of SQL procedural language.
252 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
15
Note that the enhancements that V9 has provided to SQL procedures are all applicable only
to the native SQL procedures, not to the external SQL procedures.
With V9 new function mode, when you create a native SQL procedure, its procedural
statements are converted to a native representation that is stored in the DB2 catalog and
directory, as it is done with other SQL statements. The parameter list and procedure options
are stored in the database catalog tables as in the prior releases. When you CALL a native
SQL procedure, DB2 loads the native representation from the directory and the DB2 engine
executes the procedure.
The following table depicts the differences between native and external SQL procedures in
the build process (preparation) as well as the execution phase. It furthermore shows the
dramatic simplification introduced by the native SQL procedures.
External SQL procedures Multiple steps necessary, The load module for the
from V5 on requires C compiler. generated C program requires
a WLM environment to run.
Native SQL procedures Single-step DDL. Runs entirely within the DB2
starting with V9 NFM engine.
There are other differences between the two types of SQL procedures regarding the creation,
the execution environment, the SQL language, and the returned messages. We will talk about
these topics later in this chapter.
254 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Improved performance
Native SQL procedures are executed entirely in the DB2 engine, whereas external SQL
procedures are executed in the WLM environment. The native SQL procedures are
expected to outperform typical external SQL procedures.
Offloadable to zIIP
Native SQL procedures are eligible for offloading to a zIIP. If a native SQL procedure is
called from a DRDA client using TCP/IP, then a portion of the SQL procedure processing
is directed to a zIIP. If a native SQL procedure is called from a local application and the
SQL procedure performs a parallel query, then a portion of the child tasks will be directed
to a zIIP. There should not be any noticeable performance impact other than more CPUs
are available to process the parallel requests.
Enhanced SQL support
Native SQL procedures offer enhanced support for the SQL Procedural Language. This
implies new constructs like FOR loops, nested compound statements and more data types
(e.g. BIGINT, BINARY, VARBINARY, DECFLOAT). A developer is thus capable of writing
very complex SQL procedures.
Better family compatibility, portability, and standards compliance
Native SQL procedures support more SQL PL language, which is already available on
other platforms such as LUW and i5/OS®. Therefore, these types of procedures are much
more portable especially in a heterogeneous environment.
Application life cycle support for native SQL procedures
Native SQL procedures have been designed with the view of the application development
lifecycle in mind. You can create a version of an SQL procedure, debug it, replace it or add
a new version of the procedure, and finally deploy it into production. DB2 manages the
various aspects of the application development lifecycle in a consistent and integrated
manner providing enhanced security, including the source code for the native SQL
procedures. Also native SQL procedures offer application and tools support like SPUFI,
DSNTEP2 on the server side, and the Data Studio on the client side.
ORIGINAL_ENCODING_CCSID INTEGER NOT NULL The original CCSID of the statement text
string
STRING_DELIMITER CHAR(1) NOT NULL The string delimiter that is used in COBOL
string constants:
A Apostrophe(’)
Q Quote (“)
SQL_STRING_DELIMITER CHAR(1) NOT NULL The SQL string delimiter that is used in
string constants:
A Apostrophe(’)
Q Quote(“)
DECIMAL_ARITHMETIC CHAR(1) NOT NULL The rules that are to be used for CURRENT
PRECISION and when both operands in a
decimal operation have a precision of 15 or
less:
1 DEC15 specifies that the rules do not
allow a precision greater than 15 digits
2 DEC31 specifies that the rules allow a
precision of up to 31 digits
256 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Column name Data type Description
IBMREQD CHAR(1) NOT NULL A value of Y indicates that the row came
from the basic machine-readable material
(MRM) tape.
ROUNDING CHAR(1) NOT NULL WITH The rounding mode that is used when
DEFAULT arithmetic and casting operations are
performed on DECFLOAT data:
C ROUND_CEILING
D ROUND_DOWN
F ROUND_FLOOR
G ROUND_HALF_DOWN
E ROUND_HALF_EVEN
H ROUND_HALF_UP
U ROUND_UP
Note: The same set of environment variables can be associated with multiple native SQL
procedures or with multiple versions of a native SQL procedure.
Authorization
In order to be able to use the CREATE PROCEDURE SQL statement, you must have at least
one of the following:
The CREATEIN privilege on the schema that you are using
SYSADM or SYSCTRL authority
Operational hint
As we explained before, native stored procedures are not translated to C code, compiled, and
bound later. Instead, native SQL stored procedures are compiled into runtime structures and
bound at creation time. As a result the procedure’s non-logic part, as well as the logic part, is
stored as a package in your DB2 directory.
On average, native SQL procedure packages are significantly larger than packages of stored
procedures written in any other programming language or those from external SQL stored
procedures. In these fenced or external procedures, the logic part corresponds to the load
module that executes outside the engine.
Note: Your packages are loaded into the EDMPOOL at execution time. Since those
packages might be significantly larger than other packages, you might run into EDMPOOL
short of space conditions if you do not monitor its usage.
In DB2 z/OS Version 9, some parts of the EDMPOOL have been moved above the 2 GB bar,
which are amongst others structures like the skeleton cursor and skeleton package tables.
This resolves some size limitations from former versions and also significantly reduces the
EDMPOOL size below the bar with an average estimation of 60%.
258 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
READS SQL DATA
DYNAMIC RESULT SETS 1
BEGIN
DECLARE v_numRecords INTEGER DEFAULT 1;
DECLARE v_counter INTEGER DEFAULT 0;
DECLARE c1 CURSOR FOR
SELECT salary FROM staff ORDER BY salary;
DECLARE c2 CURSOR WITH RETURN FOR
SELECT name, job, salary
FROM staff
WHERE salary > medianSalary
ORDER BY salary;
DECLARE EXIT HANDLER FOR NOT FOUND
SET medianSalary = 0;
SELECT COUNT(*) INTO v_numRecords FROM STAFF;
OPEN c1;
WHILE v_counter < (v_numRecords / 2 + 1) DO
FETCH c1 INTO medianSalary;
SET v_counter = v_counter + 1;
END WHILE;
CLOSE c1;
OPEN c2;
END
With the introduction of native SQL procedures, the semantics of the CREATE PROCEDURE
statement for an SQL procedure have changed. Starting in Version 9.1 NFM, all SQL
procedures that are created without the FENCED option or the EXTERNAL option in the
CREATE PROCEDURE statement are native SQL procedures. In previous releases of DB2, if
you did not specify either of these options, the procedures were created as external SQL
procedures.
Note: The FENCED keyword is not really new on CREATE PROCEDURE SQL
statements. It has been used as the default for SQL and other stored procedures. The
meaning of FENCED is that the procedure runs in an external address space, which
typically used the assigned WLM stored procedure address space. In addition to that,
FENCED also specifies that the SQL procedure program is an MVS load module with an
external name.
Starting with DB2 V9, if you specify FENCED or EXTERNAL together with LANGUAGE
SQL on a CREATE PROCEDURE statement, you are asking for the creation of an external
SQL procedure.
Using the VERSION option introduces application life cycle into the native SQL procedure. It
creates a first initial version MEDIAN_V1 of the SQL procedure. Without specifying this
keyword a default of V1 is assumed. In 15.3.7, “ALTER PROCEDURE syntax” on page 296
where the ALTER statement is explained, a new version is added for the same SQL
procedure. To learn more about versioning refer also to 15.2.2, “CREATE PROCEDURE
syntax” on page 265.
For native SQL procedures the LANGUAGE SQL keyword is now optional.
The DYNAMIC RESULT SETS 1 option on the CREATE PROCEDURE statement indicates
that a result set may be returned to the caller of this procedure. DECLARE c2 CURSOR
WITH RETURN FOR statement declares that the cursor c2 is associated with this result set.
Finally, the OPEN c2 statement executed at the last statement in the body of this procedure
will allow the caller to retrieve data from the result set associated with the cursor c2. Note that
An SQL procedure is essentially a single SQL statement that consists of multiple SQL
sub-statements, and may also include comments and white space. For readability, it is usually
formatted on multiple lines. SPUFI, DSNTEP2, and DSNTEP4 accept multi-line input that lies
within columns 1 and 72 of one or more 80-column input records. Such preprocessing of SQL
into a linear, comment-free format is the standard, long-established behavior of SPUFI,
DSNTEP2, and DSNTEP4, but this behavior complicates diagnostics and debugging of SQL
procedure language, and effectively modifies the source by discarding SQL comments and
comment blocks.
is converted to:
SELECT name, job, salary FROM staff WHERE salary > medianSalary ORDER BY salary;
To enhance the usability of SPUFI, DSNTEP2, and DSNTEP4, three additional processing
options affect how they preprocess SQL input before handing it off for PREPARE:
SQL
specifies that SQL statements are to be preprocessed as in earlier versions of DB2.
SPUFI, DSNTEP2, and DSNTEP4 accept multi-line SQL statements but copy them
seamlessly into an SQL buffer for PREPARE, effectively converting the multi-line input to a
single line. In addition, SQL comments are removed.
SQLCOMNT
specifies that SQL-style comments are to be passed in the statement buffer for PREPARE
instead of stripped out and discarded (the default behavior of SPUFI, DSNTEP2, and
DSNTEP4). A LF character is appended after the detected SQL comment if none are
found in the remaining input buffer (the portion that would otherwise be discarded). The
purpose is to prevent loss of SQL comments, to assist with diagnostics and debugging,
and to retain the format of the SQL procedure.
SQLPL
like SQLCOMNT, specifies that SQL-style comments are to be preserved. It also requests
that a line formatting (LF) character is to be appended to each input line that ends without
a token split. The purpose is to preserve the SQL comments and multi-line format of an
SQL procedure in order to provide better diagnostics and debugging. It also helps retain
the format of the SQL procedure when it is stored in the DB2 catalog.
To maintain multi-line granularity for debugging purposes and to preserve SQL comments,
you can manually embed a line formatting character at the end of each line that ends with an
undelimited token. Alternatively, you can use the new SQLPL option to have a line feed
character x'25' added automatically.
260 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
With the option in effect, the above example is passed for PREPARE as:
SELECT name, job, salary, -- Result set to be returned<LF> FROM staff<LF> WHERE salary >
medianSalary<LF> ORDER BY salary;<LF>
Alternatively, you may wish to minimize modification of the input by preserving SQL
comments but without adding line formatting characters. However, if SQL comments are to be
preserved it is necessary to terminate them with line formatting characters because the
parser otherwise cannot distinguish where they end, as the following example shows:
SELECT name, job, salary, -- Result set to be returned FROM staff WHERE salary >
medianSalary ORDER BY salary;
Use the SQLCOMNT option to specify that SQL comments are to be preserved, and
terminated automatically by a line feed character if one is not provided in the source. Note
that only SQL comments will be terminated. This is the difference between the SQLCOMNT
option and the SQLPL option.
Note: When creating a SQL procedure, we recommend to use SQLPL as SQL FORMAT.
This is especially true for scenarios where tools are employed, that extract the DDL from
the DB2 catalog. This way we ensure that the multi-line formatting is preserved.
. . . . . . . . . . . . . . . . . . . . . . . . . . .
DSNESP02 CURRENT SPUFI DEFAULTS SSID: DB9B
===>
As indicated in the previous section it is recommended to make use of the SQLPL format
when developing SQL procedures. Also notice that the SQL TERMINATOR has been set to
pound sign (#). This is required, as the SQL procedure contains embedded SQL statements
that terminate with a default semicolon (;) and need to be distinguished from the embracing
BEGIN and END.
Then some synthetic data is created by multiple INSERT statements on the staff table as
shown in Example 15-3.
Finally the SQL procedure can be created by using the SQL statement in Example 15-4.
Calling this stored procedure returns the median salary in the output parameter as well as the
staff that contain a higher salary than the median in the result set.
262 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Example 15-5 demonstrates the creation of the MEDIAN_RESULT_SET SQL procedure in
DSNTEP2. This sample illustrates the use of SQLFORMAT parameter to select SQLPL
behavior when calling DSNTEP2.
Note also the use of the SQLTERM parameter to change the SQL terminator from a
semicolon to a pound sign (#). Individual statements within the SQL procedure body are
terminated with a semicolon, so a different character is required to mark where the SQL
procedure itself terminates.
Note the use of the TERMINATOR control statement to change the SQL terminator character
from the default semicolon to the pound sign, and then back to the semicolon.
264 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
15.2.2 CREATE PROCEDURE syntax
Figure 15-2, Figure 15-3 on page 266, and Figure 15-4 on page 267 show the complete
CREATE PROCEDURE syntax for native SQL procedures.
parameter-declaration
parameter-declaration:
IN
parameter-name parameter-type
OUT
INOUT
parameter-type:
built-in-type
SMALLINT
INTEGER
INT
BIGINT
(5.0)
DECIMAL
DEC (integer )
NUMERIC , integer
(53)
FLOAT
(integer)
REAL
PRECISION
DOUBLE
(34)
DECFLOAT
(16)
(1)
CHARACTER
CHAR (integer) CCSID ASCII FOR SBCS DATA
CHARACTER VARYING (integer) EBCDIC MIXED
CHAR UNICODE BIT
VARCHAR (1M))
CHARACTER LARGE OBJECT
CHAR (integer ) CCSID ASCII FOR SBCS DATA
CLOB K EBCDIC MIXED
M UNICODE
G
(1)
GRAPHIC
(integer) CCSID ASCII
VARGRAPHIC ( integer ) EBCDIC
(1M) UNICODE
DBCLOB
(integer )
K
M
G
(1)
BINARY
(integer)
BINARY VARYING (integer)
VARBINARY
(1M)
BINARY LARGE OBJECT
BLOB (integer )
K
M
G
DATE
TIME
TIMESTAMP
266 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 15-4 shows the last part of the CREATE PROCEDURE syntax with the option list.
DETERMINISTIC RESULT SETS integer DISALLOW DEBUG MODE PARAMETER CCSID ASCII
ALLOW DEBUG MODE PARAMETER CCSID EBCDIC
DEBUG MODE PARAMETER CCSID
UNICODE
ASUTIME NO
LIMIT
QUALIFIER schema-name PACKAGE authorization-name ASUTIME LIMIT integer
OWNER
COMMIT ON RETURN NO INHERIT SPECIAL REGISTERS STOP AFTER SYSTEM DEFAULT
FAILURES
COMMIT ON RETURN YES DEFAULT SPECIAL REGISTERS STOP AFTER integer FAILURES
CONTINUE AFTER FAILURE
WLM ENVIRONMENT FOR DEBUG MODE name DEFER PREPARE CURRENT DATA YES DEGREE ANY
NODEFER PREARE
DYNAMICRULES RUN WITHOUT EXPLAIN
In comparison to what we had and still have for external SQL procedures, the most keywords
were added to the part shown in Figure 15-4. In this section, we only cover those keywords
that are new or have some changed rules. Additionally, most of the parameters are basically
the same as those used in BIND and REBIND. Refer to either DB2 Version 9.1 for z/OS SQL
Reference, SC18-9854, or DB2 Version 9.1 for z/OS Command Reference, SC18-9844, for a
more detailed description of those commonly used options.
VERSION
This specifies the version identifier for the first version of the procedure that is to be
generated. A routine-version-id can be up to 124 UTF-8 bytes. You can use an ALTER
PROCEDURE statement with the ADD VERSION clause or the BIND DEPLOY command to
create additional versions of the procedure. V1 is the default version identifier. Refer to
15.3.7, “ALTER PROCEDURE syntax” on page 296, to learn more about adding versions.
Important: If you use either ALLOW DEBUG MODE or DISALLOW DEBUG MODE, you
must have specified a valid value for WLMENV in DSNTIJUZ. You should also make sure
that your WLM environment is set up properly so that debugging really can be invoked. You
have to provide a valid value for the WLMENV in the DSNZPARM even if you specify
DISALLOW DEBUG MODE on your CREATE statement, because with ALTER
PROCEDURE you have the chance to switch between ALLOW and DISALLOW later on. If
you already know for sure at creation time that you are not going to use debugging at all,
you should use the DISABLE DEBUG MODE option.
QUALIFIER schema-name
Use this keyword to specify the implicit qualifier that is used for unqualified names of tables,
views, indexes, and aliases that are referenced in the procedure body. The default value is the
same as the default schema.
268 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Note: As for every other stored procedure, you must have the appropriate authority for the
WLM application environment to define a procedure that is to run in a specified WLM
application environment.
Do not specify WLM ENVIRONMENT FOR DEBUG MODE when DISABLE DEBUG MODE is
specified.
If WLM ENVIRONMENT is specified for native SQL procedures without the FOR DEBUG
keywords, an error is issued. This means that if one of the forms of the WLM ENVIRONMENT
clause supported for external SQL procedures is specified (WLM ENVIRONMENT name or
WLM ENVIRONMENT (name,*)), then an error is issued. If WLM ENVIRONMENT is
specified for a native SQL procedure, WLM ENVIRONMENT FOR DEBUG must be specified.
CURRENT DATA
This specifies whether to require data currency for read-only and ambiguous cursors when
the isolation level of cursor stability is in effect. CURRENTDATA also determines whether
block fetch can be used for distributed, ambiguous cursors.
DEGREE
This specifies whether to attempt to run a query using parallel processing to maximize
performance.
DYNAMICRULES
This specifies the values that apply, at runtime, for the following dynamic SQL attributes:
The authorization ID that is used to check authorization
The qualifier that is used for unqualified objects
The source for application programming options that DB2 uses to parse and semantically
verify dynamic SQL statements
Whether dynamic SQL statements can include GRANT, REVOKE, ALTER, CREATE,
DROP, and RENAME statements
In addition to the value of the DYNAMICRULES clause, the runtime environment of a native
SQL procedure controls how dynamic SQL statements behave at runtime. The combination
of the DYNAMICRULES value and the runtime environment determines the value for the
dynamic SQL attributes. That set of attribute values is called the dynamic SQL statement
behavior. The following values can be specified:
RUN This specifies that dynamic SQL statements are to be processed using
run behavior. RUN is the default.
BIND This specifies that dynamic SQL statements are to be processed using
bind behavior.
DEFINEBIND This specifies that dynamic SQL statements are to be processed using
either define behavior or bind behavior.
DEFINERUN This specifies that dynamic SQL statements are to be processed using
either define behavior or run behavior.
ISOLATION LEVEL
This specifies how far to isolate the procedure from the effects of other running applications.
KEEP DYNAMIC
This specifies whether DB2 keeps dynamic SQL statements after commit points.
OPTHINT
This specifies whether query optimization hints are used for static SQL statements that are
contained within the body of the procedure.
SQL PATH
This specifies the SQL path that DB2 uses to resolve unqualified user-defined distinct type,
function, and procedure names in the procedure body. The default value is SYSIBM,
SYSFUN, SYSPROC, and procedure-schema, where procedure-schema is the schema
qualifier for the procedure that is the target of the statement.
RELEASE AT
This specifies when to release resources that the procedure uses: either at each commit point
or when the procedure terminates.
REOPT
This specifies whether DB2 will determine the access path at runtime by using the values of
SQL variables or SQL parameters, parameter makers, and special registers.
270 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
The DB2 subsystem rechecks for the objects and privileges at runtime
for those SQL statements that failed the checks during processing of
the CREATE PROCEDURE statement. The authorization checks the
use of the authorization ID of the owner of the procedure. VALIDATE
RUN is the default.
VALIDATE BIND This specifies that if needed objects or privileges do not exist at the
time the CREATE PROCEDURE statement is processed, an error is
issued and the CREATE PROCEDURE statement fails.
ROUNDING
This specifies the desired rounding mode for manipulation of DECFLOAT data. The default
value is taken from the DEFAULT DECIMAL FLOATING POINT ROUNDING MODE in DECP.
DEC_ROUND_CEILING
This specifies that numbers are rounded towards positive infinity.
DEC_ROUND_DOWN
This specifies that numbers are rounded towards 0 (truncation).
DEC_ROUND_FLOOR
This specifies that numbers are rounded towards negative infinity.
DEC_ROUND_HALF_DOWN
This specifies that numbers are rounded to nearest. If equidistant, round down.
DEC_ROUND_HALF_EVEN
This specifies that numbers are rounded to nearest. If equidistant, round so that the final
digit is even.
DATE FORMAT
This specifies the date format for result values that are string representations of date or time
values.
TIME FORMAT
This specifies the time format for result values that are string representations of date or time
values.
Compatibilities
For compatibility with previous versions of DB2, you can still specify the clauses listed below.
DB2 will ignore those statements and issue SQLCODE +434 as a warning.
LANGUAGE SQL
STAY RESIDENT
PROGRAM TYPE
RUN OPTIONS
NO DBINFO
COLLID or NO COLLID
SECURITY
Note: If you specify WLM ENVIRONMENT wlmname without the FOR DEBUG keyword,
DB2 issues an error SQLCODE.
In addition to the above-mentioned keywords that DB2 ignores, you can continue to use the
following:
For the DYNAMIC RESULT SETS keyword, you can also:
– Omit the DYNAMIC keyword.
– Use SET instead of SETS.
For DETERMINISTIC you can use NOT VARIANT instead.
For NOT DETERMINISTIC you can use VARIANT instead.
For CALLED ON NULL INPUT, NULL CALL can be used.
To illustrate the usage of a FOR loop construct consider the SQL statement in Example 15-7,
which calculates the sum of the salaries of all employees in a table.
Utilizing the FOR SQL statement, an equivalent result can be obtained with the native SQL
procedure in Example 15-8.
272 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
END#
Note: You always have to be aware that rewriting statements might result in a performance
decrease because it could invalidate some internal processing capabilities.
Example 15-9 is a bit more complex. It shows a native SQL procedure that receives an owner
authorization ID as input parameter. A query on the DB2 catalog table
SYSIBM.SYSPACKAGE then retrieves all package names that are associated to this ID. A
FOR loop then iterates over all these qualifying packages and tries to rebind them. For the
actual rebind the DB2 supplied stored procedure ADMIN_COMMAND_DSN is called from
within the FOR loop. The message parameter that is populated by ADMIN_COMMAND_DSN
is finally passed back to the caller as output parameter of the REBIND_PACKAGES
procedure.
Example 15-10 shows another native SQL procedure that implements the FOR loop
construct. The basic idea here is that the procedure checks whether all values in a column of
type INTEGER feature the same value. If this is true, then the value is returned in the output
parameter; otherwise, NULL is returned.
For completeness, the FOR statement syntax diagram is attached in Figure 15-5. For detailed
parameter explanations, refer to DB2 Version 9.1 for z/OS SQL Reference, SC18-9854.
FOR
label: for-loop-name AS W ITHOUT HOLD
cursor-name CURSOR FOR
W ITH HOLD
Extended GOTO
Native SQL procedures provide support for an extended version of the GOTO statement. This
statement now allows for branching out (upwards) of the current compound statement to
different levels within the same scope. There are two major restrictions on the target label that
you need to be aware of:
If the GOTO statement is in a condition handler, the target label must be defined in that
condition handler as well.
If the GOTO statement is not in a condition handler, the target label must not be defined in
a condition handler.
Example 15-11 depicts a case where the GOTO statement branches out of the current
compound statement to a label defined at a higher level.
LAB1: SET A = 1;
BEGIN
274 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
LAB2: SET A = 2;
BEGIN
SET I = I + 1;
IF I < 3 THEN GOTO LAB1;
END IF;
END;
END;
END P1#
Note: When a GOTO statement branches out of a compound statement, all open cursors
that are declared in the compound statement that contains the GOTO are closed. The only
exception are cursors that return a result set. The same holds for nested compound
statements.
Example 15-12 declares cursors at multiple levels. The GOTO statement branches out of the
compound statement labelled L1. Therefore, all cursors that are defined within this compound
statement (C1, C2, and C3) are closed.
Tip: Using GOTO is usually considered a bad programming practice and should be
avoided. In general, it decreases the readability of code, and makes it harder to maintain.
Up to DB2 V8, the body of an SQL procedure could contain only a single compound
statement, which could contain other SQL statements, except for another compound
statement, or a single SQL procedure statement other than the compound statement. Thus,
A compound statement is easily recognized as starting and ending with the keywords BEGIN
and END. You can provide a label on the BEGIN statement to identify the code block.
You can use this label to qualify names of SQL variables that are defined in a compound
statement, while cursor names must be unique within a procedure. These labels are very
useful with nested compound statements. It is possible that you have an SQL procedure that
contains both nested compound statements and compound statements that are at the same
level. Figure 15-6 illustrates a possible outline of an SQL procedure that consists of the
compound statement OUTERMOST, which contains two other compound statements,
INNER1 and INNER2. Additionally, the INNER1 compound statement contains another
compound statement, INNERMOST.
276 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
nested can have the same name. Also, a label must not be the same as the name of the
procedure.
You can reference a label in another statement such as the GOTO, LEAVE, and ITERATE
SQL Procedure language control statements. A label can only be referenced in the compound
statement in which it is defined, including any compound statements that are nested in that
compound statement.
Example 15-13 shows a very simple native SQL procedure, SCOPELAB, that implements
labels in nested compound statements. The procedure features an integer variable named
FLAG as INOUT parameter. The outermost compound statement is labelled OUTER1 and
contains two further compound statement labels INNER1 and INNER 2 which are on the
same nesting level. The SQL comments indicate the flow of the logic in the procedure which
is determined by the input value of the FLAG parameter.
If a FLAG features a value of 1, the code traverses to the statement labelled ABC, which then
makes the program flow exit the INNER1 label scope. Next the INNER2 scope is entered, and
the command with label XYZ executed. In this case, the procedure returns a value of 5 to the
caller. In case the SQL procedure is invoked with a value of 2 in the FLAG parameter, label
XYZ in the INNER1 label scope, jumps out of the OUTER1 scope which at the same time
ends the procedure. A value of 2 is returned here.
Notice that the XYZ label is defined twice. This is valid, because both are in different scopes
on the same nesting level.
Figure 15-7 illustrates the use of statement labels and their scope. As you can see, a
reference to OUTER 1 from inside the INNER1 compound statement is okay, because label
OUTER1 is on a higher level than INNER1. In contrast to that, the statement of label NOWAY
is not allowed and leads to an error, because the target label INNER2 is not within the scope
of the LEAVE statement.
Let us have a look at more examples to get used to what is allowed and what is not allowed
with regards to usage of labels in nested compound statements. See Figure 15-8.
L1: BEGIN
L2: SET A = B;
Duplicate use of label L1
L1: GOTO L2; => ERROR
END L1;
L1: BEGIN
L2: BEGIN
L4: BEGIN
DECLARE A CHAR (5); Duplicate use of label L4,
SET A = B; BUT not in the same scope
END L4; => OK
END L2;
L3: BEGIN
L4: BEGIN
DECLARE A CHAR (5);
SET A = B;
END L4;
END L3;
END L1;
In the upper part of Figure 15-8, the use of label L1 is invalid, because it is in the same scope
as the outer label L1. The correct usage of nested labels is shown in the lower part of
Figure 15-8. Here we used label L4 twice as well, but since they are not in the same scope,
you do not receive an error in this case.
278 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
In general, labels for compound statements are useful to avoid conflicts with column names in
SQL statements. A developer should always use the qualified variable name, as shown in
Example 15-14. Here, using the unqualified name SALARY would cause an ambiguity
problem, which could lead to undesired side effects when calling the procedure.
When you use non-unique variable names in an SQL stored procedure, each SQL variable
must be declared within a different scope. An SQL variable name must be unique in the
compound statement in which it is declared, excluding any declarations in compound
statements that are nested within that compound statement. Following this, an SQL variable
can only be referenced in the compound statement in which it is declared, including any
compound statements that are nested within that compound statement. When there is a
reference to an unqualified SQL variable name, the variable can be declared within the
compound statement that contains the reference, or within a compound statement in which
that compound statement is nested. In this case, DB2 uses the declaration of a variable by
that name in the innermost compound statement.
If multiple variables with the same name exist in the stored procedure and there is an
unqualified reference to the variable name, the name may not be interpreted as intended,
because it resolves to the most local definition. For this reason we recommend that you
always qualify the SQL variable with the name as the label from the compound statement in
which it was declared.
Example 15-15 shows a stored procedure that implements some techniques for scoping
variable declarations. It basically returns a value in the FLAG parameter, which is dependent
on its input value. In case the procedure is invoked with FLAG = 1, a value of 300 is returned.
For FLAG = 2, NULL is returned, and for FLAG = 3, a value of 100 is returned to the caller.
The outermost block of the procedure is labelled OUTER1. It contains two further nested
compound blocks INNER1 and INNER2 which are on the same nesting level.
INNER2: BEGIN
DECLARE A INTEGER DEFAULT NULL;
DECLARE Z INTEGER DEFAULT NULL;
SET A = A + OUTER1.A; -- NULL + 100 = NULL
IF FLAG = 2 THEN
SET FLAG = A; -- FLAG = NULL
END IF;
END INNER2;
-- END OF INNER COMPOUND STATEMENT INNER2 -------
IF FLAG = 3 THEN
SET FLAG = A; -- FLAG = 100
-- A REFERENCES HERE THE OUTER1.A
END IF;
END OUTER1#
The variable A is declared in the OUTER1 block. In the nested INNER1 compound statement,
another variable A is declared. Both variables A are visible and accessible for statements
within the INNER1 compound statement, and can be distinguished by using the respective
labels as prefix. If no label prefix is specified, the declaration of the innermost nesting is used.
For example, the unqualified variable A in the following statement in the INNER1 block,
SET A = A + OUTER1.A
is equivalent to specifying INNER1.A. The latter should be preferred because this improves
the readability of the code. As indicated with a comment, the following statement would cause
an error when defined in the INNER1 block:
280 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
This is because INNER1 and INNER2 are at the same nesting level. Therefore a local
variable defined in the INNER2 scope is not visible from within the INNER1 scope and thus
cannot be referred to. However, the variable A in the OUTER1 scope is visible to both
compound statements INNER1 and INNER2 and hence can be accessed.
As indicated in the comment, the following statement would also result in an error.
This is because a variable from within the scope of INNER1 is requested, which is no longer
valid.
The following unqualified statement to a variable A refers to its declaration in the OUTER1
scope:
SET FLAG = A;
Here both inner compound statement scopes INNER1 and INNER2 are no longer active.
Note: DECLARE statements always have to appear directly after the BEGIN statement.
Therefore, compound statements are very useful, especially in large SQL procedures, to
bring variable declarations close to their usage. This means that you can avoid declaring
all your variables up front in the procedure.
A cursor name remains a single part name as in previous releases. That means a cursor
name must be unique within the stored procedure, even when compound statements are
used.
However, any cursor that is declared in an SQL procedure as a result set cursor (that is, the
WITH RETURN clause was specified as part of the cursor declaration) can be referenced by
the calling application. This is true even for the case where the cursor is not declared in the
outermost compound block of the procedure.
INNER1: BEGIN
DECLARE Y CURSOR WITH RETURN FOR -- INNER DECLARATION FOR Y
END OUTER1#
Example 15-16 defines two cursors, X and Y. X is accessible and visible in the OUTER1 and
INNER1 block, whereas Y is only valid within the INNER1 block. Cursor X is opened and rows
are fetched from it inside of the INNER1 block. Accessing Y from within the OUTER1 block
would result in an error as indicated by the comments. Notice also that the calling application
can access the result set associated with X, although the OPEN statement is not performed in
the outermost compound statement.
The stored procedure shown in Example 15-17 deletes certain database objects that are
associated with an ownerid specified in one of the input parameters. The object types to be
deleted are either triggers, sequences, or distinct types. The procedure keeps track of the
successfully dropped objects by inserting the respective names in a table MYRESULT.
Several nested compound statements are employed that allow for structuring the procedure
code. Notice that the cursor is not defined in the outermost block, but closer to its utilization in
the GET_OBJ block. As shown in the sample, it is possible to first construct a SELECT
statement as a string, prepare it, and later on declare and open the cursor on it. Since
DECLARE statements always have to appear at the beginning of a block, the nested
compound statement GET_OBJ has been injected.
VERSION V1
LANGUAGE SQL
MODIFIES SQL DATA
MAIN: BEGIN
DECLARE SELSTMT VARCHAR(256);
DECLARE TABNAME VARCHAR(128);
DECLARE OBJTYPE VARCHAR(32);
DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
DECLARE SQLCODE INTEGER DEFAULT 0;
282 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
SET TABNAME = 'SYSIBM.SYSSEQUENCES';
SET OBJTYPE = 'SEQUENCE';
ELSEIF (TYPE = 'T') THEN
SET TABNAME = 'SYSIBM.SYSTRIGGERS';
SET OBJTYPE = 'TRIGGER';
ELSEIF (TYPE = 'D') THEN
SET TABNAME = 'SYSIBM.SYSDATATYPES';
SET OBJTYPE = 'TYPE';
END IF;
GET_OBJ: BEGIN
DECLARE OBJNAME VARCHAR(128);
DECLARE OBJSCHEMA VARCHAR(128);
DECLARE C1 CURSOR FOR SQLSTMT;
OPEN C1;
FETCH_LOOP:
LOOP
FETCH C1 INTO OBJSCHEMA, OBJNAME;
IF (SQLCODE <> 0) THEN
-- NO MORE ELEMENT FOUND EXIT LOOP
LEAVE FETCH_LOOP;
END IF;
DRP_OBJ:
BEGIN
-- THIS SECTION DROPS THE ASSOCIATED OBJECT
DECLARE DRPSTMT VARCHAR(256);
SET DRPSTMT = 'DROP ' || OBJTYPE || ' ' ||
OBJSCHEMA || '.' || OBJNAME;
EXECUTE IMMEDIATE DRPSTMT;
INSERT INTO MYRESULT
VALUES ('DROPPED '||OBJSCHEMA||'.'||OBJNAME);
END DRP_OBJ;
END GET_OBJ;
SET RES = 'Objects successfully removed';
END MAIN!
As for cursor names, a condition name remains a single part name as in previous releases.
When multiple conditions are defined with the same name there is no way to explicitly refer to
the condition that is not the most local in scope. Any reference to a non-unique condition
name is an implicit reference to the innermost declaration of a condition of that name.
SIGNAL ABC;
-- (3) SIGNAL ABC HERE IS INTERPRETED AS REFERRING
-- TO THE CONDITION NAMED ABC THAT IS
-- DECLARED IN THE OUTERMOST BLOCK.
END OUTER1#
Example 15-19 shows an SQL procedure that issues a DROP statement on a table name,
which has been provided by an input parameter of a procedure. The procedure implements a
condition handler that is triggered if the provided table name does not exist, and thus the
DROP would result in an error. The handler implements a compound statement which
prepares a string to return from the procedure, as well as writes further debug information into
a predefined table MYRESULT.
284 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
DECLARE SQLCODE INTEGER DEFAULT 0;
DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
DECLARE NO_TABLE CONDITION FOR SQLSTATE '42704';
A: BEGIN -- (1)
DECLARE DRPSTMT VARCHAR(256);
DECLARE EXIT HANDLER FOR NO_TABLE -- (3)
BEGIN -- (4)
SET OUT_BUFFER = 'ERROR DURING DROP TABLE';
INSERT INTO MYRESULT
VALUES ('TABLE '||TABNAME||' DOES NOT EXIST');
END;
The declaration specifies the condition that activates the condition handler, the type of the
condition handler (CONTINUE or EXIT), and the handler action. The type of the condition
handler determines where control is returned to after successful completion of the handler
action.
The scope of the declaration of a condition handler is the compound statement in which it is
declared, including any compound statements that are nested within that compound
statement. A condition handler declared in a compound statement can handle a condition that
is encountered in a compound statement that is enclosed within this compound statement if
the condition is not handled at a lower level. However, a condition handler declared in an inner
scope takes precedence over a condition handler defined to handle the same condition in an
outer scope, even if the condition handler declared in an outer compound statement is more
specific than a condition handler that is declared in an inner scope.
A condition handler is activated when it is the most appropriate condition handler for a
condition that has been encountered. The most appropriate handler is the condition handler
that most closely matches the SQLSTATE of the exception or completion condition.
Example 15-20 reconsiders the procedure SCOPECUR2 from Example 15-17 and augments
it with two condition handler declarations. One condition handler is declared in the outermost
block MAIN and catches general SQLExceptions. The procedure SCOPECUR2 would have
VERSION V1
LANGUAGE SQL
MODIFIES SQL DATA
MAIN: BEGIN
DECLARE SELSTMT VARCHAR(256);
DECLARE TABNAME VARCHAR(128);
DECLARE OBJTYPE VARCHAR(32);
DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
DECLARE SQLCODE INTEGER DEFAULT 0;
-- Declare a general SQL error condition handler
DECLARE EXIT HANDLER FOR SQLEXCEPTION
SET RES = 'SQL ERROR, SQLCODE= ' || CHAR(SQLCODE) ||
' SQLSTATE= ' || SQLSTATE;
GET_OBJ: BEGIN
DECLARE OBJNAME VARCHAR(128);
DECLARE OBJSCHEMA VARCHAR(128);
DECLARE C1 CURSOR FOR SQLSTMT;
-- Error handling for the Fetch Loop
DECLARE EXIT HANDLER FOR NOT FOUND
CLOSE C1;
286 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
OPEN C1;
FETCH_LOOP:
LOOP
FETCH C1 INTO OBJSCHEMA, OBJNAME;
DRP_OBJ:
BEGIN
-- THIS SECTION DROPS THE ASSOCIATED OBJECT
DECLARE DRPSTMT VARCHAR(256);
SET DRPSTMT = 'DROP ' || OBJTYPE || ' ' ||
OBJSCHEMA || '.' || OBJNAME;
EXECUTE IMMEDIATE DRPSTMT;
INSERT INTO MYRESULT
VALUES ('DROPPED '||OBJSCHEMA||'.'||OBJNAME);
END DRP_OBJ;
END GET_OBJ;
SET RES = 'Objects successfully removed';
END MAIN!
As shown in Figure 15-9, if exception condition exception1 is raised in the body of the
condition handler for exception0, there is no appropriate handler. In this case the procedure is
terminated because of the unhandled exception condition.
Note: Note that the condition handler defined for exception1 is not within the scope of the
condition handler for exception0. Condition handlers that are declared in the same
compound statement cannot handle conditions encountered in each other or in
themselves. The scope of a condition handler includes the compound statement in which it
is declared, but excludes the bodies of other condition handlers declared in the same
compound statement.
For more information about how the names of these items are resolved, see the topic
“References to SQL parameters and SQL variables” in DB2 Version 9.1 for z/OS SQL
Reference, SC18-9854. The rules used for name resolution in external SQL procedures
remain unchanged.
288 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
There is one difference in the name resolution in native and external stored procedures that
we need to explicitly mention. Assume that we have a procedure body that looks like that
shown in Figure 15-10.
Figure 15-10 Name resolution in external and native SQL stored procedures
In the given situation, there is a difference between external and native SQL procedures in
the way dept is resolved:
External SQL stored procedures match this dept to the SQL variable in the declare
statement.
Native SQL stored procedures and SQL stored procedures on LUW and iSeries interpret
this dept as the column name of table emp in the SELECT statement of cursor c1.
Figure 15-11 Better practice with name resolution in external and native SQL stored procedures
SQL variable The compound Yes, it can be The compound statement in which it is declared,
statement in which it is qualified with the including any compound statements that are
declared, excluding any label of the nested within that compound statement. When
declarations in compound multiple SQL variables are defined with the same
compound statements statement in which name you can use a label to explicitly refer to a
that are nested within the variable was specific variable that is not the most local in scope.
that compound declared.
statement.
Example 15-21 illustrates the use of an empty compound statement as a way of ignoring a
condition. This might be useful when you are inserting a row into a table that has a unique
column, and if the value to be inserted for the row already exists in the table, then the row
does not need to be inserted. Although DB2 will detect the case where the value to be
inserted is not unique, there is no need to tell the application about this. Instead, the INSERT
statement will not be processed.
290 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Example 15-21 Empty compound statement
DECLARE CONTINUE HANDLER FOR '23505'
BEGIN -- ignore error for duplicate value
END;
Restriction: XML, UDTs, ROWIDs, LOB locators, and LOB file references are not yet
supported.
15.3 Versioning
In V9, the option VERSION is added in the CREATE PROCEDURE and ALTER
PROCEDURE statements for native SQL procedures. This means that multiple versions can
be created or added for one stored procedure. Any version can be “promoted” to be the active
version, but only one can be the current, active version for one procedure. By default, the
current active version will be the one to run when the stored procedure is called.
Maintaining existing and adding additional versions is implemented with the help of the
ALTER PROCEDURE statement. You can embed this statement in an application program or
issue it interactively. It is an executable statement that can be dynamically prepared only if
DYNAMICRULES run behavior is implicitly or explicitly specified. If your ALTER statement
contains either a REPLACE VERSION or a ADD VERSION clause, the statement can only be
dynamically prepared.
Tip: If you create the following SQL procedures in SPUFI, make sure the proper settings
for SQLFORMAT and SQLTERM are performed, as described in “SQL FORMAT on SPUFI
defaults panel” on page 261.
VERSION routine-version-id
routine-version-id is the version identifier that is assigned when the version is defined. This
must identify a version of the specified procedure that exists at the current server. The
version ID is an SQL identifier of up to 124 UTF-8 bytes. See Example 15-24.
292 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
READS SQL DATA
DYNAMIC RESULT SETS 1
BEGIN
DECLARE V_NUMRECORDS INTEGER DEFAULT 1;
DECLARE V_COUNTER INTEGER DEFAULT 0;
DECLARE C1 CURSOR FOR
SELECT SALARY FROM STAFF ORDER BY SALARY;
DECLARE C2 CURSOR WITH RETURN FOR
SELECT NAME, JOB, SALARY
FROM STAFF
WHERE SALARY <= MEDIANSALARY
ORDER BY SALARY;
DECLARE EXIT HANDLER FOR NOT FOUND
SET MEDIANSALARY = 0;
SELECT COUNT(*) INTO V_NUMRECORDS FROM STAFF;
OPEN C1;
WHILE V_COUNTER < (V_NUMRECORDS / 2 + 1) DO
FETCH C1 INTO MEDIANSALARY;
SET V_COUNTER = V_COUNTER + 1;
END WHILE;
CLOSE C1;
OPEN C2;
END#
Example 15-25 basically adds the new version MEDIAN_V2 to the existing SQL procedure. In
addition to this the selection criterion for the returned result set is changed as well. The two
DB2 catalog tables SYSIBM.SYSROUTINES and SYSIBM.SYSPARMS each now contain
two rows for the procedure MEDIAN_RESULT_SET, one for MEDIAN_V1 and the other for
MEDIAN_V2.
In order to make MEDIAN_V2 the active version, which is then used in the next CALL
statement, a second ALTER statement with the ACTIVATE option has to be executed:
ALTER PROCEDURE MEDIAN_RESULT_SET ACTIVATE VERSION MEDIAN_V2#
Note: A way to interactively specify the version to be executed is to employ the special
register CURRENT ROUTINE VERSION. If set, this register overrides the setting in the
ACTIVE column in the SYSROUTINES catalog table. In the section about stored
procedure execution, more details are provided.
REGENERATE automatically rebinds, at the local server, the package for the SQL control
statements for the procedure and rebinds the package for the SQL statements that are
included in the procedure body. If a remote bind is also needed, you must explicitly use the
BIND PACKAGE COPY command for all of the remote servers.
The following command causes the regeneration of the active version of the
MEDIAN_RESULT_SET procedure, which is still MEDIAN_V2:
ALTER PROCEDURE MEDIAN_RESULT_SET
REGENERATE ACTIVE VERSION#
Note: REGENERATE is different from a REBIND PACKAGE in the sense that the REBIND
PACKAGE command implies the generation of possibly better access paths for the
embedded SQL statements. REGENERATE only affects the SQL control statements in the
procedure definition. These stay the same for a REBIND PACKAGE.
294 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
SET MEDIANSALARY = 0;
SELECT COUNT(*) INTO V_NUMRECORDS FROM STAFF;
OPEN C1;
WHILE V_COUNTER < (V_NUMRECORDS / 2 + 1) DO
FETCH C1 INTO MEDIANSALARY;
SET V_COUNTER = V_COUNTER + 1;
END WHILE;
CLOSE C1;
END GET_MEDIAN;
OPEN C2;
END MAIN#
Example 15-27 employs the ALTER statement to drop version MEDIAN_V1. MEDIAN_V2
cannot be dropped because this is the currently active procedure version.
When only a single version of the procedure exists at the current server, you can use the
DROP PROCEDURE statement to drop the procedure. A version of the procedure for which
the version identifier is the same as the contents of the CURRENT ROUTINE VERSION
special register can be dropped if that version is not the currently active version of the
procedure.
A LT E R P R O C E D U R E p ro c e d u re -n a m e
A LT E R A C T IV E
V E R S IO N o p t io n - lis t
V E R S IO N r o u t in e - v e r s io n - id
A C T IV E
R EPLACE V E R S IO N r o u t in e - s p e c if ic a t io n
V E R S IO N r o u t in e - v e r s io n - id
A D D V E R S IO N r o u t in e - v e r s io n - id r o u t in e - s p e c if ic a t io n
A C T IV E V E R S IO N r o u t in e - v e r s io n - id
A C T IV E
REGENERATE V E R S IO N
V E R S IO N r o u t in e - v e r s io n - id
DROP V E R S IO N r o u t in e - v e r s io n - id
S Q L - r o u t in e - b o d y
(1 ) o p t io n - lis t
( )
,
p a r a m e t e r - d e c la r a t io n
N o te s :
1. A ll v e r s io n s o f th e p r o c e d u r e m u s t h a v e th e s a m e n u m b e r o f p a r a m e te r s
p a ra m e te r -d e c la r a tio n :
IN
p a ra m e te r - n a m e b u ilt - in - t y p e
OUT
IN O U T
296 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 15-13 shows the continuation of the ALTER PROCEDURE statement with the built-in
type.
SMALLINT
INTEGER
INT
BIGINT
(5.0)
DECIMAL
DEC (integer )
NUMERIC , integer
(53)
FLOAT
(integer)
REAL
PRECISION
DOUBLE
(34)
DECFLOAT
(16)
(1)
CHARACTER
CHAR (integer) FOR SBCS DATA CCSID ASCII
CHARACTER VARYING (integer) MIXED EBCDIC
CHAR BIT UNICODE
VARCHAR (1M))
CHARACTER LARGE OBJECT
CHAR (integer ) FOR SBCS DATA CCSID ASCII
CLOB K MIXED EBCDIC
M UNICODE
G
(1)
GRAPHIC
(integer) CCSID ASCII
VARGRAPHIC (integer) EBCDIC
(1M) UNICODE
DBCLOB
(integer )
K
M
G
(1)
BINARY
(integer)
BINARY VARYING (integer)
VARBINARY
(1M)
BINARY LARGE OBJECT
BLOB (integer )
K
M
G
DATE
TIME
TIMESTAMP
Most of the options are the same as described at “CREATE PROCEDURE syntax” on
page 265.
ASUTIME NO LIMIT
VALIDATE RUN
298 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
15.4 Execution of a native SQL procedure
With V9 new function mode, when you create a native SQL stored procedure, its procedural
statements are now converted to a native representation that is stored in the DB2 catalog and
directory, as is done with other SQL statements. The parameter list and procedure options
are stored in the database catalog tables as in the prior releases. When you call a native SQL
procedure, DB2 loads the native representation from the catalog and the DB2 engine
executes the procedure.
Figure 15-15 depicts the DB2 components involved when a native SQL procedure is called
either from a remote application, a DB2 attached program, or an allied address space
respectively. As illustrated, the SQL statements are no longer executed in an external WLM
address space but natively in the database system services address space. For execution,
the procedure packages are loaded into the EDM pool.
SP1 or
SQL PL native logic CALL SP1
SQL
SQL
EDM pool
Once the correct procedure has been resolved, the current active version is determined. Only
one active version of a native SQL procedure exists at any point in time. By default the current
active version is the version that contains a flag Y in the ACTIVE column of the catalog table
SYSIBM.SYSROUTINES. Any version that exists for a native SQL procedure can be
“promoted” to be the active version with the ACTIVATE VERSION option of the ALTER
statement. To default the execution of the procedure MEDIAN_RESULT_SET to version
MEDIAN_V2, the following command can be used:
When the stored procedure is now invoked via the SQL CALL statement, the second version
(MEDIAN_V2) is called and executed. Example 15-28 shows a small Java excerpt that
executes the SQL procedure:
cstmt.registerOutParameter(1, Types.INTEGER);
For ad hoc testing of a specific version, a new special register called CURRENT ROUTINE
VERSION is provided. If an application sets this register to an existing valid version, it
temporarily overrides the setting in column ACTIVE of the SYSIBM.SYSROUTINES catalog
table. If the provided value is not valid, the default catalog settings are used. The subsequent
CALL to the stored procedure has to be dynamically prepared, otherwise the register is not
taken into account. This is mainly because a static CALL to the native SQL procedure already
has the version identifier bound to in the respective package.
Example 15-29 makes use of the CURRENT ROUTINE VERSION register to invoke the
version MEDIAN_V1 for the subsequent CALL to the procedure.
CallableStatement cstmt =
con.prepareCall("CALL PAOLOR3.MEDIAN_RESULT_SET(?)");
cstmt.registerOutParameter(1, Types.INTEGER);
Tip: When you use the CURRENT ROUTINE VERSION special register to test a version
of one or more native SQL procedures, you should use a routine version identifier that is a
value other than the default value (V1) on the CREATE PROCEDURE statement. This will
avoid having the special register affect more procedures than you intend when testing a
new version of a procedure. For example, assume that you want to run version VER2 of
procedure P1, and procedure P1 invokes another procedure, P2. If a version exists for both
procedures P1 and P2 with the routine version identifier VER2, that version will be used for
both procedures.
To fall back to the default version specified in the catalog, just set this register to an empty
string constant. The register’s value is not cached in the catalog, that is, in case the thread
which set this value terminates, the register’s content is no longer accessible and the default
catalog value determines the current version.
300 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Tip: If you do not want to write an application program for calling your stored procedure,
you can do this via the Developer Workbench, which comes with DB2 9 for LUW and the
DB2 for z/OS Client Management Package and replaces the Development Center. This
tool is used to handle similar development and testing functionality for DB2 UDB V8 for
LUW.
The DB2 enhanced support for deployment of native SQL procedures is useful if you want to
install a native SQL procedure to a production system after it has been tested well on the test
system. This can now be done via the extended BIND PACKAGE command featuring the new
keyword DEPLOY.
Deployment is different from remote BIND package, because the logic of the procedure body
(stored as a special section in the package) will not be re-bound. That means you do not need
to worry about unexpected behavior change after the deployment.
You can use DEPLOY when the target DB2 subsystem is also a DB2 for z/OS subsystem that
is operating with a compatible PTF level. If the PTF level is not compatible, SQLCODE -20249
is issued.
If you specify ACTION(ADD) for a version that does not exist at the target location, DB2
creates or adds a new version of the native SQL procedure and its associated package while
keeping the source native SQL procedure’s logic. DB2 adds a new version if a native SQL
procedure with the same target name already exists.
If you specify ACTION(REPLACE), DB2 replaces the version specified in COPYVER. If you
specify REPLVER, the version ID must be the same as the COPYVER version ID or DB2
returns TSO error message DSNE977E.
For the example shown in the next few figures starting with Figure 15-16, we used SANJOSE
as the name of the current server and BERLIN as the name of the remote server.
Notice that the schema name used becomes the collection-id of the package. At the same
time the procedure name also becomes the package-id itself. This is important in the
following deployment step.
The next step in the deployment process is to create a new SQL procedure for the production
environment on a remote DB2 subsystem, named
BERLIN.PRODUCTION.MEDIAN_RESULT_SET from the existing SQL procedure that we
have just created (that is, SANJOSE.TEST.MEDIAN_RESULT_SET).
As you can see from Figure 15-17 on page 303, both procedures have the same version
MEDIAN_V1. The new procedure schema and at the same time collection-id is
PRODUCTION, whereas the procedure name as well as the package-id stay the same.
Furthermore the procedure BERLIN.PRODUCTION.MEDIAN_V1 has a different qualifier, as
this makes sense for the production environment. The example shown in Figure 15-17 on
page 303 is considered being a remote bind on location BERLIN.
302 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
BIND PACKAGE(BERLIN.PRODUCTION) -
DEPLOY(TEST.MEDIAN_RESULT_SET) -
COPYVER(MEDIAN_V1) -
ACTION(REPLACE) -
QUALIFIER(PAOLOR1)
Figure 15-17 Bind Package statement with DEPLOY option
Refer to the bind statement shown in Figure 15-19, which we used to deploy version
MEDIAN_V2 of procedure SANJOSE.TEST.MEDIAN_RESULT_SET to
BERLIN.PRODUCTION.UPDATE_BALANCE.
In case all procedures in the PAOLOR3 schema are stopped, a different DISPLAY
PROCEDURE(PAOLOR3.*) is obtained. Example 15-31 shows the output after the following
command has been issued:
STOP PROCEDURE(PAOLOR3.*)
304 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Example 15-31 DISPLAY output - all procedures in a schema have been stopped
STC00053 DSNX940I ) DSNX9DIS DISPLAY PROCEDURE REPORT FOLLOWS -
------- SCHEMA=PAOLOR3
DSNX9DIS PROCEDURES A - Z* STOP QUEUE
DSNX9DIS DISPLAY PROCEDURE REPORT COMPLETE
STC00053 DSN9022I ) DSNX9COM '-DISPLAY PROC' NORMAL COMPLETION
Once the SQL procedure is started again, it does not appear in the DISPLAY
PROCEDURE output anymore. See Example 15-32.
A native SQL procedure that is currently being debugged will show under DISPLAY
PROCEDURE command as in ACTIVE state. This is a consequence of the fact that the
procedure that is being debugged is executing in a WLM environment. The WLM
environment is specified in the CREATE PROCEDURE or ALTER PROCDURE statement.
For the procedure MEDIAN_RESULT_SET the following statement has been applied:
WLM ENVIRONMENT FOR DEBUG MODE DB9AWLM ALLOW DEBUG MODE
Example 15-33 contains the DISPLAY PROCEDURE output for a currently debugged
MEDIAN_RESULT_SET procedure. Notice that the WLM_ENV column features a value of
the specified WLM environment DB9AWLM.
REBIND PACKAGE only rebinds the SQL statements that are included in the procedure. The
native representation of the logic part (that is, the control statements in the procedure
definition) is not rebound.
COMMENT ON PROCEDURE
The COMMENT ON PROCEDURE statement has been extended to handle multiple versions
of a procedure. Similar to the ALTER PROCEDURE statement, a distinct procedure version
can be defined with either the ACTIVE VERSION or the VERSION routine-version-id
keyword. Example 15-34 shows how to add a value to the REMARKS columns in
SYSIBM.SYSROUTINES of version MEDIAN_V2.
DROP statement
The SQL DROP statement drops all versions of a SQL procedure as well as all associated
packages (packages that are remotely bound are not dropped). To drop only one existing
version of a procedure, and in addition only the package associated with this version, the
statement ALTER PROCEDURE...DROP VERSION routine-version-id can be used (refer to
15.3.6, “Dropping an existing version” on page 295).
DISALLOW
ALLOW
DISABLE
306 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
The mode options are:
DISALLOW
This specifies that DISALLOW DEBUG MODE is the default option for CREATE
PROCEDURE statements when defining an SQL or Java procedure, or ALTER
PROCEDURE statements that create or replace a version of a native SQL procedure.
ALLOW
This specifies that ALLOW DEBUG MODE is the default option for CREATE
PROCEDURE statements when defining an SQL or Java procedure, or ALTER
PROCEDURE statements that create or replace a version of a native SQL procedure.
DISABLE
This specifies that DISABLE DEBUG MODE is the default option for CREATE
PROCEDURE statements when defining an SQL or Java procedure, or ALTER
PROCEDURE statements that create or replace a version of a native SQL procedure.
For more information on the DEBUG MODE options, refer to 15.2.2, “CREATE PROCEDURE
syntax” on page 265.
A sample illustrating how to work with this register is provided in 15.7, “Error handling and
debugging” on page 308.
host-variable
string-constant
If you want to reset the special register, specify an empty string constant, a string of blanks, or
a host variable that is empty or contains only blanks. A routine version override is not in effect
when the special register is reset.
If you set the CURRENT ROUTINE VERSION special register to a version identifier, it will
affect all SQL procedures that are subsequently invoked using CALL statements that specify
the name of the procedure using a host variable, until the value of CURRENT ROUTINE
VERSION is changed. If a version of the procedure that is identified by the version identifier in
the special register exists for an SQL procedure that is being invoked, that version of the
procedure is used. Otherwise, the currently active version of the procedure (as noted in the
catalog) is used.
A sample showing how to use this register is provided in 15.4, “Execution of a native SQL
procedure” on page 299.
Possible values are ALLOW DEBUG MODE, which basically enables the procedure for
debugging with the Unified Debugger technology, as well as the values DISALLOW or
DISABLE DEBUG MODE that prevent debugging capabilities on this procedure. The major
difference between DISALLOW and DISABLE is that an ALTER PROCEDURE statement can
be used to switch between DISALLOW and ALLOW option. However, once a procedure is
defined with DISABLE DEBUG MODE, it can never be debugged in its lifetime. To change this
status the procedure either has to be dropped and recreated, or a new version has to be
added, since these options have a version granularity. Figure 15-22 depicts the possible state
changes for the DEBUG MODE option. Note that once a procedure version is in DISABLE
state, no transition to another state is possible in the version’s lifecycle.
ALTER to DISALLOW
SQL PL procedures SQL PL procedures
in ALLOW state in DISALLOW state
ALTER to ALLOW
ALTER to ALTER to
DISABLE DISABLE
SQL PL procedures
in DISABLE state
308 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
DECLARE V_COUNTER INTEGER DEFAULT 0;
DECLARE C1 CURSOR FOR
SELECT SALARY FROM STAFF ORDER BY SALARY;
DECLARE C2 CURSOR WITH RETURN FOR
SELECT NAME, JOB, SALARY
FROM STAFF
WHERE SALARY > MEDIANSALARY
ORDER BY SALARY;
DECLARE EXIT HANDLER FOR NOT FOUND
SET MEDIANSALARY = 0;
SELECT COUNT(*) INTO V_NUMRECORDS FROM STAFF;
OPEN C1;
WHILE V_COUNTER < (V_NUMRECORDS / 2 + 1) DO
FETCH C1 INTO MEDIANSALARY;
SET V_COUNTER = V_COUNTER + 1;
END WHILE;
CLOSE C1;
OPEN C2;
END#
Note: The DEBUG MODE DISABLE setting is mainly used for security. A native SQL
procedure that has been created as (or subsequently altered to) DEBUG MODE DISABLE
can never be allowed to be debugged. Note that the ability to debug means the procedure
source would be viewable to step through. It would also mean that SQL variable values
could be changed during the debugging session which could cause data integrity issues.
The purpose of DEBUG MODE DISABLE feature is to protect such unauthorized viewing
of the source code and for the impact of the side effects from the debug sessions, for the
SQL procedures that require such protection.
We recommend to update existing procedures to make use of the compound block technique.
Before this language element was available, a programmer was able to simulate a compound
block within the handler as illustrated in Example 15-37.
However, you should refrain from using this trick, because in native SQL procedures,
SQLCODE and SQLSTATE values will be reset after executing the IF clause.
DB2_LINE_NUMBER also returns the line number when a CALL statement invokes a native
SQL procedure and the procedure returns with an error. This information is not returned for
an external SQL procedure. This value will only be meaningful if the statement source
contains new line control characters, that is, the source is not converted to a single statement
line when it gets processed. For example, in DSNTEP2 new line control characters are
included when SQLPL is used as SQL format.
The new keywords introduced are CURRENT and STACKED in the GET DIAGNOSTICS
statement (where default is CURRENT). Therefore, the GET STACKED DIAGNOSTICS
statement used within the body of a handler will look at the stacked diagnostics area instead
of the current one. The SQL procedure in Example 15-38 divides the numerator by the
denominator, which are both provided as input parameters. In case the denominator is set to
0 an error condition is raised, which is caught by the CONTINUE HANDLER. In the handler,
the first GET DIAGNOSTICS statement obtains information from the current diagnostics area
which contains the diagnostic information for the last SQL statement that was executed
except for another GET DIAGNOSTICS statement. Therefore, MSG_TEXT is set to the
diagnostic information concerning the statement SET DIVIDE_RESULT = -1. The second
GET DIAGNOSTICS statement specifies the STACKED keyword. The use of the STACKED
keyword allows access to the stacked diagnostics area, which contains the diagnostic
information for the condition that caused the handler to be activated. Therefore,
310 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
DIVIDE_ERROR is set to the diagnostic information concerning the statement SET
DIVIDE_RESULT = NUMERATOR / DENOMINATOR.
BEGIN
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
END
If the external procedure has been defined with the options FENCED or EXTERNAL, these
have to be deleted from the procedure options of a native SQL procedure. Furthermore when
the keyword WLM ENVIRONMENT is specified in an external procedure, the FOR DEBUG
clause has to be added for a native procedure. Otherwise, the WLM ENVIRONMENT clause
needs to be deleted. For more information on migrating from external to native SQL
procedures, refer to Chapter 14, “External SQL procedures” on page 233.
-440 Procedure name called and parameter Fix the problem and retry.
list specified are not compatible.
Routine-name was either incorrectly This can involve a change to the SQL
specified or does not exist in the statement, the addition of new routines
database. or a change to the user’s current path, a
change to the execution privileges for
A qualified reference was made, the stored procedure.
and the qualifier was incorrectly
spelled.
A user’s current path does not
contain the schema to which the
desired function belongs, and an
unqualified reference was used.
The wrong number of arguments
was included.
The routine invoker is not
authorized to execute the routine.
314 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
16.1.2 Connectivity SQL errors
The errors listed in Table 16-2 reflect various types of connection problems from Logical Unit
of Work issues to security violations for remote processing.
-114 THE LOCATION NAME location DOES NOT MATCH Take one of these actions to resolve the mismatch:
THE CURRENT SERVER Change the location qualifier to match the
A three -part SQL procedure name was provided CURRENT SERVER special register.
for one of the following SQL statements: Issue an SQL CONNECT to the location where the
– ASSOCIATE LOCATORS stored procedure resides before issuing the SQL
– CALL statement. Ensure that the SQL CALL statement is
issued before the ASSOCIATE LOCATORS or
– DESCRIBE PROCEDURE
DESCRIBE PROCEDURE.
The first part of the SQL procedure name, which
Bind the package containing the three -part SQL
specifies the location where the stored procedure procedure name with the BIND option
resides, did not match the value of the SQL
DBPROTOCOL(DRDA). With this option, DB2
CURRENT SERVER special register.
implicitly uses the DRDA protocol for remote
access to the stored procedure.
Correct the statements so that the exact syntax
used to specify the procedure name on the CALL
statement is the same as that on the ASSOCIATE
LOCATOR and/or DESCRIBE PROCEDURE.
– If an unqualified name is used to CALL the
procedure, the one-part name must also be
used on the other statements.
– If the CALL statement is made with a
three-part name, and the current server is the
same as the location in the three-part name,
the ASSOCIATE LOCATOR or DESCRIBE
procedure can omit the location.
-426 DYNAMIC COMMIT NOT VALID AT AN The IMS or CICS protocols should be used to commit
APPLICATION SERVER WHERE UPDATES ARE NOT work in these environments.
ALLOWED
An application executing using DRDA protocols
has attempted to issue a dynamic COMMIT
statement, or a stored procedure has attempted to
issue a COMMIT_ON_RETURN, while connected
to a location at which updates are not allowed.
A dynamic COMMIT or COMMIT_ON_RETURN
can be issued only while connected to a location at
which updates are allowed.
-842 A CONNECTION TO location-name ALREADY The correction depends on the error, as follows:
EXISTS If the location name is not the intended name,
One of the following situations occurred: correct it.
A CONNECT statement identifies a location with If SQLRULES(STD) is in effect and the CONNECT
which the application process has a private statement identifies an existing SQL connection,
connection, using system-directed access. replace the CONNECT with SET CONNECTION
SQLRULES(STD) is in effect and a CONNECT or change the option to SQLRULES(DB2).
statement identifies an existing SQL connection. If the CONNECT statement identifies an existing
A private connection, using system-directed private connection, destroy that connection (by
access, cannot be established because of an using the RELEASE statement in a previous unit of
existing SQL connection to that location. work) before executing the CONNECT statement.
A CONNECT (type 2) request that includes the If the SQL statements following the CONNECT
USER/USING clause identifies an existing SQL can be executed using system-directed access, an
connection. alternative solution is to change the application to
use that method.
If system-directed access cannot be used, destroy
the conflicting SQL connection (by using the
RELEASE statement in a previous unit of work)
before executing the SQL statement that requires
system-directed access. An alternative solution is
to change the application so that only
application-directed access is used.
Destroy the connection (by using the RELEASE
statement in a previous unit of work) before
executing the CONNECT statement, which
includes the USER/USING clause.
Correct the error in the application, rebind the plan or
package, and resubmit the job.
-925 COMMIT NOT VALID IN IMS, CICS OR RRSAF The IMS, CICS, or RRS protocols should be used to
ENVIRONMENT commit work in these environments.
An application executing in either an IMS or CICS If a stored procedure is being called from IMS or
environment or an application executing in an CICS, ensure that the stored procedure is not
RRSAF environment when DB2 is not the only defined to perform a commit on return.
resource manager has attempted to execute a
COMMIT statement. The SQL COMMIT statement
cannot be executed in these environments.
-926 ROLLBACK NOT VALID IN IMS, CICS The IMS, CICS, or RRS protocols should be used to roll
OR RRSAF ENVIRONMENT back work in these environments.
An application executing in either an IMS or CICS
environment or an application executing in an
RRSAF environment when DB2 is not the only
resource manager has attempted to execute a
ROLLBACK statement. The SQL ROLLBACK
statement cannot be executed in these
environments.
-30082 CONNECTION FAILED FOR SECURITY REASON DB2 uses the communications database (CDB) to
reason-code (reason-string) control network security functions. Make the
The attempt to connect to a remote database appropriate changes to the CDB to correct the security
server was rejected due to invalid or incorrect failure.
security information.
The cause of the security error is described by the
reason-code and reason-string values.
DB2 Version 9.1 for z/OS Codes, GC18-9843.
-30090 An update operation or a dynamic commit or rollback Do not attempt to update data or issue dynamic
was attempted at a server that was supporting an commits or rollbacks from IMS or CICS applications
application that was in a read-only execution that are accessing remote data.
environment (IMS or CICS).
316 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
16.1.3 CALL statement error SQLCODEs
Table 16-3 contains information relating to the errors that can occur on the CALL statement.
-430 routine-type routine-name (SPECIFIC NAME The stored procedure or function needs to be fixed.
specific-name) HAS ABNORMALLY TERMINATED Contact the author of the routine or your database
An abnormal termination has occurred while the administrator. Until it is fixed, the routine should not be
routine routine-name (stored procedure or used.
function) was in control. See 16.2, “Debugging options” on page 328.
-444 USER PROGRAM name COULD NOT If the EXTERNAL_NAME column value in the
BE FOUND SYSIBM.SYSROUTINES table is incorrect, use the
DB2 received an SQL CALL statement for a stored ALTER PROCEDURE statement to correct the value.
procedure and found the row in the SYSIBM. If the EXTERNAL_NAME column value is correct,
SYSROUTINES catalog table associated with the use the MVS linkage editor to create the required
requested procedure name. However, the MVS load MVS load module in one of the MVS load libraries
module identified in the EXTERNAL_NAME column of used by your installation for stored procedures.
the SYSIBM.SYSROUTINES row could not be found.
This error can also occur if you are invoking a
WLM-managed stored procedure that is not APF
authorized, and the DB2 load libraries are not in
the STEPLIB concatenation because they are
being loaded from LINKLIST.
– If you want the stored procedure program to
run APF-authorized, linkedit it with AC=1 into
an MVS APF authorized library.
– If you do not want the stored procedure
program to run APF authorized, add the DB2
load library to the STEPLIB concatenation of
the JCL used to start the WLM-managed
address space.
-450 USER-DEFINED FUNCTION OR STORED Check the calling parameter list sequence against the
PROCEDURE name, PARAMETER NUMBER defined parameter list sequence and the procedure’s
parmnum, OVERLAYED STORAGE BEYOND ITS parameter list sequence.
DECLARED LENGTH.
Upon return from a stored procedure name, DB2 If the sequence is correct, then check the data
has detected an overlay storage beyond a definitions of each parameter.
parameter’s declared length. The parameter
number is specified for a stored procedure or Contact the author of the function/procedure or your
function. database administrator.
-470 SQL CALL STATEMENT SPECIFIED A If the stored procedure should not accept null values,
NULL VALUE FOR INPUT PARAMETER number, BUT change the calling application to provide a nonnull
THE STORED PROCEDURE DOES NOT SUPPORT value.
NULL VALUES.
DB2 received an SQL CALL statement for a stored If the stored procedure should accept null values, use
procedure and found a null value in the incoming the ALTER PROCEDURE statement to change the
parameter list. The stored procedure was defined PARAMETER STYLE of the stored procedure to be
in the SYSIBM.SYSROUTINES catalog table with SQL or GENERAL WITH NULLS.
PARAMETER_STYLE of GENERAL, which
specifies that the routine does not accept null
values.
A call to a stored procedure with a LANGUAGE
value of JAVA or COMPJAVA receives this
SQLCODE if an input parameter in the compiled
Java stored procedure has a Java base type that
cannot be set to a null value.
number: The parameter number from the
ORDINAL field in SYSIBM.SYSPARMS.
318 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
SQLCODE REASON RESPONSE
RC00E79002 RC00E79002
The CALL statement was not accepted because If the routine was stopped, issue a DB2 START
the procedure could not be scheduled before the PROCEDURE command.
installation-defined time limit expired. If the WLM application environment is quiesced,
Reasons: issue the MVS command
– The DB2 STOP PROCEDURE(name) WLM DISPLAY,APPLENV=wlmenv
command was in effect. to verify the status of the application environment.
– The dispatching priority assigned by WLM to Then the MVS command
the caller of the user-written routine was too WLM VARY APPLENV=wlmenv,RESUME
low, which resulted in WLM not assigning the
request to a TCB before the time limit expired. can be used to activate the environment if it is
quiesced.
– The user-written routine could not be assigned
to a TCB in the DB2-established stored For TCB management, contact your DB2
procedures address space in the required time administrator to raise the dispatching priority of the
interval, because all available stored procedure.
procedure TCBs were in use.
All other reason codes:
Refer to DB2 Version 9.1 for z/OS Codes, GC18-9843
for the meanings and suggested response activities.
-729 A STORED PROCEDURE SPECIFYING COMMIT ON The SQL statement is not executed. If the CALL
RETURN CANNOT BE THE TARGET OF A NESTED statement references a remote server, the unit of work
CALL STATEMENT is placed in a must rollback state.
A stored procedure defined with the COMMIT ON Remove the CALL to the stored procedure that was
RETURN attribute was called from a stored procedure, defined with the COMMIT ON RETURN attribute.
user-defined function, or trigger.
-751 object-type object-name (SPECIFIC NAME specific Any Commit or Rollback statements in the stored
name) ATTEMPTED TO EXECUTE AN SQL procedure must be removed, or the client application
STATEMENT statement THAT IS NOT ALLOWED should be modified to establish an environment that
allows the stored procedure to execute SQL Commit
A stored procedure issued an SQL statement that and/or Rollback statements.
forced the DB2 thread to roll back the unit of work. The
SQL statement that caused the thread to be placed in When control returns to the SQL application that issued
the MUST_ROLLBACK the SQL CALL statement, the SQL application must roll
state is one of the following: back the unit of work. This can be done by issuing an
COMMIT SQL ROLLBACK statement or the equivalent IMS or
CICS operation.
ROLLBACK
All further SQL statements are rejected until the SQL
application that issued the SQL CALL statement rolls
back the unit of work.
320 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
What can go wrong? Table 16-4 contains information about errors that are not detected until
statements that are dependent on the call execute. Most of these errors are “linkage” in
nature, and occur when referring to parameters or other objects shared with the stored
procedure.
-423 INVALID VALUE FOR LOCATOR IN For a result set locator there are two common causes
POSITION position-# for the error:
The value specified in a result set locator host The host variable used as a result set locator was
variable, a LOB locator host variable, or a table never assigned a valid result set locator value.
locator that is specified at position-# in the locator Result set locator values are returned by the
variable list of the SQL statement does not identify DESCRIBE, PROCEDURE, and ASSOCIATE
a valid result set locator, LOB locator variable, or LOCATORS statements. Make sure the value in
table locator, respectively. your host variable is obtained from one of these
statements.
Result set locator values are only valid as long as
the underlying SQL cursor is open. If a commit or
rollback operation closes an SQL cursor, the result
set locator associated with the cursor is no longer
valid.
For an LOB locator, some common causes for the error
are:
The host variable used as a LOB locator was never
assigned a valid LOB value.
A commit or rollback operation or an SQL FREE
LOCATOR statement freed the locator.
For a table locator, the error commonly occurs when the
host variable that was used as a table locator was never
assigned a valid table locator value.
-482 THE PROCEDURE procedure-name Determine if result set locators are returned from the
RETURNED NO LOCATORS identified procedure by using the DESCRIBE
The procedure identified in an ASSOCIATE PROCEDURE statement.
LOCATORS statement returned no result set
locators.
-496 THE SQL STATEMENT CANNOT BE EXECUTED Connect to the server that called the stored procedure,
BECAUSE IT REFERENCES A RESULT SET THAT which created the result set before running the SQL
WAS NOT CREATED BY THE CURRENT SERVER statement that failed.
The SQL statement cannot be executed because
the current server is different from the server that
called a stored procedure. The SQL statement can
be any of the following:
– ALLOCATE CURSOR
– DESCRIBE CURSOR
– FETCH, with an allocated cursor
– CLOSE, with an allocated cursor
-499 CURSOR cursor-name HAS ALREADY BEEN Determine if the target result set named in the
ASSIGNED TO THIS OR ANOTHER RESULT SET ALLOCATE CURSOR statement has been previously
FROM PROCEDURE procedure-name. assigned to a cursor.
An attempt was made to assign a cursor to a result If the result set has been previously assigned to
set using the SQL statement ALLOCATE cursor cursor-name, then either choose another
CURSOR and one of the following applies: target result set or call the stored procedure again
The result set locator variable specified in the and reissue the ASSOCIATE LOCATOR and
ALLOCATE CURSOR statement has been ALLOCATE CURSOR statements.
previously assigned to cursor cursor-name. If the result set has not been previously assigned
Cursor cursor-name specified in the ALLOCATE to a cursor, the cursor cursor-name specified in the
CURSOR statement has been previously assigned ALLOCATE CURSOR statement has been
to a result set from stored procedure previously assigned to some result set from stored
procedure-name. procedure procedure-name. You cannot assign
cursor cursor-name to another result set, so you
must specify a different cursor name in the
ALLOCATE CURSOR statement.
Correct the statements so that the exact syntax used to
specify the procedure name on the CALL statement be
the same as that on the ASSOCIATE LOCATOR and/or
DESCRIBE PROCEDURE.
If an unqualified name is used to CALL the
procedure, the one-part name must also be used
on the other statements.
If the CALL statement is made with a three-part
name, and the current server is the same as the
location in the three-part name, the ASSOCIATE
LOCATOR or DESCRIBE procedure can omit the
location.
322 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
SQLCODE REASON RESPONSE
-504 CURSOR NAME cursor-name IS NOT DECLARED Check the application program or SQL routine for
completeness and for a possible spelling error in the
Cursor cursor-name was referenced in an SQL cursor declaration or allocation.
statement, and one of the following is true:
Cursor cursor-name was not declared (using the The declaration for or allocation of a cursor must
DECLARE CURSOR statement) or allocated appear in an application program or SQL routine before
(using the ALLOCATE CURSOR statement) in the SQL statements that reference the cursor.
application program or SQL routine before it was
referenced. If the cursor-name was <UNKNOWN>, then the cursor
was not successfully declared or allocated. This error
Cursor cursor-name was referenced in a
can occur if SQL(DB2) was used, and a warning
positioned UPDATE or DELETE statement which
message was issued during precompilation. Check the
is not a supported operation for an allocated precompile output for warning messages on the
cursor.
DECLARE CURSOR or ALLOCATE CURSOR
Cursor cursor-name was allocated, but a CLOSE statement, and correct the statement.
cursor statement naming cursor-name was issued
and deallocated the cursor before this cursor For an allocated cursor, if an implicit or explicit
reference. COMMIT, ROLLBACK, or CLOSE occurred since the
Cursor cursor-name was allocated, but a cursor was successfully allocated, modify the
ROLLBACK operation occurred and deallocated application program logic to do one of the following
the cursor before this cursor reference. actions:
Cursor cursor-name was allocated, but its After the COMMIT, ROLLBACK, or CLOSE
associated cursor declared in a stored procedure operation, call the associated stored procedure
was not declared WITH HOLD, and a COMMIT again, and reissue the ASSOCIATE LOCATORS
operation occurred and deallocated the cursor and ALLOCATE CURSOR statements.
before this cursor reference. The COMMIT For COMMIT, declare the associated cursor in the
operation can be either explicit (the COMMIT stored procedure WITH HOLD so the COMMIT
statement) or implicit (that is, a stored procedure operation will not deallocate the cursor.
defined as COMMIT_ON_RETURN = ’Y’ was For an allocated cursor, if the associated stored
called before this cursor reference).
procedure was called again, and new result sets were
Cursor cursor-name was allocated, but its returned since the cursor was allocated, reissue the
associated stored procedure was called again ASSOCIATE LOCATORS and ALLOCATE CURSOR
since the cursor was allocated, new result sets statements.
were returned, and cursor cursor-name was
deallocated.
The declaration of a cursor cursor-name was not in
scope for the reference to a cursor named
cursor-name.
The most prevalent of unhandled errors is the scenario when a stored procedure cannot take
corrective action because it abnormally terminated. The invoker receives an SQLCODE of
-430 from the CALL statement. Since the procedure abended, it was, obviously, unable to
handle the error condition, and the invoker cannot rely on any information contained in the
output parameters. Once the stored procedure has been corrected, it might be necessary to
issue a -START PROCEDURE statement if the procedure was placed in the STOPABN state
because the maximum number of abends have been reached for the address space.
Another common unhandled error is when a stored procedure receives SQLCODE of +100
on initial fetch, no rows found, and fails to place a default value into the output parameters.
Depending upon the definition of the parameters, the invoking program can receive
SQLCODE -310 (invalid decimal data) or -180 (invalid date, time, or timestamp value) on the
CALL. If the programs included SQLCODE and/or SQLSTATE parameters, the invoking
It is important for every stored procedure to correctly handle encountered SQL errors. What is
correct is dictated by the needs of the application. Communication, though, is the key to
handling most application errors. If the stored procedure determines that a process cannot
continue as expected, this fact must be reported to the caller.
At a minimum, the stored procedure needs to share its SQLCODE and or SQLSTATE values
and an appropriate error message. Remember, just because the SQLCODE from the CALL
statement is zero, it does not mean that the stored procedure accomplished its mission.
SPECIFIC PROCNAME The specific name of the stored procedure. The specific name
is a VARCHAR(128) value that is the same as the unqualified
name.
DIAGNOSTIC MESSAGE The SQL diagnostic string that is to be returned to DB2. This is
a VARCHAR(70) value. Use this area to pass descriptive
information about an error or warning to the caller.
Important: The parameters mentioned in Table 16-5, must be referenced in the linkage
definition area of the stored procedure source program.
The additional parameters associated with PARAMETER STYLE SQL are not defined or
referenced in the invoking program or in the CREATE PROCEDURE statement. A COBOL
example of the stored procedure definitions would be:
1. Define the program/stored procedure parameters.
2. Define a separate and independent indicator variable for each parameter.
3. Establish linkage with the USING clause of the PROCEDURE DIVISION header and the
sequence of the parameters. See Example 16-1.
324 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
01 PARM3 ...
01 IV-PARM1 ...
01 IV-PARM2 ...
01 IV-PARM3 ,,,
01 SQL-SQLSTATE PIC X(05).
01 SQL-QUAL-PROCNAME.
49 SQL-QUAL-PROCNAME-LEN PIC S9(04) COMP.
49 SQL-QUAL-PROCNAME-TEXT PIC X(517).
01 SQL-SPEC-PROCNAME.
49 SQL-SPEC-PROCNAME-LEN PIC S9(04) COMP.
49 SQL-SPEC-PROCNAME-TEXT PIC X(128).
01 SQL-DIAGNOSTICS.
49 SQL-DIAGNOSTICS-LEN PIC S9(04) COMP.
49 SQL-DIAGNOSTICS-TEXT PIC X(70).
For examples in other languages, refer to DB2 Version 9.1 for z/OS Application Programming
and SQL Guide, SC18-9841.
If the stored procedure program sets the SQL-SQLSTATE parameter, then DB2 will set the
SQLCODE for the invoking call statement to a negative value. To see what values will be
placed in the caller’s SQLSTATE and SQLCODE fields, refer to 10.2.6, “Handling
PARAMETER STYLE SQL” on page 119.
Most program designs that check for time-out and deadlocks will interrogate the SQLCODE
for a value of -911. Stored procedures that encounter this condition and are “victimized” will
be notified with an SQLCODE of -913. This means that DB2 did not execute a ROLLBACK for
the application and the application needs to rollback or commit as soon as possible.
An SQLCODE of -805 when executing a stored procedure can occur for one of two reasons:
Either DB2 cannot find the package for the application that contains the SQL CALL
statement,
or DB2 cannot find the package for the stored procedure being called.
If the -805 is returned, this should be a lot more specific to stored procedures. The first task is
to determine if it is the CALL statement package that cannot be found, or if the call statement
got to the stored procedure program and the stored procedure package cannot be found. The
actions are different to resolve each. Often the stored procedure program is changed and
rebound, so the timestamp does not match unless a WLM refresh is done.
-913
UNSUCCESSFUL EXECUTION CAUSED BY DEADLOCK OR TIMEOUT. REASON CODE reason-code, TYPE
OF RESOURCE resource-type, AND RESOURCE NAME resource-name
Explanation: The application was the victim in a deadlock or experienced a time-out. The
reason code indicates whether a deadlock or time-out occurred.
Response: The application should either commit or roll back to the previous COMMIT. Then,
generally, the application should terminate. See message DSNT376I in DB2 Version 9.1 for
z/OS Messages, GC18-9849, for possible ways to avoid future deadlocks or time-outs.
-805
DBRM OR PACKAGE NAME location-name.collection-id.dbrmname.consistency.token NOT
FOUND IN PLAN plan-name. REASON reason
The REASON token is blank if the length of “location-name” is 16, the length of “collection-id”
is 18, and the length of “dbrm-name” is 8 due to the length of SQLERRMT.
The DBRM or package name was not found for one or more of the following reasons:
01: The DBRM name was not found in the member list of the plan and there is no package
list for the plan. Refer to the first SQL statement under problem determination for
assistance in determining the problem.
The package name was not found because there is no package list for the plan. Refer to
the second SQL statement under Problem Determination for assistance in determining the
problem.
02: The DBRM name dbrm-name did not match an entry in the member list or the package
list. Any of the following conditions could be the problem:
Bind conditions:
– The collection-id in the package list was not correct when the application plan
plan-name was bound. Refer to the second SQL statement under Problem
Determination for assistance in determining the problem.
– The location-name in the package list was not correct when the application plan-name
was bound. Refer to the second SQL statement under Problem Determination for
assistance in determining the problem.
– The location-name in the CURRENTSERVER option for the bind subcommand was not
correct when the application plan plan-name was bound. Refer to the third SQL
statement under Problem Determination for assistance in determining the problem.
– DB2 private protocols are not supported under the bind parameter.
Application conditions:
– The CURRENT PACKAGESET special register was not set correctly by the application.
– The application was not connected to the proper location.
When using SET CURRENT PACKAGESET = :HV, be sure to use the correct encoding
scheme, that matches with the :HV in ZPARM options. This statement does not require
package or DBRM bound into the plan, so it uses the encoding scheme defined for system.
The same applies to SET CURRENT PACKAGE PATH.
326 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
03: The DBRM name dbrm-name matched one or more entries in the package list and the
search of those entries did not find the package. The conditions listed under reason 02 or
the following conditions might be the problem.
The DBRM of the version of the application program being executed was not bound (A
package with the same consistency token as that of the application program was not
found.) Refer to the fourth and fifth SQL statements under the Problem Determination
section.
The incorrect version of the application program is being executed.
04: The package collection-id.dbrm-name.consistencytoken does not exist at the remote
site, location-name. Refer to the fifth SQL statement under the Problem Determination
section.
In a native SQL procedure, if the affected SQL statement follows a SET CURRENT
PACKAGESET, SET CURRENT PACKAGE PATH, CONNECT statement, or if it refers to an
object on a remote server, additional package or packages will need to be bound via BIND
COPY. Whenever the native SQL procedure is changed such that a regeneration is needed,
the additional package also needs to be bound with the copy option.
Response: Based on the above reasons, the programmer can perform one or more of the
following operations for each reason to correct the error:
01: Add the DBRM name dbrm-name to the MEMBER list of the BIND subcommand and
bind the application plan plan-name,
or,
Add the PKLIST option with the appropriate package list entry to the REBIND
subcommand and rebind the application plan plan-name.
02: Correct the dbrm-name of the entry in the PKLIST option and use the REBIND
subcommand to rebind the application plan plan-name, or correct the location-name of the
entry in the PKLIST option and use the REBIND subcommand to rebind the application
plan plan-name, or correct the location-name in the CURRENTSERVER option and use
the REBIND subcommand to rebind the application plan plan-name, or set the CURRENT
PACKAGESET special register correctly, or Connect to the correct location name.
03: All the operations under reason 02 above might fix the problem, plus the following
operations.
Correct the collection-id of the entry in the PKLIST option and use the REBIND
subcommand to rebind the application plan plan-name, or bind the DBRM of the version of
the application program to be executed into the collection collection-id, or execute the
correct version of the application program. The consistency token of the application
program is the same as the package that was bound.
04: According to DB2 Version 9.1 for z/OS Codes, GC18-9843 all the operations under
reason 02 and 03 might fix the problem.
If this error is issued for one of the situations described for a native SQL procedure, use BIND
COPY to bind the additional packages.
Problem Determination: The following queries aid in determining the problem. Run these
queries at the local location:
This query displays the DBRMs in the member list for the plan. If no rows are returned,
then the plan was bound without a member list:
SELECT PLCREATOR, PLNAME, NAME, VERSION
FROM SYSIBM.SYSDBRM
WHERE PLNAME = ’plan-name’;
328 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Example 16-2 Program produced displays
********************************* TOP OF DATA *********************************
++ BONNIC1C STARTING ++
WS-TIMESTAMP = 2003-12-03-19.37.17.697857
PEMPNO = 000250
WS-SQLCODE = - 430
DSNT408I SQLCODE = -430, ERROR: PROCEDURE DEVL7083.PRGTYPE1 (SPECIFIC NAME
DEVL7083.PRGTYPE1) HAS ABNORMALLY TERMINATED
DSNT418I SQLSTATE = 38503 SQLSTATE RETURN CODE
DSNT415I SQLERRP = DSNX9CAC SQL PROCEDURE DETECTING ERROR
DSNT416I SQLERRD = 0 0 0 -1 0 0 SQL DIAGNOSTIC INFORMATION
DSNT416I SQLERRD = X'00000000' X'00000000' X'00000000' X'FFFFFFFF'
X'00000000' X'00000000' SQL DIAGNOSTIC INFORMATION
******************************* BOTTOM OF DATA ********************************
Figure 16-1 shows the console messages that accompany the abend of the stored procedure.
You may see message DSNX905I, DSNX906I, or DSNX966I, depending on the
circumstances.
Figure 16-1 Console messages for abend that resulted in SQLCODE -430
2. Compile the stored procedure with the option ‘TEST(SYM)’ if you would like to have a
formatted local variable dump included in the CEEDUMP output of the stored procedure.
For more details on this compile option, refer to Enterprise COBOL for z/OS Programming
Guide Version 3 Release 4, SC27-1412-05.
3. Locate the stored procedure output, CEEDUMP, and program displays by:
a. Using System Display and Search Facility (SDSF), with a prefix equal to the WLM
environment name, enter one of the following commands:
DA to display active or, ST for the status of, STC (Started Tasks)
Example 16-4 accesses the Job Data Set panel by coding ? in the NP field.
b. Example 16-5 shows the Job Data Set Display (JDSD) accessed, and the selection of
the SYSDBOUT data set referenced in the runtime options of Example 16-3.
c. With Example 16-6, the stored procedure PRGTYPE1 terminated with a S0C7 at
statement 331.
330 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Example 16-6 Message in SYSDBOUT data set
CEE3207S The system detected a data exception (System Completion Code=0C7).
From compile unit PRGTYPE1 at entry point PRGTYPE1 at statement 331 at
compile unit offset +000005D4 at entry offset +000005D4 at address 0001BC6C.
d. Next, select the CEEDUMP data set. Example 16-7 highlights, most importantly, the
data content of the field in error, PCALL-CTR. The local variables appear in the
CEEDUMP output because of the TEST(SYM) compile option.
e. Use the compiler listing to determine exactly what statement was executing at the time
of the error.
4. Repeating step 3 on page 330, locate the compile SYSPRINT for the stored procedure. As
shown in Example 16-8, you now have the failing statement in the stored procedure
source code.
The data shown in Example 16-7 on page 331 was indicative of an uninitialized value.
Whether or not the invoker initializes this field is irrelative. DB2 did not move the output
parameter’s data to the work area at the time of the call.
On the surface, the stored procedure needs to deal with the initialization of PCALL-CTR.
Note: We think it is usually best if the invoker counts for itself. If the stored procedure is
not going to further process the count, why force every user to supply a counter even if
the caller is not concerned with the number of calls issued.
Using this counter to keep track of its own utilization, it could initialize the counter when it
is defined, and just increment within itself and not be a parameter at all.
If the stored procedure is going to process this count, then you must consider the
reusability of this module to develop a method that will also maintain the integrity of the
counter.
332 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
16.4 Compiler and LE options for debugging
We describe the COBOL Compiler and LE options available for debugging.
To simplify debugging, use the NOOPTIMIZE compiler option. Program optimization can
change the location of parameters and instructions in the dump output.
You can use the following COBOL compiler options to prepare your program for runtime
debugging:
LIST, MAP, OFFSET, TEST, VBREF, XREF
Refer to Enterprise COBOL for z/OS Programming Guide Version 3 Release 4, SC27-1412
for details.
The Debug Tool helps you test programs and examine, monitor, and control the execution of
programs written in Assembler, C, C++, COBOL, or PL/I on a z/OS system. Your applications
can include other languages; Debug Tool provides a disassembly view that lets you debug at
the machine code level those portions of your application. However, in the disassembly view,
your debugging capabilities are limited. Table 16-6 and Table 16-7 map out the combinations
of compilers and subsystems that are supported.
For an updated list of supported compilers and environments, see the Debug Tool Web site
at:
http://www.ibm.com/software/awdtools/debugtool
Batch mode
You can use Debug Tool command files to predefine a series of Debug Tool commands to be
performed on a running batch application. Neither terminal input nor user interaction is
available for batch debugging of a batch application. The results of the debugging session are
saved to a log, which you can review at a later time.
334 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Full-screen mode
Debug Tool provides an interactive full-screen interface on a 3270 device, with debugging
information displayed in four windows:
Monitor window Displays the variables and their values, controlled by entering the SET
AUTOMONITOR ON and MONITOR commands.
Source window Displays the source or listing file. The Debug Tool can find this for you,
or you can specify where to find it.
Log window Records your interactions with Debug Tool and the results of those
interactions.
Memory window Displays a section of memory, controlled by entering the MEMORY
command.
The default screen displays three physical windows, with one assigned the Monitor window,
the second assigned the Source window, and the third assigned the Log window. You can
swap the Memory window with the Log window.
You can debug all languages supported by Debug Tool in full-screen mode. This refers to the
debugging mode that requires a second terminal, a VTAM terminal, to be started and used to
debug an application.
After the VTAM terminal has been started, you can optionally use the Debug Tool Terminal
Interface Manager, or TIM for short, to identify that terminal to Debug Tool by using a user ID
instead of a LU name. If you are use the Debug Tool Terminal Interface Manager, specify the
VTAM suboption with your user ID, as in the following example:
Test=(,,,VTAM%USERABCD)
Our example of Debug Tool session at 16.5.2, “IBM Debug Tool on z/OS: An example” on
page 336, uses the Terminal Interface Manager.
TSO Y Y Y
JES batch Y Y Y
CICS Y Y Y
DB2 Y Y Y
For example, a COBOL batch job running in MVS/JES, or a COBOL CICS batch transaction,
can be interactively debugged through a TCP/IP connection to a workstation that has the
Rational® Developer for System Z installed in it.
The remote operating system that Rational Developer and WebSphere Developer supports
are Windows 2003, Windows Vista®, Windows XP. Check the following Web sites for more
information regarding the above products.
http://www.ibm.com/software/awdtools/rdz/support/index.html
http://www.ibm.com/software/awdtools/devzseries/support/
The DB2 administrator must define the address space where the stored procedure runs. This
can be a DB2 address space or a Workload Manager (WLM) address space. This address
space is assigned a name that is used to define the stored procedure to DB2. In the JCL for
the DB2 or WLM address space, verify that the following data sets are defined in the LINK
LIST or STEPLIB concatenation and that they have the appropriate RACF read authorization
for programs to access them:
LOADLIB for the stored procedure
SEQAMOD for Debug Tool
SCEERUN for Language Environment
After updating the JCL, the DB2 administrator must recycle the DB2 or WLM address space
so that these updates take effect.
As previously mentioned, Debug Tool gives you the capability of testing programs in batch,
using a non-programmable terminal in full-screen mode, or using a workstation interface to
remotely debug your programs.
Before demonstrating some of the debugging commands and options available with Debug
Tool, we discuss the Terminal Interface Manager, or TIM, and its setup. Next, we describe the
stored procedure setup, and finally, an example using the program previously debugged in the
classical manner.
Refer to Debug Tool for z/OS Debug Tool Utilities and Advanced Functions for z/OS User's
Guide Version 8.1, SC19-1196 for details of using the Debug Tool in this and other modes.
336 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
16.5.3 The Terminal Interface Manager
A feature of the Debug Tool is the Terminal Interface Manager (TIM). TIM enables a user to
use full-screen mode through a VTAM terminal without having to know the LU name of the
VTAM terminal. The Terminal Interface Manager provides a method to correlate a user ID to
the terminal. This is useful in situations where it is cumbersome to edit the TEST runtime
parameter with the LU name of the VTAM terminal.
The setup for using TIM is very similar to using VTAM MFI. There are some differences,
however, namely:
The port number you use in the Telnet session’s Link parameters will be different. Your
system programmer will need to do some setup to assign this port number to a TIM
session.
You will need to change the RUN OPTIONS in your stored procedure to the following:
TEST(,,,VTAM%userid:*)
Note that rather than an LU name, a userid is specified.
2. Save this session as a Workstation Profile, and give it a meaningful name such as
DT_TIM.ws as shown in Figure 16-3.
338 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 16-4 Terminal Interface Manager, login page
After entering your TSO userid and password, you will get a message:
EQAY001I Terminal S070095 connected for user <your TSO userid>
EQAY001I Ready for Debug Tool
You will need to call your stored procedure, either through an application or tooling. Once the
stored procedure is called, this session hosts the Debug Tool full screen session, and you will
be able to enter the debug operations we discuss in 16.5.5, “Demonstration of Debug Tool
with TIM” on page 340.
340 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
The PF Keys
The PF1 key, ?, gives a list of the Debug Tool commands. Commonly used commands such
as Step, Go, List and Find are assigned to PF2, PF4 and PF5 respectively.
Layout command
The Debug Tool layout command allows you to customize the layout of the debug session.
Enter the layout on the command line. Select your layout preference as shown in
Figure 16-6.
In our example, let’s find the variable PCALL-CTR. Type FIND PCALL-CTR on the command line.
Debug Tool will position the source window on the first executable statement that uses this
variable. The variable that is found is identified by a black background, as shown in
Figure 16-8.
342 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 16-8 Debug Tool TIM, Find PCALL-CTR
In the Monitor window, the variable PCALL-CTR is displayed, and the contents of this variable
are displayed as shown in Figure 16-9.
We note that the value of PCALL-CTR is unprintable, so we want to see what’s in memory.
Debug Tool can display the value of a variable in memory and displays the hex values in the
Memory window. To display what’s in storage starting at the register where PCALL-CTR is
located, issue the following commands:
LIST STORAGE (PCALL-CTR);
MEMORY PCALL-CTR;
ZOOM MEMORY;
Debug Tool will access the address assigned to PCALL-CTR, which in this case is 32A470F8,
and display what is in memory, starting at that address, as shown in Figure 16-10.
344 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 16-10 Debug Tool TIM, Memory display starting at address 32A470F8
However, we can see that this variable is not initialized. So, let us initialize the value of
PCALL-CTR. You can do this by simply typing over the current value in the Monitor view. In our
example, we typed 0000 in the value field. This action generated the statement MOVE 0000 TO
PCALL-CTR, as shown in Figure 16-11.
Creating breakpoints
You can create breakpoints by placing the cursor at a given line and pressing PF6. If you
know the line number where you want execution to stop, you can issue the AT <line number>
command.
In Figure 16-12, the current statement to be executed is denoted by the red line on line 301.
We create a breakpoint in line 306 by placing the cursor there, and pressing PF6 or by typing
the command AT 306.
346 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 16-12 Debug Tool TIM, AT command
Obviously, you have not seen everything that is available for debugging with the Debug Tool.
We barely scratched the surface. For more information about the Debug Tool commands,
refer to Debug Tool for z/OS Debug Tool Utilities and Advanced Functions for z/OS(R) User's
Guide Version 8.1, SC19-1196.
The routine extracts the TEST runtime option from a data set with a name that is constructed
dynamically from a naming pattern, which includes the user ID token &USERID. This token is
replaced with the user ID of the current user during name construction. Each user can specify
an individual TEST runtime option when debugging an application.
If the PROGRAM TYPE for a DB2 stored procedure is MAIN, you can specify the TEST
runtime options through the DB2 catalog or Language Environment EQADDCXT exit routine.
If you specify the TEST runtime option through the Language Environment EQADDCXT exit
routine, you can run the stored procedure with your own set of suboptions. Another user can
run or debug the stored procedure with his own set of suboptions. Therefore, multiple users
can run or debug the stored procedure at the same time.
348 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
– Sequential data set (DSORG=PS)
– Record format and length requirements:
• RECFM(F) or RECFM(FB) and LRECL >=80
• RECFM(V) or RECFM(VB) and LRECL >=84
Launch the Debug Tool Utilities and select Manage TEST Run-time Data Set as shown in
Figure 16-14.
In the next page, specify the data set that you created in the first step as shown in
Figure 16-15.
Specify the TEST runtime option you want to use through the DB2 catalog or Language
Environment EQADDCXT exit routine. See Figure 16-16.
Note: If the PROGRAM TYPE for the stored procedure is SUB, you must specify the TEST
runtime option through the DB2 catalog. You are limited to specifying one specific set of
suboptions, which means that every user that runs or debugs that stored procedure uses
the same set of suboptions. If both methods are used, the Language Environment exit
routine takes precedence over the DB2 catalog.
350 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 16-16 Managing your Run-time Option Data Set
INSERT
INSERT INTO INTO T1T1 FOR
FOR 55 ROWS
ROWS VALUES
VALUES (:array);
(:array);
GET DIAGNOSTICS :errcount =
GET DIAGNOSTICS :errcount = NUMBER; NUMBER;
DO
DO |||| == 11 TO
TO ERR_COUNT;
ERR_COUNT;
GET
GET DIAGNOSTICS
DIAGNOSTICS FOR FOR CONDITION
CONDITION :||
:||
:rc
:rc == RETURNED_SQLSTATE;
RETURNED_SQLSTATE;
END;
END;
In Figure 16-18 we show the syntax for the GET DIAGNOSTICS statement.
352 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
GET DIAGNOSTICS syntax
GET DIAGNOSTICS statement-information
condition-information
combined-information
statement-information:
host-variable = statement-information-item-name
statement-information-item-name:
Information about last statement
DB2_GET DIAGNOSTICS_DIAGNOSTICS
DB2_LAST_ROW executed (capability of cursor)
DB2_NUMBER_PARAMETER_MARKERS
DB2_NUMBER_RESULT_SETS
DB2_RETURN_STATUS
DB2_SQL_ATTR_CURSOR_HOLD
Some fields will only apply for
DB2_SQL_ATTR_CURSOR_ROWSET
DB2_SQL_ATTR_CURSOR_SCROLLABLE
particular statements
DB2_SQL_ATTR_CURSOR_SENSITIVITY Get Diagnostics
DB2_SQL_ATTR_CURSOR_TYPE
MORE
Multi-row fetch
NUMBER Prepare
ROW_COUNT
Call
condition-information: Open/Allocate
CONDITION host-variable2
integer
,
host-variable3 = condition-information-item-name
connection-information-item-name
The following C language program example demonstrates the use of this new statement.
In an application, use GET DIAGNOSTICS to determine how many rows were updated:
long rcount;
EXEC SQL UPDATE T1 SET C1 =C1 +1;
EXEC SQL GET DIAGNOSTICS :rcount = ROW_COUNT;
After execution of this code segment, rcount contains the number of rows that were updated.
Additional information may be obtained about the fetch, including information on all exception
conditions encountered while processing the fetch statement from the GET DIAGNOSTICS
statement.
Consider an example where we attempt to fetch 10 rows with a single FETCH statement.
This information is also available from the GET DIAGNOSTICS statement, for example:
GET DIAGNOSTICS :num_row = ROW_COUNT, :num_cond = NUMBER;
There are some cases where DB2 returns a warning if indicator variables are provided, or an
error if indicator variables are not provided. These errors can be thought of as data mapping
errors that result in a warning if indicator variables are provided. The GET DIAGNOSTICS
statement may be used to retrieve information about all the data mapping errors that have
occurred.
The SQLCA reflects the last warning encountered. The SQLCA is used to return information
on errors and warnings found during a multiple-row-insert. If indicator arrays are provided, the
indicator variable values are used to determine if the value from the host variable array, or
NULL, is used. The SQLSTATE contains the warning from the last data mapping error.
Additionally, when NOT ATOMIC is in effect, then status information is available for each
failure or warning that occurred while processing the insert. The status information for each
row is available through the GET DIAGNOSTICS statement.
As an example, assume that you are inserting multiple rows using host variable arrays for
column values. The table T1 has 2 columns, C1 is a SMALL INTEGER column, and C2 is an
INTEGER column. INSERT 10 rows of data into the table T1. The values to be inserted are
provided in host variable arrays :hva1 (an array of INTEGER) and :hva2 an array of
DECIMAL(15,0) values. The data values for :hva1 and :hva2 are represented in Table 16-8.
1 1 32768
2 -12 90000
3 79 2
4 32768 19
5 8 36
6 5 24
354 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Array entry :hva1 :hva2
7 400 36
8 73 4000000000
9 -200 2000000000
10 35 88
After execution of the INSERT statement, we have the following in the SQLCA:
SQLCODE = 0
SQLSTATE = 0
SQLERRD3 = 8
Although we attempted to insert 10 rows, only eight rows of data were inserted. Further
information can be found by using the GET DIAGNOSTICS statement, for example:
GET DIAGNOSTICS :num_row = ROW_COUNT, :num_cond = NUMBER;
If the client executes in one DB2 subsystem (DB2L) and the stored procedure resides and
executes in another, remote DB2 subsystem (DB2R), then the stored procedure is termed a
remote stored procedure.
Stored procedures, being reusable programmed components that are executed on the data
server side, can be called both from local applications as well as remote applications.
The subsystem where the client program executes is usually referred to as the local
subsystem (DB2L in our example). In other words, the local subsystem is the one where the
application plan or package is bound. If the stored procedure is executed on a subsystem
other than the local subsystem, this subsystem is then called remote subsystem (DB2R in our
example). The remote DB2 subsystem can physically reside on the same machine, for
example in a different subsystem in the same operating system, or it can even reside
thousands of miles away on a different machine.
S to r e d S to r e d
C lie n t P roced ure D B2R
P roc ed ure
ne two rk
D B 2L C lie n t
D B 2L
L o c a l s to r e d pro c e dure
R e m o te s to r e d pro c e dure
No matter where the remote DB2 subsystem resides, it is known to your local subsystem by
its location name. The location name of the remote subsystem (DB2R) is recorded in the local
subsystem’s communication database (CDB).
Before calling a remote stored procedure, a client has to establish a connection to the remote
subsystem. There are two ways to do this:
Use an explicit SQL CONNECT statement:
358 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
EXEC SQL CALL SYSPROC.ADMIN_INFO_SSID(?,?,?)
Execute the CALL with a qualified three-part name. Here the connection is implicitly
established.
Either way, the information for the DRDA connectivity, and especially the location name, is
found in the communication database.
Communication database
The communication database (CDB) is essentially a set of DB2 catalog tables, that let you
control and configure how requests come in and leave your local DB2 subsystem.
Furthermore, it configures how the conversations with a remote database management
system (DBMS) are established. On DB2 for z/OS the Distributed Data Facility (DDF) uses
the CDB to send and receive distributed data requests. Data at a remote DB2 subsystem can
be accessed with two access protocols, DRDA or the DB2 private protocol. However,
invocation of a stored procedure is supported only with DRDA, therefore the DB2 private
protocol is no longer considered in this chapter. Refer to the chapter “Connecting distributed
database systems” in DB2 Version 9.1 for z/OS Installation Guide, GC18-9846-02 for more
differences between DRDA and the DB2 private protocol.
The following tables have been modified with the advent of Version 9:
SYSIBM.IPLIST:
Column IPADDR revised (enabled for IPv6 addresses)
SYSIBM.IPNAMES:
Column IPADDR revised (enabled for IPv6 addresses)
Columns USERNAMES and SECURITY_OUT revised
SYSIBM.LOCATIONS:
New columns TRUSTED, SECURE added
SYSIBM.USERNAMES:
Column TYPE revised (new type ’S’ added)
If a DB2 subsystem is intended to act only as a data server, there is no need to populate the
CDB tables, the defaults are sufficient. To communicate with remote DB2 subsystems in order
to request data, the CDB of the requesting DB2 subsystem has to be populated. Information
like the remote subsystem’s IP address, the port number, or the location name has to inserted
Practical information with sample case studies can be found in the following two IBM
Redbooks publications:
Moving Data Across the DB2 Family, SG24-6905 (especially: Section 5.1 “Coding for
distributed data”)
Distributed Functions of DB2 for z/OS and OS/390, SG24-6952 (especially: “Appendix B -
DB2 connectivity”)
For more information on how to establish DRDA connectivity, refer to the following manuals:
DB2 Version 9.1 for z/OS Installation Guide, GC18-9846-02
DB2 Version 9.1 for z/OS SQL Reference, SC18-9854-02
DB2 Version 9.1 for z/OS Administration Guide, SC18-9840-02
Reference for Remote DRDA Requesters and Servers, SC18-9853
CONNECT statement
The CONNECT statement, as illustrated in Example 17-1, connects the application process
to a designated database server. There are two types of CONNECT statements. Both have
the same syntax but feature different semantics.
CONNECT type 1 - Lets the application connect to only a single database at any time during
a unit of work. This type of connection models DRDA remote unit of work processing (DB2
Version 9.1 for z/OS SQL Reference, SC18-9854-02, Chapter 1: “Distributed Data - Remote
unit of work”).
CONNECT type 2 - Lets the application connect concurrently to any number of database
servers within a single unit of work. The unit of work can contain multiple SQL statements that
access different database servers. However, a single SQL statement can only access one
distinct database server. This type of connection models DRDA distributed unit of work
processing (see DB2 Version 9.1 for z/OS SQL Reference, SC18-9854-02, Chapter 1:
“Distributed Data - Distributed unit of work“).
Only one CONNECT statement can be executed within the More than one CONNECT statement can be executed
same unit of work. within the same unit of work. Only one connection is active
(current) at a time.
360 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
CONNECT (type 1 - Remote unit of work) CONNECT (type 2 - Distributed unit of work)
- A CONNECT statement is executed successfully only There are no rules about the connectable state. An
when the application process is in the connectable state, application process is either connected or unconnected.
which implies that there is no active unit of work.
- A unit of work starts only when a SQL statement
accesses data, after the CONNECT was executed.
- Once a unit of work is started the application process is
moved to a unconnectable state.
- A COMMIT or ROLLBACK puts the process back in a
connectable state.
- If a CONNECT statement fails because the application If a CONNECT statement fails, the current SQL connection
process is not in the connectable state, the connection is unchanged and any subsequent SQL statements are
state of the application process is unchanged. executed by the currently connected server, unless the
failure prevents the execution of SQL statements by that
- If a CONNECT statement fails although it is in a server.
connectable state, the application process is placed in the
connectable and unconnected state until the CONNECT
succeeds.
A successful CONNECT ends any existing connections of CONNECT does not end connections and does not close
the application process. Accordingly, CONNECT also cursors. It does not issue any implicit COMMIT
closes any open cursors of the application process. (The statements.
only cursors that can possibly be open when CONNECT is
successfully executed are those defined with the WITH
HOLD option.)
A CONNECT to the current server is executed like any If the SQLRULES(STD) bind option is in effect, a
other CONNECT (Type 1) statement. The SQLRULES CONNECT to an existing SQL connection of the
bind option has no effect on it. application process is an error. Thus, a CONNECT to the
current server is an error. For example, an error occurs if
the first explicit CONNECT is a CONNECT TO x where x is
the local DB2.
CONNECT(2) - Refers to type 2 connections or “distributed unit of work“. Use this type of
connection type whenever multiple data servers are involved in a single unit of work. This is
the default value.
CONNECT(1) - Causes the CONNECT statements to work according to the limited “remote
unit of work” definitions.
The connect rules that apply to an application process are determined by the first CONNECT
statement that is executed (successfully or unsuccessfully). Programs containing multiple
CONNECT statements that are precompiled with different CONNECT precompiler options
cannot execute as part of the same application process.
DB2 Version 9 for z/OS now supports native SQL procedures that are not compiled and linked
to an executable program, but rather store their procedural statements natively in the DB2
catalog and directory. To create a native SQL procedure, only the following steps are
required:
1. Define the stored procedure with the procedural statements embedded in the procedure
body.
2. Grant an execute privilege to the invoker of the stored procedure.
Note: Native SQL procedures support a new DEPLOY keyword on the BIND statement
that allows for easy deploying on a remote data server. For more information, refer to
Chapter 15, “Native SQL procedures” on page 253.
Note: If your client program has a need to access multiple servers, then you have to
bind the program at each sever.
362 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
17.2.2 Sample scenarios of program preparations
Invoke a local stored procedure from a DB2 application
Let us consider a few examples where the client program calls local as well as remote stored
procedures. Let us begin with Example 17-3 where we first deal with a local stored procedure
call, and then move towards more complex remote calls.
BIND for client looks like (only important options are shown).
Local bind:
BIND PACKAGE(col1) -
MEMBER(drpgm) -
LIBRARY(dbrm_library_name) -
PATH(schema) -
VALIDATE(BIND)
BIND PLAN(plan_name) -
PKLIST(col1.drpgm)
Example 17-3 shows the steps for preparing a client program to invoke a local stored
procedure, SP. In this case the stored procedure and the client both execute against the same
DB2 subsystem, for example DB2L. Notice that the PATH option determines the SQL path
that DB2 uses to resolve unqualified stored procedure calls. The VALIDATE(BIND) option
ensures that all objects and required privileges exist during bind time, otherwise an error is
issued.
As soon as the package is bound, you can bind the local package into a plan at the local
subsystem. The PKLIST option determines the packages that are bound into the plan. This is
especially important when in the later examples remote packages are bound into the local
application plan.
Comparing Example 17-3 with Example 17-4 on page 364 reveals that there is essentially no
difference in the CALL statement to the procedure, no matter whether it is local or remote.
Before you can actually invoke the remote stored procedure, the DBRM has to be bound as a
package at the local DB2 server and as a remote package at the remote DB2 server, DB2R.
The package bind for the local DB2 should have the DBPROTOCOL(DRDA) option specified,
due to the explicit CONNECT statement. Observe that the local package is bound with
VALIDATE(RUN). This is because we make and unqualified call to a stored procedure the
local DB2 does not know about. The stored procedure is only defined at the remote data
server.
DB2 issues warning messages for unresolved objects during BIND with VALIDATE(RUN)
option, but completes successfully. The procedure name can then be resolved during runtime
unqualified CALL
EXEC SQL
CALL SP (parameter_list)
END-EXEC.
BIND for client looks like (only important options are shown).
Local bind:
BIND PACKAGE(col1) -
MEMBER(drpgm) -
LIBRARY(dbrm_library_name) -
PATH(schema) -
DBPROTOCOL(DRDA) -
VALIDATE(RUN)
Remote bind:
BIND PACKAGE(db2r.col1) -
MEMBER(drpgm) -
LIBRARY(dbrm_library_name) -
PATH(schema) -
VALIDATE(BIND)
BIND PLAN(plan_name) -
PKLIST(col1.drpgm, db2r.col1.drpgm) -
DBPROTOCOL(DRDA).
Both packages, local and remote, have to be bound to a local plan. Again the PKLIST option
is used for that. At the remote server, the package will be executed under the DISTSERV
plan. So, if you run any performance reports like accounting data, you might be interested to
know that it will appear under your local plan on local DB2 server and under DISTSERV on a
remote DB2 server.
Local SQL processing and remote procedure CALL from a DB2 application
As shown in Example 17-5 on page 365, the client program issues some SQL statements
that should be processed at the local DB2 server and additionally calls a remote stored
procedure. The preparation looks similar to Example 17-4 except that the remote package
bind also has the VALIDATE(RUN) option. This is because the tables referred to in local DB2
are not known to the remote DB2. The VALIDATE(RUN) option is therefore required to bypass
the error checking and successfully perform the remote bind. Another change is the
QUALIFIER option for a local package. QUALIFIER is used to qualify unqualified DB2 objects,
whereas the PATH option is used to qualify stored procedures and user-defined functions.
364 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Example 17-5 Client program with local SQL and invoking remote stored procedure
Client program looks like:
Remote SP call
EXEC SQL
CALL SP (parameter_list)
END-EXEC.
BIND for client looks like (only important options are shown).
Local bind:
BIND PACKAGE(col1) -
MEMBER(drpgm) -
LIBRARY(dbrm_library_name) -
PATH(schema) -
QUALIFER(qual) -
DBPROTOCOL(DRDA) -
VALIDATE(RUN)
Remote bind:
BIND PACKAGE(db2r.col1) -
MEMBER(drpgm) -
LIBRARY(dbrm_library_name) -
PATH(schema) -
VALIDATE(RUN)
BIND PLAN(plan_name) -
PKLIST(col1.drpgm, db2r.col1.drpgm) -
DBPROTOCOL(DRDA).
EXEC SQL
CALL SP (parameter_list)
EXEC SQL
CALL SP1 (parameter_list)
END-EXEC.
EXEC SQL
CALL SP2 (parameter_list)
END-EXEC.
BIND for client looks like (only important options are shown).
Local bind:
BIND PACKAGE(col1) -
MEMBER(drpgm) -
LIBRARY(dbrm_library_name) -
PATH(schema) -
DBPROTOCOL(DRDA) -
VALIDATE(RUN)
Remote bind:
BIND PACKAGE(db2r.col1) -
MEMBER(drpgm) -
LIBRARY(dbrm_library_name) -
PATH(schema) -
VALIDATE(RUN)
Remote bind:
BIND PACKAGE(db2s.col1) -
MEMBER(drpgm) -
LIBRARY(dbrm_library_name) -
PATH(schema) -
VALIDATE(RUN)
Remote bind:
BIND PACKAGE(db2p.col1) -
MEMBER(drpgm) -
LIBRARY(dbrm_library_name) -
PATH(schema) -
VALIDATE(RUN)
BIND PLAN(plan_name) -
PKLIST(col1.drpgm, db2r.col1.drpgm, -
db2s.col1.drpgm, db2p.col1.drpgm) -
DBPROTOCOL(DRDA).
At any point in time, the DB2 special register CURRENT SERVER indicates the location
name of the server to which the application thread is currently connected.
The DB2 statement CONNECT RESET can be used to reset the connection back to the local
DB2 subsystem.
366 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
17.2.3 Other considerations on preparing
Precompiler options
The following precompiler options are relevant for preparing a package to be run using DRDA
access:
CONNECT
Use CONNECT(2), explicitly or by default.
CONNECT(1) causes your CONNECT statements to allow only the restricted function
known as “remote unit of work”. Be particularly careful to avoid CONNECT(1) if your
application updates more than one DBMS in a single unit of work.
SQL
Use SQL(ALL) explicitly for a package that runs on a server that is not DB2 for z/OS. The
precompiler then accepts any statement that obeys DRDA rules.
Use SQL(DB2), explicitly or by default, if the server is DB2 for z/OS only. The precompiler
then rejects any statement that does not obey the rules of DB2 for z/OS.
368 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
18
Table 18-1 shows an example of different environments and levels for an application. As
shown, each level is designated for a specific purpose.
Each DB2 subsystem maintains a set of catalog tables which contain details about stored
procedures, packages and other pertinent information about DB2 objects. When an
application invokes a stored procedure, DB2 accesses these catalog tables. Like other DB2
objects, it is recommended to make unqualified references to stored procedures within the
application for easy portability. Therefore, it is important to understand the relationship
between the application code at different release levels and a DB2 subsystem. Depending on
the size and activity of your site, multiple environments can be mapped to a single DB2
subsystem, or each environment can be mapped to multiple DB2 subsystems. Note that the
entire discussion in this section is with regard to a single application and the management of
code levels for that application. Normally, DB2 subsystems are shared by multiple
applications,
We now look at some of the common configurations. In each configuration we assume that
there is a development, quality and production environment.
One DB2 subsystem per environment
In this configuration we have the three environments with one DB2 subsystem per
environment. There is no sharing of code or data across environments. Figure 18-1 shows
an example of this type of configuration. Notice that there can be multiple code levels
within each environment.
370 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Application = ABC
Development Quality Production
Level = D01 Level = Q01 Level = P01
Level = Q02
Level = D02 Level = P02
Level = Q03
Application = ABC
Development Quality Production
Level = D01 Level = Q01 Level = P01
Level = Q02
Level = D02 Level = P02
Level = Q03
DB2A DB2B
Application = ABC
Development Quality Production
Level = D01 Level = Q01 Level = P01
Level = Q02
Level = D02 Level = P02
Level = Q03
Figure 18-3 One DB2 subsystem for one or more levels of an environment
Once the code is developed and tested, it will be promoted to production to serve the
intended business functionality. Depending on the complexity of the environments,
configuration management of stored procedures can vary from a simple process to a most
complex one. Therefore, each site should have proper change management procedures in
place to ensure a smooth operation. Whatever the complexity of the environments, there are
two challenges that exist for the configuration management of stored procedures:
Maintaining different versions of stored procedures within a DB2 subsystem
Promoting stored procedures from the development environment to the production
environment
These challenges can be quite complicated if your site supports different types of stored
procedures like external (written in COBOL, C, PL/I, etc.), SQL Procedures language and
Java. Native SQL procedures introduced in DB2 9 for z/OS have additional versioning
capabilities that we will discuss.
372 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
18.2 Versioning of stored procedures
DB2 uses three variables to identify and execute a stored procedure at runtime: procedure
name, package name and load module name. In order to distinguish between different
versions of a stored procedure, we need to “qualify” the three variables. Let us study what
happens when a SQL CALL is made from an application to the point where the stored
procedure gets executed. There are several logical instructions happening; in this section we
just focus on the steps showing the relationship among the three variables for the following
CALL statement:
EXEC SQL
CALL PROC1 (:PARM1, :PARM2, :PARM3)
END-EXEC.
Figure 18-4 summarizes the connection between the variables at CALL time.
Application
CALL proc1
SYSIBM.SYSPACKAGE
1 Collid Name .....
2
WLMSQL1 hlq.load SPROA
........
3
WLM definitions ..........
WLM AE PROC Name EXEC SQL
Name
Steplib SPROA
WLMAE1 WLMSQL1 Select ...
DSN=hlq.load
WLMAE2 WLMSQL2 SPROB
End-Exec
........
Figure 18-4 Relationship between SCHEMA, COLLID and WLM Application Environment at runtime
Note: The external name of a stored procedure cannot be greater than eight characters
due to a restriction on z/OS on length of program name and member of load module. If
possible, it is recommended to have the name of the stored procedure also be no more
than eight characters, and the stored procedure name should be the same name as the
external name. We used different names for the purpose of demonstrating the
relationship between the two.
4. While executing the module SPROA, when the first SQL statement is encountered, DB2
locates the package SPROA under collection ID COL1 in SYSIBM.SYSPACKAGE.
Note: If the stored procedure is defined with NO COLLID, then DB2 uses the collection ID
of the caller.
As shown in the above steps, SCHEMA, COLLID, and the WLM_ENVIRONMENT name can
be used to locate and execute a unique stored procedure.
Table 18-2 summarizes the relationship between the variables DB2 uses to locate a stored
procedure and the qualifiers it uses.
Load module WLM Application Load module resides in a PDS or PDSE data set. By
environment name keeping multiple versions of a load module in different
load libraries and each load library concatenated to
different JCL procedures associated with a WLM
application environment, we can maintain multiple
versions of a load module. To make it simple, the
application environment can qualify the load module.
a. Package versioning is not possible for environments where compilation is done only once.
So, by defining a stored procedure with unique combinations of the above three qualifiers,
multiple versions of stored procedures can be maintained within the same DB2 subsystem.
Any combination of the three variables is possible. However, it is strongly recommended to
have a one-to-one relationship between SCHEMA, COLLID and WLM_ENVIRONMENT of a
stored procedure. The following section provides an example of how to access multiple
versions of a stored procedure in the same DB2 subsystem.
374 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
procedure. To make this possible, the following preparations are required to create multiple
versions of the stored procedure and multiple versions of the calling program.
Example 18-1 DDL to create four code levels of the same stored procedure
CREATE PROCEDURE SCH1.PROC1
(
parameter list...
)
EXTERNAL NAME SPROA
WLM ENVIRONMENT DB2QWL1
COLLID COL1 ;
2. Compile and link-edit the stored procedure PROC1. Ensure that the load module SPROA
is stored in four different load libraries. For instance:
for level Q01, the stored procedure load library is ‘hlq.ABC.DB2QWL1’
for level Q02, the stored procedure load library is ‘hlq.ABC.DB2QWL2’
for level Q03, the stored procedure load library is ‘hlq.ABC.DB2QWL3’
for level Q04, the stored procedure load library is ‘hlq.ABC.DB2QWL4’
The SPROA load module now exists in all the above libraries. Each library will contain the
load module for the version of the source code that was compiled and link-edited to that
library.
3. Bind the package SPROA with different collection IDs. The collection ID here should
match the collection ID specified in the CREATE PROCEDURE statement. If the stored
procedure is defined with NO COLLID, then the collection ID should match the collection
ID of the caller. For instance:
At the conclusion of the above steps there are now four versions of each component required
for stored procedure PROC1.
Table 18-3 shows that the procedure name remains the same across all code levels, while the
schema, which is used as the qualifier, and the collection ID change. Note that the package
name and external name are also the same across all four versions.
Table 18-3 Sample naming convention for versioning of a stored procedure in an environment
Level Procedure Schema Package Collection External WLM
name name ID name application
environment
name
The following SQL query will extract the different versions of a particular stored procedure
from the catalog:
Select Name, Schema, Collid, External_name, WLM_environment
from SYSIBM.SYSROUTINES
where name ='PROC1';
376 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 18-5 shows how the application ABC at multiple release levels (Q01 to Q04) can
access the same DB2 subsystem (DB2Q) and distinguish multiple versions of a stored
procedure based on the schema.
Application = ABC
Development Quality Production
Level = D01 Level = Q01 Level = Q02 Level = P01
DB2Q
Name Schema COLLID External WLM_ENVI
Name RONMENT
PROC1 SCH1 COL1 SPROA DB2QWL1
PROC1 SCH2 COL2 SPROA DB2QWL2
PROC1 SCH3 COL3 SPROA DB2QWL3
PROC1 SCH4 COL4 SPROA DB2QWL4
Stored procedures consist of two parts: One is source code and the other is DDL (the
CREATE PROCEDURE statement). Depending on the type of stored procedure (external
high-level language, external SQL language, or native SQL language) the two parts may exist
as two components or one component.
External high-level language: Source code + DDL (CREATE PROCEDURE statement).
The following sections explain in detail the necessary steps in the promotion of stored
procedures, depending on the change management policy and the type of stored procedures.
Figure 18-6 shows the development activities (on the left side of the picture) and the
production promotion activities (on the right side of the picture) for the “compile just once”
method for external high-level language stored procedures. We list the development activities
and promotion and/or installation activities below.
Development activities
1. Define the stored procedure using the CREATE PROCEDURE statement.
2. Precompile, compile and link-edit the source code, which produces a load module and a
DBRM.
3. Bind the DBRM to produce a DB2 package.
4. Refresh the WLM application environment.
5. Test and verify the stored procedure functionality.
378 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Ensure that SCHEMA, COLLID, and WLM AE correspond to the new environment or code
level.
4. Copy the DBRM and bind the DBRM to produce a DB2 package.
Ensure that the collection ID of the BIND statement and COLLID of the CREATE
PROCEDURE statement are the same.
5. Copy the load module and refresh the WLM AE.
Tip: A batch job can be built with all the above steps for repeated executions. IBM-supplied
sample job DSN8ED6 can be used to refresh WLM AE. Refer to the DSNTEJ6W job in the
hlq.SDSNSAMP data set to set up the WLM_REFRESH job.
Development Production
Source
Copy
modified
DDL and
DDL
modify
Compile and
link-edit
Bind Bind
Figure 18-6 Promotion of external high-level language stored procedures - Compile only once
If you developed your stored procedures using the Stored Procedure Builder or the
Development Center, then you could use the DB2Build utility, which executes on the client
side (UNIX and Windows), to promote your external SQL language stored procedures. But
this utility recompiles the program. Since your site’s policy is to compile just once in
Figure 18-7 shows the actions that are taken by Developer Workbench or Data Studio when
you are in the Deploy Wizard and click the option Deploy using binaries. We list the
development activities and promotion or installation activities below.
SYSROUTINES_SRC
Extract to a
dataset
Source
Copy and
Source Define stored
modify procedure
Figure 18-7 Promotion of external SQL language stored procedures - Compile only once
Development activities
1. Build an SQL procedure using either Developer Workbench or Data Studio.
2. Follow the steps in the Developer Workbench or Data Studio to deploy the stored
procedure in your development environment.
3. Test and verify the stored procedure functionality.
380 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Native SQL language stored procedures
DB2 9 for z/OS introduced native SQL language stored procedures. These procedures, like
external SQL language stored procedures, are written entirely in the SQL Procedures
language. The difference is that they do not get generated into C code and they run in the
DB2 engine instead of a WLM address space. Therefore, there are no load modules that
need to be link-edited and there are no WLM address spaces that need to be refreshed. For
details on deploying native SQL language stored procedures, see 15.5, “Deployment of a
native SQL procedure to another server” on page 301.
Figure 18-8 shows the development activities (on the left side of the picture) and the
production promotion activities (on the right side of the picture) for the “compile every time”
method for external high level language stored procedures. We now list the development
activities and promotion or installation activities.
Development activities
1. Define the stored procedure using the CREATE PROCEDURE statement.
2. Precompile, compile and link-edit the source code, which produces a load module and a
DBRM.
3. Bind the DBRM to produce a DB2 package.
4. Refresh the WLM application environment.
5. Test and verify the stored procedure functionality.
Note: A sample REXX DDLMOD and sample job DDLMODJB can be found in the
Additional material. See the notes inside the DDLMOD source code file on its usage.
3. Define the stored procedure using the modified DDL. IBM supplied programs DSNTIAD or
DSNTEP2 can be used.
Note: Ensure that SCHEMA, COLLID, and WLM AE correspond to the new
environment/code level.
Note: Ensure that collection ID of the BIND statement, and COLLID of the CREATE
PROCEDURE statement are the same.
Tip: A batch job can be built with all the above steps for repeated executions. IBM supplied
sample job DSN8ED6 can be used to refresh WLM AE. Refer to the DSNTEJ6W job in the
hlq.SDSNSAMP data set to set up WLM_REFRESH job.
Development Production
Compile Compile
and Copy and
link-edit and modified link-edit
DDL DDL
modify
LOAD LOAD
DBRM DBRM
module module
Bind Bind
Define Define
Refresh WLM Refresh WLM
stored stored
AE AE
procedure procedure
Figure 18-8 Promotion of external high level language stored procedures - Compile every time
Figure 18-9 shows the development activities (on the left side of the picture) and the
production promotion activities (on the right side of the picture) for the “compile every time”
382 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
method for external SQL language stored procedures. We list the development activities and
promotion/installation activities below.
Development activities
The development activities for external SQL language stored procedures in the “compile
every time” scenario are the same as in the “compile just once” scenario. The steps are as
follows:
1. Build SQL procedure using either Developer Workbench or Data Studio.
2. Follow the steps in the Developer Workbench or Data Studio to deploy the stored
procedure in your development environment.
3. Test and verify the stored procedure functionality.
After you have copied the source code to the production environment, you can then use
Developer Workbench or Data Studio to build the stored procedure in the production
environment using the same steps you used in the development environment, as shown in
Figure 18-9.
Define
SYSROUTINE_SRC Source stored
procedure
Extract to a
dataset Copy and
modify
Source Compile
and Refresh
link-edit WLM AE
Load module
Load
module
Figure 18-9 Promotion of external SQL language stored procedures - Compile every time
In DB2 for z/OS Stored Procedures: Give Them a CALL Through the Network, SG24-7083,
the authors describe some sample REXX execs, two of which, GETSQLSP and PUTSQLSP,
assist with this process. However, since Developer Workbench and Data Studio provide the
capability to deploy SQL language stored procedures using binaries, which perform the file
movement process for you, there is no longer a need for using the GETSQLSP and
PUTSQLSP REXX execs.
A third sample REXX exec, DDLMOD, is still useful for managing code for external high-level
language stored procedures, so we include documentation for DDLMOD in this chapter.
18.4.1 DDLMOD
Functionality
The DDLMOD exec is designed to allow you to easily generate the CREATE PROCEDURE
statement and supporting SQL statements for an existing stored procedure that is to be
moved from one environment to one or more other environments. This REXX exec performs
the source code and control statement copying function that is performed by the binary
deploy function within the stored procedure development tools. DDLMOD performs the
following two functions:
Modifies the DDL based on the values specified in the configuration file.
Generates SYSIN cards, which can be used for the WLM refresh job, the DROP
PROCEDURE statement, and the SET CURRENT SQLID statement.
Input parameter
Level: A unique ID representing an environment or code level. This level is provided as part of
the contents of the SYSTSIN DD statement after the name of the REXX exec. It is used to
determine which record in the configuration file to use for this execution of the REXX exec.
384 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
--------- ----- -------- ------- --------- --------
D01 DB9A DSCH1 DCOL1 DB9AWLM PROD7083
D02 DB9A DSCH2 DCOL2 DB9AWL2 PROD7083
Q01 DB9A QSCH1 QCOL1 DB9AWL1 PROD7083
Q02 DB9A QSCH2 QCOL2 DB9AWL2 PROD7083
Q03 DB9A QSCH3 QCOL3 DB9AWL3 PROD7083
Q04 DB9A QSCH4 QCOL4 DB9AWL4 PROD7083
P01 DB9A PSCH1 PCOL1 DB9AWL1 PROD7083
P02 DB9A PSCH2 PCOL2 DB9AWL2 PROD7083
Usage notes
DDLMOD REXX modifies the input DDL for the schema, the collection ID, and the WLM
application environment name, using the values provided in the record in the configuration
file that matches the level provided in the input parameter.
If your site requires some more parameters to be modified between environments/code
levels, the above REXX can be customized. What we provide is just a sample.
The output produced in the SETSQLID, DROPSP, and WLMRFRSH data sets will help to
automate the promotion process between environments. For example, SETSQLID will be
useful if your site implements secondary authorization IDs, and you use them while
defining the modified DDL. Similarly, DROPSP will be useful if you drop the stored
procedure before you create it. WLMRFRSH will be useful if you want to refresh the target
WLM address space in batch mode.
We ran the DDLMOD exec using the sample JCL in Example 18-3. The output shown in the
SYSOUT from running this job is shown in Example 18-4.
To see how the REXX exec works we can show you the CREATE PROCEDURE statement as
it appears before and after running DDLMOD. Example 18-5 shows the DDL that was input to
the DDLMOD job.
Example 18-6 shows the modified DDL after running the DDLMOD job. You can see that the
schema name, WLM environment name, and collection ID have been changed to the values
specified in the configuration file.
386 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Example 18-6 CREATE PROCEDURE statement after running DDLMOD
CREATE PROCEDURE DSCH2.EMPDSAMP
(
IN PEMPNO CHAR(6)
,OUT PFIRSTNME VARCHAR(12)
,OUT PMIDINIT CHAR(1)
,OUT PLASTNAME VARCHAR(15)
,OUT PWORKDEPT CHAR(3)
,OUT PHIREDATE DATE
,OUT PSALARY DEC(9,2)
,OUT PSQLCODE INTEGER
,OUT PSQLSTATE CHAR(5)
,OUT PSQLERRMC VARCHAR(250)
)
RESULT SETS 0
EXTERNAL NAME EMPDSAMP
LANGUAGE COBOL
PARAMETER STYLE GENERAL
MODIFIES SQL DATA
NO DBINFO
WLM ENVIRONMENT DB9AWL2
RESIDENT NO
COLLID DCOL2
TYPE SUB
COMMIT ON RETURN NO ;
If you have many environments and code levels you can set up a configuration file with
multiple records, like the sample file shown in Example 18-2, with one record for each
environment or code level to which you would promote a stored procedure.
For external high-level language stored procedures, once you promote your stored
procedures to production, further new versions of stored procedures do not necessarily
require you to drop and create the procedure. You can just promote the program associated
with the stored procedure for logical changes. You can issue an ALTER PROCEDURE
statement, wherever permissible, to change the definition. However, if you need to alter the
input and output parameters, you have to drop and recreate the stored procedure.
Part 4 Performance
In this part we discuss how an installation can manage the performance of the stored
procedures it executes. After a general introduction, the discussion is organized into the
themes of address space management and I/O management. Each theme is discussed in
detail, and instrumentation to support analysis for that theme is also described. The intent
here is to identify the key performance items which differentiate a stored procedure from a
normal DB2 transaction and provide some recommendations.
DB2 stored procedures enable the application designer to divide the application processing
between the client and the server:
Without stored procedures
In a client/server application, the client performs all application processing and the server
performs only database request (SQL) processing. With such an application, a network
send and receive operation is required for SQL statements like INSERT, UPDATE,
DELETE, and SELECT, while the SQL FETCH statement may only need one network
send and receive operation per block of rows returned by the server. The elapsed time of
an application may increase with the number of SQL statements, and it is heavily
dependent on the network connection speed.
There is also a certain amount of overhead associated with building the DRDA request
and reply messages. The network send and receive operations, and the overhead
associated with building messages increase the SQL path length for distributed
applications when compared to local DB2 SQL applications.
With stored procedures
The SQL CALL statement allows local DB2 applications or remote DRDA applications to
invoke stored procedures at a DB2 server. The client only has to issue a single network
send and receive operation to run a stored procedure at the server, and the stored
procedure can then issue multiple SQL statements. The use of stored procedures reduces
the number of network send and receive operations, thus improving the elapsed time and
CPU time consumed by an application. The SQL statements issued by a stored procedure
use a local DB2 interface (RRSAF), so there is no additional distributed overhead on the
SQL statements.
In order to take advantage of stored procedures, you need to understand their possible
impact on your current environment, and identify the key parameters that can be used to
optimize stored procedure performance.
392 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
19.1.1 The address spaces
When DB2 V4 introduced stored procedures, a new address space was added to the
traditional ones utilized by the DB2 subsystem. The DB2 Stored Procedure Address Space
(SPAS) is an allied address space dedicated to running stored procedures; it can be stopped
independently from DB2, and allows separation and protection of DB2 from application errors.
With DB2 V5, multiple stored procedure address spaces were supported, providing for
greater scalability and flexibility in handling applications with different priorities. The support
of multiple address spaces requires that the address spaces are managed by WLM in goal
mode. With DB2 V8, support for new stored procedures was only available with WLM
managed address spaces, however existing stored procedures could still run in the DB2
Stored Procedure Address Space (SPAS). With DB2 9 for z/OS, support for stored
procedures in the SPAS has been removed. Figure 19-1 shows the types of address spaces
that are typically active when stored procedures are being executed in DB2 9 for z/OS.
Highest xxxxWLMx
xxxxMSTR xxxxDBM1
xxxxDIST
WLM
Buffers,
IRLM
DDF Managed
System I/O
Work Stored
Services Services
Procs
z/OS
Similar
importance
The IRLM address space always needs to be assigned to a service class whose goal would
give it one of the highest MVS dispatching priorities, usually SYSSTC will suffice. IRLM needs
this priority because it manages resources that may or may not be accessed by work within
the DB2 address spaces.
Next, the DB2 system services address space (MSTR), DB2 database services address
space (DBM1), and the distributed data facility address space (DIST) should be assigned to
service classes whose goals would be similar, but would result in an MVS dispatching priority
just below the dispatching priority for the service class for the IRLM address space. The main
reason for including DIST in this list is that it is considered a service address space to MVS
Finally, the WLM-managed stored procedures address spaces themselves should be given a
goal much like and probably similar to the goal for the other main DB2 address spaces
(MSTR, DBM1, and DIST). These address spaces are MVS service address spaces and
need the priority to get new work started quickly. In their case, the better the priority, the
sooner a free TCB will get allocated to run a stored procedure. The lower the priority, the
longer it will take. See 20.1.4, “WLM management of server address spaces” on page 427 for
more information about classifying your workloads.
Stored procedures that run in WLM-managed address spaces run at the same priority as the
calling application. This ensures that the performance behavior of the stored procedure is
synchronized with the application that calls it.
Figure 19-2 helps in identifying the additional steps of the stored procedure.
Assume that an application is running on a client, this application needs first to connect to
DB2. DB2, then assigns a thread to the user and initiates an accounting process. Sometime
during its execution, the application decides to issue an SQL CALL, providing options, and
input and output parameters. The application waits while the stored procedure is executed;
processing in the application will continue only when the stored procedure completes.
In the meantime, DB2 handles the CALL, retrieves information about the stored procedure
from DB2 catalog table SYSIBM.SYSROUTINES (the WLM application environment name,
the load module name, and the input and output parameter definitions), then passes the
request to WLM. Most likely the information from the catalog will be cached, and no I/O will be
necessary.
WLM puts the request in a queue for the application environment specified in the DB2
catalog. If an address space is already started and there is an available TCB, then the stored
procedure is scheduled to run under one of the available TCBs. If there is no available TCB,
or there is no address space started, then WLM will start another address space and the
stored procedure will run under a TCB in the new address space. See Chapter 20, “Server
address space management” on page 423 for more details on how WLM uses TCBs and
address spaces to control execution of stored procedures.
DB2 will not have to create a new thread for the stored procedure because it runs under the
thread of the caller.
394 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
User
Application DB2 System WLM
COMMIT
The stored procedure address space uses the Language Environment product libraries that
are defined in the startup JCL for the address space to load and execute the stored
procedure. If the stored procedure was defined with the STAY RESIDENT YES option, the
load module may not need to be loaded.
Parameters are passed from the calling program to the stored procedure, according to the
parameter definitions in DB2 catalog table SYSIBM.SYSPARMS. In addition, any LE runtime
options specified when the procedure was created are in effect.
If the stored procedure contains SQL (remember, it does not have to!) then the DB2 package
for the stored procedure is loaded into the EDM pool.
The stored procedure starts executing and issues SQL calls handled by the DB2 subsystem.
The data returned by DB2 is moved by the Stored Procedure Manager to the output
parameters. If the stored procedure is written to return result sets to the calling program, then
the stored procedure will open the appropriate cursors, but not fetch any rows.
DB2 copies the output parameters received from the stored procedure to the client
application parameter area, and returns control to the client application.
The calling program receives the output parameters and continues the same unit of work. If
the stored procedure returned any result sets, then the calling program will fetch rows from
the result sets and process those rows, all within the same unit of work. The calling program
will then close the cursor for any result sets after fetching all the rows.
The client application issues a COMMIT statement, which commits the work done by the
stored procedure and by the client application. A COMMIT, either issued within the stored
Figure 19-3 shows the components of the execution time for a stored procedure, including
which components are counted in class 1 elapsed time and which components are counted in
class 2 elapsed time.
Class 1
Class 2
Figure 19-3 Where the execution time goes, including class 1 and class 2 breakdown
396 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Loading the package into the EDM pool
Before your stored procedure can execute, the package for the stored procedure must
reside in the EDM pool. If the package already exists in the EDM pool, then the time to
locate it is very small. If the package is not found in the EDM pool then there is a delay to
load it.
Loading the stored procedure object code
If the load module for the stored procedure has not already been loaded, then there is
some delay associated with loading it. The STAY RESIDENT option can impact whether
the stored procedure remains in storage. If the stored procedure is accessed frequently,
then there is a high probability that it will remain in storage even if defined with STAY
RESIDENT NO, and there will be no delay to load it.
Operating system delay
There may be some additional operating system or WLM workload delays depending on
the level of CPU constraint on your system.
Access to non-DB2 resources
If your stored procedure accesses non-DB2 resources, such as VSAM files or IMS
databases, then that also contributes to the execution time of the procedure.
Stored procedure SQL execution
The time spent executing SQL statements within the procedure is included here. This time
will show up under package accounting time. See 19.2.2, “Reporting on DB2 accounting
class 7 and 8 data” on page 402 for more details on DB2 accounting time for stored
procedures.
Note: There is also an execution time component for SQL processing associated with
the stored procedure, but which occurs after returning to the calling application. This
includes time spent in result set processing and time spent in commit processing, if
COMMIT ON RETURN is specified. This time, as well as time associated with
scheduling the stored procedure, is charged under the package name SYSSTAT. If you
have stored procedures that execute a small amount of SQL and return large result
sets, then it is not unusual to see the SYSSTAT package account for more time than the
stored procedure package.
You can see that there are many components to the execution of a stored procedure. There
are differences depending on whether the stored procedure is called from a distributed client
through DDF, or if it is called locally by another application running on z/OS. You will need to
monitor each of these components to ensure that your stored procedures are performing
efficiently. We discuss in more detail the CPU costs of these components, and how to monitor
these costs in the sections that follow.
1.6
1.38
1.4 1.3
1.21
1.2 1
1 0.82
0.8 0.65
0.53
0.6
0.37
0.4
0.2
0
G6 (9672 z800 G6 turbo z900 z900 z890 z990 z9 (2094)
x17) (2066) (9672 (2064-1) turbo (2086) (2084)
z17) (2064-2)
Figure 19-4 CPU multiplier across the evolution
DB2 9 for z/OS extensively uses the long-displacement instruction set that is available in
z/Architecture® mode, which was introduced with 64-bit addressing. These instructions are
available on the System z990, z890, and System z9 models in z/Architecture mode that
exploit the long-displacement instruction set. Previous CPU models do not have such
hardware support and are run in emulation mode. Therefore, some penalty in CPU overhead
will occur when running DB2 9 for z/OS on System z900 and z800 models because the
hardware support is simulated by microcode.
Estimates of CPU times for components of an online transaction running on the host:
Read-only commit = 45 to 90 µs
Update commit = 160 to 280 µs
Create/Terminate Thread = 250 to 500 µs
– Or, with thread reuse and release deallocate = 80 µs for signon
Distributed Create/Terminate Thread = 2000 to 4000 µs
– Or, inactive thread = 300 to 600 µs
What happens if the data is accessed from a distributed client? The CPU time estimates for
DRDA access are:
If block fetch not in effect = 210 µs for each SQL call
If block fetch in effect = 5 to 10 µs for each Fetch SQL call:
+ 80 µs for each message
+ 300 to 600 µs for inactive thread scheduling per transaction (2000 to 4000 µs if Create/
Terminate Thread)
For each SQL call in DRDA non block fetch, add:
28 to 56 µs + 170 µs message send/receive = 210 µs
398 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Block Fetch is enabled if:
– The query is read-only.
– Or, CURRENT DATA NO specified and an ambiguous cursor exists (dynamic SQL
present).
What happens if the data is accessed through a stored procedure call from a distributed
client? The CPU time estimates for a stored procedure access are:
Stored procedure invocation CPU time = 220 to 560 µs
+ 170 µs for each message send/receive
You can have between zero and two message send/receive transmissions for each stored
procedure call: each message send and message receive takes 170 µs.
– Zero messages sent or received if the stored procedure is local.
– One message sent and none received if the stored procedure is defined with COMMIT
ON RETURN and is WLM-managed (default = no commit on return): 170 µs.
– Two messages incurred (one send and one receive) if the stored procedure is
distributed, and is either defined with COMMIT ON RETUN NO or is DB2-managed:
340 µs in a distributed environment.
In our measurements, we assume the stored procedure is defined as STAY RESIDENT YES
to avoid stored procedure reloading (default= NO).
Note that in addition to a reduction in CPU time, the stored procedure will also experience
faster response times because there is only one send/receive pair versus ten for the
distributed access case.
There have been numerous performance studies done for stored procedures, but in many
cases the cost comparison for some of the languages is so close that it is difficult, if not
impossible, to definitively state that one language performs better than another. We can
conclude from these studies that COBOL and C stored procedures generally tend to be the
best performers, while interpreted languages such as Java and REXX tend to be the slowest
performers. Stored procedures written using external and native SQL Language fall
somewhere in between and can vary based on your environment.
External SQL procedures can incur the overhead of extra SELECT statements against the
SYSDUMMY1 table for some SQL statements because some SQL control statements are
similar to C language statements and require DB2 to perform an extra translation. This
overhead is less with native SQL procedures because all of the runtime structures are
generated as a control section which contains the logic part of the program; there is no need
for DB2 to perform an extra translation that requires access to the SYSDUMMY1 table
because there is no need to generate C language statements. In some cases both external
SQL language and native SQL language procedures need to access the SYSDUMMY1 table
and in some cases only external SQL procedures have to access SYSDUMMY1. In no case
is SYSDUMMY1 access required for native SQL procedures and not for external SQL
procedures.
Native SQL procedures have the additional advantage of running as an enclave SRB and
remote native SQL procedures are eligible to be run on a zIIP processor. This should not be
overlooked when doing capacity planning and when considering the total software cost of a
solution.
When a WLM application environment goes into stopped state, it sends the message
IWM032I to the console. This is not a highlighted message; some proactive method should be
400 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
in place to track this message, and take an action to bring the WLM application environment
up again.
In this section we briefly describe the most common functions and tools that you can use to
monitor and measure a stored procedure’s performance. It is important to be current on
maintenance. See Appendix A: Summary of performance maintenance for DB2 V9 in DB2 9
for z/OS Performance Topics, SG24-7473 for a list of performance related APARs.
You can see from the report that all the procedures are started except EMPDTL2C and
EMPDTL3C. EMPDTL3C is in STOPREJ status, which indicates that a -STOP PROCEDURE
command was issued with the ACTION(REJECT) option. Any subsequent requests for the
procedure are rejected. EMPDTL2C is in STOPQUE status, which indicates that a -STOP
PROCEDURE command was issued with the ACTION(QUEUE) option. Any subsequent
requests for the procedure are queued. You can see in the QUED column that there is one
stored procedure request queued for EMPDTL2C. If there were any procedures in STOPABN
status, which is also displayed in the STATUS column, that would indicate that the procedure
experienced an abend and the maximum number of abends as defined by zparm
For each stored procedure, you also see the number of active and queued threads; the
maximum number of queued threads waiting concurrently since DB2 was last started; the
number of times an SQL CALL statement timed out waiting for the procedure to be
scheduled; and the number of times the procedure failed. All of these values are reset when
you issue a START PROCEDURE command. You can use this information to monitor the
behavior of each application environment and adjust the number of TCBs, or move
applications to different environments as needed.
Note that native SQL procedures will not show up in the output of a -DISPLAY PROCEDURE
command unless you run the procedures in DEBUG mode. If you do run the procedure in
DEBUG mode, the WLM environment column in the output contains the “ WLM
ENVIRONMENT FOR DEBUG MODE name” that you specified when you created the native
SQL procedure. For more details on native SQL procedures, see Chapter 15, “Native SQL
procedures” on page 253.
For more details on starting traces and the appropriate trace classes to choose, see IBM
Tivoli OMEGAMON XE for DB2 Performance Expert on z/OS Version 4.1.0, Reporting User’s
Guide, SC18-9983-01. Another source of information on this tool is IBM DB2 Performance
Expert for z/OS Version 2, SG24-6867-01. Example 19-1 shows a sample -START TRACE
command that you can use to start an accounting trace for monitoring stored procedures.
402 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Example 19-1 START TRACE command to monitor stored procedures
-START TRACE(ACCTG) CLASS(1,2,3,7,8)
If you have either the IBM Tivoli OMEGAMON XE for DB2 Performance Expert on z/OS or
IBM Tivoli OMEGAMON XE for DB2 Performance Monitor on z/OS tool installed, you can
start your trace using the DB2 PM Workstation Monitor or DB2 PM Online Monitor. For our
test cases we used DB2 PM batch and the Online Monitor for our monitoring. If you have
other performance monitoring tools, you will need to review the documentation for those tools
to determine how to best monitor stored procedure performance.
DB2 PM provides monitoring capabilities for stored procedures in both batch and online
mode. Batch monitoring reports on activity for a given time period. Online monitoring reports
on stored procedure activity for active threads.
Batch monitoring
Since stored procedures run under the plan of the caller, you can see stored procedure
activity in the accounting report for the appropriate plan, which will often be the plan for your
distributed application. In our test cases, the Java stored procedures were run under a plan
name of javaw.ex. Example 19-2 shows a stored procedures section from a DB2 PM
Accounting Long Report, which lists information about the stored procedure activity for that
plan.
Example 19-2 Stored procedures trace block of DB2 PM Accounting Long Report
PRIMAUTH: PAOLOR5 PLANNAME: javaw.ex
The AVERAGE column represents the average number of occurrences per thread during the
monitoring duration, while the TOTAL column represents the total number of occurrences for
all threads during the monitoring duration.
To see accounting information for the stored procedures themselves, you need to look at the
data for the stored procedure package. You can do a search for your package name within the
accounting report. Information for each package executed during the reporting period is
displayed within the section of the report for the associated plan name. In our test case one of
the stored procedures executed is EMPRSETC, which was executed under plan javaw.ex,
which is a Java plan initiated from a distributed platform. Example 19-3 shows a package
identification section from a DB2 PM Accounting Long Report, which lists information about
the activity within stored procedure EMPRSETC.
EMPRSETC VALUE
------------------ ------------------
TYPE PACKAGE
LOCATION DB2G
COLLECTION ID DEVL7083
PROGRAM NAME EMPRSETC
OCCURRENCES 1
SQL STMT - AVERAGE 2.00
SQL STMT - TOTAL 2
STOR PROC EXECUTED 0
UDF EXECUTED 0
USED BY STOR PROC 1
USED BY UDF 0
USED BY TRIGGER 0
SUCC AUTH CHECK 0
The pertinent counters for stored procedures in this section of the report are:
STOR PROC EXECUTED: The number of stored procedures scheduled by this package
USED BY STOR PROC: The number of times this package was invoked by a stored
procedure
The Accounting Long Report also provides information that can help you tune your WLM
address spaces. The reporting of elapsed time includes various counters for SUSPEND
TIME, including SUSPEND TIME STORED PROC. This counter reports on the total elapsed
time waiting for an available TCB before a stored procedure could be scheduled. Since the
elapsed time counters show average times, you would expect this field to be non zero for
stored procedures, because it is likely that at some point WLM would either need to start a
new address space or need to add more TCBs to an existing address space. However, you
would like this counter to be as small as possible.
The Accounting Long Report extract in Example 19-4 shows that the stored procedure
suspend time accounts for about 38% of the total stored procedure elapsed time. This is an
indication that the stored procedure request had a fairly long wait for a TCB to be scheduled.
Example 19-4 Accounting Long Report showing stored procedure suspend time
AVERAGE APPL(CL.1) DB2 (CL.2)
------------ ---------- ----------
ELAPSED TIME 0.463223 0.001396
NONNESTED 0.040053 0.000691
STORED PROC 0.423170 0.000704
UDF 0.000000 0.000000
TRIGGER 0.000000 0.000000
404 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
IIP CPU TIME 0.000000 0.000000
STORED PROC 0.000000 0.000000
In this test case we were running a very small number of stored procedures, so the wait time
is likely to be overstated when compared to a production environment where many stored
procedures are running in the same address space and can use available TCBs. WLM’s
Resource Adjustment function, described in 20.1.4, “WLM management of server address
spaces” on page 427 explains how WLM determines when to start new address spaces and
when it is better to wait for an available TCB in an already started address space.
See DB2 Performance Monitor for z/OS Version 7.2, Report Reference, SC27-1647 for more
details on the layout of the Accounting Long Report.
Online monitoring
You can use DB2 Performance Expert or DB2 Performance Monitor to report on the activity of
currently executing threads. You can use these tools to monitor stored procedures that you
know are causing you problems. We used DB2 Performance Expert for z/OS Version 1 to
monitor stored procedures in our test cases. Follow these steps to view stored procedure
activity for the thread being monitored:
1. From the DB2 PE main menu, select option 3. View online DB2 activity.
2. From the Online Monitor Main Menu, select option 1. Display Thread Activity.
3. The Thread Summary panel is displayed, as shown in Figure 19-6.
DB2G DB2G V7
To display a thread, place any character next to it, then press Enter.
4. Select the thread that you wish to monitor and press Enter. The Thread Detail panel is
displayed, as shown in Figure 19-7. Elapsed and CPU times are displayed.
For details, place any character next to heading, then press Enter.
More: +
_ Thread Identification
Primauth . . . . . : PAOLOR5 Correlation Name . . . : javaw.ex
Planname . . . . . : DISTSERV Connection type . . . . : DRDA
Connection ID . . : SERVER Type . . . . . . . . . : DBAT
Requesting Location: 9.1.39.26 Status . . . . . . . . : APPL
_ Current Package . . . . . . . . . . . : DSNJDBC2
s Times Elapsed CPU
Class 1 . . . . . . . . . . . . . . . . . : 4:54.216568 0.002834
Class 2 . . . . . . . . . . . . . . . . . : 0.001407 0.002926
Class 3 . . . . . . . . . . . . . . . . . : 26.492065 N/A
Class 7 . . . . . . . . . . . . . . . . . : 0.000465 0.000278
Class 8 . . . . . . . . . . . . . . . . . : N/P N/A
_ Locking Activity
Timeouts . . . . . . . . . . . . . . . . . : 0
Deadlocks . . . . . . . . . . . . . . . . : 0
Suspensions . . . . . . . . . . . . . . . : 0
Lock escalations . . . . . . . . . . . . . : 0
Maximum page locks held . . . . . . . . . : 0
Select the Times option to see details on elapsed and CPU times for the thread. The
Thread Times panel is displayed, as shown in Figure 19-8 and Figure 19-9.
0 ________________________________________________________________________
| Thread Times | _
| Command ===> ________________________________________________________ |
| |
| More: + | +
| Class 1 Class 2 |
| In Appl In DB2 Outside DB2 |
| Elapsed time . . . . . . : 4:54.216568 0.001407 4:54.215161 |
| CPU time . . . . . . . . : 0.002834 0.002926 N/C |
| TCB . . . . . . . . . : 0.001022 0.001199 N/C |
| TCB - Stored Proc . . : 0.001811 0.001727 |
| Parallel tasks . . . . : 0.000000 0.000000 |
| Waiting time . . . . . . : N/A 0.000208 |
| Suspension time . . . . : N/A 26.492065 |
| TCB . . . . . . . . . : N/A 26.492065 |
| Parallel tasks . . . . : N/A 0.000000 |
| Not accounted . . . . . : N/A N/C |
| Time Event |
| Suspensions (Class 3) . . . . . . . . . : 26.492065 2 |
| Locks and latches . . . . . . . . . . : 0.000000 0 |
| Synchronous I/O . . . . . . . . . . . : 0.000000 0 |
| Other read I/O . . . . . . . . . . . : 0.000000 0 |
| Other write I/O . . . . . . . . . . . : 0.000000 0 |
406 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
0 ________________________________________________________________________
| Thread Times | _
| Command ===> ________________________________________________________ |
| |
| More: - + | +
| Other write I/O . . . . . . . . . . . : 0.000000 0 |
| Services task switch . . . . . . . . : 0.000000 0 |
| Archive log (quiesce) . . . . . . . . : 0.000000 0 |
| Archive log read . . . . . . . . . . : 0.000000 0 |
| Drain lock . . . . . . . . . . . . . : 0.000000 0 |
| Claim release . . . . . . . . . . . . : 0.000000 0 |
| Page latch . . . . . . . . . . . . . : 0.000000 0 |
| Stored procedures . . . . . . . . . . : 26.492065 3 |
| Notify messages . . . . . . . . . . . : 0.000000 0 |
| Global contention . . . . . . . . . . : 0.000000 0 |
| |
| DB2 entry/exit events |
| Non stored procedures . . . . . . . . : 2 |
| Stored procedures . . . . . . . . . . : 10 |
| |
| Class 5 (IFI) |
| Elapsed time . . . . . . . . . . . . . : N/P |
| TCB time . . . . . . . . . . . . . . . : N/P |
In the Thread Times panels you can see details for class 1, class 2, and class 3 times. Note
that the total class 3 (suspensions) time is 26.49 seconds, and that the stored procedure
suspension time accounts for all of that total. This means that there was a wait time of 26.49
seconds for an available TCB before the stored procedure could be scheduled. This is a
considerably high number, which is most likely due to our NUMTCB value being set too low
for our test case.
Returning to the Thread Detail panel, we can now select the option to see the SQL activity for
the thread, as shown in Figure 19-10.
For details, place any character next to heading, then press Enter.
More: - +
_ Locked Resources
_ RID List Processing
Unsuccessful - any reason . . . . . . . . : 0
s SQL Activity, Commits and Rollbacks
DML . . . : 14 Commit . . . . . . : 0
DCL . . . : 2 Rollback . . . . . : 0
DDL . . . : 0 Changes/Commit . . : 2.0
_ Buffer Manager Activity
Getpage requests . . . . . . . . . . . . . : 34
Buffer updates . . . . . . . . . . . . . . : 7
Prefetch requests . . . . . . . . . . . . : 2
Synchronous I/O . . . . . . . . . . . . . : 0
_ SQL Statement and Package . . . . . . . . : DSNJDBC2
_ Distributed Data
Requester elapsed time . . . . . . . . . . : N/A
_ IFI (Class 5) and Data Capture
_ Query Parallelism Data
Data Sharing Locking Activity
The SQL Activity panel is displayed. This panel shows you counts for each type of SQL
statement executed within the thread. You need to scroll forward to see all the counters. The
SQL Activity panels for our test case are shown in Figure 19-11, Figure 19-12, and
Figure 19-13 on page 410. The SQL Activity panels show us that there were two stored
procedures called during the time that this thread was monitored (SQL call = 2 on
Figure 19-13) and there were nine rows fetched from cursors (Fetch = 9 on Figure 19-12).
408 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
0 ______________________________________________________ DB2G DB2G V7
| SQL Activity | ____________________
| Command ===> _____________________________________ |
| |
| More: + |
| Incremental bind . . . . . . . . . . : 0 |
| Reoptimization . . . . . . . . . . . : 0 |
| Prepare statement match . . . . . . . : 1 |
| Prepare statement no match . . . . . : 0 |
| Implicit prepare . . . . . . . . . . : 0 |
| Prepare from cache . . . . . . . . . : 0 |
| Cache limit exceeded . . . . . . . . : 0 |
| Prepare statement purged . . . . . . : 0 |
| Commit . . . . . . . . . . . . . . . : 0 |
| Rollback . . . . . . . . . . . . . . : 0 |
| Changes/Commit . . . . . . . . . . . : 2.0 |
| |
| Total DML . . . . . . . . . . . . . . : 14 |
| Select . . . . . . . . . . . . . . : 0 |
| Insert . . . . . . . . . . . . . . : 1 |
| Update . . . . . . . . . . . . . . : 0 |
| Delete . . . . . . . . . . . . . . : 1 |
| Prepare . . . . . . . . . . . . . . : 1 |
As you can see there is a large quantity of performance information available for stored
procedures. For more details on monitoring the performance of stored procedures during real
time, see DB2 Performance Expert for z/OS Version 1 Monitoring Performance from ISPF,
SC27-1652-02.
Example 19-5 Stored procedures trace block of DB2 PM Statistics Long Report
STORED PROCEDURES QUANTITY /SECOND /THREAD /COMMIT
--------------------------- -------- ------- ------- -------
CALL STATEMENT EXECUTED 16.00 0.02 0.64 0.62
PROCEDURE ABENDED 0.00 0.00 0.00 0.00
CALL STATEMENT TIMED OUT 0.00 0.00 0.00 0.00
CALL STATEMENT REJECTED 0.00 0.00 0.00 0.00
See DB2 Performance Monitor for z/OS Version 7.2, Report Reference, SC27-1647-02 for
more details on the layout of the Statistics Long Report.
19.2.4 RMF
You can use RMF™ to monitor distributed processing, including stored procedures called
from a distributed client. RMF reports on SMF type 72 records, which monitors the portions of
the client’s request that are covered by individual enclaves. The duration of the enclave
410 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
depends on whether the threads are active or inactive. We recommend you use type 2
inactive threads. RMF reports on the time that the thread is active. This includes any
queueing time, which includes the time waiting for an existing thread or new thread to become
available.
The type 72 records contain data collected by RMF monitor 1. There is one type 72 record for
each service class period, report class, performance group number (PGN) period, and report
performance group (RPGN) per RMF monitor 1 interval. Each enclave contributes its data to
one type 72 for the service class or PGN and to zero or one (0 or 1) type 72 records for the
report class or RPGN. By using WLM classification rules, you can segregate enclaves into
different service classes or report classes (or PGNs or RPGNs, if using compatibility mode).
By doing this, you can understand the DDF work better.
Example 19-6 shows a sample job to run an RMF monitor 1 report that shows workload by
service class. The literal DDFSP8 represents the service class we are monitoring. To monitor
a different service class, change the variable. To monitor a service class period use the
keyword SCPER instead of SCLASS.
See z/OS V1R7.0 Resource Management Facility User’s Guide, SC33-7990-10 for details on
producing RMF reports.
Block fetch
Stored procedures work best for applications with many non-blocked SQL statements.
Distributed applications can take advantage of block fetch for read-only cursors. Applications
About block fetching, it is worth considering that prior to the addition of the FETCH FIRST
clause, the OPTIMIZE FOR clause was used to control network blocking and to control
access path selection. With the addition of the FETCH FIRST clause, its interaction with the
OPTIMIZE FOR clause also influenced network blocking and access path selection. If both
clauses are specified and the customer is using OPTIMIZE FOR for the desired blocking and
access path selection, the FETCH FIRST clause can override the OPTIMIZE FOR clause if
its value was less than the OPTIMIZE FOR value. DB2 V7 APAR PQ49458 has modified the
behavior of the FETCH FIRST n ROWS ONLY clause as follows:
The FETCH FIRST clause will have no impact on network blocking. If the FETCH FIRST
clause is specified and the OPTIMIZE FOR clause is not specified, access path will use
the FETCH FIRST value for optimization, but DRDA will not consider the value when it
determines network blocking.
When both the OPTIMIZE FOR clause and FETCH FIRST clause are specified, the
OPTIMIZE FOR value will be honored even if it is greater than the FETCH FIRST value.
Currently, if both clauses are specified, the lower of the two integer values is used for
access path selection. However, if a customer is explicitly specifying both clauses, DB2
should use the specified values since they may have been chosen for performance
reasons.
Note: With DB2 V8, DRDA internally and automatically exploits multi-row operations.
This means that for remote transactions, the fetching and inserting of rows between the
DDF and DBADM1 address spaces will benefit from fewer interactions.
NUMTCB
When you define each WLM application environment, you specify a NUMTCB value.
NUMTCB specifies the maximum number of TCBs that can run concurrently in a WLM
address space. When a request for a TCB is received, and the maximum number of TCBs for
that address space is already reached, WLM needs to start another address space for that
application environment. Your stored procedure has to wait for that address space to be
scheduled. The wait time is shown in DB2 accounting as part of the class 1 (suspension) time
(see Example 19-4 on page 404). You can adjust the NUMTCB value of each application
environment to meet the performance needs for those environments. See 20.1.2, “NUMTCB”
on page 425 for more details on the implications of your NUMTCB settings.
Note that installation panel DSNTIPX - ROUTINE PARAMETERS includes a field named
NUMBER OF TCBS. The value of this field is used as the default NUMTCB value when
address space JCL is generated.
Native SQL procedures run under an enclave SRB so they are not subject to any NUMTCB
limits.
Note: Starting with DB2 for z/OS V8, Workload Manager will not automatically assign the
number of TCBs that is specified in NUMTCB. Instead, WLM will consider the NUMTCB
value as a maximum and will manage the number of TCBs in an address space based on
resource utilization. See 20.2.4, “Recommendation - Exploit WLM server task thread
management” on page 433 for more details.
412 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
CREATE PROCEDURE statement
There are a number of options on the CREATE PROCEDURE statement, which can impact
the performance of your stored procedures. We discuss each of the options here.
PROGRAM TYPE (SUB or MAIN)
– If you specify MAIN, then your stored procedure and all its called modules run as main
routines. The load modules for any programs called by your stored procedure are
reloaded into memory for each execution, and then are deleted from memory at the
end of each execution. Although reloading each time ensures that all work areas are
initialized, there is considerable overhead incurred.
– If you specify SUB, then your stored procedure and all its called modules run as
subroutines. The load modules for any programs called by your stored procedure
remain in memory after they have been loaded the first time. Specifying SUB reduces
the overhead of loading modules, but it forces application developers to ensure that
work areas are properly initialized.
STAY RESIDENT (YES or NO)
– If you specify YES, then the load module for your stored procedure remains in memory
after it has been loaded the first time. This has no impact on any programs called by
the stored procedure. Specifying YES reduces the overhead of loading modules, but it
forces application developers to ensure that work areas are properly initialized.
– If you specify NO, then the load module for your stored procedure is loaded into
memory each time it is called, and then deleted from memory at the end of each
execution, unless there are other tasks that are accessing the stored procedure. This
has no impact on any programs called by the stored procedure. Although reloading
each time ensures that all work areas are initialized, there is considerable overhead
incurred.
COMMIT ON RETURN (YES or NO)
– If you specify YES, then DB2 issues a commit when the stored procedure returns to
the calling program. This commits the work of the stored procedure, and the work of
the calling application. This is useful for distributed applications because it releases the
locks held by the client. However, if the stored procedure is called via a connection
established via DB2 Connect in a sysplex environment where sysplex workload
balancing is enabled, the client does not see the commit and does not know to reuse
the connection. This can affect how work is distributed among members of a sysplex. If
the connection is established via a Java Type 4 connection, then the client will
recognize the commit and the connection can be reused.
– If you specify NO, then DB2 does not issue a COMMIT when the stored procedure
returns to the calling program. It is the calling program’s responsibility to issue a
commit or a rollback.
– If you code a COMMIT inside the stored procedure, regardless of the COMMIT ON
RETURN setting, the thread is not eligible to become an INACTIVE thread.
PARAMETER STYLE (GENERAL, GENERAL WITH NULLS, SQL)
– If you specify GENERAL, then only the parameters on the call statement are passed to
the stored procedure. You have the capability to set output parameters to null by
including null indicators for those parameters, but you cannot set input parameters to
null. Therefore all input parameters are passed to the stored procedure.
– If you specify GENERAL WITH NULLS or SQL, then you can set both input and output
parameters to null and reduce the amount of information that is passed to and from the
stored procedure. Prior to DB2 for z/OS V8 the value of DB2SQL was used instead of
SQL. In DB2 V8 and V9 the value of DB2SQL is still accepted and acts as a synonym
for PARAMETER STYLE SQL.
If you do not provide any classification rules for your DDF workload, then default service
classes apply. Stored procedures will default to the SYSOTHER service class, which has a
discretionary goal. This means that when the system is near capacity, your DDF work will not
get the resources it needs to complete. You can prevent work from falling into a service class
with a discretionary goal by making sure that all combinations of workloads are covered by
the classification rules. For example, you can define one service class at the subsystem level,
then another for a list of packages that start with some common characters. See Chapter 36,
“Assigning procedures and functions to WLM application environments” in the DB2 UDB for
z/OS Version 8 Administration Guide, SC18-7413 for details on setting address space
priorities.
For the library access, the LE libraries should be placed in LLA with the FREEZE option,
either if allocated through LNKLST or STEPLIB. Further improvements can be obtained by
placing in LPA the eligible portion of SCEERUN as listed in LPALST. For details, see the z/OS
1.4 Language Environment Customization, SA22-7564-4.
There is some overhead in establishing this environment, especially in regard to the amount
of storage required by LE when running many stored procedures concurrently. You can
minimize the storage required below the 16 MB line for LE by specifying some runtime
options when you create your stored procedures. See 19.3, “Recommendations” on page 418
for more details.
414 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Important: If you group stored procedures of different language types, such as COBOL
and C, in the same environment, each language may have different LE runtime options.
When stored procedures that are defined with PROGRAM TYPE SUB with one set of LE
runtime options execute in an application environment, and are followed by a stored
procedure with a different set of LE runtime options in the same environment, all the stored
procedures with the initial set of LE runtime options are invalidated, and must be reloaded
at the next execution. When the stored procedures with the original runtime options are
subsequently executed, the stored procedure that had the different options is now
invalidated, and must be reloaded upon next execution. The effect is that the LE
environment is refreshed, making it behave more like PROGRAM TYPE MAIN, and even
worse, because all modules loaded into that environment are deleted. So, you can see that
mixing stored procedures with different LE options is not a good idea.
Note that you can run into this same issue with stored procedures written in the same
language with the same default LE runtime options if you specifically set runtime options
for a stored procedure. For example, you can use the TEST runtime option for debugging
purposes. Some customers specify an IP address in the TEST option during development,
but neglect to remove that runtime option when deploying the stored procedure in
production. As a result, there are multiple stored procedures running in the same
application environment that have different runtime options and the LE environment is
refreshed each time a stored procedure is loaded that has different runtime options than
the last stored procedure that ran in that application environment. This can be very costly
in terms of performance. For more details on using the TEST runtime option, see 5.2.3,
“TEST and NOTEST” on page 49.
You want to separate your Java stored procedures from your other language stored
procedures. Since Java stored procedures load a JVM into the application environment for
each TCB, and the JVM can be quite large, you can realistically run with a NUMTCB value of
no more than 8 for an application environment that runs Java code. If you mix stored
procedures written in other languages with your Java stored procedures, you are limiting the
number of procedures you can run for the other language. Furthermore, the whole
environment is torn down between Java and non-Java, and then the JVM is recreated on the
next stored procedure call whether or not a Java stored procedure is invoked there next. If the
WLM environment is set up for Java, DB2 makes sure to have a JVM ready.
There are also some considerations for nested stored procedures. If you have a stored
procedure running in one address space that calls another stored procedure that runs in the
same address space, you can experience a situation where the nested stored procedure is
waiting on a TCB, and the stored procedure that called the nested procedure is waiting for the
nested procedure to complete. If you are using nested stored procedures, you should
consider placing them in a separate application environment from the stored procedures that
call them.
DSNTRACE facility
DSNTRACE is a facility that can be used to capture all trace messages for offline reference
and diagnosis. We recommend that you do not use the DSNTRACE DD statement (not even
a DUMMY DD name) in any of your stored procedures address space startup procedures,
because DSNTRACE greatly increases the stored procedure initialization overhead. Also,
DSNTRACE does not function in a multitasking environment because the CAF does not
serialize access to the DSNTRACE trace data set.
Authorization caching
DB2 system parameter CACHERAC controls the size of the routine authorization cache,
which stores authorization IDs for stored procedures once DB2 has retrieved them from the
DB2 catalog and validated them. Specifying a routine authorization cache that is too small
can cause entries in the cache to be overwritten and require DB2 to re-read those entries
from the DB2 catalog.
IBM Tivoli OMEGAMON XE for DB2 Performance Monitor on z/OS (DB2 PM) reports on the
effectiveness of the routine authorization cache in the Authorization Management section of
the Statistics Report. Example 19-7 shows an excerpt from the Authorization Management
section.
In this sample report you can see that more than half of the time DB2 could not find the
needed authorization in the cache, as shown by the value in RTN-AUTH UNSUCC-CACHE.
In those instances DB2 had to read the authorization from the DB2 catalog. You can expect a
high number of unsuccessful cache reads if every stored procedure request came in with a
different authorization ID than the previous one, but that is usually not the case. The counter
RTN CACHE OVERWRT - AUTH ID represents how many times an authorization ID in the
cache was overwritten due to there not being enough space to store additional authorization
IDs.
If you are using the default value for CACHERAC, which is 32 KB in DB2 V7 and 100 KB in
DB2 V8, and you see a non-zero value in RTN CACHE OVERWRT - AUTH ID, then you need
to increase the size of your cache. The default value of 32 KB in V7 is enough to hold about
370 routines. The default value of 100 KB in V8 and V9 is enough to hold about 690 routines.
Note that the size of many objects in DB2 changed from DB2 V7 to V8, so if your routines fit
nicely in the authorization cache in V7 it does not necessarily mean they will fit nicely in the
V8 cache if you maintain a cache size of 32 KB. Note also that a maximum of five
authorization IDs can be cached for each routine, so if you don’t use secondary authids you
won’t get as much benefit from the cache. See 7.5.8, “Authorization caching” on page 81 for
more details on the process DB2 follows to search for authorization IDs.
416 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Accounting data as package SQLPROCEDURECOLS. If you are using the IBM Data Server
Driver for JDBC and SQLJ, also known as the IBM Universal Driver, on your client platform,
then you will not see the calls to this routine. The IBM Universal Driver assumes the maximum
size for output parameters and never tries to call any metadata procedures.
If your client platform is still using the legacy JDBC driver (not supported with DB2 V9), then
there is a db2cli.ini option provided in DB2 for LUW Version 8, fixpak 12 called "DescribeCall"
which, when set to 0, will block the DESCRIBE from happening on CALL statements.
There is also an issue with the legacy JDBC driver when there is a data type mismatch
between the parameters passed and the DB2 column definitions on SET statements. This
data type mismatch will also result in a call to SQLPROCEDURECOLS to DESCRIBE the
parameters. There is a db2cli.ini parameter called “DescribeParam” which, when set to 0, will
block the DESCRIBE from happening.
You can actually prevent calls to the metadata procedure SQLPROCEDURECOLS for both of
the above situations by setting either of the two above parameters to zero. What happens is
that setting either parameter to zero will tell CLI that SQLDescribeParam is not supported,
and the DESCRIBE will not happen for any function triggering DESCRIBE information,
regardless of the type of SQL statement.
There is another db2cli.ini setting that you can use to minimize the impact of the DESCRIBE
of the stored procedure parameters in a client environment that uses the legacy JDBC driver.
Parameter SPCache, when set to 1, will cache DESCRIBE information returned from
metadata procedure SQLPROCEDURECOLS. If a subsequent call to the same stored
procedure occurs on the same connection, then the DESCRIBE does not need to happen.
This parameter is disabled by default.
If you reference LOBs or distinct types in your stored procedure, you need to perform the
metadata calls to SQLPROCEDURECOLS or your application will receive an error. This is the
case where SPCache=1 should be used to minimize the overhead.
We recommend that you migrate your DB2 for LUW client environment to use the IBM
Universal Driver so you do not have to worry about adjusting db2cli.ini file settings.
Non-resettable JVMs
DB2 for z/OS Version 8 APAR PK09213 provides new function that allows Java applications
to run in non-resettable mode. Prior to this APAR all Java stored procedures ran in a Java
Virtual Machine (JVM) in resettable mode, which limited what Java routines could do in order
that the JVM did not become corrupted. Running in resettable mode also limited how many
stored procedures you could run in an address space because of memory constraints.
After applying this APAR, which requires the IBM Universal Driver, you can run Java stored
procedures in non-resettable mode by specifying a value of less than zero for Java
environment variable RESET_FREQ. This variable specifies the number of routine
invocations between JVM resets. Setting RESET_FREQ to a negative value in effect prevents
the JVM from being reset. This lets you specify a larger amount of memory for Java stored
procedures, therefore allowing you to run more stored procedures in an address space.
Where you previously could only run 5 to 7 TCBs in an address space, you can now run 20 to
40 TCBs, although this depends on the size of your Java stored procedures and the settings
you use for the non-system heap (-Xmx) and for the middleware heap (-Xms). For more
details on making use of this feature, see the APAR text for APAR PK09213.
DB2 9 for z/OS supports two types of inactive threads: an inactive DBAT and an inactive
connection. An inactive connection allows the thread to be pooled and reused for other
connections. Therefore a smaller number of threads can be used to service a larger number
of connections. A CMTSTAT value of INACTIVE is recommended whether you use stored
procedures or any other processing that requires a database access thread. Note that prior to
DB2 for z/OS V8 the default for this system parameter was ACTIVE. For DB2 V8 and beyond
the default is INACTIVE.
19.3 Recommendations
Here, we group some recommendations for parameter definition of the following:
For the CREATE PROCEDURE statement
For the Language Environment
For nested stored procedures
Handling result sets from DB2-supplied stored procedures
418 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
We recommend that you specify NO for stored procedures that are called locally.
We recommend that you do not specifically code a COMMIT statement in a stored
procedure if it is called from a distributed client application because the thread will not be
eligible to become an INACTIVE thread.
PARAMETER STYLE (GENERAL WITH NULLS or SQL)
We recommend that you specify either GENERAL WITH NULLS or SQL. Either of these
options will give you the capability to set IN, OUT, and INOUT parameters to null in your
calling programs and stored procedures by setting the associated indicator value to a
negative value. Nullifying parameters that are not used during either a call to or a return
from a stored procedure reduces the amount of data that is passed. For example, output
parameters do not have data in them during the call to the stored procedure, so you can
nullify the output parameters in the calling program. For stored procedures that are called
by distributed applications this can result in a savings in the amount of data transferred
across the network, thus a reduction in network transmission time. Prior to DB2 for z/OS
V8 the value of DB2SQL was used instead of SQL. In DB2 V8 and V9 the value of
DB2SQL is still accepted and acts as a synonym for PARAMETER STYLE SQL.
Use WLM-managed stored procedures
Although you will be able to maintain existing DB2-managed stored procedures in DB2 for
z/OS Version 8, you will not be able to create any new DB2-managed stored procedures.
In DB2 9 for z/OS you must convert all of your DB2-managed stored procedures to
WLM-managed stored procedures as DB2 9 does not support DB2-managed stored
procedures at all. WLM-managed stored procedures provide much more flexibility with
regards to setting priorities on stored procedure workloads, and segregating workloads to
lessen the impact that one inefficient stored procedure can have on the rest of the stored
procedures in your environment. You need to make sure that your WLM classification rules
have been defined for your stored procedure workloads to prevent them from running in a
default service class that has a discretionary goal. See Chapter 20, “Server address
space management” on page 423 for more information on managing your WLM address
spaces.
Consider the cost of invoking a stored procedure versus the cost of network transmission
for a distributed application.
When developing distributed applications, the amount of SQL you expect to execute
should be a factor in deciding whether to use stored procedures. One of the main
advantages of stored procedures is that multiple SQL statements can be executed in one
call to the mainframe, rather than issuing many calls over the network to do one SQL
statement for each call. The trade-off for the minimum number of SQL statements where it
is more efficient to call a stored procedure varies by the amount of data being selected
and transmitted, but a good rule of thumb is that you should have four or more SQL
statements to see a performance benefit from stored procedures. Remember that you may
also have other reasons besides performance for using stored procedures, such as code
reuse and security.
Use the Language Environment (LE) runtime options to minimize storage usage.
There are a number of LE runtime options that you can specify to minimize storage usage
below the 16 MB line. They are documented in Chapter 25, DB2 Version 9.1 for z/OS
You can list these options in the RUN OPTIONS parameter of the CREATE PROCEDURE, or
the ALTER PROCEDURE statement if they are not Language Environment installation
defaults. For example, the RUN OPTIONS parameter can specify:
H(,,ANY),STAC(,,ANY,),STO(,,,4K),BE(4K,,),LIBS(4K,,),ALL31(ON)
See Appendix B, “Additional material” on page 887 for details on accessing the DDL for the
CREATE PROCEDURE statement for example stored procedure EMPODB1C, which
includes the above RUN OPTIONS settings.
DB2 uses the Workload Manager (WLM) to schedule every stored procedure that is invoked,
or every UDF that is the first UDF of the cursor that is being accessed. Whether the stored
procedures are nested or not is not a factor in terms of performance. The cost of using the
WLM to schedule the stored procedure is the same whether the stored procedure is the
highest level stored procedure in the nesting or the lowest.
You declare the Workload Manager environment in which you need to run a particular stored
procedure. DB2 honors that declaration, because it assumes that your program is dependent
on certain things in that WLM procedure. For instance, your program might be dependent on
the STEPLIB concatenation to get the right program loaded into memory. Your program might
also be dependent on certain DD cards in the procedure that provide access to specific data
sets. There is a wide variety of other possible dependencies for a particular WLM procedure.
So, the question is: If I have stored procedure A defined in WLM environment 1, and stored
procedure B defined in WLM environment 2, how can I force them both to run in WLM
environment 1? DB2 has no mechanism for that situation. DB2 assumes that you put stored
procedure B into WLM environment 2, because you had a dependency on that WLM
environment, so DB2 honors that association for the life of the stored procedure. Scheduling
the stored procedures in the same address space does not offer a significant performance
advantage.
420 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
stored procedures on your subsystem, and run clients that use the JCC such as WebSphere
type 2 and 4 JCC drivers, make sure that primary space is large enough and secondary is 0
for optimal performance.
Read this chapter if your work is missing its performance goals and there is reason to believe
that stored procedures are not being scheduled quickly enough. Criteria for establishing this
are discussed in 20.2.1, “When to adjust WLM’s management of server address spaces” on
page 429.
Note: In this chapter we only discuss the server address spaces that Workload Manager
(WLM) manages. The previous implementation (the DB2-established stored procedures
address space) is not discussed. We also assume that WLM is operating in goal mode, as
compatibility mode is no longer available starting with z/OS V1R3.
All work in a system is assigned a service class (SC). A service class is a group of work with
similar performance goals, resource requirements, or business importance. Each stored
procedure or User Defined Function (UDF) is assigned a specific Application Environment
(AE). A work queue is created for each combination of SC and AE. When an application
invokes a stored procedure, its SC and the stored procedure’s AE determine which work
queue it joins.
Each work queue has at least one server address space to service its requests. WLM creates
additional server address spaces as required, based on the arrival patterns of work on that
queue. WLM also deletes server address spaces when they are no longer needed.
Each server address space contains a number of TCBs, which are ATTACHed when the
address space is started. Each concurrently executing stored procedure requires at least one
TCB:
If the stored procedure does not call another stored procedure or invoke a UDF, a single
TCB is required.
If the stored procedure does call another stored procedure or invokes a UDF, additional
TCBs are required. If these in turn call other stored procedures or invoke more UDFs,
additional TCBs are required.
TCBs are acquired for the life of the stored procedure execution:
When the stored procedure starts, it is scheduled to run on a TCB.
When a top level stored procedure starts, the TCB it runs on joins the caller’s WLM
enclave. This is true even if the caller is not distributed. If this stored procedure calls other
stored procedures or UDFs, their TCBs also join the enclave. An enclave is an
independent dispatchable unit of work, which is basically a business transaction that can
span multiple address spaces, and can include multiple SRBs and TCBs.
When the stored procedure finishes, it frees up the TCB for another stored procedure to
use.
When one stored procedure calls another, the caller’s TCB is suspended while the called
stored procedure runs.
UDFs behave slightly differently. For a row level UDF, the TCB is retained until all rows have
been processed. This means a UDF can require a TCB for the life of a unit of work, whereas
a stored procedure might release it, decreasing the utilization of TCBs.
424 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
In this case a single TCB is required, joining the enclave created from the batch job’s TCB.
In this case the top-level stored procedure requires a TCB, and each of the stored procedures
it calls requires its own TCB. These nested (or second-level) stored procedures run at
different times, so the most TCBs required at any one time is two, not three.
The population of required TCBs depends on the stored procedures workload. In particular,
the degree of concurrency and the nesting complexity of the stored procedures determine
how many TCBs are needed at any time. In the nested stored procedures’ case, many of
these TCBs might be suspended waiting for other stored procedures they call to end.
20.1.2 NUMTCB
Each application environment (AE) is assigned its own NUMTCB value, which defaults to 8.
NUMTCB specifies the maximum number of TCBs a server address space can use to
concurrently process stored procedure requests for the AE it supports. Because each work
queue contains requests for stored procedures from a single AE, each address space
servicing that queue is subject to the same NUMTCB value, which is the same maximum
number of TCBs.
The higher the NUMTCB value, the more concurrent stored procedures can be processed in
parallel by a single server address space. More concurrent stored procedures in a single
server address space potentially means:
More CPU cycles consumed per second by the server address space
Each concurrent TCB can be dispatched independently on a processor, so a larger
NUMTCB allows more concurrent execution.
More virtual storage allocated and used by the server address space
Stored procedures may allocate and use virtual storage both below the 2 GB line and
above the 2 GB line within a server address space. Each stored procedure allocates and
uses its own virtual storage, to store the load module and for work areas, so a higher
NUMTCB value leads to more concurrent virtual storage usage.
More real storage used by the server address space
An increase in virtual storage leads to an increase in real storage.
A higher Input/output (I/O) rate to non-DB2 data accessed by the server address space
Individual stored procedures can perform I/O at the same time, so an increase in
NUMTCB can lead to a higher I/O rate.
In general, a larger NUMTCB value for a server address space means the server address
space consumes more resources.
For some types of stored procedures, the NUMTCB value specified for its AE is constrained
by specific considerations:
20.1.3 How TCBs drive the demand for server address spaces
TCBs must reside in an address space. When stored procedures run, they acquire TCBs in
server address spaces. A server address space can only contain a limited number of TCBs,
determined by the NUMTCB value for the queue. See 20.1.2, “NUMTCB” on page 425 for
more information on NUMTCB.
For a single work queue (combination of SC and AE) there are dedicated server address
spaces, and hence a predetermined number of TCBs, available. Demand for server address
spaces depends on the arrival pattern of stored procedures:
When a stored procedure request arrives, it requires a TCB to be able to start. If all the
TCBs in the existing server address spaces for its work queue are already processing
stored procedures, another server address space is needed.
When a stored procedure ends, the TCB it acquired is relinquished. If there were no other
TCBs in use in its server address space, there will be no TCB in use when the stored
procedure ends.
WLM manages the creation and termination of server address spaces. It might not
immediately create a server address space if creating a new address space would negatively
impact other work in z/OS. Similarly, WLM might not immediately terminate a server address
space when all of its TCBs become unused if there is a statistical likelihood that new work will
arrive shortly that will acquire a TCB in the address space. See 20.1.4, “WLM management of
server address spaces” on page 427 for details on how WLM’s Resource Adjustment function
determines when to create or terminate a server address space.
Because the creation of a server address space may be delayed, the acquisition of a TCB
may be delayed, and the stored procedure might not immediately run. This has two potential
consequences:
If a stored procedure does not immediately run, the elapsed time of the calling application
will be increased, perhaps to an unacceptable extent.
Another stored procedure might terminate before the new server address space is
created. If so, its TCBs become available for the waiting stored procedure to use. In this
case, the new server address space will not be created, and the waiting stored procedure
will reuse these newly-released TCBs.
426 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Note: With nested stored procedures (where one stored procedure calls another) the
number of TCBs concurrently required might be quite large, especially if the level of
nesting is quite large. For this reason, nested stored procedures are particularly intensive
in their use of TCBs, and particularly bursty. That is, a large number of TCBs might
suddenly be acquired when a stored procedure executes. Similarly, a large number of
TCBs might be relinquished almost simultaneously when a nested stored procedure
terminates.
If a calling stored procedure is defined to use a different AE from the stored procedure it
calls, the two stored procedures are in different work queues. In such a case, the two TCBs
to run these stored procedures may be created in different server address spaces. If you
define your stored procedures with the WLM ENVIRONMENT parameter of the form
(name,*) then the nested stored procedure will run in the same AE as the calling stored
procedure; they may or may not run in the same address space, depending on available
TCBs.
Note: The caller of the stored procedure determines what classification rule the stored
procedure runs under. The default service class assigned to that classification rule will be
used. However, you do have the capability to define the service class the work will run
under at a granular level. For DB2 work, you can categorize work by such criteria as
package name, stored procedure name, userid and correlation ID, among other criteria.
Once categorized, you can define a different service class definition for each category or
individual stored procedure. This is especially useful if you have a situation where some
procedures are more mission critical than others and require more stringent response time
or velocity goals.
WLM manages work in the system by trying to meet two conflicting objectives:
Meeting the goals of work running in SCs
Optimizing the use of resources
With stored procedures, this translates into a trade-off between minimizing the delay to start
new server address spaces, and minimizing the number of server address spaces:
The faster WLM starts a new server address space, the less delay there is to the work
waiting for the address space to start its stored procedure’s TCB.
The slower WLM is in starting a new server address space, the greater the chance it will
not have to start it, and hence the more optimal the use of resources.
WLM’s Resource Adjustment function runs every two seconds, but will only add one server
address space in a 10-second interval. During resource adjustment, WLM checks goal
attainment and system conditions.
Under the following circumstances WLM may create another server address space:
Adding a server address space would help an SC meet its goals better.
This might be the case if there is a build up of stored procedures waiting for a TCB, caused
by a shortage of server address spaces.
Adding a server address space would not impact other work in the system.
WLM uses the resource profile of existing server address spaces servicing the work
queue to determine the likely impact of adding another server address space. The main
resource considered is CPU, but memory is also considered.
WLM will never start more than one new server address space for a work queue in any
10-second interval. If system conditions are unfavorable, it might take more than ten seconds
for an additional server address space to be created, even if a stored procedure is delayed by
this additional wait for a server address space (and hence a TCB). The 10-second minimum
interval introduces latency. The 10-second cycle was chosen when WLM was developed to
minimize the resources required to run WLM algorithms, and to provide enough performance
data for WLM to make good decisions.
Because of this latency, it is desirable to avoid the need to create additional server address
spaces. The main control for minimizing the need to create additional server address spaces
is NUMTCB. By specifying a higher value of NUMTCB, more concurrent stored procedures
can be run in each server address space. But, the likelihood of WLM delaying starting a new
428 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
server address space is increased the more resources the server address space is expected
to consume. In other words, the larger the NUMTCB value, the more resources WLM expects
the address space to consume, so WLM may delay in starting that address space to see if
work will finish in the already started address space. In 20.1.2, “NUMTCB” on page 425, we
describe how a server address space’s resource consumption is related to the server address
space’s NUMTCB value.
The larger the NUMTCB value, the smaller the likelihood that a server address space will
have no TCBs processing stored procedures. So, a large NUMTCB value reduces the need to
start and stop server address spaces as the stored procedures workload fluctuates. But a
large NUMTCB value may inhibit WLM from being able to adjust the number of server
address spaces as the workload fluctuates.
Workloads that are likely to require more active management have some of the following
characteristics:
The workload is bursty rather than unvarying.
The workload is highly complex.
The workload has particularly stringent performance requirements.
The workload is high volume.
Note: Business goals are not necessarily the same as WLM goals. In a well managed
environment, WLM goals do reflect business goals. If business goals and WLM goals
are in alignment, examining the attainment of WLM goals is sufficient.
2. Establish if stored procedure scheduling delays are a significant factor in the work not
meeting business goals:
– If important work is missing its business goals and stored procedure scheduling delays
are a significant factor, you should actively manage server address spaces.
– If important work is missing its business goals, but stored procedure scheduling delays
are not a significant factor, you should direct your tuning efforts elsewhere.
You can check if a WLM service class is meeting its goals using Resource Management
Facility’s (RMF) Workload Activity report. RMF also writes SMF Type 72 records containing
the same information. Most installations use reporting software to track WLM goal attainment,
using SMF Type 72 records. If the performance index for a goal is greater than 1, the goal is
not attained. A value of 1 or less for the performance index means the goal was attained.
------------------------------------------------------------------------------
You can check if DB2 work is delayed waiting for a server address space to be scheduled by
examining two fields in DB2 Accounting Trace (SMF Type 101):
QWACCAST Wait time for a stored procedure to be scheduled
QWACUDST Wait for a User Defined Function (UDF) to be scheduled
These fields are available in the SMF 101 record only if Accounting Trace Class 3 is on.
Example 20-2 shows a DB2 application that is delayed waiting for a server address space to
be created so that a stored procedure can run. The SUSPEND TIME STORED PROC field
shows this application was delayed for 0.177809 seconds. As the ELAPSED TIME field is
only 0.463223 seconds, this delay is a significant contributor. In short, 38% of the elapsed
time is due to waiting for a stored procedure to be scheduled. In this example, the time is
dominated by Class 1 time in stored procedures, the STORED PROC value being 0.423170
seconds.
Most of the time was caused by the fact that we were running a very small number of stored
procedures. If we had run additional stored procedures in this test it is likely that subsequent
stored procedures would not have to wait for a TCB until we had enough activity so that WLM
determined it had to start another address space.
430 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Example 20-2 Sample DB2 Performance Monitor Accounting Report listing
AVERAGE APPL(CL.1) DB2 (CL.2)
------------ ---------- ----------
ELAPSED TIME 0.463223 0.001396
NONNESTED 0.040053 0.000691
STORED PROC 0.423170 0.000704
UDF 0.000000 0.000000
TRIGGER 0.000000 0.000000
The Accounting Report summarizes transactions by interval, so it averages out the values
and tends to mask bursts of activities. Often, an Accounting Trace might be needed in order to
have details on all the transactions, but this will of course cause large amounts of data.
Starting with DB2 V8, the classification of stored procedure and UDF wait times in the
Accounting Report were changed from class 3 suspensions to class 1 suspensions, as shown
in Example 20-2.
Note: Stored procedures schedule wait times and UDF schedule wait times are not
calculated at the package level. The fields QPACCAST and QPACUDST always contain
zeroes. The reason that these wait times are not calculated at the package level is that
once the stored procedure or UDF package is loaded, the wait for scheduling is already
completed. Therefore, the schedule wait time only occurs at the plan level.
You can affect WLM control of server address spaces in a number of different ways:
You can change the NUMTCB value for the application environments (AE) your most
important stored procedures run in.
By increasing the NUMTCB value you can reduce the need to start additional server
address spaces. By decreasing the NUMTCB value, you may be able to decrease the time
to start another server address space. Installations will need to establish how this trade off
works in their environment.
Taken together, these measures can have a significant impact on how WLM starts and stops
server address spaces, and hence application performance.
432 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
When successful, this technique reduces the Language Environment (LE) enclave
initiation and termination cost for the stored procedure.
Program life cycle management
Keeping frequently reused programs resident in virtual storage (by specifying STAY
RESIDENT YES), rather than continually reloading them, will reduce CPU cycles and
reduce the elapsed time of the stored procedure execution. But keeping infrequently
executed programs in memory increases the server address space’s virtual storage
requirement. For non-critical, infrequently executed programs you may wish to define them
with STAY RESIDENT NO.
Virtual storage tuning
This can mean either reducing virtual storage usage, or increasing it. Normally, it is better
to reduce virtual storage usage:
– To reduce the requirement for real storage
– To allow more concurrent stored procedures to be supported in a server address space
without abnormal terminations
Where garbage collection is CPU intensive it might be better to use more virtual storage to
reduce the cost of garbage collection, provided you have the real storage to back the
virtual storage.
These techniques often interact with each other, sometimes negatively. So select the
techniques carefully.
To help analyze the use of resources by different types of stored procedures, you should
name the server address spaces in such a way that it is clear which AE they serve. With this
naming convention SMF Type 30 Subtypes 2 and 3 records can be used to determine the
resource consumption by each server address space. This information can be used to
observe the starting and stopping of WLM application environments. And furthermore, you
can see the weight of the address space - in terms of (non-DB2) I/O, memory and CPU from
the Type 30 records. Recall that the weight feeds into WLM decisions about whether it can
afford to start another address space that services the same queue. Therefore,
understanding the weight of each AE can help you in your WLM environment.
You may wish to specify a NUMTCB value other than 1 in cases where you previously
specified 1, since WLM will determine the appropriate number of tasks to run in an address
space and will also determine when to start a new address space. If you specify a NUMTCB
value of 1 you will not be able to take advantage of this capability. If you have sufficient
available memory, NUMTCB can easily be around 60 for languages such as COBOL or C, or
20 to 40 for Java stored procedures that are run in non-resettable mode.
This recommendation only applies for stored procedures that are able to share the resources
in one address space. There are still some stored procedures, for example DSNUTILS and
REXX programs, which require a value of 1 in NUMTCB.
Read this chapter if you believe non-DB2 I/O time and contention are a significant factor in the
performance of your stored procedures. This chapter does not talk about DB2 I/O because
that is not a topic specific to stored procedures. The importance of normal DB2 I/O tuning
applies to stored procedures.
This chapter is not a primer on I/O tuning. This subject has been covered in detail in many
other books. Its purpose is to highlight the nature of I/O and ENQs that can delay stored
procedures.
If your stored procedures do perform significant I/O, and performance objectives are not
being met, consider tuning stored procedures access to data. Also, consider the need to tune
program loading.
Because stored procedures server address spaces are multitasking, special considerations
apply for accessing non-DB2 data. Some access methods do not tolerate more than one task
accessing data at the same time, even if they are in the same address space. In some cases
you can share the same physical resource using ENQs.
Note: If a stored procedure issues an ENQ for a resource that another stored procedure
holds, the requester will be delayed until the holder issues a DEQ for that resource.
436 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Notes on SMF Type 42 Subtype 6 data
This data will not give any information for cases where another address space
accesses the data set. An example of this is where a stored procedure invokes a CICS
transaction.
Estimates of cache hit ratio are based on sampled disconnect time, rather than a cache
hit count in the disk controller. A value of less than half a millisecond is regarded as a
cache hit. More than half a millisecond is regarded as a miss. This technique is
susceptible to cases where disconnect time is significant, other than cache misses. An
example of this is synchronous remote copy, where much of the disconnect time for a
write I/O is waiting for the second copy to be written to another disk.
The easiest approach to tuning the I/O from a server address space is to establish which data
sets are being the most heavily used. Summarizing the SMF Type 42 Subtype 6 data by data
set across the work’s peak, sorting by total I/O time produces a prioritized list of data sets to
tune. Your z/OS performance analyst probably already has a job to do this reporting.
Example 21-1 is the output of such a reporting job. It is a simplified version of the PMDB2
service offering’s Top Data Set report. In this case the breakdown of the response times into
their components has been removed. In this example, it is a DB2 subsystem’s DBM1 address
space whose data sets are shown. As this is a large DB2 subsystem, it is not surprising that
the top ten data sets only represent 5.7% of the I/O subsystem’s I/O time.
Having established a list of data sets to work on, tune each data set based on its specific
characteristics. Some frequently encountered stored procedures data sets are:
Load libraries
Each stored procedure execution requires a load module to run. If the load module is not
already in server address space memory, or if the stored procedure is unable to use an in
memory copy, the load module must be fetched. If the STAY RESIDENT YES and
PROGRAM TYPE SUB options have been specified, and the load module has been link
edited with the RENT option, the likelihood is very high that the load module will be in the
server address space’s memory and usable by the stored procedure. In production
environments, with little change to the stored procedure’s program logic, these options are
recommended.
If the load module must be fetched, the z/OS Library Lookaside (LLA) function can be
used. LLA buffers load modules and load library directories in memory using the Virtual
Lookaside Facility (VLF). VLF tracks the number of times each module is loaded.
Frequently loaded modules are buffered in VLF data spaces.
438 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Part 5
C is the only high-level programming language that allows you to write a stored procedure
with secondary threads, where each thread can establish its own connections to the same or
different subsystems.
There are two advantages to implementing multiple threads in the stored procedure rather
than on the client:
The complexity of the code on the client is reduced to a single SQL CALL statement.
Even programming languages that do not support multi-threading can make use of a
multi-threaded stored procedure, with the potential of dramatically improving performance.
Stored procedures running on a z/OS server benefit from the computing power and
scalability of the platform.
Creating threads on the server performs considerably better than creating threads on the
client because there is no network communication overhead.
The primary thread of the stored procedure typically acts as the scheduler: it creates
secondary threads and synchronizes with them to exchange data using shared variables.
Synchronization of the control flow of the primary and secondary threads as well as
serialization of access to shared variables is accomplished using interprocess communication
mechanisms including semaphores and condition variables.
The primary thread implicitly uses RRSAF calls. You do not have to establish a database
connection explicitly any more. If you include explicit attachment facility calls in the primary
thread, DB2 rejects the calls. When you enter the main routine of the stored procedure you
are in the unit of work from the client that called the stored procedure.
However, when you create secondary threads from your main routine, these threads have no
implicit database connection. If required, you have to explicitly establish a database
connection using RRSAF from every thread that has to execute SQL statements.
Since DB2 considers the WLM-established stored procedure address space an allied
address space, it is of critical importance that the termination of these secondary threads
occurs in a coordinated manner, when all SQL activity in the secondary threads has ended.
The case study demonstrates how to do this.
You can have all your threads connect to the subsystem the primary thread is connected to or
different subsystems e.g. different members on a data sharing system for load balancing.
If you are not familiar with terms relating to the development of multi-threaded applications
(such as critical section, mutex, condition variable, or semaphore), consult the chapter “Using
threads in z/OS UNIX System Services applications” of z/OS C/C++ Programming Guide,
SC09-4765-08.
Examples of how to use mutex objects and condition variables can be found in z/OS C/C++
Programming Guide, SC09-4765-08 and z/OS C/C++ Run-Time Library Reference,
SA22-7821-09.
442 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
22.2 Which style threads to use
On z/OS you can use MTF or POSIX-style threads. If your threads have to connect to DB2,
you have to use POSIX-style threads. POSIX style threads are available on almost any
platform that makes your multi-threaded C stored procedure code portable.
Example 22-1 shows the definition of the created global temporary table in which the calling
application inserts the names of the table spaces.
After inserting the table spaces, the calling application calls the stored procedure RUNSTATP
defined in Example 22-2.
The stored procedure does not require any input parameters. After successful execution,
UTILITIES_EX contains the number of utility executions; the HIGHEST_RETCODE is the
highest DSNUTILS return code, the RETCODE from RUNSTATP itself (in case there was a
runtime or SQL error) and a message area.
It is required to use the run option POSIX(ON), otherwise the POSIX calls fail.
Every thread the stored procedure creates requires a TCB in the WLM address space.
Ensure that NUMTCB of the WLM application environment equals or is greater than the
maximum number of threads that your stored procedure creates plus 1 (for the main thread).
Otherwise, thread execution will be serialized.
Like DSNUTILS, RUNSTATP inserts the output from all utilities into a created global
temporary table, and opens a cursor on it before it returns. Example 22-3 shows the definition
of that table.
The code snippet from the calling Java application (shown in Example 22-4) helps to better
understand how to use RUNSTATP. After getting the connection, the calling program sets
AutoCommit to false, so that after inserting into the global temporary table the instance of the
table does not get reset by a COMMIT. We insert the table space names into the parameter
table before calling RUNSTATP. In our example, a list of two table space names is inserted
into the table. After that, RUNSTATP is called to run RUNSTATS on them in parallel.
Example 22-5 shows how to check for errors after the RUNSTATP call. The result set contains
utility messages and those should be printed if available. Even when the execution stopped
after just one utility and the return code is higher than 0, it is important to print whatever
output the utilities produced.
Next, the RUNSTATP return code rc is queried. If rc is greater than zero, an error occurred in
the stored procedure and we need to print the error message, which indicates the location
444 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
where the error occurred. If RUNSTATP executed successfully, we still check if the utilities ran
to completion by checking if the highest DSNUTILS return code is greater than 4.
The execution needs operator attention and intervention if either the RUNSTATP return code
was greater than 0, or the highest DSNUTILS return code was greater than 4.
if (hasResultSet)
{
rs = cs.getResultSet();
while (rs.next())
System.out.println(rs.getString(2));
rs.close();
}
cs.close();
System.out.println("DB2Runstats successful.");
con.commit();
Now we take a closer look at the stored procedure itself. In the following paragraph, we
discuss the listing. As listed in Chapter 11, “C programming” on page 147 the first element is
“Includes and compiler defines.”
You have to include pthread.h and define _OPEN_THREADS to use POSIX threads in your
stored procedure. Each thread requires its own user-defined SQLCA to avoid having to
serialize its usage. Instead of placing EXEC SQL INCLUDE SQLCA in the global scope, use
#include <sqlca.h> and add structure sqlca at the beginning of any routine that uses SQL.
See Example 22-6.
/********************************************************************/
/* Define messages. */
/********************************************************************/
#define ERR_OPEN_RS_CSR "*** SQL error when opening result set \
cursor..."
#define ERR_CLR_RS_TBL "*** SQL error when clearing result \
table..."
#define ERR_THD_IDENTIFY "Error in utility thread RRSAF \
IDENTIFY call..."
#define ERR_THD_SIGNON "Error in utility thread RRSAF \
SIGNON call..."
#define ERR_MAX_OBJECTS "Too many objects in input table..."
#define ERR_THD_CREATE_THREAD "Error in utility thread RRSAF \
CREATE THREAD call..."
#define ERR_MALLOC_SYSPRINT "Unable to allocate memory for \
rows from SYSIBM.SYSPRINT..."
#define ERR_CALL_UTILS "*** SQL error when calling \
SYSPROC.DSNUTILS..."
#define ERR_COUNT_UTILS_ROWS "*** SQL error when counting rows \
from SYSIBM.SYSPRINT..."
#define ERR_ASSOC_SYSPRINT "*** SQL error when associating result \
set locator with SYSPROC.DSNUTILS..."
446 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
#define ERR_ALLOC_SYSPRINT "*** SQL error when allocating cursor \
for SYSPROC.DSNUTILS result set locator..."
#define ERR_FETCH_SYSPRINT "*** SQL error when fetching from \
SYSIBM.SYSPRINT table..."
#define ERR_CLOSE_SYSPRINT "*** SQL error when closing cursor \
from SYSIBM.SYSPRINT..."
#define ERR_THD_COMMIT "*** SQL error when committing \
changes in utility thread..."
#define ERR_COUNT_RSP_TBL "*** SQL error when counting input \
table rows..."
#define ERR_MALLOC_PARMS "Unable to allocate memory for thread \
parameters..."
#define ERR_CALL_SS "*** SQL error when calling \
SYSPROC.ADMIN_INFO_SSID..."
#define ERR_OPEN_TS_IN "*** SQL error when opening cursor for \
input table..."
#define ERR_CLOSE_TS_IN "*** SQL error when closing cursor for \
input table..."
#define ERR_FETCH_TS_IN "*** SQL error when fetching from \
input table..."
#define ERR_THD_COMMIT "*** SQL error when committing \
changes in utility thread..."
#define ERR_THD_CREATE "Error creating a utility thread..."
#define ERR_THD_JOIN "Unable to join thread..."
#define OK_COMP "Parallel utility execution \
completed successfully..."
#define ERR_THD_TERMINATE_IDENTIFY "Error in utility thread RRSAF \
TERMINATE IDENTIFY call..."
#define ERR_THD_TERMINATE_THREAD "Error in utility thread RRSAF \
TERMINATE THREAD call..."
#define ERR_INSERT_RSP_SYSPRINT "*** SQL error when inserting into \
RSP_SYSPRINT..."
#define ERR_DSNTIAR "DSNTIAR could not detail the SQL \
error..."
The data types in Example 22-8 are required so that the primary thread can communicate
with the secondary threads. For every secondary thread, the primary thread allocates thread
parameters, which are a data area that the calling thread initializes with input parameters to
tell the secondary thread what to do, and the secondary thread will set output parameters to
tell the primary thread what it has done.
Writing to and reading from this data area has to be synchronized. In the THREAD_PARMS
structure, all input variables are prefixed with i_ , and all output variables are prefixed with o_
for clarity. The secondary thread, which executes the online utility and passes back the
output, has to allocate memory for the output and pass them back using a pointer in the
THREAD_PARMS variable. SYSPRINT_LINE is the data type that we defined to hold a single
output line. A number of structures including the release information block (RIB) are used for
RRSAF calls.
/********************************************************************/
/* Declare global variables. */
/********************************************************************/
unsigned char rrs_funcs[6][19] = {"IDENTIFY ",
"SIGNON ",
"CREATE THREAD ",
"TERMINATE THREAD ",
"TERMINATE IDENTIFY",
"TRANSLATE "};
448 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
/* 22 blanks that can be used for various RRS parms */
unsigned char rrs_parm_blanks[] = " ";
Before we code the main function, we define the error function as shown in Example 22-9.
sql_error can no longer format a global SQLCA and set a global error message and global
return code. Hence, the signature of sql_error now contains pointers to these structures,
which are declared in the scope of each function. dsnutils_thread is the function that will be
run in secondary threads.
Since all data is passed through a THREAD_PARMS variable, the thread function needs a
pointer to that variable, which we pass as an argument.
The main routine declares the sqlca locally to have its own copy. We will use the
DB2-supplied stored procedure SYSPROC.ADMIN_INFO_SSID to find out the SSID we need
to declare variables for it, as shown in Example 22-10.
450 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
When you have a large undetermined number of parameters that do not fit into an SQLDA,
passing them using one or more global temporary table is a good choice. Two cursors have to
be declared: One cursor to return the collected SYSPRINT output lines in a global temporary
table, and one cursor to get the input parameters. See Example 22-11 for the cursor
declarations.
Next, we initialize the variables and count the number of input lines, as shown in
Example 22-12. In our simple example, we create one thread per table space and we limit the
number of threads that we create to 99 (MAX_OBJECTS).
We need to determine how many threads we are going to start in order to allocate the
required THREAD_ PARM variables properly. See Example 22-13.
Next, we call ADMIN_INFO_SSID to determine the SSID of the subsystem we are connected
to with the code shown in Example 22-14. The SSID is a required parameter to make an
RRSAF connection in the secondary threads. If we wanted our threads to connect to
members of a data sharing system, we could find out this information by issuing a -DISPLAY
GROUP command using the DB2-supplied stored procedure
SYSPROC.ADMIN_COMMAND_DB2.
Now, we are ready to fetch the table spaces from the input table, initialize the thread
parameters, and use pthread_create to create a thread. pthread_create returns a thread_id,
which we save in the thread parameters. See Example 22-15. We need that thread ID to later
synchronize with the thread.
452 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
{
EXEC SQL FETCH TS_IN
INTO :h_dbname, :h_tsname;
if (SQLCODE != 0)
sql_error(ERR_FETCH_TS_IN, &errmsg, &rc, &sqlca);
else
{ /* Start DSNUTILS thread */
(pthread_parms + i)->i_thdindex = thdindex;
strcpy((pthread_parms + i)->i_ssid, h_ssid);
strcpy((pthread_parms + i)->i_dbname, trim(h_dbname));
strcpy((pthread_parms + i)->i_tsname, trim(h_tsname));
if (pthread_create(&((pthread_parms + i)->i_thdid),
NULL, dsnutils_thread,
(pthread_parms + i)) != 0)
{
strcpy(errmsg[0], ERR_THD_CREATE);
rc = RETSEV;
}
else
{
stmtno_executed++;
thdindex++;
}
}
}
After all the secondary threads have been created and are running, we have to wait for them
to finish. In Example 22-16 we show how we join each thread using pthread_join, and then
insert its output lines into the global temporary output table. After we insert the output lines,
we free the allocated memory.
if (pcurrthread_parms->o_error == TRUE)
{
memcpy(errmsg, pcurrthread_parms->o_errmsg,
sizeof(pcurrthread_parms->o_errmsg));
rc = RETSEV;
}
free(pcurrthread_parms->p_osysprintlines);
}
}
Finally, we return the results and give the control back to the caller as shown in
Example 22-17.
/* Highest_retcode */
*(long int *)argv[2] = highest_rc; /* Copy highest_rc to out par*/
locind[1] = 0; /* Tell DB2 to transmit it */
/* Return code */
if (rc == RETOK)
strcpy(errmsg[0], OK_COMP);
*(int *) argv[3] = rc; /* Copy rc to out param */
locind[2] = 0; /* Tell DB2 to transmit it */
/* Return message */
if (errmsg[0][0] == BLANK) /* If no error message exists*/
locind[3] = -1; /* tell DB2 not to send one */
454 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
else /* otherwise copy it over and*/
{ /* tell DB2 to transmit it */
pcurbyte = argv[4]; /* Set helper pointer and */
for (i = 0; i < DATA_DIM + 1; i++) /* parse a row, looking for */
{ /* the end of its msg text */
for (j=0;
(errmsg[i][j] != NULLCHAR && j < MSGROWLN);
j++)
*pcurbyte++ = errmsg[i][j]; /* Copy non-null bytes */
if (j>0)
*pcurbyte++ = LINEFEED; /* Add linefd to end of row */
}
if (pthread_parms != NULL)
free(pthread_parms);
/* Return control to caller */
}
We will not list sql_error or trim here. These functions are very similar to the ones in
Chapter 11, “C programming” on page 147. You can download the complete source code
from the Web as additional material. Download instructions can be found in Appendix B,
“Additional material” on page 887.
Next, we look at the function that runs DSNUTILS in a secondary thread. This is shown in
Example 22-18. Like the main thread, it declares its own SQLCA SQL parameters to be used
when calling DSNUTILS.
The only parameter that was passed to the thread is a pointer to its thread parameters, which
it saves in a local variable as shown in Example 22-19. In our example, it is important for the
thread to know its index (or any unique identifier) because it needs to build a unique utility-id.
First, an IDENTIFY has to be issued (as shown in Example 22-20) to establish the task as a
user of the DB2 subsystem.
Next, we do a SIGNON that provides DB2 with a user ID and optionally one or more
secondary authorization-ids for the connection. In our case we just use the security
environment of the caller.
456 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Example 22-21 RRS SIGNON
if (pthread_parms->o_error == FALSE)
{
/* The correlation id must be 12 bytes long */
sprintf(corrid, "RUNSTATP%s ", index);
The last task for establishing an RRSAF connection is to issue a CREATE THREAD to
allocate a plan or package. CREATE THREAD must be issued before any SQL statements
can be executed. See Example 22-22.
/* Call DSNUTILS */
EXEC SQL CALL SYSPROC.DSNUTILS
(:h_uid, :h_restart, :h_utstmt,
:h_retcode, :h_utility,
:h_dsn, :h_devt, :h_space,
:h_dsn, :h_devt, :h_space,
:h_dsn, :h_devt, :h_space,
:h_dsn, :h_devt, :h_space,
:h_dsn, :h_devt, :h_space,
:h_dsn, :h_devt, :h_space,
:h_dsn, :h_devt, :h_space,
:h_dsn, :h_devt, :h_space,
:h_dsn, :h_devt, :h_space,
:h_dsn, :h_devt, :h_space,
:h_dsn, :h_devt, :h_space,
:h_dsn, :h_devt, :h_space);
if (SQLCODE != 466)
{
/* An error occured while calling DSNUTILS */
/* Get error message */
sql_error(ERR_CALL_UTILS, &(pthread_parms->o_errmsg),
&dummy_rc, &sqlca);
pthread_parms->o_error = TRUE;
}
else
pthread_parms->o_utretcode = h_retcode;
}
If the call to DSNUTILS is successful, we need to retrieve the SYSPRINT lines, allocate
memory for them, and pass them back using a field in the thread parameter variable. We have
to count the number of SYSPRINT lines to know how many lines we have to allocate
dynamically. It is the responsibility of the primary thread to free the memory after reading the
SYSPRINT lines and inserting them into the output table. See Example 22-24.
458 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
if (SQLCODE != 0)
{
/* Get error message */
sql_error(ERR_COUNT_UTILS_ROWS, &(pthread_parms->o_errmsg),
&dummy_rc, &sqlca);
pthread_parms->o_error = TRUE;
}
}
if (pthread_parms->o_error == FALSE)
{
/* Allocate sysprint buffer if number of rows */
/* is greater than 0 */
pthread_parms->o_numsysprintlines = h_sysprintrows;
if (h_sysprintrows > 0)
{
if ((pthread_parms->p_osysprintlines = (SYSPRINT_LINE *)
malloc(h_sysprintrows * sizeof(SYSPRINT_LINE))) == NULL)
{
/* Required storage could not be allocated */
strcpy((pthread_parms->o_errmsg)[0], ERR_MALLOC_SYSPRINT);
pthread_parms->o_error = TRUE;
}
}
}
if (pthread_parms->o_error == FALSE)
{
/* The storage could be allocated, now we read */
/* out the lines from SYSIBM.SYSPRINT */
/* Associate result set locator */
EXEC SQL ASSOCIATE LOCATOR (:sysprint_loc)
WITH PROCEDURE SYSPROC.DSNUTILS;
if (SQLCODE != 0)
{
/* Get error message */
sql_error(ERR_ASSOC_SYSPRINT, &(pthread_parms->o_errmsg),
&dummy_rc, &sqlca);
pthread_parms->o_error = TRUE;
}
else
{
/* Try to allocate cursor with result set locator */
EXEC SQL ALLOCATE SYSPRINT_CSR CURSOR
FOR RESULT SET :sysprint_loc;
if (SQLCODE != 0)
{
/* Get error message */
sql_error(ERR_ALLOC_SYSPRINT, &(pthread_parms->o_errmsg),
&dummy_rc, &sqlca);
pthread_parms->o_error = TRUE;
}
}
}
if (pthread_parms->o_error == FALSE)
{
/* Fetch all rows */
for (i = 0; i < h_sysprintrows; i++)
if (SQLCODE != 0)
{
/* Get error message */
sql_error(ERR_FETCH_SYSPRINT, &(pthread_parms->o_errmsg),
&dummy_rc, &sqlca);
pthread_parms->o_error = TRUE;
break;
}
else
{
/* Save output line */
(pthread_parms->p_osysprintlines + i)->seqno = h_seqno;
(pthread_parms->p_osysprintlines + i)->ind = i_text;
strcpy((pthread_parms->p_osysprintlines + i)->text, h_text);
}
}
}
if (pthread_parms->o_error == FALSE)
{
EXEC SQL CLOSE SYSPRINT_CSR;
if (SQLCODE != 0)
{
/* Get error message */
sql_error(ERR_CLOSE_SYSPRINT, &(pthread_parms->o_errmsg),
&dummy_rc, &sqlca);
pthread_parms->o_error = TRUE;
}
}
Finally, we do an orderly disconnect from the subsystem and leave the utility thread as shown
in Example 24-25.
if (SQLCODE != 0)
{
sql_error(ERR_THD_COMMIT, &(pthread_parms->o_errmsg),
&dummy_rc, &sqlca);
pthread_parms->o_error = TRUE;
}
}
460 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
(long int *) &rli_rc, /* Return code */
(long int *) &rli_reas); /* Reason code */
if (rc != 0 || rli_rc != 0)
{
/* The TERMINATE THREAD call was not successful */
pthread_parms->o_error = TRUE;
strcpy((pthread_parms->o_errmsg)[0], ERR_THD_TERMINATE_THREAD);
}
}
A user with the user ID TEST7083 wants to invoke the stored procedure RUNSTATP in order
to collect statistics for the following two table spaces that are part of the DB2 catalog
DSNDB06:
SYSPKAGE, SYSPLAN
Let us further assume that the user ID TEST7083 has almost no DB2-related privileges but
nevertheless seeks to employ the Java program that is partially displayed in Example 22-4.
This client will be used to establish a JBDC connection to DB2, insert the two table spaces
and database names into a GLOBAL TEMPORARY TABLE, and finally to CALL the
procedure. The JDBC connection is opened with the user ID TEST7083.
To successfully invoke the procedure RUNSTATP, at least the following two GRANT
statements have to be issued:
462 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
This statement allows the user to INSERT the table space and database names into the
temporary input table.
This statement allows the user ID TEST7083 to eventually CALL the stored procedure from
within the Java program.
An interesting observation now is that the subthread that establishes an RRSAF connection
to DB2 in dsnutils_thread(), depends on the SECURITY option defined during the procedure
registration. This SECURITY option indicates the nature of the external security environment
created for that procedure, at execution time by DB2. Any external activity performed by that
procedure is therefore governed by this created security environment. Since SECURITY
USER was defined in the sample, the ID used to establish the security environment is the
value of the USER special register when the routine is called, that is, TEST7083.
The subthread creation is one of those governed external activities and therefore inherits this
security environment. The RRSAF attachment, performed by that subthread, is another
governed external activity. Thus the new DB2 connection thread has this security ID (special
register USER) as its primary authID, by default. This DB2 connection thread is separate and
distinct from the DB2 thread implicitly provided by DB2 for the stored procedure.
Every action that the subthread performs (authority-wise) stems from the external security
environment provided to the routine. As an example, SQL statements are executed on the
separate DB2 connection thread, which inherited the primary authID from the external
security environment, that is, TEST7083. Therefore, the following additional privilege has to
be granted to TEST7083:
This statement allows the primary authID TEST7083 to execute an SQL statement in the
dsnutils_thread() function.
The call to DSNUTILS failed and as the result set indicates the authID TEST7083 did not hold
the appropriate privileges.
In this scenario, the subthread with its own independent DB2 connection thread made an
SQL CALL to the procedure DSNUTILS. The calling characteristics here also govern the
operational characteristics of DSNUTILS, which creates another internal dependency on the
TEST7083 authID.
To solve this issue, further privileges have to be granted to the authID TEST7083:
Granting these additional privileges might not be desirable, because the user could directly
interact with sensitive database objects. Generally it is a good idea to introduce a layer that
interacts with the DB2 objects in a consistent way, such as a stored procedure, instead of
allowing users to directly access and modify them.
Furthermore it is always good practice to implement a certain division of security, that is, it
should be distinguished between the privilege a caller needs to utilize the RUNSTATP
procedure, and the privileges needed by this procedure to perform its specific internal tasks.
SECURITY DEFINER
The approach described in this section transforms the above described runtime problem into
a configuration issue.
Instead of using the SECURITY USER option in the signature, the procedure can be defined
with SECURITY DEFINER when registered to DB2. This is shown in Example 22-28.
SECURITY DEFINER implies that the external security environment is established using the
ID that registered the routine to DB2. In our example the creator of the stored procedure has
the ID DEVL7083. This is now the primary authID that the subthreads as well as the separate
DB2 connection threads security environment is based on.
464 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
For a successful CALL, it has to be ensured that the procedure DEFINER (DEVL7083) has
been granted sufficient authorities to call and use DSNUTILS (configuration-time).
The nice thing now is, that no special authorization requirements are imposed on the calling
user ID (runtime), except the privileges needed to insert rows into the temporary table and to
CALL the procedure from within the Java program. Issue the following GRANT statement to
allow any user ID to successfully call the RUNSTATP procedure.
AUTH SIGNON
Although the SECURITY DEFINER approach moved the USER privilege set out of the
internal business of the subthreads, it is very static in terms of which ID is used to establish
the security environment. A more dynamic approach is described in this section.
RRSAF allows to associate a different primary authID to the established DB2 connection
thread. This is done by replacing the SIGNON call with an AUTH SIGNON call. Example 22-30
shows the new AUTH SIGNON call, which is issued after the INDENTIFY and before the CREATE
THREAD call.
We introduce three new parameters for the AUTH SIGNON call, as can be seen in
Example 22-31. After the RRSAF connection has been successfully established, a new
primary authorization-ID, DEVL7083, is associated with this separate DB2 connection thread.
We do not provide a secondary authID because it is not required here.
In this example the new primary authID is a hard coded string value. However, a variable can
be used for a more dynamic solution.
Due to this user ID switch during the RRSAF connect, the CALL to DSNUTILS completes
successfully, assuming the new primary authID holds the required privileges.
Restriction: You can basically switch to any valid primary authorization-ID, the only
requirement is that your procedure has to run APF authorized.
22.6 Improvements
Creating a thread for every utility is not a good design. In a more sophisticated stored
procedure, we would initially start up a number of threads that run utilities in a loop to avoid
466 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
the overhead of too many secondary threads. Also, you will run into concurrency issues when
too many utilities compete for the same buffer pools and catalog tables, hence, they have to
be sorted and utility execution has to be serialized by various criteria.
If you reuse threads, you have to implement event-driven synchronization between the
primary scheduler thread and the secondary threads using condition variables, and mutex
objects. You can use the corresponding pthread_mutex and pthread_cond functions for that.
Examples of how to use mutex objects and condition variables can be found in z/OS C/C++
Programming Guide, SC09-4765-08 and z/OS C/C++ Run-Time Library Reference,
SA22-7821-09.
As an example of a deadlock that the database manager does not detect, consider a stored
procedure that has two threads, both of which access a common data structure. To avoid
problems where both contexts change the data structure simultaneously, the data structure is
protected by a semaphore. The contexts look like Example 22-32.
context 2
get semaphore
access data structure
SELECT * FROM TAB1...
release semaphore
COMMIT
Suppose the first context successfully executes the SELECT and UPDATE statements, while
the second context gets the semaphore and accesses the data structure. The first context
now tries to get the semaphore, but it cannot because the second context is holding the
semaphore. The second context now attempts to read a row from table TAB1, but it stops on
a database lock held by the first context. The application is now in a state where context 1
cannot finish before context 2 is done, and context 2 is waiting for context 1 to finish. The
application is deadlocked, but because the database manager does not know about the
semaphore dependency, neither context will be rolled back. The unresolved dependency
leaves the application suspended. You can avoid the deadlock that occurred for the previous
example in several ways:
Release all locks held before obtaining the semaphore.
Change the code for context 1 to perform a commit before it gets the semaphore.
Do not code SQL statements inside a section protected by semaphores.
Change the code for context 2 to release the semaphore before doing the SELECT.
Code all SQL statements within semaphores.
468 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
23
For example, you may have a CICS application that accesses data from a VSAM file. If you
are developing DB2 applications that need to access data from that VSAM file, and you do not
have the resources to migrate that data from VSAM to DB2 at this time, you can access the
VSAM file from a DB2 stored procedure using the external CICS interface or DB2-supplied
stored procedure DSNACICS to execute an existing CICS program. You can also access the
VSAM file from within your stored procedure, but that would require you to define a DD
statement for that file within your application environment. Then, if you alter the stored
procedure to execute in a different environment, you need to change the JCL for the old and
new environments.
If you have IMS data that you would like to access from a DB2 stored procedure, you can use
the ODBA interface to code DLI calls in your stored procedure or use DB2-supplied stored
procedure DSNAIMS to execute a program running under the IMS transaction manager.
You can also call DB2 stored procedures from CICS and IMS applications. For example, you
may have a CICS application that accesses data from a VSAM file. If you now need to access
DB2 data from that application, you can call a DB2 stored procedure to access the DB2 data.
The SQL CALLs in CICS and IMS applications do not differ from SQL CALLs in other
environments, such as batch, but the program preparation steps differ somewhat. We now
discuss how to code SQL calls in CICS and IMS applications, and give an overview of how to
prepare those applications.
Your stored procedures that access CICS and IMS can also be debugged just like any other
stored procedure. See Chapter 16, “Debugging” on page 313, and Chapter 28, “Tools for
debugging DB2 stored procedures” on page 735 for more details.
You need to be familiar with CICS or IMS to understand the topics discussed here. We make
no attempt to cover basic CICS and IMS concepts. We focus on the interfaces from DB2
Note: Complete sample programs can be downloaded from the ITSO Web site as
additional material. Download instructions can be found in Appendix B, “Additional
material” on page 887.
Before downloading, we strongly suggest that you first read 3.3, “Sample application
components” on page 24 to decide what components are applicable to your environment.
470 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
23.1 Accessing CICS systems from DB2 stored procedures
There are two alternatives for accessing CICS systems from a DB2 stored procedure: the
external CICS interface (EXCI) and stored procedure DSNACICS. Which alternative you
choose is based on the expertise of your development staff. If your developers are
experienced CICS programmers, you should be most comfortable using EXCI. If your
developers are experienced DB2 programmers with little CICS experience, you should be
most comfortable with DSNACICS.
We use the EXEC CICS interface in our case study because it is simpler to code and more
frequently used. For more details on each of the interfaces, refer to CICS Transaction Server
for z/OS V3.1 CICS External Interfaces Guide, SC34-6449-03.
In our case study we make the assumption that a legacy CICS application (COBOL program
EMPEXC2C) exists which retrieves the department name for a given department number.
The department information is stored in a VSAM file that is in the same format as the sample
DEPT table in DB2. Since the same VSAM file is used for both the CICS and IMS case
studies, sample JCL for defining the VSAM file is provided in job IMS05.txt in the additional
materials and is shown in Example 23-13 on page 480. A new DB2 stored procedure
(COBOL program EMPEXC1C) is being developed to return a results set of all employees for
a given department number, with the name of the department included for each employee.
Stored procedure EMPEXC1C is a version of EMPRSETC, the COBOL results set stored
procedure, with an EXCI call to EMPEXC2C replacing the SELECT from the DEPT table.
We executed the following steps to set up the environment and develop our EXCI test case:
Preparing CICS and WLM environments for using EXCI
Coding stored procedures to invoke EXCI
Preparing a stored procedure to use EXCI
472 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
– DSNAme - SG247083.DEPT.CL, which is the VSAM cluster name
6. Install the group SG247083:
CEDA I GROUP(SG247083)
7. ISC parameter - Verify that SIT parameter ISC is set to YES.
8. RRMS parameter - Verify that SIT parameter RRMS is set to YES. CICS supports MVS
resource recovery services (RRS) in applications that use the external CICS interface.
Remember that changes made to program EMPEXC2C only become active in CICS after
executing the following command in CICS to pull in the latest version of program EMPEXC2C:
CEMT SET PROG(EMPEXC2C) NEWCOPY
SET PROG(EMPEXC2C) NE
STATUS: RESULTS - OVERTYPE TO MODIFY
Prog(EMPEXC2C) Leng(0000005392) Cob Pro Ena Pri Ced NORMAL
Res(000) Use(0000000001) Bel Uex Ful Qua Cic
WLM definitions
We recommend that you define a separate WLM application environment for your EXCI
transactions to minimize the impact that problems with CICS systems can have on your
stored procedures. We chose to name the environment DB9AEXCI. The load library that
contains the EXCI stub program DFHMIRS needs to be included in the startup JCL for the
WLM procedure. The name of the load library typically ends in SDFHEXCI.
When the LINK statement is executed, CICS loads program DFHMIRS, the EXCI mirror
program, which in turn will load the program that is passed in the PROGRAM field of the LINK
statement, which is EMPEXC2C in our case. This program then reads the commarea that is
passed, uses the DEPTNO field in the commarea, and reads file DEPTNAME to obtain the
department name, which is then passed back in the commarea. The fields WS-COMM-AREA
and WS-COMM-LEN represent the commarea, and the length of the commarea that is
passed from the stored procedure to CICS program EMPEXC2C.
The field EXCI-EXEC-RETURN-CODE contains five diagnostic fields that are passed back to
the calling program. An example of the definition of the diagnostic fields in a COBOL program
is shown in Example 23-3.
The values for each of the diagnostic fields can be found in CICSTS31.CICS.SDFHCOB in
member DFHXCRCO.
DSNACICS is one of the sample stored procedures provided with DB2. DSNACICS gives
workstation applications a way to invoke CICS server programs while using TCP/IP as their
communication protocol. The workstation applications use TCP/IP and DB2 Connect to
connect to a DB2 for z/OS subsystem, and then call DSNACICS to invoke the CICS server
programs.
Environment
DSNACICS runs in a WLM-established stored procedure address space and uses the
Resource Recovery Services attachment facility to connect to DB2.
474 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
If you use CICS Transaction Server for OS/390 Version 1 Release 3 or later, you can register
your CICS system as a resource manager with recoverable resource management services
(RRMS). When you do that, changes to DB2 databases that are made by the program that
calls DSNACICS and the CICS server program that DSNACICS invokes are in the same
two-phase commit scope. This means that when the calling program performs an SQL
COMMIT or ROLLBACK, DB2 and RRS inform CICS about the COMMIT or ROLLBACK.
If the CICS server program that DSNACICS invokes accesses DB2 resources, the server
program runs under a separate unit of work from the original unit of work that calls the stored
procedure. This means that the CICS server program might deadlock with locks that the client
program acquires.
Authorization
To execute the CALL statement, the owner of the package or plan that contains the CALL
statement must have one or more of the following privileges:
The EXECUTE privilege on stored procedure DSNACICS
Ownership of the stored procedure
SYSADM authority
The CICS server program that DSNACICS calls runs under the same user ID as DSNACICS.
That user ID depends on the SECURITY parameter that you specify when you define
DSNACICS.
The DSNACICS caller also needs authorization from an external security system, such as
RACF, to use CICS resources.
Definition
The DDL to create the procedure is located in member DSNTIJSG of the SDSNSAMP library.
A sample CREATE PROCEDURE statement is shown in Example 23-5.
A DB2 stored procedure or application program can issue an SQL CALL to DSNACICS in
place of an EXCI call to access CICS. For our test case, we created stored procedure
EMPEXC3C, which is a copy of EMPEXC1C (which issues an EXCI call as described in
“Coding a stored procedure to use EXCI” on page 473). EMPEXC3C replaces the EXEC
CICS LINK statement with an SQL CALL to DSNACICS. The call statement that was used in
our test case is shown in Example 23-6. The parameters for the CALL statement are
described in detail in Appendix B of DB2 Version 9.1 for z/OS Administration Guide,
SC18-9840.
We now describe the parameters that are relevant for our test case. These are the same
parameters that are supplied on the CICS LINK statement for the EXCI test case:
PGM-NAME is an input parameter that contains the name of the CICS program to be
invoked by the EXCI mirror program DFHMIRS. In our case the PGM-NAME is
EMPEXC2C.
CICS-APPLID is an input parameter that contains the name of the CICS region where the
program identified in PGM-NAME will execute. In our case, the CICS-APPLID is
SCSCSAR3.
CONNECT-TYPE is an input parameter that specifies whether the CICS connection is
generic or specific. This must match the value in the Conntype parameter of the
Connections RDO entry. In our case, the CONNECT-TYPE is GENERIC.
MIRROR-TRANS is an input parameter that names the CICS transaction ID that invokes
program DFHMIRS. In our case the MIRROR-TRANS is DPT1.
COMM-AREA contains the commarea that will be passed to the CICS program.
COMM-LEN specifies the length of the commarea to be passed.
RET-CODE is an output parameter that contains the return code from the DSNACICS call.
The return code will either be 0 for successful or 12 for failure. If the return code is 12, the
error is described in the MSG-AREA parameter.
MSG-AREA is an output parameter that contains any error messages from the call.
476 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
The SYNC-OPTS parameter is a functional difference between EXCI LINK and
DSNACICS. The option tells CICS whether it should drive SYNCONRETURN (commit)
processing at the end of the CICS transaction:
– If SYNC-OPTS = 1, then the CALLING application controls when the two-phase
commit protocol will be driven, and any DB2 updates along with CICS updates will be
handled in the same commit scope.
– If SYNC-OPTS = 2, then CICS will commit at completion of the CICS transactions, and
it will not be handled in the same commit scope as any DB2 updates (or other RRS
controlled resources).
WS-DEPTNAME: OPERATIONS
++ SQLCODE AFTER OPEN = 000000000
++ END OF EMPEXC3C ++
In our case study we make the assumption that a legacy IMS database exists that contains
department information. The IMS database is called DEPT, and contains the DEPTNO and
DEPTNAME fields comparable to those defined in the DEPT sample DB2 table. We created
stored procedure EMPODB1C, which includes uses of ODBA to call the DEPT IMS database
to retrieve the department name for a given department number. EMPODB1C then returns a
result set of all employees for a given department number with the name of the department
included for each employee. Stored procedure EMPODB1C is a version of EMPRSETC, the
COBOL results set stored procedure, replacing the SELECT from the DEPT table with an IMS
GU call using the AERTDLI API.
The following sections provide information on preparing your IMS and WLM environments for
using ODBA, coding application programs to make ODBA calls, and preparing a program to
use the interface.
Add the DBD, PSB and IMS Tran macros to IMS stage 1 gen
Example 23-8 lists the macros we defined in our IMS.
478 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Example 23-8 IMS Stage 1 gen macros
**********************************************************************
* DB2 SP SG24-7083 REDBOOK FOR IMS ODBA AND DSNAIMS EXAMPLES
**********************************************************************
DATABASE DBD=DEPTDB,ACCESS=UP HDAM/VSAM
SPACE 2
APPLCTN PSB=DEPTPSBL,PGMTYPE=BATCH LOAD PSB
SPACE 2
APPLCTN PSB=DEPTPSB,PGMTYPE=TP,SCHDTYP=PARALLEL
Example 23-10 IMS PSBGEN source for the load PSB, DEPTPSBL
//PSBGEN EXEC PROC=PSBGEN,MBR=DEPTPSBL,SOUT='*'
//C.SYSIN DD *
PCB TYPE=DB,DBDNAME=DEPTDB,PROCOPT=LS,KEYLEN=3
SENSEG NAME=DEPT,PARENT=0
PSBGEN LANG=ASSEM,PSBNAME=DEPTPSBL
END
//
Example 23-11 provides the source for the application PSB after initial load is completed. The
PCBNAME is required on the PSB for the Application Interface Block (AIB) control block used
by the AERTDLI calling Application Programming Interface (API).
Example 23-11 IMS PSBGEN source for the application PSB, DEPTPSB
//PSBGEN EXEC PROC=PSBGEN,MBR=DEPTPSB,SOUT='*'
//C.SYSIN DD *
PCB TYPE=DB,DBDNAME=DEPTDB,PCBNAME=DEPTPCB,PROCOPT=A,KEYLEN=3
SENSEG NAME=DEPT,PARENT=0,PROCOPT=A
PSBGEN LANG=ASSEM,PSBNAME=DEPTPSB
END
//
Define the source and run the dynamic allocation job for the database
The JCL and source in Example 23-14 create the dynamic allocation of the DEPT database.
Using dynamic allocation is preferred to including a DD statement for the database in the IMS
procs.
Define and run the DBRC registration for the DEPT database
The JCL and source in Example 23-15 register the DEPTDB database in the DBRC recon
data sets.
480 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Example 23-15 DBRC registration for the DEPT database
//INITRCON EXEC PROC=DBRC
//D.SYSIN DD *
INIT.DB DBD(DEPTDB) SHARELVL(3) TYPEIMS
INIT.DBDS DBD(DEPTDB) DDN(DEPTDB1) -
DSN(IMS910H.DEPTDB1) -
ICJCL(ICJCL) OICJCL(OICJCL) RECOVJCL(RECOVJCL) -
REUSE RECOVPD(0) GENMAX(3)
//*
482 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
//
Once the above online JCL has been successfully run, we need to activate the current system
with this change. From the IMS console, issue the two commands in Example 23-20.
Example 23-21 WLM environment for our DB2 COBOL ODBA case study
Appl Environment Name . . DB9AODBA
Description . . . . . . . DB9A IMS-ODBA- SG247083 - devl
Subsystem type . . . . . DB2
Procedure name . . . . . DB9AODBA
Start parameters . . . . DB2SSN=&IWMSSNM,APPLENV=DB9AODBA
Example 23-22 WLM procedure for executing our DB2 COBOL stored procedure
//STEPLIB DD DSN=SG247083.DEVL.LOAD,DISP=SHR
// DD DISP=SHR,DSN=DB9A9.SDSNEXIT
// DD DISP=SHR,DSN=DB9A9.SDSNLOAD
// DD DISP=SHR,DSN=IMS910H.SDFSRESL
// DD DISP=SHR,DSN=IMS910H.PGMLIB
// DD DISP=SHR,DSN=EQAW.SEQAMOD
//SYSTCPD DD DSN=TCP.SC63.TCPPARMS(TCPDATA),DISP=SHR
//CEEDUMP DD SYSOUT=*
//DFSRESLB DD DISP=SHR,DSN=IMS910H.SDFSRESL
The first call to AERTDLI schedules a PSB and initializes the IMS database environment. The
call we issued in stored procedure EMPODB1C, along with the COBOL statements to
initialize the parameters of the AIB, is shown in Example 23-23. The parameter APSB
contains the value APSB, which is what is required to request allocation of a PSB.
Once the PSB has been scheduled, your program can issue a call to AERTDLI to read data
from the appropriate database. The call we issued, along with the COBOL statements to set
the parameters to read department D21 from the DEPT database is shown in Example 23-24.
The reserved word SSA-KEY represents the key value being read from the database. In our
case it is D21 for department D21. The fields IO-DEPTNO and IO-DEPTNAME make up
IOAREA, which represents the record layout for the IMS DEPT database. The value of
DPCBNAME is DEPTPCB, which represents the name of the PCB for our call. The
GET-UNIQUE parameter represents the type of function call, which has two byte value of GU
to read a unique record from the database with the value of D21 in the key.
Example 23-24 Sample logic for ODBA call to read an IMS database record
MOVE WS-DEPTNO TO SSA-KEY.
MOVE SPACES TO IO-DEPTNO.
MOVE SPACES TO IO-DEPTNAME.
MOVE DPCBNME TO AIBRSNM1.
CALL 'AERTDLI' USING GET-UNIQUE, AIB, IOAREA, SSA.
A stored procedure that uses ODBA must issue a DPSB PREP call to deallocate a PSB when
all IMS work under that PSB is complete. The PREP keyword tells IMS to move in-flight work
to an indoubt state. When work is in the indoubt state, IMS does not require activation of
syncpoint processing when the DPSB call is executed. IMS commits or backs out the work as
part of RRS two-phase commit when the stored procedure caller executes COMMIT or
ROLLBACK. The call we issued to deallocate the PSB is shown in Example 23-25. The
parameter DPSB contains the value DPSB, which is what is required to request deallocation
of a PSB. The parameter SFPREP contains the value PREP, which is the keyword described
above.
The complete source code for the COBOL stored procedure EMPODB1C can be found in
Appendix B, “Additional material” on page 887.
484 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Example 23-26 Sample link edit step for stored procedure with ODBA call
//LKED.SYSLMOD DD DSN=SG247083.DEVL.LOAD(EMPODB1C),
// DISP=SHR
//LKED.LOAD DD DSN=IMS910H.SDFSRESL,
// DISP=SHR
//LKED.SYSIN DD *
INCLUDE SYSLIB(DSNRLI)
INCLUDE LOAD(DFSCDLI0)
//*------------------------------------------------
In “SYSPROC.DSNAIMS” on page 556 we show the syntax diagram and list the parameters.
DSNAIMS prerequisites
The following functions are required before installing and executing the DSNAIMS stored
procedure:
A WLM-managed stored procedure address space in which to run DSNAIMS.
DB2 Version 8 requires PTF UQ94696 for APAR PQ89544 and PTF UK03998 for APAR
PK04339 if the text includes X’00’s in the input variable string.
When using two-phase commit for DSNAIMS (DSNAIMS_2PC=Y), you need:
– IMS V7 with UQ78980 and the IMS control region parameter RRS=Y
– IMS V8 with UQ70789 and the IMS control region parameter RRS=Y
Other recommended maintenance for DSNAIMS:
– PK48891 (UK29722) for IMS V9, PK52490 (UK30363) for IMS V10
– PK30395 (UK18394) for IMS V8, PK30387 (UK15224 and UK18393) for IMS V9
– PK25672 (UK25116) for IMS V8, PK16294 (UK25115) for IMS V9
DSNAIMS limitations
DSNAIMS cannot handle the following:
Specifying OTMA commit mode explicitly
IMS conversational transaction
IMS multi-segment messages - This restriction is removed in DSNAIMS2; see “Using the
DSNAIMS2 stored procedure” on page 489.
DSNAIMS setup
The following are two steps to take to ensure that DSNAIMS is ready for execution:
1. The job DSNTIJIM (provided in the SDSNSAMP data set) can be used to issue the
CREATE PROCEDURE statement for DSNAIMS and will grant the execution of the
procedure to PUBLIC. This job needs to be customized to fit the parameters of your
system.
2. OTMA Callable Interface provides a stand-alone C/I initialization program DFSYSVI0 that
must be run after every MVS IPL to initialize the C/I. You will need to add an entry in the
MVS program properties table (PPT) for DFSYSVI0. Refer to the IMS OTMA Guide and
Reference for an explanation of the C/I initialization.
486 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
IN OTMA_TPIPE_NAME CHAR(8),
IN OTMA_DRU_NAME CHAR(8),
IN USER_DATA_IN VARCHAR(1022),
IN USER_DATA_OUT VARCHAR(1022),
OUT STATUS_MESSAGE VARCHAR(120),
OUT RETURN_CODE INT)
DSNAIMS examples
For a first example we used IMS Version 9 and IMS sample application DFSSAM02 and
transaction PART.
See Example 23-30 for the result when we execute this transaction from a 3270 terminal.
PART AN960C10
Response:
We used IBM Data Studio to call DSNAIMS. See Example 23-31 for the input parameters and
the result.
Sample parameters for executing the IMS IVTNO transaction are shown in Example 23-33.
Sample parameters for Send-only transaction invocation are shown in Example 23-34.
Sample parameters for Receive-only transaction invocation are shown in Example 23-32.
DSNAIMS tips
Since DSNAIMS only connects to one IMS at a time, the following is a list of suggested steps
to connect to multiple IMS subsystems simultaneously.
Make a copy of the supplied job DSNTIJIM and customize it to your environment in
accordance with the procedures listed in the document.
Change the procedure name from SYSPROC.DSNAIMS to another name that will help
you remember its target IMS (that is, SYSPROC.DSNAIMSB).
Change the WLM environment to a different name for DSNAIMSB.
Make sure to leave the “EXTERNAL NAME” option as “DSNAIMS”.
Run the new job to create a second instance of the stored procedure.
Always use the same XCF Group and Member names for each stored procedure instance.
This will ensure that every time that stored procedure instance is invoked, a proper
connection to the intended target IMS will be created. For example:
CALL SYSPROC.DSNAIMS(“SENDRECV”, “N”, “IMS7GRP”, “IMS7TMEM”, …)
488 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
CALL SYSPROC.DSNAIMSB(“SENDRECV”, “N”, “IMS8GRP”, “IMS8TMEM”, …)
DSNAIMS2 is available in DB2 9 for z/OS. APAR PK26421 (PTF UK26421) and APAR
PK32332 (PTF UK18752) also apply.
The same function is made available to DB2 V8 through the maintenance stream: PK07907 is
the controlling APAR, currently open.
The syntax of DSNAIMS2 is the same as DSNAIMS except for the addition of one new IN
parameter, OTMA_DATA_INSEG. The new IN parameter OTMA_DATA_INSEG takes as input
the total number of segments and the length of each segment. The data type of
OTMA_DATA_INSEG is VARCHAR(512). The format of the input string is the total number of
input segments, followed by a list of lengths of all the segments, the values in the string
separated by semicolons.
The definition of DSNAIMS2 is shipped in the new sample file DSNTIJI2 (provided in the
SDSNSAMP data set). It is listed in Example 23-36.
In this example:
IMS_DATA_IN - Contains "SDK1 1ST SEGMENT FROM CI 2ND SEGMENT FROM CI"
Important: you need to make sure these lengths are correct. If the total length of the
segments do not match up to the length of the string in IMS_DATA_IN, IMS rejects the
transaction with RC=8 and Reason Code=40.
See the chapter “OTMA Callable Interface” in IMS Version 9: Open Transaction Manager
Access Guide and Reference, SC18-7829 for a complete list of codes and messages from the
C/I APIs.
490 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
23.3 Accessing DB2 stored procedures from CICS
CICS Transaction Server for z/OS, referred to as CICS in this chapter, comes with a DB2
attachment facility, which provides CICS applications the ability to access DB2 data while
operating in a CICS environment. Each CICS region can be connected to only one DB2
subsystem at a time.
CICS applications that access DB2 objects, including stored procedures, must include DB2
precompiler and bind steps during the program preparation process. The precompiler step
builds a DBRM and converts the source code into a format acceptable to the CICS translator
step. The bind step reads the DBRM created in the precompiler step, and produces an
application plan. See “Preparing a CICS application program that accesses DB2” in CICS
DB2 Guide Version 3 Release 1, SC34-6457-01 for more details on the program preparation
process for CICS programs that access DB2 objects.
Stored procedures are accessed from CICS programs by issuing SQL CALL statements. A
CALL statement that references a stored procedure must be bracketed between EXEC SQL
and the statement terminator appropriate for the host language. For COBOL programs, the
statement terminator is END-EXEC.. Example 23-39 shows what a call to stored procedure
EMPRSETC from a COBOL CICS application might look like.
The CICS application program must include logic to set the host variables prior to executing
the CALL, and must include logic to handle any error conditions returned by the stored
procedure. These two logic components are no different than what is required of a batch
program written in the same host language.
IMS applications that access DB2 objects, including stored procedures, must include DB2
precompiler and bind steps during the program preparation process. The precompiler step
builds a DBRM, and converts the source code into a format acceptable to the CICS translator
step. The bind step reads the DBRM created in the precompiler step and produces an
application plan. See 1.4.1, “Preparing a CICS application program that accesses DB2”, in
the manual CICS Transaction Server for z/OS Version 2.2 CICS DB2 Guide, SC34-6014-07
for more details on the program preparation process for CICS programs that access DB2
objects.
Stored procedures are accessed from IMS programs by issuing SQL CALL statements. A
CALL statement that references a stored procedure must be bracketed between EXEC SQL,
The IMS application program must include logic to set the host variables prior to executing the
CALL, and must include logic to handle any error conditions returned by the stored
procedure. These two logic components are no different than what is required of a batch
program written in the same host language.
492 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
24
In this chapter we provide an overview of the administrative stored procedures that are now
supplied with the DB2 server. The overview is enriched with comprehensive Java samples
that are contained in Appendix A, “Samples for using DB2-supplied stored procedures” on
page 807 and provide an excellent jump-start for working with them.
All of this enables you to write client applications that perform advanced DB2 and z/OS
functions.
SQL APIs are already used by most DB vendors. This type of access ensures a base
standard infrastructure which satisfies customer requirements and enables IBM to build on
other application layers such as Java administration APIs, Web services, and so on.
DB2 for z/OS administration requires DB2 commands, DSN subcommands, and MVS
console commands, and the use of JCL. By providing an SQL interface to DB2 commands,
DSN subcommands and JCL, DB2 provides a base standard infrastructure to build upon, not
only for DB2 tools but also for application vendors, such as SAP®, who increasingly leverage
the advantages of Web applications running in application servers like WebSphere
Application Server. The DB2-supplied stored procedures are meant to provide that
infrastructure.
The intent of this chapter is to show how most of the DB2 administration functions can easily
be executed through DB2-supplied stored procedures.
Furthermore, information about required APF authorization and program control is provided
for every stored procedure. If one of these attributes applies, refer to 24.1.2, “Setting up
DB2-supplied stored procedures” on page 502, to figure out the respective configuration
requirements.
Some of the stored procedures listed here were previously shipped as part of the DB2
Management Clients Package's z/OS Enablement component (FMID JDB881D and
JDB991D). These are now included in the DB2 base (FMID HDB8810 and HDB9910) with
modifications and enhancements. They have been given more task oriented names and their
494 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
signatures, input tables, and result sets have been altered to make them consistent and
descriptive. So refer to the syntax diagrams, input and result table formats documented in
24.2, “Administrative enablement stored procedure - details” on page 521 when porting your
application to use these new stored procedures. For your convenience, the Original name of
each of these stored procedures is shown in a column next to the Name column in the tables
that follow.
Unless otherwise specified, the schema name SYSPROC is assumed for these procedures.
Command execution
Table 24-1 shows the stored procedures that execute DB2 commands, DSN subcommands,
and z/OS UNIX commands, by listing name (new and old), the function provided, and whether
the stored procedure is APF-authorized and program-controlled.
CALL syntax - For more details on the CALL syntax of every stored procedure, refer to
24.2.1, “Command execution” on page 521.
Sample program - A sample Java program for all command execution stored procedures is
in Appendix A, “Samples for using DB2-supplied stored procedures” on page 807.
AdminDB2Command contains a sample on how to use the stored procedure
ADMIN_COMMAND_DB2 to execute multiple DB2 commands, e.g. DISPLAY DDF
DETAIL and parse the result set. Refer to A.3, “Issue DB2 commands with
AdminDB2Command” on page 819.
AdminUNIXCommand contains a sample on how to use the stored procedure
ADMIN_COMMAND_UNIX to execute a “ls -l“ UNIX command under the provided userid,
and display the command output. Refer to A.7, “Issue USS commands with
AdminUNIXCommand” on page 852.
AdminDSNSubcommand contains a sample on how to use the stored procedure
ADMIN_COMMAND_DSN to execute the DSN subcommand REBIND PACKAGE. Refer
to A.8, “Issue DSN subcommands with AdminDSNSubcommand” on page 855.
Job management
Table 24-2 lists all stored procedures that can be employed for remote job management.
CALL syntax - For more details on the CALL syntax of every stored procedure, refer to
24.2.2, “Job management” on page 530.
Sample program - A sample Java program that executes all job management stored
procedures can be found in A.6, “Submit JCL with AdminJob” on page 845.
CALL syntax - Detailed information on how to issue a CALL on a data set management
stored procedure can be found in 24.2.3, “Data set management” on page 536.
Sample program - A sample Java program that executes all data set management stored
procedures can be found in A.5, “Manage data sets with AdminDataSet” on page 838.
System administration
Table 24-4 lists the procedures that can be employed for system administration.
496 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Table 24-4 System administration stored procedure
Name Original Function APF - Program -
name authorized controlled
CALL syntax - Refer to 24.2.4, “System administration” on page 548 for more information on
the CALL syntax for the procedures ADMIN_INFO_HOST, ADMIN_INFO_SSID, DSNACICS,
DSNLEUSR, DSNAIMS and DSNAIMS2. Further examples of DSNACICS, DSNAIMS and
DSNAIMS2 are in Chapter 23, “Accessing CICS and IMS” on page 469.
The other procedures contained in the table are only listed to provide a complete picture of all
system administration server programs. For more detailed information on these, refer to the
DB2 Version 9.1 for z/OS DB2 Version 9.1 for z/OS Administration Guide, SC18-9840.
Utility execution
Table 24-5 lists the stored procedures that support utility execution.
CALL syntax - More detailed information on the CALL syntax for the two stored procedures
ADMIN_UTL_SCHEDULE and ADMIN_UTL_SORT, as well as some more best practices on
these two utility execution stored procedures can be found in 24.2.5, “Utility execution” on
page 560.
The other stored procedures in this table are only listed to provide a complete picture; more
details can be found in DB2 Version 9.1 for z/OS Utility Guide an Reference, SC18-9855.
Scheduling tasks
Table 24-6 lists the stored procedures that allow the scheduling of either stored procedures or
JCL tasks. This is the SQL interface for the DB2 task scheduler. These procedures are new
and were not part of the DB2 UDB Control Center.
CALL syntax - More detailed information on the CALL syntax for the two stored procedures
ADMIN_TASK_ADD, ADMIN_TASK_REMOVE and the table functions ADMIN_TASK_LIST,
ADMIN_TASK_STATUS can be found in 24.3, “Scheduling administrative stored procedures
with the DB2 task scheduler” on page 569. This section also provides a checklist for distinct
scheduling scenarios.
498 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
For further details, refer to DB2 Version 9.1 for z/OS Administration Guide, SC18-9840 and
DB2 Version 9.1 for z/OS SQL Reference, SC18-9854.
Sample programs - Sample Java programs can be found in A.9, “Task Scheduler Sample
Use cases” on page 858.
CALL syntax - For more information on the concept and how to work with the Common SQL
API, refer to 24.4, “Common SQL API - Administration functions common to all IBM data
servers” on page 589. Additional details can be found in DB2 Version 9.1 for z/OS
Administration Guide, SC18-9840 and DB2 Version 9.1 for z/OS SQL Reference, SC18-9854.
Sample program - Sample Java programs can be found in A.10, “Invoking the Common SQL
API stored procedures” on page 870.
CALL syntax - For more information on the concept and how to work with the DB2 provided
stored procedures for XML schema registration and removal, refer to DB2 Version 9.1 for
z/OS XML Guide, SC18-9858.
Unified Debugger
The set of stored procedures that are used by the Unified Debugger that is built into Data
Studio is listed in Table 24-9 for your reference.
DBG_ENDSESSIONMANAGER none No No
DBG_INITIALIZECLIENT none No No
DBG_LOOKUPSESSIONMANAGER none No No
DBG_PINGSESSIONMANAGER none No No
DBG_RECVCLIENTREPORTS none No No
DBG_SENDCLIENTCOMMANDS none No No
DBG_SENDCLIENTREQUESTS none No No
DBG_TERMINATECLIENT none No No
DB2DEBUG.DEBUGGERLEVEL none No No
DB2DEBUG.CREATE_SESSION none No No
DB2DEBUG.DESTROY_SESSION none No No
DB2DEBUG.QUERY_SESSION none No No
DB2DEBUG.LIST_SESSION none No No
DB2DEBUG.PUT_COMMAND none No No
DB2DEBUG.GET_REPORT none No No
For more information on the concept and how to work with the DB2-provided stored
procedures for the Unified Debugger, refer to Chapter 28, “Tools for debugging DB2 stored
procedures” on page 735.
500 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
These procedures and the associated database objects are installed with the help of the
post-install job DSNTIJMS.
SYSIBM.SQLCOLPRIVILEGES none No No
SYSIBM.SQLCOLUMNS none No No
SYSIBM.SQLFOREIGNKEYS none No No
SYSIBM.SQLPRIMARYKEYS none No No
SYSIBM.SQLPROCEDURECOLS none No No
SYSIBM.SQLPROCEDURES none No No
SYSIBM.SQLSPECIALCOLUMNS none No No
SYSIBM.SQLSTATISTICS none No No
SYSIBM.SQLTABLEPRIVILEGES none No No
SYSIBM.SQLTABLES none No No
SYSIBM.SQLGETTYPEINFO none No No
SYSIBM.SQLUDTS none No No
SYSIBM.SQLCAMESSAGE none No No
For more information about enabling the DB2-supplied stored procedures and defining the
tables used by the IBM DB2 Driver for JDBC and SQLJ, refer to DB2 Version 9.1 for z/OS
Application Programming Guide and Reference for Java, SC18-9842.
CALL syntax - For more information on how to work with the DB2 provided stored
procedures for Java procedure processing, refer to DB2 Version 9.1 for z/OS Application
Programming Guide and Reference for Java, SC18-9842.
Start
End
502 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Step 1: Install the required maintenance for HDBxx10
Table 24-12 lists all required PTF/ and PAR numbers to enable the new Administrative
enablement, the task scheduler, and the common SQL API procedures that are discussed
later in this chapter in detail.
UK32795 V9 DSNACCOX
Note: The PTF numbers listed in Table 24-12 reflect the most recent version of the
respective procedures at the time the book was published. Check for other possible PTFs
that might contain updates in the future.
In Table 24-13, if the procedure name is in bold then this procedure requires APF
authorization. If the procedure name is suffixed with (*) then special DD statements are
required in the WLM JCL or additional post-install jobs have to be submitted. In this case the
column “Recommended WLM application environment name” contains further information.
The column with DSNTIJSG lists the environment names created by default and added here
for cross reference.
504 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Stored procedure name NUMTCB Recommended WLM DSNTIJSG
application application
environment name environment name
As a best practice recommendation, we tried to keep the number of different WLM application
environments as low as possible. For the above listed DB2-supplied stored procedures we
therefore recommend to create at least eleven different WLM application environments per
DB2 subsystem. The following listing contains some more information about the WLM
application environments:
506 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
DSNWLM_UTILS - It is required that online utility execution stored procedures DSNUTILS
and DSNUTILU run in a WLM application environment where NUMTCB = 1. Both
procedures use data sets that are allocated in the JCL procedure for the WLM application
environment. If more than one instance of DSNUTILS were allowed to run in the same
address space, the instances would overwrite each other’s data sets, leading to
indeterministic behavior. Be aware that SYSIN and SYSPRINT must be allocated to work
files, in the WLM JCL.
Example 24-1 contains a sample startup procedure for the DSNWLM_UTILS WLM
application environment.
508 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
// DB2SSN=DSN,RGN=0K,NUMTCB=1
//IEFPROC EXEC PGM=DSNX9WLM,REGION=&RGN,TIME=NOLIMIT,
// DYNAMNBR=5, <== Allow for Dyn Allocs
// PARM='&DB2SSN,1,&APPLENV' <== Use 1, not NUMTCB
//*
//NUMTCB@1 SET NUMTCB= <== Null NUMTCB symbol
//*
//* Include SDSNEXIT to use Secondary Authids (DSN3@ATH DSN3@SGN exits)
//STEPLIB DD DISP=SHR,DSN=prefix.RUNLIB.LOAD
// DD DISP=SHR,DSN=CBC!!.SCCNCMP <== C Compiler
// DD DISP=SHR,DSN=prefix.SCEERUN <== LE runtime
// DD DISP=SHR,DSN=prefix.SDSNEXIT
// DD DISP=SHR,DSN=prefix.SDSNLOAD
//SYSEXEC DD DISP=SHR, <== Location of DSNTPSMP
// DSN=DSN!!0.SDSNCLST
//SYSTSPRT DD SYSOUT=*
//CEEDUMP DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSABEND DD DUMMY
//DSNTRACE DD SYSOUT=*
//*
//**** Data sets required by the SQL Procedures Processor
//SQLDBRM DD DISP=SHR, <== DBRM Library
// DSN=DSN!!0.DBRMLIB.DATA
//SQLCSRC DD DISP=SHR, <== Generated C Source
// DSN=DSN!!0.SRCLIB.DATA
//SQLLMOD DD DISP=SHR, <== Application Loadlib
// DSN=DSN!!0.RUNLIB.LOAD
//SQLLIBC DD DISP=SHR, <== C header files
// DSN=CEE!!.SCEEH.H
// DD DISP=SHR,
// DSN=CEE!!.SCEEH.SYS.H
// DD DISP=SHR, <== Debug header file
// DSN=DSN!!0.SDSNC.H
//SQLLIBL DD DISP=SHR, <== Linkedit includes
// DSN=CEE!!.SCEELKED
// DD DISP=SHR,
// DSN=DSN!!0.SDSNLOAD
//SYSMSGS DD DISP=SHR, <== Prelinker msg file
// DSN=CEE!!.SCEEMSGP(EDCPMSGE)
//*
//**** DSNTPSMP Configuration File - CFGTPSMP (optional)
//* A site provided sequential dataset or member, used to
//* define customized operation of DSNTPSMP in this APPLENV.
//*CFGTPSMP DD DISP=SHR,DSN=
//*
//**** 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=SYSALLDA,SPACE=(23476,(20,20)),
// DCB=(RECFM=VB,LRECL=137,BLKSIZE=23476)
//SQLTERM DD UNIT=SYSALLDA,SPACE=(23476,(20,20)),
// DCB=(RECFM=VB,LRECL=137,BLKSIZE=23476)
//SQLOUT DD UNIT=SYSALLDA,SPACE=(23476,(20,20)),
// DCB=(RECFM=VB,LRECL=137,BLKSIZE=23476)
//SQLCPRT DD UNIT=SYSALLDA,SPACE=(23476,(20,20)),
// DCB=(RECFM=VB,LRECL=137,BLKSIZE=23476)
//SQLUT1 DD UNIT=SYSALLDA,SPACE=(23440,(20,20)),
// DCB=(RECFM=FB,LRECL=80,BLKSIZE=23440)
//SQLUT2 DD UNIT=SYSALLDA,SPACE=(23440,(20,20)),
510 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
– SQLDUMMY - Required but needs to be allocated to DUMMY.
DSNWLM_CICS - Only for DSNACICS. If CICS 4.1 is to be called by DSNACICS,
NUMTCB must not exceed 25. If a newer version is to be called, the recommended
NUMTCB value is 40 and must not exceed 100.
Example 24-4 contains a sample startup procedure for the DSNWLM_CICS WLM
application environment.
512 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
//IEFPROC EXEC PGM=DSNX9WLM,REGION=&RGN,TIME=NOLIMIT,
// PARM='&DB2SSN,&NUMTCB,&APPLENV'
//STEPLIB DD DISP=SHR,DSN=prefix.SCEERUN
// DD DISP=SHR,DSN=prefix.SDSNEXIT
// DD DISP=SHR,DSN=prefix.SDSNLOAD
Note: The environment is frequently refreshed when debug diagnostics are activated.
DSNWLM_JAVA_LARGEMEM - Similar to DSNWLM_JAVA, but specifies additional DDs
and a maximum TCB setting of 1 to account for high memory usage by the DB2-supplied
Java routines assigned to run in it.
Example 24-9 contains a sample startup procedure for the DSNWLM_JAVA_LARGEMEM
WLM application environment.
514 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
// PATHOPTS=(ORDWR,OCREAT,OAPPEND),
// PATHMODE=(SIRUSR,SIWUSR,SIRGRP,SIWGRP,SIROTH,SIWOTH)
//JAVAERR DD PATH='/V1R7/USR/db2a10/JAVAERR.TXT',
// PATHOPTS=(ORDWR,OCREAT,OAPPEND),
// PATHMODE=(SIRUSR,SIWUSR,SIRGRP,SIWGRP,SIROTH,SIWOTH)
To minimize the overhead required to start and manage WLM application environment
address spaces, we recommend that you create the WLM application environments
DSNWLM_GENERAL / DSNWLM_XML / DSNWLM_PROGRAM_CONTROL /
DSNWLM_CICS with NUMTCB = 40 - 60, and assign the respective listed stored procedures
to them. However, in a very CPU-constrained environment, the recommendation is to use a
lower number, such as 5 - 20.
Step 3: Define the required RACF authorities and grant DB2 authorities
To execute the CALL statement, the owner of the package or plan that contains the CALL
statement must have one or more of the following privileges on each package that the stored
procedure uses:
The EXECUTE privilege on the respective package
Ownership of the package
PACKADM authority for the package collection
SYSADM authority
516 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
In addition to the required authorities to execute a stored procedure, the following RACF
authorities and DB2 authorities need to be granted.
ADMIN_COMMAND_DSN - To execute the DSN subcommand, you must use a privilege set
that includes the authorization to execute the respective subcommand, as described in DB2
Version 9.1 for z/OS Command Reference, SC18-9844.
ADMIN_COMMAND_DB2 - This procedure can be used to issue any DB2 command. Hence,
it will require the corresponding system privilege, such as the DISPLAY system privilege to
issue a -DISPLAY BUFFERPOOL. Privileges required for other DB2 commands can be found
in DB2 Version 9.1 for z/OS Command Reference, SC18-9844.
The owner of the package or plan that contains the CALL ADMIN_INFO_HOST statement
must also have the authorization required to execute the stored procedure
ADMIN_COMMAND_DB2 and the specified DB2 commands. To determine the privilege or
authority required to issue a DB2 command, see DB2 Version 9.1 for z/OS Command
Reference, SC18-9844.
DSNWZP / DSNWSPM - The primary authorization ID of the caller must have MONITOR1
and TRACE privileges to run this routine.
DSNACICS - The CICS server program that DSNACICS calls runs under the same user ID as
DSNACICS. That user ID depends on the SECURITY parameter that you specify when you
define DSNACICS. The DSNACICS caller also needs authorization from an external security
system, such as RACF, to use CICS resources. See Part 2 of DB2 Version 9.1 for z/OS
Installation Guide, GC18-9846.
DSNAIMS and DSNAIMS2 - Ensure that OTMA C/I is initialized. See IMS Version 9: Open
Transaction Manager Access Guide and Reference, SC18-7829 for an explanation of the C/I
initialization.
The owner of the package or plan that contains the CALL ADMIN_UTL_SCHEDULE
statement must also have the authorization to execute these stored procedures and run the
requested utilities. To determine the privilege or authority required to call DSNUTILU, see
DB2 Version 9.1 for z/OS Utility Guide an Reference, SC18-9855.
ADMIN_UTL_SORT - The owner of the package or plan that contains the CALL statement
must also have SELECT authority on the following catalog tables:
SYSIBM.SYSTABLEPART
SYSIBM.SYSINDEXPART
SYSIBM.SYSINDEXES
SYSIBM.SYSTABLES
DSNACCOX - The user ID that calls DSNACCOX must have SELECT authority on the
real-time statistics tables and the DISPLAY system privilege.
DSNUTILS or DSNUTILU - The user ID that runs a utility through DSNUTILS or DSNUTILU
must have authorization to run the specified utility.
Users with SYSOPR, SYSCTRL, or SYSADM authority can remove any task. Other users
who have EXECUTE privileges on this stored procedure can remove tasks that they added.
Attempting to remove a task that was added by a different user returns an error in the output
parameters return-code and message. Refer to “Removing a scheduled task” on page 575 for
further details.
APF-authorized
Some stored procedures need to run APF-authorized. In this case, ensure that all data sets in
the STEPLIB DD concatenation of the WLM JCL are added to the APF authorization list. If
only one of these data sets is not APF-authorized, all other data sets in the same STEPLIB
concatenation are treated non-APF-authorized as well.
518 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Refer to 24.1.2, “Setting up DB2-supplied stored procedures” on page 502 to obtain the APF
authorization requirement for the respective DB2-supplied stored procedure.
We did not split DSNWLM_GENERAL into two WLM application environments separating the
APF from non-APF-authorized running stored procedures, but rather used only one. This is
because we wanted to create as few WLM application environments as possible for the best
practice recommendations.
Program controlled
Several stored procedures described in this book execute the __login() function to switch
users. If the BPX.DAEMON facility class is active and the BPX.DAEMON.HFSCTL facility
class is not defined, the modules that implement these stored procedures must be defined to
RACF program control. Otherwise, the following error will be returned:
EDC5139I Operation not permitted
Once these modules are defined to RACF program control, they must be loaded into a
WLM-established stored procedure address space that only loads controlled programs. This
is the reason why we specified a different WLM application environment for these stored
procedures, instead of using DSNWLM_GENERAL.
You can define programs from traditional libraries to program control or define the
BPX.DAEMON.HFSCTL profile in the facility class so that programs that are loaded from MVS
libraries are not checked for program control. If the BPX.DAEMON.HFSCTL FACILITY class
profile has been set up, you can choose to run the stored procedure that requires RACF
program control (for example ADMIN_COMMAND_UNIX, ADMIN_JOB_SUBMIT) in the WLM
application environment where the other administration enablement stored procedures are
running (for example DSNWLM_GENERAL). Otherwise, they must run in a different WLM
environment, such as DSNWLM_PROGRAM_CONTROL.
To define programs from traditional libraries to program control, you need to:
1. Activate the RACF program control (both access control to load modules and program
access to data sets):
SETROPTS WHEN(PROGRAM)
2. Define one of the following profiles:
a. For a particular program, define a discrete RACF PROGRAM class profile:
RDEFINE PROGRAM membername ADDMEM( ’datasetname’ / volser/NOPADCHK) UACC(READ)
The following members of SDSNLOAD must be program-controlled:
• SDSNLOAD(DSNX9WLM)
• SDSNLOAD(DSNX9SPA)
• SDSNLOAD(DSNARRS)
• SDSNLOAD(DSN3ID00)
• SDSNLOAD(DSNX9WLS)
• SDSNLOAD(DSNADMJS)
• SDSNLOAD(DSNADMJP)
• SDSNLOAD(DSNADMJQ)
• SDSNLOAD(DSNADMJF)
• SDSNLOAD(DSNADMCU)
b. For all members in a data set:
RDEFINE PROGRAM * ADDMEM( ’datasetname’ / volser / NOPADCHK) UACC(READ)
3. Refresh the in-storage copy of the PROGRAM profile:
SETROPTS WHEN(PROGRAM) REFRESH
For detailed samples of RACF program control, refer to the installation job DSNTIJRA.
For more information on BPX.DAEMON and setting up program control, refer to z/OS UNIX
System Services Planning, GA22-7800-03.
Refer to 24.1.2, “Setting up DB2-supplied stored procedures” on page 502 for the
program-controlled requirement for the respective DB2-supplied stored procedure.
520 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
You can find out the location, IP address, and TCP port number by issuing the DB2 command
-DISPLAY DDF from an MVS console. In our tests we used the following commands to
catalog the test system:
db2 catalog tcpip node TCP0001 remote wtsc63.itso.ibm.com server 12345
db2 catalog dcs database DB9A as DB9A
db2 catalog database DB9A as DB9A at node TCP0001 authentication DCS
Verify that your DB2 subsystem is cataloged correctly by connecting to it. Enter the following
command from a DB2 command window:
db2 connect to <db alias> user <user> using <password>
You should see a message like the following with the version, release, and modification
number of your DB2 subsystem:
Database Connection Information
It is important that you now bind the applications and utilities on your DB2 subsystem. While
still connected and in the DB2 command window, change to the SQLLIB\bnd directory and
issue the following commands:
db2 bind @db2ubind.lst blocking all sqlerror continue grant public
db2 bind @db2cli.lst blocking all sqlerror continue grant public
You only have to bind the applications and utilities the first time you use a new client against a
DB2 subsystem. Disconnect after you have successfully bound the utilities. For more
information, refer to DB2 Connect Version 9 User’s Guide, SC10-4229-00.
CALL S Y S P R O C . A D M IN _ C O M M A N D _ U N IX (
u s e r - ID , p a s s w o rd ,
U S S -c o m m a n d , o u tp u t- la y o u t,
|- O U T M O D E = B L K - |
|- N U L L - |
|- O U T M O D E = L IN E - |
re tu rn -c o d e , m essage )
522 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
The first messages in this area are generated by the stored procedure. Messages that are
generated by DB2 might follow the first messages.
This is an output parameter of type VARCHAR(1331).
ADMIN_COMMAND_UNIX output
This stored procedure returns the following output parameters:
return-code
message
In addition to the preceding output, the stored procedure returns one result set that contains
the z/OS UNIX System Services command output messages.
Table 24-14 shows the format of the result set returned in the created global temporary table
SYSIBM.USS_CMD_OUTPUT.
SYSPROC.ADMIN_COMMAND_DSN
The SYSPROC.ADMIN_COMMAND_DSN stored procedure executes a BIND, REBIND, or
FREE DSN subcommand and returns the output from the DSN subcommand execution.
Load module name: DSNADMCS
Package name: no package, this is a REXX procedure
CALL SYSPROC.ADMIN_COMMAND_DSN (
DSN-subcommand, message )
The stored procedure returns one result set that contains the DSN subcommand output
messages. Table 24-15 shows the format of the result set returned in the created global
temporary table SYSIBM.DSN_SUBCMD_OUTPUT.
SYSPROC.ADMIN_COMMAND_DB2
The SYSPROC.ADMIN_COMMAND_DB2 stored procedure executes one or more DB2
commands on a connected DB2 subsystem or on a DB2 data sharing group member and
returns the command output messages.
Load module name: DSNADMCD
Package name: DSNADMCD
CALL SYSPROC.ADMIN_COMMAND_DB2 (
DB2-command, command-length,
parse-type, DB2-member,
|- NULL -|
commands-executed, IFI-return-code,
IFI-reason-code, excess-bytes,
group-IFI-reason-code, group-excess-bytes,
return-code, message )
524 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
command-length: Specifies the length of the DB2 command or commands. When
multiple DB2 commands are specified in DB2-command, command-length is the sum of
all of those commands, including the \0 command delimiters.
This is an input parameter of type INTEGER and cannot be null.
parse-type: Identifies the type of output message parsing requested.
If you specify a parse type, ADMIN_COMMAND_DB2 parses the command output
messages and provides the formatted result in a specific global temporary table. Possible
values are:
BP - parse “-DISPLAY BUFFERPOOL” command output messages
DB - parse “-DISPLAY DATABASE” command output messages and return database
information.
TS - parse “-DISPLAY DATABASE(...) SPACENAM(...)” command output messages
and return table spaces information.
IX - parse “-DISPLAY DATABASE(...) SPACENAM(...)” command output messages and
return index spaces information.
THD - parse “-DISPLAY THREAD” command output messages.
UT - parse “-DISPLAY UTILITY” command output messages.
GRP - parse “-DISPLAY GROUP” command output messages.
DDF - parse “-DISPLAY DDF” command output messages.
Any other value - Do not parse any command output messages.
Refer to “ADMIN_COMMAND_DB2 output” on page 526 for detailed information about the
respective result set structures which are determined by parse-type.
This is an input parameter of the type VARCHAR(3) and cannot be null.
DB2-member: Specifies the name of a single data sharing group member on which an IFI
request is to be executed.
This is an input parameter of type VARCHAR(8).
commands-executed: Provides the number of commands that were executed.
This is an output parameter of type INTEGER.
IFI-return-code: Provides the IFI return code.
This is an output parameter of the type INTEGER.
IFI-reason-code: Provides the IFI reason code.
This is an output parameter of the type INTEGER.
excess-bytes: Indicates the number of bytes that did not fit in the return area.
This is an output parameter of the type INTEGER.
group-IFI-reason-code: Provides the reason code for the situation in which an IFI call
requests data from members of a data sharing group and not all the data is returned from
group members.
This is an output parameter of the type INTEGER.
group-excess-bytes: Indicates the total length of data that was returned from other data
sharing group members and did not fit in the return area.
This is an output parameter of the type INTEGER.
ADMIN_COMMAND_DB2 output
This stored procedure returns the following output parameters:
commands-executed
IFI-return-code
IFI-reason-code
excess-bytes
group-IFI-reason-code
group-excess-bytes
return-code
message
In addition to the preceding output, the stored procedure returns two result sets.
The first result set is returned in the created global temporary table
SYSIBM.DB2_CMD_OUTPUT and contains the DB2 command output messages that were
not parsed.
The format of the second result set varies, depending on the DB2 command issued and the
parse-type value.
Table 24-17 shows the format of the second result set returned in the created global
temporary table SYSIBM.BUFFERPOOL_STATUS when parse-type = ’BP’.
526 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Column name Data type Contents
PCT_VDWQT INTEGER Vertical deferred write threshold for the buffer pool (as
percentage of virtual buffer pool size)
ABS_VDWQT INTEGER Vertical deferred write threshold for the buffer pool (as
absolute number of buffers)
PGSTEAL CHAR(4) Page-stealing algorithm that DB2 uses for the buffer
pool
Table 24-18 shows the format of the second result set returned in the created global
temporary table SYSIBM.DB2_THREAD_STATUS when parse-type = ’THD’.
Table 24-19 shows the format of the second result set returned in the created global
temporary table SYSIBM.UTILITY_JOB_STATUS when parse-type = ’UT’
NUM_OBJ INTEGER Total number of objects in the list of objects the utility is
processing
Table 24-20 shows the format of the second result set returned in the created global
temporary table SYSIBM.DB_STATUS when parse-type = ’DB’ or ’TS’ or ’IX’.
528 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Table 24-20 Result set row for SYSIBM.DB_STATUS
Column name Data type Contents
Table 24-21 shows the format of the second result set returned in the created global
temporary table SYSIBM.DATA_SHARING_GROUP when parse-type = ’GRP’
Table 24-22 shows the format of the second result set returned in the created global
temporary table SYSIBM.DDF_CONFIG when parse_type = ’DDF’:
SYSPROC.ADMIN_JOB_SUBMIT
The SYSPROC.ADMIN_JOB_SUBMIT stored procedure submits a job to a JES2 or JES3
system.
Load module name: DSNADMJS
Package name: DSNADMJS
CALL SYSPROC.ADMIN_JOB_SUBMIT (
user-ID, password,
530 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
job-ID: Identifies JES2 or JES3 job ID of the submitted job.
This is an output parameter of type CHAR(8).
return-code: Provides the return code from the stored procedure. Possible values are:
– 0 - The call completed successfully.
– 12 - The call did not complete successfully. The message output parameter contains
messages describing the error.
This is an output parameter of type INTEGER.
message: Contains messages describing the error encountered by the stored procedure.
If no error occurred, then no message is returned.
The first messages in this area are generated by the stored procedure. Messages that are
generated by DB2 might follow the first messages.
This is an output parameter of type VARCHAR(1331).
Table 24-23 shows the format of the created global temporary table SYSIBM.JOB_JCL.
ADMIN_JOB_SUBMIT output
This stored procedure returns the following output parameters:
job-ID
return-code
message
SYSPROC.ADMIN_JOB_FETCH
The SYSPROC.ADMIN_JOB_FETCH stored procedure retrieves SYSOUT from JES spool
and returns the SYSOUT.
Load module name: DSNADMJF
Package name: DSNADMJF
C ALL S Y S P R O C .A D M IN _ J O B _ F E T C H (
u s e r-ID , p a s s w o rd , jo b -ID ,
re tu rn -c o d e , m essage )
ADMIN_JOB_FETCH output
This stored procedure returns the following output parameters:
return-code
message
In addition to the preceding output, the stored procedure returns one result set that contains
the data from the JES-managed SYSOUT data set that belong to the job ID specified in the
input parameter job-ID.
Table 24-24 shows the format of the result set returned in the created global temporary table
SYSIBM.JES_SYSOUT.
SYSPROC.ADMIN_JOB_QUERY
The SYSPROC.ADMIN_JOB_QUERY stored procedure displays the status and completion
information of a job.
Load module name: DSNADMJQ
Package name: None
532 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
CALL S Y S P R O C . A D M IN _ J O B _ Q U E R Y (
u s e r -ID , p a s s w o rd , jo b - I D ,
s ta tu s , m a x -R C ,
c o m p le t io n -t y p e , s y s te m -a b e n d -c o d e , u s e r-a b e n d -c o d e
re tu rn -c o d e , m essage )
ADMIN_JOB_QUERY output
This stored procedure returns the following output parameters:
status
max-RC
completion-type
system-abend-code
user-abend-code
return-code
message
SYSPROC.ADMIN_JOB_CANCEL
The SYSPROC.ADMIN_JOB_CANCEL stored procedure purges or cancels a job.
Load module name: DSNADMJP
Package name: None
534 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
C ALL SYSPROC.ADM IN_JOB_CANCEL (
user-ID, password,
processing-option, Job-ID,
return-code, message )
SYSPROC.ADMIN_DS_BROWSE
The SYSPROC.ADMIN_DS_BROWSE stored procedure returns either text or binary records
from a physical sequential (PS) data set, generation data set, or partitioned data set (PDS) or
partitioned data set extended (PDSE) member. This stored procedure supports only data sets
with LRECL=80 and RECFM=FB.
Data set action is performed under the security context of the authorization ID of the user who
invoked the stored procedure.
Load module name: DSNADMDB
Package name: DSNADMDB
CALL SYSPROC.ADMIN_DS_BROWSE (
data-type, data-set-name,
member-name, dump-option,
return-code, message )
536 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
PDS or PDSE name: If reading from a member that belongs to this PDS or PDSE, the
data-set-name contains the name of the PDS or PDSE.
GDS name: If reading from a generation data set, the data-set-name contains the
name of the generation data set, such as USERGDG.FILE.G0001V00.
This is an input parameter of type CHAR(44) and cannot be null.
member-name: Specifies the name of the PDS or PDSE member, if reading from a PDS
or PDSE member. Otherwise, a blank character.
This is an input parameter of type CHAR(8) and cannot be null.
dump-option: Specifies whether to use the DB2 standard dump facility to dump the
information necessary for problem diagnosis when an SQL error occurred or when a call
to the IBM routine IEFDB476 to get messages about an unsuccessful SVC 99 call failed.
Possible values are:
Y - Generate a dump
N - Do not generate a dump
This is an input parameter of type CHAR(1) and cannot be NULL.
return-code: Provides the return code from the stored procedure. Possible values are:
– 0 - The call completed successfully.
– 12 - The call did not complete successfully. The message output parameter contains
messages describing the error.
This is an output parameter of type INTEGER.
message: Contains messages describing the error encountered by the stored procedure.
If no error occurred, then no message is returned.
The first messages in this area are generated by the stored procedure. Messages that are
generated by DB2 or z/OS might follow the first messages.
This is an output parameter of type VARCHAR(1331).
ADMIN_DS_BROWSE output
This stored procedure returns the following output parameters:
return-code
message
In addition to the preceding output, the stored procedure returns one result set that contains
the text or binary records read.
Table 24-25 shows the format of the result set returned in the created global temporary table
SYSIBM.TEXT_REC_OUTPUT containing text records read.
Table 24-26 shows the format of the result set returned in the created global temporary table
SYSIBM.BIN_REC_OUTPUT containing binary records read.
SYSPROC.ADMIN_DS_WRITE
The SYSPROC.ADMIN_DS_WRITE stored procedure writes either text or binary records
passed in a global temporary table to either a physical sequential (PS) data set, partitioned
data set (PDS) or partitioned data set extended (PDSE) member, or generation data set
(GDS). It can either append or replace an existing PS data set, PDS or PDSE member, or
GDS. It can create a new PS data set, PDS or PDSE data set or member, or a new GDS for
an existing generation data group (GDG) as needed. This stored procedure supports only
data sets with LRECL=80 and RECFM=FB.
Data set action is performed under the security context of the authorization ID of the user who
invoked the stored procedure.
Load module name: DSNADMDW
Package name: DSNADMDW
CALL SYSPROC.ADMIN_DS_WRITE (
data-type, data-set-name,
return-code, message )
538 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
member-name: Specifies the relative generation number of the GDS, if writing to a GDS,
or the name of the PDS or PDSE member, if writing to a PDS or PDSE member.
Otherwise, a blank character. Possible values are:
GDS relative generation number: Relative generation number of a GDS, if writing to
a GDS. For example: -1, 0, +1
PDS or PDSE member name: Name of the PDS or PDSE member, if writing to a
library member.
blank: In all other cases, blank.
This is an input parameter of type CHAR(8) and cannot be null.
processing-option: Specifies the type of operation. Possible values are:
R: Replace
A: Append
NM: New member
ND: New PS, PDS, PDSE, or GDS data set
This is an input parameter of type CHAR(2) and cannot be null.
dump-option: Specifies whether to use the DB2 standard dump facility to dump the
information necessary for problem diagnosis when an SQL error has occurred or when a
call to the IBM routine IEFDB476 to get messages about an unsuccessful SVC 99 call
failed. Possible values are:
Y - Generate a dump
N - Do not generate a dump
This is an input parameter of type CHAR(1) and cannot be null.
return-code: Provides the return code from the stored procedure. Possible values are:
0 - The call completed successfully
12 - The call did not complete successfully. The message output parameter contains
messages describing the error.
This is an output parameter of type INTEGER.
message: Contains messages describing the error encountered by the stored procedure.
If no error occurred, then no message is returned.
The first messages in this area are generated by the stored procedure. Messages that are
generated by DB2 or z/OS might follow the first messages.
This is an output parameter of type VARCHAR(1331).
Table 24-27 shows the format of the created global temporary table
SYSIBM.TEXT_REC_INPUT containing text records to be saved.
Table 24-28 shows the format of the created global temporary table
SYSIBM.BIN_REC_INPUT containing binary records to be saved:
ADMIN_DS_WRITE output
This stored procedure returns the following output parameters:
return-code
message
SYSPROC.ADMIN_DS_LIST
The SYSPROC.ADMIN_DS_LIST stored procedure returns a list of data set names,
generation data group (GDG), partitioned data set (PDS), or partitioned data set extended
(PDSE) members, or generation data sets of a GDG.
Data set action is performed under the security context of the authorization ID of the user who
invoked the stored procedure.
Load module name: DSNADMDL
Package name: DSNADMDL
CALL SYSPROC.ADMIN_DS_LIST (
data-set-name, list-members,
return-code, message )
540 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
This is an input parameter of type CHAR(44) and cannot be null.
list-members: Specifies whether to list PDS or PDSE members. Possible values are:
Y - List members. Only set to Y when data-set-name is a fully qualified PDS or PDSE.
N - Do not list members.
This is an input parameter of type CHAR(1) and cannot be null.
list-generations: Specifies whether to list generation data sets. Possible values are:
Y - List generation data sets. Only set to Y when data-set-name is a fully qualified
GDG.
N - Do not list generation data sets.
This is an input parameter of type CHAR(1) and cannot be null.
max-results: Specifies the maximum number of result set rows. This option is applicable
only when both list-members and list-generations are 'N'.
This is an input parameter of type INTEGER and cannot be null.
dump-option: Specifies whether to use the DB2 standard dump facility to dump the
information necessary for problem diagnosis when any of the following errors occurred:
– SQL error
– A call to the IBM routine IEFDB476 to get messages about an unsuccessful SVC 99
call failed
– Load Catalog Search Interface module error
Possible Values are:
Y - Generate a dump.
N - Do not generate a dump.
This is an input parameter of type CHAR(1) and cannot be null.
return-code: Provides the return code from the stored procedure. Possible values are:
0 - The call completed successfully
12 - The call did not complete successfully. The message output parameter contains
messages describing the error.
This is an output parameter of type INTEGER.
message: Contains messages describing the error encountered by the stored procedure.
If no error occurred, then no message is returned.
The first messages in this area are generated by the stored procedure. Messages that are
generated by DB2 or z/OS might follow the first messages.
This is an output parameter of type VARCHAR(1331).
ADMIN_DS_LIST output
This stored procedure returns the following output parameters:
return-code
message
In addition to the preceding output, the stored procedure returns one result set that contains
the list of data sets, GDGs, PDS or PDSE members, or generation data sets that were
requested. Table 24-29 shows the format of the result set returned in the created global
temporary table SYSIBM.DSLIST.
Member name, if
list-members is ’Y’
CREATE_YEAR INTEGER Year data set was created. Not applicable for
member and VSAM cluster.
CREATE_DAY INTEGER The day of the year that the data set was created, as
an integer in the range of 1 to 366 where 1
represents January 1). Not applicable for member
and VSAM cluster.
VOLUME CHAR(6) Volume where data set resides. Not applicable for
member and VSAM cluster.
PRIMARY_EXTENT INTEGER Size of first extent (not applicable for member and
VSAM cluster)
DASD_USAGE CHAR(8) FOR Disk usage. For VSAM data and VSAM index only.
BIT DATA
542 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Column name Data type Contents
HARBA CHAR(6) FOR High allocated RBA. For VSAM data and VSAM
BIT DATA index only.
HURBA CHAR(6) FOR High used RBA. For VSAM data and VSAM index
BIT DATA only.
When a data set spans more than one volume, one row is returned for each volume that
contains a piece of the data set. The VOLUME, EXTENTS_IN_USE, DASD_USAGE,
HARBA, and HURBA columns will reflect information for the specified volume.
SYSPROC.ADMIN_DS_RENAME
The SYSPROC.ADMIN_DS_RENAME stored procedure renames a physical sequential (PS)
data set, a partitioned data set (PDS) or partitioned data set extended (PDSE), or a member
of a PDS or PDSE.
Data set action is performed under the security context of the authorization ID of the user who
invoked the stored procedure.
Load module name: DSNADMDR
Package name: None
C AL L SY S PR O C .AD M IN _D S_R E N AM E (
return-co d e, m essage )
0 3 No message is returned.
Not 0 not applicable Contains messages describing the error encountered by the
stored procedure.
The first messages are generated by the stored procedure
and messages that are generated by z/OS might follow these
first messages. The first messages can also be generated by
z/OS.
544 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
ADMIN_DS_RENAME output
This stored procedure returns the following output parameters:
return-code
message
SYSPROC.ADMIN_DS_DELETE
The SYSPROC.ADMIN_DS_DELETE stored procedure deletes a physical sequential (PS)
data set, a partitioned data set (PDS) or partitioned data set extended (PDSE), a generation
data set (GDS), or a member of a PDS or PDSE.
Data set action is performed under the security context of the authorization ID of the user who
invoked the stored procedure.
Load module name: DSNADMDD
Package name: None
C ALL S Y S P R O C .A D M IN _ D S _ D E L E T E (
d a ta -s e t-ty p e , d a ta -s e t-n a m e ,
p a re n t- d a ta -s e t-n a m e , d u m p - o p t io n ,
re tu r n -c o d e , m essage )
ADMIN_DS_DELETE output
This stored procedure returns the following output parameters:
return-code
message
SYSPROC.ADMIN_DS_SEARCH
The SYSPROC.ADMIN_DS_SEARCH stored procedure determines if a physical sequential
(PS) data set, partitioned data set (PDS), partitioned data set extended (PDSE), generation
data group (GDG), generation data set (GDS) is cataloged, or if a library member of a
cataloged PDS or PDSE exists.
Data set action is performed under the security context of the authorization ID of the user who
invoked the stored procedure.
Load module name: DSNADMDE
Package name: None
546 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
CALL SYSPROC.ADMIN_DS_SEARCH (
ADMIN_DS_SEARCH output
This stored procedure returns the following output parameters:
data-set-exists
return-code
message
ADMIN_DS_LIST will only list the GDG. The GDSs will only be listed by ADMIN_DS_LIST
when the data-set-name is USER01.GDG and list-generations =’Y’. The DSNAME returned
then is G0001V00.
SYSPROC.ADMIN_INFO_HOST
The SYSPROC.ADMIN_INFO_HOST stored procedure returns the host name of a connected
DB2 subsystem or the host name of every member of a data sharing group.
Load module name: DSNADMIH
Package name: DSNADMIH
548 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
CALL SYSPROC.ADMIN_INFO_HOST (
processing-option, DB2-member,
|- NULL -|
return-code, message )
ADMIN_INFO_HOST output
This stored procedure returns the following output parameters:
return-code
message
In addition to the preceding output, the stored procedure returns one result set that contains
the host names.
SYSPROC.ADMIN_INFO_SSID
The SYSPROC.ADMIN_INFO_SSID stored procedure returns the name of the connected
DB2 subsystem.
Load module name: DSNADMIS
Package name: None
CALL SYSPROC.ADMIN_INFO_SSID (
ADMIN_INFO_SSID output
This stored procedure returns the following output parameters:
subsystem-ID
return-code
message
550 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
SYSPROC.DSNACICS
The CICS transaction invocation stored procedure (DSNACICS) invokes CICS server
programs.
Load module name: DSNACICS
Package name: None
DSNACICS gives workstation applications a way to invoke CICS server programs while using
TCP/IP as their communication protocol. The workstation applications use TCP/IP and DB2
Connect to connect to a DB2 for z/OS subsystem, and then call DSNACICS to invoke the
CICS server programs.
The DSNACICS input parameters require knowledge of various CICS resource definitions
with which the workstation programmer might not be familiar. For this reason, DSNACICS
invokes the DSNACICX user exit routine. The system programmer can write a version of
DSNACICX that checks and overrides the parameters that the DSNACICS caller passes. If no
user version of DSNACICX is provided, DSNACICS invokes the default version of
DSNACICX, which does not modify any parameters.
Environmental considerations
DSNACICS runs in a WLM-established stored procedure address space and uses the
Resource Recovery Services attachment facility to connect to DB2.
If you use CICS Transaction Server for OS/390 Version 1 Release 3 or later, you can register
your CICS system as a resource manager with recoverable resource management services
(RRMS). When you do that, changes to DB2 databases that are made by the program that
calls DSNACICS and the CICS server program that DSNACICS invokes are in the same
two-phase commit scope. This means that when the calling program performs an SQL
COMMIT or ROLLBACK, DB2 and RRS inform CICS about the COMMIT or ROLLBACK.
If the CICS server program that DSNACICS invokes accesses DB2 resources, the server
program runs under a separate unit of work from the original unit of work that calls the stored
procedure. This means that the CICS server program might deadlock with locks that the client
program acquires.
Syntax
The following syntax diagram shows the SQL CALL statement for invoking this stored
procedure.
Because the linkage convention for DSNACICS is GENERAL WITH NULLS, if you pass
parameters in host variables, you need to include a null indicator with every host variable. Null
indicators for input host variables must be initialized before you execute the CALL statement.
The syntax diagram in Figure 24-17 shows the SQL CALL statement for DSNACICS.
parm-level, pgm-name,
|- NULL -| |- NULL -|
CICS-applid, CICS-level,
|- NULL -| |- NULL -|
connect-type, netname,
|- NULL -| |- NULL -|
mirror-trans, COMMAREA,
|- NULL -| |- NULL -|
COMMAREA-total-len, sync-opts,
|- NULL -| |- NULL -|
return-code, message )
552 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
If this parameter contains blanks, DSNACICS passes a mirror-trans parameter value of
null to the CICS EXCI interface. This allows an installation to override the transaction
name in various CICS user-replaceable modules. If a CICS user exit routine does not
specify a value for the mirror transaction name, CICS invokes CICS-supplied default mirror
transaction CSMI.
This is an input parameter of type CHAR(4).
COMMAREA: Specifies the communication area (COMMAREA) that is used to pass data
between the DSNACICS caller and the CICS server program that DSNACICS calls.
This is an input/output parameter of type VARCHAR(32704). In the length field of this
parameter, specify the number of bytes that DSNACICS sends to the CICS server
program.
COMMAREA-total-len: Specifies the total length of the COMMAREA that the server
program needs.
This is an input parameter of type INTEGER. The length must be greater than or equal to
the value that you specify in the length field of the COMMAREA parameter and less than
or equal to 32704. When the CICS server program completes, DSNACICS passes the
server program’s entire COMMAREA, which is COMMAREA-total-len bytes in length, to
the stored procedure caller.
sync-opts: Specifies whether the calling program controls resource recovery, using
two-phase commit protocols that are supported by RRS. Possible values are:
1 - The client program controls commit processing. The CICS server region does not
perform a syncpoint when the server program returns control to CICS. Also, the server
program cannot take any explicit syncpoints. Doing so causes the server program to
abnormally terminate.
2 - The target CICS server region takes a syncpoint on successful completion of the
server program. If this value is specified, the server program can take explicit
syncpoints.
When CICS has been set up to be an RRS resource manager, the client application can
control commit processing using SQL COMMIT requests. DB2 for z/OS ensures that CICS
is notified to commit any resources that the CICS server program modifies during
two-phase commit processing.
When CICS has not been set up to be an RRS resource manager, CICS forces syncpoint
processing of all CICS resources at completion of the CICS server program. This commit
processing is not coordinated with the commit processing of the client program.
This option is ignored when CICS-level is 1. This is an input parameter of type INTEGER.
return-code: Return code from the stored procedure. Possible values are:
0 - The call completed successfully.
12 - The request to run the CICS server program failed. The msg-area parameter
contains messages that describe the error.
This is an output parameter of type INTEGER.
msg-area: Contains messages if an error occurs during stored procedure execution. The
first messages in this area are generated by the stored procedure. Messages that are
generated by CICS or the DSNACICX user exit routine might follow the first messages.
The messages appear as a series of concatenated, viewable text strings.
This is an output parameter of type VARCHAR(500).
OUTPUT
DSNACICS places the return code from DSNACICS execution in the return-code parameter.
If the value of the return code is non-zero, DSNACICS puts its own error messages and any
error messages that are generated by CICS and the DSNACICX user exit routine in the
msg-area parameter.
The COMMAREA parameter contains the COMMAREA for the CICS server program that
DSNACICS calls. The COMMAREA parameter has a VARCHAR type. Therefore, if the server
program puts data other than character data in the COMMAREA, that data can become
corrupted by code page translation as it is passed to the caller. To avoid code page
translation, you can change the COMMAREA parameter in the CREATE PROCEDURE
statement for DSNACICS to VARCHAR(32704) FOR BIT DATA. However, if you do so, the
client program might need to do code page translation on any character data in the
COMMAREA to make it readable.
Restrictions
Because DSNACICS uses the distributed program link (DPL) function to invoke CICS server
programs, server programs that you invoke through DSNACICS can contain only the CICS
API commands that the DPL function supports. The list of supported commands is
documented in CICS 3.1 Application Programming Reference, SC33-1688.
Debugging
If you receive errors when you call DSNACICS, ask your system administrator to add a
DSNDUMP DD statement in the startup procedure for the address space in which
DSNACICS runs. The DSNDUMP DD statement causes DB2 to generate an SVC dump
whenever DSNACICS issues an error message.
SYSPROC.DSNLEUSR
The DSNLEUSR stored procedure is a sample stored procedure that lets you store encrypted
values in the translated authorization ID (NEWAUTHID) and password fields of the
SYSIBM.USERNAMES table.
You provide all the values for a SYSIBM.USERNAMES row as input to DSNLEUSR.
DSNLEUSR encrypts the translated authorization ID and password values before it inserts
the row into SYSIBM.USERNAMES.
Load module name: DSNLEUSR
Package name: DSNLEUSR
Environment
DSNLEUSR has the following requirement:
z/OS Integrated Cryptographic Service Facility (ICSF) must be installed, configured, and
active. See Integrated Cryptographic Service Facility System Programmer’s Guide,
SC23-3974 for more information.
554 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Syntax
The syntax diagram in Figure 24-18 shows the SQL CALL statement for DSNLEUSR.
CALL SYSPROC.DSNLEUSR (
Type, AuthID,
|- NULL -|
LinkName, NewAuthID, password,
|- NULL -| |- NULL -| |- NULL -|
ReturnCode, MsgArea )
Output
If DSNLEUSR executes successfully, it inserts a row into SYSIBM.USERNAMES with
encrypted values for the NEWAUTHID and PASSWORD columns and returns 0 for the
ReturnCode parameter value. If DSNLEUSR does not execute successfully, it returns a
non-zero value for the ReturnCode value and additional diagnostic information for the
MsgArea parameter value.
SYSPROC.DSNAIMS
DSNAIMS is a stored procedure that allows DB2 applications to invoke IMS transactions and
commands easily, without maintaining their own connections to IMS.
DSNAIMS uses the IMS Open Transaction Manager Access (OTMA) API to connect to IMS
and execute the transactions.
Environment
DSNAIMS runs in a WLM-established stored procedures address space. DSNAIMS (and
DSNAIMS2) can share, for simplicity, a WLM environment, such as the DSNWLM_GENERAL
of Table 24-13 on page 504, since they do not require any special STEPLIB, DD or NUMTCB.
For performance, you might want to allocate DSNAIMS (and DSNIMS2) to a separate,
dedicated DSNWLM_IMS WLM environment with the same characteristics as
DSNWLM_GENERAL.
DSNAIMS requires DB2 with RRSAF enabled and IMS version 7 or later with OTMA Callable
Interface enabled.
To use a two-phase commit process, you must have IMS Version 8 with UQ70789 or later.
Authorization
To set up and run DSNAIMS, you must be authorized the perform the following steps:
1. Use the job DSNTIJIM to issue the CREATE PROCEDURE statement for DSNAIMS and
to grant the execution of DSNAIMS to PUBLIC. DSNTIJIM is provided in the SDSNSAMP
data set. You need to customize DSNTIJIM to fit the parameters of your system.
2. Ensure that OTMA C/I is initialized. See IMS Open Transaction Manager Access Guide
and Reference for an explanation of the C/I initialization.
Syntax
The syntax diagram in Figure 24-19 shows the SQL CALL statement for DSNAIMS.
556 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
CALL SYSPROC.DSNAIMS (
558 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
the output prefix and can determine the output destination for an IMS ALT_PCB output. If
an empty or null value is passed, IMS ignores this parameter.
user-data-in: This optional parameter contains any data that is to be included in the IMS
message prefix, so that the data can be accessed by IMS OTMA user exit routines
(DFSYIOE0 and DFSYDRU0) and can be tracked by IMS log records. IMS applications that
run in dependent regions do not access this data. The specified user data is not included in
the output message prefix. You can use this parameter to store input and output correlator
tokens or other information. It is ignored for RECEIXML schema processing.
The set of stored procedures that is provided to you for registration and removal of XML
schema repositories is a collection of five stored procedures and a user-defined function,
shown in Table 24-8.
VE functions.
user-data-out: On output, this field contains the user-data-in in the IMS output prefix. IMS
user exit routines (DFSYIOE0 and DFSYDRU0) can also create user-data-out for
SENDRECV and RECEIVE functions. The parameter is not updated for SEND functions.
status-message: Indicates any error message that is returned from the transaction or
command, OTMA, RRS, or DSNAIMS.
return-code: Indicates the return code that is returned for the transaction or command,
OTMA, RRS, or DSNAIMS.
SYSPROC.DSNAIMS2
DSNAIMS2 has the same characteristics of DSNAIMS above, with the addition of IMS
multi-segment transaction support implemented with the new IN parameter
OTMA_DATA_INSEG. For details on using the parameters, see also “Using the DSNAIMS2
stored procedure” on page 489.
SYSPROC.ADMIN_UTL_SCHEDULE
The SYSPROC.ADMIN_UTL_SCHEDULE stored procedure allows for parallel utility
execution.
Load module name: DSNADMUM
Package name: DSNADMUM
C ALL S Y S P R O C .A D M IN _ U T L _ S C H E D U L E (
m a x - p a ra lle l, o p tim iz e -w o rk lo a d ,
|- N U L L - |
s to p -c o n d itio n , u tility -ID -s te m ,
|- N U L L - |
s h u td o w n -d u ra tio n , nnuummbbeer r -o f- o b je c ts ,
|- N U L L - |
u tilitie s - r u n , h ig h e s t -r e tu r n - c o d e ,
p a r a lle l- ta s k s , r e tu r n -c o d e , m essage )
560 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
ADMIN_UTL_SCHEDULE option description
max-parallel: Specifies the maximum number of parallel threads that may be started. The
actual number may be lower than the requested number based on the optimizing sort
result. Possible values are: 1 to 99.
This is an input parameter of type SMALLINT and cannot be null.
optimize-workload: Specifies whether the parallel utility executions should be sorted to
achieve shortest overall execution time. Possible values are:
NO or null - The workload is not to be sorted.
YES - The workload is to be sorted.
This is an input parameter of type VARCHAR(8). The default is NO.
stop-condition: Specifies the utility execution condition after which
ADMIN_UTL_SCHEDULE will not continue starting new utility executions in parallel, but
will wait until all currently running utilities have completed and will then return to the caller.
Possible values are:
AUTHORIZ or null: No new utility executions will be started after one of the currently
running utilities has encountered a return code from DSNUTILU of 12 or higher.
WARNING: No new utility executions will be started after one of the currently running
utilities has encountered a return code from DSNUTILU of 4 or higher.
ERROR: No new utility executions will be started after one of the currently running
utilities has encountered a return code from DSNUTILU of 8 or higher.
This is an input parameter of type VARCHAR(8). The default is AUTHORIZ.
utility-ID-stem: Specifies the first part of the utility ID of a utility execution in a parallel
thread. The complete utility ID is dynamically created in the form utility-ID-stem followed
by TT followed by NNNNNN, where:
TT - The zero-padded number of the subtask executing the utility
NNNNNN - A consecutive number of utilities executed in a subtask.
For example, utilityidstem02000005 is the fifth utility execution that has been processed by
the second subtask.
This is an input parameter of type VARCHAR(8) and cannot be null.
shutdown-duration: Specifies the number of seconds ADMIN_UTL_SCHEDULE will wait
for a utility execution to complete before a shutdown is initiated. When a shutdown is
initiated, current utility executions can run to completion, and no new utility will be started.
Possible values are:
null - A shutdown will not be performed.
1 to 999999999999999 - A shutdown will be performed after this many seconds.
This is an input parameter of type FLOAT(8). The default is null.
number-of-objects:
input - Specifies the number of utility executions and their sorting objects that were
passed in the SYSIBM.UTILITY_OBJ. Possible values are: 1 to 999999.
output - Specifies the number of objects that were passed in SYSIBM.UTILITY_OBJ
table that are found in the DB2 catalog.
This is an input/output parameter of type INTEGER and cannot be null.
utilities-run: Indicates the number of actual utility executions.
This is an output parameter of type INTEGER.
message: Contains messages describing the error encountered by the stored procedure.
If no error occurred, then no message is returned.
The first messages in this area are generated by the stored procedure. Messages that are
generated by DB2 might follow the first messages.
This is an output parameter of type VARCHAR(1331).
The stored procedure reads objects for utility execution from SYSIBM.UTILITY_OBJ.
Table 24-33 shows the format of the created global temporary table SYSIBM.UTILITY_OBJ.
OBJECTID INTEGER A unique positive identifier for the object the utility
execution is associated with. When you insert multiple
rows, increment OBJECTID by 1 for every insert, starting
at 0.
562 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Column name Data type Contents
PART SMALLINT Partition number of the object for which the utility will be
invoked. Null or 0 if the object is not partitioned.
ADMIN_UTL_SCHEDULE output
This stored procedure returns the following output parameters:
number-of-objects
utilities-run
highest-return-code
parallel-tasks
return-code
message
In addition to the preceding output, the stored procedure returns two result sets.
The first result set is returned in the created global temporary table
SYSIBM.UTILITY_SYSPRINT and contains the output from the individual utility executions.
Table 24-35 shows the format of the created global temporary table
SYSIBM.UTILITY_SYSPRINT.
OBJECTID INTEGER A unique positive identifier for the object the utility
execution is associated with.
The second result set is returned in the created global temporary table
SYSIBM.UTILITY_RETCODE and contains the return code for each of the individual
DSNUTILU executions. Table 24-36 shows the format of the output created global temporary
table SYSIBM.UTILITY_RETCODE.
564 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Table 24-36 Result set row format for SYSIBM.UTILITY_RETCODE
Column name Data type Contents
OBJECTID INTEGER A unique positive identifier for the object the utility
execution is associated with.
RETCODE INTEGER Return code from DSNUTILU for this utility execution.
the corresponding utility execution will be deferred and utility execution on these objects will
be exclusive. That is, ADMIN_UTL_SCHEDULE waits until all parallel tasks have completed
utility execution, and then these exclusive objects will be executed sequentially.
Intra-utility parallelism
Whenever possible, intra-utility parallelism should be used (even through
ADMIN_UTL_SCHEDULE) for the utilities that support it, such as COPY, to achieve optimal
results.
Hence, the optimizer relies on current catalog statistics gathered by the RUNSTATS utility. If
the catalog information is not current, or has only partially been gathered, optimization may
not be always optimal.
With parallel execution there may be more scans and more contention so that the overall
performance gains are less than expected. However, if the objects are unrelated, parallel
utility execution when used with client programs will significantly shorten total execution time,
also because of a number of remote stored procedure invocations, it is reduced to 1, and no
redundant utility execution data is transferred between the client and the server.
Every started subtask requires a minimum of two DB2 threads, more if the utility supports
intra-utility parallelism. The maximum number of allied threads that can be allocated
concurrently at a subsystem is determined by the CTHREAD parameter. You may consider
increasing CTHREAD to run ADMIN_UTL_SCHEDULE with higher parallelism.
SYSPROC.ADMIN_UTL_SORT
The SYSPROC.ADMIN_UTL_SORT stored procedure sorts objects for parallel utility
execution using JCL or the ADMIN_UTL_SCHEDULE stored procedure.
Load module name: DSNADMUS
Package name: DSNADMUS
C ALL S Y S P R O C . A D M IN _ U T L _ S O R T (
m a x _ p a ra lle l, m a x -p e r-jo b ,
|- N U L L - |
o p tim iz e - w o rk lo a d , b a tc h - e x e c u tio n ,
|- N U L L - | |- N U L L - |
m a x -o b je c ts , m a x -s e q u e n c e s ,
r e t u r n -c o d e , m essage )
566 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
1 to 255 - Steps per job for batch execution
null - Online execution.
This is an input parameter of the type SMALLINT. This parameter cannot be null if
batch-execution is YES.
optimize-workload: Specifies whether the parallel units should be sorted to achieve
shortest overall execution time. Possible values are:
NO or null - The workload is not to be sorted.
YES - The workload is to be sorted.
This is an input parameter of type VARCHAR(8). The default value is NO.
batch-execution: Indicates whether the objects should be sorted for online or batch (JCL)
execution.
NO or null - The workload is for online execution.
YES - The workload is for batch execution.
This is an input parameter of type VARCHAR(8). The default value is NO.
number-of-objects:
input - Specifies the number of objects that were passed in
SYSIBM.UTILITY_SORT_OBJ. Possible values are: 1 to 999999.
output - Specifies the number of objects that were passed in
SYSIBM.UTILITY_SORT_OBJ table that are found in the DB2 catalog.
This is an input/output parameter of type INTEGER and cannot be null.
parallel-units: Indicates the number of recommended parallel units.
This is an output parameter of type SMALLINT.
max-objects: Indicates the maximum number of objects in any parallel unit.
This is an output parameter of type INTEGER.
max-sequences: Indicates the number of jobs in any parallel unit.
This is an output parameter of type INTEGER.
return-code: Provides the return code from the stored procedure. Possible values are:
0 - Sort ran successfully.
4 - The statistics for one or more sorting objects have not been gathered in the
catalog or the object no longer exists.
12 - An ADMIN_UTL_SORT error occurred. The message parameter will contain the
details.
This is an output parameter of type INTEGER.
message: Contains messages describing the error encountered by the stored procedure.
If no error occurred, then no message is returned.
The first messages in this area are generated by the stored procedure. Messages that are
generated by DB2 might follow the first messages.
This is an output parameter of type VARCHAR(1331).
OBJECTID INTEGER A unique positive identifier for the object the utility
execution is associated with.
When you insert multiple rows, increment OBJECTID by
1 for every insert, starting at 0.
PART SMALLINT Partition number of the object for which the utility will be
invoked. Null or 0 if the object is not partitioned.
568 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
ADMIN_UTL_SORT output
This stored procedure returns the following output parameters:
number-of-objects
parallel-units
max-objects
max-sequences
return-code
message
In addition to the preceding output, the stored procedure returns one result set that contains
the objects sorted into parallel execution units.
Table 24-38 shows the format of the result set returned in the created global temporary table
SYSIBM.UTILITY_SORT_OUT.
To work with the scheduler, it is crucial to understand the life cycle of a scheduled task. We
therefore recommend to read “24.3.1, “A brief functional overview” on page 569” and “24.3.2,
“Interacting with the scheduler” on page 570”. 24.3.3, “Scheduling stored procedures” on
page 575” has the layout of a checklist, that is, when scheduling a task you should figure out
the proper parameter settings by only reading the paragraphs that really apply to your specific
scheduling scenario.
Before working with scheduler it is crucial to understand the lifecycle of a scheduled task as
this implies to differentiate between scheduling a task, executing a task and controlling the
task status. The following section provides a chronological rough overview of such a
scheduled task lifecycle.
The parameters are verified and if they are found to be correct, the task is added to the
scheduler’s task lists, and the next execution of the task is scheduled. If no task name has
been specified when calling the procedure, a system-generated task name is returned in the
task_name output parameter. The return code and message output parameters provide
information about possible scheduling errors.
Figure 24-22 shows a high-level overview of the components involved when a task is added
or removed. The left frame stating “V91AMSTR / V91ADBM1” depicts the DB2 address
spaces that implement the scheduler SQL interface. The right frame labeled
“V91AADMT“illustrates the actual task scheduler, which runs in its own address space. A
user or an application program calls one of the DB2-supplied scheduling stored procedures:
SYSPROC.ADMIN_TASK_ADD or SYSPROC.ADMIN_TASK_REMOVE. More information
about the removal of tasks can be found in “Removing a scheduled task” on page 575”.
The procedure passes the provided scheduling parameters on to the scheduler. If the
scheduler finds the parameters to be correct, it determines the next point in time when the
scheduled task has to be executed. The scheduler then also materializes the task into two
task lists, which are essentially the DB2 table SYSIBM.ADMIN_TASKS as well as a
redundant VSAM data set.
570 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
V91AMSTR/V9ADBM1 V91AADMT
add (task,...)
Stored procedures
remove(task)
SQL CALL ADMIN_TASK_SCHEDULE
ADMIN_TASK_REMOVE
Scheduler
DB2 tasklist
(SYSIBM.ADMIN_TASKS)
write / remove task
Task
VSAM
tasklist
Task
The following SQL statement lists all task names that have been created under the user ID
PAOLOR3 and sorts them according to their LAST_MODIFIED timestamp.
SELECT TASK_NAME, BEGIN_TIMESTAMP
FROM TABLE(DSNADM.ADMIN_TASK_LIST()) AS TASKLIST
WHERE CREATOR = 'PAOLOR3'
ORDER BY LAST_MODIFIED;
Example 24-13 shows the output when executing the query in a dynamic SQL processing like
SPUFI. Because of the LAST_MODIFIED predicate, the tasks are displayed in the same
order in which they have been added to the task list.
The task list contains three tasks, where the task TASK_ID_0003 is a system-generated task
name. This generic task name is always created by the system whenever there is no task
name specified in the scheduling parameters. The four-digit number always refers to task
number nnnn in the task list and makes this name unique.
For more detailed information about the columns returned, refer to DB2 Version 9.1 for z/OS
SQL Reference, SC18-9854.
Figure 24-23 illustrates the major components involved when a request to the table functions
ADMIN_TASK_LIST or ADMIN_TASK_STATUS is made. The two major frames in this picture
are the DB2 address spaces (V91AMSTR/V91ADBM1) as well as the scheduler address
space (V91AADMT). When an SQL statement queries for example ADMIN_TASK_LIST, the
scheduler is notified to ensure that both task lists (DB2, VSAM) are consistent. This is
triggered by the illustrated synch() call. After that, the table function accesses the task list
table SYSIBM.ADMIN_TASKS to retrieve and prepare the requested information.
ADMIN_TASK_STATUS is explained in the section “Listing the execution status of the
scheduled tasks” on page 574”.
572 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
V91AMSTR/V9ADBM1 V91AADMT
FROM ADMIN_TASK_STATUS()
Scheduler
DB2 tasklist
(SYSIBM.ADMIN_TASKS)
SQL Check for consistency
Task
VSAM
tasklist
Task
For a complete description of the returned table, refer to DB2 Version 9.1 for z/OS SQL
Reference, SC18-9854.
Figure 24-24 on page 574 provides an architectural overview of the components involved
when the scheduler wakes up to execute a scheduled call to the DB2-supplied stored
procedure WLM_REFRESH. As indicated with the read task box, the scheduler first reads the
task which is to be executed from the task lists. It then uses a TCB to first switch the security
context and then execute the CALL to the stored procedure on its attached distinct DB2
subsystem. When the CALL returns, the scheduler gathers possible return codes, messages,
or SQLCODES, and populates the execution status columns in the two task lists, which is
indicated with the write execution status box.
SQL Scheduler
Stored procedures
WLM_REFRESH TCB
VSAM
tasklist
Task
Example 24-14 shows the respective partial SPUFI output. Note, that the STATUS columns
for task TASK_ID_0003 are not initialized, since the stored procedures have not been
executed yet. The task execution for REORG_JOB has already completed, and the
RUNSTATS_JOB is currently in its first execution.
574 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
It is also possible to combine the ADMIN_TASK_LIST and ADMIN_TASK_STATUS output to
realize more complex use cases. Example 24-15 shows that the query returns all tasks that
are still active, that is, that will be executed in the future:
The query joins the two table functions on the TASK_NAME column. A task is then
considered to be still valid, in case the END_TIMESTAMP column value is not expired, and
basically the MAX_INVOCATIONS value is not yet reached.
For a high-level overview of the component involved when the task status is queried, refer to
Figure 24-23 on page 573.
For a complete description of the returned table, refer to DB2 Version 9.1 for z/OS SQL
Reference, SC18-9854.
Note: The scheduler does not perform any housekeeping of tasks that are no longer valid.
That means that the user should always remove tasks that are not supposed to be
executed by the scheduler anymore.
For example, a program could call the table functions ADMIN_TASK_LIST / STATUS to
determine the tasks that are expired, and invoke the procedure ADMIN_TASK_REMOVE
on the returned TASK_NAME column values. For a sample program that illustrates such
housekeeping, refer to A.9.5, “Housekeeping with the scheduler” on page 866.
576 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
For a Java sample that implements static input parameters, refer to A.9.1, “Use case -
1” on page 858.
– The input parameters are dynamic
Input parameters that are not known at scheduling time of a stored procedure or that
might change in between two successive scheduled invocations of a stored procedure
are considered to be dynamic. Here, the scheduling parameter PROCEDURE_INPUT
contains a SQL SELECT statement that queries a table where the latest stored
procedure parameters have been inserted by the application or the user. The SQL
statement in PROCEDURE_INPUT is static, but the content of the table can be
changed during the stored procedures lifetime in the scheduler. Once more the
SELECT statement has to quality one row of data, with compatible column data types
for every input parameter. Dynamic and static parameters (literals) can both appear in
the SELECT statement at the same time.
For a Java sample that implements dynamic input parameters, refer to A.9.3, “Use
case - 3” on page 863.
– The parameters of a scheduled stored procedure have Unicode values
The scheduler is able to retrieve and pass Unicode parameters when invoking a
scheduled stored procedure. In order to invoke a stored procedure with Unicode
parameters, a user or an application has to make use of the dynamic parameter
approach described above. The table containing the input parameters has to be
defined with a Unicode CCSID, such that the returned column values are in Unicode
when they are passed on to the scheduled stored procedure. The
PROCEDURE_INPUT scheduling parameter contains an EBCDIC SQL statement.
Thus, the targeted table name and its associated column names must not contain any
characters that cannot be expressed in EBCDIC. Otherwise, there is a chance that
characters get broken. The scheduling parameters PROCEDURE_NAME and
PROCEDURE_SCHEMA are defined in EBCDIC as well and thus behave similarly.
The scheduled stored procedure also returns output parameters
Every output parameter has to be qualified in the PROCEDURE_INPUT scheduling
parameter. That means the SELECT statement has to contain literals of compatible type
for every output parameter of the scheduled stored procedure. Here as well it has to be
assured that the literal positions in the SELECT statement fits the position of the output
parameters in the scheduled stored procedure.
When scheduling the DB2-supplied stored procedure WLM_REFRESH, which has two
input parameters and two output parameters of type VARCHAR and INTEGER, one could
use the following SQL statement in the PROCEDURE_INPUT scheduling parameter:
SELECT ’WLMENV1’, ’V91A’, ’Message’, 0 from SYSIBM.SYSDUMMY1;
Refer to A.9.3, “Use case - 3” on page 863 to see a Java sample that schedules a stored
procedure that contains output parameters.
– How to access the output from the scheduled stored procedure
The scheduler does neither store nor make output parameters accessible to the user or
the calling application. It is the responsibility of the stored procedure developer to
materialize the needed information in a non-transient repository, for example a DB2
table or a data set. This also holds for result sets or temporary tables. For provided
stored procedures that cannot be changed, a user has to wrap those into another
stored procedure which performs the result set materialization. It is the wrapping
stored procedure that has to be scheduled with the scheduler. In case of a DB2 error,
the following debug information is accessible to the user:
SQLCOD
SQLSTATE
578 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Once more, multiple instances of the same task cannot run in parallel, thus the next
execution would be skipped if the previous one is still running.
How to specify one or several non regular points in time
The cron format consists of five time and date fields each separated by at least one
blank. For each field, comma-separated lists and ranges indicated by a hyphen are
allowed to implement recurring task execution characteristics. The fields supported
are the following:
minutes: 0 - 59
hour: 0 - 23
day of month: 1 - 31
month: 1 - 12
day of week: 0 – 7 here, 0 or 7 refer to a Sunday
The following is an example of a cron string which schedules a task to be executed
at 3:12 p.m. on December 31:
POINT_IN_TIME = ’12 15 31 12 *’
A stored procedure that runs repeatedly at 6 a.m. on the 11th and 12th of every
month and also every Saturday and Sunday would be scheduled like this:
POINT_IN_TIME = ’0 6 11,12 * 6-7’
For more information about the UNIX cron format support implemented in the
scheduler, refer to Chapter 14 of DB2 Version 9.1 for z/OS Administration Guide,
SC18-9840.
A.9.3, “Use case - 3” on page 863 shows a Java sample that makes use of the
POINT_IN_TIME scheduling parameter.
– The stored procedure execution is triggered
To define dependencies between sequences of stored procedures, the triggering
capabilities of the scheduler can be employed. Stored procedure triggering is
implemented with the scheduling parameters
TRIGGER_TASK_NAME
TRIGGER_TASK_COND
TRIGGER_TASK_CODE
When these are employed, the following time-based scheduling parameters have to be
set to NULL:
POINT_IN_TIME
INTERVAL
A triggered stored procedure is only executed when the triggering task completes its
execution, or a triggering event occurs. Triggered stored procedures are also constraint
to a single execution instance at any point in time. This means that a triggering task
running every 3 minutes triggers a stored procedure that runs for 5 minutes. The
second triggering event after 6 minutes will be skipped because the first triggered
procedure execution after 3 minutes is still running. The stored procedure will
successfully be triggered for a second time after 9 minutes.
• The stored procedure execution is triggered by a predefined DB2 event
There are two predefined events for the scheduler: DB2START and DB2STOP. A
stored procedure execution can only be triggered when DB2 starts. Reacting on a
DB2-stop event, does not make sense for a stored procedure execution. To
schedule such DB2-start triggered stored procedure executions, use the following
scheduling parameter + value combination:
TRIGGER_TASK_NAME = “DB2START”
580 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
The end of the validity time window is determined by the value of the
END_TIMESTAMP parameter. A stored procedure will not be executed after the
timestamp defined in this scheduling parameter.
For a Java sample that schedules a stored procedure that is not executed after a
certain point in time, refer to A.9.2, “Use case - 2” on page 861.
– The task is only valid within a certain time window
Employ the following two time window scheduling parameters at the same time, to
define the validity window of a task:
BEGIN_TIMESTAMP
END_TIMESTAMP
Consider, if BEGIN_TIMESTAMP and END_TIMESTAMP are not NULL, then both
timestamps have to be in the future and END_TIMESTAMP has to be later than
BEGIN_TIMESTAMP. See A.9.3, “Use case - 3” on page 863.
– The task should be executed not more than a certain number of times
To limit the number of executions of, for example, a recurring or triggered stored
procedure, the MAX_INVOCATIONS scheduling parameter can be used. It defines the
maximum number of attempts the scheduler can execute a stored procedure. If both
MAX_INVOCATIONS and END_TIMESTAMP are specified and the value in
MAX_INVOCATIONS reached the defined limit, but END_TIMESTAMP is not yet
exceeded, the task is no longer executed although it is still within the validity time
window. If the value in END_TIMSTAMP is exceeded, but the number of
MAX_INVOCATION is not yet reached, the stored procedure validity is nevertheless
expired and it is no longer executed as well.
A.9.1, “Use case - 1” on page 858 shows a Java sample that implements the
scheduling of a stored procedure with MAX_INVOCATIONS = 1.
– The task can be executed as many times as scheduled
Setting the MAX_INVOCATIONS scheduling parameter to NULL implies that the
number of invocations of a stored procedure is not constraint. Within the provided
validity time interval, a stored procedure can be executed without limitations to the
number of times it is invoked.
After the execution completes, the scheduler logs out and returns to its default security
context.
The stored procedure can be executed by any user
There is no special authorization required to execute the task. When scheduling the stored
procedure, the USERID and PASSWORD parameters can be set to NULL. In this case the
stored procedure is executed under the default execution user configured for the
scheduler.
The stored procedure has to be executed under a distinct user ID
To switch to a certain security context when executing a stored procedure, provide the
required credentials in the USERID and PASSWORD scheduling parameters. The
provided password is not stored. The credentials are only validated once, when the task is
582 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
user ID the stored procedure status has been updated for the last time. Additionally the
NUM_INVOCATIONS column provides information about the number of times this stored
procedure was already executed, including the current execution. This counter is independent
of a successful or unsuccessful execution of a stored procedure. The remainder of the
execution status can be interpreted according to the different values of the STATUS column:
NOTRUN: The scheduler was not able to start executing the stored procedure. The
START_TIMESTAMP and the END_TIMESTAMP values are the same, and a MSG value
states why the stored procedure execution could not be started. The DB2 execution status
columns (SQLCODE, SQLSTATE, SQLERRMC, and SQLERRP) may contain additional
debug information in case the reason not to execute the task is related to DB2 (for
example DB2 connection could not be established).
RUNNING: The scheduler started executing the stored procedure, which has not
completed yet. All other execution status columns are NULL.
COMPLETED: The last task execution completed. The START_TIMESTAMP column
indicates when the task execution started, whereas the END_TIMESTAMP column
indicates when the execution completed and the MSG column potentially contains an error
or an informational message. The DB2 execution status columns (SQLCODE, SQLSTATE,
SQLERRMC, and SQLERRP) might be filled with additional DB2 debugging information.
UNKNOWN: The task execution status is unknown. This occurs when the scheduler is
stopped while a stored procedure is executed.
For more detailed information about the columns returned, refer to Chapter 3 of DB2 Version
9.1 for z/OS SQL Reference, SC18-9854.
task-name, description,
|- NULL -| |- NULL -|
return-code, message )
584 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
When trigger-task-name completes at or after begin-timestamp - The task
execution begins the next time that trigger-task-name completes at or after
begin-timestamp.
Null value for begin-timestamp
Immediately - The task execution begins immediately if point-in-time and
trigger-task-name are NULL.
Next point in time defined -The task execution begins at the next point in time defined
if point-in-time is non-null.
When trigger-task-name completes -The task execution begins the next time that
trigger-task-name completes.
The value of this parameter cannot be in the past, and it cannot be later than
end-timestamp.
For further details, refer to ““When does the task have to be executed?” on page 578”.
This is an input parameter of type TIMESTAMP.
end-timestamp: Specifies when a task can last begin execution. If this parameter is set to
NULL, then the task can continue to execute as scheduled indefinitely.
The value of this parameter cannot be in the past, and it cannot be earlier than
begin-timestamp.
This is an input parameter of type TIMESTAMP.
max-invocations: Specifies the maximum number of executions allowed for a task. This
value applies to all schedules: triggered by events, recurring by time interval, and recurring
by points in time. If this parameter is set to NULL, then there is no limit to the number of
times this task can execute.
For tasks that execute only one time, max-invocations must be set to 1 and interval,
point-in-time and trigger-task-name must be NULL.
If both end-timestamp and max-invocations are specified, the first limit reached takes
precedence. That is, if end-timestamp is reached, even though the number of task
executions so far has not reached max-invocations, the task will not be executed again. If
max-invocations have occurred, the task will not be executed again even if end-timestamp
is not reached.
This is an input parameter of type INTEGER.
interval: Defines a time duration between two executions of a repetitive regular task. The
first execution occurs at begin_timestamp. If this parameter is set to NULL, the task is not
regularly executed. If this parameter contains a non-null value, the parameters
point-in-time and trigger-task-name must be set to NULL.
This is an input parameter of type INTEGER.
point-in-time: Defines one or more points in time when a task is executed. If this
parameter is set to NULL, the task is not scheduled at fixed points in time. If this parameter
contains a non-NULL value, the parameters interval and trigger-task-name have to be set
to NULL.
The point-in-time string has the UNIX cron format. The format contains the following
pieces of information separated by blanks: given hour, given minute or minutes, given hour
or hours, given day or days of the month, given month or months of the year, and given
day or days of the week. For each part, you can specify one or several values, ranges, and
so forth. For more detailed information, refer to “How to specify one or several non regular
points in time” on page 579.
This is an input parameter of type VARCHAR(400).
586 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
members to execute the task, so that the task can only be executed as long as the
scheduler of DB2-SSID is running.
For a task being triggered by a DB2 start or DB2 stop event in trigger-task-name,
specifying a value in DB2-SSID will let the task be executed only when the named
subsystem is starting and stopping. If no value is given, each member that starts or stops
will trigger a local execution of the task, provided that the executions are serialized.
If this parameter is set to NULL, any of the scheduler will be allowed to execute the task.
This is an input parameter of type VARCHAR(4).
procedure-schema: Specifies the schema of the DB2 stored procedure this task will
execute. If this parameter is set to NULL, DB2 uses a default schema. This parameter
must be set to NULL if procedure-name is set to NULL.
This is an input parameter of type VARCHAR(128).
procedure-name: Specifies the name of the DB2 stored procedure this task will execute.
If this parameter is set to NULL, no stored procedure will be called. In this case, a JCL job
must be specified.
This is an input parameter of type VARCHAR(128).
procedure-input: Specifies the input parameters of the DB2 stored procedure this task
will execute. This parameter must contain a DB2 SELECT statement that returns one row
of data. The returned value will be passed as parameter to the stored procedure.
If this parameter is set to NULL, no parameter are passed to the stored procedure. This
parameter has to be set to NULL when procedure-name is set to NULL.
This is an input parameter of type VARCHAR(4096).
JCL-library: Specifies the name of the data set where the JCL job to be executed is
saved.
If this parameter is set to NULL, no JCL job will be executed. In this case, a stored
procedure must be specified.
This is an input parameter of type VARCHAR(44).
JCL-member: Specifies the name of the library member where JCL job to be executed is
saved.
If this parameter is set to NULL, the data set specified in JCL-library must be sequential
and contain the JCL job to be executed. This parameter must be set to NULL if JCL-library
is set to NULL.
This is an input parameter of type VARCHAR(8).
job-wait: Specifies whether scheduler executes the job synchronously or asynchronously.
This parameter can only be set to NULL if JCL-library is set to NULL. Otherwise, it must be
one of the possible values:
NO - Asynchronous execution (scheduler does not wait for job to finish execution).
YES - Synchronous execution (scheduler waits for job to finish execution).
PURGE - Synchronous execution after which the job status in z/OS is purged
This is an input parameter of type VARCHAR(8).
task-name: Specifies a unique name assigned to the task.
A unique task name is returned when the task is created with a NULL task-name value.
This name is of the format TASK_ID_xxxx, where xxxx is 0001 for the first task named,
0002 for the second task, and so forth.
ADMIN_TASK_ADD output
This stored procedure returns the following output parameters:
task-name
return-code
message
SYSPROC.ADMIN_TASK_REMOVE
The SYSPROC.ADMIN_TASK_REMOVE stored procedure removes a task from the task list
of the scheduler.
If the task is currently running, it continues to execute until completion, and the task is not
removed from the scheduler task list. If other tasks depend on the execution of the task to be
removed, this task is not removed from the administrative scheduler task list.
Users with SYSOPR, SYSCTRL, or SYSADM authority can remove any task. Other users
who have EXECUTE authority on this stored procedure can remove tasks that they added.
Attempting to remove a task that was added by a different user returns an error in the output.
Load module name: DSNADMTR
Package name: DSNADMTR or DSNADMTU
CALL SYSPROC.ADMIN_TASK_REMOVE (
588 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
ADMIN_TASK_REMOVE option descriptions
task-name: Specifies the task name of the task to be removed from the scheduler task
list. The task name cannot be NULL.
This is an input parameter of type VARCHAR(128).
return-code: Provides the return code from the stored procedure. Possible values are:
0 - The call completed successfully and the task was successfully removed.
12 - The call did not complete successfully and the task has not been removed. The
message output parameter contains messages describing the error.
This is an output parameter of type INTEGER.
message: Contains messages describing the error encountered by the stored procedure.
The first messages in this area, if any, are generated by the stored procedure. Messages
that are generated by DB2 might follow the first messages.
This is an output parameter of type VARCHAR(1331).
ADMIN_TASK_REMOVE output
This stored procedure returns the following output parameters:
return-code
message
The common SQL API described here attempts to solve these problems for the common
application development and administration tooling solution space, benefiting tools such as
the Data Studio Administration Console (name of the tool is not finalized yet, still subject to
rebranding) and future tooling efforts across all data servers, such as performance tools.
590 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
– DT, CONDBAT, MDBAT, ADBAT, QUEDBAT, INADBAT, CONQUED, DSCDBAT,
INACONN
Connected DB2 subsystem
– Subsystem ID of the DB2 that currently executes GET_CONFIG.
Resource limit facility information
– Table name of the active resource limit specification
Active log data set information
– Active log data set names, volume names
Timestamp of last DB2 restart
All three common SQL API stored procedures feature the same signature. This signature
stability and commonality are achieved by using simple XML documents as input and output
parameters. The data server information that is collected by the respective stored procedure
is thus wrapped into an XML document and returned as a BLOB to the caller. All XML
documents, either input or output, are described by a common XML Document Type
Definition (DTD). Version, platform and technology differences are expressed through
different key or value pairs in these so-called hierarchical XML property lists.
CALL SYSPROC.GET_SYSTEM_INFO (
|- SYSPROC.GET_CONFIG -|
|- SYSPROC.GET_MESSAGE -|
XML_OUTPUT, XML_MESSAGE )
MINOR_VERSION Similarly as with major version, the stored procedure will return the
INTEGER, output XML documents in the minor version indicated in this
INOUT parameter. If the provided version is not supported an error is
returned.
The lowest minor version supported starts at 0. The highest
supported minor version for all the XML documents is always
returned in the output parameter.
REQUESTED_LOCALE By using this parameter the caller can request localized content to be
VARCHAR(33), returned in the XML_OUTPUT and XML_MESSAGE parameters. If
CCSID EBCDIC, the language indicated is not supported on the server-side, the
IN output documents are returned in a default language.
XML_FILTER The stored procedure will always return the complete XML output
BLOB (4K), document unless an XML_FILTER is provided by the caller. It is
IN specified as a valid but restricted XPath query string in UTF-8, that
qualifies and returns a single element in the XML tree.
XML_OUTPUT If the call to the stored procedure could successfully be executed, this
BLOB(2G) AS LOCATOR, parameter returns the complete XML output document for the
IN respective stored procedure. Alternatively if an XML filter has been
applied only the single qualifying string is returned.
The content of this parameter is encoded in UTF-8.
XML_MESSAGE If the call to the stored procedure results in an SQL warning being
BLOB(64K), raised, this parameter may contain a complete XML message
OUT document. This provides detailed information on the warning
condition encountered as well as additional debug information to
resolve the problem.
The content of this parameter is encoded in UTF-8.
592 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
http://developer.apple.com/documentation/CoreFoundation/Conceptual/CFPropertyLists/CFProper
tyLists.html
A single piece of information is described by entries in the XML document, which are usually
grouped using nested dictionaries (dict). These entries are basically a set of key or value
pairs. A value associated with a key is further structured to include the actual Value’ a
(translated) Display Name, and a (translated) Hint key. Optionally, a (translated) Display Unit
key may be provided to correctly interpret the value. A sample entry that contains information
about the Real Storage Size is shown in Example 24-16.
The entry Display Unit will be omitted if no unit of measure is applicable to the value being
described. The details and content for the specific entries depend on each stored procedure.
The type for the value may be <integer>, <string>, <date>, <real>, or an <array>. If it is an
<array>, all elements in the array must be <integer>, <string>, <date>, or <real>. For a
Complete-Mode document the keys <true> and <false> are supported.
Whereas XML_INPUT and XML_OUTPUT documents differ for each of the Common SQL
API stored procedures, the XML_MESSAGE structure is shared among them all. In the
following section we provide an overview of the basic structure of the three XML documents.
XML_INPUT
The XML_INPUT document is used to provide special runtime information to a stored
procedure, which basically influences the amount and the type of the returned XML output
document content. The major structure of the document consists of a set of key or value pairs
that are common to all stored procedures that support input documents, and two sections
containing Required Parameters and Optional Parameters that are stored procedure specific.
The general structure of an XML input document is listed in Example 24-17. Note that the key
or value pairs in italic are used by all stored procedures, whereas the pairs in bold are
procedure-specific.
The value of the Document Type Name key determines whether the XML document is an input
or an output document, as well as the stored procedure this XML document is associated
with. In Example 24-17 the string value Data Server Message Input indicates an input
document for the GET_MESSAGE stored procedure.
Note, the Complete entry is optional and can be omitted if the value is false. In this case the
only required entries are:
Document Type Name, Required Parameters, Optional Parameters
Non-Complete Mode implies a regular call to the stored procedure that returns an XML output
document. For example, calling GET_MESSAGE with a non-Complete Mode input document
will return an output document containing the respective short message text.
If the value for the Complete key is true, for example <key>Complete</key><true/>, the
called stored procedure will operate in the Complete Mode.
This means that a caller wants the stored procedure to only return a template XML input
document that looks similar to the one in Example 24-17. This template XML input document
is returned in the XML_OUTPUT parameter and can then be populated with the Required
Parameters and Optional Parameters. In a second successive call to the stored procedure
this augmented, now non-Complete Mode input document can be used to retrieve the desired
information from the data server contained in the XML output document.
Example 24-18 is a minimal XML input document in Complete Mode. Note that there is no
stored procedure-specific information in there, so that it can be used for any Common SQL
API stored procedure that supports an input document. Should the XML input document for
Complete Mode contain XML elements in addition to the ones shown, those other entries are
ignored and will not be retained in the document returned.
594 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
<dict>
<key>Complete</key><true/>
</dict>
</plist>
As mentioned, when calling a procedure in Complete Mode the returned XML document is a
full XML input document in non-Complete Mode, including a Document Type and sections for
all possible required and optional parameters. There are additional Hint sections included,
that might provide additional information on how to interpret distinct sections in the XML
document.
Figure 24-28 depicts the typical work flow when employing the Common SQL API stored
procedures that support an input document. When the Complete Mode approach is
employed, two calls to the stored procedure are required. The interaction would start with the
upper CALL statement in the figure. Note that the XML_OUTPUT content is reused in the
second CALL as XML_INTPUT content.
Alternatively, if a valid non-Complete Mode XML input document is already available, one
CALL is sufficient. A user or application program would start with the lower CALL statement
illustrated in Figure 24-28.
XML_INPUT XML_OUTPUT
Template
XML input
SQL CALL document Common SQL API
XML input document
stored procedures ‘non-Complete
‘Complete Mode‘
Mode‘
XML_INPUT XML_OUTPUT
XML input
SQL CALL document
Common SQL API XML output
stored procedures document
‘non-Complete
Mode‘
XML_OUTPUT
If the Common SQL API stored procedure has been invoked in Complete Mode, the
XML_OUTPUT parameter returns a template XML input document. This document can be
used in the XML_INPUT parameter for the same stored procedure in a second call in
non-Complete Mode as illustrated in Figure 24-28. In this case the XML_OUTPUT parameter
returns the stored procedure-dependent data server information, wrapped into an XML
document. This output document contains a header section that implements the same keys
for all Common SQL API stored procedures. These common keys are highlighted in italic in
Example 24-19.
Once more the Document Type Name key refers to the stored procedure that is associated with
the output document as well as to the type of the document. The above example is thus
extracted from an XML output document obtained through a GET_MESSAGE stored
procedure call. The other key or value pairs in the common header of the output document
describe version and the environment information for the stored procedure call. The stored
procedure-specific output information is placed underneath the common header section,
indicated in the example by the placeholder:
Document type specific data here
XML_MESSAGE
When a stored procedure encounters an internal processing error, or an invalid input
parameter, a warning with the respective SQLCODE is created. In this case, all output
parameters are set to NULL, except for the MAJOR_VERSION, MINIOR_VERSION, and the
XML_MESSAGE output parameter. XML_MESSAGE will return an XML message document
containing more detailed error and debug information for the situation.
The XML message document structure is common across all Common SQL API stored
procedures and features always the same value for the Document Type Name key:
Data Server Message. Example 24-20 illustrates an XML message document.
596 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
<key>Display Name</key><string>Short Message Text</string>
<key>Value</key>
<string>...additional description of warning...</string>
<key>Hint</key><string></string>
</dict>
</dict>
</plist>
Here the string:“...additional description of warning...” will contain a message ID and the
corresponding short message text in case of a real error.
For example, when GET_MESSAGE is called with improperly initialized parameters, the
following XML message document is returned with the entry Short Message Text that
contains debug information, as shown in Example 24-21.
Error handling
The three common SQL API stored procedures implement a common set of SQLCODEs and
SQLSTATEs that either indicate an error or a warning. The general idea of the stored
procedures is to refrain from returning error SQLCODEs, but rather return warnings for most
problem scenarios, if possible. The advantage of returning a positive SQLCODE (warning) is
basically that the output parameters are still accessible. This allows the utilization of the XML
message output document for efficient problem determination and resolution. For some
warning scenarios, the stored procedures are even able to construct and retrieve a complete
XLM output document. However, as a general rule the XML_OUTPUT and XML_MESSAGE
parameters are mutually exclusive, that is, either the XML output or the XML message
document is returned in a warning scenario. The following table lists the common SQLCODE
and SQLSTATES that are implemented by all three stored procedures, as well as which
document is returned. The error SQLCODEs are listed in Table 24-40.
Versioning
The signature stability for all three Common SQL API stored procedures is a result of the
flexibility that is provided by employing XML documents as parameters. All XML documents
are versioned with the help of a major and a minor version, starting with an initial version of
1.0. With the introduction of a new version, a new structure or new key or value pairs could be
supported. For a single call to any stored procedure the major and minor version of all
documents involved are constant. That means it is ensured that the XML input document
always has the same version as the generated XML output or message document.
A caller can request a certain major and minor version for the output documents by setting the
MAJOR_VERSION and MINOR_VERSION parameters of the stored procedure accordingly.
The returned XML output document (either XML_OUTPUT or XML_MESSAGE) contains two
key or value pairs in the common header section indicating the actual major and minor
version. These pairs are shown in Example 24-22.
598 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Example 24-22 Key or value pairs for the version of the XML_OUTPUT or XML_MESSAGE document
<key>Document Type Major Version</key><integer>1</integer>
<key>Document Type Minor Version</key><integer>0</integer>
The XML_INPUT document features optional key or value pairs for Document Type Major
Version and Document Type Minor Version in the common header section, which indicate the
version of the input document. To ensure that the input document is of the same version as
the output document, the Document Type Major Version and Document Type Minor Version
have to match the MAJOR_VERSION and MINOR_VERSION parameters in the signature. If
they are not identical, a +20458 SQLCODE is raised. This avoids scenarios where a higher
major or minor version adds new required parameters to the input document that are not yet
supported in the lower output document version.
Again, if they are present, Document Type Major Version and Document Type Minor Version
must be specified together in the XML input document, that is, both must be specified with a
valid and supported version, or both must not be specified. Otherwise, a +20458 SQLCODE
is raised.
When the call did not result in an error SQLCODE, that is, the specified version is supported,
the highest supported major and minor version is always returned in the MAJOR_VERSION
and MINOR_VERSION output parameters.
Note: To provide further user assistance to determine the latest major and minor versions
supported by the currently installed Common SQL API stored procedures, all input
parameters, especially MAJOR_VERSION and MINOR_VERSION, can be set to NULL.
Such a call completes successfully and returns only the highest supported version
numbers in the associated output parameters. In this case no further processing is done by
the procedure.
Locale handling
The content of the Display Name, Hint, and Display Unit keys is language-sensitive and will
be translated to the language specified in the value for the REQUESTED_LOCALE
parameter. If the language is not supported by the current version of the stored procedure,
then a default locale is employed, which is n_US. Therefore, the caller should always
compare the value of the REQUESTED_LOCALE parameter with the actual locale returned
in the XML output documents. This is indicated by the key or value pair in the common header
section shown in Example 24-23.
Note: Version 1.0 of all Common SQL API stored procedures only supports the locale
en_US.
SYSPROC.GET_MESSAGE
The GET_MESSAGE stored procedure returns the short message text that is associated with
a certain SQLCODE. The SQLCODE and, if available, some message tokens are passed to
the stored procedure while being wrapped into the XML input document. The short message
text is returned in the XML output document.
Any XML input document that is associated with the GET_MESSAGE stored procedure must
contain the key or value pair in its common header section shown in Example 24-25.
Any GET_MESSAGE XML output document contains the key or value pair of Example 24-26.
Since GET_MESSAGE supports an XML input document, it can be called in Complete Mode.
A typical workflow including a call in Complete Mode could be comprised of the following
steps:
Complete Mode - Invoke GET_MESSAGE with an XML input document in Complete Mode.
Set the following parameter values:
MAJOR_VERSION = 1
MINOR_VERSION = 0
REQUESTED_LOCALE = ”en_US”
XML_FILTER = NULL
Example 24-27 shows a Complete Mode XML input document that could be used for the
XML_INPUT parameter.
600 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Valid XML input document - After the invocation in Complete Mode, a template XML input
document is returned via the XML_OUTPUT parameter. This document can now be
augmented with the respective SQLCODE and the message tokens, if applicable. It then can
be used in a second call. Also note that the highest supported major and minor versions are
returned in the output parameters MAJOR_VERSION and MINOR_VERSION. An
augmented XML input document could look like Example 24-28 when used for a second call
to GET_MESSAGE.
Note that the key Complete = false is assumed when it is not provided. As indicated in bold,
the section containing the SQLCODE has been augmented with a -805, the stored procedure
should get the short message text for it. Additionally, some message tokens have been added
to the optional parameter section. Invoking GET_MESSAGE with this XML input document
returns the XML_OUTPUT document shown in Example 24-29.
SYSPROC.GET_SYSTEM_INFO
GET_SYSTEM_INFO collects system-related information and returns it in the XML output
document. The stored procedure can be called with an XML input document that allows to
specify an SMPCSI data set name and a list of SYSMODs whose status will be queried from
the SMPCSI data set in the information gathering process. In order to query the status of a
SYSMOD, it is assumed that the software components are administered using SMP/E, and
furthermore that the SMPCSI data set is up-to-date. The SMPCSI and SYSMOD keys are
contained in the Optional Parameter section, thus GET_SYSTEM_INFO can also be called
without XML input parameter document. Without an XML input document there will be no
SYSMOD status returned in the XML output document.
Any XML input document that is associated with the GET_SYSTEM_INFO stored procedure
contains the key or value pair shown in Example 24-30 in its common header section.
Any GET_SYSTEM_INFO XML output document contains the key or value pair shown in
Example 24-31.
Since an XML input document is supported for GET_SYSTEM_INFO, the stored procedure
can be called in Complete Mode to retrieve a valid XML input document. The Complete Mode
document passed in the XML_INPUT parameter might look like Example 24-32.
602 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
<plist version="1.0">
<dict>
<key>Complete</key><true/>
</dict>
</plist>
Note that the key Complete = false is assumed when it is not provided. To finally obtain the
system information and additional SYSMOD information, set the following parameter values
so as to employ the augmented XML input document:
MAJOR_VERSION = 1
MINOR_VERSION = 0
REQUESTED_LOCALE = “en_US”
XML_FILTER = NULL.
SYSPROC.GET_CONFIG
The GET_CONFIG stored procedure returns data server configuration information in the
XML_OUTPUT parameter. There is no XML input document supported for GET_CONFIG,
thus the stored procedure cannot be called in Complete Mode.
Any XML output document that is associated with the GET_CONFIG stored procedure
contains the key or value pair in its common header section, as shown in Example 24-35.
When calling GET_CONFIG the XML_INPUT, the parameter has to be nullified. Basically
there are three ways to nullify this input parameter: Pass a NULL reference (which implies
setting the indicator host variable to -1 in embedded SQL, or a NULL reference in Java),
blanks only, or an empty string. To obtain the data server configuration output, set
604 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
MAJOR_VERSION = 1
MINOR_VERSION = 0
REQUESTED_LOCALE = “en_US”
XML_INPUT = NULL
XML_FILTER = NULL
Note that the highest supported major and minor versions are additionally returned in the
output parameters MAJOR_VERSION and MINOR_VERSION.
Note: APAR PK64298 (PTFs UK37310 and PK37311 respectively for DB2 Version 8 and
DB2 9 for z/OS) add options for the DB2-supplied stored procedures
SYSPROC.GET_CONFIG, SYSPROC.GET_MESSAGE, and
SYSPROC.GET_SYSTEM_INFO.
XML_FILTER
Especially the procedures GET_SYSTEM_INFO and GET_CONFIG return a vast amount of
information in the XML output parameter document. In some cases it might not be necessary
to get the complete XML output document, but instead only a single value could be required.
Here, the complete XML document can be retrieved and then parsed for this specific value;
however, this approach involves some application programming overhead. Alternatively, the
XML_FILTER parameter can very easily be employed. This input parameter allows to specify
Sample XML_FILTERs
GET_CONFIG - IP Address:
XML_OUTPUT: “::9.30.189.213“
XML_OUTPUT: “EBCDIC“
XML_OUTPUT: “256”
Note: The XPath expression must always be absolute from the root node.
Full XML XPath definition is not supported in the Common SQL API, it only offers limited
capabilities. For example, currently XML_FILTER cannot be used for filtering elements in an
array. For a complete list of all XPath limitations, refer to DB2 Version 9.1 for z/OS
Administration Guide, SC18-9840.
Furthermore, Appendix B contains a very simple Java program that invokes the
GET_CONFIG stored procedure with a valid XPath to only retrieve the value of the IP
Address. Refer to A.10.1, “Simple GET_CONFIG invocation with a valid XPath” on page 883.
606 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
24.5 Using the DB2-supplied stored procedures
In this section, we list the complete applications written in Java that call DB2-supplied stored
procedures. The actual listings are in Appendix A, “Samples for using DB2-supplied stored
procedures” on page 807, and are available for download as described in Appendix B,
“Additional material” on page 887. To compile and run the applications, you have to install the
Java 2 SDK, Standard Edition, Version 1.4.0 or higher. If you develop on Windows, we
recommend setting the PATH variable to include the path to the Java 2 SDK executables
(javac.exe, java.exe, javadoc.exe, etc.) so that you can use them from any directory without
having to type the full path of the command. Read the README file in your Java directory for
detailed instructions on how to set the PATH permanently.
Create a directory where you will be saving your source code files. Open a command prompt
window and change to that directory. Once you have created a file, such as
AdminSystemInformation.java there, compile it with the following command:
javac AdminSystemInformation.java
The compiler stores the byte code program for the class or classes defined in the source file
with the extension .class. To execute the byte code program, enter the following command:
java AdminSystemInformation DBALIAS USERID PASSWORD
Most of the programs require you to enter the database alias, the user ID, and the password
to run the program.
Table 24-42 shows the functions available and where they are listed in Appendix A, “Samples
for using DB2-supplied stored procedures” on page 807.
AdminSystemInformation Display DB2 ADMIN_INFO_SSID, A.1, “Display DB2 system information with
system information ADMIN_INFO_HOST, AdminSystemInformation” on page 808
DSNWZP,
DSNUTILU,
AdminDataSet Manage data sets ADMIN_DS_WRITE, A.5, “Manage data sets with
ADMIN_DS_BROWSE, AdminDataSet” on page 838
ADMIN_DS_RENAME,
ADMIN_DS_SEARCH,
ADMIN_DS_LIST,
ADMIN_DS_DELETE
AdminSchedule1 Multiple Use Cases ADMIN_TASK_ADD, A.9, “Task Scheduler Sample Use cases”
AdminScheduleR and code for ADMIN_TASK_REMOVE on page 858
Trigger: scheduling
USER.TR_WLM_REFR administrative
tasks. Code for
housekeeping of
expired tasks
SPDriver, Invoke Common GET_SYSTEM_INFO, A.10, “Invoking the Common SQL API
SPWrapper, SQL API stored GET_MESSAGE, stored procedures” on page 870
GetConfigDriver procedures, XML GET_CONFIG
handling with
Jakarta Commons
Configuration
24.6 Summary
In this chapter we discussed the stored procedures that are shipped with DB2 and how to use
them in an application program. Whether you code your application program in Java or any
other programming language such as C, the applications will enable you to correctly
implement calling the stored procedure, passing and retrieving parameters and result sets,
and handling error conditions correctly.
608 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
25
Working with LOBs involves defining the LOBs to DB2, moving the LOB data into DB2 tables,
then using SQL operations to manipulate the data. This chapter concentrates on accessing
LOB data through stored procedures. For general information on LOBs, see LOBs with DB2
for z/OS: Stronger and Faster, SG24-7270. For information on defining LOBs to DB2, see
Chapter 5 of DB2 Version 9.1 for z/OS SQL Reference, SC18-9854. For information on how
DB2 utilities manipulate LOB data, see Part 2 of DB2 Version 9.1 for z/OS Utility Guide and
Reference, SC18-9855.
There are four basic steps in defining LOBs and moving data to DB2:
1. Define a DB2 table with a column of the appropriate LOB type and a row identifier
(ROWID) column. Define only one ROWID column even if there are multiple LOB columns
in the table. The LOB column holds information about the LOB not the LOB data itself. The
table that contains the LOB information is called the base table. DB2 uses the ROWID
column to locate your LOB data. You need only one ROWID column in a table that
contains one or more LOB columns. You can define the LOB column and the ROWID
column in a CREATE TABLE or ALTER TABLE statement. if you are adding a LOB column
and a ROWID column to an existing table, you must use two ALTER TABLE statements.
Add the ROWID with the first ALTER TABLE statement and the LOB column with the
second in DB2 V8 if no ROWID column exists. When you define an LOB column (by using
a CREATE TABLE or ALTER TABLE statement), DB2 implicitly creates a ROWID column
and appends it as the last column of the table.
2. Create the table space and table to hold the LOB data. The table space and table are
called LOB table space and auxiliary table. If your base table is non partitioned, you must
create one LOB table space and one auxiliary table for each LOB column. If your base
table is partitioned, for each LOB column you must create one LOB table space and one
auxiliary table for each partition. For example, if your base table has three partitions, you
must create three LOB table spaces and three auxiliary tables for each LOB column.
Create these objects using the CREATE LOB TABLESPACE and CREATE AUXILIARY
TABLE statements.
3. Create an index on the auxiliary table.
4. Put the LOB data into DB2. If the total length of an LOB column and the base table row is
less than 32 KB, you can use the LOAD utility to put the data in DB2. Otherwise, you must
use INSERT or UPDATE statements. Even though the data is stored in the auxiliary table,
the LOAD utility statement or INSERT statement specifies the base table. Using INSERT
can be complicated because your application will need enough storage to hold the entire
value that goes into the LOB column.
610 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Note: In DB2 V9, if the base table is created implicitly, all those LOB-related objects are
created automatically. This in turn is now independent from the CURRENT RULES setting.
DB2 still supports SET CURRENT RULES = 'STD' automatic creation. The automatic
creation does not apply for explicitly created table spaces.
We used the IBM supplied sample tables for our case study. The LOB table DDL used is listed
in Example 25-1.
Tip: Before you can execute this CREATE PROCEDURE statement, the executable load
module must exist in the CLASSPATH for your Java stored procedures. Refer to
Chapter 13, “Java stored procedures” on page 181 to learn more about how to set up Java
stored procedures.
The sample code for the Java stored procedure is in Example 25-3.
conndb2 = DriverManager.getConnection("jdbc:default:connection");
Statement stmtdb2 = conndb2.createStatement();
612 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Be aware of the following points about the code listed in Example 25-2:
The emp_photo variable is defined as an output variable of type java.sql.Blob.
The getBlob method is used to retrieve the BLOB column.
LOB materialization is important when using BLOBs in a stored procedure. LOB
materialization means that DB2 places an LOB value into contiguous storage in a data
space. Because LOB values can be very large, DB2 avoids materializing LOB data until
absolutely necessary. However, DB2 must materialize LOBs when your application
program moves an LOB into or out of a stored procedure.
You cannot use LOB locators as input or output parameters for Java stored procedures.
try {
resp.setContentType("image/bmp");
OutputStream out = resp.getOutputStream();
Class.forName("com.ibm.db2.jcc.DB2Driver"); 2.
Connection con =
DriverManager.getConnection(
"jdbc:db2://wtsc63.itso.ibm.com:12345/DB9A",
"paolor7",
"bhas11"); 3.
CallableStatement cstmt =
con.prepareCall("CALL DEVL7083.EMPPHOTJ(?,?,?)");
cstmt.setString(1, "000130");
cstmt.registerOutParameter(2, Types.BLOB); 4
cstmt.registerOutParameter(3, Types.VARCHAR);
cstmt.execute();
resp.setContentType("image/bmp"); 5
inps = cstmt.getBlob(2).getBinaryStream(); 6
} catch (Exception e) {
System.out.println("Error found" + e.toString());
}
3. Once the classes for the Universal Driver are loaded, the format of the connection string
decides the type of connection. We can use either a Type 4 or a Type 2 connection. In our
example we are using a Type 4 connection. The syntax for the Type 4 connection string is
shown in Example 25-5.
url - jdbc:db2://server:port/databasename
uid - userid
pwd - password
server - wtsc63.itso.ibm.com
port - 12345
databasename - DB9A (Location Name for z/OS)
userid - paolor7
password - bhas11
Assume that you have a column defined as a BLOB of 100 MB, and that you have a picture of
0.5 MB stored in this column. When you issue the getBlob() Method to retrieve the BLOB
data, DB2 tries to allocate and look for a storage of about 100 MB even though the data in the
614 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
column is only 0.5 MB. When handling large LOB columns, it is better to retrieve BLOB data
in chunks. Otherwise, you will get an outofMemory abend.
Example 25-6 shows a stored procedure EXTRACT_JAR that extracts a BLOB column
named JAR_DATA from a DB2 Catalog Table SYSIBM.SYSJAROBJECTS. The stored
procedure creates an HFS file that contains the extracted jar file.The JAR_DATA column is
defined as BLOB of 100 MB, and holds the jar file.
sqltxt =
"SELECT Length(JAR_DATA) FROM SYSIBM.SYSJAROBJECTS WHERE JAR_ID = "
+ "'"
+ jarID
+ "'"
+ "and JARSCHEMA = '"
+ schemaName
+ "'";
ResultSet rs = stmt.executeQuery(sqltxt);
if (rs.next())
In our example, we read the BLOB data in chunks of 4 KB, we issue a SUBSTRING
command multiple times, and at each invocation we read a 4 KB chunk, and write it to an HFS
file.
The stored procedure takes three input parameters: SCHEMANAME, JAR_ID, and the HFS
File Name. It extracts the BLOB column and puts it into the file name. Example 25-7 shows
the DDL used for creating the stored procedure.
616 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Example 25-7 DDL for EXTRACT_JAR stored procedure
CREATE PROCEDURE DEVL7083.EXTRACT_JAR
( IN SCHEMANAME CHARACTER(8),
IN JARID CHAR(18),
IN FILENAME VARCHAR(100),
OUT OUTPUTMESSAGE VARCHAR(250))
EXTERNAL NAME 'ExtractJarSp.GetJarFile'
LANGUAGE JAVA
PARAMETER STYLE JAVA
COLLID DSNJDBC
PROGRAM TYPE SUB
WLM ENVIRONMENT DB9ADJC2
The DDL used for creating the stored procedure can be found in Example 25-9.
conndb2 = DriverManager.getConnection("jdbc:default:connection");
Statement stmtdb2 = conndb2.createStatement();
try {
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
Class.forName("com.ibm.db2.jcc.DB2Driver");
Connection con =
DriverManager.getConnection(
"jdbc:db2://wtsc63.itso.ibm.com:12345/DB9A",
618 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
"paolor7",
"bhas11");
CallableStatement cstmt =
con.prepareCall("CALL DEVL7083.EMPCLOBJ(?,?,?)");
cstmt.setString(1, "000130");
cstmt.registerOutParameter(2, Types.CLOB);
cstmt.registerOutParameter(3, Types.VARCHAR);
cstmt.execute();
inps = cstmt.getClob(2).getCharacterStream() ;
out.println("<HTML><BODY>");
out.println("<P><B> This page is built by a java servlet EmpClobSpServlet "
+ " which calls a DB2 Stored Procedure which in turn returns a Resume Data
stored as a CLOB on DB2 V8 . </P>");
out.println("</B><P>");
char[] buf = new char[1024];
while ((nread = inps.read(buf)) > 0)
out.write(buf, 0, nread);
out.println("</P></BODY><HTML>");
} catch (Exception e) {
System.out.println("Error found" + e.toString());
}
IBM, recognizing the need for XML support, has introduced, with DB2 9 for z/OS as well as
with DB2 for Linux, UNIX and Windows pureXML™, a collection of XML capabilities that are
built into the DB2 9 family. DB2 is now an hybrid database fully supporting relational and XML
data.
Beyond XML for data exchange, enterprises are keeping large amounts of business-critical
data permanently in XML format. This has various reasons, such as a need to keep it for
auditing and regulatory compliance. Also, in life science applications, for example, the data is
highly complex and hierarchical in nature and yet may contain significant amounts of
unstructured information. Most of today’s genomic data is still kept in proprietary flat file
formats, but major efforts are under way to move to XML. These proprietary flat files can be
accessed using WebSphere Federated Server technology.
Application development
Application development support of XML enables applications to combine XML and relational
data access and storage. The following programming languages support the new XML data
type:
Assembler
C and C++ (embedded SQL or DB2 ODBC)
COBOL
Java (JDBC and SQLJ)
PL/
The result of this statement is a table consisting of two columns, character column C1 and
column C2 with data type XML.
As a result of issuing the CREATE TABLE statement shown in Figure 25-1, the following
objects have also been created implicitly by DB2 to support the XML column:
A column called DB2_GENERATED_DOC_ID_FOR_XML. We refer to this column as
DocID column from now on. DocID uniquely represents each row. This column is hidden.
For each table, DB2 only needs one DocID column even if you would add additional rows
with data type XML. This DocID is defined as generated always, meaning that you cannot
update the DocID column.
A unique index on the DocID column that is defined as NOT NULL. This index is known as
a document ID index.
An XML table space. The XML table space always uses the Unicode UTF-8 encoding
scheme.
An XML table with columns docid, min_nodeid, and xmldata.
A NodeID index on the XML table with key DocID and min_nodeid
620 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Note: These DB2-required objects are always generated automatically. Special register
CURRENT RULES has no influence on this.
A whole new set of tables containing XML columns are now defined through execution of job
DSNTEJ1. Currently the IVP does not contain any help to populate those tables. The sample
database on DB2 for LUW contains the same tables. Here they are populated with a couple of
rows containing XML documents as well as relational data. Unfortunately, the structure of the
tables is not the same as for DB2 for z/OS.
Refer to Chapter 3, “Our case study” on page 23 if you want to learn an easy way to populate
these tables on DB2 for z/OS with the data rows that reside on DB2 for LUW using Data
Studio.
The DDL used in job DSNTEJ1 to create the existing sample tables is shown in
Example 25-11, Example 25-12, Example 25-13, Example 25-14, and Example 25-15.
However, even if inserting and retrieving data is the same as using other applications, IN,
OUT, and INOUT parameters can never have data type XML associated to them.
If you tried to use data type XML for an IN, OUT, or INOUT parameter of your stored
procedure, you would end up in SQLCODE -20060, as shown in Figure 25-2, where we tried
to create a very simple native SQL stored procedure. The provided example contains almost
no programming logic because our objective here is to provide the information that is
important regarding the usage of the XML data type. If you are interested to learn more about
native SQL stored procedures in general, or if you are looking for more complex examples, we
recommend that you refer to Chapter 15, “Native SQL procedures” on page 253.
622 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
As a result, the attempt to select the contents of an XML column, PORDER in our case, into
an output variable defined as CHAR or VARCHAR fails, as shown in Figure 25-3.
Figure 25-3 Assignment of XML data type to CHAR OUT parameter fails
To overcome this problem and to be able to return the contents of your XML data column as
OUT parameter to your calling application, you must make sure that the contents of your XML
column are cast to another data type. XMLSERIALIZE is the only function that you can use to
initiate the casting. The only two data types that are valid target data types for this cast are
CLOB and DBCLOB.
Refer to Figure 25-4, which shows how to use XMLSERIALZE to cast the XML data type, for
example, to CLOB data type. Since CLOB and VARCHAR are data types compatible for cast,
there is no need to also change the definition of OUT parameter PORDEROUT to CLOB.
In case you are not interested in the whole XML document and are using the XMLQUERY
function to retrieve parts of your XML documents with XPATH statement syntax, the returned
data type is also XML. There is no way to directly cast the result of XMLQUERY to any other
data type directly. You must use XMLSERIALIZE here as well as the OUT function to finally
cast the results from XML to either CLOB or DBCLOB.
Figure 25-5 on page 624 shows a sample XML document that is provided through our sample
data for column PORDER of table DSN8910.PURCHASEORDER.
Refer to Figure 25-6 to verify the above statement. Our attempt to create a native stored
procedure in which we used an XMLQUERY statement to determine the value that is passed
to our OUT parameter PORDEROUT fails, because the result of the XMLQUERY statement
is represented in data type XML.
As stated above, the workaround for this is to use scalar function XMLSERIALIZE to cast data
types from XML to either CLOB of DBCLOB. Example 25-7 on page 625 shows you once
again how this can be done.
624 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
CREATE PROCEDURE XMLSEL3
( OUT PORDEROUT VARCHAR(2000))
VERSION VERSION1
ISOLATION LEVEL CS
RESULT SETS 1
P1: BEGIN
SELECT XMLSERIALIZE(XMLQUERY('//*' PASSING PORDER) AS CLOB)
INTO PORDEROUT
FROM DEVL7083.PURCHASEORDER1 ;
END P1#
The result of the execution of stored procedure XMLSEL3 is the whole XML document as
shown in Figure 25-5 on page 624 in a serialized format, that is, as a long character string.
XML data is usually available as TEXT data. That means that you would either talk about it
using data type CHAR, VARCHAR, CLOB, or DBCLOB. That means that passing an XML
document to a stored procedure through a parameter does not cause you any problems at all
since it is typically not delivered to your application in XML data type format.
As a consequence you would pass your XML text string to your stored procedure using IN or
INOUT parameters defined as:
CHAR
VARCHAR
CLOB
DBCLOB
As a result, your stored procedure definition, including the definition of IN parameters, could
look as shown in Figure 25-8. In this trivial example, you can see that the IN parameter that is
passing the XML document is defined as VARCHAR(2000). You could do the same thing by
using any of the four data types described above. Refer to Example 25-13 if you would like to
see the DDL that we used to create table DSN8910.PURCHASEORDER.
Figure 25-8 Simple stored procedures passing an XML document through the IN parameter
To run this stored procedure, we used Data Studio as the calling program. Refer to
Chapter 27, “The IBM Data Studio” on page 643 if you want to learn more about what Data
Studio is and how to use this new tool to execute stored procedures.
Let us assume that we enter the parameters as shown in Figure 25-10 and press OK. The
parameters are then passed to the stored procedure and inserted into the specified columns.
DB2 converts the XML document that has been passed in as VARCHAR text format to XML
data type.
626 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 25-10 Specified values in Data Studio for IN parameters
25.6.4 Use of the XML data type in stored procedure result sets
Different from what you just read about the use of XML data type in OUT and INOUT
parameters of a stored procedure, there is nothing you need to worry about or code differently
than you would for any other data type when talking about result sets.
Let us take a look at Figure 25-11, which is very similar to what we showed you in
Figure 25-2. Figure 25-11shows a CREATE statement for a native SQL stored procedure.
In contrast to the one in Figure 25-2, this procedure does not accept or return any
parameters. Instead, we are generating a result set containing all the purchase-IDs and the
XML documents stored in XML column PORDER. The creation of this stored procedure
628 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
26
Note: Complete sample programs can be downloaded from the ITSO Web site as
additional material. Download instructions can be found in Appendix B, “Additional
material” on page 887.
Before downloading, we strongly suggest that you first read 3.3, “Sample application
components” on page 24 to decide what components are applicable to your environment.
If you are not familiar with the definition of a trigger, refer to Chapter 12, “Using triggers for
active data” in DB2 Version 9.1 for z/OS Application Programming and SQL Guide,
SC18-9841 or Chapter 3, “Triggers” in DB2 for z/OS Application Programming Topics,
SG24-6300 for details.
Example 26-1 shows how trigger EMPTRIG3 on table EMP invokes user-defined function
EMPAUDTU once for each row whenever a salary increase of more than 10% occurs. The
parameters passed are the employee number and the old and new salary. Notice that the
user-defined function is invoked with a VALUES statement. Also note that the delimiter used
at the end of the CREATE TRIGGER statement is a number sign (#) rather than an asterisk.
You need to use the number sign because the trigger includes an SQL statement within the
trigger action (also called the trigger body) and that SQL statement is delimited by an
asterisk.
Trigger EMPTRIG3 has access to the value of the SALARY column before and after the
update by using the transition variables identified in the REFERENCING clause. The UDF
EMPAUDTU will take the three variables supplied (EMPNO, old SALARY and new SALARY)
and return a value of 1, 2, 3 or 4 depending on the percentage of the employee raise. The
trigger will then use the CASE statement to return a SQLSTATE value of between 75001 and
75004 along with a respective literal of JUNK1 through JUNK4. We tested this trigger by
issuing an UPDATE statement on the EMP table in IBM Data Studio. Figure 26-1 shows the
SQLSTATE of 75002 and the message text of JUNK2 that is returned by EMPAUDTU. For
more details on using IBM Data Studio to test DB2 applications, see Chapter 27, “The IBM
Data Studio” on page 643.
630 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Starting run
UPDATE DEVL7083.EMP
SET SALARY = SALARY * 1.12
WHERE EMPNO = '000070'
Figure 26-1 Messages tab in IBM Data Studio Data Output View showing trigger test results
An alternative way to conditionally invoke a user-defined function from a trigger, based on the
number of rows of a table, is to issue a SELECT statement against the transition table.
Transition tables are discussed in 26.2.2, “Using transition tables” on page 633.
Similarly, Example 26-2 shows a trigger that accomplishes the same result by calling a stored
procedure instead of invoking a trigger. Stored procedure EMPAUDTS is invoked under the
same conditions and is passed the same parameters. Since the trigger is invoking a stored
procedure, a CALL statement is used in place of the VALUES statement that was used for a
user-defined function.
Figure 26-2 SDSF output showing DISPLAY results for stored procedure invoked by trigger
The parameters of a stored procedure call from a trigger must be literals, transition variables
(see 26.2.1, “Using transition variables” on page 633), transition tables (see 26.2.2, “Using
transition tables” on page 633), or expressions.
Note that a transition variable or transition table is not affected after being returned from a
stored procedure invoked from a trigger. This is true regardless of how the corresponding
parameter is defined in the CREATE PROCEDURE—IN, OUT or INOUT.
As you will see from the discussion above, there is a substantial overlap in the functionality of
user-defined functions and stored procedures when invoked by a trigger. However, you must
consider the error handling requirements before making the decision. We discuss this in 26.4,
“Stored procedures versus user-defined functions” on page 636.
Table 26-1 summarizes the allowable combinations of transition variables and transition
tables that you can specify for the various trigger types. The MERGE statement, introduced in
DB2 9 for z/OS, performs an UPDATE if the row exists and an INSERT if the row does not
exist. Any INSERT or UPDATE triggers that are defined on the table are fired depending on
what operation actually gets executed, so we do not provide any distinction in the following
table for the MERGE operation. INSTEAD OF triggers, also introduced in DB2 9 for z/OS,
result in an INSERT, UPDATE or DELETE operation on a base table when one of those
operations is requested on a view. INSTEAD OF triggers, as well as BEFORE triggers, must
be defined with a granularity of FOR EACH ROW.
632 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Granularity Activation time triggering SQL Transition Transition
operation variables tables allowed
allowed
The list of parameters must be compatible with the parameter list defined in the linkage
section of the stored procedure and the PROCEDURE DIVISION USING... statement. For the
sample stored procedure EMPAUDTS, the linkage section looks like this in COBOL:
LINKAGE SECTION.
01 PEMPNO PIC X(6).
01 POLDSALARY PIC S9(7)V9(2) COMP-3.
01 PNEWSALARY PIC S9(7)V9(2) COMP-3.
The procedure division for the stored procedure looks like this in COBOL:
PROCEDURE DIVISION USING PEMPNO, POLDSALARY, PNEWSALARY.
Transition tables are read-only. Like transition variables, transition tables also use the names
of the columns of the subject table, but the old and new transition tables each have a qualifier
specified that allows the complete set of affected rows to be treated as a table.
We now describe how to access transition tables in a stored procedure, but the same applies
to a user-defined function.
To access transition tables in a stored procedure, use table locators, which are pointers to the
transition tables. You declare table locators as input parameters in the CREATE
PROCEDURE statement using the TABLE LIKE table-name AS LOCATOR clause. See
Chapter 5 of DB2 Version 9.1 for z/OS SQL Reference, SC18-9854 for more information.
The five basic steps to accessing transition tables in a stored procedure are:
1. Declare input parameters to receive table locators. You must define each parameter that
receives a table locator as an unsigned 4-byte integer. This is shown in Example 26-5 for
COBOL. This step is optional and it is required only if you plan to use the locator later in
the program and need to save it. In general, for COBOL you can use the locators from the
LINKAGE SECTION directly.
2. Declare table locators. The syntax varies with the application language. See Chapter 9,
“Embedding SQL statements in host languages” of the DB2 Version 9.1 for z/OS
Application Programming and SQL Guide, SC18-9841 for information on the syntax for C,
C++, COBOL, and PL/I. See Chapter 6 of DB2 Version 9.1 for z/OS SQL Reference,
SC18-9854 for information on the syntax for SQL procedures. This is shown in
Example 26-6.
3. Declare a cursor to access the rows in each transition table. This is shown in
Example 26-7.
634 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
FROM TABLE(:TRIG-TBL-ID-OLD LIKE EMP) AS OLDTAB
, TABLE(:TRIG-TBL-ID-NEW LIKE EMP) AS NEWTAB
ORDER BY EMPNO
END-EXEC.
4. Assign the input parameter values to the table locators. This is shown in Example 26-8.
5. Access rows from the transition tables using the cursors that are declared for the transition
tables. This is shown in Example 26-9.
Now let’s return to our transition table example from Example 26-4 on page 634. Since trigger
EMPTRIG2 is an AFTER trigger on an UPDATE statement, stored procedure EMPAUDTX
has access to the before and after copies of the row being updated by using the transition
tables. Stored procedure EMPAUDTX fetches the data from the before and after transition
tables and displays the old and new salary, as well as the SQLCODE returned from the
FETCH from each transition table if the employee’s salary was updated by more than 10%.
The displayed output is shown in Figure 26-3.
Figure 26-3 SDSF output showing DISPLAY results for stored procedure with transition tables
Another option to cause errors in a stored procedure to return an error to the trigger is to
issue a ROLLBACK in the stored procedure when you encounter an error. It is incorrect
syntax to issue a COMMIT or a ROLLBACK in a stored procedure that is called by a trigger.
This is stated in Chapter 5 of DB2 Version 9.1 for z/OS SQL Reference, SC18-9854. Since a
ROLLBACK is not allowed in a stored procedure that is called by a trigger, the ROLLBACK
will receive an SQLCODE of -751 and, as a result of that error, an SQLCODE of -723 will be
returned for the original SQL statement that caused the trigger to be invoked. Therefore, the
original SQL statement will fail and none of the changes will be committed. In a way the
ROLLBACK in the stored procedure works, just not directly.
If your stored procedure is written in Java, then you could throw a Java exception which would
cause an exit from the Java program. This in turn will cause the trigger to fail, which will cause
an error SQLCODE of -723 to be returned for the original SQL statement that caused the
trigger to be invoked.
The ability to handle errors in a trigger is severely limited, especially when it calls a stored
procedure, as we have shown above. For this reason, you must decide carefully whether you
use a stored procedure or a user-defined function. This is discussed next in 26.4, “Stored
procedures versus user-defined functions” on page 636.
Data validation deals with invoking complex business logic to determine whether or not a
certain action (INSERT, UPDATE, or DELETE) should be permitted. This is typically achieved
with a user-defined function invoked by a BEFORE trigger. Data propagation deals with
invoking complex business logic after a certain action has taken place. This is typically
achieved with a stored procedure invoked by an AFTER trigger. Figure 26-4 shows how a
user-defined function can be used for data validation.
636 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Data validation using a trigger and a user defined function
DB2 Table
MQ-Series
Insert IMS/db
Update
Delete
- - - - - -
CICS
IMS/tm - - - - - -
Example 26-10 shows how a user-defined function can pass an output parameter back to the
trigger. In this case, our sample user-defined function EMPAUDTU is passed three input
parameters and sets the PRTNCD parameter and passes it back to the trigger.
COMPUTE WS-RAISE-PCT
= (WS-NEWSALARY - WS-OLDSALARY)* 100.00 /
WS-OLDSALARY.
EVALUATE TRUE
WHEN WS-RAISE-PCT < 5.00
MOVE SPACES TO PRTNCD
WHEN WS-RAISE-PCT < 10.00
MOVE '1' TO PRTNCD
Example 26-11 shows how you can use the result of a user-defined function to return different
error messages to the calling application.
The user-defined function DEVL7083.EMPAUDTU returns a value to the trigger, then the
CASE statement within the trigger body determines whether the built-in function
RAISE_ERROR is invoked to return a SQLSTATE value. The COALESCE function is used
because the CREATE TRIGGER statement will receive a syntax error on the RAISE_ERROR
function due to the possibility that the function will return a null value. The SQLSTATE value
must conform to the following rules:
Each character must be numeric (0 through 9) or uppercase alphabetic (A through Z).
The SQLSTATE class (first two characters) cannot be 00, 01, or 02 because these are not
error classes.
If the SQLSTATE class starts with 0 through 6, or A through H, then the subclass (last
three characters) must start with a letter in the range I through Z.
If the SLQSTATE class starts with 7 through 9, or I through Z, then the subclass (last three
characters) can be any of 0 through 9, or A through Z.
Figure 26-5 shows how a stored procedure can be used for data propagation.
638 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Data propogation using a trigger and a stored procedure
DB2 Table
MQ-Series
Insert IMS/db
Update
Delete
- - - - - -
CICS
IMS/tm - - - - - -
The stored procedure could take information available in either transition variables or a
transition table and use that data to update another DB2 table, write to an MQ queue or
propagate any of the other object types described in Figure 26-5.
Invoking a user-defined function from a stored procedure is identical to how you invoke it from
any other application. There are no special considerations that apply.
Invocation of a user-defined function or a stored procedure within one logical unit of work is
considered as “nesting” (subject to the limit of 16); this is discussed in 10.3.1, “Nested stored
procedures” on page 130.
As before, invocation of a stored procedure from a user-defined function within one logical
unit of work is considered as “nesting” (subject to the limit of 16); this is discussed in 10.3.1,
“Nested stored procedures” on page 130.
640 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Part 6
As of the publication of this book, there are three “versions” of IBM Data Studio, shown in
Table 27-1.
The IBM Data Studio is a comprehensive data management solution that empowers you to
effectively design, develop, deploy and manage your data, databases and database
applications throughout the entire application development life cycle utilizing a consistent and
integrated user interface. Included in this tooling suite are the tools for developing and
deploying DB2 for z/OS stored procedures. Unlike Development Center (DC), which was
included in the DB2 V8.1 UDB Application Development Client (ADC) component, the IBM
Data Studio is independent of any other product offering and does not require a DB2 client
installed.
IBM Data Studio supports the entire family of DB2 servers, as well as Informix, using the
DRDA architecture. It supports Versions 8 and 9 of DB2 for Linux, UNIX and Windows;
Versions 7, 8 and 9 of DB2 for z/OS; Versions 5.3 and up of DB2 for iSeries; and Informix
While IBM Data Studio is a tooling suite that delivers features that go beyond stored
procedure development, in this chapter we limit our discussions to the routine tooling feature
for creating, developing and deploying SQL and Java stored procedures. Additional features
in support of stored procedures are mentioned at the end of this chapter.
IBM Data Studio and Rational Application Developer both sit on top of the Eclipse Framework.
Thus, both products have a similar “look and feel”. The setup for z/OS, which we describe in
this chapter for creating SQL and Java stored procedures for IBM Data Studio, applies to
Rational Application Developer as well. The same setup applies when using .NET to create
SQL stored procedures on z/OS.
In 3.3, “Sample application components” on page 24, we discussed the sample SQL and
Java stored procedures on DB9A, a DB2 for z/OS V9 server. We create similar stored
procedures using IBM Data Studio in this section.
IBM strongly recommends using the IBM Data Server driver for JDBC and SQLJ, also known
as the Universal JDBC driver, when connecting to the DB2 servers. While IBM Data Studio
provides the ability to connect using the Legacy driver, the support for this is very limited. In
this chapter, we assume that the IBM Data Server driver for JDBC and SQLJ is used
throughout. For information on using the Legacy Driver with DB2 Development Center, refer
to section 29.2.5 in the previous edition of this book.
644 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
This chapter contains the following:
Eclipse workbench common terminology
Prerequisites and setup steps
Navigating through the IBM Data Studio workspace
Developing stored procedures with IBM Data Studio
Developing stored procedures
Deploying a stored procedure
Advanced IBM Data Studio topics
Data Studio is based on the open and extensible framework of the Eclipse Workbench.
Workspace
When you open the workbench, you are asked to choose a workspace. All your resources
and settings are saved in this workspace. Only one workspace is active at any given time. You
may open a different workspace each time you open the workbench. You can also switch
workspaces by clicking File Switch Workspace.
Resources
A resource is a collective term for the projects, folders, and files that you created in a
workspace. Typically, resources are viewed in a hierarchical format and can be opened for
editing. There are three basic types of resources that exist in the Workbench:
Files
A file in Eclipse is comparable to files in the workstation. Each resource in Eclipse is
associated with a file. Eclipse persists or saves all resources in the workspace as files in the
file system.
Folders
Folders in the Eclipse workspace are comparable to directories in a file system. In the
workspace, folders are containers for the various resources that can be created, viewed
and/or manipulated by the tooling.
Projects
In Eclipse, development is contained in projects. Projects contain folders which in turn can
contain either a set of objects or another folder. Projects have one or more nature associated
with it, meaning that the contents and tasks that can be done on the objects within the project
depend on the kind of project created.
A project is either open or closed. When a project is closed, it cannot be changed in the
Workbench. The resources of a closed project will not appear in the Workbench, but the
resources still reside on the local file system. When a project is open, the structure and
contents of the project can be viewed and modified.
646 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Perspectives
A perspective is a group of views and editors in the Workbench window. One or more
perspectives can exist in a single Workbench window. Each perspective contains one or more
views and editors. Each perspective may have a different set of views but all perspectives
share the same set of editors.
Data perspective
The Data perspective is the primary perspective used by IBM Data Studio. The Data
perspective provides a set of functions and specialized views for displaying, creating,
deploying and managing database objects.
Debug perspective
The Debug perspective is the primary perspective used by IBM Data Studio when debugging
an SQL or Java stored procedure. This perspective is used by other products, such as the
Rational Developer V7 for System Z.
Other perspectives used by IBM Data Studio are the Java Perspective, the Team Perspective
and the Resource Perspective.
Views
A view is a visual component within the Workbench that is used to display a hierarchy of
resources in the Workbench, display properties of a resource, and perform tasks on the
resource. Modifications made in a view are saved immediately. Only one instance of a
particular type of view may exist within a Workbench window.
Several views can share an area of the workspace as in the case when multiple objects are
opened in the Editor. The Output view also shows multiple types of output (e.g. Error Log,
Problems, Data Output, etc.)
For most tasks, a database developer will use the Database Explorer, Data Project Explorer,
and the Data Output views. More information about these views in IBM Data Studio is given in
27.3, “Navigating through the IBM Data Studio workspace” on page 667.
Editors
An editor is a visual component within the Workbench that is used to edit or browse a
resource. Modifications made in the editor follow an open-save-close lifecycle model. An
editor can be specialized for a function. Multiple instances of specialized editors may exist
within a Workbench window.
Wizards
A wizard is a visual component within the Workbench that is used to step a user through a
series of tasks related to a resource. The purpose of the wizard is to make a task easy for the
user.
1 - Review prerequisites
The following lists the minimum prerequisites:
IBM Data Studio installation software or CD.
Unlike IBM Development Center, the Developer Workbench and IBM Data Studio are
separate installable products. Both are available as part of DB2 on LUW V9. IBM Data
Studio is also available as part of the DB2 Accessories Suite for z/OS, V1.2 (5655-R14).
The free version of IBM Data Studio is available as a download from the following Web
site:
https://www14.software.ibm.com/webapp/iwm/web/preLogin.do?lang=en_US&source=swg-ids
Optionally, DB2 9 Connect or DB2 V8.1 Connect Enterprise Server Edition can be
installed on the client workstation.
A restricted use license of DB2 Connect Personal Edition for development purposes can
be obtained in the DB2 for z/OS Management Clients Package. See the section on setup
at “Workstation” on page 761 to obtain the FMIDs for the Management Clients Package.
If you want to prototype your SQL or Java Stored procedures for DB2 on your client
workstation, you need to install any edition DB2 V9.1 or DB2 V9.5 for LUW on your
workstation.
648 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
5. In the Shared Resourced Directory, select C:\Program Files\IBM\SDP70Shared. Click
Next.
6. In the Installation Directory text box, select C:\Program Files\IBM\SDP70. Click Next.
7. Do not extend the Eclipse IDE. Click Next.
8. The default setting is English. Select your language, then click Next.
9. A default list of features are preselected for you. Deselect or select features that you want
installed. Click Next.
10.Verify that the disk space you have can accommodate the installation size. Click Install.
11.Check for Success, then click Finish.
Note: IBM Data Studio Developer V1.1.1 can share a package group with other compatible
products that have been installed with IBM Installation Manager. So in Step 7 above, you
can opt to extend the Eclipse Integrated Development Environment (IDE) you currently
have installed in your system. The following products also include the Eclipse IDE in their
installation. You can significantly reduce the storage requirements if you opt to “shell share”
or share the base Eclipse plugins of the following products with IBM Data Studio.
The following products have been tested to successfully share the Eclipse package with
IBM Data Studio Developer Version 1.1.1. Other products have not been tested and you
should not attempt to install IBM Data Studio Developer Version 1.1.1 with them in a
shared package group.
Rational Data Architect Version 7.0.0.4
Rational Application Developer Version 7.0.0.5
Rational Software Architect Version 7.0.0.5
IBM Data Studio is installed into two default directories C:\Program Files\IBM\SDP70Shared
and C:\Program Files\IBM\SDP70.
IBM Data Studio ships with the IBM Data Server driver for JDBC and SQLJ1, also called the
Universal driver. These include the license jars, db2jcc.jar and db2jcc_license_cisuz.jar,
needed to connect to DB2 for z/OS servers. However, these jars only work with IBM Data
Studio. When you connect to DB2 for z/OS, the tooling uses these default license jars.
You can opt to use the license jars supplied by DB2 Connect. However, certain features and
functions in IBM Data Studio require a specific level of db2jcc.jar. So, you need to verify if the
version of the DB2 Connect license jars is equal to or greater than the version shipped with
IBM Data Studio. To verify this, type the command shown in Example 27-1 on a Windows
command prompt where classpath is the directory where db2jcc.jar is located.
In the example, -url points to the domain:port//location of the DB2 for z/OS server that you
want to connect to. The user is the TSO logon ID and password is the TSO logon ID
password. The bind may need to be repeated after applying a FixPak to IBM Data Studio. If
the DB2Binder is not run, and you do not re-execute the bind, you receive -805 at the
workstation when trying to use IBM Data Studio.
Note: Both the location and collection IDs should be in uppercase when submitting the
DB2Binder command from the client. To continue typing a long line to the next line, type a
backslash (\), followed by a space, then continue typing on the next line.
650 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
The minimum prerequisites are listed next.
SQL and Java stored procedures:
– DB2 for z/OS, minimum Version 8
– LE
– WLM
– RRS
– REXX language
– Unicode support
External SQL stored procedures
– C compiler
Java stored procedures
– JDBC driver
– SDK 1.4.2
IBM Data Studio interacts with the DB2 for z/OS subsystems using several DB2-supplied
stored procedures. These stored procedures are defined using different customization jobs
included in <hlq>.SDSNSAMP.
The following customization jobs are required for both SQL and Java stored procedures:
– DSNTIJSD
– DSNTIJRX
– DSNTIJTM
– DSNTIJMS
– DSNTEJ6W
– DSNTIJSG
– DSNTIJCC
An Explain-like stored procedure can be set up that is optional on the SQL Statement
page with both the SQL and Java wizards used by IBM Data Studio.
– SYSPROC.DSNWSPM (Actual Costs) setup is currently a manual job submission.
Table 27-3 General authorities and privileges for all platforms using IBM Data Studio
Task Authorities and privileges
Drop a stored procedure You must have ownership of the stored procedure
and at least one of the following:
DELETE privilege
DROPIN privilege for the schema or all schemas
SYSADM or SYSCTRL authority
Update a stored procedure You must have ownership of the stored procedure
and at least one of the following:
UPDATE privilege
ALTERIN privilege for the schema or all schemas
SYSADM or SYSCTRL authority
The IBM Data Studio accesses a number of DB2 system catalog tables on z/OS. Table 27-4
on page 653 lists the privileges required to view the objects in the Database Explorer. The
user connecting to DB2 for z/OS must hold privileges listed in Table 27-4 and Table 27-5 on
page 653 for SQL stored procedures, and Table 27-6 for Java stored procedures. The
privileges can be held by any authorization ID of the process, either the primary authorization
ID or any secondary authorization ID.
652 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Table 27-4 Privileges required to view the objects in the Database Explorer in IBM Data Studio
Additional required privileges:
EXECUTE privilege on DSNTPSMP
For DB2 for z/OS V8 and DB2 for z/OS V9, the IBM Data Studio accesses the following
catalog and non-catalog tables when creating external SQL stored procedures.
Table 27-5 DB2 system catalog tables accessed when creating SQL stored procedures
SELECT privilege on:
SYSIBM.SYSDUMMY1
SYSIBM.SYSROUTINES
SYSIBM.SYSPARMS
For DB2 for z/OS V8 and V9, the IBM Data Studio accesses the following catalog tables when
creating JAVA stored procedures.
Table 27-6 DB2 system catalog tables accessed when creating Java stored procedures
SELECT privilege on:
SYSIBM.SYSROUTINES
SYSIBM.SYSDUMMY1
SYSIBM.SYSPARMS
SYSIBM.SYSJARCONTENTS
SYSIBM.SYSJAROBJECTS
SYSIBM.SYSJAVAOPTS
To determine if UCS is active, issue ‘D UNI,ALL’ from an SDSF screen. If the support is
installed, you receive output with the actual CCSID entries that have been defined. If UCS is
not installed, the following message is returned:
CUN2029S CONVERSION ENVIRONMENT IS NOT AVAILABLE
Without Unicode Conversion Services set up, you can initially create, view, and modify a Java
stored procedure. However, restoring the source from the database of a previously created
Java stored procedure returns the source as a single line with red blocks interspersed, which
represent line feeds that have not been translated correctly. The IBM Data Studio support for
SQL stored procedures handles the code conversion, and UCS is not required.
DSNTIJSD
This job installs the debugger server routines. All DB2 for z/OS servers must have the
complete set of debugger server routines installed to enable interaction with IBM Data Studio.
Depending on your installation, the server routines installed by this job can be used with:
The IBM Data Studio Unified Debugger clients. SYSPROC.DBG_%MANAGER server
routines are installed in the server
The SQL Debugger clients. SYSPROC.DBG_% server routines are used in the server.
DSNTIJRX
This customization job sets up REXX support, which is used by both DSNTPSMP (used for
SQL stored procedures) and DSNTBIND (used for Java SQLJ stored procedures).
654 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
DSNTIJTM
This customization job sets up DSNTWR, the external module used by the DB2-supplied
stored procedure WLM_REFRESH, which is used when creating SQL and Java stored
procedures.
DSNTIJMS
This customization job sets up SQL Wizard support. SQL Wizard is used when creating SQL
Statements within the New Stored procedure wizard in IBM Data Studio.
DSNTEJ6W
This customization job creates and populates the RACF resource profile to support
WLM_REFRESH in resource class DSNR. It also prepares and executes a sample caller of
WLM_REFRESH. Stored procedures that execute in a WLM AE may stay resident whether a
resident run option was specified or not, until the WLM application environment (AE)
terminates. To ensure that the latest changes execute during the next invocation of the stored
procedure, the WLM AE needs to be refreshed. This can be done from the MVS, SDSF
console using the following command:
V WLM,APPLENV=DB9AWLM,REFRESH
IBM Data Studio automatically performs this refresh operation using the WLM_REFRESH
stored procedure. Customization job <hlq>,SDSNSAMP(DSNTIJSG) defines the procedure,
and grants the authorization, while <hlq>.SDSNSAMP(DSNTIJTM) binds the package.
The RACF class DSNR needs to be activated first. This is done using the RACF panels
described in Table 27-8.
RACF Set Class Options Menu, panel 1 Enter YES in To CHANGE options for SPECIFIC
CLASSES field
RACF Set Class Options Menu, panel 2 Enter DSNR in CLASS field and YES in ACTIVE
field
When DSNTPSMP executes, it creates a compiled SQL load module using the C compiler in
the data set referenced by //SQLLMOD in its WLM AE. This same data set needs to be
included in STEPLIB in the WLM proc where the user’s SQL stored procedure created by
DSNTPSMP will run.
The definition of the configuration file we used on DB9A is listed in Example 27-3.
656 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
CURRENTDATA_DEFAULT = YES
;-SPECIFIES INSTALLATION CONTROL OVER THE DEFAULT VALUE FOR
;-THE BIND PACKAGE OPTION CURRENTDATA. CHANGING THE DEFAULT
;-MAY PROVIDE A PERFORMANCE IMPROVEMENT.
;
DSNTPSMP_TRACELEVEL= LOW
;- OFF, LOW, MEDIUM, HIGH
;-CONTROLS THE LEVEL OF DSNTPSMP TRACE DATA WRITTEN OUT TO
;-THE DD:SYSTSPRT DATASET IN THE WLM ADDRESS SPACE. SETTING
;-THE VALUE TO OFF WILL MINIMIZE, NOT ELIMINATE, LOG RECORDS
;-WRITTEN TO DD:SYSTSPRT IN THE WLM-SPAS.
;
Customization needed for WLM_REFRESH includes specifying the WLM AE. The proc that
runs in this WLM AE requires all APF-authorized data sets.
When multiple versions of either of these DB2-supplied stored procedures are required, first
register a new copy of DSNTPSMP with a new schema (SYSPROC is the default). In that
registration, specify a new WLM proc where this copy of DSNTPSMP will execute and
complete other similar steps as described in “Setup specific to SQL stored procedures” on
page 656 for SQL stored procedures.
When deploying a new SQL or Java stored procedure using the Deploy wizard, a different
build schema and utility (external SQL only) can be selected from the Routine options
page Deploy Options tab Build utility field as shown in the example in Figure 27-3.
DSNTIJCC
This job installs the DB2-supplied stored procedures that are called to perform database
administration tasks from the client. IBM Data Studio uses these stored procedures for
deploying using binaries external SQL stored procedures. See the discussion in “24.1.2,
“Setting up DB2-supplied stored procedures” on page 502”.
658 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 27-3 Multiple versions of schema
The default JDBC driver that IBM Data Studio uses is the IBM Data Server Driver for JDBC
and SQLJ.
660 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
executes. The JCC_HOME environment variable in this file specifies the location in UNIX
System Services (USS) where the Universal JDBC driver is installed.
The default directory structure for JCC_HOME is /usr/lpp/db2/db2910/jcc. For more details on
the //JAVAENV DD statement, see 13.3.7, “Setting up the JAVAENV data set for Java stored
procedure execution” on page 188.
See the section “Installing the IBM DB2 Driver for JDBC and SQLJ” under “Installation and
Migration” in the following URL for the DB2 for z/OS V9 Information Center for more
information on the IBM Data Server Driver for JDBC and SQLJ.
http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/index.jsp
Overview
Both JDK 1.4.2 and JDK 1.5 are supported when creating Java stored procedures on DB2 for
z/OS V9. DB2 for z/OS V8 only supports the JDK 1.4.2. The two areas that reference a JDK
are:
The build time of the stored procedure by IBM Data Studio, which includes compiling the
source
Optionally, at runtime of the stored procedure in the Work Load Manager (WLM) Stored
Procedure Address Space (SPAS)
Java methods used during build time must be available at runtime in the Java Runtime
Environment (JRE™), otherwise an execution error indicating a mismatch occurs in the WLM
SPAS. For instance, using a Java stored procedure that includes a JDK 1.5 method fails if it
executes in a WLM SPAS referencing a Java 1.4.1 JRE.
IBM Data Studio ships with a JDK 1.5 library. This is the default JDK used when developing
Java stored procedures and applications in IBM Data Studio. In a typical install, the JDK is
found in C:\Program Files\IBM\SDP70\jdk.
However, the user can opt to compile with the 1.4 level by setting the JDK level in three
places:
– In the workspace Preferences
– In the Project’s Properties
– In the stored procedure’s Deploy options
The base product of DB2 for z/OS V8 includes support for both the SDK 1.3.1 and SDK 1.4.1.
There is no support for SDK 1.3.0 or SDK 1.4.0 in DB2 V8.
When using SDK 1.4.1, the XPLINK(ON) parameter is required in the //JAVAENV DD
statement. If the XPLINK(ON) parameter is included when specifying an SDK 1.3.1, the
following information message is written to the WLM SPAS:
CEE3611I The run-time option XPLINK= was an invalid run-time option or is not supported
in this release of Language Environment.
When the XPLINK(ON) parameter is not included in a //JAVAENV DD statement that specifies
SDK 1.4.1, the WLM SPAS does not initialize and the following error message is included in
the WLM SPAS joblog:
+DSNX961I DSNX9WLJ ATTEMPT TO PERFORM JNI FUNCTION CreateJavaVM 421
FAILED FOR STORED PROCEDURE . . SSN= DB8A PROC= DB8AJAV1 ASID=
008E CLASS= METHOD= ERROR INFO= DSNX9WLS ESTAE ENTERED
662 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Example 27-6 Legacy JDBC Driver - SDK 1.3.1
ENVAR("DB2_HOME=/usr/lpp/db2/db2710",
"JAVA_HOME=/usr/lpp/java/IBM/J1.3",
"DB2SQLJPROPERTIES=/u/DB7PU/db2sqljjdbc.properties"),
MSGFILE(JSPDEBUG,,,,ENQ)
The following examples apply to Java stored procedures using the Universal JDBC driver.
Like Development Center, IBM Data Studio creates external SQL and Java stored procedures
on z/OS using multiple DB2-supplied stored procedures. The main DB2-supplied stored
procedures that perform the processing on z/OS for IBM Data Studio are:
DSNTPSMP for SQL stored procedures
SQLJ.DB2_INSTALLJAR
SQLJ.DB2_REPLACEJAR
SQLJ.DB2_UPDATEJARINFO
When connected to DB2 for z/OS V9, IBM Data Studio can create both external SQL stored
procedures as well as Native stored procedures which no longer require DSNTPSMP. The
tooling identifies the type of SQL stored procedure by appending “(external)” or “(native”) to
the stored procedure name displayed in the Data Project Explorer. Also, starting in DB2 9 for
z/OS, DSNTJSPP is no longer used for creating Java stored procedures.
664 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Type Name Function
The following steps are performed by IBM Data Studio to create external SQL stored
procedures on DB2 V7, V8 and V9:
1. Launch IBM Data Studio, and select a workspace.
2. Create a connection or Reconnect to an existing connection to a DB2 server.
3. Create a Data Development Project and set the Target connection to the above database
server.
4. Create a new SQL stored procedure using the New Stored Procedure wizard. This wizard
has an embedded SQL Wizard to help develop SQL statements. Alternatively, existing
SQL statements can be imported into the SQL stored procedure. See 27.4.4, “Creating
SQL statements to use in your stored procedure” on page 685 for details on using the SQL
Wizard.
5. The New Stored Procedure wizard allows the user to deploy the stored procedure at the
end of the wizard, or to simply display the generated DDL and configuration properties in
the Editor. Assume the automatic deploy is selected.
6. Now DSNTPSMP is called.
7. DSNTPSMP performs the following steps to create the SQL stored procedure on z/OS:
a. SQL precompile
b. C precompile
c. C compile and prelink
d. Link
e. Bind package
f. Register procedure in the DB2 catalog
g. Save options
Figure 27-6 describes how the IBM Data Studio creates SQL stored procedures on z/OS.
6 DSNTPSMP
SQL Precompile
z/OS REXX
Call DSNTPSMP SP for processing Performs
external SQL
stored procedures 7 C Compile
Link
PROCEDURE definition
Deploy
5
BIND PACKAGE
Figure 27-6 How IBM Data Studio creates SQL stored procedures
Figure 27-7 describes how the IBM Data Studio creates Java stored procedures on z/OS.
666 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
How Data Studio creates Java SPs
4
> javac or -sqlj
3 > db2sqljcustomize CALL SQLJ.DB2_INSTALLJAR DB2 for
> jar files z/OS
Deploy
2 CREATE PROCEDURE
6
Start IBM Data Studio
Call SQLJ.
1 Use wizards to create a new
DB2_UPDATEJARINFO
Java stored procedure
Figure 27-7 How IBM Data Studio creates Java stored procedures
In addition to viewing the stored procedures and UDFs that are on the server, the Database
Explorer allows you to view and work with other database objects such as tables, triggers,
views, etc.
In 27.4, “Developing stored procedures with IBM Data Studio” on page 680, we discuss the
Connection Wizard and the SQL Editor in detail.
668 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
1. Filter - This action allows you to filter what is displayed in the Stored Procedures folder in
two ways, as shown in Figure 27-9 on page 669. Right-click the Stored Procedure
folder Filter to launch the Filter dialog.
– Using an Expression: pull-down list allows the user to create clause-like expressions
such as LIKE ‘DEV%’.
– Select from a list of stored procedure names.
2. New - This action creates a new stored procedure using the New Stored Procedure wizard
or the SQL Editor.
– Using the New Stored Procedure wizard: Right-click the Stored Procedures folder
New With Routine Editor. This launches the New Stored Procedure wizard and
guides the user to creating a new SQL or Java stored procedure. At the end of the
wizard, you are asked to give the name of a project that will contain this new object.
Section 27.4, “Developing stored procedures with IBM Data Studio” on page 680 gives
more details on the New Stored Procedure wizard.
– Using the SQL Editor: Right-click the Stored Procedures folder New With SQL
Editor creates a blank editor in the Editor view. You can type your CREATE
PROCEDURE statement there, <add xref to SQL Editor>.
3. Refresh - This action reads the latest information for the specific folder from the server
catalog. Right-click the Stored Procedures folder Refresh to refresh the list of deployed
or cataloged stored procedures.
4. Deploy: This action launches the Deploy wizard. Right-click the Stored Procedures
folder Deploy allows you to redeploy one, some, or all the stored procedures listed in
this folder. Right-click a specific stored procedure Deploy allows you to redeploy only
the selected stored procedure. Figure 27-10 on page 670 shows the first page of the
Deploy Wizard. Details on the Deploy Wizard are discussed in 27.6, “Deploying a stored
procedure” on page 703.
The context menu on a specific stored procedure shows additional actions that can be
taken on the stored procedure. Right-click the stored procedure to activate the following
actions:
a. New version - This action is only available when the selected stored procedure is a
Native SQL stored procedure. This action launches the New Version wizard. This
wizard creates a new version of the selected stored procedure and optionally deploys
it.
b. Open - This action launches either the Routine Editor or the SQL Editor on the Editor
view. You are asked to specify a Data Development Project to contain the stored
procedure. IBM Data Studio assumes that you are opening the stored procedure for
editing. If you want to simply view the properties of this stored procedure, click the
Properties tab of the Output View. We discuss this in more detail in 27.3.3, “Output
view” on page 673.
c. Drop - This action issues a DROP PROCEDURE against the selected stored
procedure. A confirmation dialog is displayed before the action is sent to the server.
Note: This action drops all versions of a Native SQL Stored procedure. To drop a
specific version, expand the selected stored procedure Versions select the
specific version and activate the Drop action from this version.
d. Generate DDL - This action launches the Generate DDL Wizard. In the wizard, you
can:
• Generate the CREATE PROCEDURE DDL.
• Optionally generate the associated DROP statement before the CREATE
statement.
• Optionally generate any associated COMMENT ON and LABEL ON statements.
670 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
• Optionally generate any GRANT statements based on the current privileges held on
this stored procedure.
• Execute the generated DDL, or save and edit the generated script. You are asked to
specify an existing project to contain the generated script. IBM Data Studio looks at
the list of existing projects and defaults the project to one that is using the current
server or one that is a “best fit” (that is, same operating system, same version).
Note: For Java stored procedures, Generate DDL does not create a clone of the Java
source associated with the Java stored procedure.
Figure 27-11 shows the DDL generated for one of our sample stored procedures.
Each Data Development Project contains the database objects that you can work on, in an
object tree structure. Figure 27-12 on page 672 shows the contents of a Data Development
Project.
Note: Multiple Jars, XML and Web Services are only supported with DB2 for z/OS V9.
These folders may exist in projects associated with non-DB2 for z/OS V9 servers for
strategic purposes.
Project properties
A set of Project properties associated with the Data Development Project can be used to set
default values when creating objects within the project. Right-click the project name
Properties to launch the Properties Dialog.
The Connection page displays the connection properties of the target connection. In
27.4.2, “Creating a connection” on page 682 we discuss how to set the connection
properties.
672 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
The Development page allows you to set the Current Schema, as shown in Figure 27-13
on page 673. A discussion of the Current Schema versus Current SQLID is in 7.5.7,
“Resolution of unqualified stored procedure names at create time” on page 79.
The Routine Development page allows you to set the JDK level to be used for compiling
the Java stored procedures you create. Additionally, you can set the package owner and
build owner for SQL and SQLJ stored procedures in this page, as shown in Figure 27-14.
Both the package and build owner can be set to secondary authorization IDs.
Properties view
In the Database Explorer, when a specific object is selected, the properties of the object are
retrieved and displayed in the Output view’s Properties tab, as shown in Figure 27-15 on
page 674.
The Properties page, in turn, contains multiple tabs which group the stored procedure’s
attributes into:
General - Name, Label (on), Result sets returned, Language, Parameter style, external
name, Deterministic/Non Deterministic
Parameters - parameter type (IN, OUT, INOUT), parameter name and parameter data type
SQL or Java source
Privileges - Grantee, Grantee type, privilege, Grantor, with grant option
Procedure options - Specific name, Package ID, data access type, Collection id,
ASUTIME, External Security, Stay Resident, Program Type and Commit on Return
Build options - WLM Environment, Build Utility, Build Owner, Precompile, Compile, Prelink,
Link, and Bind options
Documentation - The text supplied in the Comment on statement for this stored procedure
is displayed here
The fields in the Property Browser are READ-ONLY. To modify an SQL or Java stored
procedure, you need to “Open” the procedure with the Routine Editor, then redeploy it.
Also, the Package and Statistics tabs are not used. To view the package information related to
a specific stored procedure, expand the Packages folder for this schema and select the
associated package ID from the list. The Properties tab is refreshed with the package
information.
674 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 27-16 Data Output view
The Data Output tab contains two panes: the Status History and the Current Output.
When a specific action in the Status History pane is selected, the Current Output pane is
populated with the output details. You can select one of four tabs to view different kinds of
output:
The Messages page of the output section displays the detailed status of each action.
The Parameters page displays the name and values of the parameters after an object is
run.
The Results page displays the results of the action. If an object returns multiple result sets,
you can scroll through the result sets by clicking the arrow at the top right corner of this
page.
Profiling data is only available when the server is DB2 for Linux, UNIX, and Windows.
You can remove an item from the action list by right-clicking the action and clicking Delete or
Delete All.
All three editors share the Editor view. Any object being viewed shows up as a tabbed page in
the Editor view.
Use this editor for viewing and changing the source code and configuration options of a
stored procedure you are working on in the Data Project Explorer. This editor is also launched
when you want to open an existing stored procedure from the Database Explorer.
Figure 27-17 and Figure 27-18 show the contents of the Routine Editor Source and
Configuration tabs.
The Routine Editor’s Source tab is a rich editor that supports cut, copy, paste, find and
replace, menu and keyboard shortcuts, and syntax highlighting. You can change the default
“look and feel” of this page in the Preferences. See 27.4.1, “Starting the IBM Data Studio for
the first time” on page 681.
The Routine Editor’s Configuration tab shows the properties of the stored procedure grouped
similarly as in the Properties tab when a stored procedure is selected from the Database
Explorer.
676 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
After saving your changes, IBM Data Studio replaces the persisted resource corresponding to
this stored procedure in the workspace. However, to replace the object in the server, you
need to deploy or redeploy the stored procedure. Depending on your deploy options, IBM
Data Studio either drops the old routine from the database and creates a routine that reflects
the changes you made, or it alters it. Changes to the source rarely cause the procedure to be
dropped. Where possible, changes to the source code of SQL stored procedures result in an
ALTER command rather than a DROP command.
Finally, the Routine Editor is also used by the Debug Perspective for debugging SQL routines.
Java Editor
The Java Editor is launched from both the Data Perspective and the Java Perspective.
From the Data Perspective, Data Project Explorer, each Java stored procedure has a Java
Source folder. Open this folder and double-click the .java or .sqlj file in this folder.
From the Data Project Explorer:
– Right-click Open on the stored procedure. The stored procedure DDL is displayed in
the Routine Editor view.
– Click the Configuration tab
– Click the .java or .sqlj link at the top of the page (see the box in Figure 27-18).
From the Java Perspective, Project Explorer, open the package or the default package to
the .java or .sqlj file. Double-click this file.
From the Java Perspective, at the end of the New Java Class wizard, the generated Java
class is displayed in the Editor area.
Java routines built by the IBM Data Studio conform to the SQLJ Routines specification. Java
objects are defined in the catalog table with LANGUAGE JAVA and PARAMETER STYLE
JAVA. Java objects must follow these rules:
The method that is mapped to the object must be defined as a public static void method.
The object must receive input parameters as host variables.
Output and InOut parameters must be set up as single element arrays.
When editing your source in the Java editor, your changes are dynamically compiled and
errors reported immediately. When you add arguments to the .java or .sqlj main method, then
save the changes, they are reflected as input parameters in the Parameters section of the
Configuration tab.
As in SQL stored procedures, changes to the source code of Java stored procedures only
change the object in the workspace. To replace the object in the server, redeploy the Java
stored procedure.
To close any object, open it in the Editor, click File Close Object or File Close All, or
click the X next to the procedure name in the Routine Editor.
Export wizard
Use the Export wizard to export routines from your current project to the file system for later
deployment. IBM Data Studio supports exporting an entire project or just the stored
procedures. You may want to export the entire project to the file system, which can then be
imported into another workspace. In this book, we discuss exporting stored procedures only.
You can export a specific stored procedure or several stored procedures at a time. To export
routines using the Export wizard:
1. In the Data Project Explorer, select the Stored Procedures folder right-click Export.
2. In the Selection page, click the checkboxes for the stored procedures you want to export.
You can also click Select All to select all stored procedures in this folder. Click Next.
3. In the Target and Options page, type the filename and directory where the exported script
will be sent. You can optionally click Browse to launch the File browser.
4. Click Next or Finish. The wizard exports the selected routines to the filename and
directory that you specified.
Import wizard
Use the Import wizard to import routines to your project. To open the Import wizard:
1. In the Data Project Explorer, select the Stored Procedures folder. Right-click Import. The
Import wizard is launched.
2. In the Import wizard’s Source page (see Figure 27-19), select the location of the object or
file that you want to import. You can import from the File System or from another Project in
this workspace.
678 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 27-19 Import Wizard
3. Click Browse to select the directory or project that contains the stored procedure. A File
browser is launched. Click OK after selecting the stored procedure.
4. If you are importing an SQL stored procedure, you can optionally set the Statement
terminator used in the imported file. Click Next.
5. The next page shows the “discovered” entry points for this stored procedure. You can
verify whether the imported stored procedure is correct. Click Next.
Note: If there are multiple CREATE PROCEDURE statements in the imported file, only
the first CREATE PROCEDURE statement is processed and imported by IBM Data
Studio.
6. The next page shows the parameters of the imported stored procedure. You can change
the parameter data types of imported Java stored procedures. You cannot change the
parameters of imported SQL stored procedures. Click Next.
7. The next page of the Import wizard allows you to specify import options. You can opt to
replace stored procedures with the same name and parameter signature that already exist
in the project. Click Next or Finish.
Deploy wizard
Use the Deployment wizard to deploy routines to a target database. The target database must
be compatible with the database for which the object was created.
The wizard consists of four steps. First, you select the target database and enter your user ID
and password. Next, you select the routines that you want to deploy. Then, you specify
deployment and error handling options. Finally, a summary shows the deployment options
that you specified in the wizard.
In the next section, 27.5, “Developing stored procedures” on page 688, we build on what
we’ve done here and continue on to creating, building, and executing our stored procedure.
680 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
27.4.1 Starting the IBM Data Studio for the first time
We start IBM Data Studio by selecting Start Programs IBM Software Development
Platform IBM Data Studio IBM Data Studio.
The first time IBM Data Studio is started, a default workspace directory, named workspace, is
created for you in C:\Documents and Settings\Administrator\IBM\rationalsdp7.0. You can click
Browse to launch the File dialog and point to a different directory. The workspace is the main
container for all the resources on which you will work.
The next window that appears is the IBM Data Studio Welcome window. To close the
Welcome window, click the X in the Welcome window title bar.
The new window presented is the Data Perspective, which is the default perspective when the
IBM Data Studio is launched. You can change the perspective by selecting the title bar
Window Open Perspective, and select from the list presented.
Configuring preferences
Each workspace has a set of preferences that is stored in an Eclipse resource. To view the
preferences specific to stored procedures, click Window Preferences Data. Click the
following folders to set specific preferences for:
Output
– Maximum number of rows retrieved and maximum number of bytes to display for
character and binary data.
Stored Procedures and User-Defined Functions Deploy Options
– The JDK level used when generating and compiling Java stored procedures
– The location of the SQLJ translator used for translating SQLJ stored procedures
– Deploy options for Java, External SQL and Native SQL stored procedures
Stored Procedures and User-Defined Functions Process
– Autocommit setting
– Save files after build
– Set Tracing on
Run/Debug DB2 Stored Procedure Debugger
– Session manager information for the Unified Debugger. See 28.2, “The Unified
Debugger” on page 738.
We will leave the default values for all of the above preferences for now.
For this exercise, we connect to the DB9A subsystem. The DDF information for this
subsystem is shown in Figure 27-23.
The first page of the wizard contains two tabs, the Driver Options and the Tracing Options.
682 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Driver options
The driver options set the properties of the JDBC driver you wish to use to connect to the
server. IBM Data Studio is delivered with a version of the IBM Data Server driver for JDBC
and SQLJ4 in <Install directory>/plugins/com.ibm.datatools.db2_<some version>\driver. The
driver and license files are db2jcc.jar and db2jcc_license_cisuz.jar.
The fields in the first page of the wizard allow you to enter the following information:
Connection name - default is the location name.
JDBC driver - default is IBM Universal Driver. IBM strongly recommends using this driver.
This driver uses the Server authentication. From the pull-down list, you can change the
driver to:
– IBM Data Server driver for JDBC and SQLJ with Kerberos security, or
– IBM Data Server driver for JDBC and SQLJ using LDAP, or
– Other
If you choose Other, you will need to provide the JDBC driver class name, class location,
and Connection URL.
Location - enter the DB2 for z/OS location ID.
Host - enter the domain or FTP address of your DB2 for z/OS server.
Port number - enter the port number of your DB2 for z/OS server.
JDBC driver class - when using the IBM Universal driver, this is pre-filled with the value
com.ibm.db2.jcc.DB2Driver.
Class location - when using the IBM Universal driver, this is pre-filled with the location of
the license jar files installed with your IBM Data Studio.
Retrieve objects created by this user only - check this box if you want to work only with
objects that you created.
Connection URL - IBM Data Studio composes this as you enter values for the location,
host, and port number. It additionally adds some default JDBC properties.
User ID - enter your DB2 for z/OS login authorization ID.
Password - enter the password associated with the above user ID.
The Test Connection button allows you to test the connection using the fields you entered.
Tracing options
The JDBC tracing options can be set in the connection URL by selecting the trace levels in
this tab of the New Connection wizard. For more information on tracing levels and other
problem determination tools for IBM Data Studio, check:
http://www.ibm.com/developerworks/db2/library/techarticle/dm-0706scanlon/
The second page of the wizard allows you to filter the schemas that will be loaded into the
connection. IBM Data Studio performs on-demand loading. The objects are loaded from the
catalog only when the object folder is opened (double-clicking the folder).
Filter connection
The next page of the New Connection wizard allows you to filter the schemas that will be
loaded into your connection. You can filter using a Where clause-like expression or select
from a list. Figure 27-9 on page 669 shows the filter page.
When you upgrade Data Studio to a new release, or when migrating from Developer
Workbench to Data Studio, the connection properties from your workspace may need to be
updated to use the Universal license jars in the new release. A typical error that you may get
when connecting is:
Edit the connection properties and point the JDBC driver class location to the new install
directory’s driver folder.
684 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Target connection - The wizard’s second page lists all the active connections available.
The user can opt to create a new connection. The New Connection wizard will be
launched.
Package Owner - Enter a valid primary or secondary authorization ID as the package
owner. If blank, the current login ID is used.
Build Owner - Enter a valid primary or secondary authorization ID as the owner of the
stored procedure created. This is the value in the OWNER column in SYSROUTINES. If
blank, the current ID is used.
Clicking Finish in the wizard creates a data development project. Figure 27-12 on page 672
shows you the folders contained in a data development project.
IBM Data Studio provides you with three tools for developing SQL statements:
SQL Builder - This is a graphical builder used for creating SELECT, INSERT, UPDATE,
DELETE, Full SELECT and WITH statements.
Enhanced SQL Editor - This is a rich text editor that can handle both DML and DDL
statements. It has colorization and content assist capabilities.
SQL Wizard - This is embedded in the New SQL Procedure wizard and is similar to SQL
Assist in Development Center.
The SQL Builder populates the Editor view with three panes: the SQL statement view, as is
shown in Figure 27-26.
686 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
To build the illustrated statement in the SQL Builder, do the following:
Right-click the graphical view (middle pane) Add table. Expand the DEVL7083 schema
and select the table PURCHASEORDER. Add the table CUSTOMER in the same manner.
This adds the selected tables to the FROM clause of the statement.
Still in the graphical view, click CUSTID in table PURCHASEORDER and drag to CID in
table CUSTOMER. This creates an inner join between the two tables. You can right-click
the join line and select Specify the join type to select another type of join, such as a left
outer join.
Click the check boxes for POID, STATUS, CUSTID, ORDERDATE, PORDER and
COMMENTS in table PURCHASEORDER. This adds those columns to the SELECT
clause of the statement.
Click the check boxes for INFO and HISTORY in table CUSTOMER.
Click the Conditions tab. Click the first cell, and a pull-down arrow is displayed. Scroll
down the list and select PURCHASEORDER.STATUS.
Click the Value column and type :V-STATUS. This creates a variable in the statement.
When you run the query, you will be prompted to provide a value for this variable.
Click Save.
In IBM Data Studio, you can also use or create code templates. This allows you to skip typing
parts of an SQL statement and tab into input fields within the templates. An example of a
template is shown in Figure 27-27 on page 688.
You can create your own template in the Preferences of IBM Data Studio. In the menu bar,
click Window Preferences Data SQL Editor Templates.
Whether you use the SQL Builder or the SQL Editor, your created scripts will be saved in the
SQL Scripts folder.
688 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
So, in this section, we discuss:
1. Creating a new native stored procedure using the wizard
– Use the new stored procedure wizard
– Use the new version wizard
– Use the Import wizard
– Create a stored procedure from an SQL script
2. Creating an external SQL stored procedure from the wizard
– Creating an SQL stored procedure on DB2 for z/OS V8 for debugging
3. Creating a Java stored procedure from the wizard
– JDBC
– SQLJ
4. Importing an SQL stored procedure
5. Importing a Java stored procedure
– JDBC
– SQLJ
6. Deploying a stored procedure
– Deploy to the current or a different server
– Duplicate and error handling options
– Deploying nested or dependent stored procedures
– Setting the JDK level for Java stored procedures
– Setting the bind options
– Setting SQLJ options
– Enabling debug
7. Executing a stored procedure
– Run the Settings dialog
– Output view status and messages
– Result sets
The pages of the wizard allow you to specify properties that are either common or specific to
a new Native SQL, External SQL, dynamic Java, or static Java stored procedure. In this
section, we start with creating a new native stored procedure. We will investigate the
differences for external SQL and Java stored procedures in later sections.
Note: IBM Data Studio accepts upper and lower case schema.procname. However,
when the SQL or Java stored procedure is built, both schema and procname are
converted to uppercase in the DB2 catalog on z/OS. To enter lowercase, enclose the
name in quotation marks, for example “MyProc”.
Note: In DB2 for z/OS, the default version for native SQL procedures is V1.
Language - This field is initially set to SQL - Native. Click the pull-down list to change to
SQL - External or Java. When the language is set to Java, the Java options box is enabled.
We will discuss Java options in 27.5.3, “Creating a Java stored procedure from the wizard”
on page 696.
Click Next.
SQL statements
A default SQL statement for testing setup is included in the SQL statement on the SQL
Statements page. The statement is SELECT SCHEMA, NAME FROM SYSIBM.SYSROUTINES (see
Figure 27-29 on page 691). We will use the default settings on this page. However, we
discuss each of the UI elements below.
690 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 27-29 SQL Statements page
Result set allows you to specify whether the stored procedure returns One, Multiple, or no
(None) result sets.
Note: If you have multiple queries and specify only One result set, the tooling will
generate a Case statement with each statement being a case. An input variable,
whichQuery, is also generated to determine which case/query will be executed.
Create SQL will launch the SQL wizard. This is discussed further in 27.4.4, “Creating SQL
statements to use in your stored procedure” on page 685.
Validate will cause the current statement in the Statement details text box to be parsed
and validated for syntax errors.
Actual Cost will call the DB2-supplied stored procedure DSNWPSM and return a cost
value for executing the statement.
Note: You need to set up this support in DB2 for z/OS beforehand. See 27.2.5, “IBM
Data Studio Actual Costs setup” on page 659.
Visual Explain (V8 only) - This launches the Visual Explain for DB2 for z/OS V8 tool. A
graphical display of the access path is shown in a separate dialog. This product is a
separate install. The first time you click Visual Explain, you will be asked if you want to
download this product from the Web.
Parameters
In this page, you can:
Specify the following errors:
– SQL Exception
Note: DB2 for z/OS V9 does not support passing parameters of XML data types.
Deploy options
In this page, we specify the options for deploying and/or debugging the stored procedure.
Deploy On Finish - Leave this unchecked. We want to deploy the stored procedure after
we examine the generated stored procedure code.
Current Schema - This is enabled and initialized with either the login authorization ID or
the Project properties’ current schema setting. See 27.7.5, “Behavior when setting the
Current Schema project property” on page 717 for more information on this.
Enable Debugging - This checkbox triggers building the stored procedure for debug.
Check this to debug this stored procedure later on. For native SQL stored procedures, the
keywords ALLOW DEBUG MODE and WLM ENVIRONMENT are generated in the
CREATE PROCEDURE DDL. The default WLM used is whatever is specified in the
Preferences (see “Configuring preferences” on page 681).
Advanced - This launches the z/OS Options dialog. For native SQL stored procedures,
this is shown in Figure 27-31 on page 693.
692 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 27-31 Deploy options page and z/OS Options dialog
Since native SQL stored procedures do not need a WLM environment unless it is enabled
for debug, the Advanced button in the Deploy Options page has the WLM Environment
field disabled.
Note: Although native SQL stored procedures do not require you to specify a WLM
environment, you still need to specify a default WLM Environment in your DSNZPARM.
Procedure Options - You can optionally update or add procedure options from the
Advanced dialog.
Code fragments
Like Development Center (DC), IBM Data Studio gives you the ability to import code
fragments into your stored procedure. In DC, you could only import one file at a time. IBM
Data Studio allows you to import multiple code fragments. The code is concatenated before
inserting into the appropriate area of the stored procedure. In 27.5.3, “Creating a Java stored
procedure from the wizard” on page 696, we will see how to insert code fragments into a Java
stored procedure.
Summary
This page (shown in Figure 27-32) summarizes our SQL stored procedure. Optionally, we can
view the SQL procedure definition by clicking Show SQL.
In Data Project Explorer, expand Project_7083, right-click the Stored Procedures folder and
then select New Stored Procedure. This launches the New Stored Procedure wizard.
In the Name and Language page (see Figure 27-28 on page 690), do the following:
– Type EXTSQLSP.
– Select SQL - External as Language.
– Note that Version is grayed out.
– Click Next.
Click Next two more times until you get to the Deploy Options page.
Click Advanced. The z/OS Options dialog is launched. This dialog contains two tabs (see
Figure 27-33 on page 695 and Figure 27-34 on page 696). In our case study, we kept the
default values in this dialog, except for the WLM environment.
Since this dialog contains additional fields when compared to a native SQL stored
procedure, we examine it further.
In the Stored Procedure Options tab, we do the following:
– Runtime options - Leave the default value NOTEST(NONE,*,*,*).
– WLM Environment - This is required for external SQL stored procedures. Type
DB9AWLM.
– ASU time limit - Leave the default as 0.
694 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
– Stay Resident - Do not check this checkbox. Checking this checkbox generates the
keyword STAY RESIDENT YES. The default is STAY RESIDENT NO.
– External Security - The radio button DB2 is pre-selected and is the default.
In the Deploy Options tab, we use all default settings. If you like, you can specify the
following:
– Build Utility - This defaults to the value in the Preferences page.
– Build Owner - Specify the authorization ID that will be the owner / definer of this
external SQL stored procedure. See 27.7.6, “Package owner and Build owner” on
page 717 for more information on this field.
– Precompile options - This defaults to MAR(1,80).
– Compile options - This defaults to NOTEST(block,noline,nopath).
– Prelink options - Specify any prelink options, default is blank.
– Link options -Specify any prelink options, default is blank.
– Bind options - The bind options are specified in two parts. The PACKAGE area is
read-only and defaults to PACKAGE(collid) where collid is the Collection ID specified in
the Deploy Options preference page.
The wizard will guide you through the following pages to create the Java stored procedure.
696 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 27-35 New Java stored procedure (SQLJ)
SQL statements
A default SQL Statement for testing is generated in the SQL statement details text box. The
statement is SELECT SCHEMA, NAME FROM SYSIBM.SYSROUTINES. See “SQL statements” on
page 690 for more information about this page.
Parameters
In the SQL Error Handling code: select the SQLState, SQLCode and SQLMessage from the
pull-down list. This generates three output parameters, as shown in Figure 27-36.
Click Next.
Deploy options
The Java stored procedure deploy options differ slightly from SQL stored procedures, as
shown in Figure 27-37 on page 698.
The Jar ID is automatically filled in with the name of the stored procedure. We override it
by typing DEVL7083.JAVATEST in our schemaname.procname.
We can automatically deploy this stored procedure after clicking Finish. We will deploy
later, so leave the Deploy on Finish button unchecked.
Check Enable Debugging to enable debugging on this stored procedure.
The Collection ID that is specified must include the JDBC drivers on z/OS. The JDBC
drivers are bound into DSNJDBC. For JDBC stored procedures, this defaults to DSNJDBC.
For SQLJ stored procedures, we can change this to a collection ID that is bound to the
JDBC drivers. We will use the default value, DSNJDBC.
Click Advanced. This displays the Z/OS Options dialog.
Since we updated our default WLM environment for executing Java stored procedures to
point to our DB9A WLM AE, DB9AWLMJ, we do not have to make changes to the Stored
Procedure Options tab.
Click the Deploy Options tab.
Check the Enable Debugging checkbox. The -g compile option is automatically added.
IBM Data Studio generates a default root package name. Change the default value to
SQLJTST. DB2 will generate four packages for the stored procedure, where the package
name is the root package + 1, 2, 3, and 4. See Figure 27-38.
Figure 27-38 SQLJ stored procedure root package and compile options
698 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Note: In DB2 for z/OS V8 and V9, you can generate single packages by specifying the
ISOLATION LEVEL in the Bind Options. In DB2 for z/OS V9, you can also specify a
package name greater than 7 characters.
Java Path
You can specify additional jar files that your stored procedure will use. We will discuss this in
more detail in 27.7, “Advanced IBM Data Studio topics” on page 710.
Code fragments
To include the sample code fragments, launch the file browser for each of the code fragments
shown in Figure 27-39.
Header fragments - Include any file with additional header statements you want included
in this stored procedure. This file is placed before the package statement.
Import fragments - Include any file with additional import statements you want included in
this stored procedure. This file is placed after any generated import statements.
Data fragments - Include any file with data definitions you want included in this stored
procedure. This file is placed after the Public class statement
Method fragments - Include any file with additional methods you want included in this
stored procedure. This file is included at the end of the generated code.
Note: The multi-file code fragments support is in Fix Pack 1 of IBM Data Studio.
Summary
This page summarizes our Java stored procedure. The generated code for this example is
shown in Example 27-10.
/**
* SQLJ Stored Procedure JAVATEST
* @param SQLSTATE_OUT
* @param SQLCODE_OUT
* @param SQLMessage_OUT
*/
/**
* Header fragment inserted from SP_JAVA_HDR.FRAGMENT
*/
package marichu;
/**
* Methods fragment inserted from SP_JAVA_MTHD.FRAGMENT
*/
}
700 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
27.5.4 Importing an SQL stored procedure
Importing an SQL stored procedure is similar to importing a Java stored procedure. See
27.5.5, “Importing a Java stored procedure” on page 703 for details on using this wizard.
When importing an SQL stored procedure from the file system to a project that is targeting a
DB2 V9 for z/OS, if the imported DDL does not contain the FENCED or EXTERNAL keyword, IBM
Data Studio constructs the imported SQL stored procedure as a Native SQL stored
procedure.
Right-click the Stored Procedures folder and then select Import to launch the Import wizard.
Source
– In the Sourcefile Location area (see Figure 27-40 on page 701), click Browse to the
right of the Name field to locate the source EMPDTLSS.ddl that we had previously
saved on our workstation.
– Click Open to import this file.
– Click Next.
Entry Points
– The EMPDTLSS entry point is the CREATE PROCEDURE itself. See Figure 27-41 on
page 702.
– Click Next.
Parameters
– On this page, one input parameter and seven output parameters are listed, as shown in
Figure 27-42.
– Click Next.
702 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Summary
– The summary page summarizes the above settings. Click Show SQL to view the DDL.
– Click Finish.
Right-click the Stored Procedures folder and then select Import to launch the Import wizard.
The Import wizard includes the following four pages for importing a stored procedure. It
parses the imported source to complete the pages when possible:
Source
On this page, you have the option to import from an existing project or the file system. We
will import from the file system. Click Browse at the right of the Name field to locate the
source EmpDtlsJ.java that we had previously saved on our workstation.
Entry Points
On the IBM Data Studio page, any methods or routines that are included in this stored
procedure are listed by the wizard to be used to select the main entry point. The EmpDtlsJ
stored procedure has one method only. IBM Data Studio selects that static method.
Parameters
On this page, one input parameter and seven output parameters are listed.
Stored Procedure Name
The stored procedure name, GetEmpDtls, shows on this page.
Options
On the Options page, type DEVL7083.EMPDTLSJ for the JAR ID, and DEVL7083 for the
Collection ID. The collection ID we choose needs to include the DSNJDBCx drivers. Leave
unchecked the radio buttons to Replace duplicate routines in the Project, Deploy and
Enable Debugging. Next, we select Advanced on this page, which launches the z/OS
Options page. Type DB9AWLMJ for the WLM environment name and click OK.
Summary
The summary page summarizes the above settings. Optionally, we can view the DDL for
the procedure definition for the DB2 catalog by clicking Show SQL.
Click Finish to generate the artifacts for the imported Java stored procedure. The Java
stored procedure DDL is displayed in the Editor view. Note that, when the server is DB2 for
z/OS, the stored procedure name, GetEmplDtls, is changed to all uppercase.
So, let’s deploy the stored procedure, GetEmplDtls, that we imported in 27.5.5, “Importing a
Java stored procedure” on page 703. Right-click GetEmpDtls and then select Deploy. The
Deploy wizard is launched, as shown in Figure 27-44 on page 705.
704 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 27-44 Deploy wizard, Deploy Options
Deploy options
Select Use current database as the Target connection.
Since this stored procedure is unqualified, we can specify the schema for this routine.
Select DEVL7083 from the pull-down list. Default is the login ID.
Use defaults for all other options. Deploy options are discussed in the 27.6.3, “Duplicate
and error handling options” on page 706.
Routine options
For Java stored procedures, you will have three tabs for this page. In the Routine Options
tab, the default WLM environment we set in the Preferences, DB9AWLMJ, is used.
In the Deploy Options tab, you can do the following:
– Click the Enable debugging checkbox to enable debug for this deploy. The compile
option -g is automatically generated. See Figure 27-38 on page 698.
– Use a different JDK level for the client by clicking Browse for the JDK home and
pointing the file browser to the directory of your JDK.
– Specify the JRE level at the server5. See Figure 27-45 on page 706 for an illustration of
how to specify the JDK and JRE levels.
– Add additional bind options in the space to the right of the PACKAGE field. Click the
ellipsis to display a text box for typing in your bind options.
– Display all messages generated during the deploy process by clicking Verbose build.
– In the Java Path tab, you can add jars from other projects to resolve references in your
stored procedure.
5 You need to supply the exact version number of the server JRE.
Summary
This page summarizes the options you specified in the wizard.
Click Finish to close the Deploy wizard. The Data Output view will be refreshed with the
status and progress of the deploy.
706 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
– Stop on errors
– Ignore errors and continue to the next routine7
In our case study, we compiled our Java stored procedure with JDK 1.5. If we deployed this
stored procedure to a DB2 for z/OS V8 server that supports a lower level version of the JDK
(for example, JDK 1.4.2), then executing this Java stored procedure compiled will fail with the
following error message:
17.38.36 STC00108 DSNX961I DSNX9WLJ ATTEMPT TO PERFORM OPERATION
- FindClass
- FAILED FOR ROUTINE . . SSN= V91A PROC= V91AWMJU ASID= 003A
- CLASS= METHOD= ERROR INFO= java.lang.NoClassDefFoundError:
- com/ibm/db2/jcc/DB2Driver
You can change the JDK level by changing the location of the JDK Home setting in the client.
You can set this for all projects, for a project or for a specific stored procedure.
Workspace scope: Go to Window Preferences Data Stored Procedures &
User-Defined Functions Deploy options.
Project scope: Right-click the project, then select Properties Routine Development.
Stored procedure scope: In the Deploy Options Advanced page of the New Stored
Procedure wizard, or in the Routine Options Deploy Options tab of the Deploy
wizard.
6
When launched from the Stored Procedures folder, the Deploy wizard allows you to select multiple stored
procedures from the folder. When a stored procedure of the same name exists on the server, this option instructs
Data Studio to ignore deployment of this stored procedure. Data Studio continues to process and deploy the other
stored procedures in the list. The default is to terminate when a duplicate is found.
7
When deploying a stored procedure from a list, if the stored procedure has errors (e.g. missing objects), then this
option instructs Data Studio to ignore these errors, and continue deploying the other stored procedures in the list.
Enabling debug
Refer to 28.2, “The Unified Debugger” on page 738 on how to enable debug using the Unified
Debugger.
708 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
27.6.6 Executing a stored procedure
After you’ve deployed your stored procedure, you can execute it from the following areas:
Database Explorer a specific stored procedure
Data Project Explorer a specific stored procedure
Routine Editor Configurations page (see Figure 27-43 on page 704)
If there are any input parameters in your stored procedure, the Specify Parameter Values
dialog is launched, as shown in Figure 27-49.
Note that the tooling can recognize that a string was entered even though single quotes were
not entered. However, double quotes are preserved in the input value. To enter FOR BIT
DATA, type an X in front of a quoted value. For example: X’F1F2F3’.
So, for example, to execute the stored procedure we imported and deployed in 27.5.5,
“Importing a Java stored procedure” on page 703, from the Data Project Explorer, right-click
GetEmpDtls and then select Run Settings.
For Java stored procedures, the Java source can be viewed from the Configuration tab. So to
view the Java source for our imported stored procedure, in Figure 27-43 on page 704, click
EmpDtls.java. The source will display in another tab in the Editor view. To view the DDL again,
click the GETEMPLDTLS tab in the Editor View and then the Source tab of this view.
710 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Edit Java source
The source of a Java stored procedure is displayed in a Java editor, which includes features
such as:
Syntax highlighting and checking
Content or code assist
Code formatting
Import assistance
Quick fix
When referring to methods or classes that are in other jar files, you need to add these jar files
in the Build Path.
To add parameters to a Java stored procedure, edit the source and add the new parameter in
the method signature. So, for example in our test stored procedure, JAVATEST, add
java.lang.String tableName in the signature, as shown in Example 27-11.
As in SQL stored procedures, you will see the new parameters in the Parameters section of
the Configuration tab in the Routine Editor, as shown in Figure 27-51.
Note: In the file browser launched for selecting the code fragments, you can select more
than one file. Use Ctrl + Click to multi-select files.
712 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 27-52 Generate multiple SQL statements
If you set the Result set to One instead of Multiple, a CASE statement is generated in the
code, as shown in Example 27-12.
Example 27-12 Java stored procedure with multiple SQL statements and one result set.
/**
* JDBC Stored Procedure JDBC_MRS
* @param whichQuery
*/
/**
* Header fragment inserted from SP_JAVA_HDR.FRAGMENT
*/
package marichu;
/**
* Imports fragment inserted from SP_JAVA_IMPORT.FRAGMENT
*/
switch (whichQuery) {
case 0:
sql = "SELECT WORKDEPT, EMPNO" + " FROM DEVL7083.EMP"
+ " GROUP BY WORKDEPT, EMPNO" + " ORDER BY WORKDEPT";
stmt = con.prepareStatement(sql);
break;
case 1:
sql = "SELECT D.DEPTNO, D.DEPTNAME, E.LASTNAME, E.FIRSTNME, E.EMPNO"
+ " FROM DEVL7083.EMP AS E, DEVL7083.DEPT AS D"
+ " WHERE E.WORKDEPT = D.DEPTNO" + " ORDER BY D.DEPTNO";
stmt = con.prepareStatement(sql);
break;
case 2:
sql = "SELECT DEVL7083.DEPT.MGRNO, DEVL7083.EMP.LASTNAME, DEVL7083.EMP.FIRSTNME"
+ " FROM DEVL7083.EMP, DEVL7083.DEPT"
+ " WHERE DEVL7083.EMP.EMPNO = DEVL7083.DEPT.MGRNO";
stmt = con.prepareStatement(sql);
break;
default:
sql = "SELECT SCHEMA, NAME FROM SYSIBM.SYSROUTINES";
stmt = con.prepareStatement(sql);
}
bFlag = stmt.execute();
rs1[0] = stmt.getResultSet();
}
/**
* Methods fragment inserted from SP_JAVA_MTHD.FRAGMENT
*/
}
If, instead, we specify Multiple in the Result set option, multiple cursors are left open, as seen
in Example 27-13.
Example 27-13 SQL stored procedure with multiple SQL statements and multiple result sets
714 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
SELECT DEVL7083.DEPT.MGRNO, DEVL7083.EMP.LASTNAME, DEVL7083.EMP.FIRSTNME
FROM DEVL7083.EMP, DEVL7083.DEPT
WHERE DEVL7083.EMP.EMPNO = DEVL7083.DEPT.MGRNO;
After the copy, you need to modify the stored procedure and deploy it against the new server.
Note that syntax differences may exist between source and target servers. Table 27-10 on
page 706 shows you the valid combinations of source and target servers that IBM Data
Studio supports.
716 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
27.7.5 Behavior when setting the Current Schema project property
The CURRENT SCHEMA value can be predefined in the project’s Properties. This setting will
be used as the default target schema when a stored procedure is deployed without a fully
qualified name.
Prior to DB2 for z/OS V8 NFM, there was no CURRENT SCHEMA special register. The
schema of an unqualified routine was determined by the value in the CURRENT SQLID
special register if the routine is created via a dynamic statement. Thus, if a project is
connected to a DB2 for z/OS V8 CM or earlier, the CURRENT SCHEMA in the project’s
Properties must be set to a valid authorization ID. In addition, the connection login ID must be
able to issue the SET CURRENT SQLID to this CURRENT SCHEMA value. If the connection
ID has SYSADM authority, there is no restriction on the CURRENT SCHEMA value.
DB2 for z/OS V8 NFM introduced a new special register, CURRENT SCHEMA. This special
register is dedicated to resolving the schema when referencing an unqualified data object. For
projects connected to DB2 for z/OS V8 NFM or later, the CURRENT SCHEMA setting in the
project Properties has no restriction and can be any legitimate schema the user has
CREATEIN privilege on.
Table 27-11 summarizes the behavior of setting the current schema in the project's Properties
when:
The connection login ID is PAOLOR5.
The CURRENT SQLID is also set to PAOLOR5.
DEVL7083 is a valid authorization ID.
PAOLOR5 has the authority to SET CURRENT SQLID to DEVL7083.
See 7.5.7, “Resolution of unqualified stored procedure names at create time” on page 79 for
more information about using the CURRENT SCHEMA on DB2 for z/OS outside IBM Data
Studio.
When the Build Owner field is set in the project Properties, the routine deployment will use
this Build owner's authority instead of the connection login ID's. Basically, the CURRENT
SQLID will be set to the value of Build Owner before the deployment starts. Therefore, the
connection login ID must be able to issue SET CURRENT SQLID to this Build owner. Binary
deployment is a special case; it cannot use the Build owner's authorization. In this scenario,
the connection login ID itself must have proper privilege to create the stored procedure in the
remote target server.
You can export native SQL, external SQL, and Java stored procedures. Note, however, that to
deploy native SQL stored procedures to another DB2 for z/OS V9 server outside of Data
Studio, requires either a DB2 Connect or a DB2 on LUW database system running on the
client issuing the deploy.
718 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Click Next. In the Target and Location page, type ITSO_Project for the File name, and
C:\Export for the Directory.
Click the Include DROP statements checkbox. See Figure 27-56 for the completed page.
Click Finish.
Verify that the Export is successful for each stored procedure in the Output view. So in our
example, we exported four stored procedures. The Output view in Figure 27-57 shows four
entries, all of which are successful.
Before deploying the stored procedures, ensure that your client’s JAVA_HOME environment
variable is pointing to a JDK level that is compatible with the JDK level at the server. The
generated ant.bat file uses the JAVA_HOME setting when launching ant.
init:
builddeploySps:
[createsp] Debug options:
[createsp] file:/C:/Export/.options loaded
[createsp] Could not connect to the target database.
[createsp] [ibm][db2][jcc][t4][2013][11249] Connection authorization failure occurred.
Reason: User ID or Password invalid.
BUILD SUCCESSFUL
Total time: 3 seconds
720 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Run ant.bat to execute the script. Type ant -buildfile ITSO_Project_java.xml.
Excerpts from the output of the ant deploy of Java stored procedures are shown in
Example 27-15.
init:
builddeploySps:
[createsp] Debug options:
[createsp] file:/C:/Export/.options loaded
[createsp] DEVL7083.SQLJTEST - Deploy started.
[createsp] DEVL7083.SQLJTEST - Created temporary working directory
C:\Export\bld1196747605594.
[createsp] DEVL7083.SQLJTEST - Translating the SQLJ source file
C:\Export\bld1196747605594\marichu\SQLJTEST.sqlj using
[createsp] SQLJ translator class: sqlj.tools.Sqlj
[createsp] SQLJ translator location: C:\SQLLIB\java\sqlj.zip;C:\Program...
[createsp] DEVL7083.SQLJTEST - SQLJ translation completed.
[createsp] C:\IBM_JDK15\bin\javac -classpath ".;C:\SQLLIB\java\sqlj.zip;C:\Program...
[createsp] DEVL7083.SQLJTEST - Javac completed.
[createsp] DEVL7083.SQLJTEST - Class file updated.
[createsp] C:\IBM_JDK15\bin\javaw -cp ".\;C:\Program... C:\Export\bld1196747605594"
com.ibm.db2.jcc.sqlj.Customizer -url jdbc:db2://wtsc63.itso.ibm.com:12347/DB9A -collection
DSNJDBC -qualifier PAOLOR4 -user PAOLOR4 -password xxxxxxxx -bindoptions "QUALIFIER
PAOLOR4" -rootPkgName S928288 marichu\SQLJTEST_SJProfile0.ser
BUILD SUCCESSFUL
Total time: 24 seconds
The IBM Data Studio’s Deploy wizard can be used to deploy using binaries—SQL or Java
stored procedures between source and target servers on the same platform.
722 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Right-click the stored procedure and then click Deploy.
In the Deploy Wizard, change the Target connection to “Use Different Database”. Select
your target database from the pull-down list, or create a new connection to this database
(see 27.4.2, “Creating a connection” on page 682).
If the stored procedure is unqualified, select the schema name to be used for this stored
procedure.
Set your duplicate and error handling options.
Click the checkbox Deploy using binaries, if available in the database.
The Target Load Library will be enabled. Specify a PDS file to receive the compiled SQL
module in the target database.
Click Next to change the deploy and routine options, as discussed in 27.6, “Deploying a
stored procedure” on page 703.
Click Finish to complete the deploy.
In addition to deploying the binaries, you may want to set up the same authorizations in the
target server. To do this, do the following:
In the Database Explorer, right-click the stored procedure you just deployed and then
select Generate DDL.
In the Options page, click Deselect All Next.
In the Objects page, select Privileges and Stored Procedures Next.
724 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Click Next to change the deploy and routine options, as discussed in 27.6, “Deploying a
stored procedure” on page 703.
Click Finish to complete the deploy.
The steps to deploy Java stored procedures using binaries are the same as those followed for
native SQL stored procedures.
For more information on package variation, see the article, “Create package variations for
z/OS DB2 stored procedures” on developerWorks® at:
http://www.ibm.com/developerworks/db2/library/techarticle/dm-0608parmeshwar/
Note: If the user did not specify a Package ID, the tooling generates a Package ID with a
value of “SQL” + a randomly generated number. After deploying the stored procedure, you
can browse the deployed stored procedure’s properties in the Database Explorer using the
Property browser. The generated Package ID is in the Options tab of the stored
procedure’s Properties View. You can also browse the package variation properties in the
same manner.
IBM Data Studio associates an installed jar file with a Java path and allows the user to specify
this Java path.
In the additional materials for this book, we provide two Java stored procedures,
EmpDtlsMJ.java and Getters_staff.jar. We use these to illustrate how to add supporting jars to
your DB2 stored procedure.
726 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
6. Figure 27-61 on page 727 shows the completed page. Click Finish.
Data Studio creates a dependency on the added jar file and reports this in the Routine
Editor’s Configuration tab Files section, as shown in Figure 27-63.
Figure 27-63 Routine Editor Configuration tab Files shows supporting jars
728 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
At this point, you will notice that there are no compilation errors in your Java stored
procedure. The calls to methods in the Getters_staff class are resolved.
In the above example, we created the jar by importing it from the file system. This created an
entry in the Jars folder of the project. You can also add previously deployed jars by dragging
and dropping them from the Database Explorer.
This feature is not automatically installed in IBM Data Studio. Select this feature when
installing IBM Data Studio as shown in Figure 27-64. If you already have IBM Data Studio
installed, use the IBM Installation Manager to Modify Packages, and add this feature.
In the next page, click the ellipsis for Select a project to migrate.
Using the File browser, point to the .dcp file you want to migrate. The input DC project
must be a .dcp file. Click Open.
Once the project is loaded, all DC project connections are listed, as shown in
Figure 27-66.
DC projects allowed multiple connections; Data Studio projects only have one connection.
In the Select one of the project connections: list box, select a connection. Click Next.
In the Data Development Project page, you can leave the old DC project name or rename
the project. You can also set the project’s CURRENT SCHEMA. Click Next.
In the Select Connection page, you can select an existing connection or create a new
connection (see Figure 27-67 on page 731). Data Studio will attempt to match the
selected connection to existing connections in the Database Explorer. Click Next.
In the next page, you can add a default Package Owner and Build Owner for routines in
this new project.
730 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 27-67 Migrate DC projects, select connection
Here we show how to add the EMPDTLSJ stored procedure to a Web service.
In the Data Explorer PROJECT_7083, right-click the Web Services folder and then
select New Web Service, as shown in Figure 27-68.
The New Web Service dialog is displayed, as in Figure 27-69. Type WebService7083 for
the Name. We will use the default URI for this Web service. Click Finish.
Now let’s add a stored procedure to this Web service. Right-click the EMPDTLS stored
procedure and then select Add to Web Service (see Figure 27-70).
In the Add Operation to Web Services page, select WebService7083 on the left panel.
Click >. The Web service is moved to the right panel, as shown in Figure 27-71 on
page 733. Click Next.
732 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 27-71 Select the Web Service to add this stored procedure to
In the Name and Operator page, the name and operation are prefilled with the stored
procedure’s name and a generated CALL to the stored procedure. Click Next.
Data Studio can generate detailed or generic XML schemas for stored procedures that
accept non-varying input values and return result sets that are always the same. To make
the XML schema as detailed as possible, Data Studio needs to know the structure of
these unchanging result sets. This information is obtained by running the stored procedure
and capturing the input and result set information. The XML schema is generated from this
run.
In the Generate XML Schema for Stored Procedure page shown in Figure 27-72 on
page 733, click Generate.
The Run Settings dialog is launched. Type 000100 in the Value column for EMPNO.Click
Finish.
Now, right-click the Web service, WebService7083 and select Build and Deploy. This
launches the Deploy a Web Service dialog shown in Figure 27-73 on page 734. You can
specify the deploy options you want in this page.
Data Studio generates the Web service runtime files such as the WebSphere Definition
Language (WSDL) file. The project folder is refreshed and the WSDL is added in the XML
folder, as shown in Figure 27-74.
734 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
28
COBOL, PL/I, C/C++ All supported Optional GUI: DB2 for z/OS V8 and
DB2 releases -IBM Rational Developer v7, V9
(RDz) for System z IBM Debug Tool
-IBM Visual Age for Cobol
-C/C++ Productivity Tools for
z/OS
SQL - external DB2 V8 and V9 Unified Debugger in IBM Data DB2 V8 and V9
Studio;
Unified Debugger in DSNTPSMP set up
Developer Workbench (DWB) including all
SQL Debugger in prerequisites (C
Development Center (DC) compiler, WLM, RRS,
V8.2 REXX)
member DSNTIJSD
from DSN810 /
DSN8910.SDSNSAMP
VisualAge COBOL
If you have VisualAge COBOL installed on your workstation and the Debug Tool installed on
your z/OS system, you can use the VisualAge COBOL Edit/Compile/Debug component with
736 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
the Debug Tool to debug COBOL stored procedures that run in a WLM-established stored
procedures address space and have been prepared for debug.
For more information on debugging COBOL/C/C++ stored procedures using the above
products, see DB2 V9.1 for z/OS, Application Programming and SQL Guide, SC18-9841-01.
DSNTPSMP
DSNTPSMP is the DB2 SQL Procedure processor that builds SQL stored procedures on DB2
for z/OS V8 (see 27.2.8, “Overview of routine development with IBM Data Studio” on
page 663 for details).
Unified Debugger
The Unified Debugger is a single debugger that can be used to debug SQL and Java stored
procedures on DB2 for z/OS, DB2 on iSeries and DB2 on Linux, UNIX and Windows. It is
included in IBM Data Studio and Developer Workbench (DWB) products. See the IBM Data
Studio or DWB online help for assistance in debugging SQL and Java stored procedures.
While this book focuses on DB2 for z/OS stored procedures, many customers prototype their
applications on DB2 for Windows or UNIX, including stored procedure development. The
distributed platforms provide some additional options for debugging Java and SQL stored
procedures. The IBM Data Studio assists in developing cross-platform SQL, and Java stored
procedures. When comparable, DB2 for z/OS DDL and stored procedure code can be defined
on DB2 for Windows and UNIX; first-level development, testing, and debugging can be
performed in the distributed environment. Table 28-2 summarizes the DB2 debugging options
for the distributed platforms.
DB2 9 for LUW, DB2 9 for z/OS yes yes no SQL only
and DB2 on iSeries V5R4
support external and native SQL
and Java procedures
For classic languages, such as COBOL and C on the one hand, the compiler products and
their associated runtime facilities provide debug capabilities. On the other hand, we have
interpreted languages such as SQL and Java where debugging sometimes has caused some
problems. The Unified Debugger that has been introduced with DB2 9 focuses on these
newer languages.
With the Unified Debugger, you can observe the execution of SQL procedure code, set
breakpoints for lines, and view or modify variable values. The Unified Debugger supports
external and native SQL procedures, including nested stored procedures.
The Unified Debugger builds upon and includes the SQL Debugger technology from DB2
Version 8.2. The name has been changed to Unified Debugger to embrace the unified
support for both Language SQL and Java stored procedure debugging. Following this, one
advanced capability that is now offered to you through the Unified Debugger is the ability to
debug nested SQL or Java stored procedures sharing the same client application call stack.
This means that users debugging a Java routine can step into and debug a called SQL
procedure.
The Unified Debugger itself is middleware. It originates from, and is serviced by, DB2 9 for
Linux, UNIX and Windows. This middle layer code is distributed to the DB2 server platforms
as object code (for running on each of the various operating systems that host DB2). There
are three basic elements:
The Unified Debugger server library - APIs that provide the interface for the DB2 servers
and the supported routine objects.
The Session Manager and the Unified Debugger routers stored procedures that
implement the client interface to the Unified Debugger at DB2 servers. This layer is
independent of any particular platform or DB2 server type.
A debug client that is written to support the Unified Debugger middleware. This client is
only based on LUW clients.
738 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
5. DS/DWB will then switch to the Debug Perspective, signalling that debugging is underway.
6. For Java stored procedures, DS/DWB drives the debug session by directly communicating
with the JVM at the server.
7. For SQL procedure debugging, the SM is the central coordinating agent.
– 7a: DS drives the debug session with direct TCP/IP communication to the SM.
– 7b: DWB drives the debug session with indirect communication to the SM. DWB calls
the debug router procedures that communicate with the SM via TCP/IP.
8. SQL procedures keep the debug server informed of program status. The debug server
coordinates control from DS/DWB via TCP/IP communication with the SM.
The chart in Figure 28-1 describes the processing flow for debugging stored procedures
using the IBM Data Studio Unified Debugger.
Workstation z/OS
Setup debug
3 SM Stored procs
Preferences
1
Create/Edit SP
Debugger router
Enable Debug SESSION 7b Stored procs
Deploy 2 MANAGER*
DB2-supplied
Debug 7a SPs
3
Debug 7b
4, 8
Perspective
5
Debug Library
SQL / Java SP
Execution
6 JVM
Figure 28-1 Processing overview - Unified Debugger with DB2 9 for z/OS
The Unified Debugger is also available in Developer Workbench (DWB). DWB is also
available as a download, or part of DB2 9 on LUW. The DWB download site is:
https://www14.software.ibm.com/webapp/iwm/web/preLogin.do?lang=en_US&source=swg-dm-db2dwb
When we say that this is a post-install job, it means that after stepping through the installation
or migration panels, you will not find a customized version of this job in your
hlq.NEW.SDSNSAMP library. Instead, you must copy this job from the DSN910.SDSNSAMP
library and customize it manually. A description of what you must change in order to get it to
work is provided within the job.
If you run this job, it will create the following DB2-supplied stored procedures for you:
DB2DEBUG.DEBUGGERLEVEL
DB2DEBUG.CREATE_SESSION
DB2DEBUG.DESTROY_SESSION
DB2DEBUG.QUERY_SESSION
DB2DEBUG.LIST_SESSION
DB2DEBUG.PUT_COMMAND
DB2DEBUG.GET_REPORT
SYSPROC.DBG_INITIALIZECLIENT
SYSPROC.DBG_TERMINATECLIENT
SYSPROC.DBG_SENDCLIENTREQUESTS
SYSPROC.DBG_SENDCLIENTCOMMANDS
SYSPROC.DBG_RECVCLIENTREPORTS
SYSPROC.DBG_ENDSESSIONMANAGER
SYSPROC.DBG_PINGSESSIONMANAGER
SYSPROC.DBG_LOOKUPSESSIONMANAGER
SYSPROC.DBG_RUNSESSIONMANAGER
Make sure that you specify an appropriate WLM environment for every single stored
procedure. We recommend that you use NUMTCB > 5 for the application environment that
you are going to assign to them.
Again, you will not find a customized version of this job in your hlq.NEW.SDSNSAMP library.
Instead, copy this job from the DSN910.SDSNSAMP library and customize it manually. A
description of what you must change in order to get it to work is provided within the job.
As a result of executing this job, you will have some packages bound on your system and the
following stored procedures will be created:
SYSIBM.SQLCOLPRIVILEGES
SYSIBM.SQLCOLUMNS
SYSIBM.SQLFOREIGNKEYS
SYSIBM.SQLPRIMARYKEYS
SYSIBM.SQLPROCEDURECOLS
SYSIBM.SQLPROCEDURES
SYSIBM.SQLSPECIALCOLUMNS
SYSIBM.SQLSTATISTICS
SYSIBM.SQLTABLEPRIVILEGES
740 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
SYSIBM.SQLTABLES
SYSIBM.SQLGETTYPEINFO
SYSIBM.SQLUDTS
SYSIBM.SQLCAMESSAGE
Note: The JDBC metadata routine setup job (DSNTIJMS) has no direct relationship to
debugging. Rather, that job is related to setup for JDBC (JCC connected) clients, such as
DWB, merely to support operations such as run, meaning the calling of a stored procedure.
If you are using .Net on your client, or you want to set up the SM on z/OS, follow the steps
described below. You can think of the SM as a daemon that in our case is running as a z/OS
started task that is waiting for work to perform. Setting up the SM on z/OS basically consists
of three steps, which we describe next.
Important: It is mandatory to use DB2UDSMD as the started task name. The Session
Manager is not tied to a specific DB2 subsystem, nor is it tied to any DB2 subsystem at all.
USRT005 was designated to be the ID associated with this started task. Since the task will run
a Java program from OMVS, also assign an OMVS segment definition to the user (that is,
UID, home dir, and so on). Finally, activate the STARTED task definition in current memory.
Example 28-2 Job to create a file in HFS to hold the environment settings
//UDBG2 JOB 'USER=$$USER','<USERNAME:JOBNAME>',CLASS=A,
// MSGCLASS=A,MSGLEVEL=(1,1), REGION=4096K,
// USER=USRT005,PASSWORD=*******
//*--------------------------------------------------------------------
//* Create a file in the HFS to hold the Environment settings used when
//* the Unified Debugger Session Manager runs as a Started Task on z/OS
//*
//* USRT005 is the ID associated with the Started Task.
//* Place the file in that users home directory.
//* Name the file DB2UDSMDenvironment
//*--------------------------------------------------------------------
//*--------------------------------------------------------------------
//* Create a file in the HFS from inline data using COPY
//*--------------------------------------------------------------------
//OCOPY EXEC PGM=IKJEFT01,DYNAMNBR=30
//SYSTSPRT DD SYSOUT=*
//HFSOUT DD PATH='/u/usrt005/DB2UDSMDenvironment',
// PATHOPTS=(OWRONLY,OCREAT,OAPPEND,OTRUNC),
// PATHMODE=(SIRUSR,SIWUSR,SIRGRP,SIROTH)
//INLINE DD *
#----------------------------------------------------------------------
# Environment settings for running the Unified Debugger Session Manager
# * _BPX_BATCH_SPAWN=NO
# * _BPX_SHAREAS=YES
# Arrange for the JVM to run in the same address space. This avoids
# launching 2 additional address spaces for the Started Task.
# * ENV=
# Reference this file. Insulates from PATH and CLASSPATH changes
# present in etc/profile.
# * PATH=
# The location of the desired JAVA release, and system binaries.
# * CLASSPATH=
# The location of the UDBG Session Manager jar file
# * JAVA_COMPILER=NONE
# Disable the JIT. The Started Task runs the Session Manager only
# one time, so disabling this saves space that will not be used.
#----------------------------------------------------------------------
_BPX_BATCH_SPAWN=NO
_BPX_SHAREAS=YES
ENV=/u/usrt005/DB2UDSMDenvironment
PATH=/usr/lpp/java150/J5.0/bin:/bin
742 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
CLASSPATH=/usr/lpp/db2/db2910_base/classes/db2dbgm.jar
JAVA_COMPILER=NONE
//SYSTSIN DD *
OCOPY INDD(INLINE) OUTDD(HFSOUT) TEXT
//
Create a file in the HFS to hold the environment settings used when the Unified Debugger
Session Manager runs as a started task on z/OS.
An ID must be designated to be associated with the started task. Suppose that USRT005 is
that ID. Place a file in that user's home directory to serve as an execution environment profile.
The file must point to the location of the Session Manager jar file, db2dbgm.jar. Name the file
something distinctive, such as DB2UDSMDprofile.
Note: Ensure that the CLASSPATH points to where the db2dbgm.jar file is installed.
Otherwise, the started task, DB2UDSMD, will not come up.
In both Example 28-1 on page 741 and Example 28-2 on page 742 we have used USRT005
as the place holder for the ID associated with started task DB2UDSMD that you must change
to your specific situation.
The use of a named HFS application profile is suggested for simple setup and segregation of
duties. At a minimum, it needs to define the CLASSPATH to the Session Manager Java
program. Other settings to tune the Java execution environment can be included. Note that
BPXBATCH reads the STDENV file, so no shell script symbol substitution can be utilized
here. Symbol substitution processing is only available to the user profile (.profile) for the
started task user ID and scripts executed from the shell command line.
The Session Manager is independent of DB2, so it can run anywhere in the network. But the
server platform (that is, the operating system that the stored procedure that you want to
debug runs) is often a better default choice than running at the client workstation. The session
Manager JAR file is now distributed on all server platforms, so it does not have to be obtained,
downloaded, sent, pulled, pushed, or transported by you.
Example 28-3 Sample started task JCL for the Session Manager on z/OS
//UDBG3 JOB 'USER=$$USER','<USERNAME:JOBNAME>',CLASS=A,
// MSGCLASS=A,MSGLEVEL=(1,1), REGION=4096K,
// USER=********,PASSWORD=*******
//*--------------------------------------------------------------------
//* Create the Started Task JCL for DB2UDSMD. A START command will then
//* be able to launch the Unified Debugger Session Manager on z/OS.
//* USRT005 is the ID associated with the Started Task, as defined in
//* the RACF STARTED class profile DB2UDSMD.**
//*--------------------------------------------------------------------
//*--------------------------------------------------------------------
//* Use IEBUPDTE to write a JCL member into SYS1.PROCLIB
//*--------------------------------------------------------------------
//WRITEJCL EXEC PGM=IEBUPDTE,PARM=NEW
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
Note: BPXBATCH does not derive PATH from STDENV. For the Session Manager, PATH
only needs to point to the Java runtime. One approach is to specify the PATH directly on
the command line, as shown in Example 28-2 on page 742. Another method requires the
use of a shell script profile (.profile) for the started task user, which we have not included in
this documentation. Note that the job step options in the JCL as shown, which includes the
OMVS shell command, were carefully arranged to efficiently utilize the limited space
available. The space is limited to 100 characters in total. As shown in Example 28-3 on
page 743, there are still about 18 characters left to adjust the path specification for Java.
744 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
The STDPARM file can accept 65.356 bytes.
So, for example, Create file ADMF001.DB2UDSMD.PARMOMVS which contains the
following data:
SH date;/ZOS17TC/usr/lpp/java/j1.4_64/bin/java com.ibm.db2/psmd.mgr.Daemon -timeout
&TIMEOUT -port &PORT;date
Code the DB2UDSMD procedure as shown in Example 28-5.
To fix this, change the permission bits for the /app/db2 directory from 700 to 755.
DB2UDSMD does not have authority to change directory at the /app/db2 directory. Every
directory in the path has to have the permissions in order to change directory.
To change to the /app/db2/tmp, the userid has to have directory permission to the:
– /app directory,
– /app/db2 directory, and
– /app/db2/tmp directory.
Tip: For more information about the Unified Debugger, see information about the DB2
Developer Workbench in the DB2 Database for Linux, UNIX, and Windows information
center at:
http://publib.boulder.ibm.com/infocenter/db2help/index.jsp
For a native SQL procedure, define the procedure with the ALLOW DEBUG MODE option
and the WLM ENVIRONMENT FOR DEBUG MODE option.
For an external SQL procedure, use DSNTPSMP or the IBM Data Studio to build the SQL
procedure with the BUILD_DEBUG option.
For a Java procedure, define the procedure with the ALLOW DEBUG MODE option, select an
appropriate WLM environment for Java debugging, and compile the Java code with the -G
option.
This section describes how to get you started with debugging an SQL stored procedure:
1. Setting up the Session Manager
1 with PTF PK41138 applied
746 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
2. Creating SQL stored procedures for debugging
3. Debugging SQL stored procedures
4. Defining the EMPDTLSS SQL case study for debugging
5. Debugging the EMPDTLSS SQL case study
C:\Program Files\IBM\SDP70\dwb\bin>db2dbgm.bat
args[0]: -port
args[1]: 4554
args[2]: -timeout
args[3]: 50
Code Level: 070418
Debug Session Manager started on IP: 9.30.28.113 - port: 4554
idleTimeOut: 50
2. Launch the IBM Data Studio. Click Window Preferences Run / Debug DB2
Stored Procedure Debugger. In this page, click Use already running session
manager. Fill in the Host IP address and Port number of the session manager as shown
in Figure 28-4 on page 748.
3. Click Apply OK.
To use the Session Manager, in the IBM Data Studio preferences shown in Figure 28-4 on
page 748, click Run the session manager on each connected server.
The IBM Data Studio Data Output window includes a message indicating whether the stored
procedure performed a build for debug. For an external SQL stored procedure, the build utility
748 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
reports a BUILD_DEBUG function, and whether it was successful or not, as shown in
Example 28-7.
For a native stored procedure, the output displays the beginning message Deploy for debug
started and ends with the message Deploy for debug successful.
When the stored procedure is launched in debug mode, the user is prompted to switch into
the Debug Perspective. Click Yes. In the Debug Perspective, you can set breakpoints in the
prefix area to the left of a valid statement, monitor and change the values of variables, and
interactively debug.
In Chapter 3, “Our case study” on page 23, we downloaded the source of this stored
procedure from the additional materials link in this book to our workstation. This SQL stored
procedure can be brought into IBM Data Studio in one of two ways:
Using the Import wizard
Using the editor
The Import wizard is opened and the Import Stored Procedure window is displayed. Select
File System Browse to point to the location of the source file in the file system, as shown
in Figure 28-7 on page 750.
The Import wizard includes the following six UI pages to be completed. The wizard parses the
imported source to fill in the appropriate fields when possible:
Source
Click Browse at the right of the Name field to locate the source EMPDTLSS.sql that we
had previously saved on our workstation. Click Next to continue.
Entry Points
Any routines that are included in this stored procedure are listed by the wizard where the
developer can select the routine to be used as the main entry point. The EMPDTLSS
stored procedure has one routine, and that routine is selected. Click Next to continue.
Parameters
One input parameter and nine output parameters are listed. Click Next to continue.
Options
The COLLID of DEVL7083 is automatically filled in from our source. Next, select
Advanced on this window, which opens the z/OS Options window. The WLM
ENVIRONMENT name included in the source is automatically filled in. Replace this with
750 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
DB9AWLMR, which is the WLM Environment for external SQL stored procedures in our
server. Click OK to end the Advanced Options window. Click the Enable debugging
checkbox causing our SQL stored procedure to be built for debugging. Click Next to
continue.
Note: When connected to a DB2 V9 server, IBM Data Studio assumes that if the
imported SQL stored procedure contains a WLM Environment, then the stored
procedure is an EXTERNAL type, rather than Native. You need to manually edit the
CREATE PROCEDURE DDL before importing and add the FENCED keyword to
correctly identify this as an External SQL procedure.
Summary
The above settings are summarized. Click Finish to build the stored procedure for debug.
Example 28-8 shows the modified listing.
Example 28-8 Modified EMPTDTLSS source for IBM Data Studio to build/debug on DB9A
CREATE PROCEDURE DEVL7083.EMPDTLSS
(
IN PEMPNO CHAR(6)
,OUT PFIRSTNME VARCHAR(12)
,OUT PMIDINIT CHAR(1)
,OUT PLASTNAME VARCHAR(15)
,OUT PWORKDEPT CHAR(3)
,OUT PHIREDATE DATE
,OUT PSALARY DEC(9,2)
,OUT PSQLCODE INTEGER
,OUT PSQLSTATE CHAR(5)
,OUT PSQLERRMC VARCHAR(250)
)
RESULT SETS 0
MODIFIES SQL DATA
FENCED
NO DBINFO
WLM ENVIRONMENT DB9AWLM
STAY RESIDENT NO
COLLID DEVL7083
PROGRAM TYPE MAIN
RUN OPTIONS 'NOTEST(NONE,*,*,*)'
COMMIT ON RETURN NO
LANGUAGE SQL
BEGIN
DECLARE SQLCODE INTEGER;
DECLARE SQLSTATE CHAR(5);
SELECT
FIRSTNME
, MIDINIT
, LASTNAME
, WORKDEPT
, HIREDATE
, SALARY
INTO PFIRSTNME
, PMIDINIT
, PLASTNAME
, PWORKDEPT
, PHIREDATE
, PSALARY
FROM EMP
END
The routine editor will now contain the new SQL stored procedure source as shown in
Figure 28-8. Click the Configuration tab to see the modified WLM and build utility.
752 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 28-8 Create the procedure EMPDTLSS using the editor
Whether you use the Import wizard, or the Routine Editor option, the build process returns the
same results when we have successfully created the SQL stored procedure for debugging. In
addition to the build process, the WLM ENVIRONMENT, DB9AWLM where EMPDTLSS
executes, is automatically refreshed to pick up our latest changes.
When a debug session has been established, IBM Data Studio initiates a switch from the
Data Perspective to the Debug Perspective.
The Debug Perspective is made up of the following related views and tool bars:
Routine Editor View - Shows the SQL code.
Breakpoints View - Shows the list of break points currently set.
Variables View - Shows the list of defined variables.
Outline View - Shows the variables and methods of the stored procedure under execution.
Data Output - Shows the status history, execution messages, parameters, and result sets,
if any.
Execution toolbar - Provides icons to debug or simply execute a stored procedure; also
keeps a list of most recently executed stored procedures.
Debugger toolbar - Provides icons for the various debug execution step commands: step
into, step over, step return, resume, pause, and terminate.
These views are connected in the sense that the break points and variables views show the
debug data for the stored procedure currently shown in the Routine Editor View. Switching to
a different procedure in the Routine Editor causes the break points and variables views to
display the debug data for the newly selected stored procedure code. The Debug Perspective
also includes a specialized set of toolbars for debugging.
Routine Editor view
The routine editor displays the stored procedures being debugged. Each tab in the Editor
view displays an open resource. You can set breakpoints in this view, either during debug
or before initiating the debug in the Data Perspective.
Execution toolbar
754 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
The Execution toolbar includes three actions, as shown in Figure 28-10.
– Debug - Executes a stored procedure in Debug mode. The pull-down list next to the
icon shows all previously debugged stored procedures. The default is to debug the last
executed stored procedure.
– Run - Executes a stored procedure. The pull-down list next to the icon shows all
previously executed stored procedures. The default is to execute the last executed
stored procedure.
– External tools - Executes an Ant script or another tool. IBM Data Studio does not use
this action.
Debugger toolbar
The Debugger toolbar includes the debug step commands illustrated in Table 28-3.
Step into next line or block of SQL code. If the current statement is a stored procedure call,
then the next line is the first line of the called stored procedure.
Step over to the next line of execution. If the current line is a call to a nested stored
procedure or the next line is an indented block of code, then the nested procedure or block
of code will be executed as one statement unless a break point was encountered.
Step return causes execution to resume at the next line in the parent stored procedure of
the current nested stored procedure unless a break point is encountered. If the current
stored procedure is the only stored procedure in the call stack, then execution will run to
completion or the next break point encountered.
Resume causes the stored procedure being debugged to run and stop or break at the next
breakpoint.
Pause causes the execution of the stored procedure to be suspended. Click Resume or
Terminate to continue or terminate execution.
Terminate causes the execution of the stored procedure to stop. This does not cause the
stored procedure to run to completion. This simulates an abort.
The Breakpoints view also has a specialized toolbar for managing the breakpoints, as
illustrated in Table 28-4.
756 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
statements change variables, while other statements do nothing. This is summarized in
Table 28-5.
Table 28-5 Valid SQL Debugger breakpoint and change variable statements
Category of statements Statements
Statements that do not accept DECLARE cursor WITH RETURN FOR <sql statement>
breakpoints and do not impact the DECLARE CONDITION (CONDITION) FOR SQLSTATE
Unified Debugger processing (VALUE) "..."
DECLARE CONTINUE HANDLER
DECLARE CURSOR
DECLARE EXIT HANDLER
DECLARE UNDO HANDLER (unless they are entered)
DO
ELSE
END CASE
END IF
END FOR
END REPEAT
END WHILE
LOOP
REPEAT (as a keyword alone)
THEN
labels, e.g. P1: :
Figure 28-12 shows the debug configuration dialog when using method 1.
After clicking Debug, the Specify Parameter Values dialog is displayed. This is because our
stored procedure has one input parameter. See Figure 28-13.
758 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
If this is the first time you are debugging, IBM Data Studio shows a dialog to confirm switching
to the Debug Perspective. Confirm by clicking Yes. See Figure 28-14.
The Debug Perspective shown in Figure 28-9 on page 754 is displayed. In the Routine Editor,
the first line, CREATE PROCEDURE... is highlighted in blue.
Set breakpoints
Next, we set a breakpoint in two places.
1. Locate the DECLARE SQLSTATE CHAR(5) statement.
2. Place the cursor in the left-hand prefix.
3. Double-click to set the breakpoint. An entry for this line is added in the Breakpoints View.
4. Locate the SET PSQLERRMC = 'ADIOS' statement.
5. Set a breakpoint on this line.
To run to this breakpoint, we select the Resume icon from the toolbar.
From this point, we step through the remaining lines of code using the Step Into icon and view
the variables in the output window at the bottom as we progress through the code. At the end
of the stored procedure, all values as they have been processed by our code appear in the
Editor. See Figure 28-15.
For more information on the Unified Debugger, see the Information Center Help included with
IBM Data Studio.
Here we discuss the following using the IBM Debug Tool with Rational Developer v7 for
System Z (RDz v7):
1. Overview of debugging COBOL procedures with the IBM Debug Tool
2. Prerequisites and setup on the:
– Workstation
– z/OS
3. Create the COBOL stored procedure source file
4. Modify the COBOL stored procedure source
5. Register the COBOL stored procedure
6. Prepare the stored procedure for debug
7. Set up a WLM AE with required data sets
8. Debug using RDz V7
9. Debug using TSO (3270 interface only)
28.4.1 Overview of debugging COBOL procedures with the IBM Debug Tool
The chart in Figure 28-17 describes the processing flow for debugging COBOL stored
procedures using RDz V7 and the IBM Debug Tool.
760 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Launches debug perspective W
RDz V7
Debug
O
Perspective R
K
S
Run COBOL Communication
Stored proc established via
P
WS IP addr in Runtime A
Options C
E
z
Reads DB2 Launches Listing /
Catalog
O
Build for debug Loads SP Execution Stored Procedure
recognized S
Loads Load Module
Debug Tool
WLM
The chart shows how RDz v7 and the Debug Tool (DT) interact to launch a debug session
accessing the language listing file.
1. RDz v7 is used to CALL the stored procedure in debug mode by clicking the Run action
against the COBOL stored procedure.
2. During initialization of the stored procedure into the SPAS, Language Environment (LE)
recognizes the TEST run option and loads Debug Tool (DT) into the stored procedure
address space. Control is passed from LE to DT. DT then parses the remaining portion of
the RUN OPTIONS string, locating the workstation IP address. Communication is
established between the Workstation and the stored procedure address space, and
debugging is started using the stored procedure listing file.
3. Once communication is established, RDz launches the Debug Perspective and displays
the listing.
Workstation
No client tool is required to debug COBOL, PL/I, or C/C++ stored procedures on z/OS when
using the IBM Debug Tool on z/OS, which can use a 3270 TSO interface for the debugging.
See 16.5, “IBM Debug Tool” on page 333 for more information on Debug Tool, and 16.5.2,
“IBM Debug Tool on z/OS: An example” on page 336.
For our testing, we used RDz V7, which is a product that is installed on top of the Rational
Application Developer V7 product. This made the debugging easy for an application
developer used to workstation Debuggers. Furthermore, since both the IBM Data Studio and
RDz v7 are Eclipse-based, the RDz Debug Perspective is exactly the same as the Debug
Perspective in IBM Data Studio. To debug COBOL, PL/I, or C/C++ stored procedures, we will
need to install:
Like IBM Data Studio, RDz v7 ships the license jar files and does not require DB2 Connect.
The location of the license jars is the same in both products.
z/OS
The products needed on the host are the LE runtime, the Debug Tool (DT) for z/OS library,
and the RDz V7 Host components.
LE runtime
– hlq.SCEERUN
Debug Tool (DT) library
– hlq.SEQAMOD
Once Debug Tool is installed on z/OS, you must make certain Debug Tool load modules
are available in an APF-authorized data set that is in the system link list concatenation.
The hlq.SEQAMOD data set must be in the load module search path whenever you debug
a program with Debug Tool. The Customization Guide in the Debug Tool for z/OS Web site
below gives more information on how to configure the Debug Tool:
http://www-306.ibm.com/software/awdtools/debugtool/
We discuss how to use the IBM Debug Tool in our case study at 16.5, “IBM Debug Tool” on
page 333.
Host configuration for RDz v7
RDz v7 requires a connection to the TSO command service on z/OS. The RDz component
that provides the core services for client-host communication is the Remote Systems
Explorer (RSE).
RDz v7 has a list of prerequisite software that must be installed and operational before the
product will work. Below is a summary of these requirements:
– The Software Configuration and Library Manager (SCLM) Developer toolkit (FMID
HSD3310).
– The C/C++ DLL class library CBC.SCLBDLL and the Language Environment (LE)
runtime libraries CEE.SCEERUN and CEE.SCEERUN2 must be in LINKLIST.
– INETD for setting up the client-host connection.
– TCP/IP and Resolver configuration files must be set up.
For additional information on configuring the z/OS server for RDz V7, see The Rational
Developer for System z Host Configuration Guide, SC23-7658.
WLM AE setup for debugging
Since Debug Tool is loaded in the WLM environment when the COBOL, PL/I, C/C++
language stored procedure has been compiled with the TEST parm and has been
executed, you may want to set up a separate WLM environment for debugging these
stored procedures.
The WLM procedure where the DB2 COBOL stored procedure executes needs to have
the following data sets added to STEPLIB, if they are not already in LINKLST:
LE data set; hlq.SCEERUN
DT data set; hlq.SEQAMOD
Stored Procedure Load Library
Example 28-9 is a sample WLM procedure for running DB2 Cobol stored procedures.
762 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Example 28-9 WLM AE procedure for running DB2 COBOL stored procedures
//*************************************************************
//* JCL FOR RUNNING THE WLM-ESTABLISHED STORED PROCEDURES
//* ADDRESS SPACE
//* RGN -- THE MVS REGION SIZE FOR THE ADDRESS SPACE.
//* DB2SSN -- THE DB2 SUBSYSTEM NAME.
//* NUMTCB -- THE NUMBER OF TCBS USED TO PROCESS
//* END USER REQUESTS.
//* APPLENV -- THE MVS WLM APPLICATION ENVIRONMENT
//* SUPPORTED BY THIS JCL PROCEDURE.
//* THIS IS FOR USER SQL STORED PROCS - 2003.05.19 M.SCANLON
//*************************************************************
//DSN7WL4 PROC RGN=0K,APPLENV=DSN7WL4,DB2SSN=DSN7,NUMTCB=15
//IEFPROC EXEC PGM=DSNX9WLM,REGION=&RGN,TIME=NOLIMIT,
// PARM='&DB2SSN,&NUMTCB,&APPLENV'
//STEPLIB DD DISP=SHR,DSN=MEL.DSN7.RUNLIB.LOAD
// DD DISP=SHR,DSN=DSN.DSN7.RUNLIB.LOAD
// DD DISP=SHR,DSN=DSN.DSN7.SDSNEXIT
// DD DISP=SHR,DSN=DSN.DSN7.SDSNLOAD
// DD DISP=SHR,DSN=SYS1.SCEERUN
//SYSTSPRT DD SYSOUT=H
//CEEDUMP DD SYSOUT=*
//SYSPRINT DD SYSOUT=H
//SYSABEND DD DUMMY
//SQLDUMMY DD DUMMY
RDz uses a REXX stored procedure, ELAXMREX, located in hlq.SFEKPROC. You will
need to define the WLM environment for this stored procedure. Example 28-10 shows a
sample WLM procedure for ELAXMREX. Because this is a REXX stored procedure, the
NUMTCB is always set to 1. The workfiles at the bottom of the procedure are needed by
the compiler.
RDz v7 is Eclipse-based and uses much of the same infrastructure as IBM Data Studio. As a
result, you will notice that the Data Perspective, the views, and the wizards are similar. Where
the user interface and procedural steps are the same, we will refer you to the IBM Data Studio
chapter.
We can create our COBOL stored procedure on the z/OS side by using TSO to create and
edit our COBOL stored procedure source.
On the client side, we can use RDz v7. Here, we show how one creates a template2 COBOL
stored procedure, edits it, and then deploys it to the z/OS server.
RDz v7 launches with the z/OS Projects Perspective. Click Window Open
Perspective Data to switch to the Data Perspective.
Click the New Connection icon, and create a new connection to DSN9. Follow the steps
in 27.4.2, “Creating a connection” on page 682. For our testing, we used the following
information:
Location: DSN9
Host: stplex4a.svl.ibm.com
Port: 8016
Remember to uncheck the checkbox “Retrieve objects created by this user only.” The
completed Connection Wizard is shown in Figure 28-19.
2
RDz creates a template only. You you will need to edit the stored procedure after leaving the New Stored Procedure
wizard
764 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 28-19 RDz - New Database connection
Create a new stored procedure using the New Stored Procedure wizard
Note: See 27.5.1, “Creating a new native stored procedure using the wizard” on page 689,
for details on each of the pages of the New Stored Procedure wizard.
In the Data Project Explorer, right-click the Stored Procedures folder New Stored
Procedure.
The New Stored Procedure wizard is launched. The default project is CobolProject2. Click
Next.
In the Name and Language page, type EMPDTLC for the name. This is the name of both the
stored procedure and the member name in the data set that you will specify in the next
page. Leave the default setting for Language as Cobol. See Figure 28-21. Click Next.
In “Select target and name”, we specify the member name in the z/OS PDS for this stored
procedure. This should be the same as what was specified in the previous page. In RDz,
this name is limited to 7 characters. Type EMPDTLC for the name. See Figure 28-22. Click
Next.
Figure 28-22 RDz - target name for stored procedure PDS member names
In the Source Location page, RDz recognizes that you are connected to the Remote
System, DSN9, and sets the Connected System to this value and the z/OS Filter String to
the default high level qualifier in this system, which is the login userid. See Figure 28-23.
766 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 28-23 RDz - Source Location
Click Browse to specify the Source data set. RDz will display a list of Select Data Sets.
Select hlg.SOURCE.COBOL. This is the Partitioned Data Set (PDS) in your z/OS system
that will contain the source code of the COBOL stored procedure. See Figure 28-24. Click
Next.
In the SQL Statements page, click Create SQL. This launches the SQL wizard.
– We will use defaults in the Specify SQL Statement Information page. Click Next.
– In the Tables tab, select DSN8910 EMP. See Figure 28-25 on page 768. Click >.
Figure 28-26 RDz - SQL wizard, Columns tab, selecting result columns
– In the Conditions tab, click the first cell Columns column, and select EMP.EMPNO.
See Figure 28-27. Press Enter.
768 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 28-27 RDz - SQL wizard, Conditions tab
– The Operator cell contains the default =. Go to the Value cell and type :PEMPNO. Press
Enter. Click Next.
– The Statement page shows the generated SQL Statement. Click Finish.
For more details on the SQL wizard and other SQL statement building tools within RDz,
see 27.4.4, “Creating SQL statements to use in your stored procedure” on page 685.
Examine the generated SQL statement in the Statement details text window. We will use
the default Result Set setting. Click Next.
In the Parameters page, click Add. The Add Parameter dialog is launched. Create the
parameters as shown in Table 28-6. In Chapter 27, “The IBM Data Studio” on page 643,
see“Parameters” on page 697 for details on using this dialog.
Table 28-6 Parameter names and values for EMPDTLC COBOL stored procedure
Parameter Name SQL Type
Mode
Although not visible in the list, RDz has generated PEMPNO as an INPUT parameter. The
completed Parameters page is shown in <RDz_Parameters.gif>. Click Next.
In the Deploy Options page, type SG247083 for the Collection ID. Click Advanced.
In the z/OS Options dialog, select the Stored Procedure Options tab and check the box
to Build Stored Procedure for Debugging. Note that the TEST options are added. This field
contains the TCP/IP address of the client. If the IP address of the client is changed, you
will need to reset this by unchecking this checkbox, saving the stored procedure, and
resetting the checkbox.
Still in this tab, type DSN9WL4 for the WLM Environment. Click the Deploy Options tab.
Figure 28-28 shows the generated COBOL stored procedure source code.
Figure 28-28 COBOL stored procedure source listing in the Editor View
Working Storage Add work variable WS-PEMPNO for storing the input parameter PEMPNO,
Working Storage Add a copylib, the DCLGEN file for table EMP.
SELECT PEMPNO... Convert SELECT PEMPNO... into SELECT PEMPNO..INTO working storage
variables;
Change WHERE clause to PEMPNO = :WS-PEMPNO
770 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Location in generated Changes
template
Add Error Handling Add Evaluate statement to check SQLCODE. If non-zero, process the
error in 9000_DBERROR.
Add procedure 9000_DBERROR.
We did additional modifications that were cosmetic in nature. After our changes, the COBOL
stored procedure is shown in Example 28-11.
772 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
010900 SALARY 01090002
011000 INTO 01100002
011100 :PFIRSTNME 01110002
011200 , :PMIDINIT 01120002
011300 , :PLASTNAME 01130002
011400 , :PWORKDEPT 01140002
011500 , :PHIREDATE 01150002
011600 , :PSALARY 01160002
011700 FROM EMP 01170002
011800 WHERE EMPNO = :WS-EMPNO 01180002
011900 END-EXEC. 01190002
012000 01200002
012100 DISPLAY '++ SQLCODE AFTER SELECT = ' SQLCODE. 01210002
012200 01220002
012300 MOVE SQLCODE TO PSQLCODE. 01230002
012400 MOVE SQLSTATE TO PSQLSTATE. 01240002
012500 MOVE SQLERRMC TO PSQLERRMC. 01250002
012600 01260002
012700 EVALUATE SQLCODE 01270002
012800 WHEN 0 01280002
012900 CONTINUE 01290002
013000 WHEN OTHER 01300002
013100 PERFORM 9000-DBERROR 01310002
013200 THRU 9000-EXIT 01320002
013300 END-EVALUATE. 01330002
013400 01340002
013500 2000-EXIT. 01350002
013600 EXIT. 01360000
013700/ 01370000
013800*-----------------------------------------------------------------01380003
013900* 9000-DBERROR - GET ERROR MESSAGE 01390000
014000*-----------------------------------------------------------------01400003
014100 9000-DBERROR. 01410000
014200 CALL 'DSNTIAR' USING SQLCA ERROR-MESSAGE ERROR-TEXT-LEN.01420000
014300 IF RETURN-CODE = ZERO 01430000
014400 PERFORM 9999-ERROR-DISPLAY THRU 01440000
014500 9999-EXIT 01450000
014600 VARYING ERROR-INDEX 01460000
014700 FROM 1 BY 1 01470000
014800 UNTIL ERROR-INDEX GREATER THAN 12. 01480000
014900 01490000
015000 GOBACK. 01500000
015100 01510000
015200 9000-EXIT. 01520000
015300 EXIT. 01530000
015400/ 01540000
015500*-----------------------------------------------------------------01550003
015600* 9999-ERROR-DISPLAY 01560000
015700*-----------------------------------------------------------------01570003
015800 9999-ERROR-DISPLAY. 01580000
015900 DISPLAY ERROR-TEXT (ERROR-INDEX). 01590000
016000 9999-EXIT. 01600000
016100 EXIT. 01610000
We first identify the data sets needed for deploying the COBOL stored procedure. Click the
Data sets for Deploy tab. Type the names for the data sets, as shown in Table 28-8.
774 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Table 28-8 Data sets for Deploy in RDz v7
Data set description What we typed in
Note: to specify multiple data sets, separate your entries with a blank.
Click the Save icon, or Ctrl-S to save your changes.
Right-click EMPDTLC and then click Deploy.3
The Data Output view displays the status and messages during compilation and
registration. If there are compile errors, you can view them in the Remote Error List tab of
the Output View, as shown in Figure 28-30.
Note: Double-click an error in the Remote Error list to go straight to the line in the source
code where the compile error is. This opens up a System z LPEX editor window.
3
Do not click Deploy... (with the ellipsis), this launches the Deploy Wizard which is supported only for SQL and Java
stored procedures.
We used the default listening port of 8001, which can alternatively be set to a different value.
The port value is specified directly after the IP address in the RUN OPTIONS parm. See
Example 28-14.
Example 28-14 CREATE PROCEDURE definition showing the IP address and port
CREATE PROCEDURE MARICHU.EMPDTLC ( IN PEMPNO CHAR(6), ...
EXTERNAL NAME EMPDTLC
LANGUAGE COBOL
WLM ENVIRONMENT DSN9WL4
RUN OPTIONS 'TEST(,,,TCPIP&9.30.28.118%8001:*)'
776 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
With RDz
Alternatively, you can use RDz to change the run options dynamically. This avoids the
need of issuing an ALTER PROCEDURE. However, you will need to drop and rebuild your
stored procedure. To do this:
– Right-click EMPDTLC and then click Open.
– In the Editor, click the Options tab and uncheck Build Stored Procedure for
Debugging.
– Recheck the Build Stored Procedure for Debugging. This will capture the latest IP
address of the client and generate a new string for the Run Options.
– Click the Save icon or press Ctrl-S again.
– In the Database Explorer, expand the DSN9 connection to the Stored Procedures
folder.
– Right-click EMPDTLC and then click Drop.
– In the Data Project Explorer, right-click EMPDTLC and then click Deploy.
Running our COBOL stored procedure is performed from the Data Perspective. There are
multiple ways to open the Data Perspective view. We opened the Data Perspective view from
the top right-side toolbar, selecting the table icon with a +. Clicking this icon expands the
Perspective selection list. Sometimes the Data keyword is displayed in this area as well. See
Figure 28-31.
Click "Open
Perspective" to see
list of perspectives
In the Data Project Explorer, right-click EMPDTLC and then click Run.
RDz will request permission to launch the Debug Perspective. Click Yes.
The Debug Perspective is launched, as in Figure 28-32.
At this point, you can use the same views and actions as discussed in 28.3, “Debugging SQL
procedures on z/OS, Linux, UNIX, and Windows” on page 746.
778 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Paste” on page 715. This requires the same z/OS setup for Java stored procedures as
described in 27.2.2, “DB2 for z/OS setup” on page 650.
Write System.out.println, System.err.println lines in your Java code to STDOUT and
STDERR.
To use the default directory structure for writing STDOUT and STDERR requires the
presence of the HFS /tmp/java directory. When this directory exists, any messages written
to STDOUT will appear in /tmp/java/server_stdout.txt. Conversely, any messages written
to STDERR will appear in /tmp/java/server_stderr.txt. If the Java directory does not
physically exist under the /tmp directory, these messages will not be written.
Alternatively, you may want to isolate the Java sysprint lines more granularly to a specific
directory for the Java stored procedures executing in a specific WLM AE. This can be
done by including a WORK_DEPT environment variable pointing to a separate HFS
directory in the WLM procedure JAVAENV statement.
Convert your Java stored procedure to a Java application, and debug using the Java
perspective in IBM Data Studio. See Chapter 29, “Debugging DB2 V8 Java procedures
with Data Studio” on page 785.
In IBM Data Studio, we copied the EmpDtlsJ stored procedure from our DB9A project on
z/OS, then pasted this stored procedure to our DB2 9 on LUW SAMPLE project. Since our
Java stored procedure created on z/OS used the EMP table, which is comparable to the
EMPLOYEE table on Windows, the only change needed to the stored procedure on Windows
was to change the SQL select statement to point to the Windows EMPLOYEE table instead of
the z/OS EMP table.
Our case study for this section performs the following steps:
1. Start IBM Data Studio and create database connections.
– Create a database connection to DB9A, our DB2 for z/OS V9 location.
– Create a database connection to SAMPLE, our DB2 9 on LUW database.
2. Create LUW project
– Create the project ProjectLUW with a target connection to SAMPLE.
3. In the Database Explorer, 28.6.3, “Drag and drop EmpDtlsJ to Windows” on page 780,
project PROJECTLUW.
4. Using the Routine Editor, 28.6.4, “Modify the table DEVL7083.EMP to EMPLOYEE” on
page 781.
5. Deploy EmpDtlsJ for debug.
6. Run EmpDtlsJ in debug mode.
Alternatively, in the Database Explorer, you can right-click DEVL7083.EMPDTLSJ, then click
Copy. Then in the Data Project Explorer, right-click the Stored Procedures folder and click
Paste.
4 Copy and Paste performs the same function as a drag and drop.
780 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 28-33 shows the state of ProjectLUW after the drag and drop. We also opened the
routine editor after the drag and drop.
Figure 28-33 Drag and drop stored procedure from z/OS to Windows
In the Deploy wizard’s Deploy Options page, click the Enable Debugging checkbox. The
Compile Options field is updated with a -g. Click Finish.
Call SQLJ.DB2_REPLACE_JAR
(<<C:\$ViperII_Stuff\Workspaces\IBMDataStudio11_ITSO\.metadata\.plugins\com.ibm.datatools.d
b2.routines.deploy.ui\bld1194560817813\spjar.jar>>, 'MARICHU.SQL7103011562640')
Call sqlj.refresh_classes( )
782 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
MARICHU.EMPDTLSJ - Removed temporary working directory
C:\$ViperII_Stuff\Workspaces\IBMDataStudio11_ITSO\.metadata\.plugins\com.ibm.datatools.db2.
routines.deploy.ui\bld1194560817813.
Update the DB2 Routine Session Manager Location in the Window Preferences
Run / Debug DB2 Stored Procedure Debugger page with the IP address and port
number of the Session Manager. See Figure 28-4, “Preferences for using the client
Session Manager” on page 748.
From the Data Project Explorer ProjectLUW Stored Procedures folder, select
DEVL7083.EMPDTLSJ. and right-click Debug.
This starts the Java stored procedure in debug mode running, as shown in Figure 28-34.
At this point, the behavior of the Unified Debugger when processing a Java stored
procedure is the same as when processing an SQL stored procedure, which we discussed
in 28.3.3, “Debugging SQL stored procedures” on page 749.
784 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
29
In this chapter we describe the third option of using IBM Data Studio to debug Java stored
procedures converted to Java programs. Our case study uses both JDBC and SQLJ stored
procedures.
1
In the previous edition of this book, there were additional methods offered involving the WebSphere Application
Developer.
As we have seen in the last chapter, the IBM Data Studio launches with the Data Perspective.
This time, we want to use the Java Perspective and create a Java project to run our test
cases.
The Java Perspective is displayed in Figure 29-2 on page 787. This is identified by the word
Java in the title bar, and in the top-right tab.
786 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
.
The default views available in the Java Perspective differ slightly from the Data Perspective. In
the Java Perspective, we have:
Package Explorer - This displays the resources in each project, and displays them as files
rather than as database objects. So, for example, the stored procedure EmpDtlsJ is shown
as EmpDtlsJ.spxmi.
Hierarchy - This displays the class hierarchy for a given class. We will not use this view.
Editor view - This is the middle part of the workspace and displays the current selected
resource for edition. This view supports multiple types of editors (for example XML editor,
Java Editor). For our case study we use the Java Editor, which shows the source code of
our Java stored procedure.
Outline view - This shows the sections of our Java source, for example import section,
variable declarations, methods, inner classes, and so on, in an outline form.
Output view Problems - This tab in the Output view shows us what Java compilation
errors were found.
Chapter 29. Debugging DB2 V8 Java procedures with Data Studio 787
From the New Project window, select Java in the left-hand window, and Java Project in
the right-hand window, as shown in Figure 29-3, and click Next.
The New Java Project wizard is launched. Type JAVASPDEBUG as the Project Name. We use
the default settings for everything else. See Figure 29-4. Click Next.
The next window shown is the Java Settings window, shown in Figure 29-5. Click the
Libraries tab.
788 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 29-5 Define the Java build settings - Source
The Libraries window is where we define the Java build settings. We need to add external
jars to our project. To add the jars, click Add External JARS on the right-hand side of the
window.
In the File Browser dialog, browse the folder in the IBM Data Studio install directory that
includes:
– db2jcc.jar
– db2jcc_license_cisuz.jar
If you installed IBM Data Studio using the default settings, this directory will be:
C:\Program Files\IBM\SDP70Shared\plugins\com.ibm.datatools.db2_<some version
#>\driver
Click Open.
The Libraries window now includes the files shown in Figure 29-6.
Chapter 29. Debugging DB2 V8 Java procedures with Data Studio 789
Click Finish at the bottom of the window, and the template for our Java application will be
generated.
Now, right-click project JAVASPDEUG and click Paste, as shown in Figure 29-8.
The Package Explorer view now has the EmpDtlsJ.java source file. It is located in the
default package folder under the JAVASPDEBUG object. Expand this folder and
double-click EmpDtlsJ.java. This opens the resource in the Editor view using the Java
Editor.
790 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
We discussed the Java Editor in Chapter 27, “The IBM Data Studio” on page 643, “Java
Editor” on page 677. The Java Editor reports syntax errors as you do your modifications.
When you save the file, it does a full compile of your Java source, and report the problems in
the Problems tab of the Output view.
public static void GetEmpDtls( public static void main (String args[])
String empno, {
String[] firstName, String empno;
String[] midInit, empno=args[0];
String[] lastName, String[] firstName = new String[1];
String[] workDept, String[] midInit = new String[1];
java.math.BigDecima[] salary, String[] lastName = new String[1];
String[] outputMessage) String[] workDept = new String[1];
java.math.BigDecimal[] salary = new
java.math.BigDecimal[1];
String[] outputMessage = new String[1];
Chapter 29. Debugging DB2 V8 Java procedures with Data Studio 791
d. Copy the Connection url value and set the url variable to this value.
e. Set the userid and password variables to the login ID and password we used to
connect to DB9A server.
f. Code the Class.forName class to com.ibm.db2.jcc.DB2Driver, the IBM Universal driver
class.
g. Set the conndb2 connection to the connection obtained from the given connection info.
Table 29-2 summarizes the changes to the connection string.
Table 29-2 Changes to the connection string
Stored procedure code Converted Java application
In the prefix area on the left side of the editor, double-click these lines as shown in
Figure 29-11. A breakpoint decorator (shaded dot) is created.
792 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 29-11 Add breakpoint for Java applications
The first time you run or debug a resource in the Java Perspective, IBM Data Studio will
ask you to configure your run/debug launch settings. The next time you run or debug a
resource, this named launch configuration will be shown as the first entry in the Debug or
Run drop-down options.
2. The next window is where we configure the debug options. From the Debug window, select
Java Application and click the New launch configuration icon as shown in
Figure 29-13.
Chapter 29. Debugging DB2 V8 Java procedures with Data Studio 793
Figure 29-13 Configure Java Application for debug
3. In the Debug Main window, select EmpDtlsJ from the Configurations portion on the left.
On the right side of the window, enter the information in Table 29-3.
Table 29-3 Debug settings for Java application
Field Value
Name Java_Debug
Project JAVASPDEBUG
794 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
The completed Main debug panel is shown in Figure 29-14.
4. Click Apply.
5. Click the Arguments tab next to the Main tab.
Our stored procedure requires input parameters to execute. These were removed as
described when we modified the stored procedure in 29.1.4, “Modify the Java stored
procedure code” . The Arguments window is where we specify these parameters. Enter
D11 for Department 11.
6. Click Debug to save these changes and start the debug session. Optionally, you can click
Apply, then Debug. However, selecting Debug performs an implicit Apply, as shown in
Figure 29-15.
Chapter 29. Debugging DB2 V8 Java procedures with Data Studio 795
Figure 29-15 Java application Debug Arguments window definition
The Debug Perspective opens. This is the same Debug Perspective we introduced in “28.2,
“The Unified Debugger” on page 738”, and in Chapter 29, “Debugging DB2 V8 Java
procedures with Data Studio” on page 785”.
You are now ready to debug your Java application. As when using the Unified Debugger, you
have the same capabilities for Step In, Step Over, Step Return, Resume, Pause, and
Terminate in the execution of this application. You also have the same capabilities for
managing breakpoints and variables.
Figure 29-16 shows the Console output from our System.out.println statements.
Figure 29-17 shows the Debug Perspective for our converted Java stored procedure.
796 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 29-17 Debug Perspective at a breakpoint
The steps to convert an SQLJ stored procedure to an SQLJ application are very similar to the
steps described in 29.1, “Debugging JDBC procedures converted to JDBC applications” on
page 786.
Chapter 29. Debugging DB2 V8 Java procedures with Data Studio 797
Select Project_7083 Java Source EmpDtl1.sqlj. Then right-click Copy as shown in
Figure 29-18.
798 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 29-20 Add SQLJ Support
Click Finish.
The SQLJSPDEBUG project now has the following objects added, as shown in
Figure 29-22:
• SQLJAnt Scripts
• sqlj.zip
• EmpDtlAJ.sqlj
Chapter 29. Debugging DB2 V8 Java procedures with Data Studio 799
• EmpDtlAJ_SJProfile0.ser
Click the X in the upper right corner to close the editor as shown in Figure 29-23. Reply yes
when prompted to save the updates.
800 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Figure 29-24 Launch the Debug configuration
Locate Java Application in Configurations in the left-hand portion of the window, then
click New launch configuration as shown in Figure 29-13 on page 794.
In the Debug Main window, enter the information in Table 29-4. If EmpDtl1J is not the
Main class selected, click Browse to select this class.
Table 29-4 Debug settings for SQLJ applications
Field Value
Name SQLJ_Debug
Project SQLJSPDebug
Click Apply.
The main configuration panel is shown in Figure 29-25 on page 802.
Chapter 29. Debugging DB2 V8 Java procedures with Data Studio 801
Figure 29-25 Define a new SQLJ Debug configuration
Our stored procedure requires input parameters to execute. These were removed as
described in 29.2.5, “Modify the source code” on page 800. So we now specify the input
parameters as input arguments to our SQLJ application.
Click the Arguments tab.
The Arguments window is where we specify these parameters. Enter 000150 selecting an
employee number in the EMP table.
Click Debug to start the debug session.
You may be asked again to confirm switching from the Java Perspective to the Debug
Perspective as shown in Figure 29-26. Click the checkbox Remember my decision to
suppress this dialog the next time you debug.
802 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
The Debug Perspective is now launched. Once the debug session starts, we can start
debugging the SQLJ application, and monitor or change variables, set breakpoints, step
through the code, etc., as shown in Figure 29-27.
Chapter 29. Debugging DB2 V8 Java procedures with Data Studio 803
804 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Part 7
Part 7 Appendixes
This part includes the Appendixes defined during this project:
Appendix A, “Samples for using DB2-supplied stored procedures” on page 807
Appendix B, “Additional material” on page 887
“Related publications” on page 897
“Abbreviations and acronyms” on page 895
This appendix details the invocation of stored procedures providing the following functions:
Display DB2 system information with AdminSystemInformation
Refresh a WLM environment with AdminWLMRefresh
Issue DB2 commands with AdminDB2Command
Automate RUNSTATS with AdminUtilityExecution
Manage data sets with AdminDataSet
Submit JCL with AdminJob
Issue USS commands with AdminUNIXCommand
Issue DSN subcommands with AdminDSNSubcommand
Task Scheduler Sample Use cases
Invoking the Common SQL API stored procedures
The structure of the sample programs is very similar across the first seven functions. To
familiarize yourself, read through A.1, “Display DB2 system information with
AdminSystemInformation” on page 808 where the sample program structure is described in
detail. The following six samples focus on calling the DB2-supplied stored procedures and do
not repeat this information. The sections about task scheduler and the Common SQL API are
very special and should be read in detail to get familiar with this.
The MVS subsystem name is important if you want to create JCL that will run DB2
commands, DSN subcommands, or DB2 online or offline utilities. While you can find out the
subsystem name by querying the DSNZPARM, ADMIN_INFO_SSID is easier to use and
does not require any special privileges such as DSNWZP.
The fully qualified domain name of your DB2 server is important if you want to FTP files to
your DB2 server. The TCP/IP hostname that you specified in your CATALOG command on the
client or in the JDBC URL of your Java application may be a DB2 Connect gateway. While you
can find out the fully qualified domain name using the -DIS DDF console command,
ADMIN_INFO_HOST is easier to use, and does not require any special privileges such as
ADMIN_COMMAND_DB2.
While the DSNZPARMs are primarily of interest to a database or system administrator to view
the configuration parameters of a DB2 subsystem, you may need to know certain
DSNZPARMs in any application program that you write. For example, if you use dynamic SQL
and your database object names need to be enclosed in delimiters, you have to know what
the SQLDELI value is. If the SQLDELI value is DEFAULT, you have to use the quotation mark
for a delimited identifier like this:
CREATE TABLE "MY TABLE" (COL CHAR(1) NOT NULL WITH DEFAULT)
If the SQLDELI value is set to the quotation mark, you have to use the apostrophe as the
escape character like this:
CREATE TABLE ‘MY TABLE’ (COL CHAR(1) NOT NULL WITH DEFAULT)
If you are planning to run utilities from a client application or a remote application server, you
have to find out which utilities are installed on the connected DB2 subsystem. In our sample
application, we use DSNUTILU to run the DIAGNOSE online utility to find out which licensed
utilities are installed.
Example A-1 lists the source code for the AdminSystemInformation class where we need to
import the required Java packages and classes first.
//***************************************************************************
// Licensed Materials - Property of IBM
// 5635-DB2
// (C) COPYRIGHT 1982, 2006 IBM Corp. All Rights Reserved.
//
// STATUS = Version 9
//***************************************************************************
// Source file name: AdminSystemInformation.java
//
// Sample: How to use the DB2 provided system information stored
// procedures
//
//The user runs the program by issuing:
//java AdminSystemInformation <alias or //server/database> <userid> <password>
//
//The arguments are:
808 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
//<alias> - DB2 subsystem alias for type 2 or //server/database for type 4
// connectivity
//<userid> - user ID to connect as
//<password> - password to connect with
//***************************************************************************
import java.sql.*;
In Example A-2 we define a bitmask for every DB2 utility. We will use these bitmasks later
when we display the installed licensed utilities.
Most of our sample applications only contain a single main() method and an exception class,
which is thrown to indicate a program error rather than a system error such as an SQL error.
The main() method checks whether all the required arguments have been passed to the
program. In case of an error, a usage message is displayed, as shown in Example A-3.
// Parse arguments
if (args.length != 3)
{
System.err.println("Usage: AdminSystemInformation " +
We now load the IBM DB2 Driver for JDBC and SQLJ by invoking the Class.forName method
with the following argument: com.ibm.db2.jcc.DB2Driver, as shown in Example A-4. This is a
single driver that allows for both type 2 and type 4 JDBC support. An application setting up a
connection via a locally registered DB2 subsystem or alias establishes a type 2 connection.
Type 4 connectivity is employed when the target server is addressed with the help of server
name, port number, and the location name. For more information on using JDBC drivers in
your application, see the DB2 Version 9.1 for z/OS Application Programming Guide and
Reference for JAVA, SC18-9842.
A number of exceptions can be thrown here. The most likely problem is that the db2jcc.jar
archive that contains the JDBC driver classes is not in your CLASSPATH when you run this
application. Now we connect to the database with a URL as specified in the JDBC
specification and using db2 as the subprotocol.
Example: A-4 Load and connect with type 2 driver for COM.ibm.db2.jdbc.app.DB2Driver
try
{
int rc = 0;
String message = null;
boolean hasResultSet = false;
// Connect to database
con = DriverManager.getConnection(url, userid, password);
con.setAutoCommit(false);
We now prepare a CallableStatement, which is the standard way in JDBC to execute stored
procedures. IN parameter values are set using the set methods inherited from
PreparedStatement. See Example A-5. The type of all OUT parameters must be registered
prior to executing the stored procedure; their values are retrieved after execution through the
get methods provided here. ADMIN_INFO_SSID has no IN parameters and three OUT
parameters, which we register and then call execute to call the stored procedure.
cs.execute();
810 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Correct and complete error handling in your applications is very important. Many of the DB2
provided stored procedures follow a similar approach. First you have to check an OUT
parameter return code to determine whether the call was successful. If ADMIN_INFO_SSID
completes normally, it issues return code 0. It if completes with an error, it issues return code
12. In case of an error we retrieve the error message from the message area and throw an
application-defined exception called AdminSystemInformationException with the return code
and the error message. If the call was successful, we retrieve the subsystem name, print it,
and close the CallableStatement to release associated JDBC and database resources. It is
generally good practice to release resources as soon as possible. This is shown in
Example A-6.
The call to ADMIN_INFO_HOST to retrieve the fully qualified domain name is shown in
Example A-7. This stored procedure has two input parameters that are initialized with the
help of the set functions, whereas the actual value of the host name is returned in a result set.
If the return code output parameter features a value of 0, the result set is accessed. In the
sample the proper result set handling is illustrated, which fetches the TCP/IP hostname for
the connected DB2 subsystem.
We use DSNWZP to retrieve the DSNZPARMs of the connected subsystem. DSNWZP has
only one OUT parameter, which we register and then call execute to call the stored
procedure. Since DSNWZP does not issue a return code, we can simply retrieve the OUT
parameter and tokenize it using the split() method, which is new since Java 1.4. The split()
method splits the string around matches of the given regular expression and returns a string
array, which we print to the terminal. See Example A-8.
System.out.println("---------------------------------------------------------------");
for (int i = 0; (i + 7) < zparms.length; i += 7)
{
System.out.println("Internal field name = " + zparms[i]);
System.out.println("Macro name = " + zparms[i + 1]);
System.out.println("Parameter name = " + zparms[i + 2]);
System.out.println("Install panel name = " + zparms[i + 3]);
System.out.println("Install panel field number = " + zparms[i + 4]);
System.out.println("Install panel field name = " + zparms[i + 5]);
System.out.println("Value = " + zparms[i + 6]);
}
cs.close();
We run the DIAGNOSE online utility through the online utility stored procedure DSNUTILU to
determine which licensed utilities are installed on the connected subsystem. This is shown in
Example A-9. DSNUTILU does not dynamically allocate data sets. In order to do so, the
TEMPLATE utility control statement has to be used. The DIAGNOSE utility does not require
any data sets, so the call is very straightforward and thus much simpler than the same call
with DSNUTILS. Here only the utility-ID, a utility restart value, as well as the actual utility
control statement has to be provided.
812 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
The error handling of stored procedures that return error messages in a result set cursor is
different from that of other stored procedures. You should always check if there is a result set
and parse it or print it to a log. An error may have occurred while the stored procedure is
inserting rows into the result set table and so you do not lose any results. The output from
DIAGNOSE DISPLAY AVAILABLE looks similar to Figure A-1.
! ! ! ! ! ! ! ! !
---------------------------------------------------------------------------------
DSNU860I DSNUGUTC - DIAGNOSE UTILITY COMPLETE
DSNU010I DSNUGBAC - UTILITY EXECUTION COMPLETE, HIGHEST RETURN CODE=0
The map shows a 1 for each installed utility, and each position represents a specific utility. We
parse the output of message number DSNU8621 and store the map string for later
processing, as shown in Example A-10.
System.out.println("---------------------------------------------------------------");
while (rs.next())
{
String line = rs.getString(2);
if (line.indexOf("DSNU862I") != -1)
map = line.substring(line.lastIndexOf(':') + 1).trim();
System.out.println(line);
}
rs.close();
}
After we have processed the result set, we check the return code as usual. For more
information on the use of DSNUTILU and the DIAGNOSE utility, refer to DB2 Version 9.1 for
z/OS Utility Guide and Reference, SC18-9855. If the return code indicates that DIAGNOSE
has completed normally, and we found a map string in the output, we string the bitmap values
for each utility together and then print it to the console. This is a good way to save the
information on which utilities are installed. See Example A-11.
814 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
System.err.println("Program error: rc=" + asie.getRC() + " message=" +
asie.getMessage());
}
catch (ClassNotFoundException e)
{
System.err.println("Could not load JDBC driver");
System.err.println("Exception: " + e);
e.printStackTrace();
}
catch (SQLException sqle)
{
System.err.println("SQLException information");
System.err.println("Error msg: " + sqle.getMessage());
System.err.println("SQLSTATE: " + sqle.getSQLState());
System.err.println("Error code: " + sqle.getErrorCode());
}
catch (Exception e)
{
System.err.println("Error: message=" + e.getMessage());
}
finally
{
// Release resources and disconnect
try
{
rs.close();
} catch (Exception e)
{
}
try
{
cs.close();
} catch (Exception e)
{
}
try
{
con.close();
} catch (Exception e)
{
}
}
}
}
Our application-defined exception class extends Exception by allowing to set and get a return
code, which is typically the stored procedure return code. See Example A-13.
SSID = V91A
---------------------------------------------------------------
DB2 member = Hostname = w25ec051.svl.ibm.com
---------------------------------------------------------------
Internal field name = SYSPAUDT
Macro name = DSN6SYSP
Parameter name = AUDITST
Install panel name = DSNTIPN
Install panel field number = 1
Install panel field name = AUDIT TRACE
Value = 00000000000000000000000000000000
...
0DSNU050I DSNUGUTC - DIAGNOSE DISPLAY AVAILABLE
DSNU862I DSNUDIAG - DISPLAY AVAILABLE UTILITIES. MAP: 11111111111111111111111000000000
---------------------------------------------------------------------------------
|CATMAINT |CHECK |COPY |DIAGNOSE |LISTDEF |LOAD |MERGECOPY|MODIFY |
|OPTIONS |QUIESCE |REBUILD |RECOVER |REORG |REPAIR |REPORT |RUNSTATS |
|STOSPACE |TEMPLATE |UNLOAD |COPYTOCOP|EXEC |BACKUP |RESTORE | |
| | | | | | | | |
---------------------------------------------------------------------------------
DSNU860I DSNUGUTC - DIAGNOSE UTILITY COMPLETE
DSNU010I DSNUGBAC - UTILITY EXECUTION COMPLETE, HIGHEST RETURN CODE=0
CATMAINT = true
CHECK = true
COPY = true
DIAGNOSE = true
LISTDEF = true
LOAD = true
MERGECOPY = true
MODIFY = true
OPTIONS = true
QUIESCE = true
REBUILD = true
RECOVER = true
REORG = true
REPAIR = true
REPORT = true
RUNSTATS = true
STOSPACE = true
TEMPLATE = true
UNLOAD = true
COPYTOCOPY = true
EXEC = true
BACKUP = true
816 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
RESTORE = true
Example A-15 lists the source code for the AdminWLMRefresh class.
//***************************************************************************
// Licensed Materials - Property of IBM
// 5635-DB2
// (C) COPYRIGHT 1982, 2006 IBM Corp. All Rights Reserved.
//
// STATUS = Version 9
//***************************************************************************
// Source file name: AdminWLMRefresh.java
//
// Sample: How to use the DB2 provided procedure WLM_REFRESH
//
//The user runs the program by issuing:
//java AdminWLMRefresh <alias or //server/database> <userid> <password>
//
//The arguments are:
//<alias> - DB2 subsystem alias for type 2 or //server/database for type 4
// connectivity
//<userid> - user ID to connect as
//<password> - password to connect with
//***************************************************************************
import java.sql.*;
// Parse arguments
if (args.length != 3)
{
System.err.println("Usage: AdminWLMRefresh <alias or //server/database> <userid>
<password>");
try
{
int rc = 0;
String message = null;
// Connect to database
con = DriverManager.getConnection(url, userid, password);
con.setAutoCommit(false);
818 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
}
finally
{
// Release resources and disconnect
try
{
cs.close();
} catch (Exception e)
{
}
try
{
con.close();
} catch (Exception e)
{
}
}
}
}
Example A-16 shows the source code for the AdminDB2Command class.
//***************************************************************************
// Licensed Materials - Property of IBM
// 5635-DB2
// (C) COPYRIGHT 1982, 2006 IBM Corp. All Rights Reserved.
//
// STATUS = Version 9
//***************************************************************************
// Source file name: AdminDB2Command.java
//
// Sample: How to use the DB2 provided stored procedure to issue DB2
// commands.
//
//The user runs the program by issuing:
//java AdminDB2Command <alias or //server/database> <userid> <password>
//
//The arguments are:
//<alias> - DB2 subsystem alias for type 2 or //server/database for type 4
// connectivity
//<userid> - user ID to connect as
//<password> - password to connect with
//***************************************************************************
import java.sql.*;
import java.util.*;
// Parse arguments
if (args.length != 3)
{
820 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
System.err.println("Usage: AdminDB2Command <alias or //server/database> <userid>
<password>");
System.err.println("where <alias or //server/database> is DB2 subsystem alias or
//server/database for type 4 connectivity");
System.err.println(" <userid> is user ID to connect as");
System.err.println(" <password> is password to connect with");
return;
}
url += args[0];
userid = args[1];
password = args[2];
try
{
int rc = 0;
String message = null;
boolean hasResultSet = false;
ArrayList<String> messageText = new ArrayList<String>();
String commandArea = null;
String parseType = null;
// Connect to database
con = DriverManager.getConnection(url, userid, password);
DatabaseMetaData databaseMetaData = con.getMetaData();
db2release = databaseMetaData.getDatabaseMajorVersion();
// Display the DB2 major version this value might be useful
// when temporary tables differ between version numbers.
// With the help of this version the right one can be chosen
// for the output.
System.out.println("DB2 major version " + db2release);
con.setAutoCommit(false);
822 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
parseResponse(parseType, rs, messageText);
if (rs != null)
rs.close();
cs.close();
}
catch (AdminDB2CommandException adce)
{
System.err.println("Program error: message=" + adce.getMessage());
}
catch (ClassNotFoundException e)
{
System.err.println("Could not load JDBC driver");
System.err.println("Exception: " + e);
e.printStackTrace();
}
catch (SQLException sqle)
{
System.err.println("SQLException information");
System.err.println("Error msg: " + sqle.getMessage());
System.err.println("SQLSTATE: " + sqle.getSQLState());
System.err.println("Error code: " + sqle.getErrorCode());
}
catch (Exception e)
{
System.out.println("Error: message=" + e.getMessage());
}
finally
{
// Release resources and disconnect
try { rs.close(); }
catch(Exception e) {}
try { cs.close(); }
catch(Exception e) {}
try { con.close(); }
catch(Exception e) {}
}
}
messageText.clear();
boolean hasResultSet = cs.execute();
if (hasResultSet)
{
rs = cs.getResultSet();
if (cs.getMoreResults())
if (ReturnCode > 0)
{
throw new AdminDB2CommandException(rc, "ADMIN_COMMAND_DB2 execution failed: " +
SQLMessage);
}
else if (IFIReturnCode != 0)
{
System.out.println("IFI error encountered:");
System.out.println("IFI return code = " + IFIReturnCode);
System.out.println("IFI reason code = " + IFIReasonCode);
System.out.println("IFI excess bytes = " + IFIExcessBytes);
System.out.println("IFI data sharing reason code = " + IFIDSReasonCode);
System.out.println("IFI data sharing excess bytes = " + IFIDSExcessBytes);
}
return rs;
}
824 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
System.out.println("STATUS = " + rs.getString(6).trim());
}
else if (parseType.equals(PARSE_THD))
{
System.out.println("TYPE = " + rs.getInt(2));
System.out.println("NAME = " + rs.getString(3).trim());
System.out.println("STATUS = " + rs.getString(4).trim());
System.out.println("ACTIVE = " + rs.getString(5).trim());
System.out.println("REQ = " + rs.getString(6).trim());
System.out.println("ID = " + rs.getString(7).trim());
System.out.println("AUTHID = " + rs.getString(8).trim());
System.out.println("PLAN = " + rs.getString(9).trim());
System.out.println("ASID = " + rs.getString(10).trim());
System.out.println("TOKEN = " + rs.getString(11).trim());
System.out.println("COORDINATOR = " + rs.getString(12).trim());
System.out.println("RESET = " + rs.getString(13).trim());
System.out.println("URID = " + rs.getString(14).trim());
System.out.println("LUWID = " + rs.getString(15).trim());
System.out.println("WORKSTATION = " + rs.getString(16).trim());
System.out.println("USERID = " + rs.getString(17).trim());
System.out.println("APPLICATION = " + rs.getString(18).trim());
System.out.println("ACCOUNTING = " + rs.getString(19).trim());
System.out.println("LOCATION = " + rs.getString(20).trim());
System.out.println("DETAIL = " + rs.getString(21).replace('\0',
'\n').trim());
}
else if (parseType.equals(PARSE_UT))
{
System.out.println("CSECT = " + rs.getString(2).trim());
System.out.println("USER = " + rs.getString(3).trim());
System.out.println("MEMBER = " + rs.getString(4).trim());
System.out.println("UTILID = " + rs.getString(5).trim());
System.out.println("STATEMENT = " + rs.getInt(6));
System.out.println("UTILITY = " + rs.getString(7).trim());
System.out.println("PHASE = " + rs.getString(8).trim());
System.out.println("COUNT = " + rs.getInt(9));
System.out.println("STATUS = " + rs.getString(10).trim());
System.out.println("DETAIL = " + rs.getString(11).replace('\0', '\n').trim());
System.out.println("NUM OBJ = " + rs.getInt(12));
System.out.println("LAST OBJ = " + rs.getInt(13));
}
else if (parseType.equals(PARSE_DDF))
{
System.out.println("STATUS = " + rs.getString(2).trim());
System.out.println("LOCATION = " + rs.getString(3).trim());
System.out.println("LUNAME = " + rs.getString(4).trim());
System.out.println("GENERICLU = " + rs.getString(5).trim());
System.out.println("IPV4ADDR = " + rs.getString(6).trim());
System.out.println("IPV6ADDR = " + rs.getString(7).trim());
System.out.println("TCPPORT = " + rs.getInt(8));
System.out.println("RESPORT = " + rs.getInt(9));
System.out.println("SQL DOMAIN = " + rs.getString(10).trim());
System.out.println("RSYNC DOMAIN = " + rs.getString(11).trim());
}
else if (parseType.equals(PARSE_GRP))
{
System.out.println("DB2 MEMBER = " + rs.getString(2).trim());
System.out.println("ID = " + rs.getInt(3));
System.out.println("SUBSYS = " + rs.getString(4).trim());
System.out.println("CMDPREF = " + rs.getString(5).trim());
if (messageText != null)
{
// Print informational message text
for (int i = 0; i < messageText.size(); i++)
{
if (messageText.get(i) != null)
System.out.println(messageText.get(i));
}
}
}
}
826 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
DBNAME = DSNDB06
SPACENAM =
TYPE = DB
PART = 0
STATUS = RW
TYPE = 1
NAME = SERVER
STATUS = SP
ACTIVE = *
REQ = 38
ID = db2jccmain
AUTHID = SYSADM
PLAN = DISTSERV
ASID = 0023
TOKEN = 23
COORDINATOR =
RESET =
URID =
LUWID =
WORKSTATION = BL3TFZVB
USERID = sysadm
APPLICATION = db2jccmain
ACCOUNTING =
LOCATION = ::FFFF:9.152.229.57
DETAIL = V429 CALLING PROCEDURE=SYSPROC.ADMIN_COMMAND_DB2,
PROC=V91AWLM1, ASID=0021, WLM_ENV=WLMENV1
V445-G91EBDD5.G1BE.C1A8A703DE26=23 ACCESSING DATA FOR
::FFFF:9.152.229.57
DSNU112I ) DSNUGDIS - NO AUTHORIZED UTILITY FOUND FOR UTILID = *
STATUS = STARTD
LOCATION = STLEC1
LUNAME = USIBMSY.SYEC1DB2
GENERICLU = -NONE
IPV4ADDR = ::9.30.189.213
IPV6ADDR =
TCPPORT = 446
RESPORT = 5001
SQL DOMAIN = w25ec213.svl.ibm.com
RSYNC DOMAIN = w25ec213.svl.ibm.com
DSNL090I DT=A CONDBAT= 64 MDBAT= 64
DSNL092I ADBAT= 1 QUEDBAT= 0 INADBAT= 0 CONQUED= 0
DSNL093I DSCDBAT= 0 INACONN= 0
DB2 MEMBER = ........
ID = 0
SUBSYS = V91A
CMDPREF = )
STATUS = ACTIVE
DB2 LVL = 910
SYSTEM NAME = ZS17PD
IRLM SUBSYS = PR21
IRLMPROC = PRLMPR21
*** BEGIN DISPLAY OF GROUP(........) GROUP LEVEL(...) MODE(N )
PROTOCOL LEVEL(3) GROUP ATTACH NAME(....)
Example A-18 shows the source code for invoking RUNSTATS on the recommended table
spaces.
//***************************************************************************
// Licensed Materials - Property of IBM
// 5635-DB2
// (C) COPYRIGHT 1982, 2006 IBM Corp. All Rights Reserved.
//
// STATUS = Version 9
//***************************************************************************
//Source file name: AdminUtilityExecution.java
//
//Sample: How to use the DB2 provided stored procedures DSNACCOX and
// ADMIN_UTL_SCHEDULE
//
//The user runs the program by issuing:
//java AdminUtilityExecution <alias or //server/database> <userid> <password>
//
//The arguments are:
//<alias> - DB2 subsystem alias for type 2 or //server/database for type 4
// connectivity
//<userid> - user ID to connect as
//<password> - password to connect with
//***************************************************************************
import java.sql.*;
// Parse arguments
if (args.length != 3)
{
System.err.println("Usage: AdminUtilityExecution <alias or //server/database>
<userid> <password>");
System.err.println("where <alias or //server/database> is DB2 subsystem alias or
//server/database for type 4 connectivity");
System.err.println(" <userid> is user ID to connect as");
System.err.println(" <password> is password to connect with");
828 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
return;
}
url += args[0];
userid = args[1];
password = args[2];
try
{
String QueryType = "RUNSTATS";
String ObjectType = "TS";
String ICType = "B";
String CatlgSchema = "SYSIBM";
String LocalSchema = "DSNACC";
int ChkLvl = 1 + 2 + 4 + 8;
String Criteria = "";
String Unused = "";
int CRUpdatedPagesPct = 20;
int CRUpdatedPagesAbs = 1000;
int CRChangesPct = 10;
int CRDaySncLastCopy = 7;
int ICRUpdatedPagesPct = 1;
int ICRUpdatedPagesAbs = 300;
int ICRChangesPct = 1;
int CRIndexSize = 1;
int RRTInsertsPct = 20;
int RRTInsertsAbs = 1000;
int RRTDeletesPct = 20;
int RRTDeletesAbs = 1000;
int RRTUnclustInsPct = 10;
int RRTDisorgLOBPct = 10;
int RRTDataSpaceRat = 10;
int RRTMassDelLimit = 0;
int RRTIndRefLimit = 10;
int RRIInsertsPct = 20;
int RRIInsertsAbs = 500;
int RRIDeletesPct = 20;
int RRIDeletesAbs = 500;
int RRIAppendInsertPct = 10;
int RRIPseudoDeletePct = 10;
int RRIMassDelLimit = 0;
int RRILeafLimit = 10;
int RRINumLevelsLimit = 0;
int SRTInsDelUpdPct = 15;
int SRTInsDelUpdAbs = 5;
int SRTMassDelLimit = 0;
int SRIInsDelUpdPct = 15;
int SRIInsDelUpdAbs = 5;
int SRIMassDelLimit = 0;
int ExtentLimit = 2;
String lastStatement = null;
int IFCARetCode = 0;
int IFCAResCode = 0;
int XSBytes = 0;
int rc = 0;
String resultMessage = null;
String message = null;
boolean hasResultSet = false;
830 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
con.commit();
resultMessage = cs.getString(44);
IFCARetCode = cs.getInt(45);
IFCAResCode = cs.getInt(46);
XSBytes = cs.getInt(47);
if (rc > 4)
{
switch (rc)
{
case 8:
message = "DSNACCOX execution failed: " + resultMessage;
break;
case 12:
lastStatement = cs.getString(42);
message = "DSNACCOX execution failed: " + resultMessage + " last statement: " +
lastStatement;
break;
case 14:
message = "DSNACCOX cannot access real-time statistics tables: " +
resultMessage;
break;
case 15:
message = "DSNACCOX encountered problem with declared temporary tables: " +
resultMessage;
break;
case 16:
message = "DSNACCOX was unable to define declared temporary tables: " +
resultMessage;
break;
}
if (hasResultSet)
{
rs = cs.getResultSet();
while (rs.next())
System.out.println("IFI message: " + rs.getString(2));
rs.close();
if (cs.getMoreResults())
{
int objects = 0;
rs = cs.getResultSet();
while (rs.next())
{
String db = rs.getString(1).trim();
String name = rs.getString(2).trim();
String status = rs.getString(9);
832 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
ps.setNull(4, Types.VARCHAR);
} else
{
ps.setString(4, db); // Object qualifier
}
ps.setString(5, name); // Object name
// m
System.out.println("Database: " + db + " Object: " + name);
if (objects > 0)
{
// Execute utilities in parallel
cs = con.prepareCall("CALL SYSPROC.ADMIN_UTL_SCHEDULE( ?, ?, ?, ?, ?, ?, " +
"?, ?, ?, ?, ?, ?, ?)");
cs.setShort(1, (short) 4); // Maximum parallel subtasks
cs.setString(2, "YES"); // Optimize workload
cs.setString(3, "ERROR"); // Stop condition
cs.setString(4, "RUNSTATS"); // Utility ID stem
cs.setNull(5, Types.FLOAT); // Shutdown
cs.setInt(6, objects); // Number of objects
cs.registerOutParameter(6, Types.INTEGER); // Number of objects
cs.registerOutParameter(7, Types.INTEGER); // Utilities executed
cs.registerOutParameter(8, Types.INTEGER); // Highest DSNUTILU return code
cs.registerOutParameter(9, Types.SMALLINT); // Actual parallel substasks
cs.registerOutParameter(10, Types.INTEGER); // Return code
cs.registerOutParameter(11, Types.VARCHAR); // Message area
hasResultSet = cs.execute();
con.commit();
if (rc > 4)
{
message = "ADMIN_UTL_SCHEDULE execution failed with RETURN_CODE " + rc;
if (hasMessage)
{
message += " message: " + resultMessage;
}
throw new AdminUtilityExecutionException(rc, message);
}
834 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
System.err.println("Program error: rc=" + re.getRC() + " message=" +
re.getMessage());
}
catch (ClassNotFoundException e)
{
System.err.println("Could not load JDBC driver");
System.err.println("Exception: " + e);
e.printStackTrace();
}
catch (SQLException ex)
{
System.err.println("SQLException information");
System.err.println("Error msg: " + ex.getMessage());
System.err.println("SQLSTATE: " + ex.getSQLState());
System.err.println("Error code: " + ex.getErrorCode());
}
finally
{
// Release resources and disconnect
try
{
ps.close();
} catch (Exception e)
{
}
try
{
ps2.close();
} catch (Exception e)
{
}
try
{
psDBType.close();
} catch (Exception e)
{
}
try
{
psTSType.close();
} catch (Exception e)
{
}
try
{
rs.close();
} catch (Exception e)
{
}
try
{
rsDBType.close();
} catch (Exception e)
{
}
try
{
cs.close();
} catch (Exception e)
{
}
try
{
con.close();
} catch (Exception e)
{
}
}
}
}
Example A-19 shows a sample output of the AdminUtilityExecution java driver. Due to the
provided threshold values, DSNACCOX recommended to run the RUNSTATS utility on two
table spaces, DSNDB06.SYSRTSTS and DSN00005.TABRWLMR.
836 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
OBJECTID = 0 TEXT = SHRLEVEL CHANGE
OBJECTID = 0 TEXT = DSNU610I ) 357 05:08:56.72 DSNUSUTP - SYSTABLEPART CATALOG UPDATE
FOR DSNDB06.SYSRTSTS SUCCESSFUL
OBJECTID = 0 TEXT = DSNU610I ) 357 05:08:56.73 DSNUSUTB - SYSTABLES CATALOG UPDATE FOR
SYSIBM.SYSTABLESPACESTATS SUCCESSFUL
OBJECTID = 0 TEXT = DSNU610I ) 357 05:08:56.80 DSNUSUCO - SYSCOLUMNS CATALOG UPDATE FOR
SYSIBM.SYSTABLESPACESTATS SUCCESSFUL
OBJECTID = 0 TEXT = DSNU610I ) 357 05:08:56.81 DSNUSUTB - SYSTABLES CATALOG UPDATE FOR
SYSIBM.SYSINDEXSPACESTATS SUCCESSFUL
OBJECTID = 0 TEXT = DSNU610I ) 357 05:08:56.91 DSNUSUCO - SYSCOLUMNS CATALOG UPDATE FOR
SYSIBM.SYSINDEXSPACESTATS SUCCESSFUL
OBJECTID = 0 TEXT = DSNU610I ) 357 05:08:56.92 DSNUSUTS - SYSTABLESPACE CATALOG UPDATE
FOR DSNDB06.SYSRTSTS SUCCESSFUL
OBJECTID = 0 TEXT = DSNU610I ) 357 05:08:56.93 DSNUSUIP - SYSINDEXPART CATALOG UPDATE
FOR SYSIBM.DSNRTX01 SUCCESSFUL
OBJECTID = 0 TEXT = DSNU610I ) 357 05:08:56.93 DSNUSUIP - SYSINDEXPART CATALOG UPDATE
FOR SYSIBM.DSNRTX02 SUCCESSFUL
OBJECTID = 0 TEXT = DSNU610I ) 357 05:08:56.94 DSNUSUIP - SYSINDEXPART CATALOG UPDATE
FOR SYSIBM.DSNRTX03 SUCCESSFUL
OBJECTID = 0 TEXT = DSNU610I ) 357 05:08:56.95 DSNUSUCO - SYSCOLUMNS CATALOG UPDATE FOR
SYSIBM.DSNRTX01 SUCCESSFUL
OBJECTID = 0 TEXT = DSNU610I ) 357 05:08:56.95 DSNUSUIX - SYSINDEXES CATALOG UPDATE FOR
SYSIBM.DSNRTX01 SUCCESSFUL
OBJECTID = 0 TEXT = DSNU610I ) 357 05:08:56.95 DSNUSUCO - SYSCOLUMNS CATALOG UPDATE FOR
SYSIBM.DSNRTX02 SUCCESSFUL
OBJECTID = 0 TEXT = DSNU610I ) 357 05:08:56.95 DSNUSUIX - SYSINDEXES CATALOG UPDATE FOR
SYSIBM.DSNRTX02 SUCCESSFUL
OBJECTID = 0 TEXT = DSNU610I ) 357 05:08:56.95 DSNUSUCO - SYSCOLUMNS CATALOG UPDATE FOR
SYSIBM.DSNRTX03 SUCCESSFUL
OBJECTID = 0 TEXT = DSNU610I ) 357 05:08:56.95 DSNUSUIX - SYSINDEXES CATALOG UPDATE FOR
SYSIBM.DSNRTX03 SUCCESSFUL
OBJECTID = 0 TEXT = DSNU610I ) 357 05:08:56.96 DSNUSUCD - SYSCOLDIST CATALOG UPDATE FOR
SYSIBM.DSNRTX01 SUCCESSFUL
OBJECTID = 0 TEXT = DSNU610I ) 357 05:08:56.99 DSNUSUCD - SYSCOLDIST CATALOG UPDATE FOR
SYSIBM.DSNRTX02 SUCCESSFUL
OBJECTID = 0 TEXT = DSNU610I ) 357 05:08:56.99 DSNUSUCD - SYSCOLDIST CATALOG UPDATE FOR
SYSIBM.DSNRTX03 SUCCESSFUL
OBJECTID = 0 TEXT = DSNU620I ) 357 05:08:56.99 DSNUSEOF - RUNSTATS CATALOG TIMESTAMP =
2007-12-23-05.08.56.673183
OBJECTID = 0 TEXT = DSNU010I 357 05:08:57.02 DSNUGBAC - UTILITY EXECUTION COMPLETE,
HIGHEST RETURN CODE=0
OBJECTID = 1 TEXT = 1DSNU000I 357 05:08:57.13 DSNUGUTC - OUTPUT START FOR UTILITY,
UTILID = RUNSTATS02000001
OBJECTID = 1 TEXT = DSNU1045I 357 05:08:57.23 DSNUGTIS - PROCESSING SYSIN AS UNICODE
UTF-8
OBJECTID = 1 TEXT = 0DSNU050I 357 05:08:57.24 DSNUGUTC - RUNSTATS TABLESPACE
DSN00005.TABRWLMR TABLE(ALL) SAMPLE 25 INDEX(ALL
)
OBJECTID = 1 TEXT = SHRLEVEL CHANGE
OBJECTID = 1 TEXT = DSNU718I ) 357 05:08:57.28 DSNUSIIX - NO INDEXES FOUND FOR
TABLESPACE 'DSN00005.TABRWLMR'
OBJECTID = 1 TEXT = DSNU610I ) 357 05:08:57.30 DSNUSUTP - SYSTABLEPART CATALOG UPDATE
FOR DSN00005.TABRWLMR SUCCESSFUL
OBJECTID = 1 TEXT = DSNU610I ) 357 05:08:57.30 DSNUSUPT - SYSTABSTATS CATALOG UPDATE FOR
USER.TAB_WLM_REFR SUCCESSFUL
OBJECTID = 1 TEXT = DSNU610I ) 357 05:08:57.31 DSNUSUPC - SYSCOLSTATS CATALOG UPDATE FOR
USER.TAB_WLM_REFR SUCCESSFUL
OBJECTID = 1 TEXT = DSNU610I ) 357 05:08:57.32 DSNUSUTB - SYSTABLES CATALOG UPDATE FOR
USER.TAB_WLM_REFR SUCCESSFUL
Example A-20 shows how to use the stored procedures for data set manipulation.
//***************************************************************************
// Licensed Materials - Property of IBM
// 5635-DB2
// (C) COPYRIGHT 1982, 2006 IBM Corp. All Rights Reserved.
//
// STATUS = Version 9
//***************************************************************************
// Source file name: AdminDataSet.java
//
// Sample: How to use the DB2 provided data set manipulation stored
// procedures
//
//The user runs the program by issuing:
//java AdminDataSet <alias or //server/database> <userid> <password>
//
//The arguments are:
//<alias> - DB2 subsystem alias for type 2 or //server/database for type 4
// connectivity
//<userid> - user ID to connect as
//<password> - password to connect with
//***************************************************************************
import java.sql.*;
838 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
String userid = null;
String password = null;
// Parse arguments
if (args.length != 3)
{
System.err.println("Usage: AdminDataSet <alias or //server/database> <userid>
<password>");
System.err.println("where <alias or //server/database> is DB2 subsystem alias or
//server/database for type 4 connectivity");
System.err.println(" <userid> is user ID to connect as");
System.err.println(" <password> is password to connect with");
return;
}
url += args[0];
userid = args[1];
password = args[2];
try
{
String dsName = userid + ".DSTEST";
String dsName2 = userid + ".DSTEST2";
int rc = 0;
String message = null;
boolean hasResultSet = false;
// Connect to database
con = DriverManager.getConnection(url, userid, password);
con.setAutoCommit(false);
cs.execute();
con.commit();
hasResultSet = cs.execute();
840 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
if (rc > 0)
{
message = cs.getString(7);
throw new AdminDataSetException(rc, "ADMIN_DS_RENAME execution failed: " +
message);
}
else
{
cs.close();
System.out.println(dsName + " renamed to " + dsName2 + ".");
}
hasResultSet = cs.execute();
System.out.println("---------------------------------------------------------------");
System.out.println("DSNAME = " + rs.getString(1).trim());
System.out.println("CREATE_YEAR = " + rs.getInt(2));
System.out.println("CREATE_DAY = " + rs.getInt(3));
System.out.println("TYPE = " + rs.getInt(4));
System.out.println("VOLUME = " + rs.getString(5).trim());
System.out.println("PRIMARY_EXTENT = " + rs.getInt(6));
System.out.println("SECONDARY_EXTENT = " + rs.getInt(7));
System.out.println("MEASUREMENT_UNIT = " + rs.getString(8).trim());
System.out.println("EXTENTS_IN_USE = " + rs.getInt(9));
System.out.println("DASD_USAGE = " + rs.getString(10));
System.out.println("HARBA = " + rs.getString(11));
System.out.println("HURBA = " + rs.getString(12));
System.out.println("---------------------------------------------------------------");
}
}
rs.close();
cs.close();
}
cs.execute();
con.commit();
842 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
System.err.println("Program error: rc=" + adse.getRC() + " message=" +
adse.getMessage());
}
catch (ClassNotFoundException e)
{
System.err.println("Could not load JDBC driver");
System.err.println("Exception: " + e);
e.printStackTrace();
}
catch (SQLException sqle)
{
System.err.println("SQLException information");
System.err.println("Error msg: " + sqle.getMessage());
System.err.println("SQLSTATE: " + sqle.getSQLState());
System.err.println("Error code: " + sqle.getErrorCode());
}
finally
{
// Release resources and disconnect
try
{
ps.close();
} catch (Exception e)
{
}
try
{
rs.close();
} catch (Exception e)
{
}
try
{
cs.close();
} catch (Exception e)
{
}
try
{
con.close();
} catch (Exception e)
{
}
}
}
}
844 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
HURBA = ffffffffffff
---------------------------------------------------------------
---------------------------------------------------------------
PAOLOR3.DSTEST2 deleted.
//***************************************************************************
// Licensed Materials - Property of IBM
// 5635-DB2
// (C) COPYRIGHT 1982, 2006 IBM Corp. All Rights Reserved.
//
// STATUS = Version 9
//***************************************************************************
// Source file name: AdminJob.java
//
// Sample: How to use the DB2 provided JCL administration stored procedures
//
//The user runs the program by issuing:
//java AdminJob <alias or //server/database> <userid> <password>
//
//The arguments are:
//<alias> - DB2 subsystem alias for type 2 or //server/database for type 4
// connectivity
//<userid> - user ID to connect as
//<password> - password to connect with
//***************************************************************************
import java.sql.*;
// Parse arguments
if (args.length != 3)
{
System.err.println("Usage: AdminJob <alias or //server/database> <userid>
<password>");
try
{
String jobid = null;
String[] jclstmt =
{
"//IEBCOPY JOB ,CLASS=K,MSGCLASS=H,MSGLEVEL=(1,1)",
"//COPY EXEC PGM=IEBCOPY,DYNAMNBR=20",
"//SYSUT1 DD DSN=SG247083.PROD.SOURCE,DISP=SHR",
"//SYSUT2 DD DSN=SG247083.PROD.SOURCE,DISP=SHR",
"//SYSPRINT DD SYSOUT=*",
"//SYSIN DD *"
};
int jobstatus = 0;
int retrycount = 0;
int rc = 0;
String message = null;
boolean hasResultSet = false;
// Connect to database
con = DriverManager.getConnection(url, userid, password);
con.setAutoCommit(false);
// Submit JCL
ps = con.prepareStatement("INSERT INTO SYSIBM.JOB_JCL(ROWNUM, STMT) VALUES(?, ?)");
for (int i = 0; i < jclstmt.length; i++)
{
ps.setInt(1, i + 1);
ps.setString(2, jclstmt[i]);
ps.execute();
}
846 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
}
else
{
jobid = cs.getString(3);
System.out.println("Job " + jobid + " submitted successfully.");
ps.close();
cs.close();
}
while (true)
{
cs.execute();
con.commit();
if (rc == 0)
{
// The job is in the OUTPUT queue
if (jobstatus == 3)
{
System.out.println("Job " + jobid + " finished execution. Job completion
information: ");
System.out.println(" Max RC: " + cs.getInt(5));
System.out.println(" Completion type: " + cs.getInt(6));
System.out.println(" System abend code: " + cs.getInt(7));
System.out.println(" User abend code: " + cs.getInt(8));
break;
}
else if (jobstatus == 1 || jobstatus == 2)
{
// The job is in the INPUT or ACTIVE queue
System.out.println("Job " + jobid + " is in the " + (jobstatus == 1 ? "INPUT"
: "ACTIVE") + " queue. Waiting for job to finish...");
Thread.sleep(1000);
continue;
}
cs.close();
System.out.println("Job " + jobid + " has finished and has output to be fetched.");
848 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
}
if (rc > 0)
{
message = cs.getString(6);
throw new AdminJobException(rc, "SYSPROC.ADMIN_JOB_CANCEL execution failed: " +
message);
}
else
{
System.out.println("Job " + jobid + " has been purged.");
cs.close();
}
}
catch (AdminJobException aje)
{
System.err.println("Program error: rc=" + aje.getRC() + " message=" +
aje.getMessage());
}
catch (ClassNotFoundException e)
{
System.err.println("Could not load JDBC driver");
System.err.println("Exception: " + e);
e.printStackTrace();
}
catch (SQLException sqle)
{
System.err.println("SQLException information");
System.err.println("Error msg: " + sqle.getMessage());
System.err.println("SQLSTATE: " + sqle.getSQLState());
System.err.println("Error code: " + sqle.getErrorCode());
}
catch (Exception e)
{
System.err.println("Error: message=" + e.getMessage());
}
finally
{
// Release resources and disconnect
try
{
ps.close();
} catch (Exception e)
{
}
try
{
cs.close();
} catch (Exception e)
{
}
try
{
con.close();
} catch (Exception e)
{
}
}
}
}
850 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
J E S 2 J O B L O G -- S Y S T E M S T L 0 -- N O D E S T L V
M 3
Example A-24 shows how to submit USS commands through stored procedures.
//***************************************************************************
// Licensed Materials - Property of IBM
// 5635-DB2
// (C) COPYRIGHT 1982, 2006 IBM Corp. All Rights Reserved.
//
// STATUS = Version 9
//***************************************************************************
// Source file name: AdminUNIXCommand.java
//
// Sample: How to use the DB2 provided stored procedures to issue
// a USS command.
//
//The user runs the program by issuing:
//java AdminUNIXCommand <alias or //server/database> <userid> <password>
//
//The arguments are:
//<alias> - DB2 subsystem alias for type 2 or //server/database for type 4
// connectivity
//<userid> - user ID to connect as
//<password> - password to connect with
//***************************************************************************
import java.sql.*;
// Parse arguments
if (args.length != 3)
{
System.err.println("Usage: AdminUNIXCommand <alias or //server/database> <userid>
<password>");
System.err.println("where <alias or //server/database> is DB2 subsystem alias or
//server/database for type 4 connectivity");
System.err.println(" <userid> is user ID to connect as");
System.err.println(" <password> is password to connect with");
return;
}
url += args[0];
userid = args[1];
password = args[2];
try
852 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
{
int rc = 0;
String message = null;
boolean hasResultSet = false;
// Connect to database
con = DriverManager.getConnection(url, userid, password);
con.setAutoCommit(false);
}
finally
{
// Release resources and disconnect
try
{
rs.close();
} catch (Exception e)
{
}
try
{
cs.close();
} catch (Exception e)
{
}
try
{
con.close();
} catch (Exception e)
{
}
}
}
}
854 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
A.8 Issue DSN subcommands with AdminDSNSubcommand
AdminDSNSubcommand uses the DB2-supplied stored procedure
ADMIN_COMMAND_DSN to issue a REBIND PACKAGE command.
Example A-26 shows how to submit DSN subcommands through stored procedures.
//***************************************************************************
// Licensed Materials - Property of IBM
// 5635-DB2
// (C) COPYRIGHT 1982, 2006 IBM Corp. All Rights Reserved.
//
// STATUS = Version 9
//***************************************************************************
// Source file name: AdminDSNSubcommand.java
//
// Sample: How to use the DB2 provided procedure ADMIN_COMMAND_DSN to issue
// DSN subcommands.
//
//The user runs the program by issuing:
//java AdminDSNSubcommand <alias or //server/database> <userid> <password>
//
//The arguments are:
//<alias> - DB2 subsystem alias for type 2 or //server/database for type 4
// connectivity
//<userid> - user ID to connect as
//<password> - password to connect with
//***************************************************************************
import java.sql.*;
// Parse arguments
if (args.length != 3)
{
System.err.println("Usage: AdminDSNSubcommand <alias or //server/database> <userid>
<password>");
System.err.println("where <alias or //server/database> is DB2 subsystem alias or
//server/database for type 4 connectivity");
System.err.println(" <userid> is user ID to connect as");
System.err.println(" <password> is password to connect with");
return;
}
url += args[0];
userid = args[1];
password = args[2];
try
// Connect to database
con = DriverManager.getConnection(url, userid, password);
con.setAutoCommit(false);
if (hasResultSet)
{
rs = cs.getResultSet();
while (rs.next())
{
System.out.println(rs.getString(2).trim());
}
rs.close();
}
856 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
}
try
{
cs.close();
} catch (Exception e)
{
}
try
{
con.close();
} catch (Exception e)
{
}
}
}
}
AdminDSNSubcommandException(String message)
{
super(message);
}
}
The scenario requires that the stored procedure DSNUTILU is executed only once at a later
time. The main scheduling parameters involved in this scenario are BEGIN_TIMESTAMP and
MAX_INVOCATIONS. Because there is no END_TIMESTAMP, the stored procedures validity
time window would never expire. It is the value of the MAX_INVOCATIONS parameter that
constraints the task to be executed only once. The DSNUTILU input parameters are known at
scheduling time and the stored procedure is only executed once, therefore the
PROCEDURE_INPUT parameter is initialized in a static way. Furthermore, the task name is
set to REORG_JOB.
The Java sample in Example A-28 shows how the parameters of ADMIN_TASK_ADD are
properly initialized to schedule a CALL to DSNUTILU at 01:00AM on the October 30. The
created task is named REORG_JOB. Note that the stored procedure parameters USERID
and PASSWORD are initialized with some dummy values (MYUSERID, MYPASSWD). When
using this sample, substitute these values with valid credentials.
858 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
// <alias> - DB2 subsystem alias for type 2 or //server/database for
// type 4
// connectivity
// <userid> - user ID to connect as
// <password> - password to connect with
//***************************************************************************
import java.sql.*;
// Parse arguments
if (args.length != 3)
{
System.err.println("Usage: AdminSchedule1 <alias or //server/database> <userid>
<password>");
System.err.println("where <alias or //server/database> is DB2 subsystem alias or
//server/database for type 4 connectivity");
System.err.println(" <userid> is user ID to connect as");
System.err.println(" <password> is password to connect with");
return;
}
url += args[0];
userid = args[1];
password = args[2];
try
{
int rc = 0;
String message = null;
// Connect to database
con = DriverManager.getConnection(url, userid, password);
con.setAutoCommit(false);
/* Schedule task */
cs.execute();
860 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
System.err.println("Could not load JDBC driver");
System.err.println("Exception: " + e);
e.printStackTrace();
}
catch (SQLException sqle)
{
System.err.println("SQLException information");
System.err.println("Error msg: " + sqle.getMessage());
System.err.println("SQLSTATE: " + sqle.getSQLState());
System.err.println("Error code: " + sqle.getErrorCode());
}
finally
{
// Release resources and disconnect
try {
if(cs != null)
cs.close();
}
catch (Exception e) {
}
try {
if(con != null) {
con.commit();
con.close();
}
}
catch (Exception e) {
}
}
}
}
Only the two columns WLM_ENV and SSID are relevant for the WLM_REFRESH call. The
TASKNAME column is populated by the trigger with the generic name WLM_REF_X, and is
also used for the TASK_NAME parameter when the WLM_REFRESH call is scheduled. The
additional columns with the prefix TASK_ are just employed for the output parameter handling
of the called ADMIN_TASK_ADD stored procedure.
862 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
END%
Note that the USERID and PASSWORD scheduling parameters need to be populated with
valid credentials before ultimately employing this example. Furthermore, be aware that the
creator of the scheduled task is the ID that executes the triggering insert event.
The first row that is inserted into the table schedules a task, with the task name WLM_REF_1,
where the identity column of the table is employed to create unique task names.
Generally, it is good practice to remove tasks from the scheduler task lists as soon as they are
no longer required. The trigger shown in Example A-31 calls ADMIN_TASK_REMOVE to
remove the WLM_REFRESH task from the scheduler that is associated with the deleted row
in the table.
Due to the 1-1 mapping of the TASKNAME column in the USER.TAB_WLM_REFR and the
TASK_NAME in the scheduler, the associated scheduler task can be removed with the help of
the transition variable REMWLM.TASKNAME. An SQL statement like the following would
remove the task WLM_REF_1 from the scheduler:
DELETE FROM USER.TAB_WLM_REFR WHERE TASKNAME = 'WLM_REF_1';
Example: A-32 Sample invocation of non-regularly recurring procedure with dynamic parameters
/* No task triggering */
cs.setNull( 8, Types.VARCHAR); // TRIGGER_TASK_NAME
cs.setNull( 9, Types.CHAR); // TRIGGER_TASK_COND
cs.setNull(10, Types.INTEGER); // TRIGGER_TASK_CODE
/* Schedule task */
cs.execute();
864 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
The schema of the table referenced by the PROCEDURE_INPUT scheduling parameter
could be similar like this:
CREATE TABLE USER.INPUT_PARMS
( ID INTEGER GENERATED ALWAYS AS IDENTITY,
WLM_ENV VARCHAR(32),
SSID VARCHAR(4));
If the SELECT statement returns multiple rows, the scheduler will use the first row retrieved to
populate the WLM_REFRESH input parameters. In order to invoke the scheduled stored
procedure with different input parameter values the next time it is executed, the first qualifying
row of the SELECT statement has to be updated. To avoid confusion, the SELECT statement
should generally return only one row or alternatively employ the ORDER BY clause, for
example:
SELECT WLM_ENV, SSID from USER.INPUT_PARMS where ID = 1;
The scenario requires that TRIGGER_TASK_NAME is properly set to the existing REORG
job. All other scheduling parameters can be initialized with NULL. Furthermore, DSNUTILU
should be executed even if the triggering REORG job did not run successfully. Therefore, the
TRIGGER_TASK_COND and TRIGGER_TASK_CODE scheduling parameters are set to
NULL as well. Similar to use case 1, PROCEDURE_INPUT contains static values for the
parameters.
The sample code in Example A-33 shows the proper initialization of the ADMIN_TASK_ADD
stored procedure to schedule a DSNUTILU call that invokes the COPY utility. This call is
triggered by the execution of the existing REORG job REORG_JOB.
/* Schedule task */
cs.execute();
Note the additional CREATOR predicate that is set to the calling user ID. This is necessary in
the application program, because the table functions would otherwise return tasks that cannot
be deleted by the following ADMIN_TASK_REMOVE call, because the calling user ID and the
user ID that added the task do not match. This would return an error and the fetch loop would
be aborted.
Example A-34 only returns and removes expired tasks that have been added with the user ID,
which is also used for establishing the JDBC connection to the server.
866 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
// Licensed Materials - Property of IBM
// 5635-DB2
// (C) COPYRIGHT 1982, 2006 IBM Corp. All Rights Reserved.
//
// STATUS = Version 9
//***************************************************************************
// Source file name: AdminScheduleR.java
//
// Sample: How to use the scheduler to remove tasks from the task list that
// are no longer valid
//
// The user runs the program by issuing:
// java AdminScheduleR <alias or //server/database> <userid> <password>
//
// The arguments are:
// <alias> - DB2 subsystem alias for type 2 or //server/database for type 4
// connectivity
// <userid> - user ID to connect as
// <password> - password to connect with
//***************************************************************************
import java.sql.*;
// Parse arguments
if (args.length != 3)
{
System.err.println("Usage: AdminScheduleR <alias or //server/database> <userid>
<password>");
System.err.println("where <alias or //server/database> is DB2 subsystem alias or
//server/database for type 4 connectivity");
System.err.println(" <userid> is user ID to connect as");
System.err.println(" <password> is password to connect with");
return;
}
url += args[0];
userid = args[1];
password = args[2];
try
{
int rc = 0;
String message = null;
String task_name = null;
ps.setString(1, userid);
rs = ps.executeQuery();
while ( rs.next() ) {
task_name = rs.getString(1);
System.out.println("Remove Task_Name: " + task_name);
//ADMIN_TASK_REMOVE parameters
cs.setString(1, task_name); // TASK_NAME
cs.registerOutParameter(2, Types.INTEGER); // RETURN CODE
cs.registerOutParameter(3, Types.VARCHAR); // MESSAGE
// Remove task
cs.execute();
con.commit();
rc = cs.getInt(2);
if (rc == 0)
{
/* Task successfully scheduled */
System.out.println("Task " + task_name + " successfully removed");
}
else
{
/* Error during task scheduling */
message = cs.getString(3);
throw new AdminScheduleException(rc,
"ADMIN_TASK_REMOVE execution failed: " + message);
}
}
}
catch (AdminScheduleException ase)
{
System.err.println("Program error: rc=" + ase.getRC() + " message=" +
ase.getMessage());
}
catch (ClassNotFoundException e)
{
System.err.println("Could not load JDBC driver");
System.err.println("Exception: " + e);
e.printStackTrace();
}
catch (SQLException sqle)
{
System.err.println("SQLException information");
System.err.println("Error msg: " + sqle.getMessage());
System.err.println("SQLSTATE: " + sqle.getSQLState());
868 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
System.err.println("Error code: " + sqle.getErrorCode());
}
finally
{
// Release resources and disconnect
try
{
cs.close();
} catch (Exception e){}
try
{
con.close();
} catch (Exception e){}
}
}
}
Example A-35 shows the output of the ADMIN_TASK_LIST table function. All listed tasks
feature an execution status different than RUNNING.
The program basically consists of two classes: The class SPDriver.java contains the main
method and instantiates an object of the class SPWrapper.java that provides the service
routines to eventually CALL the desired stored procedure.
Example A-37 shows the first part of the class SPDriver. It contains the definition of the XML
documents that are involved and also a method that gets a Connection object, which will be
used to CALL the respective stored procedures. Be aware that the stored procedure
GET_SYSTEM_INFO is invoked first in Complete Mode. The program assumes that the
XML_COMPLETE_MODE document exists in the search path. Therefore, create a file named
CompleteMode.xml and insert the following valid XML document. See Example A-36.
Furthermore, create the XML_FILTER_DOC XML document and insert a dummy string, for
example this is not a valid XPATH.
//***************************************************************************
// Licensed Materials - Property of IBM
// 5635-DB2
// (C) COPYRIGHT 1982, 2006 IBM Corp. All Rights Reserved.
//
// STATUS = Version 9
//***************************************************************************
// Source file name: SPDriver
//
// Sample: This sample calls the stored procedure SYSPROC.GET_SYSTEM_INFO
// first in Complete-Mode to retrieve a template XML input document.
// Then the XMLPropertyListConfiguration classes are used to verify
// the returned XML document and to insert the required input data.
// A second CALL employs then the augmented XML document to obtain
// the desired data.
// A third CALL is issued against SYSPROC.GET_CONFIG with an invalid
// XML_FILTER, the returned positive SQLCODE warning and message
// tokens are then wrapped into an XML_INPUT document for a
870 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
// following GET_MESSAGE CALL to obtain the respective short
// message text.
// This class instantiates an object of class SPWrapper.
//
//The user runs the program by issuing:
//java SPDriver <alias or //server/database> <userid> <password>
//
//The arguments are:
//<alias> - DB2 subsystem alias for type 2 or //server/database for type 4
// connectivity
//<userid> - user ID to connect as
//<password> - password to connect with
//***************************************************************************
// Connection information
private static String url = "jdbc:db2:";
private static final String driver = "com.ibm.db2.jcc.DB2Driver";
// Stored procedure information
private static final String GS = "SYSPROC.GET_SYSTEM_INFO";
private static final String GM = "SYSPROC.GET_MESSAGE";
private static final String GC = "SYSPROC.GET_CONFIG";
// Document information
private static final String XML_COMPLETE_MODE = "CompleteMode.xml";
private static final String XML_INPUT_DOC_GS = "XML_Input_gs.xml";
private static final String XML_INPUT_TEMPLATE_GS = "XML_TemplateIN_gs.xml";
private static final String XML_OUTPUT_DOC_GS = "XML_Output_gs.xml";
private static final String XML_INPUT_DOC_GM = "XML_Input_gm.xml";
private static final String XML_OUTPUT_DOC_GM = "XML_Output_gm.xml";
private static final String XML_OUTPUT_DOC_GC = "XML_Output_gc.xml";
private static final String XML_FILTER_DOC = "XML_Filter.xml";
private static final String XML_MESSAGE_DOC = "XML_Message.xml";
// Connect to database
con = DriverManager.getConnection(url, userid, password);
con.setAutoCommit(false);
}
catch (ClassNotFoundException cnfe) {
System.err.println("Could not load JDBC driver");
System.err.println("Exception: " + cnfe);
cnfe.printStackTrace();
return null;
} catch (SQLException sqle) {
System.err.println("SQLException information");
System.err.println("Error msg: " + sqle.getMessage());
System.err.println("SQLSTATE: " + sqle.getSQLState());
System.err.println("Error code: " + sqle.getErrorCode());
return null;
}
return con;
The main method first of all parses the provided arguments, obtains a Connection object, and
then instantiates an Object of the class SPWrapper. The calling sequence which is driven by
the main method is as follows:
CALL SYSPROC.GET_SYSTEM_INFO in Complete Mode and materialize the XML
template input document returned in the XML_OUTPUT parameter in
XML_INPUT_TEMPLATE_GS.
Augment the returned XML template input document with a valid SMPCSI data set name
and add two SYSMODs to the respective sections.
In the sample provided, the SMPCSI data set name is IEL350.GLOBAL.CSI, the names of
the SYSMODs are: AK16335, H0A4220. The name of the new XML input document is
specified in XML_INPUT_DOC_GS.
CALL SYSPROC.GET_SYSTEM_INFO a second time with the augmented and valid XML
input document.
Materialize the complete XML_OUTPUT document that now contains the gathered
system-related data and additionally information about the queried SYSMODs. The XML
output document is written to XML_OUTPUT_DOC_GS.
CALL SYSPROC.GET_CONFIG with an invalid XPath in the XML_FILTER input
parameter document. As expected, the CALL will fail with a SQLCODE of +20458. The
document containing the filter is defined in XML_FILTER_DOC.
To obtain the short message text associated to +20458, the stored procedure
GET_MESSAGE is invoked with an XML_INPUT document specifying the +20458
SQLCODE as well as the message tokens returned in the SQLERRMC structure. The
input document is materialized in XML_INPUT_DOC_GM:
CALL SYSPROC.GET_MESSAGE
The short message returned in the GET_MESSAGE XML output document text lists the
following explanation:
Short Message Text for SQLCODE: 20458:
DSNT404I SQLCODE = 20458, WARNING: THE PROCEDURE GET_CONFIG HAS ENCOUNTERED AN
INTERNAL PARAMETER PROCESSING ERROR IN PARAMETER 5. THE VALUE FOR PARAMETER 7
CONTAINS FURTHER INFORMATION ABOUT THE ERROR.
According to this message text, the CALL to SYSPROC.GET_CONFIG returned a
XML_MESSAGE output document which should contain further debug information. Taking
a look at the materialized XML_MESSAGE_DOC shows the following reasonable explanation:
DSNA630I DSNADMGC A PARAMETER FORMAT OR CONTENT ERROR WAS FOUND. Invalid XPath
expression for filtering the output document. Found string beginning with 'this
is not a valid XPATH' at position 1.
872 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
SPWrapper spDriver = null;
Connection dbCon = null;
String userid = null;
String password = null;
int callRC = 0;
int sqlcode = 0;
// Parse arguments
if (args.length != 3) {
System.err
.println("Usage: Get_Message <alias or //server/database> <userid>
<password>");
System.err
.println("where <alias or //server/database> is DB2 subsystem alias or
//server/database for type 4 connectivity");
System.err.println(" <userid> is user ID to connect as");
System.err.println(" <password> is password to connect with");
return;
}
url += args[0];
userid = args[1];
password = args[2];
The class SPWrapper.java provides the functionality to eventually CALL the stored
procedures and process the input and output parameters.
All XML documents are passed as BLOB to and from the stored procedures. The input
documents are read from a file and the respective InputStream is then directly used as input
parameter, for invoking cstmt.setBinaryStream(). Refer to the function callSP(). The output
BLOBs are materialized to files as well, by using byte arrays. Refer to function
saveBlob2File() as a sample.
As mentioned above, the program employs the Jakarta Commons Configuration. It makes
use of the XMLPropertyListConfiguration interface implementation. This requires the following
JAR files to be contained in the search path:
commons-configuration.jar
commons-codec.jar
commons-beanutils.jar
874 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
commons-digester.jar
commons-collections.jar
commons-logging.jar
commons-lang.jar
import java.io.*;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.plist.XMLPropertyListConfiguration;
// XMLPropertyList
private final String CSI_KEY_NAME = "Optional Parameters.SMPCSI Data Set.Value";
private final String CSI_KEY_VALUE = "IEL350.GLOBAL.CSI";
private final String SYSMOD_KEY_NAME = "Optional Parameters.SYSMOD.Value";
// Constructor
public SPWrapper(Connection con) {
dbCon = con;
msgTokens = new ArrayList();
}
876 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
private void saveBlob2File(Blob blob, String fn) {
PrintWriter pw = null;
String xmlInString = null;
long xmlInLength = 0;
byte xmlInByte[] = null;
try {
// Open OutputStream to save the XML document
pw = new PrintWriter(new File(fn), "utf-8");
// Write to OutputStream
pw.write(xmlInString);
pw.close();
} catch (IOException ioe) {
System.err.println("IOException: " + ioe);
ioe.printStackTrace();
}
catch (SQLException sqle) {
System.err.println("SQLException information");
System.err.println("Error msg: " + sqle.getMessage());
shortMSGTxt = (String)configPlist.getProperty(
"Short Message Text.Value");
878 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
configPlist.setProperty(CSI_KEY_NAME, CSI_KEY_VALUE);
try {
cstmt = dbCon.prepareCall(call_statement);
880 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
/* XML_OUTPUT document */
if (!outputFn.trim().equalsIgnoreCase("null")) {
output_Blob = cstmt.getBlob(6);
if (output_Blob == null) {
System.out.println("XML_OUTPUT: NULL");
} else {
saveBlob2File(output_Blob, outputFn);
if (output_Blob.length() == 0) {
System.out.println("XML_OUTPUT: Empty\n");
} else if (xml_Filter.trim().equalsIgnoreCase("null")) {
// Validate only if XML_OUTPUT not null and XML_FILTER null
System.out.println("Common Configuration validation result: ");
// Verify the returned Plist XML document
if (verificationPropertyList(outputFn)) {
System.out.println(
"XML_OUTPUT complies with plist version 1.0.\n");
} else {
System.err.println(
"XML_OUTPUT does not comply with plist version 1.0.\n");
return -1;
}
}
}
}
// XML_MESSAGE document
if(!messageFn.trim().equalsIgnoreCase("null")) {
message_Blob = cstmt.getBlob(7);
if (message_Blob == null) {
System.out.println("XML_MESSAGE: NULL");
} else {
saveBlob2File(message_Blob, messageFn);
if (message_Blob.length() == 0) {
System.out.println("XML_MESSAGE: Empty\n");
} else {
System.out.println("Common Configuration validation result: ");
// Verify the returned Plist XML document
if (verificationPropertyList(messageFn)) {
System.out.println(
"XML_MESSAGE complies with plist version 1.0.\n");
}
else {
System.err.println(
"XML_MESSAGE does not comply with plist version 1.0.\n");
return -1;
}
}
}
}
}
catch (SQLException sqle) {
System.err.println("SQLException information");
System.err.println("Error msg: " + sqle.getMessage());
// init global debug variables
SQLCODE = sqle.getErrorCode();
SQLSTATE = sqle.getSQLState();
chopTokens(sqle.getMessage());
} catch (IOException ioe) {
System.err.println("IOException: " + ioe);
ioe.printStackTrace();
Compile SPDriver.java and SPWrapper.java then enter the following command to execute it:
java SPDriver DBALIAS USERID PASSWORD
Output parameters:
Major Version returned: 1
Minor Version returned: 0
Common Configuration validation result:
XML_OUTPUT complies with plist version 1.0.
XML_MESSAGE: NULL
1st SP CAll successful
Output parameters:
Major Version returned: 1
Minor Version returned: 0
Common Configuration validation result:
XML_OUTPUT complies with plist version 1.0.
XML_MESSAGE: NULL
2nd Call successful
882 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
SQL Warning: DB2 SQL error: SQLCODE: 20458, SQLSTATE: 01H54, SQLERRMC: GET_CONFIG;5;7
Output parameters:
Major Version returned: 1
Minor Version returned: 0
XML_OUTPUT: NULL
An error occurred during the 3rd CALL
Common Configuration validation result:
XML_MESSAGE complies with plist version 1.0.
Output parameters:
Major Version returned: 1
Minor Version returned: 0
Common Configuration validation result:
XML_OUTPUT complies with plist version 1.0.
XML_MESSAGE: NULL
Short Message Text for SQLCODE: 20458:
DSNT404I SQLCODE = 20458, WARNING: THE PROCEDURE GET_CONFIG HAS ENCOUNTERED AN INTERNAL
PARAMETER PROCESSING ERROR IN PARAMETER 5. THE VALUE FOR PARAMETER 7 CONTAINS FURTHER
INFORMATION ABOUT THE ERROR.
// Parse arguments
if (args.length != 3)
{
System.err.println("Usage: GetConfDriver <alias or //server/database> <userid>
<password>");
System.err.println("where <alias or //server/database> is DB2 subsystem alias or
//server/database for type 4 connectivity");
System.err.println(" <userid> is user ID to connect as");
System.err.println(" <password> is password to connect with");
return;
}
url += args[0];
userid = args[1];
password = args[2];
try {
byte[] xml_input;
String str_xmlfilter = new String(
"/plist/dict/key[.='DB2 Subsystem Specific Information']/following-sibling::dict[1]"
+
"/key[.='V91A']/following-sibling::dict[1]" +
"/key[.='DB2 Distributed Access Information']/following-sibling::dict[1]" +
"/key[.='IP Address']/following-sibling::dict[1]" +
"/key[.='Value']/following-sibling::string[1]");
// Connect to database
con = DriverManager.getConnection(url, userid, password);
con.setAutoCommit(false);
884 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
cstmt.setString(3, "en_US");
// No Input document
cstmt.setObject(4, null, Types.BLOB);
cstmt.setObject(5, xml_filter, Types.BLOB);
// Output Parms
cstmt.registerOutParameter(1, Types.INTEGER);
cstmt.registerOutParameter(2, Types.INTEGER);
cstmt.registerOutParameter(6, Types.BLOB);
cstmt.registerOutParameter(7, Types.BLOB);
cstmt.execute();
con.commit();
if(b_out != null)
{
int out_length = (int)b_out.length();
byte[] bxml_output = new byte[out_length];
//Close streams
instr_out.close();
fxml_out.close();
}
//Close streams
instr_msg.close();
fxml_msg.close();
}
}
catch (SQLException sqle) {
System.out.println("Error during CALL "
+ " SQLSTATE = " + sqle.getSQLState()
+ " SQLCODE = " + sqle.getErrorCode()
+ " : " + sqle.getMessage());
}
catch (Exception e) {
System.out.println("Internal Error " + e.toString());
}
finally
{
if(cstmt != null)
try { cstmt.close(); } catch ( SQLException sqle) { sqle.printStackTrace(); }
if(con != null)
try { con.close(); } catch ( SQLException sqle) { sqle.printStackTrace(); }
}
}
}
Verify the created file ml_output.xml to obtain your data server’s IP address.
886 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
B
Select the Additional materials and open the directory that corresponds with this book form
number, SG247604.
The zip files that accompany this book contain all of the sample files referenced in the book.
Important: Before downloading, we strongly suggest that you first read 3.3, “Sample
application components” on page 24 to decide what components are applicable to your
environment.
Note: The additional Web material that accompanies this book includes the files described in
the following sections.
888 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
In the CALDTLnC JCL examples, the last DD card
//CARDIN DD DSN=SG247604.CALDTL1C.CARDIN,DISP=SHR
simply indicates a sequential file to be allocated and used to pass a valid employee number to
the stored procedure.
890 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
EMPRSETS.DDL
EMPRSETS.JCL
SQLSPCUS.JCL
B.1.11 Sample code for invoking the Common SQL API stored procedures
This file contains source code for Java programs and a sample XML document for use with
the examples for invoking the Common SQL API stored procedures.
892 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
The following files can be found in \Samples\SG247604-TRIGGER.ZIP:
EMPTRIG1.DDL
EMPTRIG2.DDL
EMPTRIG3.DDL
894 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Abbreviations and acronyms
AIB Application Interface Block DNS domain name server
AIX Advanced Interactive eXecutive DRDA distributed relational database
from IBM architecture
APAR authorized program analysis report DSC dynamic statement cache, local or
ARM automatic restart manager global
896 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Related publications
The publications listed in this section are considered particularly suitable for a more detailed
discussion of the topics covered in this book.
IBM Redbooks
For information on ordering these publications, see “How to get IBM Redbooks” on page 900.
Note that some of the documents referenced here may be available in softcopy only.
DB2 for z/OS Stored Procedures: Through the CALL and Beyond, SG24-7083
DB2 9 for z/OS Technical Overview, SG24-7330
DB2 9 for z/OS Performance Topics, SG24-7473
LOBs with DB2 for z/OS: Stronger and Faster, SG24-7270
DB2 for z/OS and OS/390: Ready for Java, SG24-6435
Distributed Functions of DB2 for z/OS and OS/390, SG24-6952
DB2 for z/OS Application Programming Topics, SG24-6300-00
A Deep Blue View of DB2 Performance: IBM Tivoli OMEGAMON XE for DB2 Performance
Expert on z/OS, SG24-7224
Exploring WebSphere Studio Enterprise Developer 5.1.2, SG24-6483
Building the Operational Data Store on DB2 UDB Using IBM Data Replicator, WebSphere
MQ Family, and DB2 Warehouse Manager, SG24-6513
Securing DB2 and Implementing MLS on z/OS, SG24-6480-01
Moving Data Across the DB2 Family, SG24-6905
IBM DB2 Performance Expert for z/OS Version 2, SG24-6867-01
Systems Programmer’s Guide to Resource Recovery Services (RRS), SG24-6980
Other publications
These publications are also relevant as further information sources:
DB2 Version 9.1 for z/OS Administration Guide, SC18-9840-01
DB2 Version 9.1 for z/OS Application Programming and SQL Guide, SC18-9841-01
DB2 Version 9.1 for z/OS Application Programming Guide and Reference for JAVA
SC18-9842-01
DB2 Version 9.1 for z/OS Codes, GC18-9843-01
DB2 Version 9.1 for z/OS Command Reference, SC18-9844-01
DB2 Version 9.1 for z/OS Data Sharing: Planning and Administration, SC18-9845-01
DB2 Version 9.1 for z/OS Diagnosis Guide and Reference, LY37-3218-01
DB2 Version 9.1 for z/OS Diagnostic Quick Reference, LY37-3219-00
DB2 UDB for z/OS Version 8 Administration Guide, SC18-7413
898 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Enterprise COBOL for z/OS Language Reference Version 3 Release 4, SC27-1408-04
IMS Version 9: Open Transaction Manager Access Guide and Reference, SC18-7829
CICS DB2 Guide Version 3 Release 1, SC34-6457-01
CICS 3.1 Application Programming Reference, SC33-1688-02
New IBM Technology Featuring Persistent Reusable Java Virtual Machines, SC34-6034
CICS Transaction Server for z/OS Version 3.2 CICS Application Programming Guide,
SC34-6818
z/OS V1R7.0 Resource Management Facility User’s Guide, SC33-7990-10
CICS Transaction Server for z/OS Version 2.2 CICS DB2 Guide, SC34-6014-07
Persistent Reusable Java Virtual Machine User’s Guide, SC34-6201
DB2 Performance Expert for z/OS Version 1 Monitoring Performance from ISPF,
SC27-1652-02
z/OS MVS Data Areas V1R7, GA22-7583
Debug Tool for z/OS Debug Tool Utilities and Advanced Functions for z/OS User’s Guide
Version 8.1, SC19-1196-01
Debug Tool for z/OS Customization Guide, SC19-1200
Debug Tool for z/OS Reference and Messages, GC19-1198
The Rational Developer for System z Host Configuration Guide, SC23-7658
Integrated Cryptographic Service Facility System Programmer’s Guide, SC23-3974
CICS Transaction Server for z/OS V3.1 CICS External Interfaces Guide, SC34-6449-03
DB2 Performance Monitor for z/OS Version 7.2, Report Reference, SC27-1647
z/OS MVS Data Areas, SY28-1164
Online resources
This Web site is also relevant as a further information source:
Debug Tool Web site at:
http://www.ibm.com/software/awdtools/debugtool/
The developerWorks Web site at:
http://www.ibm.com/developerworks
Information on installing the Java SDK at:
http://www.ibm.com/servers/eserver/zseries/software/java/
SQL Debugger for DB2 UDB V7.2 and DB2 UDB V8.1:
http://www.ibm.com/developerworks/db2/library/techarticle/alazzawe/0108alazzawe.html
DB2 DEMO workstation GUI tool at:
http://www.ibm.com/developerworks/db2/library/demos/db2demo/index.html
IBM Data Studio Web site:
http://www.ibm.com/software/data/studio
DB2 for z/OS library Web page:
http://www.ibm.com/software/data/db2/zos/library.html
DB2 Tools for z/OS and IMS Tools
900 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
Index
-723 636
Symbols -729 320
+20458 598 -751 124, 250, 320
+20460 598 -805 230, 325
+20461 598 -842 316
+434 271 -901 635
+466 129, 166 -905 103–104
//CFGTPSMP 656 -906 635
//SQLLMOD 656 -911 325, 635
_CEE_ENVFILE variable 189 -913 325, 635
-925 316
Numerics -926 316
00E79002 20
00E79106 175 A
0100C 129, 166 abend 329, 401, 534
02000 123 ACBGEN 480
-114 315 access to non-DB2 resources 397
1to n 524, 526 accessing a VSAM file 471
-20204 231 accessing CICS 471
-20457 598 accessing DB2 stored procedures from CICS 491
21000 124 accessing DB2 stored procedures from IMS 491
-30082 316 accessing transition tables in a stored procedure 634
-30090 316 accounting class 7 and 8 402
38000 125 active version 268, 291, 377
38001 123 ADD VERSION 291–292
38002 124 ADDRESS Space
38003 124, 250 MVS REGION SIZE 186
38004 124 address space 10, 39, 54, 66, 84, 92, 131, 186, 317, 373,
385xx 123 393, 423, 436, 444, 471, 505, 507
38yxx 123 more stored procedures 417
-423 321 MVS REGION SIZE 42
42501 69 new instance 84
42502 68 standard measure 436
-426 315 stored procedure 396, 519
-430 317, 328 stored procedure PROC1 373
-4302 125 unexpected terminations 85
-438 636 address spaces 393, 504
-440 314, 317 ADMIN_COMMAND_DB2 495, 503
-443 123 ADMIN_COMMAND_DSN 495, 503
-444 317 ADMIN_COMMAND_UNIX 495, 503
-449 108 ADMIN_DS_BROWSE 496, 505, 536
-450 230, 318 ADMIN_DS_DELETE 496, 505, 545
462 122 ADMIN_DS_LIST 496, 505, 540
-463 123 ADMIN_DS_RENAME 496, 505, 543
-470 318 ADMIN_DS_SEARCH 496, 505, 546
-471 20, 86, 175, 319 ADMIN_DS_WRITE 496, 505, 538
-487 123 ADMIN_INFO_HOST 497
-496 321 ADMIN_INFO_SSID 497
-499 322 ADMIN_JOB_CANCEL 496, 506, 517
-504 323 ADMIN_JOB_FETCH 496, 506, 517
-552 68 ADMIN_JOB_QUERY 496, 506, 517
-567 69 ADMIN_JOB_SUBMIT 496, 506, 517
57014 103 ADMIN_TASK_ADD 498, 503, 858
-577 124, 319 ADMIN_TASK_LIST 498, 503
-579 124
902 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
BUILD_DEBUG function 749 N_DS_SEARCH 841
business goals 429 N_DS_WRITE 839
N_INFO_HOST 811
N_INFO_SSID 810
C N_JOB_CANCEL 849
C language 148, 441 N_JOB_FETCH 848
C multi-thread stored procedure N_JOB_QUERY 847
check for errors 444 N_JOB_SUBMIT 846
compiling 461 N_TASK_ADD 859
constants and messages 446 N_TASK_REMOVE 863
includes and defines 445 N_UTL_SCHEDULE 833
C programming examples 27 CALL to DSNACICS 476
C stored procedures 147 Callable Interface (C/I) 486
calling a procedure with PARAMETER STYLE GEN- CallableStatement cs 809
ERAL WITH NULL 164 CallableStatement cstmt 300, 613, 879
calling application 159 called ADMIN_TASK_ADD
calling application parameter definition 149 output parameter handling 862
changing the security context 170 CALLED ON NULL INPUT 107, 112
constant defines 151 calling program preparation 376
CREATE PROCEDURE example 149 capacity planning 397
data query and returning results 155 CASE 238
data query and returning results example 162 case study 1, 23, 41, 67–68, 108, 471, 611, 681, 694,
DB2 host variable declarations 153 785, 887
elements 151 applications that call DB2-supplied stored procedure
example of handling IN parameters with NULLS 161 30–31
example of result set 169 C programming examples 26
functions defines 152 COBOL programming examples 25
global variable declarations 152 environment 24
helper function query_info 156 IMS ODBA setup 33
helper function rtrim 153 Java programming examples 27
helper function sql_error 154 multi-threaded stored procedure in C language 29
includes and compiler defines 151 naming conventions 35
initialization and handling IN parameters 154 overview 24
message defines 151 QMF queries and forms 32
multi-threading 441 REXX execs 33
NULL values in parameters 161 REXX programming examples 28
passing parameters 149 sample applications 24
result cursor definition 168 sample tables 25
result sets in the calling program 166 SQL language programming examples 28
result sets with GTT 166 stored procedures 32
sample CREATE 108 triggers 33
SQL CALL example 159 catalog query 17
SQLCA include 153 catalog table 16, 225, 255, 370, 678
structures, enums, and types defines 152 information DB2 stores 255
C stored procedures CREATE 108 CCSID EBCDIC 108, 149, 281, 443, 592, 621
C/I initialization 486, 518, 556 CDB 316, 358–359
CALL 238, 359, 442 ce 878
call attachment facility (CAF) 55, 415 ce.prin tStackTrace 878
CALL EMPDTLSC 117, 238 CEDA transaction 471
CALL statement 69, 99, 119, 130, 160, 164, 238, 293, CEE.SCEE MSGP 43, 140
307, 314, 363, 373, 392, 403, 475, 516, 631 CEE.SCEE Run 43, 140, 157, 187, 411
procedure name 315 CEEDUMP 330, 509
stored procedure 595, 631 CEEDUMP output 331
CALL statement error SQLCODEs 317 CEMT command 473
CALL SYSPROC.ADMI CFGTPSMP configuration data set 656
N_COMMAND_DB2 821 CFRM policy 55–56
N_COMMAND_DSN 856 CFRM policy activation 59
N_COMMAND_UNIX 853 character large object 610
N_DS_DELETE 842 check box 648
N_DS_LIST 841 CICS 6, 469, 511
N_DS_RENAME 840
Index 903
CICS access from DB2 stored procedures 471 procedure division with PARAMETER STYLE
CICS program 469, 471, 552 DB2SQL 121
DFHMIRS 472 result sets 128
EMPEXC2C 472–473 sample CREATE 108
program preparation process 491 SQL CALL 117
CICS region 471 SQLSTATE value 122
CICS resource working storage with PARAMETER STYLE DB2SQL
definition 552 120
definitions 1 471, 899 COBOL stored procedures and subprograms
CICS resource definitions 472, 551 comparison 133
CICS server program 474–475, 497, 517, 551 COBOL stored procedures CREATE 108
CICS transaction 24, 69, 425, 437, 471, 551–552, 899 COBOL stored procedures vs. subprograms
server 144, 193, 472, 475, 491, 551–552, 899 handling result sets 137
CICS transaction invocation stored procedure 474 COBOL subprogram
class file 195, 201, 721 call 135
class files with jars 202 interface 113, 138
class files without jars 201 COBOL subprogram interface 130
CLASSPATH 183, 190, 196, 612, 649, 810 COBOL subprograms 133
CLASSPATH directory 201, 221 code fragment 249, 693
class files 201 code level 370
CLASSPATH variable 207 code level management 369
click Finish 34, 649, 797 code, as shown in Example (CASE) 647
client application 9, 32, 70, 106–107, 320, 365, 392, 493, COLLECTION ID 16, 103, 116, 158, 374, 650, 695
528, 553, 715, 808 collection ID 103
logical continuation 15 COLLID 112, 271, 374, 443
client program 15, 130, 358, 471, 475, 551, 553 COLLID DEVL7083 79, 103, 220, 330, 386, 464, 612
client program preparation 362 COLLID DSNJDBC 110, 205, 617
CLOB 27, 610 column name 243, 256, 270, 523
CLOB stored procedure 617 com.ibm.db2.jcc.DB2D river 204, 613, 649, 792, 809
COBOL 10, 554 command output
COBOL CALL 133 message 524, 526
COBOL CALL dynamic 135 messages DB 494
COBOL CALL instead of SQL CALL 136 messages DDF 495
COBOL CALL static 135 messages GRP 525
COBOL Compiler options for debugging 333 messages Utah 525
COBOL program 26, 70, 130, 133, 471 command output messages 523–525
CALDTL1C 72 commandArea.length 821
diagnostic fields 473 commarea 473, 553
EMPEXC1C 471 COMMENT 306
COBOL programming examples 26 comment lines 237
COBOL stored procedures COMMENT ON PROCEDURE 306
calling application 115 commit before returning 106
CREATE PROCEDURE example 115 COMMIT ON RETURN 106, 131, 166, 413, 443
DBINFO parameter 125 Common SQL API
developing 114 same keys 595
invocation of subprograms 134 signature stability 598
invocation of subprograms through dynamic versus Version 1.0 599
static call 135 Working 592
linkage section 115 communications database 359
linkage section using DBINFO 127 compatibility mode 424
linkage section with null indicator variables 118 compiled Java stored procedure 182
linkage section with PARAMETER STYLE DB2SQL compiler defines 151, 445
121 compiler restrictions 51
nesting 130 Complete Mode 592, 594, 870
null indicator variables in the CALL 119 XML input document 594
null values in parameters 117 compound statement 239–240, 270, 274–276, 285
passing parameters 114 completion condition 285
preparing and binding 116 general labels 279
procedure division 116 schematic implementation 309
procedure division with nulls 119 SQL variable names 243
904 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
con.close 815 cstmt.regi sterOutParameter 300, 613, 879
con.prepareCall 205, 300, 613, 810 cstmt.setB inaryStream 874
con.prepareStatement 714, 831 cstmt.setString 613, 880
con.setA utoCommit 810 CTT 138
condition handler 240, 246, 260, 274 CURRENT DATA 269
compound statements 246, 276, 284, 309 CURRENT DATA NO 399
stacked diagnostics area 310 CURRENT DEBUG MODE 268, 306
condition names 276, 283 CURRENT PACKAGE PATH 103
configPlist.addProperty 877 CURRENT PACKAGESET 103
configuration file 33, 384, 656 CURRENT ROUTINE VERSION 295, 306–307
sample contents 384 CURRENT RULES 105
configuration management 372 CURRENT SQLID 68, 673
configuration tab 676 cursor declaration 240, 281, 323
conndb2.createStatement 212, 612 possible spelling error 323
CONNECT 358, 367 cursor declarations 451
CONNECT statement 358, 360 cursor stability 269
connected DB2 subsystem 494, 808 cursor stability (CS) 177, 261
DB2 commands 524 CURSOR statement 132, 271, 322
Host name 549–550 customization jobs 651
host name 548
subsystem ID 518
TCP/IP hostname 811 D
Connection con 204, 613, 713, 809 Data Project Explorer 647, 664
Connection conndb2 210, 612, 792 data propagation 636
connection URL 199, 683, 791 data set 43, 57, 138, 185, 187, 420, 426, 436, 480, 482,
connectivity SQL errors 315 496, 656–657, 812
constants defines 151 data sharing 270, 442, 497
CONTINUE handler 246 Data Studio 65, 236, 379, 500, 621, 625, 643, 785
controlling creation of stored procedures 66 Data type 15, 17, 24, 56, 75, 115, 149, 176, 199, 244,
COPY 294, 563 254, 291, 331, 489, 523–524, 623, 839
COPYRIGHT 1982 808 data type
COUNT 92, 451, 528 Char 625
CPU threshold value 103 invalid data 331
CPU time 173, 392, 397, 659 mismatch 417
stored procedure 399 XML 620
CPU time estimation 399 data validation 636
CPU times 397 Database Explorer 34, 203, 647, 791
CREATE PROCEDURE 11–12, 92, 413, 443 New Connection icon 682
CREATE PROCEDURE (EXTERNAL) option list 94 stored procedure 715
CREATE PROCEDURE COLLID 103 view 667
CREATE PROCEDURE statement 94 DATE 271
CREATE PROCEDURE with BLOB 611 DB2 9 12, 24, 68, 184, 233, 253, 372, 393, 485, 569, 619,
create stored procedures 632, 643, 797
privileges 67 context enhancement 72
CREATE THREAD 446, 457 family 619
created temporary tables 138 DB2 Accounting
created temporary tables (CTT) 138, 167 data 416
CREATEIN 68, 257–258 trace 430, 660
CREATEIN privilege 68, 717 DB2 address spaces 393, 570, 572
CS 261, 462 DB2 catalog 501
cs.close 811 DB2 catalog table
cs.exec ute 810 SYSIBM.SYSP ACKAGE 273
cs.getInt 811 SYSIBM.SYSR OUTINES 308
cs.getResultSet 811 DB2 catalogue 9, 68, 201, 254, 260, 314, 377, 394, 416,
cs.getString 811 561–562, 657, 892
cs.registerOutParameter 810 procedure definition 703
cs.setInt 811 DB2 client 191, 420, 643
cs.setString 812 DB2 command
cstmt.execute 613, 880 DISPLAY Thread 63
cstmt.getBlob 613, 881 output message 526
output message line 526
Index 905
window 191, 520–521, 719 DBCLOB 610
DB2 Data DBCS 256
Studio 1.1 650 DBD 478
DB2 data 12, 54, 412, 469, 491, 524, 549 DBDGEN 478–479
DB2 Development Center 65 DBINFO 16, 26, 80, 98, 112, 125, 176, 271, 386
project 729 DBM1 393
DB2 engine 254, 381 DBPROTOCOL 362, 367
DB2 family 182, 290, 494, 641 DBRC registration 478, 480
DB2 for MVS/ESA Version 4 3 DBRM 102, 116, 157, 326, 362, 378, 461, 491, 509, 602
DB2 honor 420 dbugging
DB2 member 93, 529, 549, 811 references to standard manuals 351
host name 549 DD card 188, 420
DB2 package 70, 91, 108, 134, 222, 378, 381, 395, 639 DD DISP 45, 139, 187, 507
DB2 PM DD DSN 139, 157, 461, 481
Accounting Long Report 403 DD statement 175, 184, 187, 469, 471, 480, 512, 515,
batch 403 656
Online Monitor 403 DD SYSOUT 139, 187, 385, 480, 507
Statistics Long Report 410 DDF 359, 517, 520
Statistics Report 416 DDF workload 20, 414
Workstation Monitor 403 DDL 12, 33, 49, 73, 92, 191, 236, 254, 375, 420, 475,
DB2 PM Accounting Long Report 403 489, 611, 657, 888
DB2 PM Statistics Long Report 410 DDL file 888
DB2 server DDLMOD 384
connection information 791 DEBUG MODE 268–269
DB2 stop 569 WLM ENVIRONMENT 268
DB2 Stored Procedure Address Space 393 debug mode 268, 402, 692
DB2 subsystem 55, 68, 130, 301, 358, 369, 393, 437, debug session 309, 795
456, 491, 494, 808 Debug Tool (DT) 40, 313
new client 521 Debug Tool on z/OS 328
new packages 68 Debug Tool overview 333
DB2 Universal JDBC Driver 182, 810 Debug Tool with VTAM MFI 340
certain functions 192 debugging 445, 513, 736
DB2 utility 610, 809 debugging DB2 stored procedures 735
DB2 V8 79, 93, 125, 173, 182, 251, 275, 393, 431, 610, debugging options 313, 736
643, 785 debugging options for distributed platforms 737
consideration 132 decimal 271
onward 103 declared temporary tables 138
SDK 1.4.0 662 declared temporary tables (DTT) 138, 167
system 220 DEFAULT 1 259
DB2 V9 92, 182, 260, 401, 611, 648 default SDK 661
DB2 work 427 DEFAULT Value
DB2Binder utility 191, 649 INSTALLATION CONTROL 657
DB2Build utility 379 default value 48, 82, 92, 155, 161, 268, 323, 361, 416,
db2profc 199 567, 656
DB2SQL 99 defining jars 203
db2sqljupgrade utility 222 defining stored procedures 91
DB2-start event 582 DEGREE 269
DB2-supplied stored procedure 450, 469, 493, 519–520 DEPLOY 268, 301, 362
DSNACICS 474 DEPT 24, 219, 289, 887
DB2-supplied stored procedure DSNAIMS 477 DEPT database 478
DB2-supplied stored procedure DSNAIMS2 489 department D21 484
DB2-supplied stored procedure examples 30 dynamic allocation 480
DB2UDSMD 744 DEPT table 471, 887
DB2WLMRefresh 817 DEQ 436
DB8A8.SDSN EXIT DESCRIBE PROCEDURE 129
DB8A8 222 described use case
DB9A DSNX9COM 304 sample invocation 864
DB9A9.SDSN Exit 43, 157, 187, 483 detailed information 61, 258, 311, 363, 496–498, 817
DB9A9.SDSN Load 43, 157, 187, 483 DETERMINISTIC 102, 112, 272
DBA 37, 67, 94 Developer Workbench 183, 236, 301, 379, 643
906 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
tooling support 643 DSNACCDD 496, 838
development activity 378 DSNACCDE 496, 546, 838
Development Center 182, 301, 379, 643, 746 DSNACCDL 496, 838
Actual Costs setup 659 DSNACCJQ 496, 532
client set up 648 DSNACCMD 452, 495
code fragments 712 DSNACCMO 497, 560
Editor View 675 DSNACCOX 498, 503
first time use 681 DSNACCOX execution 831
getting started 680 DSNACCSI 548, 811
Java stored procedure on z/OS 696 DSNACCSS 450, 497
multiple SQL statements with a single result set 712 DSNACCSS called to determine the SSID 452
Output View 673 DSNACCUC 495, 852, 855
prerequisites 648 DSNACICS 469, 474, 497
set up for SQL and Java stored procedures 654 DSNACICX user exit 477, 551, 553
SQL Assist 685 DSNAIMS 469, 477, 485, 497, 518, 556
SQL stored procedure on z/OS 694 DSNAIMS sample 485
Unicode support 654 DSNAIMS2 477, 489, 497, 518, 560
DEVL7083.EMPA UDTU 630 DSNALI 138
DEVL7083.EMPD TL1C 63, 72 DSNCLI 138
DEVL7083.JDBC Test 718 DSNDB06.SYSR TSTS 836
DEVL7083.PURC HASEORDER1 623 SYSTABLEPART CATALOG UPDATE 837
DEVL7083.PURC HASEORDER2 622 SYSTABLESPACE CATALOG UPDATE 837
DEVL7083.SQLJ Test 718 DSNE616I STATEMENT Execution 73, 572, 574, 869
DFSDDLT0 478, 481 DSNELI 138
DFSLI000 138 DSNHDECP 77, 606
DFSMDA Type 480 DSNLEUSR 497, 505
DFSPRP macro 478, 482 DSNRLI 55, 138, 462, 484
DFSYDRU0 559 DSNT404I SQLCODE 872
DIAGNOSE 563, 568, 812 DSNT408I SQLCODE 68, 123, 250, 329, 602, 606, 622
DIAGNOSTIC Text 122, 241, 631 DSNT415I SQLERRP 71, 122, 250, 329, 622
ERROR SQLSTATE 123 DSNT416I SQLERRD 80, 122, 250, 329, 622
DIAGNOSTICS statement 241, 310, 352 DSNT418I SQLSTATE 68, 122, 250, 329, 622
DISABLE DEBUG MODE 268 DSNTBIND 43, 495, 505
DISCONNECT 367 DSNTEJ6W 517, 654–655
discretionary goal 414 DSNTEP2 236, 260, 378
DISPLAY BUFFERPOOL (DB) 517, 819 DSNTEP4 260
-DISPLAY PROCEDURE 401 DSNTIAD 378
DISPLAY PROCEDURE 304 DSNTIAD, 236
Display/Update 62 DSNTIAR 152, 447
DIST 393 DSNTIJCC 658
distinct type 75, 282, 417 DSNTIJCI 475
distinct types privileges 75 DSNTIJI2 489–490, 505
Distributed xxxix, 360, 606 DSNTIJMS 501, 505, 654–655
Distributed Data Facility 359 DSNTIJRX 654
Distributed Data Facility (DDF) 397, 520 DSNTIJSD 506, 654
distributed program link (DPL) 554 DSNTIJSG 493–494, 654, 656
Distributed Relational Database Architecture (DRDA) DSNTIJTM 654–655
392 DSNTIJUZ 268
DISTSERV 364 DSNTIPF 77
double-byte character large object 610 DSNTIPX 92–93, 268
download instruction 18, 113, 147, 173, 233, 470, 629 DSNTPSMP 43, 379, 497, 505, 508, 650, 664
DRDA protocol 315 creating multiple versions 657
DRPSTMT VARCHAR 283 selecting a different version 658
DSN subcommand 494–495, 808 DSNTRACE 415, 509
execution 523 DSNU8621 813
output message line 524 DSNUSUCO 837
REBIND Package 495 DSNUTILS 498, 504, 507
DSN System 158, 263 DSNUTILS called 457
DSN.SDSNC.H 461 DSNUTILS in a secondary thread 455
DSN8D91X.DSN8 S91X 621 DSNUTILU 498, 504, 518
Index 907
DSNWSPM 497, 504, 517, 651, 659 SQL statement 688
DSNWZP 497, 504, 517, 812 ENQ 436
DSNX905 329 entry point
DSNX906I 329 AERTDLI 484
DSNX961I 228 initjvm 662
DSNX966I 329 PRGTYPE1 331
DSNZPARM 268, 693, 808 enums defines 152, 161
DSNZPARMs 812 environment variable 184, 187, 257, 512
DTT 138 environments and levels 370
dump 330, 411, 511, 537, 839 ERRMC 122
dump N 523 errmsg 153, 446
DYNAM option 142 Error code 815
dynamic allocation job 480 error function 449
DYNAMIC Result 110, 207, 214, 259 error handling 11, 236, 597, 632, 679, 811
DYNAMIC RESULT SETS 98, 272 error message 60, 67, 152, 314, 444, 476, 511, 523, 622,
DYNAMIC RESULT SETS n 111 638, 811
dynamic SQL 76 procedure results 61
call 182 error msg 815
present 399 Exception e 205, 612, 815
processing 571 EXCI 471, 553
program 76 EXCI CALL
statement 76, 104, 269 command 471
statement behavior 76, 269 interface 471
DYNAMICRULES 76, 269, 291 EXCI call 471
DYNAMICRULES option 76 EXEC SQL 10, 117, 150, 244, 353, 358, 445, 476, 485,
DYNRULS 77 634
ASSOCIATE Locater 130, 166
CALL EMPDTL1P 160
E CALL EMPDTL2P 164
e.prin tStackTrace 205, 815 CLOSE DEPT_CSR 168
editor 510, 647 End 150
Editor view 667, 787 Insert 168
blank editor 669 OPEN DEPT_CSR 167
GETEMPLDTLS tab 710 OPEN OUT_CSR 169, 454
SQL Editor 670 Select 156
tabbed page 675 SELECT FIRSTNME 163
EDM pool 395 EXEC SQL INCLUDE SQLCA 157
EDMPOOL 258 EXECUTE 70, 463, 475, 516, 518
embedded SQL statement execution status 241, 498, 570, 573–574, 674
access paths 294 execution time 48, 70, 258, 314, 396, 441, 561, 567, 725
EMP table 24, 630, 802, 887 existing address space
employee number 802 available TCB 396
UPDATE statement 630 existing generation data group
EMPDTLSJ 27, 188, 703 new GDS 538
EmpDtlsJ.clas s 201 EXIT Handler 241, 248, 259
EmpDtlsJ.GetE mpDtls 109, 202 EXIT handler 248
employee data 26 EXPLAIN 270, 305
employee number 24, 113, 147, 173, 233, 611, 630, 802 external and native SQL
employee information 113 Language fall 400
first one retrieves employee information 147 Language procedure 400
return employee details 24 procedure 254, 289
Employee.jar file 208 external CICS interface (EXCI) 469
EMPNO Character 109 external high-level language 10, 377
EMPRSETP_CSR CURSOR 166 promotion steps 378
empty string 50, 106, 286, 490, 522, 604 source code 10
enclave 411 external jars 789
enclave SRB 12, 400 external levels of security 66
ENCODING 367, 462 EXTERNAL NAME
END 240, 363, 450, 473, 507–508 clause 75, 202, 208
END P1 275, 623, 715 EMPDSAMP 386
Enhanced SQL Editor
908 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
EMPDTLSR 176 H
option 560 handler declarations 288
PGM00 235 hanging stored procedures 86
SPROA 375 HFS 514–515
external name 27, 75, 98, 175, 184, 259, 373–374, 475, HFS file 189, 197, 515–516, 615
612, 660 HIREDATE Date 109, 149
MVS load module 259 host variable 6, 20, 69, 151, 177, 216, 242, 260, 321,
external security products 75 491–492, 551, 604, 633, 678
External SQL DB2 column 216
condition handlers 248
language procedure 10, 81
procedure 11, 35, 97, 110, 245, 253, 400, 717 I
user procedure 44 I/O performance 435
external SQL 24, 95, 233, 253–254, 497, 651 I/O time 435
external stored procedure 10 IBM Data Server driver for JDBC and SQLJ 644
IBM Data Studio
Actual Costs setup 659
F advanced topics 710
file system 646 authorization setup 651
Java source file 700 client setup 648
File Transfer Protocol (FTP) 213 Data Project Explorer view 672
finally block 814 Database Explorer 653
first message 523 Database Explorer view 667
FIRSTNAME VARCHAR 109 DB2 for z/OS setup 650
FIRSTNME VARCHAR 108, 149 Deployment wizard 679
flexibility 367, 598 Export wizard 679
following catalog table Fix Pack 1 699
SELECT authority 518 free version 648
FOR UPDATE CLAUSE 271 getting started 663
full-screen mode 333, 336 GUI capabilities 25
Debug Tool 335 Import wizard 678
Debugging DB2 programs 351 Java Perspective 787
non programmable terminal 333 Java SDKs 661
Functional comments 263 JDBC Driver selection 660
functional overview 9, 569, 589 Menu and Task Bar 680
other problem determination tools 683
G Server View 673
GENERAL 99, 443, 551 set up specific to Java stored procedures 657
GENERAL WITH NULLS 99, 464 set up specific to SQL stored procedures 656
generation data SQL Builder 685
group 538, 542, 546 SQL stored procedures on z/OS 665
set 536, 541 stored procedure EMPEXC3C 477
generation data group (GDG) 538, 540 stored procedure EMPODB1C 485
generation data set (GDS) 540 Unicode support 654
GET DIAGNOSTICS 241, 310, 352 z/OS set up 650
GET_CONFIG 499, 503 IBM Data Studio (IDS) 24, 49, 126, 175, 182, 190, 379,
GET_MESSAGE 499, 503 474, 630, 643, 785
GET_SYSTEM_INFO 499, 503–504 IBM DB2
GetE mpDtls 75, 188 Driver 182, 500, 661, 810
global temporary table 167, 420, 443–444, 523–524, 653 JDBC Universal Driver Architecture 186
formatted result 525 IBM Redbooks
SYSIBM.UTIL ITY_RETCODE 564 Web server 887
SYSIBM.UTILITY_RETCODE 564 Web site 23, 887
global temporary tables 166 IBM WebSphere Studio Enterprise Developer 736
global variable declarations 152 IBMREQD 257
gname 57 IDCAMS 478, 480, 544
goal mode 393, 424 IDENTIFY 446, 456, 482
goals 427 IEFSSNxx 59
GOTO 239 IF 239, 515
graphical user interface (GUI) 336 IFCID 239 402
Index 909
II14421 402 user_ID 584
IMMEDWRITE 270 user-ID 522, 530, 532
import java.io 204, 612, 875 value 161, 476, 552–553, 635
import java.math 212, 612 input table 443, 531
import java.sql 204, 612, 700, 809 input to DSNLEUSR (ID) 517
Import wizard 678, 749 INSERT 290, 444
next page 679 install panel 92, 590
IMS 6, 469, 518, 556 Instrumentation Facility Component (IFC) 402
IMS access from DB2 stored procedures 477 Instrumentation Facility Interface (IFI) 148, 526
IMS application 469, 492, 557–559 int rc 152, 212, 450, 810
unsolicited output message 557 Integrated Cryptographic Service Facility (ICSF) 554
IMS data 26, 54, 469, 477, 484, 557 Integrated Development Environment (IDE) 649
IMS database interpreted Java stored procedure 182
call 477–478 Intra-utility parallelism 565
environment 483 IP address 49, 72–73, 415, 520, 606, 883
record 478, 484 procedure call 73
specific record 478 IRLM 393, 481, 529
IMS database (ID) 105, 116, 158, 177, 273, 292, 326, iSeries 125
374, 378, 397, 469 ISO 256, 462
IMS ODBA setup 33 ISOLATION LEVEL 270
IMS Open Database Access 477–478 isolation level
IMS OTMA CS 200, 622, 714
Guide 486 RR 200, 721
user exit routine 559 RS 200, 721
IMS setup for using ODBA and DSNAIMS/DSNAIMS2 UR 200, 721
478 ISP 139, 157, 411, 480, 846
IMS stage 1 gen 478 Issue DB2 607, 820
IMS Stage 2 gen 478, 482 ITERATE 241, 277, 290
IMS TM 491 iterator 217
IMS Tran 478 IWM032I 400
IMS transaction 14, 436, 477, 485, 497, 557 IWM032I messages 86
environment 485 IXGLOGR 57
invocation 485
manager 469
IMS Version J
8 556 jar file 76, 195, 615, 699, 711
9 24, 487, 490 ser file 225
IMS910H.SDFS RESL 481 stored procedure 195
includes defines 151 jar file privileges 75
independent database (ID) 66, 103, 112 JAVA 99, 511–512
index 255, 448, 525 Java 182, 306, 493–494, 746
index on expressions 255 Java application 28, 193, 417, 444, 494, 657, 785, 808
indicator variable 100, 117, 161, 177, 354 Java Development Kit (JDK) 661
additional set 117 Java Editor 675, 787
elementary item 100 Java environment variables 189, 195
in-doubt URs 61 Java method 188, 661
INHERIT SPECIAL REGISTERS 107, 112 INOUT parameters 188
INNER1 block 280 Java Perspective 647, 786
following statement 280 Java profile data set 195
input DDL (ID) 192, 385 Java programming examples 27
input document 592, 870 Java project 671
input parameter 107, 117, 150, 176, 178, 210, 244, 273, Java Runtime Environment (JRE) 661
282, 318, 384, 413, 476, 487, 522, 616, 634, 678, 795, Java SDK 183, 512, 515
811 Java source 666, 787
compatible column data types 577 DB2 server connection information 791
job-ID 532 Java stored procedure
level 385, 553 class files 201
OTMA_DATA_INSEG 489 DDL 205
stored procedure 553, 575, 865 prerequisite software 183
Type 286 sample code 211
Java stored procedures 181, 511–512
910 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
dedicated WLM 187 JSPDEBUG 512, 662
environment set up 183 JSPDEBUG DD 187, 514
external name 207 JVM reset 193, 417
NUMTCB 187 JVMPROPS 190
PROGRAM TYPE SUB 206 JVMSet 193
sample CREATE 109
WLM dedicated 187
WLM proc 186 K
WLM procedure 186 KB 50, 82, 416, 542, 610
Java Virtual Machine (JVM) 41, 184, 194, 415, 426, 707 KEEP DYNAMIC 270
java.lang.Stri ng 700 key >
java.sql.Types.INTE GER 879 CPU 604
JAVA_HOME 187, 189, 512 Data 596
javac 197, 607 Display Name 597
JAVAENV 188, 512 Display Unit 593
JAVAENV data 188–189, 657 Document Locale 594
CLASSPATH environment variable 201 Document Type Name 593
environment variables 189 Hint 593
set 207 Message Token 601
JAVAENV data set 188 Model 604
JAVAENV DD 41, 187–188, 514 Name 604
JAVAERR DD 188, 514 SMPCSI Data 603
JAVAOUT 188, 514 key word 86
JCC 741 key/value pair 596, 598–599
JCC directory 221
JCC driver 186, 220, 421, 613 L
JCC_HOME 189 LANGUAGE 111, 443, 512
JCL 41, 55, 84, 139, 157, 175, 184, 317, 395, 469, 471, Language Environment
494 installation default 420
JCL file 888 limiting storage 50
JCL job 569, 573, 586 overview 47
JCL task 498 runtime library access 414
JDBC 182, 462, 494, 500, 740 runtime option 49, 333
JDBC and SQLJ libraries 185 runtime options 48, 515
JDBC application Language Environment (LE) 48, 54, 84, 106, 149, 189,
debugging with WSAD 786 193, 329, 395, 433, 438, 662
JDBC class 204, 700 Language Environment runtime options 414, 512
JDBC driver 195, 644, 810 language SQL 110, 235, 245, 258, 271, 622, 714
class 683, 810 large object 610
implementation 182 latency 428
significance 660 LD_LIBRARY_PATH 196
JDBC driver class LE options for debugging 333
location 684 LEAVE 239
JDBC method 182, 197 Legacy Driver 221, 644
JDBC package 191, 648 Legacy driver 644
JDBC stored procedure LENGTH 261, 473
returning a result set 213 LIBPATH 196
JDBC stored procedure DDL 212 Library Lookaside 187, 437
JDBC stored procedures 211 Licensed Material 808
deploying on z/OS 213 limiting types of SQL executed 78
JDBC tracing options 683 line feed
JDK 1.5 183, 661 character 251, 260
library 661 line formatting (LF) 260
method 661 LINKAGE Section 10, 115, 633
JDK level 661, 673 linkage section
JES spool 106, 531 additional variables 120
Job Data Set Display (JDSD) 330 indicator variables 119
Job JOB00087 850 Parameter list 127
job-ID 531–532 LINKLIST 187, 515
JOBPARM SYSAFF 157, 200, 411, 461 Linux, Unix and Windows (LUW) 785
Index 911
LLA 187, 414, 419, 437 Max RC 847
LNKLST 414 MAX STORED PROCEDURES 132
load library 10, 116, 140, 374–375, 436, 473 MAX STORED PROCS 93
code level management 12 MAX_OBJECTS 446, 451
load module 10, 84, 104, 135, 235, 245, 254, 374, 381, Maximum number 87, 92, 114, 128, 148, 166, 175, 235,
395, 413, 425, 437, 517 245, 323, 401–402, 425, 446, 482, 541, 681, 841
multiple versions 374 MB line 48, 414
size 135 program heap storage 50
load module in memory 104 storage usage 50
load module name 373, 522, 536, 560 measuring 400
532, 534 medianSalary Decimal 258
DSNACICS 551 Member name 488, 539, 542, 811
DSNADMCD 524 message area 444, 810
DSNADMCS 523 message defines 152
DSNADMDD 545 message output parameter 522, 526
DSNADMDE 546 message text 241, 499, 589, 630, 826
DSNADMDL 540 message token 250, 600, 872
DSNADMDR 543 MESSAGE VARCHAR 109, 149, 443
DSNADMDW 538 Minor Version 591–592, 594, 874
DSNADMIH 548 minor version
DSNADMIS 550 output XML documents 592
DSNADMJF 531 mixed data 256
DSNADMJS 530 MODE DB2SQL 630
DSNADMTA 583 monitor and measure stored procedures 401
DSNADMTR 588 monitoring 569
DSNADMUS 566 MQSeries 7, 515
DSNLEUSR 554 MSGFILE 49, 329
LOB column 610, 615 MSGFILE data 49
auxiliary table 610 MSGFILE(ddname,,,,ENQ) 329
auxiliary tables 610 MSTR 393
total length 610 multiple release levels 374
LOB data 610 multiple remote servers 365
LOB locators 611 multiple SQL
LOB materialization 613 statement 360, 392, 713
LOB sample programs 611 sub-statements 260
LOB table space 610 variable 290
LOB TABLESPACE 610 multiple stored procedure address spaces 393
LOBs 609 multiple threads common problems 467
LOBs support in Java 611 Multiple version 111, 257, 291, 374–375, 657
local application 86, 126, 133, 255, 363 multi-thread C stored procedure 443
COBOL subprogram 138 multi-thread case study
local SQL invoking remote stored procedure 365 RUNSTATS utility 443
local stored procedure invocation 363 multi-thread stored procedures 442
location name 125, 315, 327, 358, 528, 614, 683, 810 multi-threaded C 27, 443, 891
log stream 57 multi-threaded C language examples 29
log stream (LS) 55 multi-threading 441
LOOP 239
looping stored procedures 86
LPALST 414 N
LUWID 126, 528 N.SALARY 630
NAME 107, 443, 475, 507–508
Native SQL 10, 24, 41, 93, 233, 253, 362, 622, 670
M bind options 708
machine-readable material (MRM) 257 language 12, 110, 377
Main Frame Interface (MFI) 313 language procedure 12, 400
main program 105 procedure 6, 12, 85, 96, 111, 246, 251, 253, 327,
maintenance 294, 498 369, 400, 402, 622, 690
MAJOR_VERSION 591–592 native SQL
MAX ABEND COUNT 93 multiple versions 111
max number of failures 106 Native SQL stored procedures 268, 289
MAX OPEN CURSORS 93 nested compound statement 248, 255
912 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
statement labels 276 522, 650, 698
nested stored procedures package owner 35, 76, 268, 673, 717
performance 420 package path 102, 116, 158, 177
NEW Table (NT) 632 PAOLOR3.DSTE ST2 844
NFM 254, 650 parameter list 99, 114–115, 149, 175, 207, 237, 243,
non-CALL SQL errors 320 254, 299, 314, 375, 485, 552, 592, 633, 791
non-DB2 resource 6, 15, 397, 469 PARAMETER STYLE 112, 413, 443, 489
non-resettable mode 187, 417, 426 Java 101, 185, 612, 678
non-SQL resources SQL 100, 119, 125, 149, 176, 324, 413, 419
security 105 parameter style 16, 24, 98, 114, 149, 184, 206, 313, 419,
NOOPTIMIZE 333 660
NOT VARIANT 272 DB2SQL 26
NOTEST 49 General 26, 79, 99, 120, 149, 161, 176, 330, 386,
null indicator 99, 118, 165, 413, 551 476, 674
null indicator variables 118 PARAMETER STYLE DB2SQL 100, 119, 324
null parameters 107 PARAMETER STYLE GENERAL WITH NULLS 272
null value 119, 149, 152, 318, 490, 555, 638 PARAMETER STYLE JAVA 206
NUMBER OF TCBS 92, 507–508 parse argument 809
NUMTCB 41, 412, 425, 444, 504, 507 parseType.equa ls 824
NUMTCB value 41, 407, 425, 511 Partitioned data set extended (PDSE) 536
server address space 426 partitions 270
passing parameters 99
passticket 522, 530, 532
O password PUP4SALE 191, 650
O.SALARY 630 PATH 196, 363, 514
Object type 25, 282, 562, 568, 639, 832 PATH =/usr/lpp/java/IBM/J1.4/bin 222
ODBA call 478, 483 PCALL-CTR 332
ODBA interface 469, 477–478 PDSE member 537–538
Accessing IMS databases 477 PDSE name 537–538, 543
OLD Table (OT) 632 PEMPNO Char 235
online monitoring 405 performance group number 411
OPEN c1 259, 627 performance knobs 411
OPEN C2 239, 259 performance recommendations 418
Open Transaction Manager Access (OTMA) 485, 518 permitting access to WLM REFRESH command 67
operational aspects 83 Persistent Reusable JVM 193
Operational Data Stores 7 perspective 647
OPTHINT 270 PFIRSTNME 115, 329
optimization 270, 565 PGN 411
optional caller information 102 PK04339 486
out.prin tln 614 PK07907 489
output document 592, 872 PK09213 417
certain major and minor version 598 PK16294 486
output parameter 11, 94, 117, 119, 150, 155, 176, 178, PK25672 486
206, 238, 244, 262, 273, 323, 387, 394, 476, 522–523, PK26421 489
611, 637, 697, 791, 864 PK28561 402
certain values 155 PK30387 486
compatible type 577 PK30395 486
default value 323 PK32332 489
maximum size 417 PK37311 605
Output View 35, 647, 670, 787 PK41138 650, 746
Output view 673 PK43524 310
Data Output tab 674 PK48891 486
Problems tab 791 PK52490 486
Properties tab 673 PK59752 20
stored procedure 719 PK64298 xxxvii, 605
owner 75, 475, 516–517 PKLIST 103, 363
PLASTNAME 115, 329
P plist version 593–594, 596, 870
package monitoring 403 PORDEROUT VARCHAR 623
package name 199, 205, 273, 326, 373–374, 397, 428, POSIX(ON) 443
Index 913
POSIX-style threads 443 new SQL procedure 302
PQ45854 650 stored procedure 383
PQ76769 206 program error 544, 809
PQ77702 485 program life cycle management 433
PQ89544 486 program preparation
PQ95544 650 JCL 474, 888
pragma 151, 445 job 890
pragma csect 151, 446 part 134
pragma runopts 151, 446 process 381, 474, 491
precompiler 260, 361, 491 step 375, 469
precompiler options 361, 367 program properties table (PPT) 486
prefix.SDSN SAMP 554 PROGRAM TYPE 105, 112, 271, 413, 443
private String PROGRAM Type 98, 106, 176, 184, 330, 399, 660
major_version 876 PROGRAM TYPE MAIN 415, 464
minor_version 876 provided SQLCODE
SQLSTATE 876 short message text 589
xml_Filter 876 provides monitoring (PM) 403, 579
xml_Input 876 PS data 536, 838
privileges 65, 363, 462, 475, 516–517 set 536–538
privileges to execute stored procedures 69 PS data set (PDS) 536
proc 41, 404, 473, 505, 656 ps.clos e 833
procedure address space 15, 48, 55, 66, 84, 201, 259, ps.setI nt 832
268, 393, 432, 474, 551, 661 ps.setS tring 832
procedure ADMIN_COMMAND_DSN 855 PSB 478–479
procedure body 236, 254, 362 PSB source 478–479
only statement 242 PSBGEN 478–479
SQL procedure parameter 243 PSQLERRMC 115, 238, 485
Procedure Call 27, 72, 145, 396, 415, 596 PTF number 503
procedure code 24, 210, 282, 286, 443, 692, 790 pthread.h 445–446
PROCEDURE ddl 120, 207, 666 public static void
procedure definition 42, 102, 108, 119, 206, 294, 305, GetClobDtls 617
558, 659, 694 GetEmpDtls 207, 612, 791
PROCEDURE DEVL7083.EMPR GetEmpResult 207, 214
SETJ 207, 213 GetJarFile 615
SETR 109 jAVATEST 700
ST2J 220 jDBC_MRS 713
PROCEDURE Division 10, 115, 324, 332, 633 method 678
indicator variables 119 pull-down list 669, 723
procedure DSNACICS 26, 469, 471 Select DEVL7083 705
procedure EMPDTL1C 62, 72–73
procedure EMPDTLSC 68, 70, 122–123
procedure EMPODB1C 420, 478 Q
procedure execution 188, 293, 523, 553 QMF objects 32
PROCEDURE GET_CONFIG 872 QMF query 18, 32, 892
PROCEDURE MEDIAN_RESULT_SET 258 QRPARM70 33
PROCEDURE Name 14, 35, 41–42, 59, 68, 79, 108, QRPARMER 33
243, 270, 299, 314, 374, 428, 483, 504, 529, 669 QMF report 18
procedure name 363, 373, 504 QUALIFIER 268, 364, 563, 568
PROCEDURE option 11, 254, 299, 521, 664 query_info 156
procedure package 299, 725 QUIESCE 84, 563, 568
procedure PROC1 373 QWACCAST 430
procedure program 103, 891 QWACUDST 430
procedure return 277, 310, 523, 654
PROCEDURE statement 10–11, 33, 68, 87, 89, 91–92, R
114–115, 149, 177, 235, 259, 314, 375, 377, 413, 475, RACF 475, 505–506, 741, 743
554, 556, 612, 634, 669, 679, 888 RACF panels 655
procedure wizard 655 RACF program
procedure WLM_REFRESH 66, 84, 573, 577, 817 control 170, 513, 517, 519
production environment 28, 35, 68, 86–87, 104, 106, RACF RDEFINE 67
302, 370, 405, 437, 520 RAISE_ERROR function 635
914 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
rcount 353 EMPRSETP_CSR CURSOR 166
RDEFINE Program 519 fixed number 178
RDO 471 locator variable 129
Read stability (RS) 177 maximum number 98
READA 148 variable number 178
READS 148 result sets 128, 495, 521
reason code 60, 314, 319, 455, 490, 525, 556, 821 ResultSet rs 212, 612, 809
reasons for abnormal termination 329 RESUME 84
recast arg 161, 455 RETCODE 443, 473, 565, 833
Recoverable Resource Services 7 RETCODE Integer 109, 149
Recovery Services Attach Facility (RRSAF) 53 RETURN 242, 443, 473
Redbooks Web site 900 Return code (RC) 20, 60, 122, 152, 166, 240, 329, 476,
Contact us xliv 493, 522, 810
redeploying SQL procedures 245 return h_deptname 167
reducing the network traffic 4 return rc 160, 816
REFRESH 84, 519 returned result set
refresh the environment 84 selection criterion 293
refreshing WLM RETURNS VARCHAR 184
resource profile 67 reusability 132, 332
REGION 461, 507 REXX 9, 173, 378, 508, 890
RELCREATED 256 REXX execs for configuration management 33
RELEASE AT 270 REXX program 173, 433, 893
release information block 447 execution JCL 893
release resource 811 REXX programming examples 28
remote debug mode 335 REXX stored procedure
remote server 130, 294, 301, 320, 362, 632 calling application 177
DB2 objects 632 LINKAGE section 176
remote stored procedure 358, 566 preparing and binding 177
preparation 362, 364 REXX stored procedures 173
remote stored procedure calls 357 environment 175
remote stored procedure invocation 364 multiple result sets 178
RENT 157, 462 passing parameters 175
REOPT 269–270 sample CREATE 109
Reorg Job REXX/DB2 interface 173
1 869 Right-click 34, 668
2007-12-29 869 RLF limit 104
reorg job 858 RMF 410
REPEAT 240 RMF Performance Index 430
Repeatable read (RR) 177, 261 ROUNDING 271
RES VARCHAR 279 Routine Editor 669, 676
RESET_FREQ 190 Configuration tab 711
resettable JVM 193–194 procedure name 678
resettable mode 187, 417, 426 ROWID 610
RESIGNAL 242, 283, 290 ROWID column 610
resource limit facility (RLF) 104 RPTOPTS 49
Resource Management Facility (RMF) 410, 429 RPTOPTS(ON) 106
resource manager 54, 316, 475, 551, 553 RRS 7, 448, 551
drives exit routines 54 RRS error samples 60
exit routine 54 RRS JCL procedure 59
resource profile 432, 505 RRS log streams 55
Resource Recovery RRS starting and stopping 59
Service 54 RRS subsystem name 59
Services attachment facility 116, 474, 551 RRSAF 53, 442, 556
Resource Recovery Services 54 implementation 55
Resource Recovery Services Attach Facility 53 overview 54
result set 11, 24, 73, 98, 114, 117, 148, 175, 178, 188, rs.clos e 812
207, 235, 244, 258–259, 321, 397, 444, 493, 495, 521, rs.getI nt 616
627, 674, 811 rs.getS tring 212, 612, 812
C1 CURSOR 130 Run option 16, 48, 98, 176, 329, 475, 660
C101 CURSOR 179 RUN OPTIONS 112, 271, 443
Index 915
RUNOPTS settings 50 literal positions 577
RUNSTATS 443, 507, 563, 827 semicolon 236
RUNSTATS in parallel 443 sequence number 523, 526, 690
RUNSTATS TABLESPACE 458, 563, 568, 832 ser file 201–202, 660
DSN00005.TABR WLMR Table 837 server address space 42, 389, 423–424, 435–436
DSNDB06.SYSR TSTS Table 836 additional wait 428
runtime 76, 78, 250, 269, 373, 376, 565 Adjusting WLM control 431
access path 270 control WLM management 423
CURRENT PATH special register 376 NUMTCB value 425
Runtime //JAVAENV DD statement examples 662 resource consumption 433
runtime environment 16, 48, 76–77, 138, 195, 222, 414 WLM control 431
runtime environment setup 144 WLM management 423
runtime option 32, 47, 106, 237, 329, 414 server address space management 423
Default values 48 server program 471, 475, 517, 551
large number 48 successful completion 553
MSGFILE 49 service class
NOTEST 49 WLM goals 432
RPTOPTS 49 service class (SC) 20, 393, 411, 424
TEST 49 service class period 411
runtime options 48, 106, 512 service class periods 427
service level agreement (SLA) 132
service unit 12, 86, 103
S reasonable maximum 112
same name 42, 108, 138, 242, 276–277, 374, 679, 707 service units 104
multiple conditions 283 service-oriented architecture (SOA) 620
multiple procedures 111 servlet 613
multiple SQL variables 279 SESSION 138
multiple variables 279 SG247083.DEVL.DDLM ODO 385
SQL variable 242 SIGNAL 241, 283, 290
stored procedure 707 SIGNAL SQLSTATE 638
sample JCL 92, 226, 386, 471, 520 SIGNON 446, 456
sample stored procedure DSNACICS 475 SMALLINT 529, 561
sample table 25, 113, 173, 233, 611, 621 input parameter 561, 566
sample tables 24 output parameter 562
SBCS 257 SMF Type 30 records 433
scheduling 396, 498 SMF Type 42 Subtype 6 data 436
scheduling delays 429 SMF type 72 record 410
scheduling parameter SMPCSI data 602–603, 872
DB2_SSID 582 returned GET_SYSTEM_INFO XML template input
PROCEDURE_INPUT 576–577 document 875
schema name 35, 68, 79, 112, 205, 225, 258, 299, 376, Software Developers Kit (SDK) 183, 651
386, 652 source code 10, 35, 235, 255, 309, 331, 375, 418, 455,
schema name SYSPROC 495 484, 491, 554, 607, 676, 787, 807, 888
SDK 1.3.1 662 same level 381
SDK 1.4.1 662 separate files 890
SDSF 330, 655 SOURCE compile option 157
SDSNLOD2 187 spDriver.call SP 873
secondary authid 68 spDriver.getS QLCODE 873
Secure Sockets Layer (SSL) 72 spDriver.setInputDocs 873
SECURITY 112, 271, 443, 517 spDriver.setMajorMinorEn 873
security 65, 170, 456, 517 SPUFI 236, 260, 571, 574
security considerations 74 SQL 9, 67, 91, 114, 148, 182, 233, 253, 313, 358, 367,
security context 536, 538, 540 392, 442, 469, 494, 644, 658
SELECT Count 259 SQL access 600
SELECT EMPNO 168, 218, 612 SQL Activity panel 408
SELECT FIRSTNME 216, 240 SQL API 494, 499, 559, 570
SELECT name 259, 328, 376 SQL Builder 680
SELECT RTRIM 16 illustrated statement 687
SELECT salary 259 SQL CALL
SELECT statement 260, 272, 468, 576–577, 631, 688, statement 4, 14, 92, 114, 133, 149, 300, 314, 392,
865
916 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
402, 432, 476, 491, 551, 555 using handlers 246
SQL Call 92, 114, 149, 175, 243, 373, 392, 469 SQL script 672, 685
EXEC CICS LINK statement 476 stored procedure 689
SQL CALL statement in a CICS program 491 SQL Scripts folder
SQL CALL statement in an IMS program 492 previously created SQL Statement 690
SQL comment 251, 260 SQL script 688
SQL CONNECT 14 SQL Statement
SQL DATA 16, 78, 98, 176, 259, 319, 386, 443, 751 following areas 659
Main 254 typing parts 687
SQL Data 78, 98, 262, 330, 387 SQL statement 4, 10, 68, 77, 93, 124, 133, 153, 167, 173,
SQL Debugger 738 216, 236, 242, 254, 314, 361, 384, 392, 396, 463,
SQL DIAGNOSTIC Information 80, 122, 250, 329, 622 571–572, 574, 620, 630, 633, 655, 659, 863
SQL Editor 668 application program 323
button 688 column names 279, 577
radio button 687 details text box 697
SQL error 152, 246, 286, 314, 443, 526, 697, 809 interface 237
SQL error categories 314 large numbers 173
SQL Guide 13, 50, 55, 106, 125, 173, 325, 360, 420, 485, locator variable list 321
630, 817 minimum number 419
SQL language programming examples 28 runtime 271
SQL language stored procedure CREATE 110 schema qualifier 687
SQL language stored procedures SQL variable 242
sample CREATE 110 terminator 236, 261
SQL operation 150, 610, 632 unqualified database object references 79
SQL PATH 270 UPDATE CLAUSE 218
SQL procedure 11, 233, 235, 253, 377, 497, 634, 650, view 686
664 SQL stored procedure 254, 279, 299
changed messages 258 SQL stored procedures 11, 289, 513
equivalent statement 235 SQL variable 238, 240, 260, 270
first initial version MEDIAN_V1 259 different scopes 276
GET DIAGNOSTICS 249 following restrictions 242
multi-line format 260 SQL variable declarations 276
nest compound statements 276 SQL Warning 245, 261, 592, 880
nested compound statements 275–276 sql_error 153, 450
new kind 233 SQLCA 151, 235, 352, 445, 556
new type 253 SQLCA include 153
only type 254 SQLCODE 20, 68, 122, 152, 178, 212, 239, 272, 314,
possible outline 276 451, 499, 597, 631, 866
PROCEDURE statement 259 SQLCODE +434 271
RETURN statement 249 SQLCODE +466 166
SQL statements 242 SQLCODE = -443 123
SQLCODE 249 SQLCODE = 462 122
SQLSTATE 249 SQLCODE = -463 123
Statements 236 SQLCODE = -487 123
using RETURN 249 SQLCODE = -577 124
using SIGNAL and RESIGNAL 250 SQLCODE = -579 124
sql procedure SQLCODE = -751 124
current schema 650 SQLCODE -430 328
SQL Procedure language 233 SQLCODE -4302 125
SQL procedures SQLCODE -438 636
ALTER PROCEDURE 235 SQLCODE -440 314
calling application 244 sqlcode -449 108
declaring and using variables 242 SQLCODE 466 129
defining 236 SQLCODE -471 86, 175
difference 235 SQLCODE -552 68
forcing errors with triggers 250 SQLCODE -567 69
handling error conditions 245 SQLCODE -751 250
handling result sets 245 SQLCODE -805 325
passing parameters 243 SQLCODE -905 103–104
preparing and binding 236 SQLCODE -911 325
Index 917
SQLCODE -913 325 staff Order 259
SQLCODEs 325, 597–598 SELECT SALARY 262
SQLCOMNT 260 -START TRACE 402
SQLD 129 started address space
SQLDA 129, 451 available TCB 405
SQLDELI 808 startup JCL 84, 471
sqle.getE rrorCode 815 static SQL
sqle.getS QLState 815 model 76
SQLException e 212, 612, 700 program 69
SQLException information 815 statement 270
SQLException sqle 815 statistics data 410
SQLFORMAT 262 STAY RESIDENT 104, 112, 271, 413, 443
SQLFORMAT SQLPL 264 No 104, 397
SQLJ 181–182, 494, 644, 785 option 397
binding packages 200 Yes 104, 437
SQLJ application 217, 797 Yes option 395
debug session 800 STDERR 197
debugging with WSAD 797 STDIN 197
SQLJ preparation STDOUT 197
step 200 STEPLIB concatenation 317, 420, 518
SQLJ profile customization 199 STEPLIB data sets 40
SQLJ stored procedure STEPLIB DD
DDL definition 220 concatenation 10, 518
host variables 216 STOP AFTER SYSTEM DEFAULT FAILURES 95–96,
sample code 215 112
SQLJ stored procedures 215 STOP PROC ACTION(QUEUE) 85
preparation JCL 220 STOP PROC ACTION(REJECT) 85
preparing 197 -STOP PROCEDURE 401
results set 217 STOPABN status 401
translation and compilation 198 STOPABND 85
SQLJ support 186, 798 STOPQUE status 401
SQLJ. DB2_UPDATEJARINFO 502 STOPREJ status 401
SQLJ.ALTE R_JAVA_PATH 183, 721 STOR PROC 404
SQLJ.ALTER_JAVA_PATH 502, 505 Stored procedure
SQLJ.DB2_INSTALL_JAR 501, 505 INOUT parameters 627
SQLJ.DB2_REMOVE_JAR 502, 505 stored procedure
SQLJ.DB2_REPLACE_JAR 502, 505 abend errors 329
SQLJ.INSTALL_JAR 501, 505 accidental cancel 86
SQLJ.REMOVE_JAR 501, 505 accounting information 403
SQLJ.REPLACE_JAR 501, 505 additional steps 394
SQLNAME 129 address space 15, 48, 66, 75, 84, 93, 138, 178, 393,
SQLPL 260 395, 424, 474, 551, 657
SQLPL behavior 262 ALTER PROCEDURE statement 104
SQLSTATE 68, 99, 119, 122, 245, 282, 285, 323, 577, and/or Rollback statements 320
583, 630, 650 appropriate area 693
SQLSTATE 0100C 166 associated cursor 323
SQLSTATE 09000 636 authorization ID 105
SQLSTATE 38000 125 available TCB 407
SQLSTATE 38003 250 build time 661
SQLSTATE 42501 69 CALL syntax 495
SQLSTATE 42502 68 calling application 32, 577
SQLSTATE 57014 103 calling program 362, 657
SQLSTATE class 638 catalog information 32
SQLSTATE RETURN Code 68, 104, 123, 250, 622 coding errors 85
SQLSTATE value 122, 125, 241, 249, 324, 638 collection ID 103
EXIT HANDLER 250 configuration options 676
OVERFLOW CONDITION 250 connection statements 210
SQLSTATEs 125, 597–598 connection string 211
SSID 261, 450, 586 current version 599
ST display 330 DDL definition 205
918 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
different AE 427 task-triggered execution 580
different versions 373 termination cost 433
dynamic invocation 69 transition tables 634
dynamic SQL 76 two-tabbed view 710
entry points 679 validity time window 580
execution life cycle 394 variables and their qualifiers 374
execution profile 86 various properties 710
execution time 396, 442, 566 Web Service 731
expected parameters 17 stored procedure (SP) 1, 3, 9, 24, 37, 39, 48, 54, 65, 83,
external resource 170 89, 91–92, 113–114, 147–148, 175, 181, 235, 279,
first abend 93 313–314, 369–370, 389, 391–392, 424, 435, 469, 493,
following REXX statement 178 504, 581, 589, 611, 629, 641, 643, 674, 785, 807, 889
general idea 597 stored procedure address space (SPAS) 134
implicit or explicit schema name 652 stored procedure call
last instance 132 environment information 596
life cycle 394 message send/receive transmissions 399
LINKAGE SECTION 332 parameter list 150
linkage section 120 stored procedure definition
load module 108 COBOL example 324
MINOR_VERSION parameters 598 examples 108
multiple tasks 104 stored procedure execution
multiple versions 374 elapsed time 433
nesting complexity 425 stored procedure preparation 362, 375
new invocations 84 stored procedure program
new thread 394 source code 11
new version 67 stored procedure tusing ODBA 483
next invocation 655 stored procedure using DSNACICS
operator cancellations 85 preparation 477
Options tab 726 stored procedure using EXCI 473
Packages folder 726 stored procedure using ODBA
PARAMETER STYLE 318 preparation 484
performance behavior 394 stored procedure with EXCI call
PROCEDURE DDL 208 diagnostic field definition 474
qualified name 99 stored procedures 357, 441
result sets 171 a simple example 12
return code 443, 526, 531 advantages 4
rollback statements 320 benefits 5
runtime diagnostics 49 calling user-defined functions 639
runtime files 225 catalog tables 16
runtime options 415 defining 91
same DB2 system 657 execution flow 19
scheduling behavior 578 execution time 396
schema DEVL7083 68 grouping by language 414
second instance 488 importance 3
separate application environment 415 invocation 5
single copy 11 life cycle 394
single execution 86 monitoring 400
source code file 891 multi-tiered applications 7
special registers 306 overview 9
specific name 99 performance concepts 392
SQL CALL 134 promotion 377
SQL call 135 use 6, 362
SQL CALL statement 317 versioning 373
SQL CALL statements 93 what are they? 4
statements flow 13 stored procedures vs. user-defined functions 636
static invocation 69 STORMXAB 87, 106, 402
static method 208 String args 210, 791, 820
subsequent executions 83 String driver 809
successful or unsuccessful invocation 578 String empno 207
successive scheduled invocations 577 String filename 226, 615, 876
Index 919
String message 810 catalog table 20, 300, 318
String password 809 REMARKS columns 306
String url 204, 791, 809 row 317
String userid 791, 809 runtime information query 16
String workDept 214 table 15, 317
STRUCTURE Name 57 SYSIBM.SYSROUTINES 15–16, 255, 373, 394, 653
structure sqlca 445 SYSIBM.SYSROUTINES_OPTS 653
structures defines 152, 161 SYSIBM.SYSROUTINES_SRC 653
subprogram 105, 113, 130, 149, 178, 244 SYSIBM.USER Name 497
SUBSTRING 616 AUTHID column 555
substring function 615 INSERT authority 518
subtask 561 LINKNAME column 555
supplied employee number NEWAUTHID column 555
employee data 26 NEWAUTHID field 555
SYS1.PROCLIB 59 PASSWORD column 555
SYS1.SAMPLIB 59 PASSWORD field 555
SYSADM 257, 518, 652, 827 TYPE column 555
SYSADM authority 69, 104, 475, 516, 575, 717 SYSIBM.UTIL ITY_OBJECTS 561
SYSCTRL 257 table 561
SYSDBOUT 331 utility execution 562
SYSDUMMY1 table 400 Values 831
extra SELECT statements 400 SYSIBM.UTIL ITY_STMT 562
SYSIBM.DSNR TX01 837 corresponding utility statements 563
SYSCOLDIST CATALOG UPDATE 837 statement row 562
SYSCOLUMNS CATALOG UPDATE 837 Values 832
SYSINDEXES CATALOG UPDATE 837 SYSIN DD 56, 411, 480
SYSIBM.DSNR TX02 837 SYSLIB DD DISP 139
SYSCOLDIST CATALOG UPDATE 837 SYSMOD 590
SYSCOLUMNS CATALOG UPDATE 837 SYSOTHER 414
SYSINDEXES CATALOG UPDATE 837 SYSPACKAGE 465
SYSIBM.DSNR TX03 837 Sysplex 55, 85
SYSCOLDIST CATALOG UPDATE 837 Sysplex name 56
SYSCOLUMNS CATALOG UPDATE 837 SYSPRINT 331, 444, 446
SYSINDEXES CATALOG UPDATE 837 SYSPRINT data sets 438
SYSIBM.IPLIST 359 SYSPRINT DD 438, 462
SYSIBM.IPNAMES 359 SYSPRINT lines retrieval 458
SYSIBM.LOCATIONS 359 SYSPROC 475, 495, 506
SYSIBM.LULIST 359 SYSPROC.ADMI N_COMMAND_DB2 524
SYSIBM.LUMODES 359 SYSPROC.ADMI N_COMMAND_DSN 523
SYSIBM.LUNAMES 359–360 SYSPROC.ADMI N_DS_RENAME 543
SYSIBM.MODESELECT 359–360 SYSPROC.ADMI N_DS_WRITE 538
SYSIBM.SYSD UMMY1 184, 240, 576, 630, 860 SYSPROC.ADMI N_JOB_FETCH 531
SYSIBM.SYSDUMMY1 653 SYSPROC.ADMI N_JOB_QUERY 532
SYSIBM.SYSE NVIRONMENT 19, 255 SYSPROC.ADMI N_TASK_ADD 570
Column ENVID 255 SYSPROC.ADMI N_TASK_REMOVE 570
SYSIBM.SYSJ AROBJECTS 225, 615 SYSPROC.ADMI N_UTL_SORT 566
SELECT JAR_DATA 225 SYSPROC.ADMIN_TASK_ADD 570
SYSIBM.SYSJARCONTENTS 653 SYSPROC.ADMIN_TASK_REMOVE 575
SYSIBM.SYSJAROBJECTS 653 SYSPROC.DSNA IMS 485, 560
SYSIBM.SYSJAVAOPTS 653 procedure name 488
SYSIBM.SYSP ACKAGE 328, 374 SYSPROC.DSNAIMS 486
SELECT OWNER 281 procedure name 488
SELECT QUALIFIER 282 SYSROUTINES_OPTS 379
SYSIBM.SYSP Arm 16, 318 SYSROUTINES_SRC 379
SYSIBM.SYSPARMS 15, 17, 395, 653 System Display and Search Facility (SDSF) 330
SYSIBM.SYSPSM 653 System.err.prin tln 809
SYSIBM.SYSPSMOPTS 653 System.out.prin tln 188, 616, 785, 811
SYSIBM.SYSPSMOUT 653 statement 792
SYSIBM.SYSR OUTINES 15, 50, 103, 237, 255, 373, SYSTSIN DD 384
653 SYSTSPRT DD SYSOUT 192, 385, 509, 520
920 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
SYSUDUMP DD SYSOUT 139, 192 Types.LONG VARCHAR 812
Types.TIME Stamp 859
Types.VARC HAR 613, 810
T
table emp 289, 630
column name 289 U
table locater 321, 634 U4038 228
input variables 634 UCS 654
table row 523 UDF 7
Sequence number 524 UK03998 486
table space 444, 525, 610, 827 UK15224 486
tablespace 832 UK18090 402
TABNAME VARCHAR 284 UK18393 486
target server 191, 706, 718, 810 UK18394 486
same authorizations 723 UK18752 489
stored procedure 722 UK25115 486
Task Control Blocks 424 UK25860 209
task execution 573, 579 UK26421 489
task name 570, 858, 863 UK29722 486
TCB 12, 93, 134, 319, 384, 394, 424, 444, 573 UK30363 486
TCBs and nested stored procedures 427 UK32046 503, 569
TCBs driving server address spaces 426 UK32047 503, 569
temporary table 134, 137, 167, 443, 562, 821 UK32059 503
terminator defaults 236 UK32060 503
TEST 49 UK32061 503, 603
test case 49, 55, 67, 70, 403, 405, 471, 476, 786 UK32795 503
TEST.MEDI AN_RESULT_SET 302 UK33845 503
Thread Create 396 UK37310 605
Thread Detail panel 405 unauthorized data set 44
Thread Summary panel 405 UNCOMITTED READ 159
TIME 271, 461 Uncommitted read (UR) 177, 261
TIMEOUT VALUE 93 unhandled SQL errors to CALL statements 323
timestamp 323, 580 Unicode Conversion Services 654
input parameter 585 Unicode Conversion Services installation 654
tools for debugging of DB2 stored procedures 735 UNICODE UTF-8 620, 836
total cost of ownership (TCO) 254 Unified Debugger 500, 738
transaction manager (TM) 469 Session manager information 681
transition table 26, 631 technology 311
Access rows 635 V9 FP2 650
example 633 Unified debugger 183, 308, 650, 785
transition variable 26, 630–631, 862 Unit of Recovery (UR) 56
example 633 Universal JDBC driver 644
transition variables and transition tables 632 UPDATE EMP 235
translated authorization ID UQ70789 486, 556
encrypted values 554 UQ78980 486
trigger example 630 UQ94696 486
trigger invoked with a CALL statement 631 UQ96685 485
trigger invoked with a VALUES statement 630 url jdbc
trigger invoking a stored procedure 629 db2 191, 650
triggers 33 USAGE Binary 127
error handling 635 use case 569, 576, 858
trim trailing blank 153 User Defined Function 7
Type 1 CONNECT 360 User Defined Function (UDF) 33, 404, 424
Type 2 CONNECT 360 user defined functions 364, 636, 639
Type 2 driver 182 user defined functions calling stored procedures 640
Type 4 182 user ID 69, 170, 475, 517, 679, 683, 809
Type 4 connection 614 PAOLOR5 195
Type 4 driver 182 user PAOLOR5 184, 650
typedef struct 152, 447 user-defined function (UDF) 68, 130, 318, 658, 667
types defines 152, 161 user-written routine 319
Types.INTE GER 300, 810 using IBM (UI) 663
Index 921
UTF-8 268 WITH RETURN clause 166
UTILITY Execution 497, 816 wizard 647
Utility execution WLM 20, 92, 268–269, 272, 443, 471, 504
multiple objects 498 WLM ADDRESS Space
DD
SYSTSPRT DATASET 657
V WLM address space 170, 187, 336, 374, 400, 404, 517,
v_counter INTEGER DEFAULT 0 259 631, 657
valid XPATH 606, 872 started task 631
valid XPath 870 STDERR DD cards 211
VALIDATE RUN 270 WLM address space priority 414
VALIDATE(RUN) 365 WLM AE 20, 378, 400, 655
VALUE 92, 482, 508 WLM application environment 12, 35, 40, 67, 84, 132,
values for special registers 107 184, 221, 269, 374, 396, 400, 426, 444, 504, 655, 817
VARCHAR 281, 324, 443, 475, 522, 611 address space 516
input parameter 522 appropriate authority 269
output parameter 523 DSNUTILU run 507
variables initialization 451 JCL procedure 426, 507
VARY z/OS 84 name 42, 376, 504, 817
VERSION 268, 291, 448 naming convention 35
Version 267, 359 proc 186
Version 9 182, 229–231, 254, 359, 497, 808 WLM application environment for EXCI transactions 473
VERSION MEDIAN_V1 258 WLM Application Environment recommendations 40
VERSION MEDIAN_V2 292, 303 WLM commands 655
VERSION V1 110, 272 WLM definition 473
VERSION VERSION1 622, 714 WLM ENVIRONMENT 92–93, 269, 464, 489, 507
versioning 259, 372 clause 311
versions 271 DB2GDEC1 330
view 647 DB2GWEJ1 207, 213
Virtual Lookaside Facility (VLF) 437 DB2QWL1 375
virtual storage 425 DB2QWL2 375
virtual storage tuning 433 DB2QWL3 375
VLF 437 DB2QWL4 375
VM 125, 334, 336 DB8ADJ1 221
VSAM 6, 469, 542 DB8ADJC2 221, 224
VSAM and non-VSAM data sets 438 DB8AWLM2 660
VSAM cluster 473, 542 DB9ADJC2 612
VSAM data 478, 480, 542 DB9AEXCI 475
set 57, 480, 570 DB9AREXX 109, 176
VSAM file 75, 397, 436, 469 DB9AWL2 387
DD statement 471 DB9AWLM 79, 108, 386
definition 471–472 DB9AWLMJ 110, 184
I/O 148 name 107, 330, 375, 386, 702
Sg247083.DEPT 472 parameter 432
vsamls 57 WLM environment 12, 40, 66, 84, 93, 114, 148, 175, 185,
VSE 125 187, 235, 254, 396, 401, 427, 432, 471, 478, 497, 504,
VTAM MFI 336 519, 656, 817
Debug Tool 340 stored procedures 66, 512
VTAM MFI mode 337 WLM ENVIRONMENT FOR DEBUG MODE 268
WLM environment for ODBA 483
W WLM goal 429
Web service 620, 672, 731 attainment 429
default URI 731 mode 15
Web Site 18, 23, 113, 173, 233, 334, 470, 629, 648, 762, WLM proc 41, 186, 478, 656
887 WLM PROC NAME 92
Web Site Voice 610 WLM refresh
Websphere Definition Language (WSDL) 734 job 384
WHILE 240 WLM setting up 41
WITH HOLD 106, 361, 451 WLM Spa 11, 134, 660
WITH IMMEDIATE WRITE 270 JAVAENV DD statement 660
922 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
multiple tasks 11 z/OS code 314
WLM SPAs DB2 Version 9.1 314
Load library 141 z/OS command 84
WLM_ENVIRONMENT 374 z/OS platform 32, 182, 661
WLM_REFRESH 66, 379, 497, 505, 655, 657, 817 z/OS server 10, 107, 328, 379, 442, 648, 797
WLM_REFRESH GRANT statement 67 available languages 10
Work Load Manager DB2 9 797
stored procedure 661 load module 107
Work Load Manager (WLM) 661 z/OS SQL Reference 70, 94, 233, 258, 360, 499, 610,
work queue 424, 427 634
important characteristic 428 DB2 Version 9.1 360
new server address space 428 z/OS V8 15, 68, 412, 569, 650
WORKDEPT Character 213 Curium 717
Workload Manager 10, 39, 268, 336, 412, 423 New Function Mode 79
WSAD debug options 793 NFM 717
server 707
tool 691
X z/OS V9
XDBDECOMPXML 500, 506, 559 Information Center 661
XDBDECOMPXML100MB 506 server 644, 718
XML column 34, 620 zIIP 12, 24, 255
entire documents 620
XML data 25, 619–620
column 623
many common database operations 620
type 620, 692
type format 625
XML document 499, 593, 619, 625, 870
basic structure 593
different types 593
distinct sections 595
major version 591
minor version 592
retrieval 620
storage 620
XML format 494, 591, 619
XML input document 593–594
XML output 592, 594
document 593, 596, 875
parameter document 602, 605
XML output document 592, 594, 872
xml version 593–594, 870
XML_FILTER file 880
XML_INPUT document 593–594, 870
Call GET_SYSTEM_INFO 873
XML_INPUT file 880
XML_MESSAGE document 599, 873
XML_OUTPUT 591–592
XML_OUTPUT document 593, 601, 872
XPLINK 662
XSR_ADDSCHEMADOC 499, 506, 559
XSR_COMPLETE 499, 506, 559
XSR_REGISTER 499, 506, 559
XSR_REMOVE 499, 506, 559
Z
z/OS 25, 54, 193, 401, 529
DB9A 72
name 590
recoverable resources 54
Index 923
924 DB2 9 for z/OS Stored Procedures: Through the CALL and Beyond
DB2 9 for z/OS Stored Procedures:
Through the CALL and Beyond
(1.5” spine)
1.5”<-> 1.998”
789 <->1051 pages
Back cover ®
Develop and test This IBM Redbooks publication helps you design, install, manage, and
tune stored procedures with DB2 9 for z/OS. Stored procedures can INTERNATIONAL
COBOL, C, REXX, Java
provide major benefits in the areas of application performance, code TECHNICAL
and SQL procedures
re-use, security, and integrity. DB2 has offered an ever improving SUPPORT
support for developing and operating stored procedures. ORGANIZATION
Set up, control, and
In these days, three years is a generation in the software business; if
tune the operating
you have DB2 9 for z/OS, this book replaces the previous DB2 for z/OS
environment Stored Procedures: Through the CALL and Beyond, SG24-7083-00,
and it reflects the changes that have happened to DB2 stored
Learn about IBM Data procedures and related tools from V8 to V9. BUILDING TECHNICAL
Studio and other tools INFORMATION BASED ON
We show how to develop stored procedures in several languages, PRACTICAL EXPERIENCE
including Java; we explore the functions available for the z/OS platform
deployment; and provide recommendations on setting up and tuning IBM Redbooks are developed
the appropriate stored procedure environment. by the IBM International
We talk about the external and native SQL procedures, the debugging Technical Support
options, the special registers, the deployment, and diagnostics. Organization. Experts from
IBM, Customers and Partners
A chapter is devoted to the increasing number of DB2-supplied stored from around the world create
procedures. They can be used for almost all of a DBA’s tasks. timely technical information
based on realistic scenarios.
We also devote a part to tools which can be used for accelerating the Specific recommendations
development process and go in some detail about the stored procedure are provided to help you
support provided by the latest IBM product: Data Studio. For recent implement IT solutions more
information on Data Studio, refer to Data Studio and DB2 for z/OS effectively in your
Stored Procedures, REDP-4717. environment.