Você está na página 1de 418

DB2 Java Stored Procedures

Learning by Example

Implementation guide for DB2 Java stored procedures DB2 Java stored procedures across platforms Reference guide for network computing enhancements in DB2 UDB for OS/390 V6

Maria Sueli Almeida Kirk Condon Michael Fischer Julian Stuhler

ibm.com/redbooks

SG24-5945-00

International Technical Support Organization DB2 Java Stored Procedures Learning by Example

September 2000

Take Note! Before using this information and the product it supports, be sure to read the general information in Appendix F, Special notices on page 355.

First Edition (September 2000) This edition applies to Version 6 of IBM DATABASE 2 Universal Database Server for OS/390 (DB2 UDB Server for OS/390 Version 6), Program Number 5645-DB2, Version 7 of DB2 UDB for UNIX, Windows, OS/2, and other current versions and releases of IBM products. Make sure you are using the correct edition for your level of product. This document was created or updated on September 5, 2000. Comments may be addressed to: IBM Corporation, International Technical Support Organization Dept. QXXE Building 80-E2 650 Harry Road San Jose, California 95120-6099 When you send information to IBM, you grant IBM a non-exclusive right to use or distribute the information in any way it believes appropriate without incurring any obligation to you.
Copyright International Business Machines Corporation 2000. All rights reserved. Note to U.S Government Users Documentation related to restricted rights Use, duplication or disclosure is subject to restrictions set forth in GSA ADP Schedule Contract with IBM Corp.

Contents
Figures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .xi Tables. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv How this book is structured . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv The team that wrote this redbook . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvi Comments welcome . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xviii Part 1. Background. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Chapter 1. Java platform support . . . . 1.1 Java overview . . . . . . . . . . . . . . . . . 1.2 Java and the OS/390 Platform . . . . . 1.2.1 OS/390 UNIX System Services. 1.2.2 Enterprise Toolkit for OS/390 . . 1.3 Java and the UNIX Platform . . . . . . . 1.4 Java and the Windows NT Platform . . . . . . . . . . . . . . . .. .. .. .. .. .. .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. .. .. .. .. .. .. . . . . . . . . . . . . . . . . . . . . . .. .. .. .. .. .. .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. .. .. .. .. .. .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 .3 .4 .4 .4 .6 .6

Chapter 2. Java and DB2 . . . . . . . . . . . . . . . . . . . . 2.1 Java database connectivity . . . . . . . . . . . . . . . . 2.1.1 DB2 JDBC programs . . . . . . . . . . . . . . . . . 2.1.2 DB2 SQLJ programs. . . . . . . . . . . . . . . . . . 2.1.3 Choosing the access method: JDBC versus 2.1.4 JDBC driver types. . . . . . . . . . . . . . . . . . . . 2.2 Java and DB2 stored procedures . . . . . . . . . . . . 2.2.1 What is a stored procedure? . . . . . . . . . . . . 2.2.2 Supported stored procedure languages . . . 2.2.3 DB2 Java stored procedures . . . . . . . . . . .

..... ..... ..... ..... SQLJ ..... ..... ..... ..... .....

. .7 . .7 . .7 . .8 . .9 . 11 . 12 . 12 . 13 . 14

Part 2. Developing Java stored procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 Chapter 3. Java sample application: the ACME software company 3.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 System design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3 Sample application components . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3.1 DB2 naming conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4 Portability issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.1 Java stored procedure portability . . . . . . . . . . . . . . . . . . . . . . 3.4.2 DB2 portability issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.5 Sample stored procedures standard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 . 19 . 19 . 21 . 23 . 24 . 24 . 24 . 24

Copyright IBM Corp. 2000

iii

3.5.1 JDBC stored procedure sample . . . . . . . . . . 3.5.2 SQLJ stored procedure sample . . . . . . . . . . 3.5.3 COBOL stored procedure sample . . . . . . . . . 3.5.4 Combined SQLJ and JDBC example . . . . . . 3.6 Sample stored procedures enhanced . . . . . . . . 3.6.1 JDBC enhanced stored procedure sample . . 3.6.2 SQLJ enhanced sample . . . . . . . . . . . . . . . . 3.7 Sample Client Code . . . . . . . . . . . . . . . . . . . . . . . 3.7.1 Calling the Java stored procedure from Java 3.7.2 COBOL client application sample . . . . . . . . . 3.7.3 SQLJ client application sample . . . . . . . . . . . 3.7.4 JDBC client application sample . . . . . . . . . .

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

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

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

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

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

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

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

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

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

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

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

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

. 25 . 27 . 29 . 32 . 34 . 34 . 39 . 45 . 45 . 48 . 50 . 52 . 57 . 57 . 57 . 59 . 60 . 63 . 66 . 66 . 68 . 69 . 71 . 73 . 75 . 76 . 78 . 78 . 79 . 79 . 80 . 80 . 80 . 83 . 83 . 83 . 89 . 90 . 90 . 90 . 90

Chapter 4. System setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.1 OS/390 system setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.1.1 Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.1.2 Installation tasks. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.1.3 Step 1: Design library structure . . . . . . . . . . . . . . . . . 4.1.4 Step 2: Provide .profile for users . . . . . . . . . . . . . . . . 4.1.5 Step 3: Setting up RRS. . . . . . . . . . . . . . . . . . . . . . . . 4.1.6 Step 4: Define WLM stored procedure address space 4.1.7 Step 5: Install JDBC/SQLJ driver for OS/390 . . . . . . . 4.1.8 Step 6: Set up the JAVAENV data set . . . . . . . . . . . . 4.1.9 Step 7: Verify JDBC cursor and SQLJ properties files 4.1.10 Data sharing considerations . . . . . . . . . . . . . . . . . . . 4.1.11 Maintenance considerations . . . . . . . . . . . . . . . . . . . 4.1.12 Some common setup issues . . . . . . . . . . . . . . . . . . . 4.2 Windows NT system setup . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.1 Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.2 Installation tasks. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.3 Some common setup issues . . . . . . . . . . . . . . . . . . . . 4.3 UNIX system setup. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.3.1 Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.3.2 Installation tasks. . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Chapter 5. Designing Java stored procedures . . . . . . . . . . . . 5.1 General design issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.1.1 Naming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.1.2 Parameter style: Java or DB2GENERAL . . . . . . . . . . . 5.1.3 Public static method with void return type . . . . . . . . . . . 5.1.4 Parameters must be mappable to base SQL data types 5.1.5 LOBS not supported for Java stored procedures . . . . . 5.1.6 Why do we use [ ] on the output parameters? . . . . . . . .

iv

DB2 Java Stored Procedures: Learning by Example

5.1.7 Using JDBC, SQLJ, or both . . . . . . . . . . . . . . . . . . 5.1.8 Java packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.1.9 Case sensitivity . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.1.10 Nested Java stored procedures . . . . . . . . . . . . . . 5.2 Design issues for OS/390 Java stored procedures . . . . . 5.2.1 Must use HPJ compiler . . . . . . . . . . . . . . . . . . . . . . 5.2.2 Must have Java Package as first statement . . . . . . 5.2.3 Packaging considerations . . . . . . . . . . . . . . . . . . . . 5.2.4 Environmental considerations . . . . . . . . . . . . . . . . . 5.3 Design issues for the UNIX, Windows, OS/2 platforms . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

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

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. 91 . 91 . 92 . 92 . 93 . 93 . 93 . 93 . 94 . 96

Chapter 6. Coding Java stored procedures . . . . . . . . . . . . . . . . . . . 6.1 Null handling with JDBC stored procedures . . . . . . . . . . . . . . . . . . 6.1.1 Calling a stored procedure with a null value . . . . . . . . . . . . . . 6.1.2 Using a Java base type as a parameter . . . . . . . . . . . . . . . . . 6.1.3 Determining if a selected item was an SQL null via wasNull() . 6.1.4 Inserting a NULL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2 Null handling with SQLJ stored procedures . . . . . . . . . . . . . . . . . . 6.3 SQLJ Iterators and ResultSets . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3.1 Return ResultSets from SQLJ stored procedures . . . . . . . . . . 6.3.2 Avoid returning a used ResultSet . . . . . . . . . . . . . . . . . . . . . . 6.3.3 Close interim ResultSets . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3.4 Returning Multiple ResultSets. . . . . . . . . . . . . . . . . . . . . . . . . 6.4 Error Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.4.1 Getting the results of printStackTrace . . . . . . . . . . . . . . . . . . . 6.5 Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.5.1 Initially writing as a standalone program . . . . . . . . . . . . . . . . . 6.5.2 Writing debugging statements to a table . . . . . . . . . . . . . . . . . 6.5.3 OS/390 debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.5.4 UNIX and Windows NT debugging . . . . . . . . . . . . . . . . . . . . . 6.6 Using the DB2 Stored Procedure Builder . . . . . . . . . . . . . . . . . . . . 6.6.1 Advantages of the SPB. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.7 Common errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.7.1 OS/390 errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.7.2 UNIX and Windows NT errors . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 7. Preparing Java stored procedures . . . . 7.1 Program preparation concepts . . . . . . . . . . . . . . . 7.2 OS/390 Java stored procedure preparation . . . . . 7.2.1 Java stored procedure and DB2 package . . . 7.2.2 DB2 authorization issues . . . . . . . . . . . . . . . 7.2.3 OS/390 JDBC program preparation process . 7.2.4 OS/390 SQLJ program preparation process . . . . . . . . . . . . . . . . . . . . . . .. .. .. .. .. .. .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. .. .. .. .. .. .. . . . . . . . . . . . . . .

. . 97 . . 97 . . 97 . . 97 . . 99 . . 99 . 100 . 100 . 101 . 101 . 101 . 102 . 102 . 102 . 103 . 103 . 103 . 103 . 104 . 105 . 105 . 106 . 106 . 112 . 119 . 119 . 119 . 119 . 120 . 122 . 129

7.2.5 7.3 NT / 7.3.1 7.3.2 7.3.3

Using UNIX System Services (USS) . . . . . . . . . AIX Java stored procedure preparation . . . . . . . NT / AIX JDBC program preparation process . . NT / AIX SQLJ program preparation process . . The sqlj.install_jar and sqlj.replace_jar routines

. . . . .

.. .. .. .. ..

. . . . .

. . . . .

. . . . .

. . . . .

.. .. .. .. ..

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

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

. 143 . 144 . 144 . 149 . 155 . 157 . 157 . 157 . 160 . 161 . 163 . 163 . 163 . 164 . 164 . 164 . 165 . 165 . 167 . 167 . 167 . 167 . 168 . 168 . 170 . 170 . 170 . 172 . 174 . 174 . 174 . 174 . 175 . 175 . 176 . 181 . 181 . 182 . 182 . 183 . 184

Chapter 8. Deployment and execution . . . . . . . . . . . . . . . . . . . . . 8.1 Deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.1.1 Migrating between environments on S/390 . . . . . . . . . . . . . 8.1.2 Migrating between environments on UNIX/NT . . . . . . . . . . 8.1.3 Porting between UNIX/NT and S/390 . . . . . . . . . . . . . . . . . 8.2 Execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.2.1 OS/390 execution considerations . . . . . . . . . . . . . . . . . . . . 8.2.2 UNIX and Windows NT execution considerations . . . . . . . . 8.3 Stored procedure management and version control on OS/390 . 8.3.1 Source code control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.3.2 Version control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8.3.3 Sample of a test and production version . . . . . . . . . . . . . . . 8.3.4 Running two versions in the same DB2 subsystem . . . . . . . Chapter 9. Client applications invoking Java stored procedures 9.1 DB2 plans and packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.1.1 JDBC client requirements . . . . . . . . . . . . . . . . . . . . . . . . . . 9.1.2 SQLJ client requirements . . . . . . . . . . . . . . . . . . . . . . . . . . 9.1.3 Stored procedure requirements . . . . . . . . . . . . . . . . . . . . . 9.1.4 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.1.5 Usage recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . 9.2 Client coding considerations. . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.2.1 General client coding considerations . . . . . . . . . . . . . . . . . 9.2.2 JDBC client coding considerations . . . . . . . . . . . . . . . . . . . 9.2.3 SQLJ client coding considerations . . . . . . . . . . . . . . . . . . . 9.3 Client authorization issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.3.1 JDBC client authorization . . . . . . . . . . . . . . . . . . . . . . . . . . 9.3.2 DB2 for OS/390 stored procedure execute authority . . . . . . 9.4 Sample Java client preparation scripts . . . . . . . . . . . . . . . . . . . . 9.4.1 Sample javacl script . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.4.2 Sample bindcl.rexx script . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 10. Migration of DB2 for OS/390 Version 5 to Version 6 . 10.1 Stored procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.1.1 SYSIBM.SYSPROCEDURES no longer used . . . . . . . . . . 10.1.2 Java stored procedures under Version 5. . . . . . . . . . . . . . 10.1.3 DB2 catalog maintenance . . . . . . . . . . . . . . . . . . . . . . . . . 10.1.4 Fallback considerations from Version 6 to Version 5 . . . . .

vi

DB2 Java Stored Procedures: Learning by Example

Part 3. DB2 UDB for OS/390 V6 various enhancements . . . . . . . . . . . . . . . . . . . . . 185 Chapter 11. DB2 UDB for OS/390 network computing enhancements187 11.1 DRDA support for three-part names . . . . . . . . . . . . . . . . . . . . . . . . 187 11.1.1 Three-part names prior to Version 6 . . . . . . . . . . . . . . . . . . . . 187 11.1.2 Three-part names in Version 6 . . . . . . . . . . . . . . . . . . . . . . . . 189 11.1.3 Package requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191 11.1.4 How it works . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192 11.1.5 DBPROTOCOL bind option . . . . . . . . . . . . . . . . . . . . . . . . . . 193 11.1.6 Stored procedures considerations . . . . . . . . . . . . . . . . . . . 193 11.1.7 Hopping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194 11.1.8 Advantages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196 11.1.9 Impacts. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197 11.2 DRDA query block size. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 11.2.1 OPTIMIZE FOR n ROWS clause enhancements. . . . . . . . . . . 198 11.2.2 How it works . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 11.2.3 Usage recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 11.3 DDF connection pooling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 11.4 STOP DDF MODE(SUSPEND) command . . . . . . . . . . . . . . . . . . . 203 11.4.1 Command syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204 11.5 Declared Global Temporary Tables . . . . . . . . . . . . . . . . . . . . . . . . 205 11.5.1 Usability considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207 11.6 Savepoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208 11.6.1 Connecting to other DB2 systems. . . . . . . . . . . . . . . . . . . . . . 209 11.6.2 Restrictions on using savepoints . . . . . . . . . . . . . . . . . . . . . . 210 11.6.3 Savepoint performance. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210 11.7 Identity columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210 11.7.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 11.7.2 Data definition issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 11.7.3 Data manipulation issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217 11.7.4 Utility issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 11.7.5 Other properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 11.7.6 DB2 catalog table considerations . . . . . . . . . . . . . . . . . . . . . . 221 11.7.7 Usage recommendations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222 11.7.8 Use of identity columns versus ROWID columns . . . . . . . . . . 228 11.7.9 Data propagation considerations . . . . . . . . . . . . . . . . . . . . . . 229 11.7.10 Influencing insert order in a data sharing environment . . . . . 230 11.7.11 Differences in implementation across the DB2 Family. . . . . . 230 Chapter 12. DB2 UDB for OS/390 schema support . 12.1 Schema characteristics . . . . . . . . . . . . . . . . . . . 12.2 How schemas are used . . . . . . . . . . . . . . . . . . . 12.2.1 Explicit specification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. .. .. .. . . . . . . . . . . . . . . . . .. .. .. .. . . . . . . . . . 233 . 234 . 234 . 234

vii

12.2.2 Implicit specification . . . . . . . . 12.3 Schemas and the CURRENT PATH 12.3.1 SET CURRENT PATH . . . . . . 12.3.2 PATH bind option . . . . . . . . . .

...... special ...... ......

....... register . ....... .......

.. .. .. ..

. . . .

. . . .

. . . .

. . . .

.. .. .. ..

. . . .

. . . .

. 235 . 236 . 237 . 240

Chapter 13. DB2 UDB for OS/390 stored procedures enhancements 243 13.1 Stored procedures: an overview . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 13.1.1 Why use stored procedures? . . . . . . . . . . . . . . . . . . . . . . . . . 244 13.1.2 SQL CALL processing flow. . . . . . . . . . . . . . . . . . . . . . . . . 246 13.1.3 Stored procedures time line characteristics . . . . . . . . . . . . 247 13.2 The CREATE PROCEDURE DDL statement . . . . . . . . . . . . . . . . . 259 13.2.1 Parameter definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262 13.2.2 New options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263 13.2.3 Enhanced options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265 13.2.4 Advantages of DDL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267 13.2.5 Schema name: CREATE PROCEDURE . . . . . . . . . . . . . . . . . 269 13.2.6 Schema name: CALL statement . . . . . . . . . . . . . . . . . . . . . . . 270 13.3 Lifted DML restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272 13.4 Nested stored procedures: characteristics . . . . . . . . . . . . . . . . . . . 274 13.5 Authorization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275 13.5.1 Who has EXECUTE privilege on a stored procedure? . . . . . . 277 13.6 DISPLAY PROCEDURE command. . . . . . . . . . . . . . . . . . . . . . . . . 280 13.7 Migration considerations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 Part 4. Appendices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283 Appendix A. New messages and error codes . . . . . . . . . . . . . . . . . . . . 285 A.1 STOP DDF MODE SUSPEND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285 Appendix B. Sample code, DDL, and preparation scripts . . . . . . . . . . 287 B.1 Sample DDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287 B.1.1 DB2 UDB for OS/390 DDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287 B.1.2 DB2 UDB for AIX and Windows DDL . . . . . . . . . . . . . . . . . . . . . . . 297 B.2 Sample stored procedure definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . 307 B.2.1 DB2 UDB for OS/390 stored procedure definitions . . . . . . . . . . . . 307 B.2.2 DB2 UDB for AIX and Windows stored procedure definitions . . . . 317 B.3 Sample stored procedure code. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318 B.4 Sample client code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318 B.5 Sample program preparation scripts. . . . . . . . . . . . . . . . . . . . . . . . . . . . 318 B.5.1 OS/390 program preparation scripts. . . . . . . . . . . . . . . . . . . . . . . . 318 B.5.2 AIX program preparation scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . 318 B.5.3 NT program preparation scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . 321

viii

DB2 Java Stored Procedures: Learning by Example

Appendix C. OS/390 Recoverable Resource Services (RRS) . . . . . . . 329 C.1 RRS attachment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329 Appendix D. Define WLM stored procedure address space . . . . . . . . 331 D.1 Enable stored procedure support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331 D.1.1 Step 1. Run the installation CLIST in INSTALL or MIGRATE mode.. . 331 D.1.2 Step 2. Edit DSNTIJUZ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332 D.2 How to use the WLM ISPF application . . . . . . . . . . . . . . . . . . . . . . . . . . 332 D.3 Starting the WLM application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333 D.4 Control of stored procedures in a WLM environment . . . . . . . . . . . . . . . 334 D.5 Defining the application environment . . . . . . . . . . . . . . . . . . . . . . . . . . . 335 D.6 Refreshing the environment for stored procedures . . . . . . . . . . . . . . . . 337 D.7 Using WLM application environments in compatibility mode . . . . . . . . . 338 D.8 Using WLM application environments in goal mode . . . . . . . . . . . . . . . . 339 D.9 Restricting access. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341 D.10 Summary of service definition / service policy concepts. . . . . . . . . . . . 342 D.11 Recommendations for full implementation of OS/390 WLM . . . . . . . . . 344 D.12 Considerations for compatibility mode . . . . . . . . . . . . . . . . . . . . . . . . . 345 D.13 Considerations for goal mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345 Appendix E. Using the additional material . . . . . . . . . . . . . . . . . . . . . . 347 E.1 Using the CD-ROM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347 E.1.1 Sample client code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348 E.1.2 Sample stored procedure code. . . . . . . . . . . . . . . . . . . . . . . . . . . . 349 E.1.3 Sample S390 utilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352 E.1.4 Sample SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353 E.2 Locating the additional material on the Internet . . . . . . . . . . . . . . . . . . . 354 E.3 Using the Web material. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354 E.3.1 How to use the Web material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354 Appendix F. Special notices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355 Appendix G. Related publications. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359 G.1 IBM Redbooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359 G.2 IBM Redbooks collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359 G.3 Other resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360 G.4 Referenced Web sites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361 How to get IBM Redbooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363 IBM Redbooks fax order form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364

ix

Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365 Abbreviations and acronyms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387 IBM Redbooks review . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393

DB2 Java Stored Procedures: Learning by Example

Figures
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. Java and DB2 for OS/390 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 Java and DB2 for UWO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 ACME Software Company System Design . . . . . . . . . . . . . . . . . . . . . . . . 20 SQLJ load library data set definition . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 Application load library data set definition . . . . . . . . . . . . . . . . . . . . . . . 63 JAVAENV file data set definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 RACF command to assign home directory . . . . . . . . . . . . . . . . . . . . . . . . 66 JAVAENV data set contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 DB2SQLJDBC.PROPERTIES contents . . . . . . . . . . . . . . . . . . . . . . . . 72 DB2 data sharing group with Java stored procedures . . . . . . . . . . . . . . . . 75 Java stored procedure object interrelationships . . . . . . . . . . . . . . . . . . . . 84 Our Java stored procedure object structure. . . . . . . . . . . . . . . . . . . . . . . . 85 Runtime environment overview SQLJ stored procedure. . . . . . . . . . . . 95 OS/390 JDBC program preparation process . . . . . . . . . . . . . . . . . . . . . . 122 OS/390 SQLJ program preparation process . . . . . . . . . . . . . . . . . . . . . . 129 AIX and Windows NT JDBC program preparation process . . . . . . . . . . . 145 AIX and Windows NT SQLJ program preparation process . . . . . . . . . . . 149 Source-centric migration for a JDBC application . . . . . . . . . . . . . . . . . . . 158 Executable-centric migration for a JDBC application. . . . . . . . . . . . . . . . 160 Three-part names prior to DB2 for OS/390 Version 6 . . . . . . . . . . . . . 187 Three-part name Version 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190 Package requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191 How it works. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192 Hopping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194 Loop back . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196 OPTIMIZE FOR large number . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 OPTIMIZE FOR how it works . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 Potential issue when using OPTIMIZE FOR n ROWS. . . . . . . . . . . . . . . 202 DDF connection pooling. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203 Typical parent / dependent relationship . . . . . . . . . . . . . . . . . . . . . . . . . . 223 Example DDL for a global temporary table . . . . . . . . . . . . . . . . . . . . . . . 225 Example DDL for an after-insert trigger . . . . . . . . . . . . . . . . . . . . . . . . . . 225 After-insert trigger to retrieve the generated value of an id-column. . . . . 227 Identity column data propagation issues . . . . . . . . . . . . . . . . . . . . . . . . . 229 What is a schema? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 How a schema is used explicit specification . . . . . . . . . . . . . . . . . . . . 235 How a schema is used implicit specification . . . . . . . . . . . . . . . . . . . . 236 CURRENT PATH special register . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 SET CURRENT PATH syntax. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238 Stored procedures overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245

Copyright IBM Corp. 2000

xi

41. 42. 43. 44. 45. 46. 47. 48. 49. 50.

DB2 stored procedures access DL/I databases. . . . . . . . . . . . . . . . . . . . 256 Stored procedures: parameters definition . . . . . . . . . . . . . . . . . . . . . . . . 263 Schema name: CALL statement 1/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271 Schema name: CALL statement 2/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272 SQL CALL statement (nesting) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273 Authorization CALL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276 Authorization who is checked? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278 Authorization example. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279 DISPLAY PROCEDURE command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280 Sample files directory structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348

xii

DB2 Java Stored Procedures: Learning by Example

Tables
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. JDBC driver types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 Stored procedure languages supported by DB2 platform . . . . . . . . . . . . . 14 ACME sample application components . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Sample Code Java package names . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 DB2 for OS/390 Java APAR enhancements . . . . . . . . . . . . . . . . . . . . . . . 58 VisualAge for Java Enterprise Edition for OS/390 . . . . . . . . . . . . . . . . . . 58 Sample USS library structure. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 Sample OS/390 library structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 Null handling within SQL stored procedures . . . . . . . . . . . . . . . . . . . . . . 100 Contents of SQLJPLAN by client and SP type using COLLID. . . . . . . . . 168 Contents of SQLJPLAN by client and SP type not using COLLID. . . . . . 169 Private protocol v DRDA access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 START / STOP command versus DDF status . . . . . . . . . . . . . . . . . . . . . 204 Comparison of Identity and ROWID columns . . . . . . . . . . . . . . . . . . . . . 228

Copyright IBM Corp. 2000

xiii

xiv

DB2 Java Stored Procedures: Learning by Example

Preface
Stored procedures can provide major benefits in the areas of application performance, code re-use, security, and integrity. The DB2 Family of products has offered support for stored procedures for some time, with each release offering significant enhancements over the last. In the meantime, Java has been making steady inroads as the standard application development language for many companies large and small. Its inherent portability and openness, combined with the good availability of skilled programming resource, has made it an increasingly attractive choice, and the central plank in many organizations e-business strategy. Until recently, DB2 did not support stored procedures written in Java, so the advantages of the two technologies could not be combined. The latest releases of DB2 have changed all that, opening up new possibilities for efficient, secure, highly portable application development. This IBM Redbook aims to give the reader an in-depth understanding of the techniques and issues associated with the development of DB2 stored procedures written in Java and using SQLJ and/or JDBC for their SQL operations. The extensive collection of sample code presented in this book and included on the accompanying CD-ROM was designed to run against DB2 UDB Server across the OS/390, Windows, and UNIX platforms. We have assumed that the reader has at least a basic understanding of Java terminology (such as classes, methods and packages) in addition to exposure to general DB2 application development concepts.

How this book is structured


This book is organized in four major sections: Part 1, Background provides background information on Java support on the various platforms covered in this book, together with an overview of the ways in which DB2 can be accessed from within Java programs. Part 2, Developing Java stored procedures forms the main body of the book. In it, we provide detailed guidance on how to configure your environment to use Java stored procedures, and how to design, code, prepare, and test them. Part 3, DB2 UDB for OS/390 V6 various enhancements covers some of the various network computing enhancements delivered in DB2 UDB for OS/390 Version 6.

Copyright IBM Corp. 2000

xv

Part 4, Appendices contains complete listings of all of the sample code referred to throughout the book, together with additional reference material.

The team that wrote this redbook


This redbook was produced by a team of specialists from around the world working at the International Technical Support Organization San Jose Center. Maria Sueli Almeida is a Certified I/T Specialist - Systems Enterprise Data, and is currently a DB2 for OS/390 and Distributed Relational Database System (DRDS) specialist at the International Technical Support Organization, San Jose Center. Before joining the ITSO in 1998, Maria Sueli worked at IBM Brazil assisting customers and IBM technical professionals on DB2, data sharing, database design, performance, and DRDA connectivity. Kirk Condon is a Senior Systems Manager for SBC Communications, working in St. Louis, Missouri. He has 17 years of experience in the software field. He holds two degrees from the University of Kansas: one in Computer Science, the other in English. He currently specializes in DBMS issues, helping to guide internal projects to the DBMS technologies that will meet the scaling, performance, and reliability objectives of the project. He currently specializes in Java issues that impact DBMS technologies, such as JDBC and SQLJ. He also reviews emerging technologies to assess their impact to the technologies supported by the SBC DBMS Organization. He has worked extensively with TUXEDO, ORACLE, C, and UNIX. He has developed programs for MVS and WINDOWS in disparate languages such as COBOL, PL/1, and PowerBuilder, using database technologies such as DB2, IMS, and SYBASE. He also has supported the ORACLE Transparent Gateway and the ORACLE Application Server. Michael Fischer is a DB2 Technical Specialist at the Santa Theresa Laboratory in San Jose, CA, working out of Minneapolis, MN. He has 29 years of experience in information services and 8 years experience working with DB2 OS/390. He has a degree in Business from the Metropolitan State University of Minnesota. In this time he has gained a significant amount of practical experience in application programming, database administration, technical architecture, performance tuning, and systems programming. He has worked at IBM for the 3 last years. His areas of expertise at IBM include DB2 OS/390, data sharing, SAP DB2 data sharing, and performance and tuning.

xvi

DB2 Java Stored Procedures: Learning by Example

Michael is the co-author of the IBM Redbook, Getting Started with DB2 Stored Procedures: Give Them a Call through the Network. He has also given presentations for the local DB2 User Groups of the Midwest, in the area of DB2 OS/390. Julian Stuhler is a Principal Consultant with Triton Consulting in the United Kingdom. He has over 14 years experience working with the DB2 Family of products for a number of large UK customers, including insurance, telecommunications, banking, financial services and manufacturing companies. In that time he has obtained a large amount of practical experience in areas as diverse as systems programming, application programming, database administration, technical architecture and performance tuning. More recently, Julian has specialized in distributed database performance and the relational database connectivity issues surrounding Internet and intranet applications. Julian has lectured widely on DB2 subjects, both in the UK and Europe. This includes presentations for the International DB2 Users Group (IDUG), Candle Performance Seminars, the UK GUIDE DB2 Working Group, and European GUIDE meetings. Julian is an IBM DB2 Gold Consultant, a regular teacher for IBM's European Education Centre in Belgium, and is currently a member of both the IDUG European Conference Planning Committee and the UK DB2 Guide Committee.

Thanks to the following people for their invaluable contributions to this project: Peggy Abelite John Campbell Curt Cotner Ramani Croisettier Thomas Eng Christopher Farrar Claire McFeely Todd Munk Judy Tobias Tom Toomire IBM Silicon Valley Laboratory Brent Gross Robert Indrigo

xvii

Mike Winer IBM Toronto Laboratory Paolo Bruni Yvonne Lyon IBM International Technical Support Organization, San Jose Center Vasilis Karras Rich Conway Bob Haimowitz IBM International Technical Support Organization, Poughkeepsie Center

Comments welcome
Your comments are important to us! We want our Redbooks to be as helpful as possible. Please send us your comments about this or other Redbooks in one of the following ways: Fax the evaluation form found in IBM Redbooks review on page 393 to the fax number shown on the form. Use the online evaluation form found at ibm.com/redbooks Send your comments in an Internet note to redbook@us.ibm.com

xviii

DB2 Java Stored Procedures: Learning by Example

Part 1. Background

Copyright IBM Corp. 2000

DB2 Java Stored Procedures: Learning by Example

Chapter 1. Java platform support


This chapter presents an overview of Java and how it is supported by the various platforms covered within this book.

1.1 Java overview


Java is a cross-platform language developed by Sun. Most companies have embraced Java, and are well on their way towards integrating Java with their existing technology. IBM is no exception, having become a leader in the use of Java technology. Java is designed to be portable, and Java programs developed on one platform can often run unchanged on many computer systems. The most important characteristics that make Java portable are: Java compiles to machine-independent bytecode. Java is typically compiled and executed in a two-step process. First, the Java code is compiled to bytecode, which means an assembly language for an idealized Java virtual machine (JVM). Second, this bytecode is executed by a run-time system, which can be either an interpreter, that is, an emulator for the JVM, or a Just-In-Time (JIT) compiler that first compiles the bytecode to native code, then executes the result. Summarizing, the two steps of this process can be done on totally separate platforms. Java has a portable graphic library. In many software systems, the biggest hindrance to portability is the user interface. Interfaces have typically been developed using a native windowing system rather than a cross platform graphics toolkit, because until now, this was the most convenient and widely available option. However, this often meant that distribution on a different operating system required a complete rewrite of the GUI. The Java developers realized that a truly portable language would need a standard graphics library, and included one from the beginning of the languages development. Java avoids hard-to-port constructs. The Java specification defines the size of primitive data structures such as booleans, doubles, unlike some languages that allow this to vary among implementations. For objects, Java programs cannot inadvertently depend on implementation-specific details such as the amount of memory an object consumes, or the internals of how fields or functions are laid out within an object. Java even avoids reference to the local file system when

Copyright IBM Corp. 2000

specifying which classes your program needs, using operating system neutral class and package name instead. Objects are central to Java. Understanding how they are created and used is the first task for a Java programmer. Therefore, if you are not familiar with object-oriented programming, you will need to spend some time to acquire an understanding of this concept. This book covers the use of the Java programming language for coding stored procedures within DB2 UDB. We make the assumption that the reader understands basic concepts of Java, such as: Classes Methods Packages JAR files Java Development Kit (JDK) Java environment variables, such as CLASSPATH A number of excellent publications exist that can assist you in understanding these concepts (see Appendix G, Related publications on page 359).

1.2 Java and the OS/390 Platform


In this section, we describe the Java support available on the OS/390 platform, together with some of the additional utilities required to implement Java stored procedures.

1.2.1 OS/390 UNIX System Services


OS/390 UNIX System Services is an optional, no-charge feature of OS/390 that supplies UNIX functionality on the OS/390 platform. It runs concurrently with the MVS system as a separate task. Applications can run under USS; in fact, some products require USS (and Java is one of these).

1.2.2 Enterprise Toolkit for OS/390


The Enterprise Toolkit for OS/390 (ET/390) is part of VisualAge for Java Enterprise Edition for OS/390. ET/390 provides a number of facilities to allow you to code and test enterprise Java applications on the S/390 platform.

DB2 Java Stored Procedures: Learning by Example

1.2.2.1 The OS/390 High Performance Java Compiler The OS/390 High Performance Java Compiler is part of ET/390. Its purpose is to bind standard Java bytecode into native S/390 object code, which can then run as an executable.
Note

The high performance Java compiler is also known by several other names, including; VisualAge for Java Enterprise Toolkit for OS/390 Byte Code Binder ET/390 Byte Code Binder OS/390 Byte Code Binder For convenience, we will simply refer to the compiler as the HPJ within this book. The HPJ was created for two major reasons: To allow performance-critical Java code to execute more quickly than it would in the interpretive OS/390 Java Virtual Machine (JVM) environment. To allow Java code to be executed in environments that do not have their own JVM (such as DB2 stored procedure address spaces). The HPJ is therefore necessary if you wish to implement Java stored procedures on DB2 for OS/390. Although use of the HPJ creates an OS/390 specific module that will not execute in other environments, code portability is retained, as the Java source and bytecode files are still completely standard. In the future, DB2 stored procedure address spaces will support a JVM environment, allowing the use of stored procedures executing as native Java bytecode, and the HPJ will not be necessary. However, depending upon the level of performance achieved with the JVM implementation, it is possible that you will still want to use the HPJ for performance-critical stored procedures. 1.2.2.2 Other ET/390 tools ET/390 provides a number of additional tools to assist with S/390 Java development and testing. These include: A workstation-based interactive debugger, to allow you to debug your code as it runs.

Chapter 1. Java platform support

A workstation-based performance analyzer, to allow you to graphically identify parts of your programs that may be worth tuning. These and other facilities are described in the Java Programming Guide for OS/390, SG24-5619.

1.3 Java and the UNIX Platform


Thousands of Java programs run on the UNIX platform. Many developers work directly with the Java Standard Development kits available from Sun and IBM to compile and test their Java programs. There are a number of add-on utilities, such as native-code compilers, debuggers, visual builders, performance analyzers, and other tools commonly found for programming languages. DB2 UDB for UNIX, Windows, OS/2 ships with a JDK. If another version is desired, the database can be configured to use a JDK installed anywhere on the system. It is not necessary to use a native-code compiler to transform Java to something that can be used by the database.

1.4 Java and the Windows NT Platform


Like the UNIX platform, many Java programs run on the UNIX platform. Many developers work directly with the Java Standard Development kits available from Sun and IBM to compile and test their Java programs. There are a number of add-on utilities, such as native-code compilers, debuggers, visual builders, performance analyzers, and other tools commonly found for programming languages. VisualAge for Java is a widely popular GUI builder that many developers run on Windows NT. DB2 UDB for UNIX, Windows NT, and OS/2 all ship with a JDK. If another version is desired, the database can be configured to use a JDK installed anywhere on the system. It is not necessary to use a native-code compiler to transform Java to something that can be used by the database.

DB2 Java Stored Procedures: Learning by Example

Chapter 2. Java and DB2


This chapter provides some background information on Java database connectivity and DB2 stored procedures, and introduces many of the concepts used throughout the rest of the book.

2.1 Java database connectivity


Java database connectivity has matured to the extent that the developer now has two alternative APIs for accessing a database from within a Java application: SQLJ and JDBC. JDBC is a component of the core Java API standard as defined by Sun, as it is an integral part of the Java JDK. JDBC does not directly embed SQL in the Java code, but implements a set of methods (much like ODBC) that allow SQL statements to be passed to the database, and results to be accessed and manipulated. SQLJ is an ANSI (and soon to be ISO) standard set of extensions to the core Java classes that allow SQL to be directly embedded within Java applications, in much the same way as it can be embedded in other languages such as COBOL and PL/1. This book will cover Java stored procedure support within DB2, but it is important to know that you can also make extensive use of JDBC and SQLJ from stand-alone Java programs.

2.1.1 DB2 JDBC programs


The JDBC API is a standard Java interface for connecting to relational databases from Java. JDBC consists of two parts: the high level API and multiple low-level drivers for connecting to different databases. It specifies Java interface, classes, and exceptions to support connections, SQL data manipulation language (DML), SQL data definition language (DDL), processing of data result sets, and so on. JDBC supports use of dynamic SQL so it can deal with situations where you do not know the table and column names at the time the application is written. Unlike static embedded SQL programs, dynamic SQL programs involve the execution of at least some SQL statements that are not completely known until runtime. Dynamic SQL allows you to create general and flexible applications, because the full text of the SQL statement does not have to be known at compilation time.

Copyright IBM Corp. 2000

2.1.1.1 JDBC and DB2 UDB for OS/390 JDBC is supported by VisualAge for Java based tools. It requires DB2 Version 5 or higher and OS/390 Version 2 release 5 or higher. As shown in Figure 1, JDBC-based Java programs are compiled into Java bytecode using the javac compiler, which is part of the Java Development Toolkit (JDK). Once compiled, they can be executed in the OS/390 JVM. To use JDBC, your program needs to include the java.sql package and to invoke methods according to the JDBC specification. The JDBC driver for DB2 UDB for OS/390 is a Type-2 driver, which gives substantial performance improvements to JDBC applications.

2.1.2 DB2 SQLJ programs


IBM's DB2 SQLJ driver complies with the ANSI X.3.135 standard, and allows you to create, build, and run Java applications containing embedded static SQL statements that are bound to a DB2 database. SQLJ can provide better performance and security than JDBC, based on the program authors SQL privileges. SQLJ is pre-processed by the DB2 SQLJ Translator. Coding SQLJ is much simpler, is more efficient, and performs better at runtime. This means more programmer productivity and better system utilization. SQLJ consists of a set of clauses that extend Java programs. The language specification is a joint one, supported by leading database vendors such as IBM, Oracle and Tandem. It is supported by IBMs VisualAge for Java tools, and requires DB2 Version 5 or higher and OS/390 Version 2 release 5 or higher. When using SQLJ, you directly embed SQL statements within your Java program following certain standard syntax rules. The DB2 SQLJ program preparation requires three steps: 1. Run the SQLJ translator, which is done using the SQLJ command against the source code. The SQLJ translator is comparable to the preprocessors used to support embedded static SQL in other languages, such as COBOL, and is responsible for extracting the embedded SQL commands from the source file and replacing them with calls to the SQLJ runtime library. The result is a Java source code program (.java file) that can be compiled using a Java compiler, and zero or more SQL profiles that contain

DB2 Java Stored Procedures: Learning by Example

information about the SQL operations in the program. SQLJ profiles are vendor-independent, and need to be customized for the target database in a later step. By default, SQLJ profile filenames have .ser as extension. The SQLJ translator generates a profile for each connection context class in the application (a connection context class corresponds to a particular type of database schema to which your program connects). SQLJ profiles are not produced if there are no SQLJ executable statements in the SQLJ source code. 2. Compile the Java source code output by the translator, using the javac command. This results in one or more .class files containing Java bytecode. By default, the SQLJ command invokes the Java compiler automatically. 3. Customize the SQLJ profiles for DB2, which is done using the db2profc command. Profiles are vendor-independent; therefore, they must be customized. The customization process essentially transforms the generic SQLJ profiles into DB2-specific DBRMs, which can then be bound to DB2 in the normal way. See Part 2, Developing Java stored procedures on page 17 for detailed information.

2.1.3 Choosing the access method: JDBC versus SQLJ


The JDBC and SQLJ APIs are both widely accepted open industry standards. However, each has its own set of advantages and disadvantages, which are covered below. 2.1.3.1 Application coding considerations If you come from a database background and have SQL skills, SQLJ is usually quicker and more intuitive than JDBC, as it allows you to directly embed SQL within your application code, as shown in the code fragment below:
... System.out.println("Add_customer: about to get hi cust no"); #sql { SELECT HI_CUST_NO+1 INTO :new_cust_no FROM HI_CUST_NO }; // #sql

Chapter 2. Java and DB2

...

In contrast, JDBC uses a series of generic methods to perform the data access, which is almost always more verbose than the SQLJ equivalent. For example, the JDBC equivalent of the SQLJ code above would look like this:
... System.out.println("Add_customer: about to get hi cust no"); sql = "SELECT HI_CUST_NO+1 " + "FROM HI_CUST_NO"; res = stmt.executeQuery(sql); res.next(); new_cust_no = res.getInt(1); ...

You can see that the JDBC version requires more code, and a knowledge of JDBC methods such as executeQuery, next and getInt. Note also that JDBC does not support the SELECT ... INTO statement. 2.1.3.2 Performance: static versus dynamic SQL Another major differentiator between JDBC and SQLJ can be the way in which your programs perform. JDBC presents a string containing an SQL statement to the database at runtime (which may have just been constructed within the Java application). The first time DB2 gets to see the SQL is when it is actually executed, so all JDBC calls, by their very nature, consist of dynamic SQL . When DB2 is passed the SQL statement, it must perform a number of steps to prepare the statement before it is able to execute it (including syntax checking, authorization checking, and access path selection), and this can often require longer to perform than the actual SQL itself. SQLJ is able to use static SQL by actually embedding the SQL statements within the application code. The SQLJ program preparation process extracts this SQL and binds it against the database, allowing DB2 to perform all of the checks and access path selection as a one-off process. At run time, DB2 uses the pre-prepared access plan and is able to immediately execute the SQL. In general, an SQLJ statement should therefore run more quickly than an equivalent JDBC statement1 .

10

DB2 Java Stored Procedures: Learning by Example

2.1.3.3 Authorization The way in which authorization is handled can also differ, due to the way in which dynamic and static SQL authority checking is managed by DB2. As JDBC uses dynamic SQL, all authorization checking is performed at execution time. By default, DB2 will use the authorization ID of the application process for authorization of dynamic SQL statements. This requires granting sufficient authority directly to that authorization ID to be able to execute any of the SQL statements the JDBC program is likely to submit. SQLJ uses static SQL, so all authority checking is performed at BIND time. The BIND authorization ID is used in the authorization checks, and all that is required at run time is authority to execute the DB2 package associated with the stored procedure (and, for DB2 for OS/390 V6, the authority to run the stored procedure itself). This is a complex area that is covered in more detail in 9.3, Client authorization issues on page 174. 2.1.3.4 So which access method should I use? As usual, the answer to this question is It depends! As a general rule, we recommend that you use SQLJ wherever possible, as it offers significant benefits in developer productivity, performance, and security when compared to JDBC. However, you may encounter situations that require the ability to build the SQL statement within your Java application at run time, and only JDBCs dynamic SQL support can offer this sort of additional flexibility. In these cases, you may be able to benefit from the fortunate situation that both SQLJ and JDBC can be mixed in the same source logic. The majority of the sample code included in this book and the accompanying CD-ROM is provided in both SQLJ and JDBC versions.

2.1.4 JDBC driver types


To allow the generic functions and methods implemented by JDBC to be translated into database-specific calls, each database vendor must deliver a JDBC driver to act as an interface.
1

Note that DB2 for OS/390 has introduced several features (such as the dynamic statement cache) that help to reduce the overheads associated with dynamic SQL and bring JDBC and SQLJ performance closer together. The degree to which these features will assist the performance of your JDBC calls will depend on a large number of factors - your mileage may vary.

Chapter 2. Java and DB2

11

The JDBC standard defines four different types of driver, as defined in Table 1 below.
Table 1. JDBC driver types

Type

Description

Contains native methods? Yes Yes No No

Portable? a

Uses ODBC? Yes No No No

1 2 3 4

JDBC/ODBC Bridge Native - API part Java Net - protocol all Java Native - protocol all Java

No No Yes Yes

a. Note that this column refers to the portability of the driver itself across various platforms and operating systems, and not the portability of the application using it.

IBM currently supplies Type 2 and some Type 3 drivers for the various members of the DB2 family, as detailed in the following sections. 2.1.4.1 DB2 UDB for OS/390 DB2 UDB for OS/390 Version 5 and Version 6 have Type 2 drivers available as part of the SQLJ support APAR (this SQL service APAR is a prerequisite for Java stored procedures - see 4.1.1, Prerequisites on page 57 for further information). 2.1.4.2 DB2 UDB for UNIX, NT and OS/2 Both Version 6 and Version 7 of DB2 UDB for UNIX, Windows, and OS/2 provide Type 2 and Type 3 drivers. These are installed along with the rest of the Java support components if so requested during the DB2 UDB install process.

2.2 Java and DB2 stored procedures


In this section, we provide a general description of DB2 stored procedures, together with an overview of the prerequisites necessary if you are to write them in the Java language.

2.2.1 What is a stored procedure?


Simply put, a stored procedure is a program or routine that is invoked via an SQL CALL statement issued from a client program, and executes under the control of the database manager. Parameters can be passed to, and received from, the stored procedure.

12

DB2 Java Stored Procedures: Learning by Example

Stored procedures offer a number of powerful advantages for distributed application development. These include the following; Common business functions can be encapsulated in stored procedures and made universally accessible, promoting code re-use and consistency, and providing support for object-oriented application design. Performance can be significantly improved for distributed applications that require several SQL calls to be made by the client against a remote database. Instead of one trip across the network for each of these calls, they can be combined and executed locally within a stored procedure so only a single trip across the network is needed. This performance improvement can also create subsequent benefits in reducing lock contention. Security can be enhanced, as developers are only able to work with the stored procedure input and output parameters, and are prevented from viewing or altering the underlying code that implements the business function. DB2 stored procedures are integrated with and exploit some of the key OS/390 scalability and availability features. Stored procedures benefit from OS/390 Workload Manager (WLM) address spaces, allowing individual stored procedures to be scheduled according to their business priority and optimized for the system workload. In addition, multiple WLM-controlled address spaces for DB2 stored procedures provide improved program isolation.

2.2.2 Supported stored procedure languages


DB2 stored procedures can be written in a number of languages, with the intention of supporting a common set of languages across the entire DB2 Family in the future. Table 2 summarizes the language support at the time this book was written.

Chapter 2. Java and DB2

13

Table 2. Stored procedure languages supported by DB2 platform

DB2 Version DB2 for OS/390 Java SQL Procedures Languagea COBOL C/C++ PL/1 REXX Version 5 with APAR PQ31845 Version 6 with APAR PQ31846 Version 6 with APARS PQ29782, PQ30467 & PQ433026 Version 4 Version 4 Version 4 Version 5 with APAR PQ29706 Version 6 with APAR PQ30219 DB2 for UNIX, Windows NT, and OS/2 Version 5 Version 7

Version 2 Version 2 N/A Version 2b

a. SQL Procedures Language is based on PSM, or Persistent Stored Modules, which is an ISO standard procedural SQL language. b. Use of REXX for stored procedures on the UNIX, Windows and OS/2 platforms is not encouraged for security reasons.

This book concentrates on the development of stored procedures written in the Java language.

2.2.3 DB2 Java stored procedures


DB2 for OS/390 Version 5 and Version 6 provide support for compiled Java stored procedures only. This means that you have to compile them into native OS/390 executable modules before execution, using the OS/390 High Performance Java Compiler described in 1.2.2.1, The OS/390 High Performance Java Compiler on page 5. An additional consideration is that, unlike stored procedures written in other languages, Java stored procedures have to run in a WLM address space. Figure 1 shows how DB2 provides Java support on the OS/390 platform through JDBC programs, SQLJ programs, and compiled stored procedures written in Java

14

DB2 Java Stored Procedures: Learning by Example

Java and DB2 UDB for OS/390

ET/390 hpj Compiler

Java Source Code

SQLJ Translator

Java Byte Code

OS/390 Native Instructions

Java Compiler

DB2 Bind SQLJ JDBC

Java Virtual Machine UNIX System Services OS/390

DB2 Stored Procedure DB2 UDB for OS/390

Figure 1. Java and DB2 for OS/390

Figure 2 shows a similar diagram for DB2 on the UNIX, OS/2, and Windows platforms. You can see that the picture here is somewhat simpler, because there is no requirement to compile Java stored procedures into native operating system instructions before execution (as there is on the OS/390 platform).

Java and DB2 UDB for Unix, Windows, OS/2

Java Source Code

SQLJ Translator

Java Byte Code

Java Compiler

DB2 Bind SQLJ JDBC

DB2 Stored Procedure Java Virtual Machine Unix, Windows, OS/2 DB2 UDB for Unix, Windows, OS/2

Figure 2. Java and DB2 for UWO

Chapter 2. Java and DB2

15

16

DB2 Java Stored Procedures: Learning by Example

Part 2. Developing Java stored procedures

Copyright IBM Corp. 2000

17

18

DB2 Java Stored Procedures: Learning by Example

Chapter 3. Java sample application: the ACME software company


This chapter describes the sample application that we created to demonstrate the implementation of Java stored procedures in DB2 UDB on the OS/390, NT, and UNIX platforms. All of the files necessary to reconstruct the sample application can be found on the CD-ROM. Alternatively, you can download them directly from the IBM Redbooks Web site: ibm.com/redbooks. Refer to Appendix E, Using the additional material on page 347 for more details.

3.1 Overview
The Java examples in this book explore the initial programs of a mythical start-up software company named ACME. This company chose to develop their customer management systems using DB2 UDB.

3.2 System design


The ACME system design, shown in Figure 3 on page 20, wraps the business logic and database access within DB2 using stored procedures written in Java. This allows the companys software ordering system to be accessed worldwide via a simple HTML browser as well as by batch programs. If the application architecture changes over time, these same stored procedures could also be called in a large number of alternative ways (such as from within Java applets, Enterprise Java beans, ODBC applications, and many more). Similarly, if ACMEs hardware platform changes in the future, the Java stored procedures can be easily ported to the new environment with very few changes being required. Our sample application consists of only those components necessary to implement a single business function (to add a software order for a new customer). Of course, in a real situation, many additional business functions would need to be handled, but these could all use the same basic approach as shown in our examples.

Copyright IBM Corp. 2000

19

S/390
Websphere

HTTP Server

Java Servlet

Internet

... Call... ...

DB2 UDB For OS/390 V6

DB2 Data Browser


Batch

DB2

COBOL Program ... Call... ...

Figure 3. ACME Software Company System Design

20

DB2 Java Stored Procedures: Learning by Example

3.3 Sample application components


Table 3 lists the individual components of the sample application.
Table 3. ACME sample application components

Type
Table

Name
CUSTOMER PRODUCT ORDER ORDER_ITEM

Description
Stores customer details Stores product details Stores order details Stores order item details Adds new customer details into ACMEs system. Summarizes order information by order number or customer number in groups of 5 items Reads new customer / order information from a batch file and invokes the Add_cust_order stored procedure.

Stored Procedure

Add_customer Query_oi_summ

COBOL Program

ADDCUST

To provide practical examples that covered as many different situations as possible, we produced versions of the stored procedures and clients that ran on different platforms OS/390, AIX and Windows NT and used different APIs to access DB2 data such as JDBC only, SQLJ only, and a combination of both JDBC and SQLJ. We also produced a COBOL version of the OS/390 programs, to allow those readers familiar with that language to more easily interpret what the Java programs are doing. Finally, to allow us to make use of some of the new network computing features being introduced to DB2 while retaining compatibility with older releases, we produced two versions of the code. The standard version uses features available today across the entire DB2 family. The enhanced version uses some of the new features available in the DB2 family. The enhanced version also includes the Query_oi_summ stored procedure, which explores advanced topics in Java stored procedures.

Chapter 3. Java sample application: the ACME software company

21

The stored procedures were packaged according to the following naming conventions:
ACMEapf where

refers to the API

J for JDBC S for SQLJ B for Both JDBC and SQLJ C for COBOL O for OS/390 U for UNIX (AIX) N for Windows NT S for standard E for enhanced

refers to the platform

refers to the features

These Java package names are shown in full in Table 4 below. The Java package names in bold italics are included in the sample code that accompanies this book (see Appendix B, Sample code, DDL, and preparation scripts on page 287).
Table 4. Sample Code Java package names

API

Platform

Features Standard Enhanced


ACMEJOE

JDBC

OS/390 AIX Windows NT

ACMEJOS ACMEJUS ACMEJNS ACMESOS ACMESUS ACMESNS ACMEBOS ACMEBUS ACMEBNS ACMECOS
N/A N/A

ACMEJUE ACMEJNE
ACMESOE

SQLJ

OS/390 AIX Windows NT

ACMESUE ACMESNE
ACMEBOE ACMEBUE ACMEBNE

BOTH (SQLJ and JDBC)

OS/390 AIX Windows NT

COBOL

OS/390 AIX Windows NT

ACMECOE
N/A N/A

22

DB2 Java Stored Procedures: Learning by Example

In addition, client applications invoking these stored procedures were written in Java and COBOL. For the Java client applications, there is a JDBC version and a separate SQLJ version.

3.3.1 DB2 naming conventions


The sample DDL and source code refer to various database names, table names and stored procedure names, which we describe below. See 5.1.1, Naming on page 83 for a more detailed discussion of object naming in a Java stored procedures environment.
3.3.1.1 Database names To allow us to concurrently develop the samples against both the standard and enhanced versions of the tables, we placed the tables in different databases as follows: ACMES is the database in which we put the Standard objects. ACMEE is the database in which we put the Enhanced objects. 3.3.1.2 Table qualifiers To allow us to concurrently develop the samples against both the standard and enhanced versions of the tables, we used different table creators as follows: ACMES is the qualifier referring to Standard tables. ACMEE is the qualifier referring to to Enhanced tables. 3.3.1.3 Stored procedure names DB2 for OS/390 Version 5 does not support the use of schemas in stored procedure names. Therefore, we prefixed the stored procedure name with the type and level it was aimed at, as follows:
af_spname
where

refers to the API

J for JDBC S for SQLJ B for Both JDBC and SQLJ C for COBOL S for standard

f spname

refers to the features refers to the stored procedure name

Chapter 3. Java sample application: the ACME software company

23

For DB2 UDB for OS/390 V6 and DB2 UDB for UNIX, Windows, OS/2 (the enhanced feature level in our examples), we were able to use schemas to qualify the stored procedure name, with the schema name being set to the Java package name that the example belonged to.

3.4 Portability issues


Java is highly-touted in the trade press as being portable. This section discusses the portability of the Java stored procedures built for this book.

3.4.1 Java stored procedure portability


The standard version of Add_customer was initially written to NT, which then ported immediately and easily to UNIX and OS/390. The only difference within the Java code came in the Java clients that invoked the Add_customer stored procedure....and these changes were limited to the URL and the driver name. (Exception: DB2 V5 for OS/390 does not support schemas.)

3.4.2 DB2 portability issues


Although there is a high degree of consistency between the implementations of DB2 on various platforms at an application level, some minor differences exist in areas such as DDL. This required a few changes to be made to the DB2 for OS/390 version of the DDL in order for it to work in the NT and AIX environments. Examples of these changes include; Changing the CREATE DATABASE SQL statement to a CREATE DATABASE COMMAND (with associated parameter changes). Removing references to storage groups. Altering parameters in CREATE TABLESPACE statements. Altering table space references in CREATE TABLE statements. No changes were required to any of the DML embedded within the application code.

3.5 Sample stored procedures standard


We demonstrate Java stored procedures with four examples.

24

DB2 Java Stored Procedures: Learning by Example

3.5.1 JDBC stored procedure sample


Below is the source code of the stored procedure Add_customer written in Java using JDBC.
//////////////////////////////////////////////////// // JDBC Stored Procedure Add_customer // //////////////////////////////////////////////////// package ACMEJNS ; import java.sql.*; import java.math.*; public class Add_customer { public static void add_customer ( String in_cust_firstname, String in_cust_lastname, String in_cust_address, int[] out_cust_no, String[] mark, String[] mark_error_text ) throws SQLException, Exception { try { java.sql.PreparedStatement pstmt; ResultSet res; int new_cust_no; int updateCount; int selectCount; String sql; //////////////////////////////////////////////////////// // mark_error_text and mark are used to report // errors trapped in the catch block //////////////////////////////////////////////////////// mark_error_text[0] = "OK"; new_cust_no = 0; //////////////////////////////////////////////////////// // get the connection //////////////////////////////////////////////////////// mark[0] = "Add_customer: getConnection"; Connection con = DriverManager.getConnection("jdbc:default:connection"); ////////////////////////////////////////////////////////

Chapter 3. Java sample application: the ACME software company

25

// find the next customer number to use //////////////////////////////////////////////////////// mark[0] = "Add_customer: createStatement"; Statement stmt = con.createStatement(); stmt.execute("set schema = ACMES"); mark[0] = "Add_customer: Get high cust no"; sql = "SELECT HI_CUST_NO+1 " + "FROM HI_CUST_NO"; res = stmt.executeQuery(sql); //////////////////////////////////////////////////////// // there will be only one number so use next() to // get the first row //////////////////////////////////////////////////////// res.next(); new_cust_no = res.getInt(1); //////////////////////////////////////////////////////// // update the table -- note that this should be // modified in a multi-user application //////////////////////////////////////////////////////// mark[0] = "Add_customer: Update high cust no"; sql = "UPDATE HI_CUST_NO " + "SET HI_CUST_NO = ?"; pstmt = con.prepareStatement(sql); pstmt.setInt(1, new_cust_no); updateCount = pstmt.executeUpdate(); //////////////////////////////////////////////////////// // insert a new customer using the calculated cust no //////////////////////////////////////////////////////// mark[0] = "Add_customer: Insert new cust row"; sql = "INSERT INTO CUSTOMER " + "( " + "CUST_NO, " + "CUST_FIRSTNAME, " + "CUST_LASTNAME, " + "CUST_ADDRESS " + ") " + "VALUES" + "( " + "? , " + "'"+ in_cust_firstname + "' , " + "'"+ in_cust_lastname + "' , " + "'"+ in_cust_address + "'" + " )"; pstmt = con.prepareStatement(sql);

26

DB2 Java Stored Procedures: Learning by Example

pstmt.setInt(1, new_cust_no); updateCount = pstmt.executeUpdate(); out_cust_no[0] = new_cust_no; mark[0] = "Add_customer: Complete"; if (stmt != null) stmt.close(); if (con != null) con.close(); } // try catch (SQLException e) { mark_error_text[0] = "SQLException raised, SQLState = " + e.getSQLState() + " SQLCODE = " + e.getErrorCode() + " :" + e.getMessage(); } catch (Exception e) { mark_error_text[0] = "Add_customer: major exception caught: " + e.getMessage(); } } // add_customer }

3.5.2 SQLJ stored procedure sample


Below is the source code of the stored procedure Add_customer written in Java using SQLJ.
package ACMESNE ; //////////////////////////////////////////////////// // SQLJ Stored Procedure add_customer //////////////////////////////////////////////////// import import import import java.sql.*; sqlj.runtime.*; sqlj.runtime.ref.*; java.math.*;

public class Add_customer { public static void add_customer ( String in_cust_firstname, String in_cust_lastname, String in_cust_address, int[] out_cust_no, String[] mark, String[] mark_error_text

Chapter 3. Java sample application: the ACME software company

27

) throws SQLException, Exception { System.out.println("Add_customer: start - SQLJ version"); try { //////////////////////////////////////////////////////// // mark_error_text and mark are used to report // errors trapped in the catch block //////////////////////////////////////////////////////// int new_cust_no; mark_error_text[0] = "OK"; mark[0] = "Add_customer: Get context"; System.out.println("Add_customer: about to getDefaultContext" ); DefaultContext ctx = DefaultContext.getDefaultContext(); mark[0] = "Add_customer: insert into customer"; #sql { INSERT INTO CUSTOMER ( CUST_FIRSTNAME, CUST_LASTNAME, CUST_ADDRESS ) VALUES ( :in_cust_firstname, :in_cust_lastname, :in_cust_address ) }; // #sql ///////////////////////////////////////////////////////////// // get the value of the identity column which is passed back ///////////////////////////////////////////////////////////// mark[0] = "Add_customer: retrieve cust no"; #sql { SELECT CUST_NO INTO :new_cust_no FROM GTT_CUST_NO }; //#sql out_cust_no[0] = new_cust_no; mark[0] = "Add_customer: complete"; } // try catch (SQLException e)

28

DB2 Java Stored Procedures: Learning by Example

{ mark_error_text[0] = "Add_Customer: SQLException raised: " + "SQLState = " + e.getSQLState() + " SQLCODE = " + e.getErrorCode() + " :" + e.getMessage(); System.out.println("Add_customer: caught sqlexception"); System.out.println("Add_customer: "+ mark_error_text[0]); e.printStackTrace(); } catch (Exception e) { mark_error_text[0] = "Add_customer: major exception caught: " + e.getMessage(); System.out.println("Add_customer: caught java exception"); System.out.println("Add_customer: "+ mark_error_text[0]); e.printStackTrace(); } } // add_customer }

3.5.3 COBOL stored procedure sample


Below is the source code of the stored procedure Add_customer written in COBOL. This example was tested on OS/390.
IDENTIFICATION DIVISION. PROGRAM-ID. "ADDCUST". ***************************************************** * * * ACME Software Company - Add New Customer * * * * This stored procedure inserts a row into the * * ACME.CUSTOMER table. * * * * The file PREPCUST contains the preparation JCL * * for this program. * * * ***************************************************** DATA DIVISION. WORKING-STORAGE SECTION. EXEC SQL INCLUDE SQLCA END-EXEC. 01 NEW-CUST-NO PIC S9(9) COMP. * DSNTIAR PARMS 01 ERROR-MESSAGE. 02 ERROR-LEN PIC S9(4) COMP VALUE +240.

Chapter 3. Java sample application: the ACME software company

29

02 77 77 77 77

ERROR-TEXT PIC X(80)

ERROR-TEXT-LEN PIC S9(9) ERR-CODE ERR-MINUS LINE-EXEC PIC 9(8) PIC X PIC X(20)

OCCURS 3 TIMES INDEXED BY ERROR-INDEX. COMP VALUE +80. VALUE 0. VALUE SPACE. VALUE SPACE.

LINKAGE SECTION. 01 CUST-FNAME PIC X(20). 01 CUST-LNAME PIC X(20). 01 CUST-ADDR PIC X(30). 01 CUST-NO PIC S9(9) COMP. 01 MARK PIC X(40). 01 MARK-ERROR-TEXT PIC X(240). * ***************************************************** * Procedure Division * ***************************************************** * PROCEDURE DIVISION USING CUST-FNAME, CUST-LNAME, CUST-ADDR, CUST-NO, MARK, MARK-ERROR-TEXT. EXEC SQL WHENEVER SQLERROR GOTO SQL-ERROR END-EXEC.

DISPLAY "ADD_CUSTOMER: START". MOVE "OK" TO MARK-ERROR-TEXT. * * Get new customer number * * MOVE "ADD_CUSTOMER: GET HIGH CUSTOMER NO" TO MARK. DISPLAY "ADD_CUSTOMER: GET HIGH CUSTOMER NO". EXEC SQL SELECT HI_CUST_NO+1 INTO :NEW-CUST-NO FROM HI_CUST_NO END-EXEC. * * Update high customer number * * MOVE "ADD_CUSTOMER: UPDATE HIGH CUSTOMER NO" TO MARK. DISPLAY "ADD_CUSTOMER: UPDATE HIGH CUSTOMER NO". EXEC SQL UPDATE HI_CUST_NO

30

DB2 Java Stored Procedures: Learning by Example

SET HI_CUST_NO = :NEW-CUST-NO END-EXEC. * * Insert into Customer table * MOVE "ADD_CUSTOMER: INSERT INTO CUSTOMER" TO MARK. DISPLAY "ADD_CUSTOMER: INSERT INTO CUSTOMER". EXEC SQL INSERT INTO CUSTOMER (CUST_NO, CUST_FIRSTNAME, CUST_LASTNAME, CUST_ADDRESS) VALUES (:NEW-CUST-NO, :CUST-FNAME, :CUST-LNAME, :CUST-ADDR) END-EXEC. MOVE NEW-CUST-NO TO CUST-NO. MOVE "ADD_CUSTOMER: COMPLETE" TO MARK. DISPLAY "ADD_CUSTOMER: COMPLETE". EXIT-PROG. GOBACK.

SQL-ERROR. MOVE SQLCODE TO ERR-CODE . IF SQLCODE < 0 THEN MOVE '-' TO ERR-MINUS. DISPLAY "ADD_CUSTOMER: NEGATIVE SQLCODE ENCOUNTERED". DISPLAY "ADD_CUSTOMER: SQLCODE = " ERR-MINUS ERR-CODE. CALL 'DSNTIAR' USING SQLCA ERROR-MESSAGE ERROR-TEXT-LEN. IF RETURN-CODE < 8 PERFORM ERROR-PRINT VARYING ERROR-INDEX FROM 1 BY 1 UNTIL ERROR-INDEX GREATER THAN 3 STRING ERROR-TEXT(1) ERROR-TEXT(2) ERROR-TEXT(3) DELIMITED BY SIZE INTO MARK-ERROR-TEXT ELSE DISPLAY "ADD_CUSTOMER: BAD RETURN CODE FROM DSNTIAR" DISPLAY "ADD_CUSTOMER: " RETURN-CODE. GO TO EXIT-PROG. ERROR-PRINT. DISPLAY "ADD_CUSTOMER: " ERROR-TEXT (ERROR-INDEX).

Chapter 3. Java sample application: the ACME software company

31

3.5.4 Combined SQLJ and JDBC example


The following example shows a combination of SQLJ and JDBC.
package ACMEBNS ; //////////////////////////////////////////////////// // SQLJ/JDBC Stored Procedure add_customer //////////////////////////////////////////////////// import import import import java.sql.*; sqlj.runtime.*; sqlj.runtime.ref.*; java.math.*;

public class Add_customer { public static void add_customer ( String in_cust_firstname, String in_cust_lastname, String in_cust_address, int[] out_cust_no, String[] mark, String[] mark_error_text ) throws SQLException, Exception { try { //////////////////////////////////////////////////////// // mark_error_text and mark are used to report // errors trapped in the catch block //////////////////////////////////////////////////////// ResultSet res; String sql; int new_cust_no; mark_error_text[0] = "OK"; new_cust_no = 0;

//////////////////////////////////////////////////////// // get default contect and connection //////////////////////////////////////////////////////// mark[0] = "Add_customer: Set context"; DefaultContext ctx = DefaultContext.getDefaultContext(); mark[0] = "Add_customer: getConnection"; Connection con = DriverManager.getConnection( "jdbc:default:connection");

32

DB2 Java Stored Procedures: Learning by Example

mark[0] = "Add_customer: createStatement"; Statement stmt = con.createStatement(); mark[0] = "Add_customer: Get high cust no"; //////////////////////////////////////////////////////// // determine high customer number using JDBC //////////////////////////////////////////////////////// sql = "SELECT HI_CUST_NO+1 " + "FROM ACMES.HI_CUST_NO"; res = stmt.executeQuery(sql); while (res.next()) { new_cust_no = res.getInt(1); } mark[0] = "Add_customer: Update high cust no"; //////////////////////////////////////////////////////// // update the table using SQLJ //////////////////////////////////////////////////////// #sql { UPDATE HI_CUST_NO SET HI_CUST_NO = :new_cust_no }; // #sql mark[0] = "Add_customer: Insert new cust row"; //////////////////////////////////////////////////////// // now can update the Customer table, using SQLJ //////////////////////////////////////////////////////// #sql { INSERT INTO CUSTOMER ( CUST_NO, CUST_FIRSTNAME, CUST_LASTNAME, CUST_ADDRESS ) VALUES ( :new_cust_no , :in_cust_firstname , :in_cust_lastname , :in_cust_address ) }; // #sql

Chapter 3. Java sample application: the ACME software company

33

out_cust_no[0] = new_cust_no; //set output cust no mark[0] = "Add_customer: Complete"; } // try catch (SQLException e) { mark_error_text[0] = "Add_Customer: SQLException raised: " + "SQLState = " + e.getSQLState() + " SQLCODE = " + e.getErrorCode() + " :" + e.getMessage(); } catch (Exception e) { mark_error_text[0] = "Add_customer: major exception caught: " + e.getMessage(); } } // add_customer }

3.6 Sample stored procedures enhanced


The previous examples, which showed the stored procedure Add_customer in various flavors, introduced using Java for building a stored procedure. In the following sections we show examples of more complex Java stored procedures. We developed the stored procedure, Query_oi_summ, which explores issues that will be encountered by programmers building a complex application. The problems addressed by this stored procedure include: Null handling Using ResultSets Error handling

3.6.1 JDBC enhanced stored procedure sample


Below is the JDBC version of the Query_oi_summ stored procedure.
//////////////////////////////////////////////////// // JDBC Stored Procedure Query_oi_summ // // This stored procedure demonstrates: // 1) handling null input fields // 2) generating interim values // into a temporary table which is returned // as a ResultSet to the client // 3) debugging by writing to a local file

34

DB2 Java Stored Procedures: Learning by Example

// 4) handling nulls returned from a query // // NOTE: if this stored procedure fails hard (dumps) // it may be because you have not created // a TMP directory on NT //////////////////////////////////////////////////// package ACMEJNE ; import import import import import import import import java.sql.*; java.math.*; java.io.*; java.io.StringWriter; java.io.PrintWriter; java.text.DateFormat; java.util.Date; java.text.SimpleDateFormat;

public class Query_oi_summ { public static void query_oi_summ ( String in_cust_no, String in_order_no, String[] mark, String[] mark_error_text, ResultSet[] out_rs ) throws SQLException, Exception { PrintWriter pwx = null; // declare outside try for catch to close final boolean dbg = true; // this could be set by an input parm try { //////////////////////////////////////////////////////// // establish debugging file: name is timestamped //////////////////////////////////////////////////////// Date debugDate = new Date(); DateFormat dateFormat = DateFormat.getDateTimeInstance(); ((SimpleDateFormat)dateFormat).applyPattern("MM_dd_HH_mm_ss"); String debugdf = dateFormat.format(debugDate); if (dbg) { pwx = new PrintWriter( new FileWriter("/tmp/" + debugdf + ".txt"), true); } //////////////////////////////////////////////////////// // mark_error_text and mark are used to report

Chapter 3. Java sample application: the ACME software company

35

// errors trapped in the catch block //////////////////////////////////////////////////////// mark_error_text[0] = "OK"; mark[0] = "Query_oi_summ: getConnection"; Connection con = DriverManager.getConnection("jdbc:default:connection"); //////////////////////////////////////////////////////// // establish where clause: either an order number is // sent in or a customer number is sent in //////////////////////////////////////////////////////// String where_clause = ""; if (null != in_cust_no) where_clause = " where OI.ord_item_prod_no = P.prod_no " + " and OI.ord_item_ord_no = O.ord_no " + " and O.ord_cust_no = C.cust_no " + " and C.cust_no = " + in_cust_no; else where_clause = " where OI.ord_item_ord_no = " + in_order_no + " and OI.ord_item_prod_no = P.prod_no" ; //////////////////////////////////////////////////////// // construct SQL statement and execute the Query //////////////////////////////////////////////////////// String sql = "select sum(OI.ORD_ITEM_QTY) Total_Qty ," + " P.prod_no Product#," + " P.prod_desc DESCRIPTION " + " from acmee.order_item OI, acmee.product P," + " acmee.order O, acmee.customer C" + where_clause + " group by P.prod_no, P.prod_desc " + " order by P.prod_desc "; if (dbg) pwx.println("sql =>" + sql + "<="); if (dbg) pwx.println("in_cust_no=" + in_cust_no); if (dbg) pwx.println("in_order_no=" + in_order_no); mark[0] = "Query_oi_summ: createStatement"; if (dbg) pwx.println(mark[0]); Statement stmt = con.createStatement(); mark[0] = "Query_oi_summ: executeQuery"; if (dbg) pwx.println(mark[0]); ResultSet rs = stmt.executeQuery(sql); if (dbg) pwx.println("post stmt.executeQuery"); String insert_vals = ""; Statement stmt2 = con.createStatement(); ////////////////////////////////////////////////////////

36

DB2 Java Stored Procedures: Learning by Example

// walk thru the result set, using the returned values // to insert to the correct category in the // summary table //////////////////////////////////////////////////////// if (rs == null) { mark_error_text[0] = "Query_oi_summ: query failed for " + sql; } else { while (rs.next()) { if (dbg) pwx.println("rs=" + rs.getString(1) + "," + rs.getString(2) + "," + rs.getString(3)); if (rs.getInt(1) < 6) insert_vals = " 'X' , ' ', ' ' "; else if (rs.getInt(1) < 11) insert_vals = " ' ' , 'X', ' ' "; else insert_vals = " ' ' , ' ', 'X' "; ////////////////////////////////////////////////////////////// // determine if production description is SQL null, in // which case we specifically tell JDBC that we are // inserting a null ////////////////////////////////////////////////////////////// String ins_prod_desc = ""; String ret_prod_desc = rs.getString(3); if (rs.wasNull()) ins_prod_desc = "NULL"; else ins_prod_desc = "'" + rs.getString(3) + "'" ; ////////////////////////////////////////////////////////////// // finally have all the calculated pieces to build the // full insert statement and execute it ////////////////////////////////////////////////////////////// String sql2 = "insert into acmee.order_item_summ " + "(prod_desc, qty_1_to_5,QTY_6_TO_10,QTY_11_PLUS) " + "values(" + ins_prod_desc + "," + insert_vals + ")"; if (dbg) pwx.println("sql2=" + sql2); stmt2.executeUpdate(sql2); } // while

Chapter 3. Java sample application: the ACME software company

37

} // else stmt.close(); stmt2.close(); if (dbg) pwx.println("stmt and stmt2 close"); //////////////////////////////////////////////////////// // get the summarized information into a ResultSet // to return to the client //////////////////////////////////////////////////////// Statement stmt3 = con.createStatement(); if (dbg) pwx.println("stmt3 executeQuery"); out_rs[0] = stmt3.executeQuery("select * from acmee.order_item_summ"); if (con != null) con.close(); if (dbg) pwx.println("graceful end"); if (dbg) pwx.close(); } // try catch (IOException e) { mark_error_text[0] = "Query_oi_summ: IOException: " + e.getMessage(); StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); mark_error_text[0] += ":printStackTrace=" + sw.toString() ; if (dbg) pwx.close(); } catch (SQLException e) { mark_error_text[0] = "Query_oi_summ: " + "SQLException raised, SQLState = " + e.getSQLState() + " SQLCODE = " + e.getErrorCode() + " :" + e.getMessage(); StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); mark_error_text[0] += ":printStackTrace=" + sw.toString() ; if (dbg) pwx.close(); } catch (Exception e) { mark_error_text[0] = "Query_oi_summ: Exception: " + e.getMessage(); StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); mark_error_text[0] += ":printStackTrace=" + sw.toString() ;

38

DB2 Java Stored Procedures: Learning by Example

if (dbg) } } // query_oi_summ }

pwx.close();

3.6.2 SQLJ enhanced sample


Below is the SQLJ version of the Query_oi_summ stored procedure.
//////////////////////////////////////////////////////////// // SQLJ Stored Procedure Query_oi_summ // // This stored procedure demonstrates: // 1) Handling null input fields. // 2) Generating interim values // into an interim results table which is returned // as a ResultSet to the client. // 3) Debugging by writing to a local file. // 4) Handling nulls returned from a query. // 5) Using both named and positional iterators. ///////////////////////////////////////////////////////////// package ACMESNE ; import import import import import import import java.sql.*; sqlj.runtime.*; sqlj.runtime.ref.*; java.math.*; java.io.*; java.text.*; java.util.Date;

////////////////////////////////////////// // iter1 is a named iterator // iter2 is a positional iterator ////////////////////////////////////////// #sql iterator Defined_iter1 (int Total_Qty , int Product_no , String Description); #sql iterator Defined_iter2 (String, int, int, int); public class Query_oi_summ { public static void query_oi_summ ( String in_cust_no, String in_order_no,

Chapter 3. Java sample application: the ACME software company

39

) { PrintWriter pwx = null; final boolean dbg = false; String all_errs; try { Defined_iter1 iter1 = null; //////////////////////////////////////////////////////// // establish debugging file: name is timestamped //////////////////////////////////////////////////////// Date debugDate = new Date(); DateFormat dateFormat = DateFormat.getDateTimeInstance(); ((SimpleDateFormat)dateFormat).applyPattern("MM_dd_HH_mm_ss"); String debugdf = dateFormat.format(debugDate); if (dbg) { pwx = new PrintWriter( new FileWriter("/tmp/" + debugdf + ".txt"),true ); } if (dbg) pwx.println("Query_oi_summ: SQLJ version"); //////////////////////////////////////////////////////// // mark_error_text and mark are used to report // errors trapped in the catch block //////////////////////////////////////////////////////// mark_error_text[0] = "OK"; //////////////////////////////////////////////////////// // query based either upon the input customer number // or the input order number //////////////////////////////////////////////////////// if (null != in_cust_no) { int int_in_cust_no = Integer.parseInt(in_cust_no.trim()); if (dbg) pwx.println("Query_oi_summ: in_cust_no not null, =" + in_cust_no); #sql iter1 = { select sum(OI.ORD_ITEM_QTY) Total_Qty , OI.ord_item_prod_no Product_no, P.prod_desc Description from acmee.order_item OI, acmee.product P,

String[] mark, String[] mark_error_text, ResultSet[] out_rs throws SQLException, Exception

40

DB2 Java Stored Procedures: Learning by Example

acmee.order O, acmee.customer C where OI.ord_item_prod_no = P.prod_no and OI.ord_item_ord_no = O.ord_no and O.ord_cust_no = C.cust_no and C.cust_no = :int_in_cust_no group by OI.ord_item_prod_no, P.prod_desc order by OI.ord_item_prod_no }; // #sql } else { int int_in_order_no = Integer.parseInt(in_order_no.trim()); if (dbg) pwx.println("Query_oi_summ: in_order_no not null, =" +in_order_no); #sql iter1 = { select sum(OI.ORD_ITEM_QTY) Total_Qty , OI.ord_item_prod_no Product_no, P.prod_desc Description from acmee.order_item OI, acmee.product P where OI.ord_item_prod_no = P.prod_no and OI.ord_item_ord_no = :int_in_order_no group by OI.ord_item_prod_no, P.prod_desc order by OI.ord_item_prod_no }; // #sql } // else //////////////////////////////////////////////////////// // walk thru the iterator, using the returned values // to insert to the correct category in the // summary table //////////////////////////////////////////////////////// if (dbg) pwx.println("Query_oi_summ: post selects"); if (null == iter1) { mark_error_text[0] = "Query_oi_summ: query failed"; if (dbg) pwx.println("Query_oi_summ:" + mark_error_text[0]); } else { while (iter1.next()) { if (dbg) pwx.println("iter1=" + iter1.Total_Qty() + "," +

Chapter 3. Java sample application: the ACME software company

41

iter1.Product_no() + "," + iter1.Description()); String five_or_below = " "; String six_to_ten = " "; String eleven_and_above = " "; if (dbg) pwx.println("about to get total variable"); int total = iter1.Total_Qty(); if (total < 6) five_or_below = "X"; else if (total < 11) six_to_ten = "X"; else eleven_and_above = "X"; if (dbg) pwx.println("just set X marks");

String ins_prod_desc = ""; String ret_prod_desc = iter1.Description(); ins_prod_desc = ret_prod_desc ; ////////////////////////////////////////////////////////////// // finally have all the calculated pieces to build the // full insert statement and execute it ////////////////////////////////////////////////////////////// if (dbg) pwx.println("about to insert to ois with " + "/" + ins_prod_desc + "/" + five_or_below + "/" + six_to_ten + "/" + eleven_and_above + "/" ); #sql { insert into acmee.order_item_summ (prod_desc, qty_1_to_5, QTY_6_TO_10, QTY_11_PLUS) values (:ins_prod_desc, :five_or_below , :six_to_ten , :eleven_and_above) }; // #sql } // while } // else iter1.close(); //////////////////////////////////////////////////////// // get the summarized information into an Iterator // to return to the client //////////////////////////////////////////////////////// if (dbg) pwx.println("Query_oi_summ: about to do iter2"); Defined_iter2 iter2; #sql iter2 = { select prod_desc, qty_1_to_5, QTY_6_TO_10, QTY_11_PLUS

42

DB2 Java Stored Procedures: Learning by Example

from acmee.order_item_summ }; // #sql out_rs[0] = iter2.getResultSet(); //////////////////////////////////////////////////////// // walk thru iterator here -- data will not be available // in client (according to design) after viewing here //////////////////////////////////////////////////////// if (dbg) { ResultSet tmp_rs = iter2.getResultSet(); if (dbg) pwx.println("Query_oi_summ: tmp_rs has data"); ResultSetMetaData stmtInfo = tmp_rs.getMetaData(); int numOfColumns = stmtInfo.getColumnCount(); //////////////////////////////////////// // print column labels //////////////////////////////////////// for( int i=1; i <= numOfColumns; i++ ) { if (dbg) pwx.print(stmtInfo.getColumnLabel(i)); if( i != numOfColumns ) { if (dbg) pwx.print(" , "); } } if (dbg) pwx.println(""); //////////////////////////////////////// // print data in table //////////////////////////////////////// while( tmp_rs.next() ) { for( int i=1; i <= numOfColumns; i++ ) { String tmp_get_desc = tmp_rs.getString(i); if (tmp_rs.wasNull()) { if (dbg) pwx.print("Null Description } else { if (dbg) pwx.print(tmp_get_desc); } if( i != numOfColumns ) { if (dbg) pwx.print(" , "); } } //for

");

Chapter 3. Java sample application: the ACME software company

43

if (dbg) pwx.println(""); } // while } // else if (dbg) //iter2.close(); if (dbg) pwx.println("Query_oi_summ: graceful end"); if (dbg) pwx.close(); } // try catch (IOException e) { all_errs = "Query_oi_summ: IOException: " + e.getMessage(); StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); all_errs += ":printStackTrace=" + sw.toString() ; if (dbg) pwx.println(all_errs); if (dbg) pwx.close(); mark_error_text[0] = all_errs.substring(0,199); } catch (SQLException e) { all_errs = "Query_oi_summ: " + "SQLException raised, SQLState = " + e.getSQLState() + " SQLCODE = " + e.getErrorCode() + " :" + e.getMessage(); StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); all_errs += ":printStackTrace=" + sw.toString() ; if (dbg) pwx.println(all_errs); if (dbg) pwx.close(); mark_error_text[0] = all_errs.substring(0,199); } catch (Exception e) { all_errs = "Query_oi_summ: Exception: " + e.getMessage(); StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); all_errs += ":printStackTrace=" + sw.toString() ; if (dbg) pwx.println(all_errs); if (dbg) pwx.close(); mark_error_text[0] = all_errs.substring(0,199); } } // query_oi_summ }

44

DB2 Java Stored Procedures: Learning by Example

3.7 Sample Client Code


The sections that follow provide some sample code for invoking the stored procedures we have listed above. The URL and the driver name may need to change depending upon the platform upon which the client runs (see 8.1.3, Porting between UNIX/NT and S/390 on page 161).

3.7.1 Calling the Java stored procedure from Java


Below is a Java client application calling the Java stored procedure Add_Customer using JDBC.
Platform differences

This sample ran on NT. A UNIX version would require no change. An OS/390 version requires changes to the driver name and to the URL. If the stored procedure is to be run under Version 5 of DB2 for OS/390, the source code would need to be modified where the schema name is used, because schemas were not a valid construct in Version 5.

import java.sql.*; ////////////////////////////////////////////////////////////////////////// / // jscall_Add_customer // // Simple Java application that calls the Add_customer stored procedure. // UNIX and NT version. // // example: java jscall_Add_customer ACMEJNS lastname firstname address ////////////////////////////////////////////////////////////////////////// / class jscall_Add_customer { static { try { Class.forName("COM.ibm.db2.jdbc.app.DB2Driver"); } catch (Exception e)

Chapter 3. Java sample application: the ACME software company

45

{ System.out.println("\nError loading DB2 Driver...\n"); e.printStackTrace(); } } // static public static void main(String argv[]) { Connection con = null; String url; String procName = ""; CallableStatement callStmt; try { if (argv.length < 4) { String usage_stmt = "Usage: java jscall_Add_customer schema lastname firstname address"; System.out.println(usage_stmt); System.exit(0); } // argv.length /////////////////////////////////////// // connect /////////////////////////////////////// System.out.println("Trying to connect..."); url = "jdbc:db2:ACMES"; con = DriverManager.getConnection(url); con.setAutoCommit(false); ///////////////////////////////////////////////// // prepare the call to the stored procedure ///////////////////////////////////////////////// System.out.println("Preparing call..."); procName = argv[0] + ".Add_customer"; String sql = "CALL " + procName + "(?,?,?,?,?,?)"; callStmt = con.prepareCall(sql); /////////////////////////////////////// // register the output parameters /////////////////////////////////////// System.out.println("Preparing parms..."); callStmt.registerOutParameter (4, Types.INTEGER); // cust nbr callStmt.registerOutParameter (5, Types.CHAR); // mark callStmt.registerOutParameter (6, Types.CHAR); // mark_error_text ///////////////////////////////////////

46

DB2 Java Stored Procedures: Learning by Example

// set input parameters /////////////////////////////////////// callStmt.setString (1, argv[1]); // lastname callStmt.setString (2, argv[2]); // firstname callStmt.setString (3, argv[3]); // address /////////////////////////////////////// // call the stored procedure /////////////////////////////////////// System.out.println ("\nCall stored procedure named " + procName); callStmt.execute(); /////////////////////////////////////// // retrieve output parameters /////////////////////////////////////// int returned_cust_no = callStmt.getInt(4); String returned_mark = callStmt.getString(5); String returned_mark_error_text = callStmt.getString(6); //////////////////////////////////////// // report results and commit or rollback //////////////////////////////////////// if (returned_mark_error_text.trim().equals("OK")) { System.out.println ("returned_cust_no: " + returned_cust_no ); con.commit(); } else { System.out.println ("returned_mark: " + returned_mark ); System.out.println ("returned_mark_error_text:" + returned_mark_error_text.trim() ); con.rollback(); } /////////////////////////////////////// // tidy up /////////////////////////////////////// callStmt.close (); con.close (); } // try catch (Exception e) { System.out.println ("catch Exception being executed" ); try { con.close(); } catch (Exception x) { }

Chapter 3. Java sample application: the ACME software company

47

e.printStackTrace (); } // catch } // main }

3.7.2 COBOL client application sample


Below is the OS/390 COBOL client application calling the Java stored procedure Add_customer :
Platform differences

Note that the call is to CS_Add_Customer. This version was written for OS/390 DB2 Version 5 which does not support schemas. This client source code could be modified to take advantage of schemas in a Version 6 system. See 3.3.1, DB2 naming conventions on page 23 for more details.

IDENTIFICATION DIVISION. PROGRAM-ID. "CSCALLAC". ***************************************************** * * * ACME Software Company - Driver for proc ADDCUST * * * * This program calls the Add_customer stored * * procedure (COBOL version). * * * * The file PREPCALL contains the preparation JCL * * for this program. * * * ***************************************************** ENVIRONMENT DIVISION. DATA DIVISION. WORKING-STORAGE SECTION. EXEC SQL INCLUDE SQLCA END-EXEC. * PARM TO RECEIVE THE SQLCODE ERROR MESSAGES 01 ERROR-MESSAGE. 02 ERROR-LEN PIC S9(4) COMP VALUE +960. 02 ERROR-TEXT PIC X(120) OCCURS 8 TIMES INDEXED BY ERROR-INDEX. 77 ERROR-TEXT-LEN PIC S9(8) COMP VALUE +120.

48

DB2 Java Stored Procedures: Learning by Example

77 77 77 01 01 01 01 01 01 01

ERR-CODE ERR-MINUS LINE-EXEC CUST-FNAME CUST-LNAME CUST-ADDRESS CUST-NO MARK MARK-ERROR-TEXT INDARRAY. 05 INDVAR1 05 INDVAR2 05 INDVAR3 05 INDVAR4 05 INDVAR5 05 INDVAR6

PIC 9(8) PIC X PIC X(20) PIC PIC PIC PIC PIC PIC PIC PIC PIC PIC PIC PIC

VALUE 0. VALUE SPACE. VALUE SPACE.

X(20). X(20). X(30). S9(9) COMP. X(80). X(240). COMP. COMP. COMP. COMP. COMP. COMP.

S9(4) S9(4) S9(4) S9(4) S9(4) S9(4)

* ***************************************************** * Procedure Division * ***************************************************** * PROCEDURE DIVISION. DISPLAY "PROGRAM CSCALLAC STARTED" MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE MOVE 0 TO INDVAR1. 0 TO INDVAR2. 0 TO INDVAR3. 0 TO INDVAR4. 0 TO INDVAR5. 0 TO INDVAR6. "JOHN" TO CUST-FNAME. "SMITH" TO CUST-LNAME. "FROM VERSION ACMECOS" TO CUST-ADDRESS. 0 TO CUST-NO. SPACES TO MARK. SPACES TO MARK-ERROR-TEXT.

EXEC SQL CALL CS_ADD_CUSTOMER (:CUST-FNAME:INDVAR1, :CUST-LNAME:INDVAR2, :CUST-ADDRESS:INDVAR3, :CUST-NO:INDVAR4, :MARK:INDVAR5, :MARK-ERROR-TEXT:INDVAR6) END-EXEC.

Chapter 3. Java sample application: the ACME software company

49

MOVE SQLCODE TO ERR-CODE . IF SQLCODE < 0 THEN MOVE '-' TO ERR-MINUS PERFORM SQL-ERROR THRU END-SQL-ERROR. DISPLAY "SQLCODE FROM CALL = " ERR-MINUS ERR-CODE. DISPLAY "RETURN VALUES: " DISPLAY "Customer no: " Cust-no. DISPLAY "CALL RESULT 1: " MARK. DISPLAY "CALL RESULT 2: " MARK-ERROR-TEXT. EXIT-PROG. GOBACK. SQL-ERROR. CALL 'DSNTIAR' USING SQLCA ERROR-MESSAGE ERROR-TEXT-LEN. IF RETURN-CODE = ZERO PERFORM ERROR-PRINT VARYING ERROR-INDEX FROM 1 BY 1 UNTIL ERROR-INDEX GREATER THAN 8 ELSE DISPLAY "BAD RETURN CODE FROM DSNTIAR:" RETURN-CODE. END-SQL-ERROR. ERROR-PRINT. DISPLAY ERROR-TEXT (ERROR-INDEX).

3.7.3 SQLJ client application sample


Below is the SQLJ client application invoking the Add_customer stored procedure.
import java.sql.*; import sqlj.runtime.ref.*; /////////////////////////////////// // call Add_customer as sqlj ////////////////////////////////// #sql context SACCTX; class sscall_Add_customer { static { try

50

DB2 Java Stored Procedures: Learning by Example

{ System.out.println(" sscall_Add_customer"); Class.forName("COM.ibm.db2.jdbc.app.DB2Driver"); } catch (Exception e) { System.out.println("\nError loading DB2 Driver...\n"); e.printStackTrace(); } } // static public static void main(String argv[]) { String url; String procName = ""; try { if (argv.length != 3) { System.out.println("Usage: " + "java call_Add_customer lastname firstname address"); System.exit(0); } // argv.length /////////////////////////////////////// // connect /////////////////////////////////////// url = "jdbc:db2:ACMES"; Connection con = DriverManager.getConnection(url); con.setAutoCommit(false); SACCTX myconn = new SACCTX (con); SACCTX.setDefaultContext(myconn); String lastname = argv[0]; String firstname = argv[1]; String address = argv[2]; if (address.equalsIgnoreCase("null")) { System.out.println("setting address to null"); address = null; } int cust_no = 0; String returned_mark = "OK"; String returned_mark_error_text = "OK"; #sql[myconn]{ CALL ACMEJNS.Add_customer

Chapter 3. Java sample application: the ACME software company

51

(:IN lastname,:IN firstname,:IN address,:OUT cust_no, :OUT returned_mark,:OUT returned_mark_error_text)}; //////////////////////////////////////// // report results and commit or rollback //////////////////////////////////////// if (returned_mark_error_text.trim().equals("OK")) { System.out.println ("returned cust_no =" + cust_no); con.commit(); } else { System.out.println ("returned_mark: " + returned_mark ); System.out.println ("returned_mark_error_text:" + returned_mark_error_text.trim() ); con.rollback(); } /////////////////////////////////////// // tidy up /////////////////////////////////////// con.close (); } // try catch (Exception e) { System.out.println ("catch Exception being executed" e.printStackTrace (); } // catch } // main }

);

3.7.4 JDBC client application sample


Below is a JDBC client application invoking the Query_oi_summ stored procedure.
import java.sql.*; /////////////////////////////////////////////////////////////////////// // call the Query_oi_summ stored procedure // which summarizes qty of purchases into buckets // and displays the ResultSet /////////////////////////////////////////////////////////////////////// class jecall_Query_oi_summ {

52

DB2 Java Stored Procedures: Learning by Example

static { try { System.out.println("test Query_oi_summ"); Class.forName("COM.ibm.db2.jdbc.app.DB2Driver"); } catch (Exception e) { System.out.println("\nError loading DB2 Driver...\n"); e.printStackTrace(); } } // static public static void main(String argv[]) { Connection con = null; String url; String procName = ""; CallableStatement callStmt; if (argv.length != 3) { System.out.println("\nUsage: "); System.out.println(" java call_Query_oi_summ schema cust# order#"); System.out.println(" where one of them equals the string null"); System.out.println(" and the other a number. Example:"); System.out.println(" java call_Query_oi_summ ACMESUE 1 null"); System.exit(0); } // argv.length /////////////////////////////////////// // connect /////////////////////////////////////// try { System.out.println("Trying to connect..."); url = "jdbc:db2:ACMEE"; con = DriverManager.getConnection(url); con.setAutoCommit(false); ///////////////////////////////////////////////// // prepare the call to the stored procedure ///////////////////////////////////////////////// System.out.println("Preparing call..."); procName = argv[0] + ".Query_oi_summ"; String sql = "CALL " + procName + "(?,?,?,?)";

Chapter 3. Java sample application: the ACME software company

53

callStmt = con.prepareCall(sql); /////////////////////////////////////// // register the output parameters /////////////////////////////////////// System.out.println("Preparing parms..."); callStmt.registerOutParameter (3, Types.CHAR); // mark callStmt.registerOutParameter (4, Types.CHAR); // mark_error_text /////////////////////////////////////// // set input parameters /////////////////////////////////////// if (argv[1].equalsIgnoreCase("null")) callStmt.setNull (1, Types.CHAR); // null cust no else callStmt.setString (1, argv[1].trim()); // cust no if (argv[2].equalsIgnoreCase("null")) callStmt.setNull (2, Types.CHAR); // null order no else callStmt.setString (2, argv[2].trim()); // order no

/////////////////////////////////////// // call the stored procedure /////////////////////////////////////// System.out.println ("\nCall stored procedure named " + procName); callStmt.execute(); /////////////////////////////////////// // retrieve output parameters /////////////////////////////////////// String returned_mark = callStmt.getString(3); String returned_mark_error_text = callStmt.getString(4); //////////////////////////////////////// // report results and commit or rollback //////////////////////////////////////// if (returned_mark_error_text.trim().equals("OK")) { System.out.println ("returned OK" ); ResultSet rs = callStmt.getResultSet(); if (null == rs) { System.out.println("Oh oh, rs was null"); System.exit(1); }

54

DB2 Java Stored Procedures: Learning by Example

ResultSetMetaData stmtInfo = rs.getMetaData(); if (null == stmtInfo) System.out.println("Oh oh, stmtInfo was null"); int numOfColumns = stmtInfo.getColumnCount(); //////////////////////////////////////// // print column labels //////////////////////////////////////// for( int i=1; i <= numOfColumns; i++ ) { System.out.print(stmtInfo.getColumnLabel(i)); if( i != numOfColumns ) System.out.print(" , "); } System.out.println(""); //////////////////////////////////////// // print data in table //////////////////////////////////////// while( rs.next() ) { for( int i=1; i <= numOfColumns; i++ ) { String get_desc = rs.getString(i); if (rs.wasNull()) System.out.print("Null Description "); else System.out.print(get_desc); if( i != numOfColumns ) System.out.print(" , "); } System.out.println(""); } con.commit(); } else { System.out.println ("returned_mark: " + returned_mark ); System.out.println ("returned_mark_error_text:" + returned_mark_error_text.trim() ); con.rollback(); } /////////////////////////////////////// // tidy up /////////////////////////////////////// callStmt.close (); con.close ();

Chapter 3. Java sample application: the ACME software company

55

} // try catch (Exception e) { System.out.println ("catch Exception being executed" e.printStackTrace (); } // catch } // main } // class

);

56

DB2 Java Stored Procedures: Learning by Example

Chapter 4. System setup


This chapter details the prerequisites for the deployment of Java stored procedures on the major application platforms, together with an overview of the steps necessary to enable this support, and some of the common problems you may encounter.

4.1 OS/390 system setup


In this section we summarize the requirements to run a compiled Java stored procedure in an OS/390 environment. As mentioned before, at the first delivery of Java stored procedures on OS/390, DB2 provides support only for compiled Java stored procedures. In the following sections we cover the prerequisite code levels, install tasks, design library structure, setting up the Recoverable Resource Manager Services (RRS) attachment facility and the OS/390 Workload Manager (WLM) environment. The compilation of Java stored procedures into native OS/390 instructions is done using the VisualAge for Java Enterprise Toolkit for OS/390 (ET/390) through the use of the High Performance Java Compiler (HPJ) component of the ET/390. We document how to install HPJ JDBC/SQLJ drivers, setting up the JAVAENV data set, and verifying the contents of the JDBC cursors and SQLJ properties files. In addition, we discuss some common setup issues.

4.1.1 Prerequisites
To be able to use Java stored procedures on the S/390 platform, the following prerequisites exist: OS/390 V2 R6 or above, with UNIX Systems Services (USS) enabled. Java for OS/3901 , implementing JDK 1.1.8 (a non-priced OS/390 feature that can be downloaded from the Web or ordered directly from IBM).

It is possible to remove this prerequisite, provided you perform application development and some of your program preparation steps on another platform. However, we assume in this book that if you are developing stored procedures for the OS/390 platform, you will want to develop and prepare them there as well.

Copyright IBM Corp. 2000

57

DB2 UDB for OS/390 Version 5 and above. For Version 5 and 6 with JDBC, SQLJ and Java stored procedure support are enabled, as shown in Table 5.
Table 5. DB2 for OS/390 Java APAR enhancements

Version
Version 5

Feature

APAR / PTF
PQ36643/UQ43898

JDBC and SQLJ driver including support for Visual Age Java'
Java Stored Procedures

PQ31845/ UQ46170 PQ31845/UQ46171 PQ36644/UQ43899

Version 6

JDBC and SQLJ driver including support for Visual Age Java'
Java Stored Procedures

PQ31846/ UQ46114 PQ31846/UQ46115

The prerequisites for VisuaAge for Java Enterprise Edition for OS/390 are in Table 6.
Table 6. VisualAge for Java Enterprise Edition for OS/390

Version
Version 2.0

Feature
VisualAge for Java, Enterprise Edition for OS/390

APAR / PTF
APAR PQ38178/ UQ43439 Rel. 2.01 APAR PQ38179/UQ43443 Rel. 2.02

Use Of Type 2 Drivers

Implementation of SQLJ support for both Version 5 and Version 6 will result in JDBC Type 2 drivers being installed. For the OS/390 platform and Java stored procedure support, the Type 2 drivers must be made available. This is done when you apply the APAR PQ36644. You can only support one JDBC driver at a time in OS/390, so the JDBC Type 1 driver will not exist in your system anymore! The Enterprise Toolkit for OS/390, part of VisualAge for Java, Enterprise Edition. This product provides the HPJ compiler needed for Java stored procedures on the OS/390 platform. OS/390 Recoverable Resource Services (RRS) and Workload Manager (WLM) Java stored procedures can only be run in a WLM-established stored procedure address space, so implementation of OS/390 Recoverable Resource Services (RRS) is necessary.

58

DB2 Java Stored Procedures: Learning by Example

We recommend that you apply the USS APAR OW41492, which significantly improves performance of the multi-context support in the Type 2 driver.

4.1.2 Installation tasks


To prepare your OS/390 environment to execute Java stored procedures, you should perform the following tasks. It is assumed that all of the products and services listed in the previous section on prerequisites have been installed and properly configured.
JDBC Support

Part of the install process for JDBC support involves running the db2genJDBC utility, which creates 4 generic DBRMs for use by JDBC programs (and JDBC stored procedures). We recommend that you bind these 4 DBRMs into DB2 packages belonging to a suitably named collection (we used DSNJDBC). This makes it simpler to ensure that these DB2 packages are picked up at execution time, as described in 9.1, DB2 plans and packages on page 167). 1. Design your library structure and naming standards. Java stored procedure support requires libraries to be set up both within the USS and the native OS/390 environment, and your job will be made much easier if you decide upon these in advance. 2. Tailor the .profile script for the stored procedure developers, to ensure that the necessary USS environment variables are being defined. 3. Set up the RRS environment for support of WLM-established stored procedures (if you have not already done so). 4. Set up a new WLM application environment for Java stored procedures, and the associated address space JCL.
WLM environments

While it is not strictly necessary for you to do so, we strongly advise you to set up at least one separate WLM application environment and JCL procedure to handle your Java stored procedures. 5. Create high performance Java versions of the JDBC/SQLJ drivers.

Chapter 4. System setup

59

6. Set up the JAVAENV data set, and add an associated DD card to the WLM stored procedure address space JCL. JAVAENV contains the USS environmental variables (such as CLASSPATH and LIBPATH) that will be allocated within the WLM stored procedure address space. 7. Tailor the contents of the SQLJ properties file and cursors file, to ensure that correct values are being set. These tasks are described in more detail in the sections that follow.

4.1.3 Step 1: Design library structure


Java stored procedure support requires a fairly complex network of libraries to be set up both within the USS and the native OS/390 environment, and your job will be made much easier if you decide upon these libraries in advance. It is recommended that you set up one hierarchical file system (HFS) per DB2 subsystem or data sharing group. Table 7 provides a summary of the USS libraries required, together with the settings we used in our environment.
Table 7. Sample USS library structure

Type
USS

Description

Sample Name
/USR/LPP/HPJ/LIB

HPJ base libraries. Contains all HPJ libraries (installed as part of ET/390 see 4.1.1, Prerequisites on page 57).
Must be in included in CLASSPATH environment variable of the Java SP environment data set (see Figure 8 on page 70).

SQLJ/JDBC base libraries. Contains all SQLJ and JDBC classes, libraries and binaries. Delivered as part of base SQLJ/JDBC support (installed as part of SQLJ support see 4.1.1, Prerequisites on page 57).
The LIB directory must be in included in LIBPATH environment variables of the Java SP environment data set (see Figure 8 on page 70).

/USR/LPP/DB2/DB2nnn/CLASSES /USR/LPP/DB2/DB2nnn/BIN /USR/LPP/DB2/DB2nnn/LIB where nnn is release level (510, 610, and so on). See set environmental variables for SQLJ/JDBC on Page 65, and include the HPJ and SQLJ
libraries in the environmental variables

on Page 65.

60

DB2 Java Stored Procedures: Learning by Example

Type

Description

Sample Name
/u/ssss/links/ where ssss is the DB2 subsystem ID or data sharing group attached name.

Links directory. Contains all USS links to PDSE load libraries that contain compiled Java routines.
Must be in included in LIBPATH environment variable of the Java SP environment data set (see Figure 8 on page 70). Must be the HOME path for the Java SP procedure owner (see Figure 7 on page 66). The SQLJ properties file: db2sqljjdbc.properties and the cursor definitions file db2jdbc.cursors must also be installed in this directory. The SQLJ properties file must be referenced by the DB2SQLJPROPERTIES environment variable (see define where the SQLJ run-time properties file is located on Page 64).

Serialized profiles directory. Contains all of the serialized profiles generated by the sqlj precompiler (used as input to db2profc, the profile customizes).
The JDBC serialized profile: DSNJDBC_JDBCProfile.ser, should be moved in this directory. Must be included in the CLASSPATH environment variable of the Java SP environment data set (see Figure 8 on page 70).

/u/ssss/ser/ where ssss is the DB2 subsystem ID.

Chapter 4. System setup

61

Table 8 provides a summary of the OS/390 libraries required, together with the settings we used in our environment.
Table 8. Sample OS/390 library structure

Type
OS/390

Description

Sample Name
Site specific. One library per subsystem recommended. Site specific. One library per subsystem/testing level recommended. Site specific. One library per WLM environment recommended.

SQLJ load library. Contains HPJ compiled versions of JDBC/SQLJ classes. See Figure 4. Application load library. Contains HPJ compiled versions of Java stored procedure code. See Figure 5.
JAVAENV data set. Contains settings for Java environment variables used within the stored procedures address space. See Figure 6.

DBRM library. Contains DBRMs generated by db2profc step for SQLJ procedures. See DB2SQLJDBRMLIB parameter in Figure 9 on page 72.

Site specific. One library per subsystem/testing level recommended.

The SQLJ load library must be defined as a PDSE library. Figure 4 shows an example of this data set definition:

Data Set Name . . . : HPJ.SDSNJDBC.DBZ2 General Data Management class . . : **None** Storage class . . . : **None** Volume serial . . . : TOTDB1 Device type . . . . : 3380 Data class . . . . . : **None** Organization . . . : PO Record format . . . : U Record length . . . : 0 Block size . . . . : 24760 1st extent tracks . : 5 Secondary tracks . : 5 Data set name type : LIBRARY

Figure 4. SQLJ load library data set definition

The application load library must be defined as a PDSE library. Figure 5 shows an example of this data set definition.

62

DB2 Java Stored Procedures: Learning by Example

Data Set Name . . . : USER.HPJSP.PDSE.DBZ2 General Data Management class . . : **None** Storage class . . . : **None** Volume serial . . . : TOTDB1 Device type . . . . : 3380 Data class . . . . . : **None** Organization . . . : PO Record format . . . : U Record length . . . : 0 Block size . . . . : 24760 1st extent tracks . : 5 Secondary tracks . : 5 Data set name type : LIBRARY

Figure 5. Application load library data set definition

The JAVAENV data set must be defined as a variable blocked sequential data set, as in Figure 6 below:

Data Set Name . . General Data Volume serial . . Device type . . . Organization . . Record format . . Record length . . Block size . . . 1st extent tracks Secondary tracks

. : HPJ.JAVAENV . . . . . . . . : : : : : : : : TOTTSY 3390 PS VB 255 4096 2 2

Figure 6. JAVAENV file data set definition

4.1.4 Step 2: Provide .profile for users


Use of HPJ, SQLJ and JDBC requires some environmental variables to be set. By creating a standard .profile script that is automatically executed by developers as they login to USS, you can ensure that these variables are being set to their correct values.

Chapter 4. System setup

63

Use of .profile scripts

In the UNIX world it is standard practice to establish a .profile script for every USS user. It is equivalent to the ISPF logon proc, in that it establishes the initial environment for the user. Some shops may wish to create a centralized script that establishes the basic DB2 environment. Each users .profile would then execute that centralized script within their .profile. If a centralized script is used, be sure to dot the command within the .profile. For example, if the centralized script is called /usr/apps/db2/db25/profile, then each .profile script would execute it using the following command.....notice the period followed by a space followed by the script.....this executes the script within the current process instead of forking a separate process:
. /usr/apps/db2/db25/profile

Here is a example of the .profile used for our sample users. (We did not use a centralized script).
#---------------------------------------------------------------------# Profile for the common EC environment to compile SQLJ and JDBC code #---------------------------------------------------------------------echo off cls I=0 while test $I = 0 do echo "5 For DB21 V5 properties file" echo "6 For DBZ2 V6 properties file" echo "enter number for DB2 properties file" read DBPROP case $DBPROP in 5) I=1 export SSID=DB21 export SSIDHFS=db2510 SSIDLIB=DB2V510;; 6) I=1 export SSID=DBZ2 export SSIDHFS=db2610 SSIDLIB=DSN610;; *) echo "Huh? Did not enter 5 or 6 entered > $DBPROP";; esac done echo "SSID = $SSID SSIDHFS = $SSIDLIB SSIDLIB = $SSIDHFS" #-----------------------------------------------------# define where the SQLJ run-time properties file is located #-----------------------------------------------------export DB2SQLJPROPERTIES=/u/$SSID/links/db2sqljjdbc.properties ##### Added for tso -t from telnet

64

DB2 Java Stored Procedures: Learning by Example

# Assign the DD names to allocate # export TSOALLOC=sysexec # # Allocate the OpenMVS EXEC data set to SYSEXEC # export sysexec=SYS1.OS390.EXEC #end# Added for tso -t from telnet #-----------------------------------------------------# set environmental variables for HPJ #-----------------------------------------------------export IBMHPJ_HOME="/usr/lpp/hpj" export IBMHPJ_RTL="CEE.SCEELKED:CEE.SCEELKEX:CEE.SCEEOBJ:CEE.SCEECPP" #-----------------------------------------------------# set environmental variables for DSNAOINI data set #-----------------------------------------------------export DSNAOINI=DB2V610.$SSID.DSNAOINI #-----------------------------------------------------# set environmental variables for SQLJ/JDBC #-----------------------------------------------------export SQLJ_HOME=/usr/lpp/db2/$SSIDHFS export JDBC_HOME=/usr/lpp/db2/$SSIDHFS # # Java_HOME is where the current JDK is installed #export Java_HOME=/usr/lpp/Java/J1.1 # Java_COMPILER is used to turn the JIT OFF export Java_COMPILER= # Tell make and others we are NOT using Optimized versions unset SQLJ_OPTIMIZED #-----------------------------------------------------# include the HPJ and SQLJ libraries in the environmental variables #-----------------------------------------------------export CLASSPATH=.:$JDBC_HOME/classes/db2sqljclasses.zip:\ $Java_HOME/lib/classes.zip:\ $SQLJ_HOME/classes/db2sqljruntime.zip:\ $SQLJ_HOME/classes/db2jdbcclasses.zip:\ /u/$SSID/links:\ /u/$SSID/ser:\ $Java_HOME/lib:$IBMHPJ_HOME/lib export PATH=$PATH:$SQLJ_HOME/bin:$IBMHPJ_HOME/bin:$PATH export LIBPATH=$SQLJ_HOME/lib:$JDBC_HOME/lib:\ $Java_HOME/lib/mvs/native_threads:$IBMHPJ_HOME/lib:$LIBPATH # export STEPLIB=$SSIDLIB.sdsnload.test:$STEPLIB ix export STEPLIB=$SSIDLIB.sdsnload:$STEPLIB export STEPLIB=$SSIDLIB.sdsnlink:$STEPLIB export LD_LIBRARY_PATH=.:$SQLJ_HOME/bin:$JDBC_HOME/lib:\

Chapter 4. System setup

65

$Java_HOME/lib/mvs/native_threads #-----------------------------------------------------# print out Java and hpj versions #-----------------------------------------------------Java -version hpJava -version export EDITOR=vi set -o vi echo '*---------------------------------------------------------------' echo ' profile executed for HPJ, Java and SQLJ ' echo '*---------------------------------------------------------------'

4.1.5 Step 3: Setting up RRS


OS/390 Recoverable Resource Services (RRS) is a feature of MVS that coordinates two-phase commit processing of recoverable resources in an MVS system. The RRS attachment is required for stored procedures that run in a WLM-established address space. If you do not have RRS active in your OS/390 system, see Appendix C, OS/390 Recoverable Resource Services (RRS) on page 329.

4.1.6 Step 4: Define WLM stored procedure address space


If you do not have WLM-established stored procedures active, see Appendix D, Define WLM stored procedure address space on page 331. To add Java support to the WLM-established address space you will have to add these two steps. First, assign a RACF STC userid to the procedure; and second, modify the JCL procedure for the Java required files.
4.1.6.1 RACF STC userid Assigning a RACF STC userid to the Java WLM stored procedure address space is required. For Java stored procedures, you will also need to assign a home directory to the environment variable HOME of user ID assign to it. This will be the links directory that contains all USS links to PDSE load libraries that contain compiled Java routines. Figure 7 shows the RACF command that you should use to do this:

alu db2stcZ2 omvs(home(/u/DBZ2/links))


Figure 7. RACF command to assign home directory

Then you create a profile in the STARTED class names DBZ2Java.* for the WLM Java address space, as follows:

66

DB2 Java Stored Procedures: Learning by Example

rdefine started DBZ2Java.* stdata(user(db2stcz2)group(sys1)privileged(no)trace(no)trusted(no))

Finally, since STARTED is a RACLISTed class, you must do a RACF refresh using the following command:
setropts raclist(started) refresh

4.1.6.2 JCL procedure of a Java WLM-established address space Here is an example of a JCL procedure for starting the WLM-established address space with Java support:
//DBZ2Java PROC RGN=0K,APPLENV=WLMJavaDBZ2,DB2SSN=DBZ2, // NUMTCB=1,TME=NOLIMIT //DBZ2Java EXEC PGM=DSNX9WLM,REGION=&RGN,TIME=&TME, // PARM=&DB2SSN,&NUMTCB,&APPLENV //STEPLIB DD DISP=SHR,DSN=DB2V610V.RUNLIB.LOAD // DD DISP=SHR,DSN=SYS1.SCEERUN // DD DISP=SHR,DSN=DSN510.SDSNLOAD // DD DISP=SHR,DSN=USER.HPJSP.PDSE.DBZ2 #1 // DD DISP=SHR,DSN=HPJ.SDSNJDBC.DBZ2 #2 // DD DISP=SHR,DSN=HPJ.SHPJMOD #3 // DD DISP=SHR,DSN=HPJ.SHPOMOD #4 //JAVAENV DD DISP=SHR,DSN=HPJ.JAVAENV.DBZ2 #5 //JSPDEBUG DD SYSOUT=A #6 //DSSPRINT DD SYSOUT=A //UTPRINT DD SYSOUT=A //SYSPRINT DD UNIT=SYSDA,SPACE=(4000,(20,20),,,ROUND) //SYSUDUMP DD SYSOUT=A

This procedure contains the following statements: 1. DD statement for the high performance Java compiled stored procedure PDSE load library. 2. DD statement for the high performance Java JDBC/SQLJ library. 3. DD statement for the high performance Java SHPJMOD library. 4. DD statement for the high performance Java SHPOMOD library. 5. JAVAENV DD statement for the work load managed Java stored procedure runtime environment options. This data set applies to the entire WLM environment, not just individual stored procedures. See 4.1.8, Step 6: Set up the JAVAENV data set on page 69 for more details. JSPDEBUG DD statement for Java stored procedure debug information. This is a critical source of information when debugging Java stored procedures in an S/390 environment (see 6.5, Debugging on page 103)
67

Chapter 4. System setup

4.1.7 Step 5: Install JDBC/SQLJ driver for OS/390


You need to use the Java high performance compiler (HPJ) to compile the JDBC/SQLJ Driver for OS/390 DB2 into an OS/390 executable that can be used within the WLM address space. This is done with the shell script installVAJDLLs, that can be found in /usr/lpp/db2/db2610. Create a subdirectory install in the rood directory /usr/lpp/db2/db2610 and copy the script installVAJDLLs to this directory. Modify this script for your environment. Here are the modifications we made to it. We customized the installation root directory of the JDBC/SQLJ driver installation as follows:
export IBMJDBC_HOME=/usr/lpp/db2/db2610

We modified the PDSE to hold the JDBC/SQLJ driver as follows:


-o "//'HPJ.SDSNJDBC.DBZ2(DSNAQDLL)'" \

We modified the external HFS link to PDSE member DLL to our /u/DBZ2/links directory as follows:
rm -f /u/DBZ2/links/libdb2os390vaj.so ln -e DSNAQDLL /u/DBZ2/links/libdb2os390vaj.so

We modified the build PDSE Java DLL for the output as follows:
-o "//'HPJ.SDSNJDBC.DBZ2(DSNAQJLL)'" \

and the links as follows:


-t /u/DBZ2/links

HPJ Storage Requirements

This step requires a large amount of storage, so when you log onto TSO, make sure you have set the logon region size to 1100000. Failure to do so will result in messages such as:
HPJ3115(S) Unable to fetch module "HPJ3TBY".

After running installVAJDLLs, the directory /u/DBZ2/links will contain the following:
/u/DBZ2/links/

68

DB2 Java Stored Procedures: Learning by Example

COM ibm libdb2os390vaj.so -> DSNAQDLL sqlj sqlj.jll -> DSNAQJLL /u/DBZ2/links/sqlj mesg.jll runtime runtime.jll util /u/DBZ2/links/sqlj/runtime error.jll profile profile.jll ref.jll /u/DBZ2/links/sqlj/runtime/profile ref.jll util.jll /u/DBZ2/links/sqlj/util io.jll

Also, the PDS library HPJ.SDSNJDBC.DBZ2 will contain:


sqlj.jll alias of DSNAQJLL DSNAQDLL DSNAQJLL

Applying maintenance

This step must be repeated when any related maintenance has been applied to the system that effects the JDBC/SQLJ drivers. In addition, there are other considerations that you have to keep in mind; see 4.1.11, Maintenance considerations on page 75.

4.1.8 Step 6: Set up the JAVAENV data set


You need to define a data set to hold the Java environment statements to be used by Java stored procedures running within your WLM established stored procedures address space. Depending upon how you intend to segregate your stored procedure workloads, we recommend that you have a different JAVAENV data set for each WLM application environment. See 4.1.3, Step 1: Design library structure on page 60 for details of the data set attributes for the JAVAENV data set.
4.1.8.1 Data set composition The contents of this data set are described below.

LIBPATH The environment variables point to load libraries.

Chapter 4. System setup

69

SQLJ contains sqlj .so dynamic load libraries. JDBC contains jdbc .so dynamic load libraries. HPJ contains hpj .so dynamic load library. The USS directories containing these libraries must be referenced in the LIBPATH environment variables. See Figure 8 on page 70 on how LIBPATH is used.
CLASSPATH CLASSPATH contains all the directories that contain the required SQLJ and JDBC class files .zip:
CLASSPATH must also point to the directory used to store your SQLJ serialized

profiles and JDBC cursors and SQLJ properties files (see 4.1.9, Step 7: Verify JDBC cursor and SQLJ properties files on page 71). Finally, the location where you will store the external links for your stored procedure modules must also be referenced.
TZ
TZ is used to set the local time zone. It is an optional parameter.

4.1.8.2 Sample contents Figure 8 shows an example of the contents of a JAVAENV data set.

ENVAR("CLASSPATH=.:/usr/lpp/hpj/lib:/u/DBZ2/ser", "LIBPATH=/usr/lpp/hpj/lib:/usr/lpp/db2/db2610/lib:/u/DBZ2/links")
Figure 8. JAVAENV data set contents

Note: This data set is supplied on the CD-ROM in directory SAMPLES\S390 UTILITIES\INSTALLATION\JAVAENV. See Appendix E, Using the additional

material on page 347 for more details.

70

DB2 Java Stored Procedures: Learning by Example

Note:

The current restriction for the total length of the ENVAR variable is 255 characters. You must be careful when structuring your libraries to ensure that this limit is not exceed. No error messages are issued if the limit is exceeded: any characters beyond position 255 will be ignored, which may lead to errors such as failure to load classes.

4.1.9 Step 7: Verify JDBC cursor and SQLJ properties files


The JDBC cursors file and the SQLJ properties file contain critical configuration parameters that will affect your environment. Sample versions of each of these files will be created as part of the base JDBC/SQLJ driver installation process, but they are likely to require some tailoring for your environment.
4.1.9.1 JDBC cursors file The JDBC cursors file contains a definition of the cursors to be used by JDBC programs running within the USS environment.

A sample cursor definition file called db2jdbc.cursors is created as part of the base JDBC/SQLJ installation. This contains 250 cursor definitions (125 cursors WITH HOLD and 125 without). This file can be amended (or an alternative version defined) if you wish to have more cursors available, or to rename the cursors that JDBC will use. Because the cursors file is used as input to the db2genJDBC utility that creates the generic JDBC DBRMs used by all JDBC programs, you need to re-run db2genJDBC after amending the cursors file. Refer to 4.1.11, Maintenance considerations on page 75 for some further actions you should take after doing this.
4.1.9.2 SQLJ properties file The SQLJ run-time properties file contains parameters that specify any program preparation or run-time information that is not in environmental variables. Use the environmental variable DB2SQLJPROPERTIES in your . PROFILE to point to this file. For Example:
export DB2SQLJPROPERTIES=/u/DBZ2/links/db2sqljjdbc.properties

Chapter 4. System setup

71

Using multiple SQLJ properties files

As the SQLJ properties file contains information such as the plan used for all SQLJ/JDBC client programs that execute under USS, you may want to consider defining multiple properties files (for different groups of users, or different applications, for instance) and tailoring your .profile scripts to point to each as necessary. See 9.1.5, Usage recommendations on page 170 for more details. Here is a sample of the contents of an SQLJ properties file. This sample can also be found in file DB2SQLJDBC.PROPERTIES on the CD-ROM in directory SAMPLES\S390 UTILITIES\INSTALLATION\. See Appendix E, Using the additional material on page 347 for more details.

DB2SQLJSSID=DBZ2 #DB2SQLJ_TRACE_FILENAME=/tmp/mytrc #DB2SQLJ_TRACE_BUFFERSIZE=4096 DB2SQLJPLANNAME=SQLJPLAN DB2SQLJATTACHTYPE=RRSAF DB2SQLJJDBCPROGRAM=DSNJDBC DB2SQLJDBRMLIB=SG245945.DBRMLIB.DBZ2


Figure 9. DB2SQLJDBC.PROPERTIES contents

These parameters are discussed in the sections that follow. For a full explanation of these and other parameters, please refer to the Application Programming Guide and Reference for Java, SC26-9018.
DB2SQLJSSID Specifies the name of the DB2 subsystem to which a JDBC or an SQLJ application connects. DB2SQLJPLANNAME Specifies the name of the plan that is associated with JDBC and SQLJ serialized profile. This is used by Java clients that run in the USS environment and JDBC dynamic SQL Java stored procedures programs. DB2SQLJATTACHTYPE Specifies the attachment facility that a JDBC or an SQLJ application program uses to connect to DB2. DB2SQLJJDBCPROGRAM Specifies the name of a JDBC connected profile that is used by SQLJ run-time environment.

72

DB2 Java Stored Procedures: Learning by Example

DB2SQLJDBRMLIB Specifies the fully-qualified name of the OS/390 partition data set into which DBRMs are placed. DBRMs are generated by the creation of a JDBC profile and the customization step of the SQLJ program preparation process.

4.1.10 Data sharing considerations


In a DB2 OS/390 data sharing environment you will have to consider how you define your WLM application environment and set up your USS HFS.
4.1.10.1 WLM application environment When defining you application environment to WLM to run in a data sharing group, use the symbolic parm &IWMSSNM for the DB2SSN parm of your JCL procedure. This will allow you to use one JCL procedure for the application environment for all members of the data sharing group. Example:
Start parameters .. DB2SSN=&IWMSSNM,NUMTCB=2,APPLENV='WLMJavaDBZ2'

4.1.10.2 Data sharing and HFS In a data sharing environment, you are sharing the catalog, directory, and all databases among all members of the group. You will only have one copy of these data sets in the sysplex environment. However, the USS HFS is unique for each member of the sysplex under OS/390 V2 R8.
*** Note ***

With OS/390 V2 R9 and above, there will be shared HFS in a sysplex.

OS/390 V2 R8 will require you to do some special planning on how to set up and use the HFS for each member. You will have to duplicate the HFS directory structure in each member of the sysplex. This will allow you to bring any DB2 member of the group up in any OS/390 sysplex member and to run the Java store procedure in the other members of the group. Using the group name for the higher directory level for the links and user directories will make it easier to duplicate and to migrate to OS/390 V2 R9 and above. This will allow you to use the same HOME path name for the WLM stored procedure address space and the same owner name across the sysplex. The following are steps that you will have to do to duplicate the work done on one sysplex member in each other sysplex member or members that run DB2 members of the data sharing group: Follow Step 1: Design library structure on page 60. Follow Step 2: Provide .profile for users on page 63.

Chapter 4. System setup

73

Follow Step 5: Install JDBC/SQLJ driver for OS/390 on page 68. Follow Step 7: Verify JDBC cursor and SQLJ properties files on page 71. Transmit all of the related Java program class files over to the other sysplex member or members HFS. This is input to the HPJ compiler to create the LINKs. You will need to run the HPJ compiler over on the other sysplex member or members to create the LINKs into the /u/DB2Groupname/links path. This will restrict you to do all of your Java development on only one sysplex member within the sysplex. Figure 10 shows a diagram of a DB2 data sharing group called DBZ1 with two members, DBZ1 and DBZ2. The WLM application environment for the Java stored procedures that run in this group are set up to use a started task procedure named DBZ1JAVA. The RACF owner for this STC is the procedure name DBZ1JAVA with an OMVS Home path set to /u/DBZ1/links. You can see that each OS/390 member in the sysplex has its own OS/390 USS HFS and shares the same OS/390 DASD.

74

DB2 Java Stored Procedures: Learning by Example

MVSPLEX V2 R8
os/390 Shared Dasd
DBZ1 Cat & Directory DBZ1 Tables DBZ1 Logs DBZ1 BSDS HPJ.JAVAENV.DBZ! HPJ.SQLJ.PDSE USER.JAVA.PDSE.DBZ1

DB2 DS Group DBZ1 Members


DBZ1 DBZ2

MVS1
DBZ1MSTR STC DBZ1DBM1 STC DBZ1IRLM STC DBZ1JAVA DBZ1JAVA Home=/u/DBZ1/links

MVS2
DBZ2MSTR STC DBZ2DBM1 STC DBZ2IRLM STC DBZ1JAVA DBZ1JAVA Home=/u/DBZ1/links

OS/390 USS HFS


/u/DBZ1/links /u/DBZ1/ser /u/JAVA/Package /usr/lpp/db2/db2610/classes

OS/390 USS HFS


/u/DBZ1/links /u/DBZ1/ser /u/JAVA/Package /usr/lpp/db2/db2610/classes

Figure 10. DB2 data sharing group with Java stored procedures

4.1.11 Maintenance considerations


From time to time, IBM may issue maintenance for the JDBC drivers requiring the drivers to be prepared again, using the db2genJDBC2 utility supplied for the purpose. If this occurs, you must perform some important follow-up actions once db2genJDBC has been successfully executed: Re-create the high performance Java compiled versions of the JDBC/SQLJ drivers, as described in 4.1.7, Step 5: Install JDBC/SQLJ driver for OS/390 on page 68.
2

The db2genJDBC utility resides in the bin subdirectory of the USS directory where your SQLJ/JDBC support has been located (for example, /usr/lpp/db2/db2610/bin). It is used at the time JDBC is installed, to generate the generic JDBC DBRMs that will be needed by all JDBC stored procedures and clients. See the Application Programming Guide and Reference for Java , SC26-9018 for more details.

Chapter 4. System setup

75

Re-bind all DB2 packages that use the generic JDBC DBRMs (DSNJDBC1, DSNJDBC2, DSNJDBC3 and DSNJDBC4).

4.1.12 Some common setup issues


The paragraphs below cover some of the more common errors that we encountered during the setup process.
4.1.12.1 Out of storage HPJ compile JDBC and SQLJ classes

Symptom:
An out-of-storage error message is issued during HPJ compile:
Class missing for error: Java/lang/OutOfMemoryError

Possible resolution:
Increase TSO region size if logged on via TSO. We recommend a value of 1100000.
4.1.12.2 Unable to load HPJ module during HPJ compile

Symptom:
A message is issued during HPJ compile indicating that an HPJ module cannot be fetched:
HPJ3115(S) Unable to fetch module "HPJ3TBY".

Possible resolution:
Increase TSO region size if logged on via TSO. We recommend a value of 1100000.
4.1.12.3 00E79107 Unable to find user class

Symptom:
The reason code 00E79107 is encountered when attempting to invoke a Java stored procedure.

Additional SQLCA information provided with the message has the name of the class that could not be found.

Possible resolution:

76

DB2 Java Stored Procedures: Learning by Example

Make sure that all classes have been bound into the PDSE data set. Make sure external links are to packages.
4.1.12.4 Unable to find user method

Symptom:
00E79107 or 00E79108 reason code on -471 when calling a complied Java stored procedure. Additional SQLCA information provided with the message has signature provided by SQL types.

Possible resolution:
Make sure the PARAMETERS column maps to JDBC types. Check the Java signature using Javap -s -private <classname> Remember, result sets are in the signature, but not in the PARAMETERS column.
4.1.12.5 CEE5207E The signal SIGABRT was received

Symptom:
This message is printed out in the Java SP address space and the client receives a -965. SQLCODE back.
invoking class: ACMEJOS/Add_customer, method: add_customer Add_customer: start - JDBC version Add_customer: getConnection CEE5207E The signal SIGABRT was received.

Possible resolution:
Either the db2jdbc.cursors or db2sqljjdbc.properties file was not found in the HOME path of the Java stored procedure environment (/u/DBZ2/links). Make sure these two files are included in the HOME PATH.
4.1.12.6 ICH408I USER(uuuu) GROUP(ggggg) NAME(nnnn) 928

Symptom:

Chapter 4. System setup

77

This message is shown on the OS/390 console log. The client application receives a SQLCODE of -965 and the Java stored procedure shows an error loading the JDBC driver.
PROC= DBZ2Java ASID= 0085 WLM_ENV= WLM_Java_DBZ2 DSNX906I =DBZ2 DSNX9CAC PROCEDURE JS_ADD_CUSTOMER 927 TERMINATED ABNORMALLY. THE PROCEDURE HAS BEEN STOPPED. ASID= 0085 WLM_ENV= WLM_Java_DBZ2 ICH408I USER(DB2STC ) GROUP(SYS1 ) NAME(Java DB2 STCS ) 928 /u/DBZ2/links CL(DIRSRCH ) FID(01E3E2D4E2F4F100690C000000000003) INSUFFICIENT AUTHORITY TO LOOKUP ACCESS INTENT(--X) ACCESS ALLOWED(GROUP ---) --TIMINGS (MINS.)--

Possible resolution:
The HFS /u/DBZ2 was not built with the proper permission setting to allow search of directories down from /u/DBZ2. Make sure that the directory is set with 755. To make sure your directories are set at 755, use the UNIX command ls -l to verify that it is set, as follows:
drwxr-xr-x 2 DB2RES3 DBZ2 8192 Mar 16 13:44 aa

Use the chmod command to set the permissions to 755 on directory DBZ2, executing the following UNIX commands: - cd /u - chmod 755 DBZ2 - ls -l

4.2 Windows NT system setup


Establishing Windows NT for Java stored procedures is considerably easier, as compared to the method used for the OS/390 environment.

4.2.1 Prerequisites
Windows NT Version 4 or above A JDK any one of the following will suffice: - The Java Development Kit (JDK) and Java Runtime Environment (JRE) for Win32 (version 1.1.7 or above) from IBM. These are shipped with DB2 for Windows NT. - The Java Development Kit (JDK) Version 1.1 or later for Win32 from Sun Microsystems - Microsoft Software Developer's Kit for Java, Version 3.1.

78

DB2 Java Stored Procedures: Learning by Example

4.2.2 Installation tasks


To prepare your Windows NT environment to execute Java stored procedures, you should perform the following tasks: 1. Install the DB2 UDB SDK for Windows NT. This includes the Java JDK 1.1.8, as well as the necessary DB2 data access drivers and utilities to prepare DB2 Java programs for execution. 2. Ensure that the PATH system variable includes the directory that contains the JDK binaries (usually c:\sqllib\Java\jdk\bin). The PATH system variable can be set from the Environment tab of the Windows NT Control Panel System Properties applet. 3. Update the jdk11_path DBM configuration parameter to point to the location of the JDK you are using (probably c:\SQLLIB\Java\jdk if you are using the IBM JDK supplied with DB2). For example:
db2 update dbm cfg using JDK11_PATH c:\SQLLIB\Java\jdk

A comprehensive set of sample applications is supplied with DB2, and you may want to try running some of these before writing your own code to verify that the environment is properly configured. The samples can be found in the sqllib\samples\Java directory.

4.2.3 Some common setup issues


The paragraphs below cover some of the more common errors encountered during the setup process.
4.2.3.1 Path or file name "Java" not found

Symptom:
The following error message is produced when you try to use any of the DB2 preparation utilities (SQLJ, DB2PROFC, etc.):
Error in sqlj: path or file name "Java" not found.

Possible resolution:
Ensure that Windows NT PATH variable includes the directory that contains the JDK binaries (usually c:\sqllib\Java\jdk\bin). See 4.2.2, Installation tasks on page 79 for more details. Try building a simple Java application at the DOS command level to make sure that Java works. Simple Java examples can be found on Web sites that introduce the language to novice Java programmers.

Chapter 4. System setup

79

4.3 UNIX system setup


As for Windows NT, establishing UNIX for Java stored procedures is considerably easier than for OS/390. We used AIX for our testing. Other UNIX platforms should be similar, but be sure to read the platform-specific documentation.

4.3.1 Prerequisites
For AIX, use JDK 1.1.8 Fixpak 4 or later. For other UNIX variations, obtain the most recent JDK that has been tested by IBM as being compatible. The list of JDKs can be found at:
http://www-4.ibm.com/software/data/db2/Java/index.html

4.3.2 Installation tasks


Install the JDK. On AIX, this must be installed by the system administrator using smit or installp or an equivalent system tool. The JDK may be installed in a location different than the default location. This may be necessary due to multiple applications sharing the same machine requiring different releases of the JDK. Confirm that DB2 uses the JDK you installed. To change the location, use the following command (in this case, setting it to /usr/jdk_base):
db2 update dbm cfg using JDK11_PATH /usr/jdk_base

The userid owning DB2 must establish some environment variables to tell DB2 where the JDBC and SQLJ runtime support can be found. This can be done in the .profile file. This includes the following tasks: Establishing the general DB2 environment variables, typically done by executing the sqllib/db2profile, which is in the directory of the install userid. Setting Java_HOME. Setting CLASSPATH to include the classes and ZIP files containing JDBC and SQLJ functionality. Setting the PATH variable to use the bin directory for DB2. Setting LIBPATH and LD_LIBRARY_PATH to use the libraries shipped with DB2.

80

DB2 Java Stored Procedures: Learning by Example

The following is a sample from our test environment:


if [ -f sqllib/db2profile ]; then . sqllib/db2profile fi export Java_HOME=/usr/jdk_base export DB26=/usr/lpp/db2_06_01 export DB26J=$DB26/Java export CLASSPATH=.:$DB26J/db2Java.zip:\ $Java_HOME/lib/classes.zip:\ $Java_HOME/lib:\ $DB26J/runtime.zip:\ $DB26J/sqlj.zip export PATH=$Java_HOME/bin:$DB26/bin:$PATH export LIBPATH=$DB26/lib:$LIBPATH export LD_LIBRARY_PATH=$DB26/lib:$LD_LIBRARY_PATH

Each developer wishing to create Java stored procedures would use the same .profile information with a minor change for the location of the db2profile script.

Chapter 4. System setup

81

82

DB2 Java Stored Procedures: Learning by Example

Chapter 5. Designing Java stored procedures


In this chapter we discuss the various issues that an application designer must be aware of when developing Java stored procedures.

5.1 General design issues


The following sections present some general issues that you need to consider when designing your Java stored procedures.

5.1.1 Naming
There are a number of interrelationships between the various components used in a Java stored procedure environment. Therefore, it is a good idea to come up with some naming standards as soon as possible in the design process. The following sections provide some general naming recommendations for a Java stored procedure environment (see Figure 13 on page 95 for a discussion of how the various programming objects interact). Remember that there are some issues surrounding case sensitivity with many of these names. Be consistent in your use of case, and implement some site conventions for everybody to follow.
5.1.1.1 Relationships between stored procedure components Figure 11 shows the interrelationship between the various components in a Java stored procedure environment:

Each stored procedure is implemented as a Java method, and there is a one-to-one relationship between a method and a stored procedure. One or more methods belong to a Java class. There is a one-to-one relationship between a Java class and a Java source file. One or more classes reside in a Java package. There is a one-to-one relationship between a Java package and an operating system directory (which stores all of the Java source files for that package). One or more Java packages reside within an OS/390 executable module (on the OS/390 platform) or within a JAR file (on the UNIX and NT platforms).

Copyright IBM Corp. 2000

83

Load Module (OS/390) or JAR (Unix/Windows)


Java Package = OS Directory Java Package = OS Directory Class = Java Source File
Method = Stored Procedure Method = Stored Procedure

Class = Java Source File


Method = Stored Procedure Method = Stored Procedure

Class = Java Source File


Method = Stored Procedure Method = Stored Procedure

Class = Java Source File


Method = Stored Procedure Method = Stored Procedure

Figure 11. Java stored procedure object interrelationships

Most code management products and procedures operate at source code file level. Therefore, we felt that storing any more than one stored procedure within a single source code file can cause version management issues. For this reason, we chose to implement a single method per class, which resulted in a single stored procedure per source file. We also implemented a single Java package per OS/390 executable or JAR file, to keep the size of these objects manageable. This approach is summarized in Figure 12.
Note

As with any other naming conventions, there are no definitive right and wrong ways to name components. Within this section we present the conventions that we used during the production of this book. This approach seemed to provide a good compromise between flexibility and manageability. However, your mileage may vary: you must define your own conventions based upon any existing standards and the particular environment that you are working within.

84

DB2 Java Stored Procedures: Learning by Example

Load Module (OS/390) or JAR (Unix/Windows)


Java Package = OS Directory Class = Java Source File
Method = Stored Procedure

Class = Java Source File


Method = Stored Procedure

Figure 12. Our Java stored procedure object structure

5.1.1.2 Stored procedure name If you already use non-Java stored procedures, you will probably have standards in place for stored procedure names (the name you specify in the SQL CALL statement to invoke the stored procedure).

Remember that you have a full 18 characters to use, so make the name as meaningful as possible in relation to the stored procedures function. For example, Add_customer, Promote_employee, and Bill_client are all good descriptive names. DB2 UDB for OS/390 Version 6 and DB2 UDB for UNIX, Windows NT, and OS/2 support 2-part stored procedure names, which give you still more flexibility in your naming convention.
5.1.1.3 Java method name There is a one-to-one relationship between a method name and a stored procedure name. Although the names can be dissimilar, for ease of understanding, we suggest that the stored procedure and the method be named the same.

Chapter 5. Designing Java stored procedures

85

5.1.1.4 Java class name A Java class contains one or more methods. We found it easiest to place one method in a class and to name the method the same as the class, changing the initial character of the class name to upper case.

In our example, the Java method called add_customer is the only method in a Java class called Add_customer.
5.1.1.5 JDBC source file / SQLJ Source File There is a one-to-one relationship between a Java class and the file the source is stored in. Therefore, we recommend that you name the source file after the Java class it contains.

So, if you are following our previous recommendation of one method (stored procedure) per Java class, you can name the source file after the stored procedure name. In our example, the stored procedure Add_customer would be implemented as a method called add_customer, within a class called Add_customer, and stored in a file called Add_customer.java (for a JDBC procedure) or Add_customer.sqlj (for a SQLJ procedure).
How many stored procedures per source file?

We feel that the approach we have described above provides the greatest flexibility in a typical development environment, where version management and concurrent development requirements would make the placement of multiple stored procedures within each source file much more difficult to manage. However, there is nothing to stop you from setting up your environment in such a way as to place multiple stored procedures in each .java source file if you wish. In this case, each stored procedure becomes a separate method within the class represented by the source file. You will need to create a meaningful name for the source file that encompasses the stored procedures within it.

5.1.1.6 Java package The Java package name is the basic grouping unit within the Java stored procedures environment, allowing you to associate related stored procedures with each other.

86

DB2 Java Stored Procedures: Learning by Example

Some of the items you may wish to include in your standard for Java package are listed below: An application identifier, if you are grouping your procedures into packages by application (PAYROLL, for example). An environment identifier, if you will be mixing several development environments within the same system (for example, development, unit test, or system test).
How many Java packages per load module or JAR?

In our tests, we created a discrete OS/390 load module (on the S/390 platform) or JAR file (on UNIX and Windows NT) for each Java package. However, you may incorporate several Java packages into a single HJP load module or JAR file if you wish. The remainder of this discussion assumes a one-to-one relationship between the Java package and the OS/390 load module or JAR.

The source files for all stored procedures that belong to a given Java package should be grouped together in a single USS directory named after the Java package. For example, the Add_customer and Add_order SQLJ procedures both belong in the ACME package. Therefore, the ACME directory contains the source files Add_customer.sqlj and Add_order.sqlj.

Chapter 5. Designing Java stored procedures

87

Case sensitivity in Java package names on S/390

As we are suggesting that you implement a one-to-one relationship between Java packages and OS/390 load modules, you may be tempted (as we were initially) to simply name the OS/390 load module after the Java package. This should be avoided, as it has a number of disadvantages: It imposes a limit of 8 characters on your Java package names (the maximum length of a PDSE member name), making them less descriptive. It can lead to case sensitivity problems with Java package names, due to the fact that the OS/390 load module name is always in upper-case. For instance, two Java packages named package1 and PACKAGE1 will be completely discrete within the USS environment, but will both result in a load module name of PACKAGE1 with the PDSE dataset. This may lead to existing modules being overwitten during the program preparation process. For these reasons, we recommend that your program preparation scripts use different names for the Java package and the PDSE member name. The sample scripts described in 7.2, OS/390 Java stored procedure preparation on page 119 reflect this.
5.1.1.7 OS/390 load module The HPJ load module contains an optimized, OS/390 specific, compiled version of all of the stored procedures within one or more Java packages.

We recommend the use of a single Java package per OS/390 load module. However, as the OS/390 load module can only be a maximum of 8 characters in length, you will probably need to create a suitable means of shortening or transforming the Java package name to fit.
5.1.1.8 JAR file In a DB2 UDB for UNIX, Windows, OS/2 environment, the JAR file is used to contain all of the .class files associated with a particular Java package. Therefore, it is functionally equivalent to a HPJ executable module on the S/390 platform.

We recommend that you name your JAR file the same as your Java package name to ease problem solving. There is no technical limitation requiring the JAR name to be named the same as the Java package name.

88

DB2 Java Stored Procedures: Learning by Example

5.1.1.9 DB2 package The program preparation process for each SQLJ procedure will result in 4 DB2 packages being produced (one for each isolation level). Therefore, if you have 2 SQLJ procedures in a Java package, that Java package will have 8 DB2 packages associated with it (the terminology is a little confusing here make sure you are clear about the differences between Java packages and DB2 packages).

DB2 package names must be limited to 7 characters, as the db2profc process appends a number (between 1 and 4) after the supplied name to generate the 4 packages. You must therefore create a reasonable 7-character abbreviation for your 18-character stored procedure name. For example, for the Add_Customer stored procedure, you could decide to use a package name of ADDCUST, which would cause db2profc to generate DBRMs to bind into packages ADDCUST1, ADDCUST2, ADDCUST3, and ADDCUST4. For JDBC stored procedures, a generic set of DB2 packages (DSNJDBC1,
DSNJDBC2, DSNJDBC3, and DSNJDBC4) are used.

5.1.1.10 DB2 package collection Once again, you will probably already have some standards set up for collection naming within your organization.

Unless your existing site standards dictate otherwise, we suggest that you use one DB2 package collection for each Java package, and name that collection after it. So, for Java package ACME containing SQLJ stored procedures Add_customer (DB2 package name ADDCUST) and Add_order (DB2 package name ADDORD), you may have a package collection called ACME, containing 8 DB2 packages (ADDCUST1 to ADDCUST4 and ADDORD1 to ADDORD4). See 9.1, DB2 plans and packages on page 167 for details on the relationship between client plans and Java stored procedure package colelctions.

5.1.2 Parameter style: Java or DB2GENERAL


This document describes the Java stored procedures that correspond to the SQLJ Routines specification. These are known as parameter style Java stored procedures.

Chapter 5. Designing Java stored procedures

89

For DB2 UDB for UNIX, Windows, OS/2, an earlier, more proprietary, solution for making Java stored procedures is known by the name Parameter Style DB2GENERAL. It was developed before industry standards had been established.

5.1.3 Public static method with void return type


A DB2 Java stored procedure returns no return code. Any value determined by the stored procedure must return in one of the parameters passed into the stored procedure. The declaration of the method looks something like this:
public class Add_customer { public static void add_customer ( String in_cust_firstname, String in_cust_lastname, String in_cust_address, int[] out_cust_no, String[] mark, String[] mark_error_text ) throws SQLException, Exception

The stored procedure in this example has the name of Add_customer. The method to be invoked is add_customer.

5.1.4 Parameters must be mappable to base SQL data types


The parameters used by a Java stored procedure must be able to be mapped to base SQL data types. The mapping between Java and SQL data types is explained in the section Supported SQL Data Types in the chapter Programming in Java in the DB2 UDB Application Development Guide, SC09-2845.

5.1.5 LOBS not supported for Java stored procedures


At this point in time, LOBS are not supported for any SQLJ or JDBC programs. Therefore, they are not supported as parameters for Java stored procedures.

5.1.6 Why do we use [ ] on the output parameters?


The output parameters must be declared within the SQLJ source as Java arrays. However, only the [0] element is used. The SQLJ standard requires this form of parameter style.

90

DB2 Java Stored Procedures: Learning by Example

Note

If you use an output parameter in a SELECT statement, be sure to enclose the entire name, including the [0], with parantheses. Failure to do will result in a syntax error. Example: SET HI_CUST_NO = :(out_cust_no[0])

5.1.7 Using JDBC, SQLJ, or both


A stored procedure may be built using JDBC, SQLJ, or both. JDBC can be considered the Java equivalent of ODBC. The JDBC statements are executed dynamically. SQLJ can be considered the Java equivalent of embedded SQL for the Java language. SQLJ source code runs through a precompiler to produce Java (JDBC) source code as well as other files that go through additional processing to allow DB2 to prepare the SQL into compiled static statements. A stored procedure may mix both SQLJ and JDBC. For recommendations on which API to use, refer to 2.1.3, Choosing the access method: JDBC versus SQLJ on page 9.

5.1.8 Java packages


A stored procedure may be built using the Java package statement (not to be confused with a DB2 package!). The OS/390 platform requires the use of the Java package statement. For other platforms, use of Java packages is optional.
Portability

If it is important to you to be able to easily port your stored procedure code between OS/390 and other platforms, we recommend that you code all of your stored procedures using Java packages. For this reason, all of the Windows NT and UNIX examples in this book use the Java package statement.

From a design perspective, use of Java packages helps organize stored procedures into application groups. Most shops host more than one

Chapter 5. Designing Java stored procedures

91

application on a machine, consequently, we recommend using Java packages for your stored procedures. A Java program becomes part of a Java package if it has the token package followed by the Java package name at the top of the source file. Example:
package ACMESOS;

For recommendations regarding Java package, module, and JAR naming standards, see 5.1.1, Naming on page 83.

5.1.9 Case sensitivity


Some recommendations on naming various objects within a Java stored procedures environment can be found in 5.1.1, Naming on page 83. You should be aware that with the exception of purely DB2 objects such as plans and packages, most object names are case sensitive, so it is vital that you be consistent in your naming. We suggest that you formulate some conventions for use at your site. In particular, you should be aware of the following issues: On the OS/390 platform, all OS/390 load module names are folded to upper case. Therefore, it is possible to accidentally overwrite load modules if you specify a PDSE member name of module1 during the HPJ step, and subsequently specify another called MODULE1. A Java client (SQLJ or JDBC) calling an S/390 stored procedure must code the stored procedure name in upper case. See 9.2.1.2, The SQL CALL statement on page 171 for further information. An SQLJ stored procedure on the OS/390 platform must refer to DB2 object names in upper-case within embedded SQL statements, or a SQLCODE -204 results.

5.1.10 Nested Java stored procedures


DB2 UDB for OS/390 Version 6 allows one Java stored procedure to call another (nesting). For DB2 UDB for UNIX, Windows, OS/2, as of Version 7, a Java stored procedure may not call another Java stored procedure. This restriction may change in a future version. Stored procedures written in other languages may nest, and they may be written in different languages, if they meet the following requirements:

92

DB2 Java Stored Procedures: Learning by Example

- Java is not a language used to build one of the stored procedures - All the procedures must be fenced and catalogued.

5.2 Design issues for OS/390 Java stored procedures


The following sections present some issues that you need to consider when designing your Java stored procedures for OS/390.

5.2.1 Must use HPJ compiler


The OS/390 platform requires Java stored procedures to be compiled with the High Performance Java compiler (HPJ). The HPJ compiler produces a load module similar to COBOL or PL/1, or any other LE 3GL load module. The HPJ step must be completed because a Java Virtual Machine does not execute within the address space that DB2 executes. This restriction may change in a future version.

5.2.2 Must have Java Package as first statement


The OS/390 platform requires a Java package statement to be the first statement in the source. The Java package name subsequently is mapped to the load module produced by the HPJ. For example, these two techniques are functionally equivalent: a Java package groups a number of class files, and an HPJ-produced load module groups a number of class files into an executable unit.

5.2.3 Packaging considerations


The number of routines you choose to group together, and their degree of complexity, may impact the performance of the system. For instance, placing many very large procedures into a single Java package will result in all of the code being compiled into a single HPJ executable module. At run time, the entire module has to be loaded into the stored procedure address space, which can be wasteful if only a single, small routine is required. On the other hand, grouping commonly-used routines into a single Java package may provide some benefits, as the chances of the required module already being resident in the stored procedure address space are increased. There are no hard-and-fast rules for this packaging. We suggest the following rules of thumb: Cluster together (package) the small, often-used stored procedures.

Chapter 5. Designing Java stored procedures

93

Larger, less-used procedures should stand by themselves in order to allow them to be paged out of memory when not being used. Whenever possible, package the most frequently used of the remaining procedures together.

5.2.4 Environmental considerations


The environment required to execute Java stored procedures on the S/390 platform is a fairly complex one, utilizing both base OS/390 and USS. The program preparation process (which is described in detail in 7.2, OS/390 Java stored procedure preparation on page 119) results in the following objects being produced: An OS/390 load module for the stored procedure, stored in a PDSE data set A link to the load module, within a nominated HFS directory under OS/390 UNIX Systems Services (USS) A set of DB2 packages, if the stored procedure accesses DB2 using SQLJ (JDBC procedures use a set of generic JDBC packages). A serialized profile, if the stored procedure accesses DB2 using SQLJ (again, JDBC procedures use a generic JDBC profile). Figure 13 shows how these objects are used when a client issues a call to a Java SQLJ stored procedure.

94

DB2 Java Stored Procedures: Learning by Example

SQLJ Source
Program Preparation Process

DB2 Packages

ACMESOS/ Add_customer.sqlj

ACMESOS1 ACMESOS2 ACMESOS3 ACMESOS4


ion ect c oll in Via ound plan b t's n clie

USS Directory
via PDSE link

ACMESOS
PDSE Link

ACMESOS
via CLA SSP ATH

via ST E PLIB

HPJ load module PDSE dataset

ADD_CUSTOMER

JAVAENV Dataset
2 NAME
ADD_CUSTOMER

via JAVAENV DD

WLMJAVA
SP WLM Address Space

SYSROUTINES (V6)
EXTERNAL_NAME
ACMESOS/Add_customer.add_customer

WLM_ENV
WLMJAVA

...

Client
... CALL ADD_CUSTOMER (FIRSTNAME, ....) ...

SYSPROCEDURES (V5)
1 PROCEDURE
ADD_CUSTOMER

RUNOPTS
ACMESOS/Add_customer.add_customer

WLM_ENV
WLMJAVA

...

Figure 13. Runtime environment overview SQLJ stored procedure

1. The client issues a call to the stored procedure ADD_CUSTOMER. 2. Depending upon the version of DB2 for OS/390 being used, either the RUNOPTS column of SYSIBM.SYSPROCEDURES or the EXTERNAL_NAME column of SYSIBM.SYSROUTINES is used to determine the Java package, class, and method associated with the call. This is defined within the catalog according to standard Java syntax:
package/classname.methodname

3. The JAVAENV data set specified in the procedure JCL for the selected WLM environment (also obtained from SYSPROCEDURES or SYSROUTINES) is used to obtain the value of the CLASSPATH parameter. The USS libraries specified in CLASSPATH are searched to find a link named after the Java package name

Chapter 5. Designing Java stored procedures

95

specified in the SYSROUTINES or SYSPROCEDURES definition (ACMESOS in our example). 4. The link is used to obtain the PDSE member name containing the HPJ compiled stored procedure load module for the Java package being used. 5. This load module is loaded into the relevant WLM stored procedure address space. 6. DB2 searches for the stored procedures DB2 packages in the collection that the clients plan/package belongs to (or looks in the collection specified in the COLLID keyword on the CREATE PROCEDURE command).

5.3 Design issues for the UNIX, Windows, OS/2 platforms


There are no major design issues for Java stored procedures on the UNIX, Windows, or OS/2 platforms. Programmers coming from OS/390 to a UNIX, Windows, or OS/2 platform should understand that Java stored procedures within DB2 UDB are able to execute stored procedures as native Java bytecode running within a Java Virtual Machine (JVM). They do not require the HPJ compiler, nor are they able to execute a Java stored procedure that has been put through the HPJ compile process, as the resultant module is an S/390 executable.

96

DB2 Java Stored Procedures: Learning by Example

Chapter 6. Coding Java stored procedures


This chapter provides some practical guidance on the techniques you can use when coding your DB2 Java stored procedures. The following sections are not intended to be a programming reference. We assume that you have at least a basic knowledge of Java, DB2, JDBC and SQLJ. If you need more background information on these subjects, please refer to the resources listed in Appendix G., Related publications on page 359.

6.1 Null handling with JDBC stored procedures


A Java stored procedure requires special programming when handling null values.

6.1.1 Calling a stored procedure with a null value


JDBC programs handle SQL nulls with a special technique when passing a null. When calling the stored procedure from a JDBC client, use the special function setNull for marking the parameter as null. You cannot simply pass a null Java object.
6.1.1.1 Invalid coding Here is an example of invalid coding:
String nullguy = null; callStmt.setString (3, nullguy); // null address, fails for JDBC

6.1.1.2 Valid coding Here is an example of valid coding:


callStmt.setNull(3,Types.CHAR);// null address, works for JDBC

6.1.2 Using a Java base type as a parameter


You may need to establish the parameters of the stored procedure in a different format than the way that they are defined to the database, if you are passing in nulls.

Copyright IBM Corp. 2000

97

For example, the following code fragment defines several parameters:


public class Query_test1 { public static void query_test1 ( int in_prod_no, String prod_desc, int in_qty_on_hand )

These parameters were defined to match the DDL for the table:
create table test1 ( PROD_NO integer not null, PROD_DESC char(30), QTY_ON_HAND integer )

Notice that QTY_ON_HAND is nullable (under the business assumption that at a point in time it may not be known how many items of that product are available). Because the SQL field is defined as an integer, it appears to make sense to define the stored procedure parameter as an integer. Unfortunately, this will fail when trying to invoke the stored procedure with a null value. A Java int field is a base type and thus cannot be set to an actual null value. To work around this issue, define the parameter as a String. This gives you the ability to assess if the String is a null object.
Trim a Numeric String

If you use a String to pass a numeric value, be sure to trim the spaces from the string.
Example:

callStmt.setString (2, argv[2].trim());

98

DB2 Java Stored Procedures: Learning by Example

For example:
public class Query_test1 { public static void query_test1 ( int in_prod_no, String prod_desc, String in_qty_on_hand ) . . . int local_in_qty_on_hand; if (null == in_qty_on_hand) { //do special handling for when it is null } else local_in_qty_on_hand = Integer.parseInt(in_qty_on_hand.trim());

6.1.3 Determining if a selected item was an SQL null via wasNull()


Use the wasNull method of ResultSet to determine if the field just examined equals an SQL null. A ResultSet holds the contents of an executed SQL select. Example:
String ins_prod_desc = ""; String ret_prod_desc = rs.getString(3); if (rs.wasNull()) ins_prod_desc = "NULL"; else ins_prod_desc = "'" + rs.getString(3) + "'" ;

6.1.4 Inserting a NULL


Inserting a NULL in JDBC follows the same rules as any other language use the NULL value when building the insert statement. For example:
String sql2 = "insert into acmee.order_item_summ " + "(prod_desc, qty_1_to_5,QTY_5_TO_10,QTY_11_PLUS) " + "values(" + ins_prod_desc + "," + insert_vals +

Chapter 6. Coding Java stored procedures

99

")"; stmt2.executeUpdate(sql2);

This example builds upon the previous example, which calculated the ins_prod_desc field either to the value in the third column of the ResultSet surrounded by single quotes, or to the value NULL.

6.2 Null handling with SQLJ stored procedures


Null handling in SQLJ stored procedures is considerably easier than for JDBC. SQLJ is intuitive about null-handling. For example, a null Java object translates to a nullable column without needing to use a special method as in JDBC.
Table 9. Null handling within SQL stored procedures

Requirement
Calling a stored procedure from an SQLJ client Using a base Java type as a parameter

Restrictions
When calling a stored procedure from an SQLJ client, you can send a null Java object. It is not possible to set a base Java type to null and have it actually understood by downstream processing as a null. Instead, you can cast parameters to a String type (or other Java type subclassed from Object) which can then be set to null. A SQLJ stored procedure can receive a null Java object as a parameter. SQLJ understands that when a Java object is null and it is being inserted to the database that a null value is to be placed in the associated nullable column in the table. The host variable is set to Java null when a select statement reads an SQL null value into that host variable.

Receiving a null in an SQLJ stored procedure Inserting a null from an SQLJ stored procedure

Receiving a null within an SQLJ stored procedure

6.3 SQLJ Iterators and ResultSets


SQLJ introduces the concept of the Iterator, which is SQLJs version of a ResultSet where the fields have been cast to Java types. This allows for some up front cross-checking.

100

DB2 Java Stored Procedures: Learning by Example

There are two types of Iterators: Positional refers to the fields by position Named refers to the fields by name

6.3.1 Return ResultSets from SQLJ stored procedures


Consider returning a ResultSet instead of an Iterator from an SQLJ stored procedure. The technique to do this is shown in the following code fragment (where out_rs[0] is a ResultSet in the parameter list):
Defined_iter2 iter2; #sql iter2 = { select prod_desc, qty_1_to_5, QTY_6_TO_10, QTY_11_PLUS from acmee.order_item_summ }; // #sql out_rs[0] = iter2.getResultSet();

There are two reasons why you might choose to return ResultSets instead of Iterators. First, on the UNIX and Windows NT platforms, the system has been designed to recognize only ResultSets, not Iterators. (This may change some time in the future). Secondly, on the OS/390 platform, although it has been tested as being able to return Iterators, it is less efficient than using ResultSets.

6.3.2 Avoid returning a used ResultSet


An Iterator points to an underlying cursor. Once you walk through that Iterator, the cursor is considered exhausted. (Future versions of DB2 UDB for OS/390 will allow backwards walking through a cursor). If you cast to a ResultSet and walk through it, that activity also exhausts the cursor. Therefore, the only ResultSets that can be returned to the client are those that have been freshly created from a select statement without a subsequent review.

6.3.3 Close interim ResultSets


If you code a stored procedure that uses an interim ResultSet then be sure to close that interim ResultSet. Failure to do so may cause data not to be returned. It is good coding practice to close ResultSets that no longer need to be used.

Chapter 6. Coding Java stored procedures

101

6.3.4 Returning Multiple ResultSets


A SQLJ stored procedure can return multiple ResultSets. Adherence to SQL standards requires that ResultSets be returned to the client in the order in which they are opened. Consequently, if you need two ResultSets, open the first declared ResultSet before opening the second declared ResultSet. Reversal of the order of the opening will produce odd results in your client.

6.4 Error Handling


A Java stored procedure does not return a value. We suggest sending in two parameters for determining successful (or unsuccessful) execution. One is used to mark where the stored procedure last successfully executed. The second holds the text produced by the catch block of an exception. The following code fragment illustrates this:
. . mark[0] = "Add_customer: getConnection"; Connection con = DriverManager.getConnection("jdbc:default:connection"); . . catch (SQLException e) { mark_error_text[0] = "SQLException raised, SQLState = " + e.getSQLState() + " SQLCODE = " + e.getErrorCode() + " :" + e.getMessage(); e.printStackTrace(); } catch (Exception e) { mark_error_text[0] = "Add_customer: major exception caught: " + e.getMessage(); e.printStackTrace(); }

6.4.1 Getting the results of printStackTrace


The code fragment above executes the statement e.printStackTrace() . However, that output goes to the standard output (or perhaps standard error). What this means is that the invoking client will not see the stack trace. It will be printed, on OS/390, to the output of the WLM address space location specified by JSPDEBUG. On UNIX and Windows NT, the output drops off the edge.

102

DB2 Java Stored Procedures: Learning by Example

To return the printStackTrace to the client, use StringWriter and PrintWriter methods to get the output into a string. For example:
mark_error_text[0] = "Query_oi_summ: " + "SQLException raised, SQLState = " + e.getSQLState() + " SQLCODE = " + e.getErrorCode() + " :" + e.getMessage(); StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); mark_error_text[0] += ":printStackTrace=" + sw.toString() ;

6.5 Debugging
Sadly, our computers often remind us that, unlike them, we are not perfect! Our programs rarely work correctly the first time. Stored procedures can be difficult to debug, due to the limitation that they run underneath the control of a separate process, perhaps on a different machine than that of the invoking client.

6.5.1 Initially writing as a standalone program


One common technique when writing stored procedures in any language has the developer start by writing the code as a standalone program. Write the stored procedure as one class and the driver as a separate class. When you complete the draft version you customize the stored procedure class to fit within the database. One item that must change will be the Connection, which would have been established by the driver in the standalone program.

6.5.2 Writing debugging statements to a table


One approach to debugging is to write debugging statements to a table. We question the feasibility of this approach, due to rollbacks. Quite frankly, the stored procedures that most need debugging are the ones that will end so badly the system rolls back the work, erasing all the debug data!

6.5.3 OS/390 debugging


You can use three techniques for OS/390 debugging:
6.5.3.1 ET/390 Debugger The ET/390 Debugger can be useful for debugging Java stored procedures. Refer to the ET/390 Concepts & Overview manual for further details1.

Chapter 6. Coding Java stored procedures

103

6.5.3.2 System.out.println The developer may choose to put statements in the source code of the Java stored procedure to say, Here is where I am right now, and this is the value of a questionable variable. This technique is quite similar to the use of COBOL Display statements or the C printf statements.

These statements show in the WLM output (as pointed to by the JSPDEBUG DD) of the job executing the Java stored procedures. Your systems programmer can tell you the name of the data set on your system. These statements must be used with care, and only on the development platform if they get pushed out to production, the performance of the production system may be negatively impacted.
6.5.3.3 Writing to an output file A technique for writing stored procedure output to a file is described in 6.5.4, UNIX and Windows NT debugging on page 104. This technique also works on OS/390. The file is created on the UNIX Systems Services file system, because a USS environment is created within the WLM address space.

6.5.4 UNIX and Windows NT debugging


The UNIX and Windows NT platforms offer two techniques for debugging.
6.5.4.1 Debugging option of the SPB The debugging feature of the Stored Procedure Builder may be useful. Refer to 6.6, Using the DB2 Stored Procedure Builder on page 105 for more information. 6.5.4.2 Writing to a text file Using the system.out.println statement within a Java stored procedure on the UNIX or Windows NT platforms produces no output, by design. However, these types of statements can be directed to a file.

In the following example, a file is created with a date and time stamp for the file name. (Note that Java is smart enough to convert the /tmp to \tmp on the Windows NT platform.)

At the time of writing, the ET/390 manuals did not have formal IBM publication numbers. However, they can be downloaded from the Web in PDF format at http://www-4.ibm.com/software/ad/vajava/library.htm.

104

DB2 Java Stored Procedures: Learning by Example

//////////////////////////////////////////////////////// // establish debugging file: name is timestamped //////////////////////////////////////////////////////// Date debugDate = new Date(); DateFormat dateFormat = DateFormat.getDateTimeInstance(); (SimpleDateFormat)dateFormat).applyPattern("MM_dd_HH_mm_ss"); String debugdf = dateFormat.format(debugDate); PrintWriter pwx = new PrintWriter( new FileWriter("/tmp/" + debugdf + ".txt"),true ); pwx.println("sql =>" + sql + "<=");

An example file name on Windows NT created from this process is \tmp\03_16_09_25_59.txt , which indicates that the stored procedure ran on March 16 at 9:25AM at 59 seconds past the minute. The pwx.println statement at the end of the code fragment writes what the stored procedure considers to be the value of the sql variable to this debugging file. Observe these two cautions: 1. If the stored procedure fails, the pwx.close() statement (not shown) will not have executed; a DB2 process will still own this file in an open mode, thus the file cannot be deleted until the database is brought down. A better approach is to put the pwx.close() not only in the main body of the stored procedure, but also in the catch blocks, as seen in some of the examples, to close the file. 2. Never allow this debugging technique to go onto the production system. It will hurt performance and possibly bring down the system.

6.6 Using the DB2 Stored Procedure Builder


The DB2 Stored Procedure Builder (SPB) is a GUI tool to assist developing DB2 stored procedures. You will need to assess the SPB for your own use. Our investigation uncovered both advantages and limitations. Most GUI tools are improved on a rapid basis, such that the difficulties we see now may be corrected by the time you read this book.

6.6.1 Advantages of the SPB


The SPB offers the following useful features.

Chapter 6. Coding Java stored procedures

105

6.6.1.1 Testing existing stored procedures One of the most attractive benefits to the SPB is that it gives you the ability to test an already-built stored procedure.

You need not make the source available on the platform upon which the SPB runs; the SPB reads the catalog definitions to build the window that asks for the input parameters. This facility frees you from the requirement to write a specific client driver program for each stored procedure when testing. DB2 Connect is required for being able to invoke stored procedures located within DB2 databases on other platforms, such as OS/390 or UNIX.

6.7 Common errors


In the following sections we document some of the errors we have seen when working with Java stored procedures.

6.7.1 OS/390 errors


Errors produced by OS/390 Java stored procedures sometimes return data back to the client. Other errors show in the WLM logs.
6.7.1.1 HPJ3115(S) message received during HPJ compile

Symptom
HPJ compile issues this error message:
HPJ3115(S) Unable to fetch module "HPJ3TBY".

Possible Solution
Increase region size.
6.7.1.2 Class Not Found at runtime

Symptom
This error message is issued at runtime:
class not found in classpath: ACME/ADD_CUSTOMER to String string from error is: java.lang.NoSuchMethodError

106

DB2 Java Stored Procedures: Learning by Example

Possible Solution
The PDSE member created by the HPJ compiler will have its name folded into upper case (OS/390 does not support lower case PDSE member names). Check that the USS link to the PDSE member in your links directory points to an upper case version of the PDSE member name. If this has been incorrectly specified as a lower case name, the link will not work, and this error message will be returned. See 5.1.9, Case sensitivity on page 92 for more details.
6.7.1.3 Method Not Found at runtime

Symptom
This error message is issued at runtime:
error GetStaticMethodID class name: ACMESOE/Add_customer func name: Add_customer toString string from error is: java.lang.NoSuchMethodError: Add_customer

Possible Solutions
Ensure case of method name in SYSPROCEDURES or SYSROUTINES matches that defined in SP Ensure that SP code has method defined as public static, with void return type Ensure that parameter definition in SYSPROCEDURES or SYSROUTINES matches CALL definition.
6.7.1.4 SQLCODE -104 At DB2 Package Bind

Symptom
SQLCODE -104 is issued at package bind;
DSNX200I =DBZ2 BIND SQL ERROR USING DB2RES2 AUTHORITY PLAN=(NOT APPLICABLE) DBRM=ADDCUST1 STATEMENT=1 SQLCODE=-104 SQLSTATE=42601 TOKENS=;-<END-OF-STATEMENT CSECT NAME=DSNHPARS RDS CODE=0

Chapter 6. Coding Java stored procedures

107

DSNT233I =DBZ2 UNSUCCESSFUL BIND FOR PACKAGE = DBZ1.ACMESOE.ADDCUST1.()

Possible Solutions
Ensure that you havent put semicolons within the #SQLJ curly brackets at end of SQL statements (normal Java statement terminator semicolons are still required outside the #SQLJ curly brackets).
6.7.1.5 SQLCODE -113 when executing from a Java client

Symptom
SQLCODE -113 is issued when executing from a Java client. The error looks something like this:
java.sql.SQLException: DB2JDBCSection Received Error in Method execute_call:SQLCODE==> -113 SQLSTATE ==> 42602 Error Tokens ==> <<DB2/OS390 V5.1 ANSI SQLJ-0/JDBC 1.0>> Add_customer 000 at COM.ibm.db2os390.sqlj.jdbc.DB2SQLJJDBCSection.setError(DB2SQLJJDBCSection. java:1049) at COM.ibm.db2os390.sqlj.jdbc.DB2SQLJJDBCSection.execute_call(DB2SQLJJDBCSect ion.java:874) at COM.ibm.db2os390.sqlj.runtime.DB2SQLJRTStatement.execute(DB2SQLJRTStatemen t.java:987) at sqlj.runtime.ExecutionContext$StatementFrame.execute(ExecutionContext.java :741) at sqlj.runtime.ExecutionContext.execute(ExecutionContext.java:419) at acmecl.sscall_Add_customer.main(sscall_Add_customer.java:169)

Solution
Define the stored procedure in SYSPROCEDURES to be known by an uppercase name. This uppercase name now becomes the name used by the Java client to invoke the stored procedure. Please note that the stored procedure itself can still be written with lowercase letters: it is the indirection in SYSPROCEDURES that makes it visible as uppercase.
6.7.1.6 SQLCODE -440 when trying to invoke a stored procedure

Symptom

108

DB2 Java Stored Procedures: Learning by Example

DB2 is not able to find the stored procedure or the caller does not have execute authority on stored procedure.

Solution
One thing DB2 checks is whether the stored procedure was created after the original bind of the CALL statement. This can only happen during autobind. The calling DB2 package has to be explicitly rebound in this case.

Solution
Another check is whether the caller has execute authority to the stored procedure. The owner of the stored procedure needs to issue a GRANT EXECUTE ON PROCEDURE to this user. Callers of stored procedures that were migrated from V5 and have not been dropped and recreated do not need this authority, as they have no OWNER.

Solution
The most common error is that a procedure by this name with this number of parameters was not found in the catalog table. To resolve this, you should obtain the result of a SELECT of all columns of SYSIBM.SYSROUTINES for the SP that you want to invoke. First, verify that the number of parameters sent on the CALL statement, or described in the SQLDA if it is a USING DESCRIPTOR call, matches the number of parameters column in SYSIBM.SYSROUTINES. If this is correct, then it's a problem with the stored procedure name. Now you need to determine exactly what name was specified on the SQL CALL statement. The name can be either explicitly specified, or contained in a host variable. If you are running on a distributed client using a workstation development tool that uses ODBC or JDBC, then you are definitely running the SQL CALL statement with the name specified in a host variable. Either way, the name can be a 1-part, 2-part, or 3-part name. A 3-part name is LOCATION.SCHEMA.PROCNAME. In this case, make sure that LOCATION is the current location. and SCHEMA and PROCNAME match what is in SYSIBM.SYSROUTINES, which was filled in by CREATE PROCEDURE. Similarly, a 2-part name is SCHEMA.PROCNAME, so make sure that they match what is in SYSROUTINES. For a 1-part name, only PROCNAME is specified, and in this case, DB2 must determine the schema name. DB2 uses a combination of CURRENT SQLID and CURRENT PATH to look for a match, so you need to make sure that the schema

Chapter 6. Coding Java stored procedures

109

name in SYSIBM.SYSROUTINES is in the concatenation of schemes used to resolve the SP name. It is different for call with a literal than call with a host variable:
CALL <literal> SQL statements are resolved at bind time. The PATH bind option is used to determine schema name. CALL <host variable> SQL statements are resolved at run time. The CURRENT_PATH special register is used to determine the list of potential

schema names.
Note

With APAR PQ39037 is applied, this situation changes. Refer to the APAR text for further details.

Solution if CLIENT/SERVER with DB2 for OS/390 as the CLIENT:


If you are invoking a remote DB2 stored procedure from a DB2 for OS/390 V6 client, it's possible that since we now process the CALL statement at bind time in V6, DB2 packages that were bound in V5 will fail to bind on V6. Stored procedures are now real DB2 objects, so a reference to a remote stored procedure when binding a DBRM into a plan or DB2 package locally behaves just like a reference to a remote table. This is what the calling application may look like in this case:
CONNECT TO B; CALL P1;

P1 doesn't exist at the local site. This doesn't fail on the BIND in V5, but does in V6. The way to fix this is to handle it exactly the same way as you would handle a reference to a remote table, which will get a -204 if you try to bind the DBRM locally with VALIDATE(BIND). Here are some suggestions: 1. Don't bind the calling DB2 package locally, i.e., don't use MEMBER(x) on the BIND PLAN, use pklist(location.collection.x). This only works if DBRM x doesn't contain SQL to access the local location. 2. Use VALIDATE(RUN) on the BIND. This is the recommended approach, and what is usually done for other remote objects, like tables. Don't worry, VALIDATE(RUN) has no overall performance degradation on the local SQL statements. It only affects those specific SQL statements that cannot be bound during the static BIN. because the objects or auth aren't found at that time -- like SQL referencing remote objects (non 3-part names), including this specific type of CALL statements.

110

DB2 Java Stored Procedures: Learning by Example

3. Use SQLERROR(CONTINUE) on the BIND. SQLERROR(CONTINUE) is usually used only if the DB2 package uses an SQL statements that DB2 390 doesn't support but the application will only execute the statements after a CONNECT to a non -390 DB2 server. 4. Modify the calling application to use a 3-part name on the CALL statement. A 3-part name in V6, when the DB2 package is bound with DBPROTOCOL(DRDA), uses DRDA to implicitly connect to the remote location. 5. Issue a CREATE PROCEDURE P1 at the local site to act as a dummy entry and get past BIND errors.

Solution if just migrated stored procedures from V5 to V6 :


When you run CATMAINT, the resulting V6 stored procedure has no OWNER. This means that the authorization rules don't change from V5. If you subsequently DROP and CREATE the stored procedure, now it has an OWNER, so the caller must have EXECUTE ON PROCEDURE authority to invoke it. Migrated stored procedures have SCHEMA set to 'SYSPROC'. This means that to invoke them, SYSPROC has to be in the concatenation of schemes that DB2 uses in resolution.
6.7.1.7 Location name not listed SQLSTATE=42705, SQLCODE=-950

Symptom
When running a client the following error is seen:
java.sql.SQLException: DB2SQLJConnection error in native method: constructor: LOCATION NAME NOT LISTED IN CDB SQLSTATE=42705 and SQLCODE=-950

Solution
The wrong location name was argued in the connect statement, therefore DB2 attempts to find the remote DB2, however, one is not listed. Details described at 9.2.1, General client coding considerations on page 170.
6.7.1.8 SQLCODE==> -113 SQLSTATE ==> 42602 Error Tokens ==> <

Symptom

Chapter 6. Coding Java stored procedures

111

When running a client, the following error message appears:


java.sql.SQLException: DB2JDBCSection Received Error in Method execute_call:SQLCODE==> -113 SQLSTATE ==> 42602 Error Tokens ==> <<DB2/OS390 V5.1 ANSI SQLJ-0/JDBC 1.0>> SS_ADD_CUSTOMER 000 at COM.ibm.db2os390.sqlj.jdbc.DB2SQLJJDBCSection.setError(DB2SQLJJDBCSec tion.java:1106) at COM.ibm.db2os390.sqlj.jdbc.DB2SQLJJDBCSection.execute_call(DB2SQLJJDB CSection.java:897) at COM.ibm.db2os390.sqlj.runtime.DB2SQLJRTStatement.execute(DB2SQLJRTSta tement.java:1054) at sqlj.runtime.ExecutionContext$StatementFrame.execute(ExecutionContext .java:741) at sqlj.runtime.ExecutionContext.execute(ExecutionContext.java:419)

Solution
Remove hidden whitespace characters that somehow were introduced into the sample. (Speculation: perhaps FTPing between platforms introduces this kind of error). Carefully remove or retype what looks like blanks, especially at the ends of lines.

6.7.2 UNIX and Windows NT errors


In the following sections we list of some errors you may see on UNIX or Windows NT.
6.7.2.1 SQL4301N Java interpreter start-up or communication failed

Symptom
When trying to execute a Java stored procedure, an error message says there was a Java Interpreter start-up or communication failure. For example:
db2inst3@azov:[/u/db2inst3/apps/test1/samples]>java DB2SpCli Java Stored Procedure Sample debug: drop procedure debug: completed drop procedure

112

DB2 Java Stored Procedures: Learning by Example

Registering Java stored procedure SAMPLESTOREDPROC as DB2Stp!salaryModification in not fenced mode debug: starting prepareCall debug: completed prepareCall Calling stored procedure: SAMPLESTOREDPROC COM.ibm.db2.jdbc.app.DB2Exception: [IBM][CLI Driver][DB2/6000] SQL4301N Java interpreter startup or communication failed, reason code "0". SQLSTATE=58004 at java.sql.SQLException.<init>(Compiled Code) at COM.ibm.db2.jdbc.app.DB2Exception.<init>(Compiled Code) at COM.ibm.db2.jdbc.app.SQLExceptionGenerator.throw_SQLException(Compiled Code) at COM.ibm.db2.jdbc.app.SQLExceptionGenerator.check_return_code(Compiled Code) at COM.ibm.db2.jdbc.app.DB2CallableStatement.execute2(Compiled Code) at COM.ibm.db2.jdbc.app.DB2PreparedStatement.execute(Compiled Code) at DB2SpCli.callStoredProc(Compiled Code) at DB2SpCli.main(Compiled Code)

Solution
Reconfigure the DB2 instance to point to the correct JDK on the machine. For example, it may be in /usr/jdk_base, although it could be installed anywhere, as in /usr/lpp/J1.8.1. Your DBA reconfigures this value. It can be seen doing a get dbm cfg, DB2 command, or by looking at the Instance configuration values from Control Center.
6.7.2.2 SQL10013N The specified library could not be loaded

Symptom
When trying to execute a Java stored procedure, an error message says the <DB2HOME>/sqllib/function/<Java class name> could not be loaded. Example:
COM.ibm.db2.jdbc.app.DB2Exception: [IBM][CLI Driver][DB2/6000] SQL10013N The specified library "/u/db2inst3/sqllib/function/Add_customer" could not be loaded.

Chapter 6. Coding Java stored procedures

113

at java.sql.SQLException.<init>(Compiled Code) at COM.ibm.db2.jdbc.app.DB2Exception.<init>(Compiled Code) at COM.ibm.db2.jdbc.app.SQLExceptionGenerator.throw_SQLException(Compiled Code) at COM.ibm.db2.jdbc.app.SQLExceptionGenerator.check_return_code(Compiled Code) at COM.ibm.db2.jdbc.app.DB2CallableStatement.execute2(Compiled Code) at COM.ibm.db2.jdbc.app.DB2PreparedStatement.execute(Compiled Code) at call_Add_customer_with_userid.main(Compiled Code)

Solution
The JAR or class has not been made available to the database. If you are using JAR files, you must use the sqlj.install_jar routine. If you are not using JAR files, you copy the .class to location specified in the statement.
6.7.2.3 SQL20201N JAR name is invalid during sqlj.install_jar

Symptom
An error message is produced when trying to insert a valid JAR name.

Example
The command: call sqlj.install_jar('file:/u/db2inst3/apps/ACMESUS/ACMESUS.jar','ACMESUS'); Produced the error message: SQL20201N The install, replace or remove of "ACMES the jar name is invalid. SQLSTATE=46002

.ACMESUS" failed as

Solution
The JAR is already defined to the database. You need to remove it or replace it.

114

DB2 Java Stored Procedures: Learning by Example

6.7.2.4 SQL1000N CALL" is not a valid database alias name

Symptom
When issuing any sqlj.xxxxxx command from Windows NT, such as:
call sqlj.refresh_classes(void)

You receive the following error message:


SQL1000N "CALL" is not a valid database alias name.

Solution
This is a maintenance issue, which has been resolved in Version 7 Fixpak 1. Note that despite this message, the command actually works.
6.7.2.5 The sqlj command hangs

Symptom
The sqlj command hangs after producing .java and .ser files.

Possible Solution
Try using the -compile=false option to split the precompile step from the Java compile. Often, sqlj will complete successfully and a subsequent javac will reveal Java errors that need to be corrected in your program source.
6.7.2.6 SQLCODE -818 when executing SQLJ stored procedure

Symptom
Client receives SQLCODE -818 (timestamp mismatch error) when trying to invoke an SQLJ stored procedure on the Windows NT or AIX platform, even after the program preparation process has been completely re-run.

Possible Solution
Check the subdirectories within the SQLLIB/function directory to ensure that an old version of the .jar file containing your stored procedure code has not found its way into another directory. If this happens, DB2 may pick up the old version, generating the -818 error. Try to remove the old version using the sqlj.remove_jar command; if that fails, simply delete the culprit.

Chapter 6. Coding Java stored procedures

115

6.7.2.7 SQL4304N .. could not load Java class reason code "1"

Symptom
When trying to execute a Java stored procedure that appears to have installed correctly, the following error message returns to the client:
COM.ibm.db2.jdbc.app.DB2Exception: [IBM][CLI Driver][DB2/6000] SQL4304N Java stored procedure or user-defined function "ACMEBUS .ADD_CUSTOMER", specific name "SQL000322080850190" could not load Java class "ACMEBUS/Add_customer", reason code "1". SQLSTATE=42724

Solution
This is typically caused by forgetting to change the Java package name in the Java source code after having copied source code from one directory to another. Everything compiles and installs fine. However, during execution the stored procedure actually has a different Java package name. It is peculiar that the mismatch is not found during the javac step.
6.7.2.8 SQLCODE==> -965 SQLSTATE ==> 51021

Symptom
The system cannot find a matching method (stored procedure), even if you were able to install it in the database with no errors.
java.sql.SQLException: DB2JDBCSection Received Error in Method execute_call:SQLCODE==> -965 SQLSTATE ==> 51021 Error Tokens ==> <<DB 2/OS390 V5.1 ANSI SQLJ-0/JDBC 1.0>> QUERY_OI_SUMM java.lang.NoSuchMethodError: query_oi_summ ^20^L ^20^L ^20^L ^20^L ^20^L at COM.ibm.db2os390.sqlj.jdbc.DB2SQLJJDBCSection.setError(DB2SQLJJDBCSection. java:1049) at COM.ibm.db2os390.sqlj.jdbc.DB2SQLJJDBCSection.execute_call(DB2SQLJJDBCSect ion.java:874) at COM.ibm.db2os390.sqlj.jdbc.DB2SQLJCallableStatement.execute(DB2SQLJCallabl eStatement.java:116) at jecall_Query_oi_summ.main(jecall_Query_oi_summ.java:86)

116

DB2 Java Stored Procedures: Learning by Example

Solution
The number of parameters the client sent to DB2 does not match the number of parameters that DB2 understands the stored procedure to contain. This often is caused by forgetting to set the number of ResultSets when defining the stored procedure. This is somewhat perplexing when comparing source code against the stored procedure definition. The source code may show, for example, 5 parameters, yet the stored procedure definition shows 4. The difference is in the ResultSets value of the definition. Consequently, (the number of parameters in the source code) should equal ((the number of parameters in the stored procedure definition) + (the number of ResultSets in the stored procedure definition)).
6.7.2.9 SQLCODE==> -471 SQLSTATE ==> 55023

Symptom
The client returns an error message similar to this:
ava.sql.SQLException: DB2JDBCSection Received Error in Method execute_call:SQLCODE==> -471 SQLSTATE ==> 55023 Error Tokens ==> <<DB 2/OS390 V5.1 ANSI SQLJ-0/JDBC 1.0>> QUERY_OI_SUMM 00E79001 ^20^L at COM.ibm.db2os390.sqlj.jdbc.DB2SQLJJDBCSection.setError(DB2SQLJJDBCSection. java:1049) at COM.ibm.db2os390.sqlj.jdbc.DB2SQLJJDBCSection.execute_call(DB2SQLJJDBCSect ion.java:874) at COM.ibm.db2os390.sqlj.jdbc.DB2SQLJCallableStatement.execute(DB2SQLJCallabl eStatement.java:116) at jecall_Query_oi_summ.main(jecall_Query_oi_summ.java:86)

Solution
Recognize where the error is being seen: at the client, or when trying to invoke the stored procedure. The SQLSTATE value (the Class Code value of 55) implies that the object is not in the prerequisite state. From a stored procedure perspective, it means that a previous incarnation of the stored procedure ended badly in the database, putting it into a state that prevents it from being executed. Contact your DBA to determine the best method to make it available again.

Chapter 6. Coding Java stored procedures

117

6.7.2.10 JNI panic during db2profc

Symptom
Error message from db2profc similar to:

[IBM][SQLJ Driver] SQJ0001W Customizing profile "sscall_Add_customer_SJProfile0" JNI panic: JNI received a null class at COM.ibm.db2.sqlj.DB2SQLJInstaller.customizeProfile(DB2SQLJInstaller.j ava:263) at COM.ibm.db2.sqlj.DB2SQLJInstaller.main(DB2SQLJInstaller.java:1204) Solution
One cause may be special characters embedded within the SQL, such as newlines. Carefully replace all whitespace within the SQL (or delete the whitespace).
6.7.2.11 Cannot call a schema-qualified stored procedure

Symptom
During db2profc, an error message returns indicating that several stored procedures match the name. (However, the source code has qualified the call with a Schema). The error message looks like:

sscall_Add_customer.sqlj:76.1-79.6: Error: Unable to resolve stored procedure ACMESNS.ADD_CUSTOMER - 2 declarations match this call. Total 1 error. Solution
There may be a fix available for this error....investigate the IBM DB2 Web site for availability. Alternatively, use a unique stored procedure name that is not shared across schemas.

118

DB2 Java Stored Procedures: Learning by Example

Chapter 7. Preparing Java stored procedures


As with any programming language, there are steps required to transform the source code into something that can be executed. This chapter describes the steps required for Java stored procedure preparation.

7.1 Program preparation concepts


Preparing a Java stored procedure for DB2 requires the same basic steps regardless of the platform: 1. Translate and customize (if stored procedure uses SQLJ not required for JDBC). 2. Bind extracted SQL into DB2 packages (if stored procedure uses SQLJ not required for JDBC). 3. Compile Java. 4. Package Java .class files into correct format for deployment platform. The details of each step vary, depending upon the platform and the type of source (JDBC or SQLJ), and are described in the following sections.

7.2 OS/390 Java stored procedure preparation


As WLM-managed stored procedure address spaces do not yet support a Java Virtual Machine (JVM) environment, it is necessary to convert Java .class files into OS/390 executable modules. This is done using the IBM High Performance Java Compiler, part of VisualAge for Java Enterprise Edition for OS/390. OS/390 supports both JDBC and SQLJ stored procedures, and the preparation process for each is described in the following sections. Note that if a procedure uses both SQLJ and JDBC, the SQLJ preparation process should be used.

7.2.1 Java stored procedure and DB2 package


Assuming that your Java stored procedure accesses DB2 in some way, the program preparation process needs to produce either a DBRM or set of DBRMs that can be bound into the DB2 package for the client issuing the SQL CALL to the stored procedure.

Copyright IBM Corp. 2000

119

For JDBC stored procedures, all that is required are the 4 generic JDBC DB2 packages that are bound at the time JDBC support is installed (called DSNJDBC1, DSNJDBC2, DSNJDBC3 and DSNJDBC4). For SQLJ stored procedures, 4 application specific DB2 packages will be produced as part of the program preparation process. See 9.1, DB2 plans and packages on page 167 for a discussion on how these are used when binding client program plans.

7.2.2 DB2 authorization issues


This section describes some of the authorization issues you will need to consider, both during the program preparation process and at run time. Note that this section covers authorization issues from the stored procedure perspective only. Additional considerations apply to client authorization, and these are covered in 9.3, Client authorization issues on page 174.
7.2.2.1 SQLJ stored procedures As SQLJ stored procedures use static SQL, authorization is relatively straightforward.

Authorization checking is performed at the time the SQLJ DB2 packages for the stored procedure are bound to DB2 (see 7.2.4, OS/390 SQLJ program preparation process on page 129), and you may use any of the usual BIND parameters (such as OWNER and QUALIFIER) to achieve the security environment you need. The authorization ID binding the client plan will require EXECUTE authority on the stored procedure DB2 packages (see 9.1, DB2 plans and packages on page 167).
7.2.2.2 JDBC stored procedures As JDBC stored procedures use dynamic SQL, the authorization issues become a lot more complex.

When trying to understand the DYNAMICRULES options discussed below, you should remember that DB2 first attempts to use the option specified for the generic JDBC stored procedure DB2 packages. If DYNAMICRULES is not specified for the packages, DB2 will use the value specified in the client plan. If you do not explicitly code a value for the DYNAMICRULES option at the time you bind the JDBC generic DB2 packages (DSNJDBC1, DSNJDBC2, DSNJDBC3, and DSNJDBC4) or the client plan, then by default DB2 will use run behavior.

120

DB2 Java Stored Procedures: Learning by Example

Authorization checking for any dynamic SQL statements executed by the JDBC stored procedure will be conducted using the CURRENT SQLID of the client application (which is set to the clients primary authorization ID unless explicitly changed with a SET CURRENT SQLID statement prior to the stored procedure call). Therefore, all client authorization IDs must be given the necessary access to any tables that may be used by the stored procedure, which can be undesirable from a security and administration perspective. Use of DYNAMICRULES(BIND) when binding the JDBC generic DB2 packages or the client plan causes DB2 to use bind behavior. The authorization ID of the DB2 package owner will be used for authorization checking, which removes the requirement to give table access to each client authorization ID. Note that use of this option will prevent the stored procedure from being able to use the SQL GRANT, REVOKE, CREATE, ALTER, DROP and RENAME statements. Two new options in DB2 for OS/390 V6 provide even more flexibility, due to the implementation of stored procedure schema support. Specifying DYNAMICRULES(DEFINEBIND) when binding the JDBC generic DB2 packages or the client plan causes DB2 to use define behavior. The authorization ID of the owner (or schema) of the stored procedure will be used for authorization checking. This allows a number of alternative security strategies to be considered (for example, you could create the stored procedure in the same schema as your DB2 tables, which would implicitly give the stored procedure access to any tables in that schema).
DYNAMICRULES(DEFINERUN)

For stored procedure DB2 packages, use of the DYNAMICRULES(DEFINERUN) option is equivalent to DYNAMICRULES(DEFINEBIND). Specifying DYNAMICRULES(INVOKEBIND) when binding the JDBC generic DB2 packages or the client plan causes DB2 to use invoke behavior. If the CURRENT SQLID is set to the primary authorization ID of the client process at the time of the stored procedure call, both the primary authorization ID and all secondary authorization IDs are used for authorization checking. Otherwise, just the CURRENT SQLID is used.

Chapter 7. Preparing Java stored procedures

121

DYNAMICRULES(INVOKERUN)

For stored procedure DB2 packages, use of the DYNAMICRULES(INVOKERUN) option is equivalent to DYNAMICRULES(INVOKEBIND). For a full explanation of the DYNAMICRULES BIND option, refer to DB2 UDB for OS/390 Command Reference , SC26-9006.

7.2.3 OS/390 JDBC program preparation process


If the source contains JDBC statements, the program preparation process is as shown in Figure 14.

Source

Java Bytecode
Other CLASS files

4
CREATE PROCEDURE or INSERT into SYSPROCEDURES

prog.JAVA

Java Compiler (JAVAC)


3

prog.CLASS

JAR HPJ Compiler

DB2 Catalog .JAR file

External Link

JLL in PDSE

Optional Step

Can run on any JDK platform Run on S/390 platform

Figure 14. OS/390 JDBC program preparation process

1. From within USS, Java-compile the source code (using the javac command). This produces one or more .class files, which represent the Java bytecode for your procedure. 2. If you wish, you may package multiple .class files into a single .jar file via the jar command. This step is entirely optional, and as we are already packaging multiple .class files into a single OS/390 executable in the HPJ step next anyway, we elected to omit it.

122

DB2 Java Stored Procedures: Learning by Example

3. HPJ-compile the .class files produced in step 2 to create an OS/390 Java DLL. This module resides in a PDSE data set, but HPJ also creates an external link to the module, to allow it to be referenced from within the USS environment. 4. Define the stored procedure to DB2 (via an INSERT into SYSIBM.SYSPROCEDURES for DB2 for OS/390 V5, or via CREATE PROCEDURE if you are using DB2 UDB for OS/390 V6). Unlike DB2 UDB for UNIX and DB2 UDB for Windows NT, DB2 for OS/390 allows you to perform this step before the stored procedure exists.
Use of COLLID

We recommend that you explicitly specify the DB2 package collection that your stored procedure DB2 packages will reside in. For JDBC stored procedures, you will specify the DB2 package collection that the 4 generic JDBC packages belong to (these generic packages will have been created when JDBC support was installed, using the db2genJDBC utility - see JDBC Support on page 59). The way in which you can accomplish this depends upon the release of DB2 UDB for OS/390 you are using: - For DB2 UDB for OS/390 V5, you can provide a value for the COLLID column when performing the INSERT into SYSIBM.SYSPROCEDURES. - For DB2 UDB for OS/390 V6, you can specify the COLLID keyword on the CREATE PROCEDURE statement. If you do not do this, you will be forced to bind the 4 JDBC DBRMs into DB2 packages belonging to the same collection as the clients DB2 package. See 9.1, DB2 plans and packages on page 167 for more details).

Development platform

Steps 1 and 2 of this process can be performed on any platform that contains a suitable JDK. We performed them within UNIX Systems Services (USS) within an S/390 environment. Steps 3 and 4 must be performed on the S/390 platform.

Chapter 7. Preparing Java stored procedures

123

7.2.3.1 OS/390 JDBC detailed preparation example The example JDBC stored procedure has been coded with this Java package statement:
package ACMEJOS;

Java package statement

The use of package statements is obligatory on the S/390 platform. To build this program, go up one directory from the source. For example, if your source was in /U/DB2RES3/ACMEJOS/Add_customer.java, then you change directory to /U/DB2RES3 to execute the build statements. Start by compiling your Java source using the javac Java command, as follows:
javac ACMEJOS/Add_customer.java

The resulting .class files are placed in the ACMEJOS subdirectory. Next, you need to perform the HPJ compile. Here is the command as we used:
hpj -o "//'SG245945.HPJSP.PDSE(ACMEJOS)'" -alias ACMEJOS.jll -O -jll -nofollow -t /u/sysadm/links ACMEJOS/Add_customer >hpj.map 2>&1 \ \ \ \ \ \ \

Refer to the VisualAge for Java Version 2.0 ET/390 Reference for a full explanation of the hpj command parameters. Here is a brief description of the main ones used in the command above: -o specifies the output PDSE data set that will contain the OS/390 executable. This data set must be allocated to your WLM address space (see JCL procedure sample shown in 4.1.6.2, JCL procedure of a Java WLM-established address space on page 67). -alias specifies the name of the alias to be created in the output PDSE data set. This must correspond with the Java package name within your stored procedure code.

124

DB2 Java Stored Procedures: Learning by Example

-t specifies the name of the USS directory used to store links to the PDS data set. Upon completion of the compile, you should have an OS/390 executable and alias within your PDSE data set, and a link to the executable within your USS links library. For an overview of the runtime environment for an SQLJ stored procedure, see Figure 13 on page 95. If you have not done so already, you now need to define your stored procedure to DB2. The location of your stored procedure is specified using the format <package>.<class>.<method>, where <package> is the Java package name, and <class> and <method> are the class and method names defined in your code. DB2 for OS/390 Version 5 requires you to manually insert a row into SYSIBM.SYSPROCEDURES:
INSERT INTO SYSIBM.SYSPROCEDURES (PROCEDURE,AUTHID,LUNAME,LOADMOD,LINKAGE,COLLID, LANGUAGE,ASUTIME,STAYRESIDENT,IBMREQD, RUNOPTS, PARMLIST, RESULT_SETS,WLM_ENV,PGM_TYPE, EXTERNAL_SECURITY,COMMIT_ON_RETURN) VALUES( 'JS_ADD_CUSTOMER', '', '', '', 'N', 'DSNJDBC', 'COMPJAVA', 900, '','N', 'ACMEJOS/Add_customer.add_customer', 'CHAR(20) IN, CHAR(20) IN, CHAR(30) IN, INTEGER OUT, CHAR(40) OUT, CHAR(240) OUT', 0,'WLM_JAVA_DB21','S','N','N' );

Note

For DB2 for OS/390 Version 5, the RUNOPTS column of SYSPROCEDURES is used to store the procedure name, and the LOADMOD column is ignored. This is due to the fact that LOADMOD can only hold 8 characters. DB2 UDB for OS/390 Version 6 provides full DDL and schema support for stored procedures, so the equivalent command would be as follows:
CREATE PROCEDURE ACMEJOE.ADD_CUSTOMER ( IN FIRSTNAME CHAR(20), IN LASTNAME CHAR(20), IN ADDRESS CHAR(30), OUT CUSTNO INTEGER,

Chapter 7. Preparing Java stored procedures

125

OUT MARK CHAR(40) OUT MARK_ERROR_TEXT CHAR(200) ) FENCED MODIFIES SQL DATA LANGUAGE COMPJAVA EXTERNAL NAME(ACMEJOE.Add_customer.add_customer) PARAMETER STYLE JAVA COLLID DSNJDBC WLM ENVIRONMENT DBS1JAVAWLM DYNAMIC RESULT SETS 0 PROGRAM TYPE SUB;

Use of COLLID

In the example above, we have specified a DB2 package collection of DSNJDBC for the JDBC stored procedure. This is the name of the collection we bound the 4 generic JDBC DBRMs into at the time JDBC support was installed. See JDBC Support on page 59 for further details. The stored procedure is now ready for execution.
7.2.3.2 Sample program preparation scripts We used the scripts below for JDBC program preparation. Note: These scripts can be found on the CD-ROM, in the SAMPLES\S390 UTILITIES\PROGRAM PREPARATION directory. Refer to Appendix E, Using the

additional material on page 347 for more information. The entire process is invoked from the USS command line using a syntax such as:
javaspj Add_customer ACMEJOS ACMEJOS acmes ACMEJOS

This can be found in script driver_josj.

Script javaspj prepare JDBC stored procedure This script performs the main program preparation tasks, and calls script hpjsp to perform the HPJ compile.
# JDBC stored procedure with no SQLJ # phase 1 javac # phase 2 hpj # # Call format for shell is => javaspj pgm pkg mem qualifier pdsemem

126

DB2 Java Stored Procedures: Learning by Example

# Example => javaspj $1 $2 $3 $4 # $1= Java class name # $2= Java package name # << $3 Not used for JDBC only >> # $3= Member package name used for binds - limit 7 # $4= Table qualifier # $5= OS/390 PDSE member name - uppercase limit 8 # pgm=$1 # pgm is the Java class name. # pkg=$2 # pkg is the used for the SP package collection, JAVA package, # directory where the JAVA code is. # mem=$3 # Member package name used for binds - limit to 7 characters # qual=$4 # qual is the table qualifier pdse=$5 # pdse is the OS/390 PDSE member name - uppercase limit to 8 characters # # set directory to Java code #cd $pkg #pgmuln=$1'_SJProfile0' #echo $pgmuln echo "Starting phase 1 - JDBC javac for" $pkg $pgm javac $pkg/${pgm}.java echo "Starting phase 2 - JDBC hpj compile" hpjsp $pkg $pdse # echo "JDBC build for" $pkg $pgm "complete"

Chapter 7. Preparing Java stored procedures

127

Script hpjsp perform HPJ compile This script executes the HPJ compile process, to create an OS/390 executable module from the Java classes.
echo "Starting hpj for $1 $2" U2=`echo $2 | tr 'a-z' 'A-Z'` echo "current dir is `pwd`" echo "building member in SG245945.HPJSP.$SSID.PDSE($U2)" echo "building links in /u/$SSID/links" CLASSES_TO_USE=`ls $1/*.class | sed 's/.class//'` echo "using classes $CLASSES_TO_USE " # -classpath .:/usr/lpp/hpj/lib/classes.zip \ hpj -o "//'SG245945.HPJSP.$SSID.PDSE($U2)'" \ -alias $1.jll \ -O \ -jll \ -nofollow \ -t /u/$SSID/links \ $CLASSES_TO_USE \ >hpj$1.map 2>&1 echo 'Ended hpj for ' $1 $2 ' - results' more hpj$1.map

128

DB2 Java Stored Procedures: Learning by Example

7.2.4 OS/390 SQLJ program preparation process


If your Java stored procedure was written using SQLJ, or a combination of SQLJ and JDBC, the program preparation process is somewhat more complex, as shown in Figure 15.

SQLJ Source

prog.JAVA prog.SQLJ

SQLJ Translator

Java Compiler (JAVAC)

prog.CLASS

Other CLASS files

Profile Customiser (DB2PROFC)

prog_ SJProfileKeys.class

JAR

prog_ SJProfile0.ser

Serialized Profile
DBRM DBRM

HPJ Compiler

.JAR file

Optional Step

DB2 BIND PACKAGE

External Link

JLL in PDSE
7
CREATE PROCEDURE or INSERT into SYSPROCEDURES

Can run on any JDK platform Run on S/390 platform

DB2 Catalog

Figure 15. OS/390 SQLJ program preparation process

1. From USS, translate your source code using the sqlj command. This will extract all of the embedded SQL from your code and place it in an SQLJ serialized profile (a kind of generic, database independent DBRM). Serialized profiles are stored in .ser files. Your source code will be modified, and placed in a .java file. 2. Java-compile the source code (using the javac command). This will produce at least two .class files one containing your code and one containing the SQLJ access stub.

Chapter 7. Preparing Java stored procedures

129

Note

Unless you specifically request otherwise by specifying the


-compile=false option, javac will be automatically executed by sqlj and

there is no need to perform this step separately. 3. If you wish, you may package multiple .class (or .jar) files into a single .jar file via the jar command. This step is entirely optional, and as we are already packaging multiple .class files into a single OS/390 executable in the HPJ step next anyway, we elected to omit it. 4. HPJ-compile the .class files produced in step 2 to create an OS/390 executable module. This module resides in a PDSE data set, but HPJ also creates an external link to the module, to allow it to be referenced from within the USS environment. 5. Execute the DB2 profile customizer using the db2profc command. This translates the generic serialized profile created in step 1 into a set of 4 DB2 for OS/390 DBRMs (one for each type of isolation level: repeatable read, read stability, cursor stability and uncommitted read). 6. Bind the 4 DBRMs produced by db2profc into DB2 packages using standard DB2 for OS/390 BIND PACKAGE commands. The DB2 packages can belong to any DB2 package collection - in our examples we named the DB2 package collection after the Java package name. 7. Define the stored procedure to DB2 (via an INSERT into SYSIBM.SYSPROCEDURES for DB2 for OS/390 V5, or via CREATE PROCEDURE if you are using DB2 UDB for OS/390 V6).

130

DB2 Java Stored Procedures: Learning by Example

Use of COLLID

We recommend that you explicitly specify the DB2 package collection that your stored procedure DB2 packages will reside in. For SQLJ stored procedures, you will specify the DB2 package collection that you bound your 4 application specific DBRMs into earlier. The way in which you can accomplish this depends upon the release of DB2 UDB for OS/390 you are using; - For DB2 UDB for OS/390 V5, you can provide a value for the COLLID column when performing the INSERT into SYSIBM.SYSPROCEDURES. - For DB2 UDB for OS/390 V6, you can specify the COLLID keyword on the CREATE PROCEDURE statement. If you do not do this, you will be forced to bind the 4 SQLJ DBRMs into DB2 packages belonging to the same collection as the clients DB2 package. See 9.1, DB2 plans and packages on page 167 for more details).

Development platform

Steps 1 to 3 of this process can be done on any platform that contains a suitable JDK. We performed them within UNIX Systems Services (USS) in an S/390 environment. Steps 4 to 7 must be performed on the S/390.
7.2.4.1 OS/390 SQLJ detailed preparation example The SQLJ stored procedure has been coded with this Java package statement:
package ACMESOS;

The Java package statement

The use of package statements is obligatory on the S/390 platform. To build this program, go up one directory from the source. For example, if your source was in /U/DB2RES3/ACMESOS/Add_customer.java, then you change directory to /U/DB2RES3 to execute the build statements. Start by precompiling your SQLJ source program using the sqlj command, as follows:

Chapter 7. Preparing Java stored procedures

131

sqlj ACMESOS/Add_customer.sqlj

Use of SQLJ command

Due to an oddity in our environment, we were forced to fully qualify the location of the sqlj routine in order to get it to work with SQLJ source files that were located in subdirectories. The command we used was:
/usr/lpp/db2/db2510/bin/sqlj ACMESOS/Add_customer.sqlj

This can be made more generic by using the whence command to return the location of sqlj in your environment, like this:
`whence sqlj` $pkg/$pgm.sqlj

This is the command that appears in our sample preparation scripts. By default, sqlj will also invoke javac (the Java compiler) to save you from having to do this separately afterwards (to disable this and run javac yourself, use the -compile=false option). Assuming that you elected to automatically run javac as part of sqlj, the output of the command will be: A .java file containing a modified version of your source. As this will be immediately input to javac to produce .class files, the .java file plays no further part in the program preparation process and may be considered an intermediate temporary file. At least two Java .class files (one for your stored procedure code and one, called <classname>_SJProfileKeys.class, for the SQLJ stub). A serialized profile, called <classname>_SJProfile0.ser. This contains the SQL statements extracted by the sqlj process, in a generic database independent format. Next, we need to perform the HPJ compile. Here is the command we used during our tests:
hpj -o "//'SG245945.HPJSP.PDSE(ACMESOS)'" -alias ACMESOS.jll -O -jll -nofollow -t /u/sysadm/links ACMESOS/Add_customer ACMESOS/Add_customer_SJProfileKeys >hpj.map 2>&1 \ \ \ \ \ \ \ \

132

DB2 Java Stored Procedures: Learning by Example

Refer to the VisualAge for Java Version 2.0 ET/390 Reference1, for a full explanation of the hpj command parameters. Here is a brief description of the main ones used in the commands above: -o specifies the output PDSE data set that will contain the OS/390 executable. This data set must be allocated to your WLM address space (see JCL procedure sample shown in 4.1.6.2, JCL procedure of a Java WLM-established address space on page 67). -alias specifies the name of the alias to be created in the output PDSE data set. This must correspond with the Java package name within your stored procedure code. -t specifies the name of the USS directory used to store links to the PDS data set.
Including the correct class files

You need to include all of the .class files produced by the sqlj step in the hpj compile, including the <classname>_SJProfileKeys.class stub. Upon completion of the compile, you should have an OS/390 executable and alias within your PDSE data set, and a link to the executable within your USS links library. For an overview of the runtime environment for an SQLJ stored procedure, see Figure 13 on page 95. Next, you need to execute db2profc, which takes the serialized profile created by sqlj above and creates four DB2 for OS/390 DBRMs. Below is an example of how to invoke the db2proc:
db2profc -pgmname=ACMESOS ACMESOS/Add_customer_SJProfile0.ser

In our example, the DBRMs that would be generated are called ACMESOS1, ACMESOS2, ACMESOS3 and ACMESOS4.These DBRMS are used to represent the different isolation levels that could be used (UR, CS, RS and RR for ACMESOS1 to 4 respectively). The DBRMs will be placed in the PDS specified in the DB2SQLJDBRMLIB parameter of your SQLJ properties data set (see 4.1.8, Step 6: Set up the JAVAENV data set on page 69). In the examples below, the PDS is
SG246945.SAMPLIB.DBRM.

Now we have our DBRMs, we can BIND them. The DB2 packages we bind can belong to any DB2 package collection. In our example we are using a DB2
At the time of writing, the ET/390 manuals did not have formal IBM publication numbers. However, they can be downloaded from the Web in PDF format at http://www-4.ibm.com/software/ad/vajava/library.htm.
1

Chapter 7. Preparing Java stored procedures

133

package collection named after the Java package referenced in our stored procedure:
BIND PACKAGE(ACMESOS) MEMBER(ACMESOS1) ACT(REP) ISOLATION(UR) VALIDATE(BIND) LIBRARY('SG246945.SAMPLIB.DBRM') QUALIFIER(ACMES) BIND PACKAGE(ACMESOS) MEMBER(ACMESOS2) ACT(REP) ISOLATION(CS) VALIDATE(BIND) LIBRARY('SG246945.SAMPLIB.DBRM') QUALIFIER(ACMES) BIND PACKAGE(ACMESOS) MEMBER(ACMESOS3) ACT(REP) ISOLATION(RS) VALIDATE(BIND) LIBRARY('SG246945.SAMPLIB.DBRM') QUALIFIER(ACMES) BIND PACKAGE(ACMESOS) MEMBER(ACMESOS4) ACT(REP) ISOLATION(RR) VALIDATE(BIND) LIBRARY('SG246945.SAMPLIB.DBRM') QUALIFIER(ACMES)

If you have not done so already, you now need to define your stored procedure to DB2. The location of your stored procedure is specified using the format <package>.<class>.<method>, where <package> is the Java package name, and <class> and <method> are the class and method names defined in your code. DB2 for OS/390 Version 5 requires you to manually insert a row into
SYSIBM.SYSPROCEDURES; INSERT INTO SYSIBM.SYSPROCEDURES (PROCEDURE,AUTHID,LUNAME,LOADMOD,LINKAGE,COLLID, LANGUAGE,ASUTIME,STAYRESIDENT,IBMREQD,

134

DB2 Java Stored Procedures: Learning by Example

RUNOPTS, PARMLIST, RESULT_SETS,WLM_ENV,PGM_TYPE, EXTERNAL_SECURITY,COMMIT_ON_RETURN) VALUES( 'SS_ADD_CUSTOMER', '', '', '', 'N', 'ACMESOS', 'COMPJAVA', 900, '','N', 'ACMESOS/Add_customer.add_customer', 'CHAR(20) IN, CHAR(20) IN, CHAR(30) IN, INTEGER OUT, CHAR(40) OUT, CHAR(240) OUT', 0,'WLM_JAVA_DB21','S','N','N' );

Note

For DB2 for OS/390 Version 5, the RUNOPTS column of SYSPROCEDURES is used to store the procedure name. This is due to the fact that the LOADMOD column can only hold 8 characters. DB2 UDB for OS/390 Version 6 provides full DDL and schema support for stored procedures, so the equivalent command would be as follows:
CREATE PROCEDURE ACMESOE.ADD_CUSTOMER ( IN FIRSTNAME CHAR(20), IN LASTNAME CHAR(20), IN ADDRESS CHAR(30), OUT CUSTNO INTEGER, OUT MARK CHAR(40) OUT MARK_ERROR_TEXT CHAR(200) ) FENCED MODIFIES SQL DATA LANGUAGE COMPJAVA EXTERNAL NAME(ACMEJOE.Add_customer.add_customer) PARAMETER STYLE JAVA COLLID ACMESOS WLM ENVIRONMENT DBS1_JAVA_WLM DYNAMIC RESULT SETS 0 PROGRAM TYPE SUB;

The stored procedure is now ready for execution.


7.2.4.2 Sample program preparation scripts We used the scripts below for SQLJ program preparation. These scripts can be found on the CD-ROM, in the SAMPLES\S390 UTILITIES\PROGRAM PREPARATION

Chapter 7. Preparing Java stored procedures

135

directory. Refer to Appendix E, Using the additional material on page 347 for more information. The entire process is invoked from the USS command line using a syntax such as:
javasp Add_customer ACMESOS addcust acmes ACMESOS

This can be found in script driver_sos.

Script javasp prepare SQLJ stored procedure This script performs the main program preparation tasks, and calls scripts hpjsp to perform the HPJ compile and bindsp to create and execute the necessary BIND statements.
# java stored procedure with SQL # phase 1 SQLJ translator # phase 2 db2profc create DBRMs # phase 3 HPJ compile # phase 4 bind packages # phase 5 copy *.ser files # # Call format for shell is => javasp nam pkg mem qualifier pdsemem # Example => javasp $1 $2 $3 $4 # $1= Java class name # $2= Java package name # $3= Member package name used for binds - limit 7 # $4= Table qualifier # $5= OS/390 PDSE member name - uppercase limit 8 # pgm=$1 # pgm is the Java class name. pkg=$2 # pkg is the used for the SP package collection, JAVA package, # directory where the JAVA code is, HPJ module name and DB2 package # collection name mem=$3 # mem package name used for binds - limit to 7 characters qual=$4 # qual is the table qualifier pdse=$5 # pdse is the OS/390 PDSE member name - uppercase limit to 8 characters # pgmuln=$1'_SJProfile0' echo $pgmuln echo "Starting phase 1 - SQLJ translator" $pkg $pgm

136

DB2 Java Stored Procedures: Learning by Example

`whence sqlj` $pkg/$pgm.sqlj echo "Starting phase 2 db2profc -pgmname=$mem echo "Starting phase 3 hpjsp $pkg $pdse # echo "Starting phase 4 - db2profc" $pkg/$pgmuln.ser - HPJ compile"

- bind plans"

bindsp.rexx $mem $pkg $qual umem=`echo $mem | tr 'a-z' 'A-Z'` cat bind$SSID$umem.out | sed 's/ *$//' # # copy *.ser files to /u/$SSID/ser # echo "Starting phase 5 - copying *.ser files to /u/$SSID/ser" cp $pkg/*.ser /u/$SSID/ser/$pkg chmod 777 /u/$SSID/ser/$pkg/* echo "Build for" $pkg $pgm "complete"

Script hpjsp perform HPJ compile See Script hpjsp perform HPJ compile on page 128. Script bindsp.rexx generate/execute BIND PACKAGE commands This script builds the bind statements and passed them to the TSO REXX exec OEBIND.
/* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* rexx Unix System Services (USS) bindsp.rexx MEM PKG qual called by JAVA prep shell scripts to bind the stored procedure packages. */ */ */ */ */ Licensed Materials - Property of IBM */ */ (C) COPYRIGHT International Business Machines Corp. 1995, 1997 */ All Rights Reserved. */ */ US Government Users Restricted Rights - Use, duplication or */ disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ Written 03/05/200 by Michael J. Fischer */ */ Input parms: 3 */ MEM package base name */

Chapter 7. Preparing Java stored procedures

137

/* /* /* /* /* /* /* /* /* /* /* /* /* /*

name) */ unqualified tables. */ PDSE library */ */ unqualified tables. */ */ Calls TSOE rexx program "OEBIND" to run DSN in TSOE */ environment. This was done so the JAVA prep shell scripts */ can run in the OMVS or telnet environment. DSN will not run */ under telnet. */ */ To display help enter bindsp.rexx ? or bindsp.rexx '?' */ */ Note: In USS the ? is converted to a 2 */

PKG qual MEM PKG qual

Collection name (java Package Table qualifier name used for DBRM member name used for the Package name for bind. Table qualifier name used for

arg MEM PKG qual if MEM = "?" | MEM = 2 then do do i = 1 while substr(sourceline(i),1,2) = "/*" say sourceline(i) end return 0 end if length(MEM) > 7 then do say "ERROR**** Package base name must be 7 characters or less" say "Unable to create BIND statements" return 999 end x=0 /* Find the DB2SQLJPROPERTIES environment variable and set it. */ /* If no DB2SQLJPROPERTIES variable set then default to */ /* db2sqljjdbc.properties in working directory */ do I = 1 to __environment.0 if substr(__environment.i,1,17) = 'DB2SQLJPROPERTIES' then do DB2SQLJPROPERTIES = substr(__environment.i,19,length(__environment.i)-18) x=1 end if substr(__environment.i,1,5) = 'TERM=' then do termenv = substr(__environment.i,6,length(__environment.i)-5) end end if x=0 then DB2SQLJPROPERTIES = 'db2sqljjdbc.properties' /* Pick up the DB2 subsystem ID and DBRMLIB to use for the Binds */

138

DB2 Java Stored Procedures: Learning by Example

/* from the DB2SQLJPROPERTIES file. address syscall "readfile (DB2SQLJPROPERTIES) file." if retval < 0 then do say "ERROR*** The" DB2SQLJPROPERTIES "file does not exist" say "Unable to create BIND statements" return 999 end else do i = 1 to file.0 if substr(file.i,8,4) = 'SSID' then ssid = substr(file.i,13,length(file.i)-12) if substr(file.i,8,7) = 'DBRMLIB' then dbrmlib = substr(file.i,16,length(file.i)-15) if substr(file.i,8,8) = 'PLANNAME' then planname = substr(file.i,17,length(file.i)-16) end /* /* Build the BIND statements and save them in file BINDssidINPUT /*

*/

*/ */ */

say '****** NOTE: ******' say 'If this JAVA SP is called by a JAVA USS client make sure' say 'collection' PKG||'.* is in PLAN' planname '. If this collection' say 'is new to this plan, rebind it after adding collection.' say '*******************' b.0 = 5 b.1 ="BIND PACKAGE("PKG") MEMBER("MEM"1) ACT(REP) (BIND) LIBRARY('"DBRMLIB"') QUALIFIER("QUAL")" b.2 ="BIND PACKAGE("PKG") MEMBER("MEM"2) ACT(REP) (BIND) LIBRARY('"DBRMLIB"') QUALIFIER("QUAL")" b.3 ="BIND PACKAGE("PKG") MEMBER("MEM"3) ACT(REP) (BIND) LIBRARY('"DBRMLIB"') QUALIFIER("QUAL")" b.4 ="BIND PACKAGE("PKG") MEMBER("MEM"4) ACT(REP) (BIND) LIBRARY('"DBRMLIB"') QUALIFIER("QUAL")" b.5 ="END" input = "BIND"||ssid||"INPUT" address syscall "writefile ("||input||") 777 b." if retval=-1 then do "error*** writing bind input file" input return 999 end address syscall "getcwd cwd"

ISOLATION(UR) VALIDATE ISOLATION(CS) VALIDATE ISOLATION(RS) VALIDATE ISOLATION(RR) VALIDATE

Chapter 7. Preparing Java stored procedures

139

if retval=-1 then do "error*** getting current directory to save" return 999 end /* /* Call DSN on the tsoe os/390 to run. /* if termenv = 'vt100' then /* telnet "tso -t oebind" ssid cwd input mem else "tso oebind" ssid cwd input mem */ */ */ */

/* /* Remove input file with BIND statements in /* "rm" input /* /* make sure the directory exist for ser files in /u/ssid/ser/ /* address syscall "chdir /u/"ssid"/ser/"pkg if retval=-1 then do "chdir /u/"ssid"/ser/" if retval=-1 then do say "error*** getting directory /u/"ssid"/ser" return 999 end "mkdir" pkg 777 if retval=-1 then do say "error*** making directory /u/"ssid"/ser/"pkg return 999 end end /* reset current directory "chdir" cwd if retval=-1 then do say "error*** reseting directory" cwd "to current" return 999 end RETURN

*/ */ */

*/ */ */

*/

REXX exec OEBIND The REXX exec executes the BIND statements and send the bind output back to the USS HFS.

140

DB2 Java Stored Procedures: Learning by Example

/* rexx TSOE BIND ssid path input */ /* */ /* Called from Unix System Services (USS) rexx programs "bindsp.rexx"*/ /* and 'bindcl_plan.rexx that built the BIND statements for the */ /* JAVA client or stored procedure programs. */ /* */ /* Licensed Materials - Property of IBM */ /* */ /* (C) COPYRIGHT International Business Machines Corp. 1995, 1997 */ /* All Rights Reserved. */ /* */ /* US Government Users Restricted Rights - Use, duplication or */ /* disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ /* Written 03/05/200 by Michael J. Fischer */ /* */ /* Input parms: 3 */ /* ssid DB2 subsystem group or member name. */ /* path USS HFS path name to store output file to. */ /* input USS HFS path and file name for BIND input file. */ /* pkg Java package name */ /* */ /* This REXX program will read the HFS file of BIND statements */ /* and put them to the REXX stack. It will then start the DB2 */ /* "DSN" program for the subsystem passed to process the Bind */ /* statements from the REXX stack. It will trap the output from */ /* the BINDs and copy them to a HFS file back on USS */ /* */ /* To call this REXX exec from OS/390 Unix System Services running*/ /* telnet, add the following statements to your .profile. */ /* */ /* .profile */ /* ##### Added for tso -t from telnet */ /* # Assign the DD names to allocate */ /* # */ /* export TSOALLOC=sysexec */ /* # */ /* # Allocate the OpenMVS EXEC data set to SYSEXEC */ /* # */ /* export sysexec=SYS1.OS390.EXEC <== library where you stored */ /* # this exec. */ /* */ /* For help enter: OEBIND ? or OEBND '?' */ parse arg ssid path input pkg . if ssid = "?" | ssid = "'?'" then do do i = 1 while substr(sourceline(i),1,2) = "/*" say sourceline(i)

Chapter 7. Preparing Java stored procedures

141

end return 0 end l='abcdefghijklmnopqrstuvwxyz' u='ABCDEFGHIJKLMNOPQRSTUVWXYZ' ssid = translate(ssid,u,l) say "SSID is " ssid patho = "'"||path||"/bind"||ssid||pkg||".out'" input = "'"||path||"/"||input||"'" /* allocate bind output file "alloc fi(bindout) da(dsn.bindout) unit(sysallda) new reuse, space(16,16) tracks recfm(f,b) lrecl(131) blksize(13100)" /* allocate bind input file to copy bind statements to "alloc fi(bindin) da(dsn.bindin) unit(sysallda) new reuse, space(1,1) tracks recfm(v,b) lrecl(1024) blksize(13100)" /* allocate bind input hfs file with bind statements in 'alloc ddname(hfsin) path('input') pathopts(ordwr,ocreat)', 'pathmode(sirusr,siwusr)' 'ocopy indd(hfsin) outdd(bindin) text convert(no)' 'free fi(hfsin)' (STEM in. FINIS" */

*/

*/

"execio * diskr bindin do i = 1 to in.0 queue in.i end

/* turn on outtrap to capture bind output statements from DSN x = OUTTRAP('VAR.') "DSN SYSTEM("ssid")" y = OUTTRAP('OFF') /*write bind output statement to a file to copy to hfs file "EXECIO" var.0" DISKW bindout (STEM var. FINIS" /* allocate bind output hfs file for bind 'alloc ddname(hfsout) path('patho') pathopts(ordwr,ocreat)', 'pathmode(sirusr,siwusr)'

*/

*/

*/

142

DB2 Java Stored Procedures: Learning by Example

/* copy bind output to hfs file from bind run */'ocopy indd(bindout) outdd(hfsout) text convert(no)' 'free fi(hfsout)'

'delete dsn.bindout' 'delete dsn.bindin' return 0

7.2.5 Using UNIX System Services (USS)


The Java programs must be prepared in UNIX System Services (USS), which is the UNIX variation of OS/390. It was formerly known as OpenEdition; sometimes the OE can be seen associated with USS, as can be seen on the URL for the main USS Web site:
http://s390.ibm.com/oe/

7.2.5.1 If you are OS/390 fluent If you are fluent in OS/390, you may need to learn a minimum set of UNIX commands. The technical investigation for this book was completed by two people fluent in OS/390 and one person fluent in UNIX. The OS/390 people were able to do most of their work with the following set of UNIX commands:

cd pwd ls oedit omvs whence env more cat chmod

Also necessary is an understanding of environment variables such as CLASSPATH and how they are set in .profile.. More information about using these and other USS commands can be found in the OS/390 UNIX System Users Guide, SC28-1891. Alternatively, the early adaptors in your organization will have opportunities to develop mechanizations to hide UNIX from pure OS/390 devotees.

Chapter 7. Preparing Java stored procedures

143

7.2.5.2 If you are UNIX fluent If you are UNIX fluent and are being asked to work on USS to access OS/390 DB2, most of your UNIX skillset will transfer immediately. The messages may look a little different, but for the most part it behaves like any other UNIX. You will be able to telnet or login into USS to use your favorite editor vi.

Your biggest difficulty may consist of those commands that must execute on OS/390. DSN was a major stumbling block for our group, requiring the construction of an extensive Kshell and Rexx procedure. The early adaptors in your organization will have opportunities to develop mechanizations to hide OS/390 from pure UNIX devotees.

7.3 NT / AIX Java stored procedure preparation


A DB2 UDB for UNIX, Windows, or OS/2 Java stored procedure can be either JDBC or SQLJ. These have different preparation procedures. When a stored procedure mixes both, it goes through the SQLJ process.
Note

The examples used in this section are for the Windows NT platform. Some minor changes (for example, the use of forward slashes (/) instead of back slashes (\) for directory names) will need to be made for the AIX platform.

7.3.1 NT / AIX JDBC program preparation process


If the source consists of JDBC statements, the program preparation for a stored procedure consists the steps shown in Figure 16.2

2 From a programmers perspective, all work and all statements can be executed on a personal workstation. The define of the procedure, the install of the JAR, and so on, can be executed through a connection to a remote database. The one hitch is that the install and replace JAR routines require the JAR file to reside on the remote server.

144

DB2 Java Stored Procedures: Learning by Example

Source

Java Bytecode

prog.JAVA

Java Compiler (JAVAC)

prog.CLASS

Other CLASS files


2

JAR
3

package.JAR
JAR File in sqllib/function

SQLJ.INSTALL_JAR
package.JAR

JAR File
Can run on any JDK platform

CREATE PROCEDURE

DB2 Catalog

Run on NT or AIX deployment platform

Figure 16. AIX and Windows NT JDBC program preparation process

1. Java Compile the source code (using the javac command). This produces one or more .class files, which represent the Java bytecode for your procedure. 2. Package the class file(s) produced in the previous into a single .jar file via the jar command. This step is mandatory for applications using the Java package statement. 3 3. Install the JAR file in the database using the sqlj.install_jar command. This provides a DB2 name for the JAR file, enters details of the classes contained within it to the SYSIBM.SYSJARCONTENTS catalog table, and copies the file to a standard location so that DB2 is able to access it at run time. 4. Define the stored procedure to DB2 using the CREATE PROCEDURE statement. Note that the stored procedure cannot be defined until its associated JAR file exists.

It is possible to avoid use of JAR files by leaving out the package statement in the JAVA source. The resulting class files are copied directly to the <DB2>/sqllib/function directory, as seen in the examples shipped with the database. However, as discussed earlier in Chapter 5, Designing Java stored procedures on page 83, this creates a flat namespace that may cause conflicts between different applications. We recommend using JAVA packages and JARs to segregate applications.

Chapter 7. Preparing Java stored procedures

145

A word about JAR files

DB2 UDB for UNIX, Windows, OS/2 is very particular about the order in which these steps are conducted when it comes to JAR files. For example, it will not allow a procedure to be created until it exists in the referenced JAR file, or allow you to remove or refresh a JAR file while procedures are defined that refer to it. We found that the safest way to go about performing steps 3 and 4 above was to do the following; 1. Drop all procedures in the Java package via the SQL DROP PROCEDURE statement. 2. Call sqlj.remove_jar followed by sqlj.install_jar to re-install the JAR file in the correct location. 3. Re-create the procedures via the SQL CREATE PROCEDURE statement. This is the process that is used in our sample code. The process can be reliably rerun when re-preparing amended procedures. However, as all procedures in a given Java package have to be placed in the same JAR file, using this process means that you have to build the Java package gradually, procedure by procedure, in order to satisfy DB2s many consistency checks. For example, lets assume that we want to produce two procedures called
Add_customer and Add_order in a Java package called ACMEJNE.

We write the first procedure, Add_customer, and go through the SQLJ program preparation process. Using the steps above we first drop the procedure (which will not yet exist), remove the JAR definition (which will not exist), install the JAR (which should work) and then define the Add_customer procedure to DB2 via SQL CREATE PROCEDURE statement. When we write the second procedure, Add_order, we will need to drop both procedures, remove and re-install the JAR definition, and then define both procedures to DB2. If we try to perform the steps in any other order, or if we try to create the Add_order procedure before there is a definition for it within the JAR file, the process will fail.

146

DB2 Java Stored Procedures: Learning by Example

7.3.1.1 NT / AIX JDBC preparation example In the DB2 UDB for UNIX, Windows, or OS/2 JDBC detailed preparation example, the JDBC stored procedure has been coded with this Java package statement:
package ACMEJNS;

Note

Although use of Java packages is not essential on the UNIX or Windows platforms, it is currently required on the OS/390 platform. If Java stored procedure portability is important to you, we recommend that you use Java packages when you code your stored procedures. To build this program, go up one directory from the source. For example, if your source was in C:\apps\ACMEJNS\Add_customer.java, then you change directory to C:\apps to execute the build statements. Start by compiling your Java source using the javac Java command:
javac ACMEJNS\Add_customer.java

The resulting .class files are placed in the ACMEJOS subdirectory. Create the JAR file to be made available to the database, as follows:
jar cvf ACMEJNS.jar ACMEJNS\*.class

Note

We use *.class to ensure that we pick up the class files for any other procedures within the Java package that may have been prepared

Note

Issue the following statements from a DB2 Command Line Processor (CLP) session. Drop all procedures in the Java package:
DROP PROCEDURE ACMESNE.Add_customer ; DROP PROCEDURE ACMESNE.Add_order ;

Install the JAR file in the database. As a precaution, we recommend that you drop it first, to allow for re-runs:
CALL SQLJ.REMOVE_JAR('ACMEJNS.ACMEJNS');

Chapter 7. Preparing Java stored procedures

147

CALL SQLJ.INSTALL_JAR('file:s:/sg245945/ACMEJNS/ACMEJNS.jar', 'ACMEJNS.ACMEJNS');

The first parameter of sqlj.install_jar or sqlj.replace_jar defines the location of the JAR file you created previously. The second parameter provides an identifer that you will use when referring to the JAR file from within DB2 commands. Note that we have qualified this identifier DB2 uses this qualifier to determine which subdirectory it will copy the JAR file to. In our example, DB2 will register the JAR file and copy it to sqllib\function\jar\ACMEJNS\ACMEJNS.jar. Now that DB2 knows about the JAR, we can define the stored procedure to DB2. Note that trying to define the procedure before the JAR has been registered will result in an error.
CREATE PROCEDURE ACMEJNS.Add_customer ( IN IN_CUST_FIRSTNAME CHAR(20), IN IN_CUST_LASTNAME CHAR(20), IN IN_CUST_ADDRESS CHAR(30), OUT OUT_CUST_NO INT, OUT MARK CHAR(40), OUT MARK_ERROR_TEXT CHAR(200) ) EXTERNAL NAME 'ACMEJNS.ACMEJNS:ACMEJNS.Add_customer.add_customer' RESULT SETS 0 LANGUAGE JAVA PARAMETER STYLE JAVA FENCED NO DBINFO ;

Note

As we dropped all of the procedures in the Java package earlier, you must remember to recreate all of them here, not just the one you are working on! The stored procedure is now ready for execution.
7.3.1.2 Sample program preparation scripts Although not nearly as sophisticated as the examples we created for the OS/390 platform, we did create some scripts for performing this program preparation process for Windows NT and UNIX. Samples can be found in the appendix.

148

DB2 Java Stored Procedures: Learning by Example

7.3.2 NT / AIX SQLJ program preparation process


If the source contains SQLJ statements (or a combination of SQLJ and JDBC statements), the program preparation for a stored procedure consists of the steps shown in Figure 17.

Modfied Source

Java Bytecode

SQLJ Source

prog.JAVA prog.SQLJ

SQLJ Translator

Java Compiler (JAVAC)

prog.CLASS

Other CLASS files

prog_ SJProfileKeys.class

JAR

prog_ SJProfile0.ser

Profile Customiser (DB2PROFC)

Serialised Profile
5

package.jar

JAR File

package.JAR
JAR File in sqllib/function

SQLJ.INSTALL_JAR

DB2 Catalog

CREATE PROCEDURE

Can run on any JDK platform Run on S/390 platform

Figure 17. AIX and Windows NT SQLJ program preparation process

1. Precompile your source code using the sqlj command. This will extract all of the embedded SQL from your code and place it in an SQLJ serialized profile (a kind of generic, database independent DBRM). Serialised profiles are stored in .ser files. Your source code will be modified, and placed in a .java file. 2. Java-compile the source code (using the javac command). This will produce at least two .class files one containing your code and one containing the SQLJ access stub.

Chapter 7. Preparing Java stored procedures

149

Note

Unless you specifically request otherwise by specifying the -compile=false option, javac will be automatically executed by sqlj and there is no need to perform this step separately. However, you may wish to split these processes if you are encountering problems with the sqlj process (see 6.7.2.5, The sqlj command hangs on page 115) 3. Package the class file(s) produced in the previous into a single .jar file via the jar command. This step is mandatory if using the Java package statement. 4. Execute the DB2 profile customizer using the db2profc command. This takes the generic serialized profile created in step 1 and binds it directly to the DB2 database you specify.
Note

If you wish, you can specify the bindfile option in the -prepoptions parameter for db2profc. This will result in a standard .bnd file being produced, which you can then use to manually bind to DB2. By default, db2profc will execute the bind directly. 5. Install the JAR in the database (using the sqlj.install_jar command). This provides a DB2 name for the JAR file, enters details of the classes contained within it to the SYSIBM.SYSJARCONTENTS catalog table, and copies the file to a standard location4 so that DB2 is able to access it at run time. 6. Define the stored procedure to DB2 using the CREATE PROCEDURE statement. Note that the stored procedure cannot be defined until its associated JAR file exists.

The path is specified by the DB2INSTPROF parameter. The default value for this is sqllib/function.

150

DB2 Java Stored Procedures: Learning by Example

A word about JAR files

DB2 UDB for UNIX, Windows, OS/2 is very particular about the order in which these steps are conducted when it comes to JAR files. For example, it will not allow a procedure to be created until it exists in the referenced JAR file, or allow you to remove or refresh a JAR file while procedures are defined that refer to it. We found that the safest way to go about performing steps 5 and 6 above was to do the following; 1. Drop all procedures in the Java package via the SQL DROP PROCEDURE statement 2. Call sqlj.remove_jar followed by sqlj.install_jar to re-install the JAR file in the correct location. 3. Re-create the procedures via the SQL CREATE PROCEDURE statement This is the process that is used in our sample code. The process can be reliably rerun when re-preparing amended procedures. However, as all procedures in a given Java package have to be placed in the same JAR file, using this process means that you have to build the Java package gradually, procedure by procedure, in order to satisfy DB2s many consistency checks. For example, lets assume that we want to produce two procedures called
Add_customer and Add_order in a Java package called ACMEJNE.

We write the first procedure, Add_customer, and go through the SQLJ program preparation process. Using the steps above we first drop the procedure (which wont yet exist), remove the JAR definition (which wont exist), install the JAR (which should work), and then define the Add_customer procedure to DB2 via CREATE PROCEDURE. When we write the second procedure, Add_order, we will need to drop both procedures, remove and re-install the JAR definition, and then define both procedures to DB2. If we try to perform the steps in any other order, or if we try to create the Add_order procedure before there is a definition for it within the JAR file, the process will fail.

Chapter 7. Preparing Java stored procedures

151

Note

Steps 1 to 3 of this process can be done on any platform that contains a suitable JDK. We performed them within UNIX Systems Services (USS) in an S/390 environment. Steps 4 to 6 must be performed on the AIX or Windows NT platform you will be deploying the stored procedure on.

7.3.2.1 NT / AIX SQLJ detailed preparation example The example SQLJ stored procedure has been coded with this Java package statement:
package ACMESOS;

Note

Although use of Java packages is not essential on the Windows or UNIX platforms, it is currently required on the OS/390 platform. If Java stored procedure portability is important to you, we recommend that you use Java packages when you code your stored procedures. To build this program, go up one directory from the source. For example, if your source was in C:\apps\ACMESOS\Add_customer.sqlj, then you change directory to C:\apps to execute the build statements. Start by precompiling your SQLJ source file. By default, the sqlj command also executes javac to Java compile your procedure. The resulting files (Java .class files and an SQLJ serialized profile) are placed in the same directory as your source.
sqlj ACMESOS\Add_customer.sqlj

If you want to save the output messages, redirect them to files as in the following example. The > references standard output , the 2> references standard error.
sqlj ACMESOS\Add_customer.sqlj > outsqlj.txt 2>outsqlj2.txt

Execute db2profc, which takes the serialized profile created by the sqlj command and binds the SQL it contains to DB2.
db2profc -prepoptions="qualifier acmes package using addcust" -url=jdbc:db2:ACMES ACMESNS\Add_customer_SJProfile0

152

DB2 Java Stored Procedures: Learning by Example

Use of pre-compile options

Use of the qualifier precompile option allows you to specify an identifier for DB2 to use for all unqualified table references in the procedure. The package using option allows you to name the DB2 package that db2profc will generate, which is essential if you have multiple procedures within one package. Other precompile options (such as specifying the plan owner) can also be used refer to the PRECOMPILE PROGRAM command in the DB2 UDB Command Reference. Create the JAR file to be made available to the database (note that we are including multiple class files and the serialized profile in the JAR).
jar cvf ACMESOS/ACMESOS.jar ACMESOS\*.class ACMESOS\*.ser .Note

We use *.class to ensure that we pick up the class files for any other procedures within the Java package that may have been prepared

Note

Issue the following statements from a DB2 Command Line Processor (CLP) session. Drop all procedures in the Java package:
DROP PROCEDURE ACMESNE.Add_customer ; DROP PROCEDURE ACMESNE.Add_order ;

Install the JAR file in the database. As a precaution, it is a good idea to drop it first to allow for re-runs:
CALL SQLJ.REMOVE_JAR('ACMESNS.ACMESNS'); CALL SQLJ.INSTALL_JAR('file:s:/sg245945/ACMESNS/ACMESNS.jar', 'ACMESNS.ACMESNS');

The first parameter of sqlj.remove_jar or sqlj.install_jar defines the location of the JAR file you created previously.

Chapter 7. Preparing Java stored procedures

153

The second parameter provides an identifer that you will use when referring to the JAR file from within DB2 commands. Note that we have qualified this identifier DB2 uses this qualifier to determine which subdirectory it will copy the JAR file to. In our example, DB2 will register the JAR file and copy it to sqllib\function\jar\ACMEJOS\ACMESNS.jar. Now that DB2 knows about the JAR, we can define the stored procedure to DB2. Note that trying to define the procedure before the JAR has been registered will result in an error.
CREATE PROCEDURE ACMESNS.Add_customer ( IN IN_CUST_FIRSTNAME CHAR(20), IN IN_CUST_LASTNAME CHAR(20), IN IN_CUST_ADDRESS CHAR(30), OUT OUT_CUST_NO INT, OUT MARK CHAR(40), OUT MARK_ERROR_TEXT CHAR(200) ) EXTERNAL NAME 'ACMESNS.ACMESNS:ACMESNS.Add_customer.add_customer' RESULT SETS 0 LANGUAGE JAVA PARAMETER STYLE JAVA FENCED NO DBINFO NULL CALL MODIFIES SQL DATA;

Note

As we dropped all of the procedures in the Java package earlier, you must remember to recreate all of them here, not just the one you are working on! The stored procedure is now ready for execution.
7.3.2.2 Sample program preparation scripts Although not nearly as sophisticated as the examples we created for the OS/390 platform, we did create some scripts for performing this program preparation process for Windows NT and UNIX. These can be found in the appendix.

154

DB2 Java Stored Procedures: Learning by Example

7.3.3 The sqlj.install_jar and sqlj.replace_jar routines


The routines used to install (and replace) the JAR files have strict syntax requirements. They also produce sometimes inscrutable error messages. You can find some documentation on the SQLJ JAR routines within the section on Java Stored Procedures and UDFs in the DB2 UDB Application Development Guide, SC09-2845-00.
Important: Observe the following cautions: Never remove a JAR from the database manually

The JAR files register to the database via the sqlj ar routines. These JAR files then can be seen at sqllib\function\jar\<schema>. Never delete a JAR file manually. Always remove a JAR file using the sqlj.remove_jar routine.
Log in as schema owner

Within Command Center, the sqlj jar routines fail to recognize a set schema ACMES. You must connect at the beginning using the schema, as in 'connect to sample user ACMES'.
EXTERNAL NAME in create procedure statement

The EXTERNAL NAME clause in create procedure is case-sensitive. The first part of the name refers to the schema. In the following example, ACMES is the schema:
EXTERNAL NAME '"ACMES"."ACMESOS":ACMESOS.Add_customer.add_customer'

Chapter 7. Preparing Java stored procedures

155

156

DB2 Java Stored Procedures: Learning by Example

Chapter 8. Deployment and execution


This chapter takes a look as some of the deployment and execution issues to be considered once you have written and tested your Java stored procedures.

8.1 Deployment
One of the great advantages of developing stored procedures in Java is the fact that you are able to write and test them on one platform, then easily deploy them on another with few or no changes being required. Even if you are developing and deploying on a single platform, you will probably want separate development and production environments, and there are issues you need to be aware of and manage.

8.1.1 Migrating between environments on S/390


If you are developing and deploying your stored procedures completely on the S/390 platform, we strongly recommend that you establish entirely separate development and production environments (consisting of separate DB2 subsystems/data sharing groups, USS HFS systems, OS/390 libraries, and everything else). If this is not possible, try to separate out as much as possible (using different schemas within DB2, separate directories within HFS, and so on). In the following discussions, we assume that you have two entirely separate environments for development and production. You should be able to handle any number of variations (additional environments such as Unit Test and System Test, a lesser degree of physical separation between environments, and so on) using the same basic approach. There are two approaches commonly used for moving applications between development and production: Source-centric. Only program source files are moved between environments, and the program preparation process is re-executed within the production environment. This is the approach adopted by sites that use source management tools such as CA Endevor. Executable-centric. Only executable modules are moved between development and production, with no program preparation being executed within the production environment.

Copyright IBM Corp. 2000

157

These two approaches are discussed in the following sections. In both cases, only the application specific aspects of the migration process are considered it has been assumed that the system setup (as described in 4.1, OS/390 system setup on page 57) has been addressed for both the source and target environments.
8.1.1.1 Source-centric migration The migration process using the source-centric approach is relatively simple, as shown in Figure 18.

Development Environment
Source
prog.JAVA

Production Environment
prog.JAVA

Source

Java Compiler

Java Compiler

Java Bytecode

prog.CLASS

prog.CLASS

Java Bytecode

HPJ Compiler

HPJ Compiler

External Link

JLL in PDSE

JLL in PDSE

External Link

DB2 Catalog

DDL

DDL

DB2 Catalog

Figure 18. Source-centric migration for a JDBC application

In this situation, all that needs to be migrated is: The Java source code for the procedure. This can be accomplished using a simple FTP command to copy the source from the development HFS system to the production one. Note that Java source files should be FTPed in text format.

158

DB2 Java Stored Procedures: Learning by Example

The DDL containing the CREATE PROCEDURE (for Version 6) or INSERT INTO SYSPROCEDURES (for Version 5) statements, plus any other DDL associated with the application. Assuming that the development and production environments use shared DASD, this can be accomplished with a simple IEBCOPY or a dedicated DB2 object management tool. , Once these two items have been moved, all that would be required is to re-perform the program preparation process within the production environment to create a new executable, and submit the necessary DDL to define the procedure to DB2.
SQLJ procedures

Figure 18 on page 158 shows a JDBC migration for simplicity. Migration of an SQLJ procedure would use an identical approach, with only the program preparation steps differing.
8.1.1.2 Executable-centric migration The migration process for the executable-centric migration approach is simpler still, as shown in Figure 19.

The following items must be copied from the source to the target environment: The HPJ compiled executable module. As this is a simple PDSE member, this can be accomplished using a utility such as IEBCOPY. The DDL containing the CREATE PROCEDURE (for Version 6) or INSERT INTO SYSPROCEDURES (for Version 5) statements, plus any other DDL associated with the application. Again, this can be accomplished with a simple IEBCOPY or a dedicated DB2 object management tool. , Once these items have been moved, all that would be required is the creation of a external link in the relevant HFS directory, to point to the newly moved PDSE executable. This can be accomplished using the USS ln command, as shown in the example below:
ln -e ACMESOS ACMESOS.jll

Chapter 8. Deployment and execution

159

Development Environment
Source
prog.JAVA

Production Environment

Java Compiler

Java Bytecode

prog.CLASS

HPJ Compiler Create Link


External Link External Link

JLL in PDSE

JLL in PDSE

DB2 Catalog

DDL

DDL

DB2 Catalog

Figure 19. Executable-centric migration for a JDBC application

SQLJ procedures

Figure 19 shows a JDBC migration for simplicity. Migration of an SQLJ procedure would use a very similar approach, but the DBRMs generated by the db2profc process on the target system would also have to be moved to the target environment, and then bound to the production DB2 system.

8.1.2 Migrating between environments on UNIX/NT


As the UNIX and Windows NT environments do not have the additional complexity of the HPJ step, the process for moving applications between environments is somewhat simpler than for OS/390.

160

DB2 Java Stored Procedures: Learning by Example

8.1.2.1 Source-centric migration The source-centric migration uses the same concepts as shown previously. You can move the JDBC or SQLJ source files from the source environment to the target environment along with the necessary INSTALL_JAR and CREATE PROCEDURE statements (using FTP or some other utility), and then re-run the entire program preparation process on the target platform. 8.1.2.2 Executable-centric migration For JDBC procedures, you can migrate between environments by executing the following steps:

1. Move the JAR file containing the procedure code and the DDL defining the procedures to the target environment. 2. Define the JAR file to DB2 using the sqlj.install_jar statement. 3. Execute the CREATE PROCEDURE commands to define the procedures to DB2. The process for SQLJ is slightly more involved: 1. Move the JAR file containing the procedure code, the DDL defining the procedures and the serialized profile generated by the sqlj command to the target environment. 2. Define the JAR file to DB2 using the sqlj.install_jar statement. 3. Execute the CREATE PROCEDURE commands to define the procedures to DB2. 4. Execute db2profc in the target environment to create the necessary DB2 packages in the target DB2 system.

8.1.3 Porting between UNIX/NT and S/390


You may want to prototype and develop your procedures within UNIX or Windows NT, and then port them to the S/390 platform for subsequent use. Although it is perfectly possible to port Java bytecode, in the guise of .class files or .jar files between the two environments, it is likely that further development may be required. Therefore, we recommend that you stick to porting source files. There are a few considerations you should be aware of when porting between these platforms. We cover these in the following sections.

Chapter 8. Deployment and execution

161

8.1.3.1 Changing Class.forName method and connection As there is no need for specific references to drivers or connections within stored procedures themselves, they can be ported with absolutely no amendments to the code. We proved this several times in the development of the examples within this book.

However, client code will have such references, so a couple of minor changes will be necessary. The Class.forName method is used to load a specific driver, which differs between UNIX/NT and OS/390 as follows: COM.ibm.db2os390.sqlj.jdbc.DB2SQLJDriver for OS/390 COM.ibm.db2.jdbc.app.DB2Driver for AIX and Windows NT Similarly, the connection URL used within JDBC clients differs as follows: jdbc:db2os390sqlj:DB21 for OS/390 Here, DB21 is the subsystem name. jdbc:db2:ACMES for AIX and Windows NT Here, ACMES is the database name.
8.1.3.2 Code translation There are some issues associated with the translation of certain ASCII and EBCDIC characters between the environments that will be well known to C and C++ programmers.

Detailed exploration of this issue is beyond the scope of this book, but here are a couple of practical pointers: Java code makes extensive use of square brackets ([ and ]). When a program is ported to the USS environment, these characters appear to be corrupted, as there is no EBCDIC equivalent for them (they appear as xAD and xBD respectively in USS). However, although this issue makes the code look somewhat messy within the USS environment, it has absolutely no impact on the execution of Java programs from within a JVM or HPJ environment. Good coding practices encourage the use of tabs in source code as a readability aid. Unfortunately, these are not always translated correctly and often appear as unprintable characters in USS. Again, this can be ignored, but it is a good idea to format code using hard space characters rather than tabs if you will be frequently porting between platforms.

162

DB2 Java Stored Procedures: Learning by Example

8.2 Execution
The following sections describe some execution considerations, depending on which platform you are using.

8.2.1 OS/390 execution considerations


8.2.1.1 Refreshing a changed procedure Once a Java stored procedure is called, the OS/390 executable can be cached by the WLM. If you subsequently call the same procedure again, the version from the cache is used, and not the one from the disk.

Do this to refresh a Java stored procedure after changes have been made: 1. Re-prepare the stored procedure, as described in 7.2, OS/390 Java stored procedure preparation on page 119. 2. Issue a V WLM,APPLENV=xxx,REFRESH command on the system console to refresh the .jlls containing the code (where applenv is the WLM application environment name).

8.2.2 UNIX and Windows NT execution considerations


Here we provide various execution considerations for these environments.
8.2.2.1 Refreshing a changed procedure Once a Java stored procedure is called, its bytecode is cached by the class loader. Then, if you call the same step again, the version from the cache is used, and not the one from the disk.

To refresh a Java stored procedure after changes have been made, do the following: 1. Re-prepare the stored procedure, as described in 7.3, NT / AIX Java stored procedure preparation on page 144. 2. Issue the following command to replace the JAR file:
call sqlj.replace_jar ('file:/aaakirk/Acme/Acme.jar','Acme');

3. Issue the following command to refresh the classes:


call sqlj.refresh_classes (void);

Chapter 8. Deployment and execution

163

8.3 Stored procedure management and version control on OS/390


With the new schema support in DB2 UDB for OS/390 V6 (see Chapter 12, DB2 UDB for OS/390 schema support on page 233), it is now possible to more effectively provide version control for DB2 stored procedures. In this section we will discuss how stored procedures can be managed with versions.

8.3.1 Source code control


DB2 for OS/390 doesn't really store the stored procedures source code, so change management is basically left up to the installation. When the Stored Procedure Builder is used, the source is stored in the OS/390 catalog tables, but only the current version is kept. To separate test and production source code, they both would be stored in separate PDSs. You would use your current source code management tools to management the movement of the source code from test to production.

8.3.2 Version control


The capability to execute different versions of a stored procedure is controlled by AUTHID in V5 and SCHEMA in V6. This allows the same stored procedure name to be used to invoke different load modules: in V5, the executing AUTHID is used to find the right catalog entry; and in V6, the SCHEMA is used to qualify the name. The number of parameters passed are also matched up. You may also accomplish version control by using the 'set current packageset' special register from inside the stored procedure to direct DB2 to the correct COLLECTION ID. WLM provides us with a seamless way to deploy a new version of the load module that is loaded and run when a stored procedure is invoked. When running in GOAL mode, a 'V WLM,APPLENV=x,REFRESH' command allows currently executing CALL statements to complete against the 'old' version of the load module, and a new address space is brought up for any new requests, so they pick up the new version of the load module. The calling application doesn't need to qualify the CALL statement on schema name. If it is not specified, it is determined from the CURRENT_PATH special register (if the SQL CALL statement specifies the stored procedure name in a host variable) or the PATH bind option (if the SQL CALL statement specifies the stored procedure name as a literal.)

164

DB2 Java Stored Procedures: Learning by Example

8.3.3 Sample of a test and production version


Here is an example of using SCHEMA to control a test and production version of a stored procedure. The production version has schema PROD, so its qualified name is PROD.PROCA. The test version has schema TEST, so its qualified name is TEST.PROCA. The calling application uses the SQL statement CALL PROCA to invoke the stored procedure. This DB2 package was bound with PATH(PROD), so when it executes, it calls PROD.PROCA. The developer creates another PROCA in schema TEST, so it's qualified name is TEST.PROCA. Its load module name is the same as PROD.PROCA, and is stored in a different load library in a different WLM application environment. Example: WLM application environment Test_Payroll and Prod_Payroll are both executing load module PAY0200. But they both have WLM start a different WLM-established JCL procedure with the different load library in it. Calling applications to use the test version are bound with PATH(TEST) or fully use the qualified TEST.PROCA. Using the bind parameter PATH(TEST) is a better solution, since there would be no application code change. 1. When it is ready to roll into production, copy the PROD version, -1 version, off to another load library. 2. Copy the TEST version into PROD library. 3. Rebind the stored procedure with PATH(PROD). 4. Issue the WLM refresh for the PROD application to make these changes visible. If you have problems with this new code in production, you can simply move the old version of the load module back to the PROD library. Then reissue the WLM refresh. This way, the calling application never has to change, or even be rebound, to pick up a new or old version of its load module.

8.3.4 Running two versions in the same DB2 subsystem


Now, with SCHEMA in V6, you can now have two or more versions of a stored procedure in the same DB2 subsystem accessing different tables. To do this, you bind the application with both the PATH and OWNER option. The OWNER option is used to point to a different copy of a table, and the PATH option used to point to a different stored procedure.

Chapter 8. Deployment and execution

165

166

DB2 Java Stored Procedures: Learning by Example

Chapter 9. Client applications invoking Java stored procedures


This chapter describes some of the issues that you need to be aware of when coding clients to invoke Java stored procedures.

9.1 DB2 plans and packages


As your client application contains at least one SQL statement (the CALL to the stored procedure), it will need to be prepared using the standard program preparation process. For an SQLJ client application, this involves running the sqlj precompiler, db2profc profile customizer, binding DB2 packages, and running a Java compile. For a JDBC client, all that is required is the Java compile step. Note that as the client application runs in the USS JVM, no HPJ compile will be required in either case. When the client is invoked (whether it is JDBC or SQLJ), the
DB2SQLJPROPERTIES environment variable is used to find the name of the SQLJ properties file. This file contains the setting for the DB2SQLJPLANNAME parameter,

which is the name of the plan DB2 uses when running the client (we used the default name of SQLJPLAN). For simplicity, we will refer to this plan as SQLJPLAN in the following paragraphs.

9.1.1 JDBC client requirements


For a JDBC client, SQLJPLAN must refer to the 4 generic JDBC DBRMs DSNJDBC1, DSNJDBC2, DSNJDBC3 and DSNJDBC4. You can do this by directly binding the DBRMs into SQLJPLAN, but we recommend binding them into a generic DB2 package collection (we used DSNJDBC, for example) and including this DB2 package collection in the DB2 package list for SQLJPLAN. In addition, you need to ensure that SQLJPLAN contains the necessary references to the DB2 packages for the stored procedure you will be invoking (if necessary). See 9.1.3, Stored procedure requirements on page 168 for details.

9.1.2 SQLJ client requirements


For an SQLJ client application, the SQLJPLAN must refer to the 4 client DBRMs created by db2profc when you went through the program preparation process for the client. You can do this by directly binding the DBRMs into SQLJPLAN, but we recommend binding them into a DB2 package collection (we used a DB2

Copyright IBM Corp. 2000

167

package collection called CLIENT, for example) and including this DB2 package collection in the DB2 package list for SQLJPLAN. In addition, you need to ensure that SQLJPLAN contains the necessary references to the DB2 packages for the stored procedure you will be invoking (if necessary). See 9.1.3, Stored procedure requirements on page 168 for details.

9.1.3 Stored procedure requirements


In 7.2.3, OS/390 JDBC program preparation process on page 122 and 7.2.4, OS/390 SQLJ program preparation process on page 129, we recommended that you explicitly specify a DB2 package collection to be associated with your stored procedure. If you followed this recommendation, you need do nothing else to ensure that the correct JDBC or SQLJ DB2 packages can be invoked at run time. If you chose not to explicitly specify the DB2 package collection, you will need to ensure that the 4 generic JDBC DBRMs (for a JDBC stored procedure) or the 4 application-specific DBRMs (for a SQLJ stored procedure) are bound into DB2 packages that belong to the same DB2 package collection as the client DB2 package/plan.

9.1.4 Summary
Table 10 contains a summary of the requirements for SQLJPLAN according to the type of client and stored procedure, if our recommendations concerning the use of COLLID are followed.
Table 10. Contents of SQLJPLAN by client and SP type using COLLID

Called Stored Procedure Type JDBC Stored Procedure JDBC Client


Collection containing the 4 generic JDBC packages DSNJDBC1, DSNJDBC2, DSNJDBC3 and DSNJDBC4 (e.g. DSNJDBC).

SQLJ Stored Procedure


Collection containing the 4 generic JDBC packages DSNJDBC1, DSNJDBC2, DSNJDBC3 and DSNJDBC4 (e.g. DSNJDBC).

168

DB2 Java Stored Procedures: Learning by Example

Called Stored Procedure Type JDBC Stored Procedure SQLJ Client


Collection (any name), containing the 4 packages produced by db2profc when preparing the SQLJ client.

SQLJ Stored Procedure


Collection (any name), containing the 4 packages produced by db2profc when preparing the SQLJ client.

Table 11 contains a summary of the requirements for SQLJPLAN according to the type of client and stored procedure, if COLLID is not explicitly supplied when defining the stored procedures. This approach is considerably more restrictive.
Table 11. Contents of SQLJPLAN by client and SP type not using COLLID

Called Stored Procedure Type JDBC Stored Procedure JDBC Client


Collection containing the 4 generic JDBC packages DSNJDBC1, DSNJDBC2, DSNJDBC3 and DSNJDBC4 (e.g. DSNJDBC).

SQLJ Stored Procedure


Collection containing the 4 generic JDBC packages DSNJDBC1, DSNJDBC2, DSNJDBC3 and DSNJDBC4 (e.g. DSNJDBC). Same collection must also contain the 4 packages produced by db2profc when preparing the SQLJ stored procedure.

SQLJ Client

Collection (any name), containing the 4 packages produced by db2profc when preparing the SQLJ client. Same collection must also contain the 4 generic JDBC packages DSNJDBC1, DSNJDBC2, DSNJDBC3 and DSNJDBC4.

Collection (any name), containing the 4 packages produced by db2profc when preparing the SQLJ client. Same collection must also contain the 4 packages produced by db2profc when preparing the SQLJ stored procedure.

Chapter 9. Client applications invoking Java stored procedures

169

9.1.5 Usage recommendations


As can be seen from Table 10 on page 168 and Table 11 on page 169, SQLJPLAN is central to the operation of both SQLJ and JDBC clients and stored procedures, and as such you should carefully consider the way in which it will be used in your environment. For instance, use of a single SQLJPLAN will result in an ever-increasing list of packages for DB2 to search through at runtime, which may start to negatively impact performance. In addition, there are practical limitations with rebinding SQLJPLAN every time a new DB2 package collection has to be added to the DB2 package list. For these reasons, we recommend that you consider creating several plans, splitting them according to development area, business unit, application or some other attribute suited to your environment. Each version of SQLJPLAN will be pointed to by a separate SQLJ properties file, which in turn must be pointed to by the DB2SQLJPROPERTIES environment variable. We suggest setting this for each user within the .profile script (possibly in response to a question regarding which environment they would like to be set up for). See 4.1.9.2, SQLJ properties file on page 71 and 4.1.4, Step 2: Provide .profile for users on page 63 for further details.

9.2 Client coding considerations


The following sections describe some of the issues that you need to be aware of when coding client applications invoking Java stored procedures.

9.2.1 General client coding considerations


In this section, we present some general client coding considerations that apply to both JDBC and SQLJ clients.
9.2.1.1 Coding the connect statement Your client will need to use the getConnection method to create a connection to the desired DB2 subsystem or data sharing group, such as the one in the example below:
url = "jdbc:db2os390sqlj:DBZ1"; con = DriverManager.getConnection(url);

The last component of the connection string (DBZ1 in the example) should refer to the location name of the system you are trying to connect to (which is defined in the DDF Communication Record in the BSDS for that subsystem).

170

DB2 Java Stored Procedures: Learning by Example

You may either specify a local location name (for a subsystem on the same OS/390 system as the client) or a remote one (for a subsystem on different OS/390 system). If you specify a remote system, that system must be defined in the communications database (CDB) for the local DB2. Refer to section 3.3 of DB2 Application Programming Guide and Reference for Java, SC26-9018-01 for further information.
9.2.1.2 The SQL CALL statement Due to an oddity in the drivers we used, we were forced to code all stored procedure names within CALL statements in upper case, as shown in the following JDBC and SQLJ examples:
procName = "ADD_CUSTOMER"; String sql = "CALL " + procName + "(?,?,?,?,?,?)"; #sql [myconn] { CALL ADD_CUSTOMER ( :IN lastname, :IN firstname, :IN address, :OUT cust_no, :OUT returned_mark, :OUT returned_mark_error_text) };

Attempts to use any lower case characters in the stored procedure name resulted in a -113 SQLCODE, indicating invalid characters in the prepared statement string. So, using the following statements:
procName = "add_customer"; String sql = "CALL " + procName + "(?,?,?,?,?,?)";

or:
#sql [myconn] { CALL add_customer ( :IN lastname, :IN firstname, :IN address, :OUT cust_no, :OUT returned_mark, :OUT returned_mark_error_text) };

will result in a runtime error similar to the one below:


java.sql.SQLException: DB2JDBCSection Received Error in Method execute_call
:SQLCODE==> -113 SQLSTATE ==> 42602 Error Tokens ==> <<DB2/OS390 V5.1 ANSI SQLJ-0/JDBC 1.0>> add_customer 000 atCOM.ibm.db2os390.sqlj.jdbc.DB2SQLJJDBCSection.setError(DB2SQLJJDBCSection.java:1049) at COM.ibm.db2os390.sqlj.jdbc.DB2SQLJJDBCSection.execute_call (DB2SQLJJDBCSection.java:874) at COM.ibm.db2os390.sqlj.jdbc.DB2SQLJCallableStatement.execute (DB2SQLJCallableStatement.java:116) at jscall_Add_customer.main(jscall_Add_customer.java:84)

Chapter 9. Client applications invoking Java stored procedures

171

Therefore, we recommend that you code all client calls using upper case names only.

COBOL clients

This issue did not appear to affect COBOL clients, and we able to successfully invoke Java stored procedures from within COBOL clients using a mixture of upper and lower case names.

9.2.2 JDBC client coding considerations


Invoking a stored procedure using JDBC requires a specific set of steps to be followed: 1. Creating the string containing the SQL CALL statement, using parameter markers in place of the stored procedure parameters 2. Preparing the SQL string for execution 3. Setting the input parameters 4. Registering the output parameters, to allow them to be accessed after the
CALL

5. Executing the call to the stored procedure 6. Retrieving the vales of the output parameters The code fragments shown in the following sections illustrate these steps.
9.2.2.1 Create SQL string First, a string must be defined containing the SQL CALL statement to invoke the stored procedure. The syntax of the CALL statement is normal, other than the fact that each reference to a parameter (normally represented by a host variable of some sort) is replaced by a ? character. In the example below, we are invoking a procedure called JS_ADD_CUSTOMER which has 6 parameters (3 input parameters and 3 output parameters).
procName = "JS_ADD_CUSTOMER"; String sql = "CALL " + procName + "(?,?,?,?,?,?)";

Note that the stored procedure name in the call is in upper case see 9.2.1.2, The SQL CALL statement on page 171.

172

DB2 Java Stored Procedures: Learning by Example

9.2.2.2 Prepare string for execution Now that we have built the SQL string, it needs to be passed to DB2 for preparation. This is done using the prepareCall method, as shown in the example below:
callStmt = con.prepareCall(sql);

9.2.2.3 Set input parameters Next, we need to tell DB2 what values to pass for the input parameters when the stored procedure is invoked. The following lines of code allocate the three parameters passed to the client program to parameters 1, 2 and 3 of the stored procedure, using the argv function.
callStmt.setString (1, argv[0]); callStmt.setString (2, argv[1]); callStmt.setString (3, argv[2]); // firstname // lastname // address

Note that in common with many other aspects of Java, the argv function defines the first parameter as argv[0], even though the setString method refers to the first stored procedure parameter as number 1.
9.2.2.4 Register output parameters In order to access the output parameters after the call, they must be associated with the call statement using the registerOutParameter method. In the example below, we are defining parameters 4, 5 and 6 according to their respective data types:
callStmt.registerOutParameter (4, Types.INTEGER); callStmt.registerOutParameter (5, Types.CHAR); callStmt.registerOutParameter (6, Types.CHAR); // generated Cust no // mark // mark_error_text

9.2.2.5 Call stored procedure Now, we are ready to call the stored procedure using the simple syntax shown below:
callStmt.execute();

9.2.2.6 Retrieve output parameters Finally, we need to retrieve the previously registered output parameters and place them into host variables so that they are accessible to the client program:
int returned_cust_no = callStmt.getInt(4); String returned_mark = callStmt.getString(5); String returned_mark_error_text = callStmt.getString(6);

Chapter 9. Client applications invoking Java stored procedures

173

9.2.3 SQLJ client coding considerations


Coding an SQLJ call to a stored procedure is simpler and less verbose than its JDBC equivalent. The CALL statement is embedded directly within the stored procedure call, and can use host variable names for the input and output parameter names within the call. The code fragment below shows a call to the same stored procedure discussed in the JDBC section earlier:
#sql [myconn] { CALL ADD_CUSTOMER ( :IN lastname, :IN firstname, :IN address, :OUT cust_no, :OUT returned_mark, :OUT returned_mark_error_text) };

Note that the stored procedure name in the call is in upper case see 9.2.1.2, The SQL CALL statement on page 171.

9.3 Client authorization issues


Section 7.2.2, DB2 authorization issues on page 120 covered DB2 security issues related to stored procedures themselves. This section looks at some additional authorization considerations from the clients perspective.

9.3.1 JDBC client authorization


Most of the authorization issues covered in 7.2.2.2, JDBC stored procedures on page 120 also apply to JDBC clients. It is possible to alter the way in which authorization checking is performed using the DYNAMICRULES parameter when binding the clients generic JDBC packages or plan.

9.3.2 DB2 for OS/390 stored procedure execute authority


When invoking a stored procedure that resides on the S/390 platform, the authority needed to execute the procedure varies depending upon whether the procedure was created prior to DB2 UDB for OS/390 Version 6 or not. Prior to Version 6, the client only requires execute authority on the DB2 packages used by the stored procedure. However, invoking a procedure created since Version 6 was installed requires a specific EXECUTE privilege on the stored procedure itself, in addition to the DB2 package privileges described above. The EXECUTE privilege is implicitly held if you are the owner of the stored procedure or a SYSADM, or may be explicitly granted using the new GRANT EXECUTE ON PROCEDURE... SQL statement.

174

DB2 Java Stored Procedures: Learning by Example

Refer to the description of the CALL statement in the DB2 UDB for OS/390 SQL Reference, SC26-9014 for a full description.

9.4 Sample Java client preparation scripts


We used the scripts below for Java client program preparation.
Note: These scripts can be found on the CD-ROM, in the SAMPLES\S390 UTILITIES\PROGRAM PREPARATION directory. Refer to Appendix E, Using the

additional material on page 347 for more information. The entire process is invoked from the USS command line using a syntax such as:
javacl sscall_Add_customer acmecl sscalac acmes

This can be found in script driver_cl.

9.4.1 Sample javacl script


This script will translate the SQLJ, create the DBRMs with db2profc, and bind the DB2 packages.
# SQLJ client with SQL # phase 1 SQLJ translator # phase 2 db2profc create DBRMs # phase 3 bind packages # # Call format for shell is => javacl pgm pkg mem qualifier # Example => javacl $1 $2 $3 $4 # $1= Java class name # $2= Java package name # $3= Member package name used for binds - limit 7 # $4= Table qualifier # pgm=$1 # pgm is the Java class name. pkg=$2 # pkg is the used for the SP package collection, JAVA package, # directory where the JAVA code is. mem=$3 # mem package name used for binds - limit to 7 characters qual=$4 # qual is the table qualifier # pgmuln=$1'_SJProfile0' echo $pgmuln

Chapter 9. Client applications invoking Java stored procedures

175

echo "Starting phase 1 - SQLJ translator" $pgm $pkg `whence sqlj` $pkg/$pgm.sqlj echo "Starting phase 2 - db2profc" db2profc -pgmname=$mem $pkg/$pgmuln.ser echo "Starting phase 3 - bind plans" # bindcl.rexx $mem $pkg $qual $spcol bindsp.rexx $mem $pkg $qual umem=`echo $mem | tr 'a-z' 'A-Z'` cat bind$SSID$umem.out | sed 's/ *$//' echo "Build for" $pgm $pkg "complete"

9.4.2 Sample bindcl.rexx script


This script builds the bind statements and passed them to the TSO REXX exec OEBIND. It will only bind the DB2 packages, and the plan will have to be manually bound.
/* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* /* rexx Unix System Services (USS) bindcl_plan.rexx MEM PKG qual spcol called by JAVA prep shell scripts to bind the client plan and packages. */ */ */ */ */ Licensed Materials - Property of IBM */ */ (C) COPYRIGHT International Business Machines Corp. 1995, 1997 */ All Rights Reserved. */ */ US Government Users Restricted Rights - Use, duplication or */ disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ Written 03/05/200 by Michael J. Fischer */ */ Input parms: 4 */ MEM DBRM member name used for the PDSE library. */ PKG Client package name for bind. */ qual Table qualifier name used for unqualified tables. */ spcol Stored procedure package collection name to use */ in Plan. */ */ Calls TSOE rexx program "OEBIND" to run DSN in the tsoe */ environment. This was done so the JAVA prep shell scripts */ can run in the OMVS or telnet environment. DSN will not run */ under telnet. */ */ To display help enter bindcl_plan.rexx ? or bindcl_plan.rexx '?' */

176

DB2 Java Stored Procedures: Learning by Example

/* /* Note: In USS a ? is converted to a 2. arg MEM PKG qual spcol . if MEM = "?" | MEM = 2 then do do i = 1 while substr(sourceline(i),1,2) = "/*" say sourceline(i) end return 0 end

*/ */

if length(MEM) > 7 then do say "ERROR**** Member name can not be greater then 7 characters" say "Unable to create BIND statements" return 999 end x=0 /* */ /* Find the DB2SQLJPROPERTIES environment variable and set the */ /* rexx DB2SQLJPROPERTIES variable to it. */ /* If no DB2SQLJPROPERTIES variable set then default to */ /* db2sqljjdbc.properties in working directory */ /* */ do I = 1 to __environment.0 if substr(__environment.i,1,17) = 'DB2SQLJPROPERTIES' then do DB2SQLJPROPERTIES = substr(__environment.i,19,length(__environment.1)-18) x=1 end if substr(__environment.i,1,5) = 'TERM=' then do termenv = substr(__environment.i,6,length(__environment.i)-5) end end if x=0 then DB2SQLJPROPERTIES = 'db2sqljjdbc.properties' /* Pick up the DB2 subsystem ID and DBRMLIB to use for the Binds /* db2sqljplanname /* from the DB2SQLJPROPERTIES file. address syscall "readfile (DB2SQLJPROPERTIES) file." if retval < 0 then do say "ERROR*** The" DB2SQLJPROPERTIES "file does not exist" say "Unable to create BIND statements" return 999 end */ */ */

Chapter 9. Client applications invoking Java stored procedures

177

else do i = 1 to file.0 if substr(file.i,8,4) = 'SSID' then ssid = substr(file.i,13,length(file.i)-12) if substr(file.i,8,7) = 'DBRMLIB' then dbrmlib = substr(file.i,16,length(file.i)-15) if substr(file.i,8,8) = 'PLANNAME' then planname = substr(file.i,17,length(file.i)-16) end /* /* Build the BIND statements and save them to the stack. /* say say say say say '****** NOTE: ******' 'If this JAVA client calls a JAVA SP, make sure the SP's' 'collection along with this clients collection' PKG||'.* is in PLAN' planname 'and rebind this PLAN' '*******************' */ */ */

b.0 = 5 b.1 ="BIND PACKAGE("PKG") MEMBER("MEM"1) ACT(REP) (BIND) LIBRARY('"DBRMLIB"') QUALIFIER("QUAL")" b.2 ="BIND PACKAGE("PKG") MEMBER("MEM"2) ACT(REP) (BIND) LIBRARY('"DBRMLIB"') QUALIFIER("QUAL")" b.3 ="BIND PACKAGE("PKG") MEMBER("MEM"3) ACT(REP) (BIND) LIBRARY('"DBRMLIB"') QUALIFIER("QUAL")" b.4 ="BIND PACKAGE("PKG") MEMBER("MEM"4) ACT(REP) (BIND) LIBRARY('"DBRMLIB"') QUALIFIER("QUAL")" b.5 ="END" input = "BIND"||ssid||"INPUT" address syscall "writefile ("||input||") 777 b." if retval=-1 then do "error*** writing bind input file" input return 999 end address syscall "getcwd cwd" if retval=-1 then do "error*** getting current directory to save" return 999 end

ISOLATION(UR) VALIDATE ISOLATION(CS) VALIDATE ISOLATION(RS) VALIDATE ISOLATION(RR) VALIDATE

/* /* Call "oebind" to run DSN on the tsoe OS/390 environment. /*

*/ */ */

178

DB2 Java Stored Procedures: Learning by Example

if termenv = 'vt100' then /* telnet "tso -t oebind" ssid cwd input mem else "tso oebind" ssid cwd input mem

*/

/* /* Remove input file with BIND statements in /* "rm" input /* /* make sure the directory exist for ser files in /u/"ssid"/ser/ /* address syscall "chdir /u/"ssid"/ser/"pkg if retval=-1 then do "chdir /u/"ssid"/ser/" if retval=-1 then do say "error*** getting directory /u/"ssid"/ser" return 999 end "mkdir" pkg 777 if retval=-1 then do say "error*** making directory /u/"ssid"/ser/"pkg return 999 end end /* reset current directory "chdir" cwd if retval=-1 then do "error*** reseting directory" cwd "to current" return 999 end RETURN

*/ */ */

*/ */ */

*/

Chapter 9. Client applications invoking Java stored procedures

179

180

DB2 Java Stored Procedures: Learning by Example

Chapter 10. Migration of DB2 for OS/390 Version 5 to Version 6


Migration to DB2 Universal Database for OS/390 Version 6 eliminates all Type 1 indexes, shared read-only data, data set passwords, and use of host variables without the colon; and it changes the usage of the RECOVER INDEX command. You can migrate to Version 6 only from a Version 5 subsystem, and you must convert all type 1 indexes to type 2 indexes. Shared read-only data has to be removed, and all data set passwords must be removed. For stored procedures, the table SYSIBM.SYSPROCEDURES is migrated to two new tables, SYSIBM.SYSROUTINES and SYSIBM.SYSPARMS. In the following sections we cover some additional migration considerations that apply specifically to DB2 stored procedures.

10.1 Stored procedures


In earlier releases of DB2, columns AUTHID and LUNAME of catalog table SYSIBM.SYSPROCEDURES were used to uniquely identify multiple instances of a stored procedure. After migrating to Version 6, you should use the SCHEMA column in the SYSIBM.SYSROUTINES catalog table, the CURRENT PATH special register, and the PATH bind option to identify multiple instances of a procedure (see Chapter 11, DB2 UDB for OS/390 network computing enhancements on page 187, Chapter 12, DB2 UDB for OS/390 schema support on page 233 and Chapter 13, DB2 UDB for OS/390 stored procedures enhancements on page 243 for background information). During the migration process, DB2 generates CREATE PROCEDURE statements which populate SYSIBM.SYSROUTINES and SYSIBM.SYSPARMS. Rows in SYSIBM.SYSROUTINES that contain non-blank values for columns AUTHID or LUNAME are not used to generate the CREATE PROCEDURE statements. You can identify those rows by using the following statement:
SELECT * FROM SYSIBM.SYSPROCEDURES WHERE AUTHID <> ' ' OR LUNAME <> ' ';

DB2 also copies rows in SYSIBM.SYSPROCEDURES into table SYSIBM.SYSPARMS and propagates information from the PARMLIST column of SYSIBM.SYSROCEDURES into SYSIBM.SYSROUTINES and SYSIBM.SYSPARMS.

Copyright IBM Corp. 2000

181

Stored procedures migrated from Version 5 do not have an owner, because they were not created with the CREATE PROCEDURE statement. This means that the authorization rules don't change from V5. If you subsequently DROP and CREATE the stored procedure, now it has an OWNER, so the caller must have EXECUTE ON PROCEDURE authority to invoke it. DB2 authorization treats these migrated procedures differently than procedures created with CREATE PROCEDURE. The authorization for migrated procedures is unchanged. Migrated stored procedures have SCHEMA set to SYSPROC. This means that to invoke them, SYSPROC has to be in the concatenation of schemes that DB2 uses in resolution. The catalog table SYSIBM.SYSPROCEDURES is not used in Version 6 to define stored procedures to DB2. The SYSCAT.PROCEDURES view of catalog table SYSIBM.SYSPROCEDURES is not used to list the stored procedures registered in DB2. Although these tables are no longer used in Version 6, DB2 does not drop them during migration because they are needed for fallback and data sharing coexistence. For more information, refer to DB2 Application Programming and SQL Guide, SC26-9004.

10.1.1 SYSIBM.SYSPROCEDURES no longer used


Catalog table SYSIBM.SYSPROCEDURES is no longer used to define stored procedures to DB2 in Version 6. During catalog migration, all rows in SYSIBM.SYSPROCEDURES are automatically migrated to the new SYSIBM.SYSROUTINES catalog table and to SYSIBM.SYSPARMS. In Version 6, you use the CREATE and ALTER PROCEDURE statement to define stored procedures. To prepare for fallback, or to run in a coexistence environment for data sharing, you must modify the SYSPROCEDURES catalog table to match the updates to SYSROUTINES and SYSPARMS that those CREATE statements make.

10.1.2 Java stored procedures under Version 5


If you used Java stored procedures in release 5, you stored the Java classname and methodname in the RUNOPTS column. After migrating to Version 6, the catmaint job has moved the contents of RUNOPTS for COMPJAVA programs to the External Name column. Therefore, in Version 6, the Java stored procedure will use the External Name column for the Java classname.

182

DB2 Java Stored Procedures: Learning by Example

10.1.3 DB2 catalog maintenance


Make sure you have a stand-alone copy of your DB2 subsystem, BSDSs, logs, catalog, directory, and libraries before you start your Version 5 subsystem with the new Version 6 libraries and run the catmaint job. This is to ensure that you have a fallback if you run into problems when running the catmaint job. If you run into errors with step 2, DNSTITC2, of the catmaint job DSNTIJCT, this step is restarted. The SYSIBM.SYSPROCEDURES is available in Version 6 to update, so you can correct any problems you might have with a stored procedure. You then can rerun the catmaint job DSNTIJTC at step 2, DSNTITC2. You will get -601 SQLCODE on the procedures that have already been defined to Version 6 and a return code of 4 on the job when you rerun it. The -601 is caused by a duplicate row on the catmaint job trying to insert a row that is already been defined to SYSIBM.SYSROUTINES from the first run. These -601 errors can be ignored.

Note

Remember to check that you have removed all data set passwords, any views on SYSIBM.SYSCOLDIST and SYSIBM.SYSCOLDISTSTATS, and convert all indexes to type 2. The sample database DSN8 is created with some type 1 indexes and has passwords on its data sets. Remember to change the passwords by following these steps: 1. Stop the database, using the -STOP DATABASE command. 2. Remove the password on all associated data sets by using VSAM access method services ALTER data.set NULLIFY(MASTERPW) command. 3. Change the password, using the DSETPASS clause of the ALTER TABLESPACE statement or the ALTER INDEX statement to a space. You must use the same password for all data sets for the same table space or index space. 4. Start the database again, using the -START DATABASE command.

Chapter 10. Migration of DB2 for OS/390 Version 5 to Version 6

183

10.1.4 Fallback considerations from Version 6 to Version 5


If you created stored procedures with the Version 6 statement CREATE PROCEDURE, you will not be able to access those stored procedures if you need to fall back to Version 5. You will receive SQLCODE -204 if you try to access a Version 6 stored procedure after fallback, because the procedure name is not in catalog SYSIBM.SYSPROCEDURES. You will need to manually keep track of your changes to SYSIBM.SYSROUTINES and SYSIBM.SYSPARMS, because on fallback to Version 5, the SYSIBM.SYSPROCEDURES table is not updated with any changes or newly created stored procedures. You will have to manually create the updates to SYSIBM.SYSPROCEDURES before you migrate, or you must have kept the DDL in a PDS that you can run and update SYSIBM.SYSPROCURES table after falling back to Version 5.

184

DB2 Java Stored Procedures: Learning by Example

Part 3. DB2 UDB for OS/390 V6 various enhancements

Copyright IBM Corp. 2000

185

186

DB2 Java Stored Procedures: Learning by Example

Chapter 11. DB2 UDB for OS/390 network computing enhancements


This chapter describes the enhancements and new support provided by DB2 UDB for OS/390 for network computing solutions that can help you to improve the development, performance, and security of your client/server applications.

11.1 DRDA support for three-part names


The following sections describe the three-part name support.

11.1.1 Three-part names prior to Version 6


With prior versions of DB2 (and with DB2 Version 6) you can use either DRDA or DB2 private protocol when making distributed calls. Prior to Version 6, the way DB2 would know which protocol to use is based on the provision of a three-part name (or an alias for a three-part name) for private protocol, or the use of the SQL CONNECT statement for DRDA. See Figure 20.

Figure 20. Three-part names prior to DB2 for OS/390 Version 6

Some of the differences between private protocol and DRDA are listed below. These differences still exist in Version 6.

Copyright IBM Corp. 2000

187

Private protocol always uses dynamic SQL. There is no way for you to specify static SQL when using private protocol. With DRDA, you can use static and dynamic SQL. Private protocol has restrictions in terms of the SQL that can be executed on the remote server. You are basically limited to DML SQL statements. With DRDA, in addition to DML, you can execute DCL and DDL statements at the remote server. Private protocol limits the server type to DB2 on the MVS platform. With DRDA, you can send/receive SQL statements to any platform that supports DRDA. Private protocol can use only SNA connections. With DB2 for OS/390 Version 5 and higher, DRDA can use SNA and TCP/IP connections. With DB2 Version 6, you have support for UDTs and LOBs. This support is only available if the underlying protocol is DRDA. LOBs can be accessed from a client only when using the DRDA protocol. Because a typical use of LOBs is on some type of workstation, DRDA is enhanced to allow a LOB value to be sent across the network. In this way, LOB values and LOB locators can be passed back and forth between a DRDA AR and AS. Both DB2 on the workstation and DB2 for OS/390 provide support for these DRDA enhancements, allowing a DB2 application to access and manipulate LOB values anywhere in the DRDA network. DB2 on the workstation, however, supports the file reference variables whereby a LOB value can be selected or inserted without the requirement for a contiguous piece of application storage to contain it. When a DRDA client sees a reference to a file reference variable in the VALUES clause of an INSERT statement or the SET clause of an UPDATE statement the DRDA client will read the files contents on the wire as a single LOB value. Similarly, when a DRDA client sees a reference to a file reference variable in the INTO clause of a SELECT or FETCH statement, the DRDA client will place the LOB value it receives from the server into the specified file. If you try to pass UDTs or LOBs using private protocol, the statement fails, and a -728 SQLCODE is returned. Stored procedures are supported only when using DRDA. See Table 12.

188

DB2 Java Stored Procedures: Learning by Example

Table 12. Private protocol v DRDA access

Category
Use of static/dynamic SQL SQL Type Remote server support Protocol support Support for Object Relational extensions (such as UDTs and LOBs) Support for stored procedures

Private Protocol
Dynamic only DML only DB2 for OS/390 only SNA only No

DRDA
Dynamic and static DML, DCL and DDL Any DRDA AS SNA and TCP/IP Yes

No

Yes

11.1.2 Three-part names in Version 6


Although DB2 Version 6 still supports the use of private protocol, it will not be enhanced in the future. Application programs using a remote three-part name, or an alias for a table with a remote three-part name, can now use the DRDA protocol if they are explicitly bound for DRDA by the use of the new BIND/REBIND option, DBPROTOCOL(DRDA). With this option, DB2 will implicitly use the DRDA protocol for remote access. Existing applications that previously resulted in private protocol flows, but are now rebound to DRDA, will not have to be rewritten. Not only can you have your existing programs converted to a DRDA flow, but new programs can be coded with less of the connection management inherent to DRDA. For example, a current DRDA program may execute these statements:
CONNECT to local; CONNECT to remote_site1; CONNECT to remote_site2; CONNECT to remote_site3; SELECT * from table3; -- (table3 SET CONNECTION to remote_site2; SELECT * from table2; -- (table2 SET CONNECTION to remote_site1; SELECT * from table1; -- (table1 SET CONNECTION to local; SELECT * from table0; -- (table0

in remote_site3) in remote_site2) in remote_site1) in local)

Chapter 11. DB2 UDB for OS/390 network computing enhancements

189

The same statements can be written as:


SELECT SELECT SELECT SELECT * * * * from from from from remote_site3.userid.table1; remote_site2.userid.table1; remote_site1.userid.table1; userid.table0;

For an illustration of these concepts, refer to Figure 21.

Figure 21. Three-part name Version 6

So, besides the advantage of minimal impact to exiting programs, the new DBPROTOCOL option produces another major advantage; coding is simplified because there is less of it. Also, if you use alias for remote tables, you achieve location transparency; if a table has to be moved from one location to the other, you do not have to change your application. It is enough to change the alias to point to another location and rebind/copy the package to that location.

190

DB2 Java Stored Procedures: Learning by Example

11.1.3 Package requirements


To effect the change at the requester, you have to rebind the local package or plan specifying DBPROTOCOL(DRDA). You have also to bind the same package (with this or another name) at the remote servers you are accessing, and include the remote servers packages in the package list of the local plan (the same way that you already do for remote packages). Once this is done, the programs that were previously using the private protocol will use DRDA. If DRDA execution is attempted, but no package is found at the remote site, a -805 SQLCODE is issued. When accessing tables using three-part names and DRDA, access to the remote server can be dynamic or static, depending on how you code your application. You can use CONNECT 1 or CONNECT 2, although you are strongly recommended to use CONNECT 2 (see Figure 22). Refer to DB2 UDB for OS/390 Version 6 SQL Reference, SC26-901, for detailed information about CONNECT (Type 1) and CONNECT (Type 2).

Figure 22. Package requirements

Chapter 11. DB2 UDB for OS/390 network computing enhancements

191

11.1.4 How it works


Figure 23 summarizes the flow that DB2 uses to identify the correct server.

SELECT * FROM LOC1.USER.TAB

DRDA

LOC1

1 - Check CURRENT SERVER 2 - CONNECT / SET CONNECTION TO LOC1 3 - SET CONNECTION back 4 - LOC1 is DORMANT

Figure 23. How it works

Following are the details of the steps shown in Figure 23: 1. DB2 first checks the value of the CURRENT SERVER special register. 2. DB2 will implicitly issue a connect or a SET CONNECTION statement to the remote location. If the program was precompiled with SQLRULES(STD) and the connection to the remote location was already established, DB2 issues the SET CONNECTION statement. Otherwise, DB2 issues the CONNECT statement. 3. Once the statement coded in the application program finishes execution, DB2 issues the SET CONNECTION statement to the previously saved value of the CURRENT SERVER special register. 4. The remote site will remain in the connection set (to maximize performance), but will be marked as a DORMANT connection. The connection management is handled automatically by DB2. There is no need for the application programmer to be concerned about SQLRULES (DB2 or STD). DB2 knows when to do a SET CONNECTION or a CONNECT. When this conversion is accomplished, the concern about having a private connection and a DRDA connection to the same location (SQLCODE -842) is eliminated.

192

DB2 Java Stored Procedures: Learning by Example

11.1.5 DBPROTOCOL bind option


These are the defaults for the DBPROTOCOL bind option: BIND PLAN/PACKAGE If not specified, this defaults to what was specified in the DSNTIP5 panel of the installation process. If you do not change it on the panel, the default is DRDA. REBIND PLAN/PACKAGE The default is what was specified the last time you bound the plan or package. Remote BIND If you specify a three-part name (LOC2.USER1.TABLE1), and in the remote system LOC2, USER1.TABLE1 is an alias for LOC3.USER1.TABLE1, then when you bind the package to LOC2, the protocol used by LOC2 to get to LOC3 is the installation default for LOC2. You have to bind the package to LOC2, and LOC3. When you bind the package to LOC2, LOC2 will not automatically create a package in LOC3. There is a new column DBPROTOCOL in SYSPACKAGE and SYSPLAN, which indicates the DBPROTOCOL bind option of PRIVATE (P) or DRDA (D).

11.1.6 Stored procedures considerations


The CALL statement to invoke a stored procedure already supported the three-part name, but at the time of the call, you had to be connected to the server specified in the stored procedure name. With Version 6, you do not have to issue the CONNECT or SET CONNECTION statement to the location where the stored procedure resides. DB2 will automatically connect to the remote location of the stored procedure.
11.1.6.1 Result sets The DESCRIBE PROCEDURE and ASSOCIATE LOCATORS statements can specify a three-part name for a remote stored procedure, and will now be executed with respect to the site specified in the three-part name. This will be done regardless of the DBPROTOCOL bind parameter.

Similarly, the statements ALLOCATE CURSOR, DESCRIBE CURSOR, FETCH cursor, and CLOSE cursor require that the application be connected to the site where the stored procedures declaring the cursor are executed. Note that the FETCH and CLOSE cursor statements also apply when a stored procedure is not being used.

Chapter 11. DB2 UDB for OS/390 network computing enhancements

193

These statements, in their syntax, contain result set locators which uniquely identify a cursor. So, although a three-part name is not contained in these statements, there is no ambiguity as to which cursor is being referenced. Therefore, the restriction about site connection has been removed for the ALLOCATE CURSOR and DESCRIBE CURSOR statements, regardless of the BIND option.
Note

When using DESCRIBE PROCEDURE and other SQL statements for accessing result sets, you should ensure that the procedure name is specified exactly as it is on the CALL statement (including the number of qualifiers used for the procedure name). See the description of the DESCRIBE PROCEDURE statement in the DB2 SQL Reference, SC26-9014 for further details.

11.1.7 Hopping
This section describes the possible hopping (three-part name) usage scenarios, which are summarized in Figure 24.

Figure 24. Hopping

194

DB2 Java Stored Procedures: Learning by Example

11.1.7.1 DRDA and private protocol The maximum level of hopping is two hops, if one of the protocols involved is private. For example, if you use a three-part name on SITE1, that refers to SITE2, and in SITE 2, this is an alias for an object residing in SITE 3. This object must be a local view or table in SITE 3; it cannot be an alias for a remote table.

In this scenario, the DRDA protocol is used in the connection between SITE 1 and SITE 2, and the private protocol is used in the connection between SITE 2 and SITE 3. The private protocol cannot be used in both.
11.1.7.2 Only DRDA protocol If you use only DRDA, there is no limit on the number of sites that you can hop, as long as there are packages at the target site. As a consequence, a middle site (SITE 2 or SITE 3 in the diagram) cannot tell how many levels have been nested. 11.1.7.3 Loop back Consider the following scenario:
On SITE 1: rtable is synonym of site2.user1.table1 On SITE 2: table1 is synonym of site1.user1.table1

In this scenario, the loop back would be possible. However, there are some scenarios where DB2 detects and avoids loop back connections. For example:
On SITE 1: rtable is synonym of site2.user1.rtable On SITE 2: rtable is synonym of site1.user1.rtable

DB2 does not allow another hop on a connection that matches the LUWID of another existing DRDA thread. So, if SITE 1 has a thread to SITE 2, and a thread from SITE 2, the incoming thread from SITE 2 will be marked so that no further hops are performed. Another example is:
On SITE 1: rtable is synonym of site2.user1.rtable On SITE 2: rtable is synonym of site3.user1.rtable On SITE 3: rtable is synonym of site1.user1.rtable

For the example above, a -904 SQLCODE with reason code 00D31052 is returned.

Chapter 11. DB2 UDB for OS/390 network computing enhancements

195

Figure 25 summarizes these scenarios.

Figure 25. Loop back

11.1.8 Advantages
Following are some more advantages of using this new enhancement: Better performance at execution time, because binding occurs when the package is bound, not during program execution. Better performance due to the fact that static statement information is not destroyed at COMMIT time. If a cursor is not specified WITH HOLD, a COMMIT will cause DB2 to discard all the statement information. If the statement is dynamic, subsequent re-execution causes another PREPARE (or REBIND) of the statement to take place.
Note

It is important to emphasize that the options available for Version 5 for truly dynamic statements, such as KEEPDYNAMIC and statement caching, also apply to Version 6. Allows access to DRDA servers that are not DB2 for OS/390 systems through the use of a three-part name (or alias).

196

DB2 Java Stored Procedures: Learning by Example

Permits hopping to non-DB2 for OS/390 systems (see 11.1.7, Hopping on page 194). Access to new DB2 functions such as stored procedures, which were added only to DRDA processing. Take advantage of DRDA DDF enhancements, such as the chained PREPARE/DESCRIBE/ pre-OPEN performance enhancements.

11.1.9 Impacts
There are some minor impacts associated with conversion to DRDA three-part table names. These include: No support for continuous block fetch. Although Version 6 provides for similar function, the OPTIMIZE FOR clause is specified. See 11.2, DRDA query block size on page 198 for details. Loop back is not allowed. See 11.1.7.3, Loop back on page 195 for details. The current restriction with CREATE, ALTER, DROP, GRANT, REVOKE, COMMENT ON, LABEL ON, RENAME is not removed. These statements (whether or not three-part name were used in coding) are excluded from private protocol. This restriction remains with the new three-part name DRDA protocol implementation. In general, only the same statements as for private protocol (DML) are allowed when using DRDA with three-part names. In addition, most SET local statements are propagated to the remote sites through the new DRDA codepoint. Only package authorization information is passed to non OS/390 DRDA servers. Authorization to a DB2 for OS/390 server (hop site) should be identical to the authorization as it currently exists. Once a server other than DB2 for OS/390 is encountered, however, only the package information will flow to that site or to downstream sites. For example, between two DB2 for OS/390 systems, the plan authorization is passed. The above is valid for DRDA and private and will continue be like that. Once DB2 hops to a non-DB2 for OS/390 system, such as DB2 UDB on the workstation, only package authorization is passed.

Chapter 11. DB2 UDB for OS/390 network computing enhancements

197

11.2 DRDA query block size


In DRDA level 1 and level 2, the amount of query data returned on each network transmission is governed by the DRDA query block size, specified by the application requester (AR). The maximum value for the DRDA query block size is 32 KB, so the amount of data exchanged between the client and the server on each data transmission is relatively small. The 32 KB limit for the DRDA query block size is a performance bottleneck for applications that need to move large amounts of data around (such as Data Propagator Relational (DPropR) and Visual Warehouse) especially when the client and the server are connected by relatively slow network connections. Because in a DRDA environment there is only one conversation, continuous block fetching (used in private protocol) cannot be deployed when using DRDA. DB2 UDB for OS/390 Version 6 implements DRDA level 3, which provides support for returning multiple DRDA query blocks on each network transmission. Although this does not remove the 32 KB limit on a single DRDA query block, it bypasses the limitation by allowing the DRDA server to send multiple 32 KB blocks in each network transmission. There are two new installation parameters, EXTRA BLOCK REQ and EXTRA BLOCK SRV, that specify the maximum number of extra negotiated query blocks to be used when the OPTIMIZE FOR n ROWS clause is coded (see 11.2.1, OPTIMIZE FOR n ROWS clause enhancements on page 198). When the client supports DRDA level 3, DRDA allows the client to specify the limit on the number of extra DRDA query blocks. The DRDA default for extra block is zero, which results in the flows that are identical to DRDA level 1 or level 2.

11.2.1 OPTIMIZE FOR n ROWS clause enhancements


Some enhancements to the OPTIMIZE FOR n ROWS clause were introduced in Version 5 to minimize the impact of sending a large block of data when just a few rows of the result set were relevant to the client application. So in general, the OPTIMIZE FOR n ROWS clause has been used only where a small number of rows are expected.

198

DB2 Java Stored Procedures: Learning by Example

With DB2 UDB for OS/390 Version 6, OPTIMIZE FOR n ROWS is also used when the result set that must be returned to the client exceeds the negotiated block size. If a DRDA client (or a stored procedure at a server) declares the cursor with the OPTIMIZE FOR n ROWS clause, the client can request extra blocks from the server, who may then send up to 32 K DRDA query blocks in one network transmission. Additionally, network I/O and SQL operations can be performed in parallel when OPTIMIZE FOR n ROWS is specified and the SQL consists of FETCH requests against the OPTIMIZE FOR n ROWS query. For example, the DRDA requester can issue an asynchronous receive operation for the next DRDA query block, while the SQL operation is processing rows from the current DRDA query block (see Figure 26).

CLIENT
OPTIMIZE FOR 10000000 ROWS

PROCESS ROWS

SYNCHRONOUS

ASYNCHRONOUS

BLOCK 1 BLOCK 2

Figure 26. OPTIMIZE FOR large number

The first block is sent synchronously. The remaining blocks are sent asynchronously. The minimum between EXTRA BLOCK SRV and EXTRA BLOCK REQ is negotiated. DRDA allows the negotiation to be conducted either at connection or at statement execution time. DB2 UDB for OS/390 Version 6 as a requester only does this at connection time, while as a server it supports negotiation either at connection or statement execution time. This allows DRDA applications to gain many of the benefits currently available in the DB2s private protocol block fetch function.

Chapter 11. DB2 UDB for OS/390 network computing enhancements

199

11.2.2 How it works


For the client, the installation parameter EXTRA BLOCK REQ specifies the maximum number of extra DRDA query blocks that this client can request. For the server, the installation parameter EXTRA BLOCK SRV specifies the maximum number of extra DRDA query blocks that this server is allowed to transmit. When the client application is coded with OPTIMIZE FOR n ROWS, where n is a large number, the following happens: 1. If the result set fits in a block, the block is sent. 2. If the result set does not fit in a block, and the client requests extra DRDA query blocks, the minimum of EXTRA BLOCK REQ and EXTRA BLOCK SRV is evaluated. 3. The extra blocks evaluated in step 2 are sent. 4. If these extra blocks are not enough (that is, there are still rows to be sent) these rows will be sent upon the next request from the client. Figure 27 shows that flow.

CLIENT EXTRA BLOCK REQ

SERVER EXTRA BLOCK SRV

Y
SEND

Rows fit in one block?

N
MINIMUM EXT REQ EXT SRV

SEND EXTRA BLOCKS

END

N
More rows?

Y
SEND on new client request

Figure 27. OPTIMIZE FOR how it works

200

DB2 Java Stored Procedures: Learning by Example

11.2.3 Usage recommendations


The OPTIMIZE FOR n ROWS clause should only be used to increase the number of DRDA query blocks in applications that have the following attributes: The application fetches a large number of rows from a read-only query. The application rarely closes the SQL cursor before reaching the end of the query answer set. The application does not issue statements other than FETCH to the DB2 server while the SQL cursor is open. In Figure 28, the DRDA client opens a cursor and fetches rows from the cursor using the OPTIMIZE FOR 1000 ROWS clause. Both the DRDA client and the DB2 server are configured to support multiple DRDA query blocks. At some point prior to the end of the query answer set, the application issues an SQL INSERT. Since OPTIMIZE FOR is being used, the DRDA connection is not available when the SQL INSERT is issued (that is, the connection is still being used to receive the DRDA query block for 1000 rows). This causes two performance problems: Application elapsed time is increased if the DRDA client has to wait for a large query answer set to be transmitted, before the DRDA connection can be used for other SQL statement. If the SQL applications closes the cursor before fetching all of the rows in the SQL answer set, the server may fetch a large number of rows unnecessarily.

Chapter 11. DB2 UDB for OS/390 network computing enhancements

201

CLIENT
..OPTIMIZE FOR 1000 ROW S; OPEN C1;

SERVER

CURSOR IS OPENED Query block with 100 rows returned Query block with 100 rows returned Query Query Query Query Query Query block block block block block block with with with with with with 100 100 100 100 100 100 rows rows rows rows rows rows returned returned returned returned returned returned

FETC H C1 INTO... FETC H C1 INTO...

INSERT INTO ....

Query block with 100 rows returned Query block with 100 rows returned Server processes INSERT statement

Figure 28. Potential issue when using OPTIMIZE FOR n ROWS

11.3 DDF connection pooling


This is another very important feature of DB2 UDB for OS/390 that allows a DRDA requester to reuse a connection for new client applications. For this support there is a new type of thread, identified as a type 2 inactive thread, which uses less storage for each thread, thus improving the throughput in a distributed environment. Following are the benefits provided by this function: DB2 can perform connection pooling between thousands of TCP/IP or SNA connections and a small number of database access threads. There are150,000 inactive threads per subsystem (but 4.8 million for Parallel Sysplex) The lower CPU cost for creating DDF threads is particularly important for workloads, such as Web Common Gateway Interface (CGI) applications, which connect and disconnect to DB2 very frequently. There is now reduced storage necessary per DDF. RELEASE(DEALLOACTE) is supported for inactive DDF threads. DB2 allows new DRDA transactions to reuse database threads (similar to CICS and IMS).

202

DB2 Java Stored Procedures: Learning by Example

DB 2 Connect Enterprise Edition

Inactive thread pool

Active thread pool

AIX HP -UX Solaris Sinix OS /2 W INDOW 3.x, 95, NT

O S/2

AIX HP-UX S olaris Sinix

WINDOW 3.x, 95, NT

Figure 29. DDF connection pooling

11.4 STOP DDF MODE(SUSPEND) command


DB2 for OS/390 Version supports a new command that quiesces the DDF workload:
-STOP DDF MODE(SUSPEND)

Using this DB2 command, you can make DDLs or other changes without breaking the connections to your DDF clients. This feature is very important and helpful to improve the overall server availability for e-business and client/server applications. When the DB2 command, -STOP DDF MODE(SUSPEND) is issued, it has the following effects: Holds INACTIVE threads in INACTIVE state, until a -START DDF command is issued. Terminates all DDF pool threads. Prevents the initiation of all inbound DDF work. Waits for ACTIVE threads to reach the INACTIVE state. After completion, no DDF user will hold locks on any DB2 object.

Chapter 11. DB2 UDB for OS/390 network computing enhancements

203

MODE(SUSPEND) is intended to be used at a DB2 for OS/390 DRDA server, especially one that has DDF THREADS = INACTIVE when there are locking conflicts between DDL and client access to the data. This function will quiesce DDF activity and terminate the DDF pool of data base access threads used to service the client requests, thus making the database available for maintenance, including DDL. The fact that MODE(SUSPEND) completes successfully does not guarantee that database resources are not still held if there is any activity other than inbound DDF processing being performed. It may be necessary to use -CANCEL THREAD to terminate other processing that is being performed in order to free the database resources. See Table 13 for a description of the actions taken when a START DDF or a STOP (DB2 or DDF) command is issued depending on the current DDF state.
Table 13. START / STOP command versus DDF status

Command DDF status


Starting Started Stopping Stopped Suspending Suspended

START DDF
Error Error Error OK (start) OK (resume) OK (resume)

STOP (DB2 or DDF)


Error OK (stop) Error Error OK (stop) OK (stop)

STOP FORCE (DB2 or DDF)


Error OK (stop) Error Error OK (stop) OK (stop)

STOP DDF MODE(SUSPEND)


Error OK (suspend) Error Error Error Error

11.4.1 Command syntax


This command allows that requests received by DB2, that would normally cause DDF work to be dispatched, including requests for new connections, are instead queued. Outbound DDF processing is not affected by this command.

204

DB2 Java Stored Procedures: Learning by Example

Following is the command syntax:


>>--STOP DDF--------------------------------------------->< | | |--MODE-----( QUIESCE )------------------| | | |--( FORCE )----------------| | | |--(SUSPEND)------------------| | | |--CANCEL(n)--| | | |--WAIT(n)----|

If CANCEL or WAIT are not specified, then this command waits for all active DDF database access threads to terminate. If this is not the desired affect, then how long the command will wait and what action will be taken after a specified time period can be controlled by the CANCEL and WAIT optional keywords. CANCEL If suspend processing has not completed successfully in n seconds, cancel all active DDF database access threads. CANCEL has a valid range of 0-9999 seconds. WAIT If suspend processing has not completed successfully in n seconds, resume DDF processing again. WAIT has a valid range of 0-9999 seconds. The affect of the WAIT option is the same as if a -START DDF command was issued after n seconds if the suspend process has not completed successfully during that period.
Note:

See Appendix A, New messages and error codes on page 285 for new messages and error codes provided to support this feature.

11.5 Declared Global Temporary Tables


DB2 for OS/390 Version 5 provides support for the function, CREATE Global Temporary Tables. The way that this support was implemented did address some customer needs, such as for Business Intelligence (BI) solutions and porting applications from Oracle, Sybase, and SQL Server.

Chapter 11. DB2 UDB for OS/390 network computing enhancements

205

With BI, there are many cases when you need to pull data out of the database, process the data, and then use it for subsequent join operations. With customers moving their application from Sybase, Oracle, or SQL Server to DB2, we found out that those products had a particular style that was different from that expected by our global temporary table support. DB2 UDB for OS/390 Version 6 provides support for declared global temporary tables, which has the same style, to provide easy porting from Oracle, Sybase, and SQL Server, as well as providing functions that simplify its use for BI. The main enhancements for declared global temporary tables are these: Support for indexes This will be helpful when you use temporary tables for join operations. Without indexes, DB2 would have to do a table space scan. When the create index statement is issued, DB2 records that information in memory; there is no catalog activity. Tables do not have to be predefined in the DB2 catalog Basically, in the middle of your program you just have to issue a new statement DECLARE GLOBAL TEMPORARY TABLE, which is a dynamic SQL statement. It does not go out to the catalog and change it. When you issue the statement, DB2 does this in memory, so only your execution can see it. The temporary table description is not shared across application processes. Each application process that uses the declare global temporary table can define the same qualified table name, with a possibly unique description for the temporary table. In addition, when issuing the DECLARE GLOBAL TEMPORARY TABLE statement, the columns definitions can be implicitly defined as a result of a SELECT statement. This means that you can populate your temporary table through the same one SQL statement used to define its columns. Full support for delete and update operations Declared global temporary tables are like regular tables. You can delete the rows, update the rows. This was not supported with Global Temporary Tables; only insert and massive delete were supported. No catalog contention at runtime This is very important for BI solutions. Using global temporary tables for the intermediate tables, you will not have the catalog contention that you would have with regular create of a real table, where operations such as creating indexes, huge volume of applications running in parallel update the catalog simultaneously.

206

DB2 Java Stored Procedures: Learning by Example

11.5.1 Usability considerations


Global temporary tables can be very helpful. They are recommended for use in scenarios such as: BI applications; e-business and client/server applications in which you want to move query data into an area that does not interfere with the OLTP processing; staging data extracted from an IMS database; and making such data accessible to ODBC clients. The additional facilities offered by declared global temporary tables make them a more attractive option than created global temporary tables under most circumstances. However, there are some situations where created temporary tables may still be preferable. For example, an application that had to support very high insert rates into the temporary table, but did not need any of the additional facilities provided by declared temporary tables, could realize performance gains due to the lack of logging for inserts to created temporary tables. Following are some considerations of using declared global temporary tables: Logging There is logging for declared temporary tables, providing the ability of doing rollback or UNDO logging up to the last COMMIT point. There is no need for the REDO recovery ability. Persistence Declared global temporary tables will typically persist for the life of your transaction until you issue a commit or roll it back. However, there is a clause with which you can specify that you want that this table to exist beyond the commit, for allocate duration, or to explicitly drop it. Qualifier The qualifier for a global temporary table is always SESSION. You do not have any flexibility on choice of a schema name. The word SESSION becomes a special name that we can easily recognize. When you say SESSION, you are talking about global temporary tables.
Note:

We recommend that you do not use the word SESSION as one of your schema names.

Chapter 11. DB2 UDB for OS/390 network computing enhancements

207

Workfiles Global temporary tables do not use the regular workfiles (DSNDB07). This means that they will not compete with your regular workload. Segmented table spaces in a special temporary database are used as the space for the table. Authorization You do not need any special authorization privilege to create or declare a temporary table. Every user automatically has the privilege to create these on their own.

11.6 Savepoints
A savepoint represents the state of data and schema at a particular point in time. An application may set named savepoints within a transaction, then as dictated by application logic, roll back subsequent data and schema changes without affecting the overall outcome of the transaction. The scope of a savepoint is the DBMS on which it is set. Savepoints enable the coding of contingency or what-if logic and could be useful in the following scenarios. Programs with sophisticated error recovery. To undo stored procedure updates when an error is detected. With no savepoints taken in the calling application, a rollback in a stored procedure will roll back the entire unit of recovery, including all work done by the caller prior to the stored procedure being invoked. A savepoint taken immediately prior to the stored procedure call could be used to allow the stored procedure to rollback in the event of a problem being encountered, without also undoing any of the changes made by the caller within the same unit of work. You can set savepoints by using the SAVEPOINT syntax documented in the DB2 UDB for OS/390 Version 6 SQL Reference, SC26-9014-01. The savepoint name can be up to 128 characters, and we suggest that you use a meaningful name. You can use the UNIQUE OPTION to assert that the savepoint name will not be reused within the transaction. If you omit the UNIQUE option and reuse the savepoint name, the old savepoint will be destroyed. Note that this is different from using the RELEASE SAVEPOINT statement, which will release all savepoints with that name.

208

DB2 Java Stored Procedures: Learning by Example

When you issue the SAVEPOINT statement, DB2 writes an external savepoint log record. Savepoints that you create are often termed external (as opposed to internal) because DB2 already uses internal savepoints as its mechanism for backing out specific units of recovery. Internal savepoints are used by DB2 only, cannot be accessed through an application, and may be liable to change in future releases or as a result of applying maintenance. In contrast, you have full control over external savepoints. To roll back to an external savepoint you have set, use the ROLLBACK TO SAVEPOINT svptname statement. This will back out all data and schema changes that were made after the savepoint. The following will not be backed out: Any updates outside of the local DBMS (such as remote DB2s, VSAM, CICS, IMS) Changes to created temporary tables (however, changes to declared temporary tables are backed out) The opening and closing of cursors Changes in cursor positioning The acquisition and release of locks The caching of the rolled back statements

11.6.1 Connecting to other DB2 systems


While there are outstanding savepoints, you cannot access a remote DBMS using DB2 private protocol access or DRDA using aliases or three-part names. For example, if there is a savepoint set at location A, location A cannot connect to location B using either of these two ways to access data. DRDA access using a CONNECT statement is allowed; however, the savepoints are local to their site. For example, location A can connect to location B, but the savepoint set at A is unknown to B and does not cover any operations performed at location B. You should note that a savepoint set prior to a CONNECT is known only at the local site, and a savepoint set after a connect is known only at the remote site. Consequently, we recommend that the processing at the alternate site to where the savepoint is known should be read-only.

Chapter 11. DB2 UDB for OS/390 network computing enhancements

209

DB2 does not restrict the use of aliases and three-part names to connect to a remote site when there are outstanding savepoints at the remote site. However, we do not recommend this; because you will not necessarily know, when you access a three-part name, whether it is local or remote. Also, the location of the data may change without knowledge of the application. It follows, therefore, that the outcome of a rollback to savepoint will be uncertain for the application. We recommend that you code the RELEASE SAVEPOINT savepoint name statement to release savepoints that are no longer required for clarity and to reenable the operation of SQL that resolves to remote locations.

11.6.2 Restrictions on using savepoints


You cannot use savepoints in global transactions, triggers, user-defined functions, or in stored procedures that are nested within triggers or user-defined functions.

11.6.3 Savepoint performance


The overhead of maintaining a savepoint is minimal. The measurements performed show that the cost of taking a savepoint is equivalent to a DML instruction.

11.7 Identity columns


A common requirement for many relational database applications is the generation of unique key values when inserting rows into a table. In the absence of any DB2 feature to support this requirement, many users have been forced to implement their own solutions (such as generating keys based on reversed timestamp values1 , or using a single-row table that contains the highest used key value2). Many other relational databases provide the ability to automatically generate these key values, based upon parameters specified at the time the table is created. This functionality, which DB2 terms identity columns, has been added to DB2 for OS/390 Version 6 via APAR PQ306523 , and is also available within DB2 for UNIX, Windows and OS/2 as part of Version 7.

1 This solution is not guaranteed to generate unique values. 2 3

This solution has the potential to cause serious performance bottlenecks, due to lock waits on the 1-row table. These are exacerbated in a data sharing environment.

If you intend to unload tables containing ID columns we recommend that you also look at PQ38493. See 11.7.4, Utility issues on page 218 for details.

210

DB2 Java Stored Procedures: Learning by Example

The remainder of this chapter describes DB2s implementation of this important new feature, which can greatly reduce the amount of work required to port some applications from other vendors database products to DB2 UDB. Unless otherwise specified, all references are to the DB2 for OS/390 product. A section at the end of this chapter deals with the major implementation differences between the OS/390 and UNIX, Windows NT, and OS/2 products.

11.7.1 Overview
DB2s implementation of this feature fulfills the following design objectives: Guarantee uniqueness, both within an individual subsystem and across a data sharing group (if applicable). Provide the ability for an application to either specify an explicit value for an identity column during INSERT, or have DB2 generate the value if required4 . Minimize the resource usage and elapsed time overheads required to generate the value in a highly concurrent environment. Provide recoverability in the event of a DB2 system failure by reconstructing the last value before the outage, thereby ensuring that uniqueness is maintained. At the time a table is created, you may specify a single numeric column within the table as being an identity column. Included in this specification is the columns start value and increment/decrement value, and whether DB2 is to allow explicit values to be supplied.

11.7.2 Data definition issues


This section looks at the DDL issues associated with creating and altering tables containing identity columns.
11.7.2.1 Creating tables with identity columns The AS IDENTITY attribute can be specified as part of the table definition on the CREATE TABLE statement or when adding a column with the ALTER TABLE statement to create an identity column. In addition, when a table is being created like another table that contains an identity column, a new option on the LIKE clause can be used to specify whether the identity column attributes are inherited.

Intended for use in data propagation environments.

Chapter 11. DB2 UDB for OS/390 network computing enhancements

211

+----------------------------------------------------------+ | COLUMN-DEFINITION: | | |--column-name--data-type--.----------------.----------| | | '-column-options-' | | COLUMN-OPTIONS: | | <-----------------------------------------------< | | |---.---------------------------------------------.----| | | |-NOT NULL------------------------------------| | | |-.-UNIQUE------.-----------------------------| | | | '-PRIMARY KEY-' | | | |-FIELDPROC--program-name--.----------------.-| | | | | <-,------< | | | | | '-(--constant--)-' | | | |-references-clause---------------------------| | | |-check-constraint----------------------------| | | '-generated-column-spec-----------------------' | | GENERATED-COLUMN-SPEC: | | |-+--------------------------------------------------+-| | | | +-WITH-+ | | | |-'------'--DEFAULT--.----------------.------------| | | | '-default-clause-' | | | | | | | +-GENERATED--.-ALWAYS-----.--.------------------.--+ | | '-BY DEFAULT-' '-as-identity-spec-' | | AS-IDENTITY-SPEC: | | |-AS IDENTITY-+---------------------------------------+-|| | | <-,-----------------------------< | | | | +---1----+ | | | | | | | | | | | +-(---+-START WITH--+-nconst-+---+--+-)-+ | | | | | | | +---1----+ | | | | | | | | | |-INCREMENT BY--+-nconst-+-+ | | | | | | | +-CACHE 20------+ | | | | | | | | | +-+-NO CACHE------+--------+ | | | | | | +-CACHE-integer-+ | | LIKE-clause (CREATE TABLE) | | |-----LIKE--+--table-name--+------------------------>> | | | | | | +--view-name---+ | | >>--+---------------------------------------------+---| | | | | |

212

DB2 Java Stored Procedures: Learning by Example

| | +-COLUMN ATTRIBUTES-+ | | | | | | | | | +--INCLUDING IDENTITY--+-------------------+--+ | +----------------------------------------------------------+

GENERATED

Specifies that DB2 generates values for the column. You must specify GENERATED if the column is to be considered an identity column, or if the data type of the column is a ROWID (or a distinct type that is based on a ROWID).
ALWAYS

Specifies that DB2 always generates a value for the column when a row is inserted into the table.
BY DEFAULT

Specifies that DB2 generates a value for the column when a row is inserted into the table unless a value is specified.
BY DEFAULT is the recommended value only when you are using data propagation.

AS IDENTITY

Specifies that the column is an identity column for the table. A table can have only one identity column. AS IDENTITY can be specified only if the data type for the column is an exact numeric type with a scale of zero (SMALLINT, INTEGER, DECIMAL with a scale of zero, or a distinct type based on one of these types). An identity column is implicitly NOT NULL.
START WITH numeric-constant

Specifies the first value for the identity column. The value can be a positive or negative value that could be assigned to the column, as long as there are no non-zero digits to the right of the decimal point. The default is 1.

Chapter 11. DB2 UDB for OS/390 network computing enhancements

213

INCREMENT BY numeric-constant

Specifies the interval between consecutive values of the identity column. This value can be any positive or negative value that is not 0, does not exceed the value of a large integer constant, and could be assigned to this column, as long as there are no non-zero digits to the right of the decimal point. The default is 1. If the value is positive, the sequence of values for the identity column ascends. If the value is negative, the sequence of values for the identity column descends.
CACHE or NO CACHE

Specifies whether to keep some preallocated values in memory. Preallocating and storing values in the cache improves performance for inserting rows into a table that has an identity column.
CACHE integer

Specifies the number of values of the identity column sequence that DB2 preallocates and keeps in memory. The minimum value that can be specified is 2, and the maximum is the largest value that can be represented as an integer. The default is 20. During a system failure, all cached identity column values that are yet to be assigned are lost and, thus, will never be used. Therefore, the value specified for CACHE also represents the maximum number of values for the identity column that could be lost during a system failure. In a data sharing environment, each member gets its own range of <integer> consecutive values to assign.
NO CACHE

Specifies that caching is not to be used.


LIKE-clause (for CREATE TABLE)

Specifies that the columns of the table have exactly the same name and description as the columns of the identified table or view. However, for an identity column, the new table inherits only the data type of the identity column; none of the other column attributes are inherited unless the new INCLUDING IDENTITY clause is specified.

214

DB2 Java Stored Procedures: Learning by Example

INCLUDING IDENTITY COLUMN ATTRIBUTES

Specifies that the new table inherits all of the column attributes of the identity column. If the table identified by LIKE does not have an identity column, the INCLUDING IDENTITY clause is ignored. If the identified object of LIKE is a view, INCLUDING IDENTITY COLUMN ATTRIBUTES cannot be specified.
11.7.2.2 Adding an identity column to an existing table The ALTER TABLE ADD COLUMN statement can be used to add an ID column to an existing table. Unless the table is empty, DB2 will place it in reorg pending status (if the table is partitioned, then all partitions are reorg pending).

Running REORG will materialize the ID column values for all rows in the table (again, if the table is partitioned, REORG must be run against the entire table space and not just one partition). The order in which DB2 will allocate the ID column values is system determined.
11.7.2.3 Altering an identity column To alter the attributes of an existing identity column, you must drop and recreate the table (using your normal procedures for conserving the table data, indexes, authorities, and other dependent objects).

When re-creating the table, you should ensure that the START WITH value that is specified is set to the next value that you want DB2 to generate after the table is reloaded with data. See 11.7.2.4, Copying tables between subsystems on page 216 for an SQL statement that can be used to determine this. Also, as you will be using the LOAD utility to reload the table data after it is recreated, you must specify GENERATED BY DEFAULT so that LOAD is allowed to reuse the previously allocated identity column values. Once this is done, there is no way to go back to GENERATED ALWAYS.

Note

See 11.7.4, Utility issues on page 218 for further considerations when unloading and loading tables containing identity columns.

Chapter 11. DB2 UDB for OS/390 network computing enhancements

215

Note

Under very specific circumstances, it may be possible to retain the GENERATED ALWAYS attribute by doing the following: 1. Make the table unavailable to prevent further INSERT/LOAD activity. 2. Unload the table in ID column order. 3. Drop and re-create the table as required, specifying GENERATED ALWAYS for the ID column and the original value for the START WITH attribute. 4. LOAD the data back into the table, excluding the unloaded ID column values from load operation, and thereby allowing DB2 to regenerate them during the load operation. However, if you want to ensure that the ID column key values remain the same (essential if the ID column is a primary key, and referenced as a foreign key in another table) you need to be very careful. Be absolutely sure that: No gaps appear in the ID column sequence (for example, if the increment is 1 and the start value is 1, the table must contain rows with values 1, 2, 3, 4, and so on, with no gaps in the series). Note that it is very likely that gaps will exist, for example, due to caching in a data sharing environment, or rollbacks of failed units of work. No one else is able to LOAD or INSERT into the table in between the time you re-create it and the time the LOAD operation is conducted.

11.7.2.4 Copying tables between subsystems Special consideration has to be given to avoiding overlaps when copying tables with ID columns between subsystems.

Consider the following procedure: 1. Stop the table space containing the table on the source subsystem, to stop any new rows from being inserted. 2. Run the following catalog query to determine the start value and increment for the CREATE TABLE statement on the target system:
SELECT B.DCREATOR, B.DNAME, B.DCOLNAME, A.INCREMENT+A.MAXASSIGNEDVAL AS NEW_START_VALUE, A.INCREMENT

216

DB2 Java Stored Procedures: Learning by Example

FROM

WHERE AND

SYSIBM.SYSSEQUENCES A INNER JOIN SYSIBM.SYSSEQUENCESDEP B ON A.SEQUENCEID = B.BSEQUENCEID B.DCREATOR = 'ACMEE' B.DNAME = 'CUSTOMER';

In these statements, the values for B.DCREATOR and B.DNAME predicates are replaced with your own table creator and table name. 3. Create the table on the target subsystem, using the start and increment values determined from the previous step. 4. Stop the table space on the target system, to prevent rows from being inserted until it is populated. 5. Copy the data from the source to the target (using DSN1COPY or similar) 6. Start the table on the target subsystem (and also the source if required).

11.7.3 Data manipulation issues


This section covers the implications of executing INSERT and UPDATE SQL statements against tables containing ID columns.
11.7.3.1 Insert If a table has an ID column defined as GENERATED ALWAYS, you may not explicitly specify a value for that column during INSERT processing (any attempt to do so will result in SQLSTATE 428C9, SQLCODE -798). You must therefore either omit the column entirely from the INSERT statement, or use the SQL DEFAULT clause.

For example, if table CUSTOMER has three columns: CUST_NO, CUST_FIRSTNAME and CUST_LASTNAME, where CUST_NO is a GENERATED ALWAYS ID column, an insert could be performed with either of the two methods shown below:
INSERT INTO CUSTOMER (CUST_FIRSTNAME, CUST_LASTNAME) VALUES (John, Doe); INSERT INTO CUSTOMER (CUST_NO, CUST_FIRSTNAME, CUST_LASTNAME) VALUES (DEFAULT, John, Doe);

For GENERATED BY DEFAULT ID columns, you may either use the above syntax to allow DB2 to generate the value, or explicitly specify a value in the normal way. As previously noted, DB2 does not do any checking for explicitly

Chapter 11. DB2 UDB for OS/390 network computing enhancements

217

supplied ID column values, so you should consider defining a unique index on the column if you wish to enforce uniqueness.
11.7.3.2 Update UPDATE statements are not allowed against GENERATED ALWAYS ID columns (SQLSTATE 42808, SQLCODE -151).

If an ID column is defined as GENERATED BY DEFAULT, updates are allowed. However, as for INSERT operations, DB2 will not do any validation of the updated column value.

11.7.4 Utility issues


This section covers the implications of executing DB2 utilities against tables containing ID columns.
11.7.4.1 REORG As mentioned previously, adding an ID column to an existed table that contains data using the ALTER TABLE ADD COLUMN statement will result in the table space being placed in reorg pending status. Running reorg will cause DB2 to generate the ID column values (in a system-determined order) and remove the REORP status.
APAR PQ38493 - Unloading Tables Containing Identity Columns

APAR PQ38493 introduces additional features to support the unload and load of identity columns. With the APAR applied, DB2 will include a dummy field called DSN_IDENTITY to represent the identity column within the LOAD statement produced by REORG UNLOAD EXTERNAL and REORG DISCARD. A new option called IGNOREFIELDS will also be present in the LOAD deck. When loading into a table with a GENERATED ALWAYS identity column, the IGNOREFIELDS option will cause LOAD to ignore the DSN_IDENTITY field, allowing LOAD to generate its own values. To load the data into a table with a GENERATED BY DEFAULT identity column (or no identity column) the IGNOREFIELDS option should be removed from the LOAD deck and the DSN_IDENTITY field renamed to point to the corresponding column in the target table. The unloaded data values will then be used. If the APAR has not been applied, the utility will omit field specifications for GENERATED ALWAYS ID columns.

218

DB2 Java Stored Procedures: Learning by Example

Identity Columns and RI

Some complications arise when a table has been altered to add an ID column and the table is part of a referential set. If that table is recovered to a point in time after the ALTER but before the REORG, it is possible for the table space to be in both check pending and reorg pending state. To resolve this situation, you can now run REORG with both CHECKP and REORP states set. After completion, CHECKP will still be set, but this can be removed by running CHECK DATA as usual.

11.7.4.2 LOAD Running the LOAD utility against a table containing ID columns will result in the same rules being applied as for INSERT processing when generating data values.

Where the ID column has been defined as GENERATED ALWAYS, DB2 will generate a value for that column as the row is loaded. You may not explicitly include ID columns in the field specification. When loading data produced from a REORG UNLOAD external operation with PQ38493 applied you can use the new IGNOREFIELDS keyword to instruct DB2 to ignore any identity column fields in the unloaded data (see description in previous section). For GENERATED BY DEFAULT, you may include the ID column in the field specification. If you do so, the supplied value in the input data file will be used. Otherwise, the value is generated by DB2. The DEFAULTIF clause can be used to get DB2 to generate a value if required. When loading data produced from a REORG UNLOAD external operation with PQ38493 applied you should remove the IGNOREFIELDS keyword to instruct DB2 to use the unloaded values (see description in previous section). For partitioned tables, you may not run the load against a single partition via LOAD INTO TABLE PART if the ID column in part of the partitioning key. If a table space has been placed in reorg pending state by using ALTER TABLE ADD COLUMN to add an ID column to a populated table, you may use LOAD REPLACE to reset the status if you wish to reload the table rather than reorganize it.

Chapter 11. DB2 UDB for OS/390 network computing enhancements

219

11.7.4.3 RECOVER As mentioned in the note above, some complications can arise when using RECOVER to restore a table space to an earlier point in time when an ID column has been added.

If the table space is recovered to a point in time between the ALTER TABLE and the subsequent REORG, the REORP status will be set upon completion of the RECOVER. Some issues can also arise regarding the highest generated value following a recovery. If a table is recovered to a prior point in time, DB2 will not reset the highest generated value for the table. This can lead to large gaps in the series of generated values, which may cause problems for some types of applications. For example, a table has an ID column defined as START WITH 1 INCREMENT BY 1, and has 1000 rows in it. The table is then recovered to an earlier point in time, where only 500 rows existed. The next INSERT operation generates a value of 1001, as DB2 will continue to use the previously generated high value, and there will be a gap in the generated values between 501 and 999.

11.7.5 Other properties


You should be aware of a number of restrictions and other properties of identity columns: The identity column must have a numeric data type of SMALLINT, INTEGER, or DECIMAL with a scale of zero (or a distinct type based on one of these types), and cannot be nullable. Only one identity column is allowed per table, and that column may not have an edit procedure specified for it. You cannot specify an edit procedure for a table containing an identity column. There is no guarantee that DB2 will allocate numbers sequentially. If a given transaction increments an identity counter twice, it is possible that the two generated values will not be sequential (possibly due to other transactions inserting into the same table). If sequential numbers are absolutely necessary, you may want to consider taking an exclusive lock on the table, but this can have a negative impact on application concurrency5.

5 And in a data sharing environment, explicitly locking the table also introduces the possibility of an exclusive retained

lock on the table if the member fails.

220

DB2 Java Stored Procedures: Learning by Example

There may be gaps in the generated column values. This can happen if a transaction is rolled back after allocating a new value, or (in a data sharing environment) if a subsystem fails and had not used all of the numbers reserved in its cache. In a data sharing environment with caching enabled, identity column values may not be inserted into the table in numeric order, as each member will allocate the next unused value in its own cache. For example, if member DB2A caches numbers 1-20 and member DB2B caches 21-40, it is possible that an INSERT from DB2B will use a value of 26, to be followed by an INSERT from DB2A with a value of 14. Global temporary tables may not contain identity columns.

11.7.6 DB2 catalog table considerations


In this section we provide some considerations on DB2 catalog tables.
11.7.6.1 New catalog tables Two new catalog tables (and associated indexes) have been introduced to DB2 for OS/390 to support ID columns:

SYSIBM.SYSSEQUENCES contains one row for each ID column, and records attributes such as the internal DB2 name for the column (SEQUENCEID), its defined start (START) and increment (INCREMENT) values, and the currently used high value (MAXASSIGNEDVAL). SYSIBM.SYSSEQUENCESDEP contains one row for each identity column, and links an ID column definition on SYSSEQUENCES (via BSEQUENCEID) to its corresponding definition in SYSCOLUMNS (via DNAME and DCOLNAME). Both of these tables reside in their own table spaces, called SYSEQ and SYSSEQ2 respectively. On other platforms, only the SYSIBM.SYSSEQUENCES table exists, but this contains mostly the same information as the S/390 implementation.
11.7.6.2 Changed catalog tables The usage of the DEFAULT column in SYSIBM.SYSCOLUMNS has been altered for ID columns as follows:

Set to I if column is an ID column and is GENERATED ALWAYS Set to J if column is an ID column and is GENERATED BY DEFAULT Note that the UPDATES column is always set to Y for ID columns, but as previously noted, GENERATED ALWAYS columns cannot be updated.

Chapter 11. DB2 UDB for OS/390 network computing enhancements

221

11.7.6.3 Catalog recovery issues As part of the DB2 catalog, the new tables must be included in your routine catalog backup and recovery jobs.

When recovering the catalog to a prior point in time, you should be aware of the implications this will have for tables containing ID columns. Recovery of SYSIBM.SYSSEQUENCES to a previous point in time may result in duplicate values being generated. To avoid this, consider one of the following options: Recover all table spaces containing tables with ID columns to the same point in time as the catalog is recovered to. Following the catalog recovery, determine the highest used ID column value within all ID column tables, then drop and recreate the table with a new START WITH value as described in 11.7.2.3, Altering an identity column on page 215.

11.7.7 Usage recommendations


In this section we provide some usage recommendations for indexing.
11.7.7.1 Indexing Use of the GENERATED BY DEFAULT clause allows you to optionally specify an explicit value for an identity column at the time the row is inserted. In order to guarantee uniqueness, DB2 will force you to create a unique index on the identity column in this situation.

However, given that identity columns will commonly be used as primary keys within a table, you should create a unique index on the column, even where GENERATED ALWAYS is used.
11.7.7.2 Retrieving generated values One of the issues you will need to be aware of when using identity columns is retrieving the unique value generated by DB2 following an insert.

For example, where a referential relationship exists between two tables, it is common to use the primary key of the parent table as a foreign key in the dependent table, as shown in Figure 30.

222

DB2 Java Stored Procedures: Learning by Example

CUSTOMER (Parent Table)


CUST_NO FIRSTNAME LASTNAME

ORDER (Dependent Table)


ORDER_NO CUST_NO ORDER_DATE

Figure 30. Typical parent / dependent relationship

Lets assume that the CUST_NO column of the parent table and the ORDER_NO column of the dependent table are both defined as identity columns, and that we wish to insert new rows into both tables. We may insert a row into the CUSTOMER table using the following SQL statement:
INSERT INTO CUSTOMER (FIRSTNAME, LASTNAME) VALUES (John, Doe);

The INSERT into the parent table is successful, with DB2 automatically generating a value for CUST_NO based upon the parameters we specified when the table was created. However, when we want to insert an associated row into the dependent table, we dont know what value to use for the CUST_NO column. This issue is being addressed via an APAR enhancement to DB2 that implements a new built-in function to return the most recently generated ID column value within the current unit of work. However, there are some requirements that this enhancement cannot address, so you may also need to consider alternative solutions.
Note

Both of the solutions presented below assume you will be using singleton inserts. The techniques will not work with mass insert operations (for example, an INSERT with embedded SELECT).

Chapter 11. DB2 UDB for OS/390 network computing enhancements

223

Use of IDENTITY_VAL_LOCAL function APAR PQ36328 introduces a new built-in function called IDENTITY_VAL_LOCAL. This function returns the most recently generated ID column value for a single-row insert within the current unit of work at the current processing level6 . The function returns a DECIMAL(31,0) value, regardless of the data type of the underlying ID column.
To use the previous example, our program successfully inserts a row into the CUSTOMER table using the following SQL:
INSERT INTO CUSTOMER (FIRSTNAME, LASTNAME) VALUES (John, Doe);

We will then be able to handle the subsequent insert into the ORDER table using the following SQL:
INSERT INTO ORDER (CUST_NO, ORDER_DATE) VALUES (IDENTITY_VAL_LOCAL(), CURRENT DATE);

Expressions in a VALUES clause are evaluated before the actual insert takes place. Therefore, the most recent generated ID column value within the processing level is for the previous insert into the CUSTOMER table, and the IDENTITY_VAL_LOCAL function within the subsequent insert into ORDER will work. There are a number of important caveats and restrictions to the use of this function, which you should be aware of: If possible, use the function immediately after the INSERT statement that generates the required ID column value. Any subsequent inserts will make it impossible to retrieve the value using this function. Where a suitable INSERT has not been performed at the current processing level, or a COMMIT or ROLLBACK has occurred since the most recent INSERT, a null value is returned. You need to take special care when using triggers in conjunction with this function. For instance, before-insert triggers will not be able to retrieve the generated value, and after-insert triggers can only retrieve values for inserts performed within the trigger body itself. Ensure that the original INSERT operation was successful before invoking the IDENTITY_VAL_LOCAL function, as the value returned following a failed INSERT is unpredictable.
6 In this context, a

processing level is all of the code within a single program, or trigger, or stored procedure. Therefore, a program calling a stored procedure which executes some SQL that invokes a trigger consists of three processing levels.

224

DB2 Java Stored Procedures: Learning by Example

Use of an after-insert trigger If you are unable to use the IDENTITY_VAL_LOCAL function, you may want to consider the use of a simple after-insert trigger to capture the generated value.
To use this technique, you should: 1. Create a global temporary table like the one shown in Figure 31 to hold the generated value.

CREATE GLOBAL TEMPORARY TABLE GTT_CUST_NO ( CUST_NO INTEGER NOT NULL );


Figure 31. Example DDL for a global temporary table

2. Create an after-insert trigger on the table with the ID column, to retrieve the generated ID column value and insert it into the global temporary table. An example of this is shown in Figure 32 below.

CREATE TRIGGER CUST_IA AFTER INSERT ON CUSTOMER REFERENCING NEW AS NEWROW FOR EACH ROW MODE DB2SQL BEGIN ATOMIC INSERT INTO GTT_CUST_NO (CUST_NO) VALUES (NEWROW.CUST_NO); END;
Figure 32. Example DDL for an after-insert trigger

Chapter 11. DB2 UDB for OS/390 network computing enhancements

225

Note

If you use SPUFI to create your triggers, you will probably encounter an error, due to the fact that SPUFI mistakes any semicolons in the BEGIN ATOMIC section as the end of the CREATE TRIGGER statement. To avoid this problem, you can terminate all statements within the SPUFI file (except the ones in the BEGIN ATOMIC section of your triggers!) with another character (a colon, for example) and update your SPUFI defaults to use this as the statement terminator. 3. From within your application program, INSERT the row into the table (thereby invoking the trigger). 4. SELECT the generated value from the global temporary table after the INSERT. 5. If further inserts will be done within the same unit of work, the row should then be deleted from the global temporary table ready for the process to be repeated. This technique is illustrated in Figure 33.

226

DB2 Java Stored Procedures: Learning by Example

Your program
... INSERT INTO CUSTOMER (FIRSTNAME, LASTNAME) VALUES ('JOHN', 'DOE') ... SELECT CUST_NO FROM GTT_CUST_NO ....

CUSTOMER
CUST_NO (ID column) 1 0010 FIRSTNAME JOHN LASTNAME DOE

CUST_NO 0010

GTT_CUST_NO

1. Program inserts row into table and DB2 generates CUST_NO value. 2. Trigger is fired, and inserts generated CUST_NO value into global temporary table. 3. Program retrieves CUST_NO value from global temporary table.

Figure 33. After-insert trigger to retrieve the generated value of an id-column

Chapter 11. DB2 UDB for OS/390 network computing enhancements

227

11.7.8 Use of identity columns versus ROWID columns


DB2 V6 introduced a new data type called ROWID. ROWID columns and ID columns share some characteristics, but have also a number of important differences. The two options are compared in Table 14.
Table 14. Comparison of Identity and ROWID columns

Attribute

Identity columns

ROWID columns

Supports DB2 generated or user-supplied valuesa DB2 guarantees uniqueness of generated values Regularly ascending or descending according to user-defined rules Supported data types

Yes Yes Yes


SMALLINT, INTEGER or DECIMAL
b

Yes Yes No
VARCHAR(40)

Easily understood external representation of generated values? Comparable with other data types? Can be used to reference LOB columns? Can be used for direct row accessc?

Yes Yes No No

No No Yes Yes

a. User specified values only allowed where columns has been defined with GENERATED BY DEFAULT clause b. For GENERATED ALWAYS columns, or GENERATED BY DEFAULT columns with unique index defined. c. Direct row access is a new feature in DB2 for OS/390 that allows an application to directly access a given row in the table if it can supply a value for the rows ROWID in the query.

In general, you should consider using ID columns for the generation of key values that may need to be presented to the user, or be meaningful in their own right. In contrast, ROWID columns are most useful when direct retrieval and manipulation of the generated value is not required, such as dealing with LOB columns and using direct row access.

228

DB2 Java Stored Procedures: Learning by Example

11.7.9 Data propagation considerations


If a source table in a one-way data propagation environment contains an ID column with the GENERATED ALWAYS attribute, you should define the corresponding ID column on the target table with GENERATED BY DEFAULT to allow the propagation process to explicitly supply a value for the column. For two-way replication, both source tables must use GENERATED BY DEFAULT for the same reason. Also, if unique values are required, you should take care when specifying the START WITH and INCREMENT BY values for the two tables to prevent the same value being generated at each site. For instance, you may decide to have one value generating odd values (using START WITH 1 INCREMENT BY 2) and one generating even values (using START WITH 2 INCREMENT BY 2). This scenario is described in Figure 34.

Site A
CREATE TABLE .... (COLA INTEGER GENERATED BY DEFAULT START WITH 2 INCREMENT BY 2 COLB ...

Site B
CREATE TABLE .... (COLA INTEGER GENERATED BY DEFAULT START WITH 1 INCREMENT BY 2 COLB ...

COLA COLB COLC (ID) 1 ... ... 2 ... ... 3 ... ...
1

COLA COLB COLC (ID) 1 ... ... 2 ... ... 3 ... ...
3

INSERT

INSERT

Figure 34. Identity column data propagation issues

Chapter 11. DB2 UDB for OS/390 network computing enhancements

229

The following is a description of the process illustrated above: 1. Process at Site A inserts a row into table (without specifying a value for COLA), and DB2 generates a value of 2. 2. Replication takes place, and row 2 is replicated to Site B (with the value for COLA being specified). As Site B only generates odd-numbered values for COLA, there is no conflict. 3. Process at Site B inserts a row into the table (without specifying a value for COLA), and DB2 generates a value of 3. 4. Replication takes place, and row 3 is replicated to Site A (with the value for COLA being specified). As Site A only generates even-numbered values for COLA, there is no conflict.

11.7.10 Influencing insert order in a data sharing environment


Some applications have a requirement that an ever-increasing key value is generated. As previously described, in a data sharing environment it is possible for rows to be inserted out of sequence, due to the way in which each member of the data sharing group caches a range of values. In order to prevent this issue, you may use the NOCACHE option (see 11.7.2.1, Creating tables with identity columns on page 211 for a description of this parameter). However, use of NOCACHE may negatively impact performance and should only be used if necessary to the application.

11.7.11 Differences in implementation across the DB2 Family


This section summarizes the major differences between DB2 UDB for OS/390s implementation of the ID columns feature and that of the DB2 UDB for UNIX, Windows NT, or OS/2 Version 7 products.
11.7.11.1 Retrieving generated values DB2 UDB for UNIX, Windows NT, or OS/2 does not yet support the new IDENTITY_VAL_LOCAL built-in function. Therefore, you should consider using an after-insert trigger to retrieve generated ID column values, as described in Use of an after-insert trigger on page 225. 11.7.11.2 Support for col=DEFAULT during update DB2 UDB for UNIX, Windows NT, or OS/2 already supported the use of the SET col = DEFAULT syntax for use with NOT NULL WITH DEFAULT columns. This capability also applies to ID columns, where DB2 will generate a value.

DB2 UDB for OS/390 does not support this syntax. However, as the clause is essentially redundant, it can simply be omitted if SQL portability is an issue.

230

DB2 Java Stored Procedures: Learning by Example

11.7.11.3 Support for ALTER ADD ID column DB2 UDB for UNIX, Windows NT, or OS/2 does not support the ALTER TABLE ADD COLUMN of an identity column to an existing table. Identity columns may only be defined as part of a CREATE TABLE statement. 11.7.11.4 Parallel processing support DB2 UDB for UNIX, Windows NT, or OS/2 does not yet support the use of identity columns in the Enterprise Extended Edition (EEE) of the product, which is designed to run on highly parallel hardware. In contrast, the DB2 UDB for OS/390 implementation offers support for data sharing environments.

Chapter 11. DB2 UDB for OS/390 network computing enhancements

231

232

DB2 Java Stored Procedures: Learning by Example

Chapter 12. DB2 UDB for OS/390 schema support


A schema is an identifier (such as a user id or an application identifier) to help group together a set of DB2 objects. A schema can be owned by an individual, and the owner can control access to the data and the objects within it. You can think of a schema as being an extension of the table qualifier concept, which now encompasses new objects such as stored procedures, user defined functions, and triggers. A schema is also an object in the database and, like a package collection, it is created automatically when the first object in a schema is created. A schema name is used as the first part of a two-part object name. When an object is created, you can assign it to a specific schema by specifying the schema as the first part of the object name. If you do not specify a schema, it is assigned to the default schema, whose name is usually the CURRENT SQLID at the time the object is created. The second part of the two-name is the name of the object. For example, a user named JOHN might have a stored procedure named JOHN.PROC_1. As in prior releases, the qualifier, or schema name, for an object may or may not represent the creator of the object. However, additional authority (administrative authority) is required to create an object with a schema name other than the SQL authorization ID of the process. All objects qualified by the same schema name can be thought of as a group of related objects. Figure 35 shows 4 schemas (JOHN, SMITH, PROD1, and TEST) and objects contained in these schemas. The type of objects contained in these schemas are UDFs, UDTs, triggers, and stored procedures.

JOHN
SP1 SP2 UDF1 TRIG2 UDT3 SP3 UDF1 UDF1 UDT2 SP3

SMITH
SP1 SP4 UDF1 TRIG2 UDT3 SP3 UDF2 UDF3 UDT1 SP5

PROD1
SPCALC UDF_SALCI US_DOLLARS TRIGGER1 UDT2 SP3

TEST
SPCALC UDF_SALCI US_DOLLARS TRIGGER1 UDT2 SP3

Figure 35. What is a schema?

Copyright IBM Corp. 2000

233

A schema can also be used for versioning. As shown in Figure 35, a version of UDF1 exists in schema JOHN and another UDF1 exists in schema SMITH (see 8.3.2, Version control on page 164 for a practical example of how this facility could be used for versioning stored procedures).

12.1 Schema characteristics


Following are some characteristics related to schemas: There is no DDL to create a schema. A schema is created when the first object qualified by this schema name is created. There are new privileges related to schemas. You have now the following GRANT and REVOKE statements:
GRANT CREATEIN|ALTERIN|DROPIN ON schema TO grantee WITH GRANT OPTION REVOKE CREATEIN|ALTERIN|DROPIN ON schema FROM grantee

When an authorization ID matches a schema name, the authorization ID is said to be the schema owner. The schema owner can issue the above commands to grant/revoke the privileges on the schema for other users. There is a new SET CURRENT PATH statement to specify the value of the CURRENT PATH special register. This register is used to specify one or more schema names that are used to resolve unqualified data type names and function names in dynamically prepared SQL statements. It is also used to resolve unqualified procedure names that are specified as host variables in SQL CALL statements (CALL host-variable). There is a new option in the BIND command to specify the value of the PATH to be used during BIND operations.

12.2 How schemas are used


In this section we explain how schemas are used.

12.2.1 Explicit specification


Schemas are used in the following situations (refer to Figure 36): When you issue the CREATE, ALTER, DROP, or COMMENT ON statement for a trigger, UDF, UDT, or stored procedure, you can explicitly specify a schema name. The schema name specified can be any primary or secondary authorization ID associated with the process.

234

DB2 Java Stored Procedures: Learning by Example

If the schema name specified is not the primary or a secondary authorization ID associated with the process, the primary or one of the secondary authorization IDs associated with the process must have either the CREATEIN, ALTERIN, or DROPIN privilege for the specified schema. To use COMMENT ON the specified object, the authorization ID (primary or secondary) associated with the process must have ALTERIN privilege on the SCHEMA. SYSADM and SYSCTRL implicitly have these privileges.

CREATE

ALTER

DROP

COMMENT ON

object-type JOHN.object_name
JOHN object_name

* Schema name can be any authorization ID of the process * Schema name can be any name if SYSADM, SYSCTRL, or user has appropriate privilege on the schema name
Figure 36. How a schema is used explicit specification

12.2.2 Implicit specification


When you issue the CREATE, ALTER, DROP, or COMMENT ON statement for a trigger, UDF, UDT, or stored procedure, you can omit a schema name. In this case, a schema name is assumed, as follows (refer to Figure 37): If the CREATE, ALTER, DROP, or COMMENT ON statement is embedded in an application program (static SQL), the implicit schema name is the authorization ID of the QUALIFIER (explicit or default) specified during the BIND for this application. If the CREATE, ALTER, DROP, or COMMENT ON statement is issued dynamically, the value of the CURRENT SQLID special register is the implicit qualifier, unless you specified DYNAMICRULES(BIND) when the application was bound. If DYNAMICRULES(BIND) was specified, then the implicit qualifier is the authorization ID of the QUALIFIER (explicit or default) specified during the BIND for this application. Note that CREATE and DROP do not allow the DYNAMICRULES(BIND) specification, that is,

Chapter 12. DB2 UDB for OS/390 schema support

235

they cannot be issued dynamically when DYNAMICRULES(BIND) was specified during BIND.

CREATE

ALTER

DROP

COMMENT ON

object-type object_name
JOHN object_name

* Static: Schema name is the authorization ID BIND QUALIFIER * Dynamic: Schema name is CURRENT SQLID
(Except for DYNAMICRULES(BIND) ==> if allowed)
Figure 37. How a schema is used implicit specification

12.3 Schemas and the CURRENT PATH special register


When you invoke a stored procedure or UDF, activate a trigger, or have a reference to a UDT, and you don't specify the schema name, name resolution occurs according to the PATH bind option or CURRENT PATH special register from left to right until it finds a schema name for which there exists a stored procedure definition with the name in the CALL statement. DB2 uses the schema names from the PATH bind option for CALL statements of the form:
CALL literal

For CALL statements of the form:


CALL host-variable

DB2 uses schema names from the CURRENT PATH special register. Name resolution is object-specific. When DB2 finds a stored procedure definition, DB2 executes that stored procedure if the following conditions are true: The caller is authorized to execute the stored procedure. The stored procedure has the same number of parameters as in the CALL statement.

236

DB2 Java Stored Procedures: Learning by Example

If both conditions are not true, DB2 continues to go through the list of schemas until it finds a stored procedure that meets both conditions or reaches the end of the list. If DB2 cannot find a suitable stored procedure, it returns a -440 SQL error code for the CALL statement. For the following discussion, refer to Figure 38. The CURRENT PATH special register is a VARCHAR string with the maximum length of 254 bytes. It contains an ordered list of schema names. The schema names SYSIBM, SYSFUN and SYSPROC are always included in the list before any other schema name, therefore you don't have to specify them. You can specify them, to override the order of the search. The schema SYSIBM already contains objects in it. Users cannot create objects in SYSIBM or SYSFUN schemas. The CURRENT PATH special register is used to resolve unqualified object names.

"RES1", "RES2", "PROD"

"SYSIBM", "SYSFUN", "SYSPROC","RES1","RES2","PROD"

"RES1", "SYSIBM", "RES2", "SYSPROC" "SYSFUN", "RES1","SYSIBM","RES2","SYSPROC"


Figure 38. CURRENT PATH special register

12.3.1 SET CURRENT PATH


The CURRENT PATH special register is set to the BIND path option at startup of the stored procedure. The SET CURRENT PATH statement changes the value of the CURRENT PATH special register; for example:
SET SET SET SET CURRENT CURRENT CURRENT CURRENT PATH PATH PATH PATH = = = = SCHEMA1, SCHEMA2, SYSIBM :hostvariable USER SYSTEM PATH

Chapter 12. DB2 UDB for OS/390 schema support

237

The SET CURRENT PATH statement has the following characteristics: It can be used in dynamic SQL. No special authorization is required. It can be static or dynamic. Schema existence is not checked. It is classified as a non-local SET statement in DRDA. The CURRENT PATH special register is used to resolve unqualified user-defined distinct types and functions in dynamic SQL statements. The CURRENT PATH special register is used to resolve unqualified stored procedure names when the SQL CALL statement specifies a host variable for the procedure name, and to resolve UDFs and stored procedures that appear in a trigger body. It is not used for the trigger itself. Invocation: This statement can be embedded in an application program or issued interactively. It is an executable statement that can be dynamically prepared. Authorization: No authorization is required to execute this statement. Syntax: For the following discussion, refer to Figure 39.

_=_ <_,____________________ >>__SET__ _ __________________________ __ PATH_ __ | __ | ___ _schema-name_________ | |_CURRENT__ ___________ _ | | |_SYSTEM PATH________ | |_FUNCTION_| | |_USER______________ |_CURRENT_PATH_____________________| |_ _ _________________ | |_CURRENT__ _____ | |_host-variable_________ |_string-constant________

Figure 39. SET CURRENT PATH syntax

- Description: schema-name

238

DB2 Java Stored Procedures: Learning by Example

Identifies a schema. DB2 for OS/390 does not validate the existence of the schema. If a schema-name is, for example, misspelled, it will not be noted and it could affect the way subsequent SQL operates. SYSTEM PATH This value is the same as specifying the schema name "SYSIBM" followed by "SYSFUN", followed by "SYSPROC". SYSTEM PATH can only be specified once (SQLSTATE 42732, SQLCODE -585). USER The value of the USER special register. USER can only be specified once (SQLSTATE 42732, SQLCODE -585). host-variable A variable of type CHAR or VARCHAR. The value of the host-variable must represent a valid schema-name and cannot be set to null. If the host-variable has an associated indicator variable, the value of that indicator variable must not indicate a null value (SQLSTATE 42815, SQLCODE -713). The schema name must: - Be left justified within the host variable - Be padded on the right with blanks if its length is less than that of the host variable string-constant A character string constant which represents a valid schema-name.
Note: If the schema name specified here as a string-constant will also be specified in other SQL statements and the schema name does not conform to the rules for ordinary identifiers, then in the other SQL statements the schema name must be specified as a delimited identifier. Notes:

- A schema name appears more than once in the path (SQLSTATE 01625, SQLCODE +585). - The number of schemas that can be specified is limited by the total length of the CURRENT PATH special register. - The special register string is built by taking each schema name specified and removing trailing blanks, adding two delimiters around it, and adding one comma after each schema except the last one.

Chapter 12. DB2 UDB for OS/390 schema support

239

- The length of the resulting string cannot exceed 254 bytes (SQLSTATE 42907, SQLCODE -586). - The schemas SYSIBM, SYSFUN and SYSPROC do not need to be specified. If one is not included in the path, it is implicitly assumed as the first schema (in this case, it is not included in the CURRENT PATH special register). If more than one is not included in the path, SYSIBM is put first in the path followed by SYSFUN and then SYSPROC. If SYSIBM, SYSFUN or SYSPROC is not specified, it is not included in the 254 byte length limit. SET CURRENT PATH is executed by the application server and is therefore classified as a non-local SET statement in DRDA.

12.3.2 PATH bind option


The new bind option PATH is applicable to BIND PLAN, BIND PACKAGE, REBIND PLAN and REBIND PACKAGE. It determines the path to be used in resolving unqualified UDTs, UDFs, and procedure names (in CALL statements) in static SQL. If this option is not specified on BIND, the default path is "SYSIBM", followed by "SYSFUN", followed by "SYSPROC", followed by the userid of the owner of the package or plan. If this option is not specified on REBIND, the previous value is retained. For plans, the value of PATH applies only to the DBRMs bound directly to the plan (named in the MEMBER option on BIND PLAN), and has no affect on PKLIST names. The bind option has no affect on dynamic SQL statements which use the value of the CURRENT PATH special register. The syntax is:
PATH (schema-name1 schema-name2 ..

where: schema-name Identifies a schema. No validation is done to determine whether the schema actually exists at precompile or at bind time. The same schema cannot appear more than once in the path (DSNT205). The number of schemas that can be specified is limited by the length of the resulting path, which cannot exceed 254 bytes. The length is calculated by taking the length of each schema, adding two for delimiters around each schema and adding one for a comma after each schema except for the last one.

240

DB2 Java Stored Procedures: Learning by Example

The SYSIBM, SYSFUN and SYSPROC schemas do not need to be explicitly specified. They are assumed implicitly to be at the beginning of the list. The implicitly added schemas are added in the order listed above. Furthermore, if SYSIBM, SYSFUN, or SYSPROC are not specified, they are not included in the 254 byte length The schema names are not folded by DB2. Therefore, specify schema names which are ordinary (non-delimited) identifiers in uppercase. Failure to do this results in these schema names being essentially ignored in the path (DB2 only matches them with schemas in the database if they are specified in uppercase). The default (that is, if this option is not specified) is as follows: - BIND PLAN:
SYSIBM, SYSFUN, SYSPROC, <I>plan or package /I>>owner

- BIND PACKAGE:
SYSIBM, SYSFUN, SYSPROC, >plan or package /I>>owner

- REBIND PLAN:
use existing value

- REBIND PACKAGE:
use existing value

Note: DB2I BIND/REBIND panels support the new PATH option.

Chapter 12. DB2 UDB for OS/390 schema support

241

242

DB2 Java Stored Procedures: Learning by Example

Chapter 13. DB2 UDB for OS/390 stored procedures enhancements


In this chapter we discuss stored procedure enhancements.

13.1 Stored procedures: an overview


Stored procedures are user-written programs that are stored at the DB2 server and can be invoked by client applications. A stored procedure can contain most statements that an application program usually contains. Stored procedures can execute SQL statements at the server as well as application logic for a specific function. A stored procedure can be written in many different languages, such as COBOL, OO COBOL, C, C++, PL/I, FORTRAN, Assembler, REXX, Java, and SQL Procedures (refer to Developing Cross-Platform DB2 stored Procedures SQL Procedures and the Stored Procedure Builder, SG24-5485 for more details). The language in which stored procedures can be written depends on the platform where the DB2 server is installed. Local client applications, remote DRDA, or remote data services (private protocol) can invoke the stored procedure by issuing the SQL CALL statement. The SQL CALL statement is part of the ISO/ANSI (SQL:1999), an open solution for invoking stored procedures among database management system vendors that support the SQL ISO/ANSI standard. The calling program can pass parameters to the stored procedure and receive parameters back from the stored procedure. The calling application can also access and process result sets generated by the stored procedure. In addition, the client program and the stored procedure do not have to be written in the same programming language. For example, a C client program can invoke a COBOL stored procedure or an SQL stored procedure. The following DB2 servers currently support DRDA stored procedures: DB2 DB2 DB2 DB2 DB2 DB2 DB2 UDB UDB UDB UDB UDB UDB UDB for for for for for for for OS/2 AIX Windows NT HP-UX Solaris AS/400 OS/390

Copyright IBM Corp. 2000

243

13.1.1 Why use stored procedures?


In previous releases of DRDA, the client system performed all application logic. The server was responsible only for SQL processing on behalf of the client. In such an environment, all database accesses must go across the network, resulting in poor performance in some cases. This is a relatively simple model, which makes the application program easy to design and implement. Because all application code resides at the client, a single application programmer can take responsibility for the entire application. However, there are some disadvantages to using this approach. Because the application logic runs only at the client, additional network input/output (I/O) operations are required for most SQL requests. These additional operations can result in poor performance. This approach also requires the client program to have detailed knowledge of the servers database design. Thus, every change in the database design at the server requires a corresponding change in all client programs accessing the database. Also, because the programs run at the client workstations, it is often complicated to manage and maintain the copies at the clients. Stored procedures enable you to encapsulate many of your applications SQL statements into a program that is stored at the DB2 server. The client can invoke the stored procedure by using only one SQL statement, thus reducing the network traffic to a single send and receive operation for a series of SQL statements. It is also easier to manage and maintain programs that run at the server than it is to manage and maintain many copies at the client machines. See Figure 40.

244

DB2 Java Stored Procedures: Learning by Example

OS/390 System

DRDA CLIENT OR LOCAL CLIENT

DB2
SCHEDULE PROGX PERFORM SQL

STORED PROC ADDRESS SPACE


PROGX EXEC SQL SELECT EXEC SQL UPDATE

EXEC SQL CALL PROGX

PERFORM SQL

PERFORM SQL RETURN VALUES TO CLIENT

EXEC SQL CREATE

PROGX ENDS

PROGY

Figure 40. Stored procedures overview

In addition, stored procedures enable you to split the application logic between the client and the server. You can use this technique to prevent the client application from manipulating the contents of sensitive server data. You can also encapsulate business logic into programs at the server. Stored procedures also enable access to features that exist only on the database server. These features include commands that run only on the server, software installed only on the server that can be accessed by the stored procedure, and the computing resources of the server, such as memory and disk space. Because stored procedures are defined in DRDA, they also take advantage of DRDA features, such as data transformation between platforms, database security and accounting, and two-phase commit support.

Chapter 13. DB2 UDB for OS/390 stored procedures enhancements

245

13.1.2 SQL CALL processing flow


Following is the processing flow of the SQL CALL statement within DB2 for OS/390. 1. A thread must be created for each application that needs DB2 services. If the application is local, the thread is created when the first SQL statement is executed. If the request comes from a remote client, the thread is created when the client application issues the SQL CONNECT statement. After the thread is created, SQL statements can be executed. 2. When a client application issues an SQL CALL statement, the stored procedure name and the I/O parameters are passed to DB2 via the Distributed Data Facility (DDF) address space. 3. When DB2 receives the SQL CALL statement, it searches in the DB2 catalog for a row associated with the stored procedure name. From this table, DB2 obtains the load module associated with the stored procedure and other information related to it. 4. Stored procedures are executed in address spaces. For DB2 for OS/390 Version 4, there is only one address space available, which is called the DB2-established address space. Since Version 5, in addition to the DB2-established address space, you can have several work load manager (WLM) established address spaces. For DB2-established or WLM-established address spaces, you can specify a number of task control blocks (TCBs) in this address space available for stored procedures. Each stored procedure is executed under one TCB. After searching the DB2 catalog, DB2 searches for a procedure address space in which to execute the stored procedure. 5. When DB2 notifies the stored procedure address space to execute a stored procedure, the thread that was created for the client application is reused for an execution. This has the following implications: - CPU cost is low because DB2 does not create a new thread. - Accounting is on behalf of the client application. - For static SQL the OWNER of the client program must have EXECUTE privilege on the stored procedure package. For dynamic SQL issued by the stored procedure, security is checked against the user of the client program, unless the DYNAMICRULES(BIND) option was specified when binding the package for the stored procedure. No sign-on or connection processing is required. - Any processing done by the stored procedure is considered a logical continuation of the client applications unit of work. Thus, locks

246

DB2 Java Stored Procedures: Learning by Example

acquired by the stored procedure are released when the client application commits or rolls back. 6. The stored procedure address space uses the LE/370 product libraries to load and execute the stored procedure. Through the DB2 catalog, you can pass run-time parameters for LE/370 when the stored procedure is executed. 7. Control is passed to the stored procedure along with the input and output parameters. The stored procedure can issue most SQL statements. It also has access to non-DB2 resources (however, such updates are outside the unit of work if the stored procedure is being executed within a DB2-established address space). 8. Before terminating, the stored procedure assigns values to the output parameters and returns the control to DB2. 9. DB2 copies the output parameters received from the stored procedure to the client application parameter area and returns control to the client application. 10.The calling program receives the output parameters and continues the same unit of work. 11.The client application implicitly issues the COMMIT statement. With DB2 Version 5, the client application can implicitly commit as soon as the stored procedure returns the control to the client application. If the client application and the stored procedure used during this execution update at different sites, the two-phase commit protocol is used. Although stored procedures are primarily used from DRDA remote clients, they are also supported locally. If a local application issues the SQL CALL statement, the distributed data facility (DDF) is not involved and need not be started.

13.1.3 Stored procedures time line characteristics


Starting with Version 4, in this section and its subsection we will describe the characteristics of DB2 stored procedures.
13.1.3.1 In Version 4 Most of the Version 4 characteristics apply to Version 6, but Version 6 introduced a number of enhancements, as we will describe later in this section and show in the examples presented in this book.

Chapter 13. DB2 UDB for OS/390 stored procedures enhancements

247

Static or dynamic SQL The stored procedure can issue static or dynamic SQL statements. Data definition language (DDL) statements, most data manipulation language (DML) statements, and data control language (DCL) statements can be coded in a stored procedure. The DRDA architecture allows SQL CALL statements to use static or dynamic SQL. For the current version of the DB2 products, the SQL CALL statement must be a static SQL. Nevertheless, parameters in the CALL statement, including the stored procedure name, can be supplied at execution time. Thus, you can use the SQL CALL statement to dynamically invoke any procedure supported by DB2. These characteristics have not changed in Version 6. Ability to use three-part names over private protocol You can reference aliases or three-part names in a stored procedure. Although for Version 4 and Version 5 you cannot issue an SQL CALL statement in your stored procedure, you can call other programs or routines from a stored procedure by using standard programming language facilities. If you must access the same remote location from a client program that uses CONNECT TYPE 2, you can issue an SQL RELEASE statement for the remote location, followed by an SQL COMMIT statement. These statements must be executed before or after the stored procedure, depending on when you want to connect to the remote location. If you use these statements, you terminate your unit of work. If you do not want to terminate your unit of work, but still want to access tables at the remote location, you can use system-directed access in your client program to the same remote location that the stored procedure is accessing. In this case use a three-part name and do not issue the SQL CONNECT statement. For client programs using CONNECT TYPE 1, you must issue an SQL COMMIT before or after the call to the stored procedure. Unlike DB2 on OS/390, if your client program is running in the workstation platform using CONNECT TYPE 2, you can connect in the same unit of work to the same remote location that is accessed by the stored procedure. Note that a new thread is created when you issue the CONNECT statement. When the stored procedure executes the SQL statement with the three-part name specification, another thread is created in DB2 for the same unit of work. In this scenario, be careful when updates are made from the client program and the stored procedure on the same data. You might get into a lock problem situation because the threads are different.

248

DB2 Java Stored Procedures: Learning by Example

If you have precompiled your program with CONNECT TYPE 1, you must issue an SQL COMMIT statement before or after the call to the stored procedure that is using system-directed access. If you do not commit, your client program receives an SQLCODE -30090 when trying to call the stored procedure or in the SQL CONNECT statement. IFI call and DB2 commands You can use IFI calls and issue commands from the stored procedure. Note that DRDA supports only SQL statements, not commands. If, for example, you need to monitor the DB2 environment from a workstation, you can invoke a stored procedure that issues DB2 commands and returns results to the workstation. Access to non-DB2 resources You can access VSAM files and IMS databases or invoke CICS transactions from a stored procedure. To access an IMS database, you have the following options: - Invoke a CICS transaction - Invoke an APPC application - Use MQ Series - Use DRA (new support in IMS, and must use DB2 Version 5 or higher) Restricted SQL operations For DB2 Version 4 and Version 5, the following SQL statements cannot be used in a stored procedure: - CALL - COMMIT - CONNECT - RELEASE - ROLLBACK - SET CONNECTION - SET CURRENT SQLID If you try to use any of the unsupported SQL statements, your stored procedure and the client program receive a -751 SQLCODE. This is an exceptional case where the client program directly receives the failing SQLCODE that the stored procedure receives. When your stored procedure receives a -751 SQLCODE, the DB2 thread associated with it is placed in a must rollback state.

Chapter 13. DB2 UDB for OS/390 stored procedures enhancements

249

When the client program receives control back from the stored procedure, it must issue a successful SQL ROLLBACK statement before it can continue processing. If the client program does not issue the SQL ROLLBACK statement and terminate, DB2 automatically rolls back the unit of work. If, because an error condition, you want to ensure a rollback in the unit of work, you can code the following ROLLBACK statement in your stored procedure:
IF error-condition THEN EXEC SQL ROLLBACK END-EXEC.

Because ROLLBACK is an invalid SQL statement for stored procedures, your unit of work is placed in a must rollback state.
13.1.3.2 In Version 5 DB2 Version 5 supports WLM-established stored procedures address spaces in addition to the DB2-established address space, which was already supported in DB2 Version 4.

DB2 for OS/390 Version 5 (with OS/390 release 3 or above) enables you to run multiple WLM-managed stored procedures address spaces. With WLM-established address spaces, you can: Access non-DB2 resources with two-phase commit. Execute stored procedures based on individual transaction priorities. Achieve workload balancing across multiple stored procedure address spaces. Utilize the increased flexibility to group or isolate applications. Do a RACF check to non-DB2 resources based on the client authorization. For WLM-established address spaces, you can use the primary authorization ID related to the client application. To do this, you must specify the value Y for the EXTERNAL_SECURITY column of SYSIBM.SYSPROCEDURES. You should only specify this option if you access non-DB2 resources and you want to check the privileges of the client authorization ID instead of the WLM-established address space. The following considerations apply if you specify Y for the EXTERNAL_SECURITY column: If you have inbound translation, the translated authorization ID is used. The RACF ID and group name that you select must have authority to run the Recoverable Resource Manager Services Attachment Facility (RRSAF) application programs.

250

DB2 Java Stored Procedures: Learning by Example

Recoverable Resource Manager Services Attachment Facility An application program can use RRSAF to connect to DB2 to process SQL statements, commands, or instrumentation facility interface (IFI) calls. Programs that run in MVS batch, TSO foreground, and TSO background can use RRSAF.
RRSAF uses OS/390 Transaction Management and Recoverable Resource Manager Services (OS/390 RRS). With RRSAF, you can coordinate DB2 updates with updates made by all other resource managers that also use OS/390 RRS in an MVS system. WLM-established address space must use RRSAF, therefore you may update non-DB2 resources that register with RRS using the two-phase commit protocol. IMS and APPC are examples of RRS enabled resource managers.

Multiple result sets in DB2 for OS/390 DB2 for OS/390 has implemented support to multiple result sets as both client and server.
If your stored procedure is executing on DB2 for OS/390, your stored procedure can return multiple result sets to a local or remote client application. These code points are supported by DB2 CONNECT. If the stored procedure is executing on a remote DRDA application server, the remote DRDA application server must support DRDA code points used to return multiple result sets. To implement multiple result sets for each result set you want returned, your stored procedure must: Declare a cursor with the WITH RETURN option Open the cursor Leave the cursor open When the stored procedure ends, DB2 return the rows in the query result when the client issues a FETCH statement. The RESULT_SETS column of the row associated with your stored procedure in the catalog table SYSIBM.SYSPROCEDURES must contain the maximum number of result sets that the stored procedure will be allowed to return to the caller. For example, if you want to return a result set that contains entries for all employees in department D11, you should code your stored procedure as follows:
251

Chapter 13. DB2 UDB for OS/390 stored procedures enhancements

1. The stored procedure declares a cursor that describes this subset of employee:
EXEC SQL DECLARE CURSOR-EMP CURSOR WITH RETURN FOR SELECT EMPNO, FIRSTNAME, MIDINT, LASTNAME, PHONENO FROM DSN8510.EMP WHERE WORKDEPT=D11; END EXEC

2. Then it opens the cursor:


EXEC SQL OPEN CURSOR-EMP END-EXEC.

3. It ends without closing the cursor or fetching rows from this cursor. If the stored procedure fetches rows, the fetched rows are not returned to the client. In general, there are no reasons for the stored procedure to fetch the row, but sometimes there might be. Following is an example of a real use for fetching rows from the cursor prior to returning to DB2: The customer has a Web application that can only display 50 rows of data on each page. Web applications are stateless, so they are not able to keep the cursor open to fetch more than 50 rows of data on any given series of Web clicks. To get around this problem, they implemented the query inside a stored procedure. The Web user clicks on a button that indicates whether they want: The first 50 rows The second group of 50 rows The third group of 50 rows And so on If the user wants the second group of 50 rows, the stored procedure issues the SELECT statement specifying WITH RETURN and OPTIMIZE FOR 50 ROWs. The stored procedure then issues 50 FETCH calls, so that the cursor is positioned on row 51. At this point, the stored procedure returns to DB2. DB2 will transmit row 51-100 to the Web server, giving the user what they wanted. In this application, rarely are more than 50 rows returned from a query, so this was a simple way to implement the support. You should use meaningful cursor names for returning result sets, because the name of the cursor that is used to return result sets is available to the client application through extensions to the DESCRIBE statement.

252

DB2 Java Stored Procedures: Learning by Example

You can use any of these objects in the SELECT statement associated with the cursor for a result set: Tables, synonyms, views, temporary tables, and aliases defined at local DB2 system. Tables, synonyms, views, temporary tables, and aliases defined at remote DB2 on OS/390 systems that are accessible through DB2 private protocol access. You can use a temporary table to return result sets from a stored procedure. This capability can be used to return nonrelational data sets such as IMS, VSAM, or QSAM, to a DRDA client. For example, you can access IMS data from a stored procedure in the following way: Access the IMS database. Receive the IMS reply message, which contains data that should be returned to the client. Insert the data from the reply message into a global temporary table. Open a cursor against the temporary table. When the stored procedure ends, the rows from the temporary table are available to the client. Using this approach, you can join information contained in the global temporary table obtained from non-relational data to your DB2 data and return it to the client. You can code your multiple result sets stored procedure in any languages supported to code stored procedures. In addition, the stored procedure can be written using the DB2 for OS/390 ODBC/CLI interface. As with a normal stored procedure, it must use LE/370. Multiple result sets stored procedures are supported in the DB2-established address space and in the WLM-established address spaces. If your application program calls a stored procedure that returns result sets, you must include code in your application to receive each of the result sets. Result sets are only available from read-only client applications. You cannot use the UPDATE OR DELETE for multiple result sets in your client application. Stored procedure result set are always marked read only, so update or delete operations fail if you issue them. This implies that UPDATE or DELETE WHERE CURRENT CURSOR is not allowed in the stored procedure or in the client application.

Chapter 13. DB2 UDB for OS/390 stored procedures enhancements

253

Unlike DB2 UDB for workstations, your DB2 for OS/390 client application can be written in any supported language and can use the DB2 for OS/390 ODBC/CLI interface. If the client application is not using ODBC/CLI, there are the following extensions in the SQL language: A result set locator SQL data type An ASSOCIATE LOCATORS SQL statement An ALLOCATE CURSOR SQL statement A DESCRIBE PROCEDURE SQL statement A DESCRIBE CURSOR SQL statement

COMMIT_ON_RETURN DB2 for OS/390 Version 5 has introduced a new column, COMMIT_ON_RETURN. If you specify N for this column. all updates performed by the unit of work are committed when the client application commits. This is the default.
If you specify Y for this column, all updates performed by the unit of work are committed when control returns to the client application if the SQLCODE for the CALL statement is zero or has a positive value. This implies that updates performed before the stored procedure is invoked, are also committed. Those updates can be updates done by the stored procedure locally or remotely (through a three-part name or using RRSAF), or done locally or remotely by the client application before invoking the stored procedure. Any updates performed by the client application after execution of the stored procedure are part of another unit of work. The client application does not need to code the commit statement. This is valid for DB2-established or WLM-established address spaces, regardless of whether the client application is using COMMIT 1 or COMMIT 2. If the application updated other DRDA servers before invoking the stored procedure, those updates are also committed upon successful execution of the stored procedure. The advantage of committing automatically is that all locks acquired previously are released, except for locks acquired for opened cursors declared with both the WITH HOLD and WITH RETURN options. If the stored procedure is coded to return result sets, you must declare the cursors for the result sets with the WITH RETURN and WITH HOLD options; otherwise the cursors are closed when control returns to the client application. For one result set, you only need to specify WITH HOLD if COMMIT_ON_RETURN is 'Y'.

254

DB2 Java Stored Procedures: Learning by Example

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

DLI support Because IMS does not support multiple TCBs for batch processing and requires that the IMS region controller be the module in control, you cannot access IMS databases directly from the stored procedures address spaces using the batch region facility.
There are several ways that you can access IMS databases: Using the database resource adapter (DRA) callable interface. Including APPC code in the stored procedure. An IMS or CICS transaction can be invoked by APPC. Using the MQI interface to access CICS transaction. Using the EXCI interface. Using the MQI interface to place a transaction on the IMS message queue. Depending on the method and the level of product you use, you can have different combinations of: Commitment control Complexity of the code Performance Once you have accessed IMS databases, you can pass IMS information through output parameters, or you can insert information obtained from IMS databases in a global temporary table, and pass this information to the client application using multiple result sets. Here we describe a method using the DRA callable interface (see Figure 41). The IMS-supplied DRA-callable interface is a facility available in IMS Version 6 as an APAR. The DRA-callable interface allows an OS/390 application execution environment (AEE), such as a stored procedures address spaces, access to IMS database through the IMS database control system (DBCTL).

Chapter 13. DB2 UDB for OS/390 stored procedures enhancements

255

A stored procedure has access to the IMS database using DRA connection to DBCTL in a CICS environment and connection to the IMS control region in an IMS TM environment, because in an IMS TM environment, DBCTL services are provided in the IMS control region. The architecture of DRA, the callable interface, resides in the DB2 stored procedure address space, and is recognized by IMS as an application execution region (AER). Using the DRA-callable interface the stored procedure can access full function DL/I databases and fast path data entry databases (DEDB). The DRA-callable interface allows DBCTL and OS/390 application programs, such as stored procedures, to be developed, installed, and maintained independently of each other.

M V S S y s te m DRDA C lien t EXEC SQL CALL PRO GX D B 2 S to re d P roc e du re s R e gio n DB2 S c h ed P R O G X P R O G X: C ALL C OB T D LI "A P SB " C ALL C OB T D LI "G U " R etu rn v a lu es to D R D A u s e r EXEC SQL C O M M IT MVS RRS

DBCTL

D L IS A S

D L /I c a lls c a n b e is s u e d fro m a s to re d p ro c e d u re R R S c o o rd in a te s th e c o m m it b e tw e e n D B 2 a n d IM S V 6 G lo b a l te m p o ra ry ta b le s c a n b e u s e d to re tu rn IM S d a ta in a s to re d p ro c e d u re q u e ry re s u lt s e t R e q u ire s O S /3 9 0 R 3 a n d IM S V 6 R 1 A P A R th a t e n a b le s R R S s u p p o rt

Figure 41. DB2 stored procedures access DL/I databases

The IMS DRA-callable interface provides new modules packaged with existing IMS Version 6 DRA modules to support the new callable interface to DBCTL.

256

DB2 Java Stored Procedures: Learning by Example

Because the interface requires OS/390 RRS, you can use the interface only in the WLM-established address space. Note that OS/390 R3 or later is required, due to RRS. As a consequence, the minimum level of DB2 that allows you to use the DRA-callable interface is DB2 for OS/390 Version 5. Because Version 4 supports only DB2-established address spaces, you cannot access an IMS database using the DRA-callable interface with DB2 Version 4. You cannot execute a stored procedure as an IMS batch application, because the batch does not connect to DBCTL. You access IMS databases using the language CALL statement. The CALLs that are available are the CALLs to the AERTDLI interface or the AIBTDLI interface. The following function calls are supported by DRA-callable interface: APSB, CIMS, DEQ, DLET, DPSB, FLD, GU, GHU, GN, GHN, GMSG, ICMD, INIT, INQY, ISRT, LOG, POS, RCMD, REPL, ROLS, SETS, SETU, SNAP, STAT, OPEN, and CLSE.
13.1.3.3 In Version 6 This section describes the stored procedures enhancements introduced in DB2 UDB for OS/390 Version 6.

CREATE PROCEDURE In Version 6, the SYSIBM.SYSPROCEDURES catalog table is no longer used. Stored procedures are defined using the CREATE PROCEDURE DDL statement. The CREATE PROCEDURE statement updates other catalog tables, such as SYSIBM.SYSROUTINES and SYSIBM.SYSPARMS.
As consequence of the CREATE PROCEDURE statement, there are also the ALTER PROCEDURE and DROP PROCEDURE DDL statements. The SQL GRANT and REVOKE statements are enhanced to allow users to manage the privileges to execute stored procedures. The CURRENT PATH special register and the PATH bind option are used to determine the schema name of unqualified stored procedures (see Chapter 12, DB2 UDB for OS/390 schema support on page 233 for more details about schemas). Stored procedures share with User Defined Functions (UDFs) the same catalog tables for CREATE/ALTER/GRANT and REVOKE.

Chapter 13. DB2 UDB for OS/390 stored procedures enhancements

257

Three-part name usage In prior release of DB2, the stored procedure name was composed of three parts. If the first part was specified, it had to match the location of the current server. If the second part was specified, it had to match exactly SYSPROC. The third part had to match the PROCEDURE column of SYSIBM.SYSPROCEDURE table.
In Version 6, the first part can match any LOCATION name specified in the SYSIBM.LOCATIONS catalog table. An implicit CONNECT statement is issued to that location, using DRDA. This provides an enhanced degree of flexibility. You can invoke a remote procedure as long as you have DRDA connectivity to the location where the stored procedure resides.

Usage of schemas In Version 6, the second part of the name does not need to be SYSPROC. it can be any schema name. Again, this provides a greater degree in management of stored procedures. You may want to group all related stored procedures under the same schema. See Chapter 12, DB2 UDB for OS/390 schema support on page 233 for more details about schemas. Some DML restrictions lifted SQL statements such as CALL, CONNECT, SET CONNECTION and RELEASE are now allowed within a stored procedure. This allows for nesting of stored procedures and flexibility to manage the connections. Authorization enhancements Because the stored procedure is now created using SQL CREATE statement, the authorization ID that creates the stored procedure is the OWNER of the stored procedure and owns it. In previous versions, if the stored procedure had no SQL, then a package was not required, and you could not directly prevent the execution of the stored procedure.
Now the owner of the stored procedure can prevent execution of the stored procedure even if the stored procedure does not require a package. Also, when you create the stored procedure, you can specify several levels of DML SQL statements that can be issued by the stored procedure.

UDFs You can invoke a UDF from a stored procedure and you can invoke a stored procedure from within a UDF. With the support for the SQL CALL statement in a stored procedure, you can nest stored procedures and UDFs. UDFs execute the same way that stored procedures do, in the WLM-established

258

DB2 Java Stored Procedures: Learning by Example

address space. Stored procedures can also be invoked from triggers. Transition tables can be passed to the stored procedure from triggers.

Note:

In version 6, UDFs cannot be written in Java.

LOBs You can use LOCATORs, BLOB, CLOB, DBCLOB as input or output parameters to the stored procedures.

Note:

In version 6, LOBs, LOCATORs and ROWID cannot be defined as parameters to stored procedures written in Java.

UDTs The built-in as well as the UDT are supported for the data type of stored procedure input/output parameters.

13.2 The CREATE PROCEDURE DDL statement


The CREATE PROCEDURE statement can be embedded in an application program or issued dynamically. It is an executable statement that can be dynamically prepared. However, if the bind option DYNAMICRULES(RUN) is not specified explicitly or implicitly, the statement cannot be dynamically prepared. This is an example of the insert statement to SYSIBM.SYSPROCEDURES for Version 5:
INSERT INTO SYSIBM.SYSPROCEDURES (PROCEDURE,AUTHID,LUNAME,LOADMOD,LINKAGE,COLLID, LANGUAGE,ASUTIME,STAYRESIDENT,IBMREQD, RUNOPTS, PARMLIST, RESULT_SETS,WLM_ENV,PGM_TYPE, EXTERNAL_SECURITY,COMMIT_ON_RETURN) VALUES( 'ADD_CUSTOMER', '', '', '', 'N', 'ACMESOE', 'COMPJAVA', 900, '','N', 'ACMESOE/Add_customer.add_customer', 'CHAR(20) IN, CHAR(20) IN, CHAR(30) IN, INTEGER OUT, CHAR(40) out, CHAR(200) out',

Chapter 13. DB2 UDB for OS/390 stored procedures enhancements

259

1,'WLMJAVADBS1','S','N','N' );

This is an example of the CREATE PROCEDURE statement for Version 6:


CREATE PROCEDURE ACMESOE.ADD_CUSTOMER ( IN FIRSTNAME CHAR(20), IN LASTNAME CHAR(20), IN ADDRESS CHAR(30), OUT CUSTNO INTEGER, OUT MARK CHAR(40), OUT MARK_ERROR_TEXT CHAR(200)) FENCED MODIFIES SQL DATA LANGUAGE COMPJAVA EXTERNAL NAME 'ACMESOE/Add_customer.add_customer' PARAMETER STYLE JAVA WLM ENVIRONMENT WLMJAVADBS1 RUN OPTIONS 'ACMESOE/Add_customer.add_customer' DYNAMIC RESULT SETS 0 PROGRAM TYPE SUB;

Note that there are new options, modified options, and options that are unmodified from previous versions. Following are the new options available in Version 6: NOT DETERMINISTIC | DETERMINISTIC This optional clause specifies whether the stored procedure will always return the same result from successive calls with identical input arguments. CONTAINS SQL | READS SQL DATA | MODIFIES SQL DATA | NO SQL This optional clause specifies whether the stored procedure issues any SQL statement, and if so, what type of SQL statements. DBINFO | NO DBINFO Specifies whether specific information known by DB2 is to be passed to the stored procedure as an additional invocation time argument. Following are the options that were enhanced in Version 6: PARAMETER STYLE Identifies the linkage convention used to pass parameters to the stored procedure. All of the linkage conventions provide arguments to the stored procedure containing the parameters specified on the SQL CALL

260

DB2 Java Stored Procedures: Learning by Example

statement. Some of the linkage conventions pass additional arguments to the stored procedure that provide more information to the stored procedure. NO WLM ENVIRONMENT | WLM ENVIRONMENT (name,*) Specifies if this stored procedure is to execute in the DB2-established stored procedure address space or in the WLM-established stored procedure address space. EXTERNAL SECURITY Specifies how this stored procedure interacts with an external security product (such as RACF) to control access to non-DB2 resources. The following options were already specifiable through the SYSIBM.SYSPROCEDURE catalog table and have not changed for this version of DB2. Following is a brief explanation of the various options: LANGUAGE Specifies the language in which this stored procedure is coded. EXTERNAL NAME Specifies the name of the load module for this stored procedure COLLID Identifies the package collection to use when the stored procedure is executed. ASUTIME Specifies the total amount of CPU that a single invocation of a stored procedure can run, in CPU service units. RUN OPTIONS Specifies the LE/370 run-time options to be passed to the stored procedure. STAY RESIDENT Specifies whether the stored procedure load module remains resident in memory when the stored procedure ends. PROGRAM TYPE Specifies whether the stored procedure runs as a main routine or as a subroutine. If the CREATE statement is embedded in a program, the default for this option depends on the value of the SQLRULES option: - If SQLRULES(DB2) is specified, the default for PROGRAM TYPE is MAIN.
261

Chapter 13. DB2 UDB for OS/390 stored procedures enhancements

- If SQLRULES(STD) is specified, the default for PROGRAM TYPE is SUB. If the CREATE statement is issued dynamically, the default for this option depends on the value of the CURRENT RULES special register: If the CURRENT RULES special register is DB2, the default for PROGRAM TYPE is MAIN. If the CURRENT RULES special register is STD, the default for PROGRAM TYPE is SUB. RESULT SET n Specifies the maximum number of result sets that can be returned by the stored procedure. COMMIT ON RETURN Indicates whether the transaction should be committed immediately upon return from a successful execution of the stored procedure. Note that in Version 6, there is no specification equivalent to AUTHID and LUNAME. These were most likely used for versioning. You can still control the versioning by placing the same stored procedure definition under different schemas. In this case, you should also specify that the stored procedure executes in different WLM-established stored procedure address spaces (different WLM application environments), if the load module name is equal for both versions, each one in a different load module library.

Note:

The stored procedures with the same name but different schemas can have different EXTERNAL NAME and be in the same WLM environment, they only have to be in different ones if they have the same EXTERNAL NAME (load module).

13.2.1 Parameter definitions


As mentioned before, stored procedures support as INPUT, OUTPUT, or INPUT-OUTPUT, parameters for the new built-in data types (rowid, BLOB, CLOB, DBCLOB), or user defined distinct data type (see Figure 42).

262

DB2 Java Stored Procedures: Learning by Example

IN | OUT | INOUT parname datatype

[schema.]udt | built_in

V5 and... rowid BLOB CLOB DBCLOB

AS LOCATOR

Figure 42. Stored procedures: parameters definition

Only a LOB data type, or a distinct type based on a LOB data type, can specify AS LOCATOR. Note that for Version 6, in the SQL CALL statement, you can pass a special register, an operator (+, -, *, /, CONCAT, !!), a CASE expression, a CAST specification, or a function besides a constant, a host variable, and the NULL value. A table can also be passed, if the SQL CALL statement is issued from a trigger. Each column of the table comes in as a separate parameter, described by an SQLDA.

Note:

In version 6, LOBs, LOCATORs and ROWID cannot be defined as parameters to stored procedures written in Java.

13.2.2 New options


This section describes in more detail the new options available in Version 6. FENCED Specifies that the stored procedure runs in an external address space to prevent DB2 storage from being corrupted. This is an optional specification because the architecture of stored procedure in DB2 has always been that the stored procedure runs in address spaces that are external to DB2. The reason for this specification is for compatibility with DB2 UDB in the workstation, when you can have stored procedures that are fenced and unfenced.

Chapter 13. DB2 UDB for OS/390 stored procedures enhancements

263

DETERMINISTIC The stored procedure always returns the same result from successive calls with identical input arguments. For example, if you issue the following CALL:
CALL TOTAL_SALES_96(itemnumber)

This is deterministic, because no matter how many times you invoke the stored procedure the total sales for a passed year will always be the same for a particular item. On the other hand, if you issue the following CALL:
CALL CURRENT_SALES(itemnumber)

This is not deterministic, because depending upon when you invoked the stored procedure, the sales for a particular item might have changed. Note that DB2 does not check if the stored procedure is consistent with the specification of DETERMINISTIC or NOT DETERMINISTIC. The specification is intended for documentation purposes. In the future, this might be used for optimization (not to actually call the stored procedure, if we already know what the answer will be). NO SQL No SQL statements are allowed in the stored procedure. If the stored procedure attempts to execute any SQL statements, then an error (SQLCODE-487) is raised at run time. Nevertheless, the stored procedure can perform complex calculations, access non-DB2 resources, or trigger events outside of DB2, such as to broadcast an e-mail. CONTAINS SQL If the stored procedure attempts to execute COMMIT, DELETE, DESCRIBE PREPARE, ROLLBACK, SELECT and INSERT SQL statements, then an error (SQLCODE-579) is raised at run time. This is the default when you create a procedure. The restriction applies to all SQL (cursors or singleton SQL). READS SQL DATA If the stored procedure attempts to execute COMMIT, DELETE, INSERT, ROLLBACK, and UPDATE SQL statements, then an error (SQLCODE-577) is raised at run time. MODIFIES SQL DATA If the stored procedure attempts to execute COMMIT, AND ROLLBACK SQL statements, then an error (SQLCODE-751) is raised at run time. If this was for a ROLLBACK statement, the whole unit of work is placed in a

264

DB2 Java Stored Procedures: Learning by Example

"must rollback state". The SYSIBM.SYSPROCEDURES (Version 5) catalog entries will be migrated to be 'MODIFIES SQL DATA', not the default CONTAINS SQL.
Note:

NO SQL, CONTAINS SQL, READS SQL DATA, and MODIFIES SQL DATA are (by ANSI rules) supposed to 'cascade' such that nested procedures obey the strictest rule specified by any parent (calling) procedure. DB2INFO When DB2INFO is specified (NO DB2INFO is the default), an additional argument is passed on invocation of the stored procedure. This specification is compatible with UDFs, therefore some of the information will be blank for stored procedures. The argument is a structure which contains the following information: - Location name length - Location name of where the stored procedure was invoked - Application run-time authorization ID, regardless of the nested routines in between this routine and the application - CCSID of the DB2 subsystem - Schema-name blank for stored procedures - Table name length, blank for stored procedures - Table name, blank for stored procedures. - Column name blank for stored procedures - Column name, blank for stored procedures - Database release level of where the stored procedure was invoked - Database version number of where the stored procedure was invoked - Operating system platform of where the stored procedure was invoked

13.2.3 Enhanced options


This section describes in more detail the enhanced options available in Version 6. PARAMETER STYLE DB2SQL In addition to GENERAL (in previous versions SIMPLE for the LINKAGE column of SYSPROCEDURES) and GENERAL WITH NULLS (in previous

Chapter 13. DB2 UDB for OS/390 stored procedures enhancements

265

versions SIMPLE WITH NULLS for the LINKAGE column of SYSPROCEDURES), the DB2SQL option can be specified. When DB2SQL is specified, additional arguments are passed to/from the stored procedure: - A null indicator for each parameter on the CALL statement - The SQLSTATE to be returned to DB2 upon completion of the stored procedure - The qualified name of the stored procedure (location.schema.procname) - The specific name of the stored procedure - Currently DB2 does not support multiple procedures with the same name in the same schema, so the specific name is the same as the procedure name - The SQL diagnostic string to be returned to DB2 Migrated stored procedures will have GENERAL or GENERAL WITH NULLS depending on the value of LINKAGE. EXTERNAL SECURITY DEFINER In addition to DB2 (in previous versions NO for the EXTERNAL_SECURITY column of SYSPROCEDURES) and USER (in previous versions YES for the EXTERNAL SECURITY column of SYSPROCEDURES), the DEFINER option can be specified. When DEFINER is specified, an external security environment should be established for the stored procedure. If the stored procedure accesses resources protected by an external security product, that access will be performed using the authorization ID of the person that created the stored procedure. This specification is valid only for WLM-established stored procedure address spaces. WLM ENVIRONMENT (name,*) When the stored procedure is called directly by an SQL application program, name specifies the WLM application environment used to run the stored procedure. If the stored procedure is called by another stored procedure or UDF (nested CALL to a stored procedure), this stored procedure will run in the environment used by the calling stored procedure or user-defined function.

266

DB2 Java Stored Procedures: Learning by Example

WLM will try to schedule the stored procedure to run in the same address space as the calling stored procedure or UDF. But if for any reason it cannot (for example, maximum number of TCBs exceeded, requirement to schedule another address space), the stored procedure will still run using the application environment of the caller, but will run in another address space. WLM uses the current workload and the priority of the thread to decide whether to schedule another address space. The stored procedure will run in the same application environment as the caller if the ,* is specified after name. Note also that to prevent users from moving a stored procedure or a UDF to a sensitive WLM application environment, DB2 invokes the external security manager (for example, RACF), to determine if the user is allowed to issue ALTER statements that reference the specified WLM environment. The RACF command below authorizes a DB2 user (DB2USER1) to CREATE or ALTER stored procedures on DB2 subsystem DB2A that specify the WLM environment PAYROLL:
PERMIT DB2A.WLMENV.PAYROLL CLASS(DSNR) ID(DB2USER1) ACCESS(READ)

13.2.4 Advantages of DDL


Following are the implications, resulting from the use of DDL to create stored procedures, as opposed to inserting rows directly into SYSIBM.SYSPROCEDURES. CREATE A better method of control over the stored procedure is now available. Although SYSIBM.SYSPROCEDURES is a catalog table, DB2 had no control over the information placed there other than the normal verification (column data type). Using DDL, DB2 can register dependencies between stored procedure and other objects. Dependencies in any packages that make a CALL to the procedure, and in triggers that invoke the stored procedure, are registered, but the stored procedure package is not tied to the UDF. DB2 now validates the parameter list at CREATE time. LE/370 run options are not validated at CREATE time, but LE/370 does that when DB2 passes the string to it. There are validations (not really new) between the options, such as which options are valid with NO WLM ENVIRONMENT. - SYSROUTINES and SYSPARMS When you create a stored procedure, DB2 places information in the new catalog tables SYSROUTINES and SYSPARMS. These tables also contain information related to UDFs.

Chapter 13. DB2 UDB for OS/390 stored procedures enhancements

267

- Privileges To CREATE a stored procedure, one of the following privileges is required: CREATE IN schema SYSADM or SYSCTRL authority. Usage of schemas The following sections describe some considerations related to the usage of schemas and stored procedures. Note that the CREATE IN schema is implicit in your own USERID. ALTER You can ALTER any of the options of a stored procedure. The altered definition and the original definition are both cached in memory. Only the application that performed the ALTER sees the altered definition. Once the application that performed the ALTER commits, the old definition is deleted and the new definition is available. - Privilege To ALTER a stored procedure, one of the following privileges is required: Ownership of the stored procedure ALTER IN schema SYSADM or SYSCTRL authority - CALL packages are invalidated Any program (client, UDFs, or another stored procedure that has a CALL for the altered procedure) have their packages invalidated. On the next invocation of the altered stored procedure, the packages are automatically rebound. DROP The keyword RESTRICT must be specified. All packages containing a CALL to the stored procedure are invalidated, but RESTRICT only applies to trigger packages. The stored procedure is not dropped if a trigger definition contains a CALL to this stored procedure.

268

DB2 Java Stored Procedures: Learning by Example

- Privilege To DROP a stored procedure, one of the following privileges is required: Ownership of the stored procedure DROP IN schema SYSADM or SYSCTRL authority COMMENT ON PROCEDURE You can use the COMMENT ON PROCEDURE procname to add comments to an existing stored procedure. These comments are registered in the REMARKS columns of the corresponding row of SYSROUTINES.

13.2.5 Schema name: CREATE PROCEDURE


When you create a stored procedure, you can specify a schema name, as for example:
CREATE schema.procname...

In this case, the schema can be the same as any authorization IDs of the process. However, if the specified name includes a qualifier that is not the same as one of these authorization IDs, then one of the following must be met: The privilege set includes SYSADM or SYSCTRL The authorization ID of the process has the CREATE IN privilege on the specified schema. If the procedure name is unqualified, as, for example:
CREATE procname....

and the statement is embedded in a program, the schema name of the procedure is the authorization ID in the QUALIFIER bind option when the plan or package was created or last rebound. If QUALIFIER was not used, the schema name of the procedure is the owner of the plan or package. If the procedure name is unqualified and the statement is dynamically prepared, the SQL authorization ID contained in the CURRENT SQLID special register is the schema name of the stored procedure.

Chapter 13. DB2 UDB for OS/390 stored procedures enhancements

269

13.2.6 Schema name: CALL statement


When the CALL statement is executed, the stored procedure must identify a stored procedure that exists at the application server for which the application is connected or in the location specified in the three-part name. When you code the client application, you have the following options: Specify a literal for the stored procedure name with the schema name. Specify a literal for the stored procedure name without a schema name. Specify a host variable for the stored procedure name. If you specify a literal for the stored procedure name with the schema name, the procedure being invoked must have already been added to the SYSROUTINES catalog table via CREATE PROCEDURE or via migration to Version 6. If the stored procedure is not found, you will get SQLCODE -440. If VALIDATE(RUN) is specified, the -440 SQLCODE does not cause the BIND to fail. If the remote DB2 is Version 4 or Version 5, no schema resolution will be done; the procedure name will be checked in SYSIBM.SYSPROCEDURES. If a qualified name (where the schema name is not SYSPROC) is sent to a Version 4 or Version 5 system, the CALL statement will fail there, just as it does today on Version 4 or Version 5. If the remote system is Version 6, the qualification is made there as described. See the other platform specifications for how they handle a CALL statement. Figure 43 shows a summary of the flow during bind: Does the schema contain the stored procedure? - If YES, that is OK. - If NO, during the bind a -440 SQLCODE is returned. - BIND will succeed or fail on what was specified for VALIDATE.

270

DB2 Java Stored Procedures: Learning by Example

V4/V5 ===> SYSPROC CALL schema.procname V6 ===> Any name


procname in schema? NO SQLCODE -440 BIND VALIDATE RUN=>OK BIND=>FAIL YES ===>OK

Figure 43. Schema name: CALL statement 1/2

You should use VALIDATE(RUN) with a remote call or the local BIND will fail, since the stored procedure will most likely not exist at the calling site. Note that there was not any such validation in Version 4 or 5. If you specify a literal for the stored procedure name without a schema name, then name resolution occurs at bind time based on the PATH bind option specification. If you specify a host variable for the stored procedure name, then name resolution occurs at the execution time based on the value of the CURRENT PATH special register. Note that all CALLs issued by ODBC, JDBC, or CLI are resolved at execution time. This is because each of these drivers map the CALL onto a CALL :hv in the driver package. DB2 searches the schema name using the CURRENT PATH special register or the PATH bind option from left to right. It qualifies the specified procedure name starting with the first schema name of CURRENT PATH or PATH bind option until a match is found. If a matching schema.procname is found, but the caller is not authorized to it, or if the number of parameters in the procedure definition does not match the number of parameters specified in the CALL statement, the next schema.procname combination is tried until one is found that the caller is authorized to execute and has a matching number of parameters, or until the list of schemas is exhausted. If the

Chapter 13. DB2 UDB for OS/390 stored procedures enhancements

271

procedure name cannot be resolved a -440 SQLCODE is returned. Figure 44 summarizes this flow.

C A L L p ro c 1 C A L L :h o s tv a r

P A T H b in d o p tio n C U R R E N T P A T H s p e c re g
N e x t s c h e m a ? = = = = > N O = = = = = > -4 4 0 p ro c 1 fo u n d ?

NO
U s e r is a u t h o ri z e d ?

M a tc h i n g n u m b e r o f p a rm s ?

T h a t's th e o n e !!!

Figure 44. Schema name: CALL statement 2/2

13.3 Lifted DML restrictions


You can now code CONNECT, SET CONNECTION and RELEASE within a stored procedure. It is strongly recommended that the stored procedure and the caller be precompiled with CONNECT 2. Because statements in a stored procedure can go to distributed sites, and COMMITs are not allowed in a stored procedure, type 1 connect would therefore be a problem. Also, you can now invoke a local or remote stored procedure from a stored procedure. With the new DRDA support for three-part names and aliases for tables, together with the nested capabilities of stored procedures, you can use DB2 to construct N-tier client/server applications, where SQL and stored procedures RPC are used to communicate between sites. DataJoiner has DRDA server capability. Today, that means a DB2 requester can issue a SELECT to DataJoiner, and obtain query results from Oracle, Sybase, and so on. In Version 6 you will be able to issue queries to DataJoiner from a DB2 stored procedure to collect data from many servers in the network, and return this data to the client as a stored procedure answer set.

272

DB2 Java Stored Procedures: Learning by Example

Note that if the stored procedure is used for complex logic and complex calculation but no data access, you can have code reuse. For example, assume you have a workstation that invokes a stored procedure on one DB2, whose hardware capability is not fitted for heavy calculations. This stored procedure can invoke a remote stored procedure just for this purpose. Figure 45 shows an example of nested SQL CALLs. See 13.4, Nested stored procedures: characteristics on page 274 for more details about nested stored procedures.

CALL PROC1

PROC1 CALL PROC2

PROC2 CALL L2.SCX.PR3

DRDA
PR3 CALL PR4 PR4

Figure 45. SQL CALL statement (nesting)

In addition, as mentioned before, if you use the three-part name, then the location name does not need to match the location of the current server. It can be any location specified in the SYSIBM.SYSLOCATIONs catalog table. Note that if you specify a location that refers to a DB2 on OS/390 prior to Version 6, you should code for the second part SYSPROC. DB2 UDB supports schema names for stored procedures. No particular DRDA level required. The schema.procname is buried within the execute SQL statement DDM message.

Chapter 13. DB2 UDB for OS/390 stored procedures enhancements

273

13.4 Nested stored procedures: characteristics


In Version 6 you are allowed to use nested stored procedures. Following are the characteristics of this feature: Environment saved/restored on each nested call The following special registers are saved before the SQL CALL is executed from the caller stored procedure and restored when the control is returned from the called stored procedure: CURRENT CURRENT CURRENT CURRENT CURRENT CURRENT CURRENT CURRENT CURRENT CURRENT DATE DEGREE PACKAGESET PATH RULES SERVER TIME TIMESTAMP TIMEZONE USER

No COMMIT ON RETURN A stored procedure with the COMMIT ON RETURN attribute cannot be nested. In other words, a stored procedure, user-defined function, or trigger cannot issue a CALL to a stored procedure defined with the COMMIT ON RETURN attribute (SQLCODE -729). However, a client can invoke a stored procedure that has COMMIT ON RETURN specified, and this stored procedure CALLs other stored procedures for which COMMIT ON RETURN was NOT specified. A stored procedure that executes in a WLM-established address space cannot be nested with a stored procedure that executes in a DB2-established address space. You can nest DB2-established with DB2-established and WLM-established with WLM-established, but you cannot nest the two with each other. Result sets Result sets are returned only to the previous levels.

274

DB2 Java Stored Procedures: Learning by Example

Up to 16 levels of nesting You can nest stored procedures, UDFs and triggers up to 16 levels. Note that if you use a three-part name to invoke a procedure at a remote location, the nesting level starts over at that new server. Also, if there is a loop back to the first server, it is again reset, but the remote chain will stop there because that server cannot nest to another location. The nesting level is any combination of stored procedures, UDFs, and triggers. Can use alias for three-part name tables This capability is no different than in previous versions of DB2. However, DRDA can now be used as the protocol; therefore, you can also access tables at non-DB2 for OS/390 remote sites from a stored procedure.

13.5 Authorization
Figure 46 shows the authorization required to issue the CALL statement for a stored procedure, depending on the caller, as follows: The client application that has a CALL coded must have a package created (if the client is remote, the package is enough), or must have a plan that includes a package, or the DBRM was bound directly in plan. The stored procedure, in turn, must have a package if it has SQL statements coded. The stored procedure can invoke another program (or stored procedure), which, in turn, must have a package if the routine has SQL statements. To execute the plan (or package for remote clients), one of the following privileges is required: EXECUTE on plan or package of the client application Ownership of the plan or package of the client application PACKADM on the collection where the package for client application was bound SYSADM authority

Chapter 13. DB2 UDB for OS/390 stored procedures enhancements

275

C LIEN T

SP1 C ALL P G M 1

CA LL S P 1

PG M 1

P LA N
C LIE N T

S P1

P A CK A G E

PGM1 P A CK A G E

P AC K A G E

To execute the package/plan m ust: EX E CU TE on plan/package Ownership of plan/package PA C K AD M on collection SY S A DM Owner of client package/authid of client m us t: E X E CU TE on S P O wnership of S P S Y S A DM

O wner (definer) of S P m ust: E X E CU TE on package(s) (S P 1 and P GM 1) O wnership of package(s) P A C KA D M on collection S Y S A DM

Figure 46. Authorization CALL

For static SQL calls that specify a literal for a procedure name, the owner of the package for the client application (OWNER bind specification) must have one of the following privileges: EXECUTE on the stored procedure Ownership of the stored procedure SYSADM authority The owner of the stored procedure (owner is the definer, who issued the CREATE PROCEDURE statement, in turn, must have one of the following privileges: EXECUTE on the stored procedure package and packages for invoked routines from the stored procedure (packages SP1 and PGM1 as shown in Figure 46) Ownership of the stored procedure package and packages for invoked routines from the stored procedure (packages SP1 and PGM1 as shown in Figure 46) PACKADM on the collection of the stored procedure and on the collection where the packages for invoked routines from the stored procedure (packages SP1 and PGM1 as shown in Figure 46) SYSADM authority

276

DB2 Java Stored Procedures: Learning by Example

13.5.1 Who has EXECUTE privilege on a stored procedure?


The following rules determine who is checked for EXECUTE privilege on a stored procedure: If a literal is specified, the owner of the package associated with the client application is checked. If a host variable or parameter marker is used, then checking for the privilege to execute the stored procedure depends on the DYNAMICRULES bind option as follows: - RUN The authorization ID is the primary or any secondary authorization ID associated with the client application process. - BIND The authorization ID is the owner of the package or plan of the client application. - DEFINE If the SQL CALL is issued from a stored procedure or a UDF, the authorization ID is the owner of the stored procedure or UDF. Otherwise, the authorization ID is the owner of the package plan of the client application. - INVOKE If the SQL CALL is issued from stored procedure or a UDF, the authorization ID is the invoker of the stored procedure or UDF. Otherwise the authorization ID is the primary or any secondary authorization ID associated with the client application process. Figure 47 summarizes the checking process.

Chapter 13. DB2 UDB for OS/390 stored procedures enhancements

277

CLIENT

SP1 CALL PGM1

CALL SP1

PGM1

PLAN
CLIENT

SP1

PACKAGE

PGM1 PACKAGE

PACKAGE

* Literal:owner of the package/plan of the client * Host variable: depends on DYNAMICRULES: RUN =>primary/sec AUTHID associated with the client BIND=>owner of package/plan containing CALL DEFINE=> equal BIND, or owner of SP/UDF INVOKE=> equal RUN, or invoker of SP/UDF
Figure 47. Authorization who is checked?

Let us now guide you though an example: Assume that a stored procedure (SP1) invokes another routine (PGM1). There is a client application with a CALL statement for this stored procedure. Three packages are invoked: PKG1 for the routine PKG2 for the stored procedure PKG3 for the client application Also assume the following: The owner of PKG1 is USER1. The owner of PKG2 is USER2. The owner of the stored procedure is USER3. The owner of the package of the client application is USER4. USER5 wants to execute the client application. Under these conditions: USER3, the owner of the stored procedure, must have EXECUTE privilege on PKG1.

278

DB2 Java Stored Procedures: Learning by Example

USER1: GRANT EXECUTE ON PKG1 TO USER3

USER5 must have EXECUTE privilege on the package of the client application:
USER4: GRANT EXECUTE ON PKG3 TO USER5

- For static SQL programs that specify a literal, the owner of the client application (USER4) must have EXECUTE privilege on the stored procedure:
USER3: GRANT EXECUTE ON PROCEDURE SP1 TO USER4

- For static SQL that specifies a host variable or parameter marker the authorization ID that will be checked for the execution of the stored procedure will be USER5 or USER4 depending on the DYNAMICRULES bind option. If DYNAMICRULES bind option is RUN, the privilege is checked against USER5:
USER3: GRANT EXECUTE ON PROCEDURE SP1 TO USER5

If DYNAMICRULES bind option is BIND, the privilege is checked against USER4:


USER3: GRANT EXECUTE ON PROCEDURE SP1 TO USER4

Figure 48 summarizes this example.

SP1 USER3

USER5

CALL SP1 CALL PGM1

PGM1

PKG3

USER4

PKG2

USER2

PKG1

USER1

USER1: GRANT EXECUTE ON PACKAGE PKG1 TO USER3 USER2: GRANT EXECUTE ON PACKAGE PKG2 TO USER3

USER4: GRANT EXECUTE ON PACKAGE PKG3 TO USER5

IN ADDITION
CALL SP1 ===> USER3: GRANT EXECUTE ON PROCEDURE SP1 TO USER4 CALL :HV ===> USER3: GRANT EXECUTE ON PROCEDURE SP1 TO USER5 (DYNAMICRULES RUN) CALL :HV ===> USER3: GRANT EXECUTE ON PROCEDURE SP1 TO USER4 (DYNAMICRULES BIND)

Figure 48. Authorization example

Chapter 13. DB2 UDB for OS/390 stored procedures enhancements

279

13.6 DISPLAY PROCEDURE command


Note that the DISPLAY PROCEDURE command accepts the qualified stored procedure name as parameter and now displays the schema name and the WLM_ENV information. See Figure 49.

-DISPLAY PROCEDURE(PAYROLL.*, HRPROD.*)

DSNX940I csect - DISPLAY PROCEDURE REPORT FOLLOWS------ SCHEMA=PAYROLL PROCEDURE STATUS PAYRPRC1 STARTED PAYRPRC2 STOPQUE PAYRPRC3 STARTED USERPRC4 STOPREJ

ACTIVE 0 0 2 0

QUEUED 0 5 0 0

MAXQUE 1 5 6 1

TIMEOUT WLM_ENV 0 PAYROLL 3 PAYROLL 0 PAYROLL 0 SANDBOX

------ SCHEMA=HRPROD PROCEDURE STATUS ACTIVE HRPRC1 STARTED 0 HRPRC2 STOPREJ 0 DISPLAY PROCEDURE REPORT COMPLETE

QUEUED 0 0

MAXQUE 1 1

TIMEOUT 0 0

WLM_ENV HRPROCS HRPROCS

Figure 49. DISPLAY PROCEDURE command

The DISPLAY PROCEDURE does not use the current path to determine schema. It works the same way from an application program as from the console. The argument to display with schema can be: Procedure name displays the named stored procedure in schema SYSPROC (*.*) displays information for all stored procedures in all schemas that have been accessed by DB2 applications, since DB2 was started. This is the default. You must have DISPLAY privilege, SYSOPR, SYSCTRL, or SYSADM authority for all schemas to issue DISPLAY PROCEDURE with this option. Note that the owner of a stored procedure can DISPLAY their stored procedures status.

280

DB2 Java Stored Procedures: Learning by Example

13.7 Migration considerations


During migration to DB2 for OS/390 Version 6, DB2 will copy the rows from the existing SYSIBM.SYSPROCEDURES and will populate SYSIBM.SYSPARMS and SYSIBM.SYSROUTINES (with appropriate reformatting), where SCHEMA column is set to SYSPROC. DB2 will not copy rows that contain non-blank values for the AUTHID or LUNAME. Although not used in Version 6, DB2 does not drop the SYSIBM.SYSPROCEDURES catalog table, DB2 needs it for data sharing coexistence and fallback. Stored procedures migrated from Version 4 and Version 5 will not have an owner. DB2 authorization will treat these migrated procedures differently that those created by the CREATE PROCEDURE statement. The migrated rows with no owner will follow the same authorization rules. Refer to Chapter 10, Migration of DB2 for OS/390 Version 5 to Version 6 on page 181 for more information about migration.

Chapter 13. DB2 UDB for OS/390 stored procedures enhancements

281

282

DB2 Java Stored Procedures: Learning by Example

Part 4. Appendices

Copyright IBM Corp. 2000

283

284

DB2 Java Stored Procedures: Learning by Example

Appendix A. New messages and error codes


This appendix presents some of the new messages and error codes for DB2 UDB for OS/390 version 6.

A.1 STOP DDF MODE SUSPEND


DSNL065I DSNL065I csect CURRENT DDF STATE DOES NOT PERMIT STOP DDF MODE(SUSPEND) Explanation: The current DDF state does not allow suspend processing to be initiated. DDF must be started for normal processing in order for suspend processing to be initiated. System Action: The command is not executed.
_____________________________________________________________

DSNL066I DSNL066I csect STOP DDF MODE(SUSPEND) COMPLETE Explanation: DDF suspend processing has completed successfully. DDF has suspended all inbound activity. System Action: Processing continues normally.
_____________________________________________________________

DSNL067I DSNL067I csect CURRENT DDF STATE DOES NOT PERMIT START DDF Explanation: The current DDF state does not allow START DDF processing to be initiated. System Action: The command is not executed.
_____________________________________________________________

DSNL068I DSNL068I csect START DDF (RESUME PROCESSING) COMPLETE Explanation: DDF has resumed normal processing. System Action: Processing continues normally.
_____________________________________________________________

DSNL069I DSNL069I csect DDF IS SUSPENDING

Copyright IBM Corp. 2000

285

Explanation: DDF has initiated suspend processing. System Action: Processing continues normally.
_____________________________________________________________

DSNL070I DSNL070I csect DDF IS RESUMING Explanation: DDF has initiated resume processing. System Action: Processing continues normally.
_____________________________________________________________

DSNL071I DSNL071I csect WAIT OR CANCEL REQUIRES KEYWORD SUSPEND Explanation: The WAIT(n) or CANCEL(n) key words require that MODE(SUSPEND) be specified. System Action: The command is not executed.
_____________________________________________________________

DSNL072I DSNL072I csect WAIT TIME EXPIRED, DDF RESUME PROCESSING INITIATED Explanation: The DDF suspend process has not completed successfully in the period of time specified for the WAIT key word and so DDF resume processing has been initiated. System Action: DDF resume processing has been initiated.
_____________________________________________________________

DSNL073I DSNL073I csect CANCEL TIME EXPIRED, CANCEL ACTIVE DBAT PROCESSING HAS BEEN INITIATED. Explanation: The DDF suspend process has not completed successfully in the period of time specified for the CANCEL key word and so DDF is cancelling all active data base access threads (DBATS). System Action: DDF is attempting to terminate all active data base access threads.

286

DB2 Java Stored Procedures: Learning by Example

Appendix B. Sample code, DDL, and preparation scripts


This appendix contains information to help you build the stored procedure samples listed in the book. You can also find all of the items within this section in electronic format on the accompanying CD-ROM (see Appendix E, Using the additional material on page 347).

B.1 Sample DDL


Below are the DDL files used to create the ACME SOFTWARE CO sample application referred to throughout this book. The DDL for each of the platforms we cover is listed separately (however, since the DDL for Windows NT and AIX is exactly the same, it is listed only once. Within each of these sections, the standard and enhanced DDL is shown (for a definition of these terms, refer to 3.3, Sample application components on page 21).

B.1.1 DB2 UDB for OS/390 DDL


This section contains the sample DDL for the OS/390 platform.
B.1.1.1 Standard DDL
----------------------------------------------------------DDL FOR ACME SOFTWARE CO EXAMPLE ----- SQL LEVEL: STANDARD (NO ENHANCED V6 FEATURES) ------------------------------------------------------------------------------------------------------------------CREATE DATABASE ----------------------------------------------------------DROP DATABASE DACMES ; COMMIT ; CREATE DATABASE DACMES ; --------------------------------------------------------CREATE TABLESPACES/TABLES/INDEXES ---------------------------------------------------------

Copyright IBM Corp. 2000

287

--- CUSTOMER -CREATE TABLESPACE SCUST IN DACMES USING STOGROUP SYSDEFLT;

CREATE TABLE ACMES.CUSTOMER ( CUST_NO INTEGER NOT NULL PRIMARY KEY, CUST_FIRSTNAME CHAR(20) NOT NULL, CUST_LASTNAME CHAR(20) NOT NULL, CUST_ADDRESS CHAR(30) ) IN DACMES.SCUST; CREATE UNIQUE INDEX ACMES.P_CUSTOMER ON ACMES.CUSTOMER (CUST_NO); --- PRODUCT -CREATE TABLESPACE SPRODUCT IN DACMES USING STOGROUP SYSDEFLT; CREATE TABLE ACMES.PRODUCT ( PROD_NO INTEGER PROD_DESC PROD_PRICE PROD_IN_STOCK ) IN DACMES.SPRODUCT;

NOT NULL PRIMARY KEY, CHAR(30) NOT NULL, DECIMAL(10,2) NOT NULL, INTEGER NOT NULL

CREATE UNIQUE INDEX ACMES.P_PRODUCT ON ACMES.PRODUCT (PROD_NO); --

288

DB2 Java Stored Procedures: Learning by Example

-- ORDER -CREATE TABLESPACE SORDER IN DACMES USING STOGROUP SYSDEFLT; CREATE TABLE ACMES.ORDER ( ORD_NO INTEGER

NOT NULL PRIMARY KEY , ORD_DATE DATE NOT NULL, ORD_CUST_NO INTEGER NOT NULL, FOREIGN KEY (ORD_CUST_NO) REFERENCES ACMES.CUSTOMER(CUST_NO) ON DELETE CASCADE ) IN DACMES.SORDER; CREATE UNIQUE INDEX ACMES.P_ORDER ON ACMES.ORDER (ORD_NO); CREATE INDEX ACMES.F_ORDER_1 ON ACMES.ORDER (ORD_CUST_NO); --- ORDER ITEM -CREATE TABLESPACE SORDITEM IN DACMES USING STOGROUP SYSDEFLT; CREATE TABLE ACMES.ORDER_ITEM ( ORD_ITEM_NO INTEGER NOT NULL PRIMARY KEY, ORD_ITEM_ORD_NO INTEGER NOT NULL, ORD_ITEM_PROD_NO INTEGER NOT NULL, ORD_ITEM_QTY INTEGER NOT NULL, FOREIGN KEY (ORD_ITEM_ORD_NO) REFERENCES ACMES.ORDER(ORD_NO) ON DELETE CASCADE, FOREIGN KEY (ORD_ITEM_PROD_NO) REFERENCES ACMES.PRODUCT(PROD_NO) ON DELETE CASCADE ) IN DACMES.SORDITEM;

Appendix B. Sample code, DDL, and preparation scripts

289

CREATE UNIQUE INDEX ACMES.P_ORDER_ITEM ON ACMES.ORDER_ITEM (ORD_ITEM_NO); CREATE INDEX ACMES.F_ORDER_ITEM_1 ON ACMES.ORDER_ITEM (ORD_ITEM_ORD_NO); CREATE INDEX ACMES.F_ORDER_ITEM_2 ON ACMES.ORDER_ITEM (ORD_ITEM_PROD_NO); --- HI_CUST_NO -CREATE TABLESPACE SHICUST IN DACMES USING STOGROUP SYSDEFLT; CREATE TABLE ACMES.HI_CUST_NO ( HI_CUST_NO INTEGER NOT NULL ) IN DACMES.SHICUST; INSERT INTO ACMES.HI_CUST_NO VALUES(1); --- HI_ORD_NO -CREATE TABLESPACE SHIORD IN DACMES USING STOGROUP SYSDEFLT; CREATE TABLE ACMES.HI_ORD_NO ( HI_ORD_NO INTEGER NOT NULL ) IN DACMES.SHIORD; INSERT INTO ACMES.HI_ORD_NO VALUES(1);

290

DB2 Java Stored Procedures: Learning by Example

B.1.1.2 Enhanced DDL


Note

If you intend to submit the following DDL using SPUFI, ensure that the termination character is set to : in the SPUFI defaults panel (see explanatory text in DDL for details).

----------------------------------------------------------DDL FOR ACME SOFTWARE CO EXAMPLE ------- SQL LEVEL: ENHANCED (USES ENHANCED V6 FEATURES) ----- NOTE: THE COLON (':') CHARACTER IS USED INSTEAD --OF THE SEMICOLON (';') CHARACTER FOR --TERMINATING COMMNANDS, DUE TO THE PRESENCE --OF CREATE TRIGGER STATEMENTS. ----IF THIS FILE IS SUBMITTED USING SPUFI, --ENSURE THAT THE TERMINATION CHARACTER IS --SET TO ':' IN THE SPUFI DEFAULTS PANEL. -----------------------------------------------------------

--------------------------------------------------------CREATE DATABASE ----------------------------------------------------------DROP DATABASE DACMEE : COMMIT : CREATE DATABASE DACMEE : --------------------------------------------------------CREATE TABLESPACES/TABLES/INDEXES ----------------------------------------------------------- CUSTOMER --

Appendix B. Sample code, DDL, and preparation scripts

291

CREATE TABLESPACE SCUST IN DACMEE USING STOGROUP SYSDEFLT:

CREATE TABLE ACMEE.CUSTOMER ( CUST_NO INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1, CACHE 10), CUST_FIRSTNAME CHAR(20) NOT NULL, CUST_LASTNAME CHAR(20) NOT NULL, CUST_ADDRESS CHAR(30) NOT NULL ) IN DACMEE.SCUST: CREATE UNIQUE INDEX ACMEE.P_CUSTOMER ON ACMEE.CUSTOMER (CUST_NO): --- PRODUCT -CREATE TABLESPACE SPRODUCT IN DACMEE USING STOGROUP SYSDEFLT: CREATE TABLE ACMEE.PRODUCT ( PROD_NO INTEGER

NOT NULL PRIMARY KEY,

PROD_DESC CHAR(30), PROD_PRICE DECIMAL(10,2) NOT NULL, PROD_IN_STOCK INTEGER NOT NULL ) IN DACMEE.SPRODUCT: CREATE UNIQUE INDEX ACMEE.P_PRODUCT ON ACMEE.PRODUCT (PROD_NO): --

292

DB2 Java Stored Procedures: Learning by Example

-- ORDER -CREATE TABLESPACE SORDER IN DACMEE USING STOGROUP SYSDEFLT: CREATE TABLE ACMEE.ORDER ( ORD_NO INTEGER PRIMARY KEY

NOT NULL

GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1, CACHE 10), ORD_DATE DATE NOT NULL, ORD_CUST_NO INTEGER NOT NULL, FOREIGN KEY (ORD_CUST_NO) REFERENCES ACMEE.CUSTOMER(CUST_NO) ON DELETE CASCADE ) IN DACMEE.SORDER: CREATE UNIQUE INDEX ACMEE.P_ORDER ON ACMEE.ORDER (ORD_NO): CREATE INDEX ACMEE.F_ORDER_1 ON ACMEE.ORDER (ORD_CUST_NO): --- ORDER ITEM -CREATE TABLESPACE SORDITEM IN DACMEE USING STOGROUP SYSDEFLT: CREATE TABLE ACMEE.ORDER_ITEM ( ORD_ITEM_NO INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1, CACHE 10), ORD_ITEM_ORD_NO INTEGER NOT NULL,

Appendix B. Sample code, DDL, and preparation scripts

293

ORD_ITEM_PROD_NO INTEGER NOT NULL, ORD_ITEM_QTY INTEGER NOT NULL, FOREIGN KEY (ORD_ITEM_ORD_NO) REFERENCES ACMEE.ORDER(ORD_NO) ON DELETE CASCADE, FOREIGN KEY (ORD_ITEM_PROD_NO) REFERENCES ACMEE.PRODUCT(PROD_NO) ON DELETE CASCADE ) IN DACMEE.SORDITEM: CREATE UNIQUE INDEX ACMEE.P_ORDER_ITEM ON ACMEE.ORDER_ITEM (ORD_ITEM_NO): CREATE INDEX ACMEE.F_ORDER_ITEM_1 ON ACMEE.ORDER_ITEM (ORD_ITEM_ORD_NO): CREATE INDEX ACMEE.F_ORDER_ITEM_2 ON ACMEE.ORDER_ITEM (ORD_ITEM_PROD_NO):

--------------------------------------------------------CREATE GLOBAL TEMP TABLES ----- THESE ARE USED BY THE AFTER-INSERT TRIGGERS THAT --- ARE DEFINED BELOW. THE TRIGGERS INSERT THE PRIMARY --- KEY VALUE OF THE NEW ROW INTO THE GLOBAL TEMP --- TABLE TO ALLOW IT TO BE ACCESSED BY THE CALLING --- APP. ----------------------------------------------------------CREATE GLOBAL TEMPORARY TABLE ACMEE.GTT_CUST_NO ( CUST_NO INTEGER NOT NULL ): CREATE GLOBAL TEMPORARY TABLE ACMEE.GTT_ORDER_NO ( ORDER_NO INTEGER NOT NULL ): --------------------------------------------------------CREATE TRIGGERS ---------------------------------------------------------

294

DB2 Java Stored Procedures: Learning by Example

CREATE TRIGGER ACMEE.CUST_IA AFTER INSERT ON ACMEE.CUSTOMER REFERENCING NEW AS NEWROW FOR EACH ROW MODE DB2SQL BEGIN ATOMIC INSERT INTO ACMEE.GTT_CUST_NO (CUST_NO) VALUES (NEWROW.CUST_NO); END: CREATE TRIGGER ACMEE.ORD_IA AFTER INSERT ON ACMEE.ORDER REFERENCING NEW AS NEWROW FOR EACH ROW MODE DB2SQL BEGIN ATOMIC INSERT INTO ACMEE.GTT_ORDER_NO (ORDER_NO) VALUES (NEWROW.ORD_NO); END: --------------------------------------------------------Create Temporary Table Used For Summary Query--------------------------------------------------------create global temporary table acmee.order_item_summ ( PROD_DESC CHAR(30) , QTY_1_TO_5 CHAR(1) NOT NULL, QTY_6_TO_10 CHAR(1) NOT NULL, QTY_11_PLUS CHAR(1) NOT NULL ): --------------------------------------------------------POPULATE PRODUCT TABLE --------------------------------------------------------INSERT INTO ACMEE.PRODUCT (PROD_NO, PROD_DESC, PROD_PRICE, PROD_IN_STOCK) VALUES (1,'Acme Word Processor',19.99,200): INSERT INTO ACMEE.PRODUCT (PROD_NO, PROD_DESC, PROD_PRICE, PROD_IN_STOCK) VALUES (2,'Acme Speadsheet',29.99,12): INSERT INTO ACMEE.PRODUCT (PROD_NO, PROD_DESC, PROD_PRICE, PROD_IN_STOCK) VALUES (3,'Acme Presentation Graphics',29.99,101): INSERT INTO ACMEE.PRODUCT

Appendix B. Sample code, DDL, and preparation scripts

295

(PROD_NO, PROD_DESC, PROD_PRICE, PROD_IN_STOCK) VALUES (4,'Acme E-Mail Client',39.99,240): INSERT INTO ACMEE.PRODUCT (PROD_NO, PROD_DESC, PROD_PRICE, PROD_IN_STOCK) VALUES (5,'Acme Office Suite',49.99,12): INSERT INTO ACMEE.PRODUCT (PROD_NO, PROD_PRICE, PROD_IN_STOCK) VALUES (6,69.99,678):

--------------------------------------------------------POPULATE CUSTOMER --------------------------------------------------------INSERT INTO ACMEE.CUSTOMER (cust_firstname, cust_lastname, cust_address) VALUES ('John Q.', 'Public', '111 1st St., San Jose, CA '):

--------------------------------------------------------POPULATE ORDER --------------------------------------------------------INSERT INTO ACMEE.ORDER (ord_date, ord_cust_no) VALUES (CURRENT DATE, 1): INSERT INTO ACMEE.ORDER (ord_date, ord_cust_no) VALUES (CURRENT DATE - 1 DAY, 1): --------------------------------------------------------POPULATE ORDER ITEM --------------------------------------------------------Insert into ACMEE.ORDER_ITEM (ORD_ITEM_ORD_NO, ORD_ITEM_PROD_NO,ORD_ITEM_QTY) VALUES(1,1,1): Insert into ACMEE.ORDER_ITEM (ORD_ITEM_ORD_NO, ORD_ITEM_PROD_NO,ORD_ITEM_QTY) VALUES(1,2,2): Insert into ACMEE.ORDER_ITEM (ORD_ITEM_ORD_NO, ORD_ITEM_PROD_NO,ORD_ITEM_QTY) VALUES(1,3,3): Insert into ACMEE.ORDER_ITEM (ORD_ITEM_ORD_NO, ORD_ITEM_PROD_NO,ORD_ITEM_QTY)

296

DB2 Java Stored Procedures: Learning by Example

VALUES(1,4,4): Insert into ACMEE.ORDER_ITEM (ORD_ITEM_ORD_NO, ORD_ITEM_PROD_NO,ORD_ITEM_QTY) VALUES(1,5,5):

Insert into ACMEE.ORDER_ITEM (ORD_ITEM_ORD_NO, ORD_ITEM_PROD_NO,ORD_ITEM_QTY) VALUES(2,1,2): Insert into ACMEE.ORDER_ITEM (ORD_ITEM_ORD_NO, ORD_ITEM_PROD_NO,ORD_ITEM_QTY) VALUES(2,2,4): Insert into ACMEE.ORDER_ITEM (ORD_ITEM_ORD_NO, ORD_ITEM_PROD_NO,ORD_ITEM_QTY) VALUES(2,3,6): Insert into ACMEE.ORDER_ITEM (ORD_ITEM_ORD_NO, ORD_ITEM_PROD_NO,ORD_ITEM_QTY) VALUES(2,4,8): Insert into ACMEE.ORDER_ITEM (ORD_ITEM_ORD_NO, ORD_ITEM_PROD_NO,ORD_ITEM_QTY) VALUES(2,5,10):

Insert into ACMEE.ORDER_ITEM (ORD_ITEM_ORD_NO, ORD_ITEM_PROD_NO,ORD_ITEM_QTY) VALUES(2,6,22):

B.1.2 DB2 UDB for AIX and Windows DDL


This section contains the sample DDL for the AIX and Windows NT platforms.
B.1.2.1 Standard DDL
----------------------------------------------------------DDL FOR ACME SOFTWARE CO EXAMPLE ----- SQL LEVEL: STANDARD (NO ENHANCED V6 FEATURES) ------------------------------------------------------------ to load: -- db2 -tvf ddls.txt

Appendix B. Sample code, DDL, and preparation scripts

297

--------------------------------------------CREATE TABLES/INDEXES --------------------------------------------CONNECT TO ACMES; --- CUSTOMER --

CREATE TABLE ACMES.CUSTOMER ( CUST_NO INTEGER NOT NULL PRIMARY KEY, CUST_FIRSTNAME CHAR(20) NOT NULL, CUST_LASTNAME CHAR(20) NOT NULL, CUST_ADDRESS CHAR(30) ) ; CREATE UNIQUE INDEX ACMES.P_CUSTOMER ON ACMES.CUSTOMER (CUST_NO); --- PRODUCT -CREATE TABLE ACMES.PRODUCT ( PROD_NO INTEGER PROD_DESC PROD_PRICE PROD_IN_STOCK ) ;

NOT NULL PRIMARY KEY, CHAR(30) NOT NULL, DECIMAL(10,2) NOT NULL, INTEGER NOT NULL

CREATE UNIQUE INDEX ACMES.P_PRODUCT ON ACMES.PRODUCT (PROD_NO); --- ORDER -CREATE TABLE ACMES.ORDER

298

DB2 Java Stored Procedures: Learning by Example

( ORD_NO

NOT NULL PRIMARY KEY , ORD_DATE DATE NOT NULL, ORD_CUST_NO INTEGER NOT NULL, FOREIGN KEY (ORD_CUST_NO) REFERENCES ACMES.CUSTOMER(CUST_NO) ON DELETE CASCADE ) ; CREATE UNIQUE INDEX ACMES.P_ORDER ON ACMES.ORDER (ORD_NO); CREATE INDEX ACMES.F_ORDER_1 ON ACMES.ORDER (ORD_CUST_NO); --- ORDER ITEM -CREATE TABLE ACMES.ORDER_ITEM ( ORD_ITEM_NO INTEGER NOT NULL PRIMARY KEY, ORD_ITEM_ORD_NO INTEGER NOT NULL, ORD_ITEM_PROD_NO INTEGER NOT NULL, ORD_ITEM_QTY INTEGER NOT NULL, FOREIGN KEY (ORD_ITEM_ORD_NO) REFERENCES ACMES.ORDER(ORD_NO) ON DELETE CASCADE, FOREIGN KEY (ORD_ITEM_PROD_NO) REFERENCES ACMES.PRODUCT(PROD_NO) ON DELETE CASCADE ) ; CREATE UNIQUE INDEX ACMES.P_ORDER_ITEM ON ACMES.ORDER_ITEM (ORD_ITEM_NO); CREATE INDEX ACMES.F_ORDER_ITEM_1 ON ACMES.ORDER_ITEM (ORD_ITEM_ORD_NO); CREATE INDEX ACMES.F_ORDER_ITEM_2 ON ACMES.ORDER_ITEM (ORD_ITEM_PROD_NO);

INTEGER

Appendix B. Sample code, DDL, and preparation scripts

299

--- HI_CUST_NO --

CREATE TABLE ACMES.HI_CUST_NO ( HI_CUST_NO INTEGER NOT NULL ) ; INSERT INTO ACMES.HI_CUST_NO VALUES(1); --- HI_ORD_NO -CREATE TABLE ACMES.HI_ORD_NO ( HI_ORD_NO INTEGER NOT NULL ) ; INSERT INTO ACMES.HI_ORD_NO VALUES(1); --- Create Procedures ------Note that all CREATE PROCEDURE statements are within the prep BAT files for each procedure. This is due to the fact that the JAR file for the procedure must exist before the procedure can be defined to DB2

B.1.2.2 Enhanced DDL


---------------------------------------------------------- Works for Version 7 of DB2/UDB for NT ---------------------------------------------------------DDL FOR ACME SOFTWARE CO EXAMPLE ----

300

DB2 Java Stored Procedures: Learning by Example

---- SQL LEVEL: ENHANCED (USES ENHANCED FEATURES) ----- NOTE: THE COLON (':') CHARACTER IS USED INSTEAD --OF THE SEMICOLON (';') CHARACTER FOR --TERMINATING COMMNANDS, DUE TO THE PRESENCE --OF CREATE TRIGGER STATEMENTS. ----IF THIS FILE IS SUBMITTED USING CLP, --ENSURE THAT THE TERMINATION CHARACTER IS --SET TO ':' as in the following: ---db2 -td: -vf ddle.txt -------------------------------------------------------CONNECT TO ACMEE: --------------------------------------------------------CREATE TABLES/INDEXES ----------------------------------------------------------- CUSTOMER --

--

CREATE TABLE ACMEE.CUSTOMER ( CUST_NO INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1, CACHE 10), CUST_FIRSTNAME CHAR(20) NOT NULL, CUST_LASTNAME CHAR(20) NOT NULL, CUST_ADDRESS CHAR(30) NOT NULL ) : CREATE UNIQUE INDEX ACMEE.P_CUSTOMER ON ACMEE.CUSTOMER (CUST_NO): --

Appendix B. Sample code, DDL, and preparation scripts

301

-- PRODUCT --

CREATE TABLE ACMEE.PRODUCT ( PROD_NO INTEGER PROD_DESC PROD_PRICE PROD_IN_STOCK ) :

NOT NULL PRIMARY KEY, CHAR(30) , DECIMAL(10,2) NOT NULL, INTEGER NOT NULL

CREATE UNIQUE INDEX ACMEE.P_PRODUCT ON ACMEE.PRODUCT (PROD_NO): --- ORDER -CREATE TABLE ACMEE.ORDER ( ORD_NO INTEGER

NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1, CACHE 10), ORD_DATE DATE NOT NULL, ORD_CUST_NO INTEGER NOT NULL, FOREIGN KEY (ORD_CUST_NO) REFERENCES ACMEE.CUSTOMER(CUST_NO) ON DELETE CASCADE ) : CREATE UNIQUE INDEX ACMEE.P_ORDER ON ACMEE.ORDER (ORD_NO): CREATE INDEX ACMEE.F_ORDER_1 ON ACMEE.ORDER (ORD_CUST_NO): --- ORDER ITEM

302

DB2 Java Stored Procedures: Learning by Example

--

CREATE TABLE ACMEE.ORDER_ITEM ( ORD_ITEM_NO INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1, CACHE 10), ORD_ITEM_ORD_NO INTEGER NOT NULL, ORD_ITEM_PROD_NO INTEGER NOT NULL, ORD_ITEM_QTY INTEGER NOT NULL, FOREIGN KEY (ORD_ITEM_ORD_NO) REFERENCES ACMEE.ORDER(ORD_NO) ON DELETE CASCADE, FOREIGN KEY (ORD_ITEM_PROD_NO) REFERENCES ACMEE.PRODUCT(PROD_NO) ON DELETE CASCADE ) : CREATE UNIQUE INDEX ACMEE.P_ORDER_ITEM ON ACMEE.ORDER_ITEM (ORD_ITEM_NO): CREATE INDEX ACMEE.F_ORDER_ITEM_1 ON ACMEE.ORDER_ITEM (ORD_ITEM_ORD_NO): CREATE INDEX ACMEE.F_ORDER_ITEM_2 ON ACMEE.ORDER_ITEM (ORD_ITEM_PROD_NO):

--------------------------------------------------------CREATE GLOBAL TEMP TABLES ----- THESE ARE USED BY THE AFTER-INSERT TRIGGERS THAT --- ARE DEFINED BELOW. THE TRIGGERS INSERT THE PRIMARY --- KEY VALUE OF THE NEW ROW INTO THE GLOBAL TEMP --- TABLE TO ALLOW IT TO BE ACCESSED BY THE CALLING --- APP. ----------------------------------------------------------CREATE TABLE ACMEE.GTT_CUST_NO (

Appendix B. Sample code, DDL, and preparation scripts

303

CUST_NO ):

INTEGER

NOT NULL

CREATE TABLE ACMEE.GTT_ORDER_NO ( ORDER_NO INTEGER NOT NULL ): --------------------------------------------------------CREATE TRIGGERS --------------------------------------------------------CREATE TRIGGER ACMEE.CUST_IA AFTER INSERT ON ACMEE.CUSTOMER REFERENCING NEW AS NEWROW FOR EACH ROW MODE DB2SQL BEGIN ATOMIC DELETE FROM ACMEE.GTT_CUST_NO; INSERT INTO ACMEE.GTT_CUST_NO (CUST_NO) VALUES (NEWROW.CUST_NO); END: CREATE TRIGGER ACMEE.ORD_IA AFTER INSERT ON ACMEE.ORDER REFERENCING NEW AS NEWROW FOR EACH ROW MODE DB2SQL BEGIN ATOMIC DELETE FROM ACMEE.GTT_ORDER_NO; INSERT INTO ACMEE.GTT_ORDER_NO (ORDER_NO) VALUES (NEWROW.ORD_NO); END: --------------------------------------------------------POPULATE PRODUCT TABLE --------------------------------------------------------INSERT INTO ACMEE.PRODUCT (PROD_NO, PROD_DESC, PROD_PRICE, PROD_IN_STOCK) VALUES (1,'Acme Word Processor',19.99,200): INSERT INTO ACMEE.PRODUCT (PROD_NO, PROD_DESC, PROD_PRICE, PROD_IN_STOCK) VALUES (2,'Acme Speadsheet',29.99,12):

304

DB2 Java Stored Procedures: Learning by Example

INSERT INTO ACMEE.PRODUCT (PROD_NO, PROD_DESC, PROD_PRICE, PROD_IN_STOCK) VALUES (3,'Acme Presentation Graphics',39.99,101): INSERT INTO ACMEE.PRODUCT (PROD_NO, PROD_DESC, PROD_PRICE, PROD_IN_STOCK) VALUES (4,'Acme E-Mail Client',49.99,240): INSERT INTO ACMEE.PRODUCT (PROD_NO, PROD_DESC, PROD_PRICE, PROD_IN_STOCK) VALUES (5,'Acme Office Suite',59.99,12): INSERT INTO ACMEE.PRODUCT (PROD_NO, PROD_PRICE, PROD_IN_STOCK) VALUES (6,69.99,678):

--------------------------------------------------------POPULATE CUSTOMER --------------------------------------------------------INSERT INTO ACMEE.CUSTOMER (cust_firstname, cust_lastname, cust_address) VALUES ('John Q.', 'Public', '111 1st St., San Jose, CA '):

--------------------------------------------------------POPULATE ORDER --------------------------------------------------------INSERT INTO ACMEE.ORDER (ord_date, ord_cust_no) VALUES (CURRENT DATE, 1): INSERT INTO ACMEE.ORDER (ord_date, ord_cust_no) VALUES (CURRENT DATE - 1 DAY, 1): --------------------------------------------------------POPULATE ORDER ITEM --------------------------------------------------------Insert into ACMEE.ORDER_ITEM (ORD_ITEM_ORD_NO, ORD_ITEM_PROD_NO,ORD_ITEM_QTY) VALUES(1,1,1): Insert into ACMEE.ORDER_ITEM (ORD_ITEM_ORD_NO, ORD_ITEM_PROD_NO,ORD_ITEM_QTY) VALUES(1,2,2): Insert into ACMEE.ORDER_ITEM (ORD_ITEM_ORD_NO, ORD_ITEM_PROD_NO,ORD_ITEM_QTY)

Appendix B. Sample code, DDL, and preparation scripts

305

VALUES(1,3,3): Insert into ACMEE.ORDER_ITEM (ORD_ITEM_ORD_NO, ORD_ITEM_PROD_NO,ORD_ITEM_QTY) VALUES(1,4,4): Insert into ACMEE.ORDER_ITEM (ORD_ITEM_ORD_NO, ORD_ITEM_PROD_NO,ORD_ITEM_QTY) VALUES(1,5,5):

Insert into ACMEE.ORDER_ITEM (ORD_ITEM_ORD_NO, ORD_ITEM_PROD_NO,ORD_ITEM_QTY) VALUES(2,1,2): Insert into ACMEE.ORDER_ITEM (ORD_ITEM_ORD_NO, ORD_ITEM_PROD_NO,ORD_ITEM_QTY) VALUES(2,2,4): Insert into ACMEE.ORDER_ITEM (ORD_ITEM_ORD_NO, ORD_ITEM_PROD_NO,ORD_ITEM_QTY) VALUES(2,3,6): Insert into ACMEE.ORDER_ITEM (ORD_ITEM_ORD_NO, ORD_ITEM_PROD_NO,ORD_ITEM_QTY) VALUES(2,4,8): Insert into ACMEE.ORDER_ITEM (ORD_ITEM_ORD_NO, ORD_ITEM_PROD_NO,ORD_ITEM_QTY) VALUES(2,5,10):

Insert into ACMEE.ORDER_ITEM (ORD_ITEM_ORD_NO, ORD_ITEM_PROD_NO,ORD_ITEM_QTY) VALUES(2,6,22): --------------------------------------------------------Create Temporary Table Used For Summary Query--------------------------------------------------------create table acmee.order_item_summ ( PROD_DESC CHAR(30) , QTY_1_TO_5 CHAR(1) NOT NULL, QTY_6_TO_10 CHAR(1) NOT NULL, QTY_11_PLUS CHAR(1) NOT NULL ):

306

DB2 Java Stored Procedures: Learning by Example

B.2 Sample stored procedure definitions


The sections that follow contain the stored procedure definitions used for the examples within this book.

B.2.1 DB2 UDB for OS/390 stored procedure definitions


The following sections contain the stored procedure definitons for the OS/390 versions of the simple and enhanced samples used in this book.
Note

The simple version of the samples was designed to work on DB2 UDB for OS/390 Version 5. The stored procedure defintitions therefore take the form of INSERT statements into the SYSIBM.SYSPROCEDURES catalog table. The enhanced version was intended for DB2 UDB for OS/390 Version 6, and therefore uses the new CREATE PROCEDURE statements.

B.2.1.1 Simple stored procedure defintions The stored procedure definitions for each of the simple samples follow.

ACMECOS
---------------------------------------------------------------SYSPROCEDURES INSERT FOR SG24-5945 ----- Package ACMECOS ----- SQL Type: COBOL/static SQL --- Platform: OS/390 --- SQL Level: Standard ------------------------------------------------------------------ Delete old rows if they exist -DELETE FROM SYSIBM.SYSPROCEDURES WHERE PROCEDURE LIKE 'CS%'; --- Add_customer --

Appendix B. Sample code, DDL, and preparation scripts

307

INSERT INTO SYSIBM.SYSPROCEDURES (PROCEDURE,AUTHID,LUNAME,LOADMOD,LINKAGE,COLLID, LANGUAGE,ASUTIME,STAYRESIDENT,IBMREQD, RUNOPTS, PARMLIST, RESULT_SETS,WLM_ENV,PGM_TYPE, EXTERNAL_SECURITY,COMMIT_ON_RETURN) VALUES( 'CS_ADD_CUSTOMER', '', '', 'ADDCUST', 'N', 'ACMECOS', 'COBOL', 900, '','N', '', 'CHAR(20) IN, CHAR(20) IN, CHAR(30) IN, INTEGER OUT, CHAR(40) OUT, CHAR(240) OUT', 0,'WLM_JAVA_DB21','S','N','N' );

--- Check all OK -SELECT * FROM SYSIBM.SYSPROCEDURES WHERE PROCEDURE LIKE 'CS%';

ACMEJOS
---------------------------------------------------------------SYSPROCEDURES INSERT FOR SG24-5945 ----- Package ACMEJOS ----- SQL Type: JDBC --- Platform: OS/390 --- SQL Level: Standard ------------------------------------------------------------------ Delete old rows if they exist -DELETE FROM SYSIBM.SYSPROCEDURES WHERE PROCEDURE LIKE 'JS%'; --- Add_customer -INSERT INTO SYSIBM.SYSPROCEDURES (PROCEDURE,AUTHID,LUNAME,LOADMOD,LINKAGE,COLLID,

308

DB2 Java Stored Procedures: Learning by Example

LANGUAGE,ASUTIME,STAYRESIDENT,IBMREQD, RUNOPTS, PARMLIST, RESULT_SETS,WLM_ENV,PGM_TYPE, EXTERNAL_SECURITY,COMMIT_ON_RETURN) VALUES( 'JS_ADD_CUSTOMER', '', '', '', 'N', 'DSNJDBC', 'COMPJAVA', 900, '','N', 'ACMEJOS/Add_customer.add_customer', 'CHAR(20) IN, CHAR(20) IN, CHAR(30) IN, INTEGER OUT, CHAR(40) OUT, CHAR(240) OUT', 0,'WLM_JAVA_DB21','S','N','N' ); --- Check all OK -SELECT * FROM SYSIBM.SYSPROCEDURES WHERE PROCEDURE LIKE 'JS%';

ACMESOS
---------------------------------------------------------------SYSPROCEDURES INSERT FOR SG24-5945 ----- Package ACMESOS ----- SQL Type: SQLJ --- Platform: OS/390 --- SQL Level: Standard ------------------------------------------------------------------ Delete old rows if they exist -DELETE FROM SYSIBM.SYSPROCEDURES WHERE PROCEDURE LIKE 'SS%'; --- Add_customer -INSERT INTO SYSIBM.SYSPROCEDURES (PROCEDURE,AUTHID,LUNAME,LOADMOD,LINKAGE,COLLID, LANGUAGE,ASUTIME,STAYRESIDENT,IBMREQD, RUNOPTS, PARMLIST,

Appendix B. Sample code, DDL, and preparation scripts

309

RESULT_SETS,WLM_ENV,PGM_TYPE, EXTERNAL_SECURITY,COMMIT_ON_RETURN) VALUES( 'SS_ADD_CUSTOMER', '', '', '', 'N', 'ACMESOS', 'COMPJAVA', 900, '','N', 'ACMESOS/Add_customer.add_customer', 'CHAR(20) IN, CHAR(20) IN, CHAR(30) IN, INTEGER OUT, CHAR(40) OUT, CHAR(240) OUT', 0,'WLM_JAVA_DB21','S','N','N' );

--- Check all OK -SELECT * FROM SYSIBM.SYSPROCEDURES WHERE PROCEDURE LIKE 'SS%';

ACMEBOS
---------------------------------------------------------------SYSPROCEDURES INSERT FOR SG24-5945 ----- Package ACMEBOS ----- SQL Type: SQLJ & JDBC Combined --- Platform: OS/390 --- SQL Level: Standard ------------------------------------------------------------------ Delete old rows if they exist -DELETE FROM SYSIBM.SYSPROCEDURES WHERE PROCEDURE LIKE 'BS%'; --- Add_customer -INSERT INTO SYSIBM.SYSPROCEDURES (PROCEDURE,AUTHID,LUNAME,LOADMOD,LINKAGE,COLLID, LANGUAGE,ASUTIME,STAYRESIDENT,IBMREQD, RUNOPTS, PARMLIST, RESULT_SETS,WLM_ENV,PGM_TYPE, EXTERNAL_SECURITY,COMMIT_ON_RETURN) VALUES(

310

DB2 Java Stored Procedures: Learning by Example

'BS_ADD_CUSTOMER', '', '', '', 'N', 'ACMEBOS', 'COMPJAVA', 900, '','N', 'ACMEBOS/Add_customer.add_customer', 'CHAR(20) IN, CHAR(20) IN, CHAR(30) IN, INTEGER OUT, CHAR(40) OUT, CHAR(240) OUT', 0,'WLM_JAVA_DB21','S','N','N' ); --- Check all OK -SELECT * FROM SYSIBM.SYSPROCEDURES WHERE PROCEDURE LIKE 'BS%';

B.2.1.2 Enhanced stored procedure definitons The stored procedure definitions for each of the enhanced samples follow.

ACMECOE
---------------------------------------------------------------CREATE PROCEDURES FOR SG24-5945 ----- Package ACMECOE ----- SQL Type: COBOL --- Platform: OS/390 --- SQL Level: Enhanced ------------------------------------------------------------------ Drop procedures if they exist -drop PROCEDURE ACMECOE.ADD_CUSTOMER RESTRICT; drop PROCEDURE ACMECOE.ADD_ORDER RESTRICT; drop PROCEDURE ACMECOE.ADD_CUST_ORDER RESTRICT; --- Add_customer -CREATE PROCEDURE ACMECOE.ADD_CUSTOMER ( IN FIRSTNAME CHAR(20),

Appendix B. Sample code, DDL, and preparation scripts

311

IN LASTNAME CHAR(20), IN ADDRESS CHAR(30), OUT CUSTNO INTEGER, OUT MARK CHAR(40), OUT MARK_ERROR_TEXT CHAR(200) ) FENCED MODIFIES SQL DATA LANGUAGE COBOL EXTERNAL NAME ADDCUST PARAMETER STYLE DB2SQL COLLID ACMECOE WLM ENVIRONMENT WLMJAVADBZ2 RESULT SETS 0 PROGRAM TYPE SUB; --- Add_order -CREATE PROCEDURE ACMECOE.ADD_ORDER ( IN CUSTNO INTEGER, IN NUM_ITEMS INTEGER, IN ORDERDETS CHAR(80), OUT ORDERNO INTEGER, OUT MARK CHAR(40), OUT MARK_ERROR_TEXT CHAR(200) ) FENCED MODIFIES SQL DATA LANGUAGE COBOL EXTERNAL NAME ADDORD PARAMETER STYLE DB2SQL COLLID ACMECOE WLM ENVIRONMENT WLMJAVADBZ2 RESULT SETS 0 PROGRAM TYPE SUB; --- Add_cust_order -CREATE PROCEDURE ACMECOE.ADD_CUST_ORDER ( IN FIRSTNAME CHAR(20), IN LASTNAME CHAR(20), IN ADDRESS CHAR(30), IN NUM_ITEMS INTEGER,

312

DB2 Java Stored Procedures: Learning by Example

IN ORDERDETS CHAR(100), OUT CUSTNO INTEGER, OUT ORDERNO INTEGER, OUT MARK CHAR(40), OUT MARK_ERROR_TEXT CHAR(200) ) FENCED MODIFIES SQL DATA LANGUAGE COBOL EXTERNAL NAME ADDCORD PARAMETER STYLE DB2SQL COLLID ACMECOE WLM ENVIRONMENT WLMJAVADBZ2 RESULT SETS 0 PROGRAM TYPE SUB;

--- Check all OK -SELECT * FROM SYSIBM.SYSROUTINES WHERE SCHEMA = 'ACMECOE';

ACMEJOE
---------------------------------------------------------------CREATE PROCEDURES FOR SG24-5945 ----- Package ACMEJOE ----- SQL Type: JDBC --- Platform: OS/390 --- SQL Level: Enhanced ----- NOTE: Java package * class name duplicated in RUNOPTS --due to current drivers ignoring EXTERNAL NAME. --This should not be required in general release of --the code, so RUNOPTS can be removed at that time. ------------------------------------------------------------------ --drop procedures if they exist --

Appendix B. Sample code, DDL, and preparation scripts

313

drop PROCEDURE ACMEJOE.ADD_CUSTOMER RESTRICT; drop PROCEDURE ACMEJOE.ADD_ORDER RESTRICT; drop PROCEDURE ACMEJOE.QUERY_OI_SUMM RESTRICT; --- Add_customer -CREATE PROCEDURE ACMEJOE.ADD_CUSTOMER ( IN FIRSTNAME CHAR(20), IN LASTNAME CHAR(20), IN ADDRESS CHAR(30), OUT CUSTNO INTEGER, OUT MARK CHAR(40), OUT MARK_ERROR_TEXT CHAR(200) ) FENCED MODIFIES SQL DATA LANGUAGE COMPJAVA EXTERNAL NAME 'acmejoe/Add_customer.add_customer' PARAMETER STYLE JAVA COLLID DSNJDBC WLM ENVIRONMENT WLMJAVADBZ2 RUN OPTIONS 'acmejoe/Add_customer.add_customer' DYNAMIC RESULT SETS 0 PROGRAM TYPE SUB; --- Add_order -CREATE PROCEDURE ACMEJOE.ADD_ORDER ( IN CUSTNO INTEGER, IN ORDERDETS CHAR(100), OUT ORDERNO INTEGER, OUT MARK CHAR(40), OUT MARK_ERROR_TEXT CHAR(200) ) FENCED MODIFIES SQL DATA LANGUAGE COMPJAVA EXTERNAL NAME 'ACMEJOE/Add_order.add_order' PARAMETER STYLE JAVA COLLID DSNJDBC WLM ENVIRONMENT WLMJAVADBZ2 RUN OPTIONS 'ACMEJOE/Add_order.add_order'

314

DB2 Java Stored Procedures: Learning by Example

DYNAMIC RESULT SETS 0 PROGRAM TYPE SUB; --- Query Order item summary -CREATE PROCEDURE ACMEJOE.QUERY_OI_SUMM ( IN IN_CUST_NO CHAR(10), IN IN_ORDER_NO CHAR(10), OUT MARK CHAR(40), OUT MARK_ERROR_TEXT CHAR(200) ) EXTERNAL NAME 'ACMEJOE/Query_oi_summ.query_oi_summ' RESULT SETS 1 LANGUAGE COMPJAVA PARAMETER STYLE JAVA COLLID DSNJDBC WLM ENVIRONMENT WLMJAVADBZ2 RUN OPTIONS 'ACMEJOE/Query_oi_summ.query_oi_summ' FENCED NO DBINFO NULL CALL MODIFIES SQL DATA PROGRAM TYPE SUB; --- Check all OK -SELECT * FROM SYSIBM.SYSroutines WHERE schema = 'ACMEJOE';

ACMESOE
---------------------------------------------------------------CREATE PROCEDURES FOR SG24-5945 ----- Package ACMESOE ----- SQL Type: SQLJ --- Platform: OS/390 --- SQL Level: Enhanced ----- NOTE: Java package & class name duplicated in RUNOPTS --due to current drivers ignoring EXTERNAL NAME. --This should not be required in general release of --the code, so RUNOPTS can be removed at that time. --

Appendix B. Sample code, DDL, and preparation scripts

315

----------------------------------------------------------------- Drop procedures if they exist -drop PROCEDURE ACMESOE.ADD_CUSTOMER RESTRICT; drop PROCEDURE ACMESOE.ADD_ORDER RESTRICT; drop PROCEDURE ACMESOE.QUERY_OI_SUMM RESTRICT; --- Add_customer -CREATE PROCEDURE ACMESOE.ADD_CUSTOMER ( IN FIRSTNAME CHAR(20), IN LASTNAME CHAR(20), IN ADDRESS CHAR(30), OUT CUSTNO INTEGER, OUT MARK CHAR(40), OUT MARK_ERROR_TEXT CHAR(200) ) FENCED MODIFIES SQL DATA LANGUAGE COMPJAVA EXTERNAL NAME 'ACMESOE.Add_customer.add_customer' PARAMETER STYLE JAVA COLLID ACMESOE WLM ENVIRONMENT WLMJAVADBZ2 RUN OPTIONS 'ACMESOE.Add_customer.add_customer' DYNAMIC RESULT SETS 0 PROGRAM TYPE SUB; --- Add_order -CREATE PROCEDURE ACMESOE.ADD_ORDER ( IN CUSTNO INTEGER, IN ORDERDETS CHAR(100), OUT ORDERNO INTEGER, OUT MARK CHAR(40), OUT MARK_ERROR_TEXT CHAR(200) ) FENCED MODIFIES SQL DATA

316

DB2 Java Stored Procedures: Learning by Example

LANGUAGE COMPJAVA EXTERNAL NAME 'ACMESOE.Add_order.add_order' PARAMETER STYLE JAVA COLLID ACMESOE WLM ENVIRONMENT WLMJAVADBZ2 RUN OPTIONS 'ACMESOE.Add_order.add_order' DYNAMIC RESULT SETS 0 PROGRAM TYPE SUB; --- Query Order item summary -CREATE PROCEDURE ACMESOE.QUERY_OI_SUMM ( IN IN_CUST_NO CHAR(10), IN IN_ORDER_NO CHAR(10), OUT MARK CHAR(40), OUT MARK_ERROR_TEXT CHAR(200) ) EXTERNAL NAME 'ACMESOE.Query_oi_summ.query_oi_summ' RESULT SETS 1 LANGUAGE COMPJAVA PARAMETER STYLE JAVA COLLID ACMESOE WLM ENVIRONMENT WLMJAVADBZ2 RUN OPTIONS 'ACMESOE.Query_oi_summ.query_oi_summ' FENCED NO DBINFO NULL CALL MODIFIES SQL DATA PROGRAM TYPE SUB; --- Check all OK -SELECT * FROM SYSIBM.SYSROUTINES WHERE schema = 'ACMESOE';

B.2.2 DB2 UDB for AIX and Windows stored procedure definitions
Due to the nature of the process, the stored procedure definitions on the AIX and Windows platforms have to be dropped and redefined as part of program preparation (see 7.3.1, NT / AIX JDBC program preparation process on

Appendix B. Sample code, DDL, and preparation scripts

317

page 144 and 7.3.2, NT / AIX SQLJ program preparation process on page 149 for an explanation of why). For this reason, the stored procedure definitions for these platfoms can be found in B.5.2, AIX program preparation scripts on page 318 and B.5.3, NT program preparation scripts on page 321.

B.3 Sample stored procedure code


The sample stored procedure code can be found in 3.5, Sample stored procedures standard on page 24 and 3.6, Sample stored procedures enhanced on page 34.

B.4 Sample client code


Some sample code for invoking the stored procedures described in this book can be found in 3.7, Sample Client Code on page 45.

B.5 Sample program preparation scripts


The sections that follow provide example listings of the program prepration scripts we developed while writing this book. For more information on how to use them, refer to Chapter 7., Preparing Java stored procedures on page 119.

B.5.1 OS/390 program preparation scripts


The OS/390 program preparation scripts for JDBC and SQLJ procedures are listed in sections 7.2.3.2, Sample program preparation scripts on page 126 and 7.3.1.2, Sample program preparation scripts on page 148.

B.5.2 AIX program preparation scripts


The UNIX platform ships with a strong scripting capability which at the minimum is compliant to Bourne shell. The script shown here runs under Bourne (or Korn). Another approach is to use a Makefile, which is seen in the stored procedure examples shipped with the database. Complex applications may want to use a Software Configuration Management product.

318

DB2 Java Stored Procedures: Learning by Example

B.5.2.1 Basic shell preparation of a JDBC stored procedure The following demonstrates using a script to compile, JAR, and install the JAR. If you choose not to use a JAR then you need to copy the resultant Java classes to the function directory as performed in the shipped samples.

prep.sh
echo off cls if [ $1 ] then PKG=$1 else PKG=ACMEJUS fi if [ $2 ] then PGM=$2 else PGM=Add_customer fi JARHOME=/u/db2inst3/sqllib/function/jar echo "setting PKG to $PKG" echo "setting PGM to $PGM"

echo "Beginning javac" javac ${PKG}/${PGM}.java

echo "Beginning JAR" jar cvf ${PKG}.jar ${PKG}/*.class echo "Updating DB2 environment"

if [ -f ${JARHOME}/${PKG}/${PKG}.jar ] then echo "found ${JARHOME}/${PKG}/${PKG}.jar " db2 -tvf replace_jar.sql else echo "failed find of ${JARHOME}/${PKG}/${PKG}.jar " db2 -tvf install_jar.sql db2 -tvf define_sp_${PGM}.sql

Appendix B. Sample code, DDL, and preparation scripts

319

fi

define_sp_Add_customer.sql
--------------------------------------------------------------------------------- SQL statements to define or redefine stored procedure ----- Note that JAR file must exist before CREATE PROCEDURE is executed, --- which is why we have put it in here rather than in the main DDL file. ----------------------------------------------------------------------------------- Connect to database -CONNECT TO ACMES; --- Drop procedure and JAR files if they exist -DROP PROCEDURE ACMEJUS.Add_customer; CALL SQLJ.REMOVE_JAR('ACMEJUS.ACMEJUS'); --- Define jar file to DB2 -call sqlj.install_jar ('file:/data/db2inst7/apps/ACMEJUS/ACMEJUS.jar','ACMEJUS.ACMEJUS'); --- Create procedure --- External name is in format ' " CREATE PROCEDURE ACMEJUS.Add_customer ( IN IN_CUST_FIRSTNAME CHAR(20), IN IN_CUST_LASTNAME CHAR(20), IN IN_CUST_ADDRESS CHAR(30), OUT OUT_CUST_NO INT,

320

DB2 Java Stored Procedures: Learning by Example

OUT MARK CHAR(40), OUT MARK_ERROR_TEXT CHAR(200) ) EXTERNAL NAME 'ACMEJUS.ACMEJUS:ACMEJUS.Add_customer.add_customer' RESULT SETS 0 LANGUAGE JAVA PARAMETER STYLE JAVA FENCED NO DBINFO NULL CALL MODIFIES SQL DATA ;

B.5.3 NT program preparation scripts


The NT platform ships with the ability to run .BAT (batch command) files, which allows for limited scripting ability. Complex applications will want to use a Makefile approach or a commercial Software Configuration Management package,both of which necessitate acquiring software not shipped with Windows NT.
B.5.3.1 Basic preparation of a JDBC stored procedure The following shows a basic preparation routine for a simple JDBC stored procedure. This preparation script performs no error checking. All values are hardcoded.

The batch file prep.bat invokes DB2 UDB in a batch mode to define the stored procedure and to install the JAR file.

Prep.bat
echo off cls echo Preparing ACMEJNS\Add_customer.java... echo echo Beginning Java compile... javac ACMEJNS\Add_customer.java echo Beginning JAR... jar cvf ACMEJNS.jar ACMEJNS\Add_customer.class echo Updating DB2 environment... db2 -tvf define_sp.sql echo Preparation complete!

Appendix B. Sample code, DDL, and preparation scripts

321

Define_sp.sql
--------------------------------------------------------------------------------- SQL statements to define or redefine stored procedure ----- Note that JAR file must exist before CREATE PROCEDURE is executed, --- which is why we have put it in here rather than in the main DDL file. ----------------------------------------------------------------------------------- Connect to database -CONNECT TO ACMES; --- Drop procedure and JAR files if they exist -DROP PROCEDURE ACMEJNS.Add_customer; CALL SQLJ.REMOVE_JAR('ACMEJNS.ACMEJNS'); --- Define jar file to DB2 -CALL SQLJ.INSTALL_JAR('file:S:\Kirk\Samples\Code - Stored Procedures\JDBC\NT\acmejns\acmejns.jar','ACMEJNS.ACMEJNS'); --- Create procedure --- External name is in format ' " CREATE PROCEDURE ACMEJNS.Add_customer ( IN IN_CUST_FIRSTNAME CHAR(20), IN IN_CUST_LASTNAME CHAR(20), IN IN_CUST_ADDRESS CHAR(30), OUT OUT_CUST_NO INT, OUT MARK CHAR(40), OUT MARK_ERROR_TEXT CHAR(200)

322

DB2 Java Stored Procedures: Learning by Example

) EXTERNAL NAME 'ACMEJNS.ACMEJNS:ACMEJNS.Add_customer.add_customer' RESULT SETS 0 LANGUAGE JAVA PARAMETER STYLE JAVA FENCED NO DBINFO NULL CALL MODIFIES SQL DATA ; CALL SQLJ.REFRESH_CLASSES(VOID);

B.5.3.2 SQLJ stored procedure preparation The following shows a complex preparation script for SQLJ stored procedures on NT.

Highlights of this script include: The SQLJ preparation step includes checking valid syntax against the DBMS (by arguing the userid/password and the URL) The automatic JAVA compile step is turned off during the SQLJ step. The class files are collected into the JAR once, after everything has been completed. Error checking within the batch file has been inserted where feasible.

Prep.bat
echo off cls echo Beginning SQLJ precompile/compile...Query_oi_summ sqlj -user=drdares2/drdares2 -url=jdbc:db2:ACMEE -compile=false -status ACMESNE\Query_oi_summ.sqlj if errorlevel 1 goto error echo Begin javac.... javac ACMESNE\Query_oi_summ.java if errorlevel 1 goto error echo Beginning profile customisation... db2profc -url=jdbc:db2:ACMEE -prepoptions="package using ACMESNE" ACMESNE\Query_oi_summ_SJProfile0 echo Beginning SQLJ precompile/compile...Add_customer

Appendix B. Sample code, DDL, and preparation scripts

323

sqlj -user=drdares2/drdares2 -url=jdbc:db2:ACMEE -compile=false -status ACMESNE\Add_customer.sqlj if errorlevel 1 goto error javac ACMESNE\Add_customer.java if errorlevel 1 goto error echo Beginning profile customisation... db2profc -url=jdbc:db2:ACMEE ACMESNE\Add_customer_SJProfile0 if errorlevel 1 goto error echo Beginning JAR... jar cvf ACMESNE.jar ACMESNE\Defi*.class ACMESNE\Qu*.class ACMESNE\Qu*.ser ACMESNE\Add_c*.ser ACMESNE\Add_c*.class if errorlevel 1 goto error echo Updating DB2 environment... db2 -tvf define_acmesne.sql if errorlevel 1 goto error echo Preparation complete! goto exit :error echo Problem encountered!!! :exit

define_acmesne.sql

--------------------------------------------------------------------------------- SQL statements to define or redefine stored procedure ----- Note that JAR file must exist before CREATE PROCEDURE is executed, --- which is why we have put it in here rather than in the main DDL file. ----

324

DB2 Java Stored Procedures: Learning by Example

-------------------------------------------------------------------------------- Connect to database -CONNECT TO ACMEE ; drop PROCEDURE ACMESNE.Query_oi_summ drop PROCEDURE ACMESNE.Add_customer; ;

CALL SQLJ.remove_JAR('ACMESNE.ACMESNE'); CALL SQLJ.install_JAR('file:s:\Kirk\Samples\Code - Stored Procedures\SQLJ\NT\Acmesne\ACMESNE.jar','ACMESNE.ACMESNE');

CREATE PROCEDURE ACMESNE.Query_oi_summ ( IN IN_CUST_NO CHAR(10), IN IN_ORDER_NO CHAR(10), OUT MARK CHAR(40), OUT MARK_ERROR_TEXT CHAR(200) ) EXTERNAL NAME 'ACMESNE.ACMESNE:ACMESNE.Query_oi_summ.query_oi_summ' RESULT SETS 1 LANGUAGE JAVA PARAMETER STYLE JAVA FENCED NO DBINFO NULL CALL MODIFIES SQL DATA ; CREATE PROCEDURE ACMESNE.Add_customer ( IN IN_CUST_FIRSTNAME CHAR(20), IN IN_CUST_LASTNAME CHAR(20), IN IN_CUST_ADDRESS CHAR(30), OUT OUT_CUST_NO INT, OUT MARK CHAR(40), OUT MARK_ERROR_TEXT CHAR(200) ) EXTERNAL NAME 'ACMESNE.ACMESNE:ACMESNE.Add_customer.add_customer' RESULT SETS 0 LANGUAGE JAVA PARAMETER STYLE JAVA

Appendix B. Sample code, DDL, and preparation scripts

325

FENCED NO DBINFO NULL CALL MODIFIES SQL DATA ;

call sqlj.refresh_classes(void);

B.5.3.3 SQLJ stored procedure preparation - parameter driven Included here is parameter-driven preparation batch file for SQLJ stored procedures on NT. This might be useful for programmers planning to build one generic script to be applied to many stored procedures.

Prep.bat
echo off REM REM GENERIC SQLJ PREP ROUTINE REM REM File <package>.sql must exist, containing necessary CREATE PROCEDURE REM and REFRESH_JAR commands rem rem Example call: prep Add_customer ACMEBNS ACMEBNS ACMES ACMES DEFINE

cls echo. echo SQLJ Prog Prep script echo. echo Input parms: echo Class name = echo Java Package\subdirectory name = echo DB2 Package name = echo Database name = echo Table qualifier = echo Action = echo.

%1 %2 %3 %4 %5 %6

REM Check Valid Action if %6 == DEFINE goto cont1 if %6 == REFRESH goto cont2 echo Error: Action must be DEFINE or REFRESH. goto error :cont1

326

DB2 Java Stored Procedures: Learning by Example

REM Check SQL define file exists if exist define_%2.sql goto cont3 echo Error: file define_%2.sql not found.... echo File must exist, and contain the necessary SQL CREATE PROCEDURE and echo REFRESH_JAR commands... echo. goto error :cont2 REM Check SQL refresh file exists if exist refresh_%2.sql goto cont3 echo Error: file refresh_%2.sql not found.... echo File must exist, and contain the necessary REPLACE_JAR commands... echo. goto error :cont3 echo Preparing %2\%1... echo. echo Beginning SQLJ precompile/compile... set CLASSPATH=.\%2;%CLASSPATH% echo start sqlj compile sqlj -compile=false %2\%1.sqlj if errorlevel 1 goto error echo start javac compile javac %2\%1.java if errorlevel 1 goto error echo Beginning profile customisation... db2profc -prepoptions="qualifier %5 package using %3" -url=jdbc:db2:%4 %2\%1_SJProfile0 if errorlevel 1 goto error echo Beginning JAR... jar cvf %2.jar %2\*.class %2\*.ser if errorlevel 1 goto exit echo Updating DB2 environment... if %6 == DEFINE db2 -tvf define_%2.sql if %6 == REFRESH db2 -tvf refresh_%2.sql

Appendix B. Sample code, DDL, and preparation scripts

327

echo Preparation complete! goto exit :error echo Problem encountered!!! :exit

328

DB2 Java Stored Procedures: Learning by Example

Appendix C. OS/390 Recoverable Resource Services (RRS)


OS/390 Recoverable Resource Services (RRS) is a feature of MVS that coordinates two-phase commit processing of recoverable resources in an MVS system. DB2 supports use of these services for DB2 applications that use the RRS attachment facility provided with DB2. Use the RRS attachment to access resources such as SQL tables, DL/I databases, MQSeries messages, and recoverable VSAM files within a single transaction scope. If your system does not have RRS running see the chapter Implementing OS/390 Resources Recovery Services (RRS) in Getting Started with DB2 Stored Procedures , SG24-4693.

C.1 RRS attachment


The RRS attachment is required for stored procedures that run in a WLM-established address space. The user ID associated with that address space must be authorized to run the Recoverable Resource Manager Services Attachment Facility (RRSAF) and is associated with the ssnm.RRSAF profile. Control access to the DB2 subsystem through RRSAF by performing the following steps: 1. If you have not already established a profile for controlling access from the RRS, you need to define ssnm.RRSAF in the DSNR resource class with a universal access authority of NONE. 2. Activate the resource class SETROPTS RACLIST(DSNR) REFRESH 3. Add user IDs that are associated with the stored procedures address spaces to the RACF started procedures table:
DC CL8DB21JAVA WLM-established stored procedure address space. DC CL8DB2STC USERID DC CL8DB2SYS GROUP NAME DC X00 NO PRIVILEGED ATTRIBUTE DC XL700 RESERVED BYTES

Stored procedures address space entries are required in the RACF started procedures table. The associated RACF user ID and group name do not need to match those used for the DB2 address spaces, but they must be authorized to run the call attachment facility (for the DB2-established stored procedure address space) or RRSAF (for WLM-established stored procedure address spaces).

Copyright IBM Corp. 2000

329

Changing the RACF started-procedures table: To change the RACF started-procedures table (ICHRIN03), change, reassemble, and link edit the resulting object code to MVS.

330

DB2 Java Stored Procedures: Learning by Example

Appendix D. Define WLM stored procedure address space


OS/390 workload management provides a solution for managing workload distribution, workload balancing, and distributing resources to competing workloads. OS/390 workload management is the combined cooperation of various subsystems (CICS, IMS/ESA, JES, APPC, TSO/E, OS/390 UNIX System Services, DDF, DB2, SOM, LSFM, and Internet Connection Server) with the OS/390 workload management (WLM) component. To workload management, work is a demand for service, such as a batch job, an APPC, CICS, DB2, or IMS transaction, a TSO/E logon, a TSO/E command, or a SOM request. All work running the installation is divided into workloads.

D.1 Enable stored procedure support


Follow these steps if you already installed DB2 but did not enable WLM-establish application environment stored procedure processing.

D.1.1 Step 1. Run the installation CLIST in INSTALL or MIGRATE mode.


On panel DSNTIPA1, specify the input member that contains field values for your current installation. In the remaining installation panels, leave the existing values, except in the following cases: On panel DSNTIPT, choose a different name for TEMP CLIST LIBRARY and SAMPLE LIBRARY to avoid overwriting your original libraries. On panel DSNTIPG, specify a data set name for LE/370 RUN TIME LIBRARY data set names for PL/I for MVS & VM (you need PL/I for MVS and VM to run the PL/I stored procedures sample applications) On panel DSNTIPX, fill in all fields for the type of stored procedure environment you will use.
Note

WLM-established stored procedure address spaces are required if you wish to write Java stored procedures. You cannot run Java stored procedures in a DB2 established stored procedure address space. Member DSNTIJMV of data set DSN610.SDSNSAMP contains sample JCL procedures for starting WLM-established address spaces. This will have to be modified for the JAVA support. Define WLM application environments for groups of JAVA stored procedures and associate a JCL start-up procedure with each application environment.

Copyright IBM Corp. 2000

331

D.1.2 Step 2. Edit DSNTIJUZ


Edit job DSNTIJUZ to add or change values of the stored procedure parameters: STORMXAB, STORPROC, and STORTIME Run DSNTIJUZ to assemble and link-edit the subsystem parameter module. Restart DB2 with the new parameters. For WLM-established stored procedures. Define JCL procedures for the stored procedures address spaces. Member DSNTIJMV of data set DSN610.SDSNSAMP contains sample JCL procedures for starting.WLM-established address spaces. Define WLM application environments for groups of stored procedures and associate a JCL startup procedure with each application environment. You can also use the variable &IWMSSNM for the DB2SSN parameter ( DB2SSN=&IWMSSNM). This variable represents the name of the subsystem for which you are starting this address space. This variable is useful for using the same JCL procedure for multiple DB2 subsystems, such as a data sharing group. WLM will substitute the correct subsystem member attach name when starting the address spaces for each member of the group. 1. Specify the WLM application environment name for the WLM_ENVIRONMENT option on CREATE or ALTER PROCEDURE (or FUNCTION) to associate a stored procedure (or user-defined function) with an application environment. 2. Using the install utility in the WLM application, install the WLM service definition that contains information about this application environment into the couple data set. 3. Activate a WLM policy from the installed service definition. 4. Begin running stored procedures.

D.2 How to use the WLM ISPF application


Once you have made some decisions on at least one service policy and your classification rules, you are ready to start using the WLM ISPF application. Your service policies and classification rules make up a service definition. You can store a service definition in the following kinds of data sets: WLM couple data set

332

DB2 Java Stored Procedures: Learning by Example

In order for all systems in a sysplex to process with an active service policy, they must all be able to access a service policy. They all access the policy from a WLM couple data set. To use workload management, you must allocate a WLM couple data set, define it to the sysplex, and install your service definition onto it. You can allocate the WLM couple data set from the application. Only one service definition can be installed on the WLM couple data set. MVS partitioned data set (PDS) You do not need to preallocate the data sets. You specify a data set name, and the application allocates it for you. You can save one service definition per MVS PDS.
Note

If you use customized data sets in your installation, or if you use DFSMS, you can use WLM application exits IWMAREX1 and IWMAREX2 to specify those changes. The data set userid.WLM.SAVExx (where userid is the TSO ID running the application and xx is some numeric value such as SAVE01) is allocated by the WLM application for recovery and is deleted by WLM upon exiting the application. This naming convention should therefore not be used for a new service definition.

D.3 Starting the WLM application


The WLM application is shipped in the internal programming control facility (IPCS) library. When you start the application, the system needs to concatenate the WLM/IPCS data sets, allocate some data sets, and then invoke the WLM panels. To start the application, specify:
TSO ex SYS1.SBLSCLI0(IWMARIN0)

Or, issue the following command:


TSO WLM

If you have different data set conventions for your IPCS data sets, or if you use storage managed data sets, you should use the WLM application exits IWMAREX1 and IWMAREX2. Within a workload, you group work with similar performance characteristics into service classes; for example:

Appendix D. Define WLM stored procedure address space

333

Performance goals Resource requirements Business importance to the installation Because some work may have variable resource requirements, you can define multiple periods for a service class. Periods are a way of defining different goals for work depending on the amount of resources the work consumes. Typically, periods are used to give shorter transactions more aggressive goals and to give longer running work of the same type less aggressive goals. If you have multiple periods, each period except the last has a duration. Duration is the amount of resources, in service units, that the work consumes before it is switched to the goals of the next period. You can also group work into a service class based on resource requirements. If you have a group of batch work that can consume vast amounts of resources, and you want to limit it, you can define a service class and assign it to a resource group with a maximum amount of capacity. If the work exceeds that capacity, workload management slows the execution rate. Also, if a certain group of work needs a minimum amount of processor capacity, you can set up a service class and assign it to a resource group. Classification rules are the rules workload management uses to associate a performance goal and/or a resource group with work by associating incoming work with a service class. Optionally, classification rules can also associate incoming work with a report class, similar to a report performance group. Classification rules work in much the same way as the IEAICSxx PARMLIB member in compatibility mode (except that classification rules are more flexible). The classification rules for a subsystem are specified in terms of transaction qualifiers such as job name or transaction class. These qualifiers identify groups of transactions that should have the same performance goals and importance. The attributes of incoming work are compared to these qualifiers and, if there is a match, the rule is used to assign a service class to the work. A subsystem can also have a default class for work that does not match any of the rules.

D.4 Control of stored procedures in a WLM environment


Programs can be grouped together and isolated in different WLM environments based on application security requirements. For example, payroll applications might be isolated in one WLM environment, because they contain sensitive data, such as employee salaries. To prevent users from

334

DB2 Java Stored Procedures: Learning by Example

creating a stored procedure in a sensitive WLM environment, DB2 invokes RACF to determine if the user is allowed to create stored procedures in the specified WLM environment. The WLM ENVIRONMENT keyword on the CREATE PROCEDURE statement (for Version 6) or the WLM_ENV column of SYSIBM.SYSPROCEDURES for Version 5) identifies the WLM environment to use for running a given stored procedure. Attempts to create a procedure fail if the user is not properly authorized. DB2 performs a resource authorization check using the DSNR RACF class as follows: In a DB2 data sharing environment, DB2 uses the RACF resource name: db2_groupname.WLMENV.wlm_environment. In a non-data sharing environment, DB2 checks the RACF resource name: db2_subsytem_id.WLMENV.wlm_environment. The RACF RDEFINE command can be used to create RACF profiles that prevent users from creating stored procedures and user-defined functions in sensitive WLM environments. For example, you can prevent all users on DB2 subsystem DB2A (non-data sharing) from creating a stored procedure or user-defined function in the WLM environment named PAYROLL:
RDEFINE DSNR (DB2A.WLMENV.PAYROLL) UACC(NONE)

The RACF PERMIT command authorizes a user to create a stored procedure or user-defined function in a WLM environment. For example, you can authorize a DB2 user (DB2USER1) to create stored procedures on DB2 subsystem DB2A (non-data sharing) in the WLM environment named WLMENV1.
PERMIT DB2A.WLMENV.WLMENV1 CLASS(DSNR) ID(DB2USER1) ACCESS(READ)

You must define a RACF user IDs for DB2 stored procedure started tasks as mention in the RRS section. You must associate each of these address spaces with a RACF user ID. Each of them can also be assigned a RACF group name.

D.5 Defining the application environment


You will need to define your Java application environment to WLM. This is done with the WLM ISPF panels. It is recommended that you keep your Java stored procedures in at least one separate application environment from your other language stored procedures. This is because of the size of the Java package. But before you do that you should see what policy you are running

Appendix D. Define WLM stored procedure address space

335

with the MVS command d wlm. This will give you the active service policy and the related service definition name.
D WLM
HQX1900------------------ SDSF PRIMARY OPTION MENU -- COMMAND ISSUED COMMAND INPUT ===> /d wlm SCROLL ===> PAGE RESPONSE=SC53 IWM025I 12.00.02 WLM DISPLAY 790 ACTIVE WORKLOAD MANAGEMENT SERVICE POLICY NAME: SPSTPC ACTIVATED: 2000/03/10 AT: 11:42:37 BY: DB2RES3 FROM: SC61 DESCRIPTION: serv pol for db2 stor proc resid RELATED SERVICE DEFINITION NAME: DB2JODBA INSTALLED: 2000/03/10 AT: 11:41:49 BY: DB2RES3 FROM: SC61 WLM VERSION LEVEL: LEVEL008

To set up your application environment definition, start up the WLM ISPF panels with TSO command WLM. Follow these steps to define a new application environment for your Java stored procedure. 1. Select option 2; Extract definition from WLM couple data set, from the Choose Service Definition Panel. 2. Select option 9; Application Environments, from the Definition Menu Panel. 3. Select option 1; create in the Action column from the Application Environment Selection List Panel. 4. PF3 to get back to the Definition Menu Panel. 5. Move the cursor to Utilities; on top of this panel, select option: 1. Install definition and press Enter. 6. Move the cursor to Utilities; on top of this panel, select option: 3. Activate service policy, and press Enter. 7. Select Policy to activate and press Enter. Here is a sample WLM Application Environment Definition:
Appl Environment Name . . WLMJAVADB21 Description . . . . . . . Java application for DB21 Subsystem type . . . . . DB2 Procedure name . . . . . DB21JAVA Start parameters . . . . APPLENV=CC51WLM1,NUMTCB=20,DB2SSN=&IWMSSNM Limit on starting server address spaces for a subsystem instance 1 1. No limit

336

DB2 Java Stored Procedures: Learning by Example

2. 3.

Single address space per system Single address space per sysplex

Verify that you have a DB2 workload defined, service class for DDF, and classification rules defined to WLM for your Java stored procedure workload. For additional information on setting up your WLM environment see the chapter WLM-Established Stored Procedures Address Spaces in Getting Started with DB2 Stored Procedures: Give Them a Call through the Network , SG24-4693. For a complete explanation of how to use and set up the OS/390 WLM, refer to OS/390 MVS Workload Management Services, GC28-1773. To define an application environment specify the subsystem type under which the applications are running. In this case, DB2 should be your subsystem type You can define whether requests can execute in multiple server address spaces and on multiple systems, or single address space per system or sysplex. If you wish workload management to automatically manage the number of servers in goal mode, set the field for Limit on starting server address spaces for a subsystem instance to 1, no limit. In the PROCEDURE NAME field put the name of the JCL procedure you want started. This JCL procedure member must reside in an accessible PROCLIB library. Any required start parameters can be passed by WLM. You can, for example, pass as a parameter the number of TCBs that should be available in the address space and the application environment name to use.

D.6 Refreshing the environment for stored procedures


If WLM is operating in goal mode, use the following MVS command to refresh the Language Environment when you need to load a new version of a stored procedure:
VARY WLM,APPLENV=name,REFRESH

In this command, name is the name of a WLM application environment associated with a group of stored procedures. This means that when you execute this command, you affect all stored procedures associated with the application environment. To stop all stored procedures address spaces associated with the WLM application environment name, use the MVS command:

Appendix D. Define WLM stored procedure address space

337

VARY WLM,APPLENV=name,QUIESCE

To start all stored procedures address spaces associated with the WLM application environment name, use the MVS command:
VARY WLM,APPLENV=name,RESUME

You also need to use the VARY WLM command with the RESUME option when WLM puts an application environment in the unavailable state. An application environment in which stored procedures run becomes unavailable when WLM detects five abnormal terminations within 10 minutes. When an application environment is in the unavailable state, WLM does not schedule stored procedures for execution in it. If WLM is operating in compatibility mode use the MVS command:
CANCEL WLM address space name

D.7 Using WLM application environments in compatibility mode


Using application environments in compatibility mode involves manually managing the server address spaces for each application environment. To accomplish this, the installation must: Know the proper number of address spaces to start for each application environment. Manually start the server address spaces. Manually terminate server address spaces that are no longer needed. Monitor the server address space delay information to ensure the right number of server address spaces are used. The above tasks can be done by using the operator START and CANCEL commands, or by using an automated operations facility like System Automation for OS/390. The VARY WLM,APPLENV command can be issued from a system that is in either compatibility or goal mode, and the command takes effect for all systems in the sysplex. However, the VARY WLM,APPLENV command has no effect on application environment server address spaces started on a compatibility mode system. This means that if you issue the quiesce or refresh options of the VARY WLM,APPLENV command on a sysplex where some systems are running in compatibility mode, the application environment state remains in the QUIESCING or REFRESHING state until all servers for the application environment on the compatibility mode systems are manually terminated.

338

DB2 Java Stored Procedures: Learning by Example

D.8 Using WLM application environments in goal mode


In goal mode, application environments can be manually controlled by the installation or automatically controlled by workload management. All of the applications in an application environment are supported by a single JCL startup procedure. Defining the name of this startup JCL procedure to workload management indicates that workload management should control the server address spaces. This is called automatic control. If you omit the name of the JCL procedure in the application environment definition, then manual control is in effect. Under manual control, the installation must create and delete, as needed, the server address spaces for each application environment. Note that the VARY WLM,APPLENV command can be used to terminate manually started server address spaces (through the quiesce or refresh options), but it will not restart them. Under automatic control, workload management creates server address spaces as started tasks using the JCL procedure specified in the application environment definitions. The startup parameters may be contained in either the JCL procedure defined for each application environment or in the application environment definition. When the server address spaces are no longer needed, workload management deletes them. Under automatic control, the quantity of server address spaces is totally controlled by workload management. If an operator or automation starts or cancels the server address spaces under automatic control, workload management will: Use servers not started by workload management as if they were started by workload management. Terminate servers not started by workload management if they are not needed. Replace a server address space that was unexpectedly cancelled.

Warning

You should use the VARY WLM,APPLENV command to manage application environment servers rather than the CANCEL command. If there are more than five server cancellations in 10 minutes, workload management stops creating new servers for the application environment.

Appendix D. Define WLM stored procedure address space

339

Commands that can be used to perform actions on an application environment: An application environment initially enters the AVAILABLE state when the service policy that contains its definition is activated. AVAILABLE means the application environment is available for use, and servers are allowed to be started for it. There are three options on the VARY command that you can use to change the state of an application environment after it has been made available: VARY WLM,APPLENV=xxxx,QUIESCE The quiesce option causes workload management to request the termination of server address spaces for the application environment upon completion of any active requests. Additional work requests are not handled by the servers, although work requests can continue to be queued, waiting for a server. If you do not want work queued, use subsystem functions to stop the queueing. You can issue a quiesce action for an application environment that is in the AVAILABLE state. When a quiesce action is issued for an application environment, it first enters the QUIESCING state until all servers have been requested to terminate. It then enters the QUIESCED state. VARY WLM,APPLENV=xxxx,RESUME The resume option restarts an application environment that was previously quiesced and is in the QUIESCED state. It indicates to workload management that server address spaces can once again be started for this application environment. The new servers process any queued requests and all new requests. When a resume action is issued for an application environment, it first enters the RESUMING state until all systems in the sysplex have accepted the action. It then enters the AVAILABLE state. VARY WLM,APPLENV=xxxx,REFRESH The refresh option requests the termination of existing server address spaces and starts new ones in their place. Existing servers finish their current work requests and end. The new servers process any queued requests and all new requests. You can issue a refresh action for an application environment that is in the AVAILABLE state. When a refresh action is issued for an application environment, it first enters the REFRESHING state until all servers have been requested to terminate. It then enters the AVAILABLE state.

340

DB2 Java Stored Procedures: Learning by Example

D.9 Restricting access


Following is an example of restricting access to application environment servers. In this example, the installation has the following situation: MVS JCL procedures for DB2 stored procedure servers are: PAY1, PAY2, PER1, PER2. These are the JCL procedures that workload management uses to start the DB2 servers that handle stored procedure calls. DB2 subsystem names are: DB2A and DB2B. These are the subsystem names used when the DB2 subsystem connects to workload management. In this example, the installation performs the following actions: Activates the STARTED and SERVER classes (if not already done):
SETR CLASSACT(STARTED) RACLIST(STARTED) GENERIC(STARTED) SETR CLASSACT(SERVER) RACLIST(SERVER) GENERIC(SERVER)

Establishes an arbitrary USERID to use in a subsequent RDEFINE command to tie an MVS procedure name to a server:
ADDUSER DB2SERV

Associates the USERID with the started task name:


RDEFINE STARTED PAY*.* STDATA(USER(DB2SERV) GROUP(SYS1)) RDEFINE STARTED PER*.* STDATA(USER(DB2SERV) GROUP(SYS1))

Defines server profiles in the form: subsys_type.subsys_name.applenv where, subsys_type is the subsystem type, as specified in the service definition osubsys_name is the instance name of the subsystem associated with this server. The subsystem uses this name when establishing itself as the work manager for application environment server requests. APPLENV is the application environment name, as specified in the service definition:
RDEFINE SERVER DB2.DB2A.* UACC(NONE) RDEFINE SERVER DB2.DB2B.* UACC(NONE)

Permits the USERID to the servers. This completes the association between the MVS procedure names and the servers:
PERMIT DB2.DB2A.* CLASS(SERVER) ID(DB2SERV) ACCESS(READ) PERMIT DB2.DB2B.* CLASS(SERVER) ID(DB2SERV) ACCESS(READ)

Refreshes the classes to refresh the RACF data base and make these changes go into effect:
SETR RACLIST(STARTED) REFRESH SETR RACLIST(SERVER) REFRESH

Appendix D. Define WLM stored procedure address space

341

D.10 Summary of service definition / service policy concepts


When you set up your service definition, you identify the workloads, resource groups, service classes, service class periods, and goals based on your performance objectives. Then you define classification rules and one or more service policies. This information makes up the base service definition. A two-step process is required before the sysplex starts using a new service definition. 1. You install the service definition onto the WLM couple data set. 2. You activate one of the service policies from the definition. With a service policy, you can override specific goals or resource groups in your base service definition. In a typical scenario, you might define a base service definition that is appropriate for your normal business hours. Because you need to have at least one service policy defined, you might create an empty service policy called NORMAL. While the NORMAL service policy is in effect, there would be no overrides to the goals or resource groups in the base service definition. If you have a special business need to change your goals for off shift processing, you might then also create a service policy called OFFSHIFT. If you were to activate this policy at the end of the business day (either by invoking the VARY WLM,POLICY=policyname command or by using the Activating a Service Policy panel in the ISPF application), then the goal overrides in the OFFSHIFT service policy would be in effect until you switched back to NORMAL the next morning.
Overrides

You can override only goals, number of periods, and resource group assignments and values. All of the workloads, service class names, classification rules, scheduling environments, and application environments defined in the service definition remain the same for any policy. If you need to change any of these, you will need to change the base service definition, re-install the service definition, and then activate a policy from that changed service definition.

342

DB2 Java Stored Procedures: Learning by Example

Policy Definition

You need to define all of your policies at the outset, while you are defining the rest of the service definition. Once the service definition is installed, then you can switch from one defined policy to another. If you need to create a new policy or change the overrides in an existing policy, you will need to re-install the service definition with the new or changed policy definition before you can activate the new policy

Watch out for work defaulting to SYSOTHER . Work in subsystems that use enclaves (DB2 is one) can suffer performance degradation if left unclassified in the service definition. If you do not add classification rules for this work in your service definition, then when you switch to goal mode, that work will be assigned to the SYSOTHER service class, which has a discretionary goal. Using the WLM application, you need to add classification rules to assign the work to service classes with appropriate response time or velocity goals. As a general rule, its a good idea to keep an eye on the SYSOTHER service class through RMF or another monitor. Any service accumulating in the SYSOTHER service class is a signal that you have unclassified work in your system. Workload management can dynamically manage the number of batch initiator address spaces is a JES2 environment. You can selectively turn over control of the batch initiator management to WLM for one or more job classes. WLM will start new initiators, as needed, to meet the performance goals of this work. By specifying or defaulting MODE=JES on the JES2 JOBCLASS initiator start, you indicate that the initiators for the job class should be JES-managed, as in the past. By specifying MODE=JES, you keep the job class in JES-managed mode. (JES will manage the batch initiators for that job class, in the same way it has in prior releases.) By specifying MODE=WLM, you put that class into WLM-managed mode. You can switch as many job classes to WLM-managed mode as you wish. You can easily switch any job class back to JES-managed mode by using the $TJOBCLASS JES2 command. A service definition contains all of the information necessary for workload management processing. Enter your service definition into the ISPF administrative application. The service definition is the way to express your installations business goals to your sysplex. In order to do this, you must understand your installations business environment.

Appendix D. Define WLM stored procedure address space

343

D.11 Recommendations for full implementation of OS/390 WLM


If your installation is managing CICS, IMS, or DDF transactions according to MVS WLM response time goals, and if you are set up to use WLM-established stored procedures address spaces, use the following service classes for velocity: The default SYSSTC service class for: VTAM address space IRLM address space (IRLMPROC)
Note: The VTAM address space and the IRLM address space must always have a higher dispatching priority than all of the DBMS address spaces, their attached address spaces, and their subordinate address spaces. Do not allow WLM to reduce the priority of VTAM or IRLM to or below that of the other DBMS address spaces.

A high velocity goal for a service class whose name you define, such as PRODREGN, for the following: DB2 (all address spaces including WLM-established stored procedures, except for the DB2-established stored procedures address space) CICS (all region types) IMS (all region types except BMPs) The velocity goals for WLM-established stored procedures, CICS and IMS regions are only important during startup or restart. After transactions begin running, WLM ignores the WLM-established stored procedures, CICS or IMS velocity goals and assigns priorities based on the goals of the transactions or packages that are running in the regions. A high velocity goal is good for ensuring that startups and restarts are performed as quickly as possible. If a CICS or IMS transaction calls a DB2 stored procedure, WLM will assign priorities base on goals of the package running in the WLM-established address space. Similarly, when you set response time goals for DDF threads or for stored procedures in a WLM-established address space, the only work controlled by the DDF or stored procedure velocity goals are the DB2 service tasks (work performed for DB2 that cannot be attributed to a single user). The user work runs under separate goals for the enclave. For the DB2-established stored procedures address space, use a velocity goal that reflects the requirements of your distributed work. Depending on

344

DB2 Java Stored Procedures: Learning by Example

what type of distributed work you do, this might be equal to or lower than the goal for PRODREGN. IMS BMPs can be treated along with other batch jobs, or can be given a velocity goal, depending on what business and functional requirements you have at your site.

D.12 Considerations for compatibility mode


In compatibility mode, threads are given a service class by the classification rules in the active WLM service policy. The MVS ICS maps service classes SRVCLASS) to a performance group number (PGN), which determines the performance group of the enclave. When workload manager operates in compatibility mode, take the following actions to establish performance objectives for DDF threads: 1. Define MVS performance groups (PGNs) for DDF threads in the IPS PARMLIB member. Do the same for WLM-established stored procedures address spaces if you are using them. 2. Create MVS ICS PARMLIB definitions to map the service classes assigned in the workload manager classification rules to the corresponding performance groups, using SUBSYS=DDF and the SRVCLASS keyword. The subsystem default performance group for SUBSYS=DDF is ignored. 3. Create MVS PARMLIB definitions to assign a performance group to the WLM-established stored procedures address spaces if you are using them. The same performance group can be assigned to these stored procedures address spaces as is assigned to DDF. 4. Activate the updated PARMLIB members (SET IPS=xx, ICS=yy). Each of the PGN values in the MVS ICS must be defined in the IPS PARMLIB member. The PGN definition can include information on the performance period, which is used by SRM to change the performance objective of a DDF thread based on the amount of processor resource the DDF thread consumes.

D.13 Considerations for goal mode


In goal mode, threads are assigned a service class by the classification rules in the active WLM service policy. Each service class period has a performance objective (goal), and workload manager raises or lowers that periods access to system resources as needed to meet the specified goal. For example, the goal might be application APPL8 should run in less than 3 seconds of elapsed time 90% of the time. Assign the DDF address space

Appendix D. Define WLM stored procedure address space

345

and any WLM-established address spaces for stored procedures and user-defined functions to the same service class as the DB2 database services address space (ssnmDBM1). Define this service class with a velocity goal. You can control which address spaces can be WLM-established server address spaces that run stored procedures. To do this, use the server resource class, which WLM uses to identify valid address spaces to which work can be sent. If the server class is not defined or activated, then any address space is allowed to connect to WLM as a server address space and to identify itself as a server address space that runs stored procedures.To use the server resource class, perform the following steps: 1. Run a version of RACF in which the resource class SERVER is included as part of the predefined resource classes (RACF Version 2 Release 2 and subsequent releases). 2. Define a RACF profile for resource class SERVER: RDEFINE SERVER (DB2.ssnm.applenv) where APPLENV is the name of the application environment associated with the stored procedure. 3. Activate the SERVER resource class: SETROPTS RACLIST(SERVER) REFRESH 4. Permit read access to the server resource name to the user IDs associated with the stored procedures address space.
PERMIT DB2.DB2T.TESTPROC CLASS(SERVER) ID(SYSDSP) ACCESS(READ) PERMIT DB2.DB2P.PAYROLL CLASS(SERVER) ID(SYSDSP) ACCESS(READ) PERMIT DB2.DB2P.QUERY CLASS(SERVER) ID(SYSDSP) ACCESS(READ)

You can find additional information in the chapter WLM_Established Stored Procedures in Getting Started with DB2 Stored Procedures, SG24-4693.

346

DB2 Java Stored Procedures: Learning by Example

Appendix E. Using the additional material


This redbook also contains additional material in CD-ROM format, and/or Web material. See the appropriate section below for instructions on using or downloading each type of material.

E.1 Using the CD-ROM


The CD-ROM that accompanies this redbook contains all of the sample files referenced within the book. Table 50 on page 348 shows the directory structure used for the samples. Most of the directories include a readme.txt file, which contains a detailed description of the samples contained within that directory.

Copyright IBM Corp. 2000

347

Sample client code Sample stored procedure code

S390 sample utilities Sample SQL code


Figure 50. Sample files directory structure

E.1.1 Sample client code


These files can be found in directory \Samples\Code_Clients
\Samples\Code_Clients\readme_clients.txt

E.1.1.1 OS/390 sample client code These files can be found in directory \Samples\Code_Clients\OS390
\Samples\Code_Clients\OS390\cscallac.txt \Samples\Code_Clients\OS390\jecall_Query_oi_summ.java \Samples\Code_Clients\OS390\jscall_Add_customer.java \Samples\Code_Clients\OS390\readme.txt

348

DB2 Java Stored Procedures: Learning by Example

\Samples\Code_Clients\OS390\sscall_Add_customer.sqlj

E.1.1.2 UNIX / NT Sample client code These files can be found in directory \Samples\Code_Clients\Unix_and_NT
\Samples\Code_Clients\Unix_and_NT \Samples\Code_Clients\Unix_and_NT\jecall_Query_oi_summ.java \Samples\Code_Clients\Unix_and_NT\jscall_Add_customer.java \Samples\Code_Clients\Unix_and_NT\prep.sh \Samples\Code_Clients\Unix_and_NT\prep_sscall.bat \Samples\Code_Clients\Unix_and_NT\sscall_Add_customer.sqlj

E.1.2 Sample stored procedure code


These files can be found in directory \Samples\Code_Stored_Procedures
\Samples\Code_Stored_Procedures\readme_procs.txt

E.1.2.1 COBOL sample stored procedure code These files can be found in directory \Samples\Code_Stored_Procedures\COBOL
\Samples\Code_Stored_Procedures\COBOL\S390 \Samples\Code_Stored_Procedures\COBOL\S390\Acmecoe \Samples\Code_Stored_Procedures\COBOL\S390\Acmecos \Samples\Code_Stored_Procedures\COBOL\S390\Acmecos\addcust.txt

E.1.2.2 JDBC sample stored procedure code These files can be found in directory \Samples\Code_Stored_Procedures\JDBC
\Samples\Code_Stored_Procedures\JDBC\readme_jdbc.txt

JDBC sample stored procedure code - NT These files can be found in directory \Samples\Code_Stored_Procedures\JDBC\NT
\Samples\Code_Stored_Procedures\JDBC\NT\Acmejne \Samples\Code_Stored_Procedures\JDBC\NT\Acmejns \Samples\Code_Stored_Procedures\JDBC\NT\Acmejne\ACMEJNE \Samples\Code_Stored_Procedures\JDBC\NT\Acmejne\define_sp.sql \Samples\Code_Stored_Procedures\JDBC\NT\Acmejne\prep.bat \Samples\Code_Stored_Procedures\JDBC\NT\Acmejne\ACMEJNE\Add_customer.java \Samples\Code_Stored_Procedures\JDBC\NT\Acmejne\ACMEJNE\Add_order.java \Samples\Code_Stored_Procedures\JDBC\NT\Acmejne\ACMEJNE\Query_oi_summ.java \Samples\Code_Stored_Procedures\JDBC\NT\Acmejns\ACMEJNS \Samples\Code_Stored_Procedures\JDBC\NT\Acmejns\define_sp.sql \Samples\Code_Stored_Procedures\JDBC\NT\Acmejns\prep.bat \Samples\Code_Stored_Procedures\JDBC\NT\Acmejns\ACMEJNS\Add_customer.java

Appendix E. Using the additional material

349

JDBC sample stored procedure code - S390 These files can be found in directory
\Samples\Code_Stored_Procedures\JDBC\S390 \Samples\Code_Stored_Procedures\JDBC\S390\ACMEJOS \Samples\Code_Stored_Procedures\JDBC\S390\ACMEJOS\Add_customer.java

JDBC sample stored procedure code - UNIX These files can be found in directory
\Samples\Code_Stored_Procedures\JDBC\UNIX \Samples\Code_Stored_Procedures\JDBC\UNIX\ACMEJUE \Samples\Code_Stored_Procedures\JDBC\UNIX\ACMEJUS \Samples\Code_Stored_Procedures\JDBC\UNIX\ACMEJUE\ACMEJUE \Samples\Code_Stored_Procedures\JDBC\UNIX\ACMEJUE\define_sp_Query_oi_summ. sql \Samples\Code_Stored_Procedures\JDBC\UNIX\ACMEJUE\install_jar.sql \Samples\Code_Stored_Procedures\JDBC\UNIX\ACMEJUE\prep.sh \Samples\Code_Stored_Procedures\JDBC\UNIX\ACMEJUE\replace_jar.sql \Samples\Code_Stored_Procedures\JDBC\UNIX\ACMEJUE\ACMEJUE\Query_oi_summ.ja va \Samples\Code_Stored_Procedures\JDBC\UNIX\ACMEJUS\ACMEJUS \Samples\Code_Stored_Procedures\JDBC\UNIX\ACMEJUS\define_sp_Add_customer.s ql \Samples\Code_Stored_Procedures\JDBC\UNIX\ACMEJUS\install_jar.sql \Samples\Code_Stored_Procedures\JDBC\UNIX\ACMEJUS\prep.sh \Samples\Code_Stored_Procedures\JDBC\UNIX\ACMEJUS\replace_jar.sql \Samples\Code_Stored_Procedures\JDBC\UNIX\ACMEJUS\ACMEJUS\Add_customer.jav a

E.1.2.3 SQLJ sample stored procedure code These files can be found in directory \Samples\Code_Stored_Procedures\SQLJ
\Samples\Code_Stored_Procedures\SQLJ\readme.txt

SQLJ sample stored procedure code - NT These files can be found in directory \Samples\Code_Stored_Procedures\SQLJ\NT
\Samples\Code_Stored_Procedures\SQLJ\NT\Acmesne \Samples\Code_Stored_Procedures\SQLJ\NT\ACMESNS \Samples\Code_Stored_Procedures\SQLJ\NT\Acmesne\acmesne \Samples\Code_Stored_Procedures\SQLJ\NT\Acmesne\define_acmesne.sql \Samples\Code_Stored_Procedures\SQLJ\NT\Acmesne\prep.bat \Samples\Code_Stored_Procedures\SQLJ\NT\Acmesne\acmesne\Add_customer.sqlj \Samples\Code_Stored_Procedures\SQLJ\NT\Acmesne\acmesne\Query_oi_summ.sqlj \Samples\Code_Stored_Procedures\SQLJ\NT\ACMESNS\ACMESNS \Samples\Code_Stored_Procedures\SQLJ\NT\ACMESNS\define_sp.sql

350

DB2 Java Stored Procedures: Learning by Example

\Samples\Code_Stored_Procedures\SQLJ\NT\ACMESNS\prep.bat \Samples\Code_Stored_Procedures\SQLJ\NT\ACMESNS\refresh.bat \Samples\Code_Stored_Procedures\SQLJ\NT\ACMESNS\refresh_sp.sql \Samples\Code_Stored_Procedures\SQLJ\NT\ACMESNS\ACMESNS\Add_customer.sqlj

SQLJ sample stored procedure code - S390 These files can be found in directory
\Samples\Code_Stored_Procedures\SQLJ\S390 \Samples\Code_Stored_Procedures\SQLJ\S390\Acmesos \Samples\Code_Stored_Procedures\SQLJ\S390\Acmesos\Add_customer.sqlj

SQLJ sample stored procedure code - UNIX These files can be found in directory
\Samples\Code_Stored_Procedures\SQLJ\Unix \Samples\Code_Stored_Procedures\SQLJ\Unix\ACMESUE \Samples\Code_Stored_Procedures\SQLJ\Unix\ACMESUS \Samples\Code_Stored_Procedures\SQLJ\Unix\ACMESUE\ACMESUE \Samples\Code_Stored_Procedures\SQLJ\Unix\ACMESUE\define_sp_Query_oi_summ. sql \Samples\Code_Stored_Procedures\SQLJ\Unix\ACMESUE\install_jar.sql \Samples\Code_Stored_Procedures\SQLJ\Unix\ACMESUE\prep.sh \Samples\Code_Stored_Procedures\SQLJ\Unix\ACMESUE\replace_jar.sql \Samples\Code_Stored_Procedures\SQLJ\Unix\ACMESUE\ACMESUE\Query_oi_summ.sq lj \Samples\Code_Stored_Procedures\SQLJ\Unix\ACMESUS\ACMESUS \Samples\Code_Stored_Procedures\SQLJ\Unix\ACMESUS\define_sp_Add_customer.s ql \Samples\Code_Stored_Procedures\SQLJ\Unix\ACMESUS\install_jar.sql \Samples\Code_Stored_Procedures\SQLJ\Unix\ACMESUS\prep.sh \Samples\Code_Stored_Procedures\SQLJ\Unix\ACMESUS\replace_jar.sql \Samples\Code_Stored_Procedures\SQLJ\Unix\ACMESUS\ACMESUS\Add_customer.sql j

E.1.2.4 SQLJ & JDBC sample stored procedure code These files can be found in directory \Samples\Code_Stored_Procedures\Both
\Samples\Code_Stored_Procedures\Both\readme.txt

SQLJ & JDBC sample stored procedure code - S390 These files can be found in directory
\Samples\Code_Stored_Procedures\Both\S390 \Samples\Code_Stored_Procedures\Both\S390\Acmebos \Samples\Code_Stored_Procedures\Both\S390\Acmebos\Add_customer.sqlj

Appendix E. Using the additional material

351

SQLJ & JDBC sample stored procedure code - NT These files can be found in directory \Samples\Code_Stored_Procedures\Both\NT
\Samples\Code_Stored_Procedures\Both\NT\ACMEBNS \Samples\Code_Stored_Procedures\Both\NT\ACMEBNS\ACMEBNS \Samples\Code_Stored_Procedures\Both\NT\ACMEBNS\define_acmebns.sql \Samples\Code_Stored_Procedures\Both\NT\ACMEBNS\prep.bat \Samples\Code_Stored_Procedures\Both\NT\ACMEBNS\refresh.bat \Samples\Code_Stored_Procedures\Both\NT\ACMEBNS\refresh_acmebns.sql \Samples\Code_Stored_Procedures\Both\NT\ACMEBNS\ACMEBNS\Add_customer.sqlj

SQLJ & JDBC sample stored procedure code - UNIX These files can be found in directory
\Samples\Code_Stored_Procedures\Both\Unix \Samples\Code_Stored_Procedures\Both\Unix\ACMEBUS \Samples\Code_Stored_Procedures\Both\Unix\ACMEBUS\ACMEBUS \Samples\Code_Stored_Procedures\Both\Unix\ACMEBUS\define_sp_Add_customer.s ql \Samples\Code_Stored_Procedures\Both\Unix\ACMEBUS\install_jar.sql \Samples\Code_Stored_Procedures\Both\Unix\ACMEBUS\prep.sh \Samples\Code_Stored_Procedures\Both\Unix\ACMEBUS\replace_jar.sql \Samples\Code_Stored_Procedures\Both\Unix\ACMEBUS\ACMEBUS\Add_customer.sql j

E.1.3 Sample S390 utilities


These files can be found in directory \Samples\S390_Utilities
\Samples\S390_Utilities\readme.txt

E.1.3.1 Sample S390 installation utilities These files can be found in directory \Samples\S390_Utilities\Installation
\Samples\S390_Utilities\Installation\.profile \Samples\S390_Utilities\Installation\db2jdbc.cursors \Samples\S390_Utilities\Installation\db2sqljjdbc.properties \Samples\S390_Utilities\Installation\dbz2java \Samples\S390_Utilities\Installation\javaenv \Samples\S390_Utilities\Installation\jdbcbind \Samples\S390_Utilities\Installation\readme.txt \Samples\S390_Utilities\Installation\sqljplan

Note:

The .profile file was recorded in the CD-ROM as profile (without the dot). Once you have downloaded it, you need to rename the file to .profile.

352

DB2 Java Stored Procedures: Learning by Example

E.1.3.2 Sample S390 program preparation utilities These files can be found in directory\Samples\S390_Utilities\Program_Preparation
\Samples\S390_Utilities\Program_Preparation\bindcl.rexx \Samples\S390_Utilities\Program_Preparation\bindsp.rexx \Samples\S390_Utilities\Program_Preparation\driver_bos \Samples\S390_Utilities\Program_Preparation\driver_cl \Samples\S390_Utilities\Program_Preparation\driver_joe \Samples\S390_Utilities\Program_Preparation\driver_jos \Samples\S390_Utilities\Program_Preparation\driver_soe \Samples\S390_Utilities\Program_Preparation\driver_sos \Samples\S390_Utilities\Program_Preparation\hpjcust \Samples\S390_Utilities\Program_Preparation\hpjsp \Samples\S390_Utilities\Program_Preparation\javacl \Samples\S390_Utilities\Program_Preparation\javasp \Samples\S390_Utilities\Program_Preparation\javaspj \Samples\S390_Utilities\Program_Preparation\oebind \Samples\S390_Utilities\Program_Preparation\readme.txt

E.1.4 Sample SQL


These files can be found in directory \Samples\SQL
\Samples\SQL\readme.txt

E.1.4.1 Sample SQL - S390 These files can be found in directory \Samples\SQL\S390
\Samples\SQL\S390\ddle.txt \Samples\SQL\S390\ddls.txt \Samples\SQL\S390\procbos.txt \Samples\SQL\S390\proccoe.txt \Samples\SQL\S390\proccos.txt \Samples\SQL\S390\procjoe.txt \Samples\SQL\S390\procjos.txt \Samples\SQL\S390\procsoe.txt \Samples\SQL\S390\procsos.txt \Samples\SQL\S390\readme.txt

E.1.4.2 Sample SQL - UNIX and NT These files can be found in directory \Samples\SQL\Unix_and_NT
\Samples\SQL\Unix_and_NT\ddle_nt_db2v7.txt \Samples\SQL\Unix_and_NT\ddle_unix_db2v6.txt \Samples\SQL\Unix_and_NT\ddls.txt

Appendix E. Using the additional material

353

E.2 Locating the additional material on the Internet


The samples contained on the CD-ROM associated with this redbook are also available in softcopy on the Internet from the IBM Redbooks Web server. Point your Web browser to:
ftp://www.redbooks.ibm.com/redbooks/SG245945

Alternatively, you can go to the IBM Redbooks Web site at:


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

Select the Additional materials and open the directory that corresponds with the redbook form number.

E.3 Using the Web material


The additional Web material that accompanies this redbook includes the following:

File name SG245945.zip

Description Zipped Code for all Samples in the book.

E.3.1 How to use the Web material


1. Download the zip file containing the samples from the IBM Redbooks Web server, as described above. 2. Create a subdirectory (folder) on your workstation to hold the samples. 3. Unzip the sample material into this folder, using PKUNZIP or any other ZIP utility. When you unzip the file, ensure that you select the relevant option to retain the directory structure for the sample files. Refer to E.1, Using the CD-ROM on page 347 for a detailed listing of the sample files.

354

DB2 Java Stored Procedures: Learning by Example

Appendix F. Special notices


This publication is intended to help system programmers, database administrators, and application developers in understanding, assessing, and utilizing the JDBC, SQLJ and Java stored procedures support of DB2 UDB Server for OS/390 Version 6. The information in this publication is not intended as the specification of any programming interfaces that are provided by DB2 UDB Server for OS/390 Version 6. See the PUBLICATIONS section of the IBM Programming Announcement for DB2 UDB Server for OS/390 Version 6 for more information about what publications are considered to be product documentation. References in this publication to IBM products, programs or services do not imply that IBM intends to make these available in all countries in which IBM operates. Any reference to an IBM product, program, or service is not intended to state or imply that only IBM's product, program, or service may be used. Any functionally equivalent program that does not infringe any of IBM's intellectual property rights may be used instead of the IBM product, program or service. Information in this book was developed in conjunction with use of the equipment specified, and is limited in application to those specific hardware and software products and levels. IBM may have patents or pending patent applications covering subject matter in this document. The furnishing of this document does not give you any license to these patents. You can send license inquiries, in writing, to the IBM Director of Licensing, IBM Corporation, North Castle Drive, Armonk, NY 10504-1785. Licensees of this program who wish to have information about it for the purpose of enabling: (i) the exchange of information between independently created programs and other programs (including this one) and (ii) the mutual use of the information which has been exchanged, should contact IBM Corporation, Dept. 600A, Mail Drop 1329, Somers, NY 10589 USA. Such information may be available, subject to appropriate terms and conditions, including in some cases, payment of a fee. The information contained in this document has not been submitted to any formal IBM test and is distributed AS IS. The information about non-IBM ("vendor") products in this manual has been supplied by the vendor and IBM assumes no responsibility for its accuracy or completeness. The use of this information or the implementation of any of these techniques is a customer

Copyright IBM Corp. 2000

355

responsibility and depends on the customer's ability to evaluate and integrate them into the customer's operational environment. While each item may have been reviewed by IBM for accuracy in a specific situation, there is no guarantee that the same or similar results will be obtained elsewhere. Customers attempting to adapt these techniques to their own environments do so at their own risk. Any pointers in this publication to external Web sites are provided for convenience only and do not in any manner serve as an endorsement of these Web sites. Any performance data contained in this document was determined in a controlled environment, and therefore, the results that may be obtained in other operating environments may vary significantly. Users of this document should verify the applicable data for their specific environment. This document contains examples of data and reports used in daily business operations. To illustrate them as completely as possible, the examples contain the names of individuals, companies, brands, and products. All of these names are fictitious and any similarity to the names and addresses used by an actual business enterprise is entirely coincidental. Reference to PTF numbers that have not been released through the normal distribution process does not imply general availability. The purpose of including these reference numbers is to alert IBM customers to specific information relative to the implementation of the PTF when it becomes available to each customer according to the normal IBM PTF distribution process. The following terms are trademarks of the International Business Machines Corporation in the United States and/or other countries:
AIX AT CICS DATABASE2 DB2 Connect Enterprise Storage Server Language Environment Netfinity Parallel Sysplex RACF RETAIN RS/6000 SP VisualAge XT AS/400 C/MVS CT DB2 DRDA IBM Net.Data OS/390 QMF RAMAC RMF S/390 System/390 VTAM 400

356

DB2 Java Stored Procedures: Learning by Example

The following terms are trademarks of other companies: Tivoli, Manage. Anything. Anywhere.,The Power To Manage., Anything. Anywhere.,TME, NetView, Cross-Site, Tivoli Ready, Tivoli Certified, Planet Tivoli, and Tivoli Enterprise are trademarks or registered trademarks of Tivoli Systems Inc., an IBM company, in the United States, other countries, or both. In Denmark, Tivoli is a trademark licensed from Kjbenhavns Sommer - Tivoli A/S. C-bus is a trademark of Corollary, Inc. in the United States and/or other countries. Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and/or other countries. Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the United States and/or other countries. PC Direct is a trademark of Ziff Communications Company in the United States and/or other countries and is used by IBM Corporation under license. ActionMedia, LANDesk, MMX, Pentium and ProShare are trademarks of Intel Corporation in the United States and/or other countries. UNIX is a registered trademark in the United States and other countries licensed exclusively through The Open Group. SET and the SET logo are trademarks owned by SET Secure Electronic Transaction LLC. Other company, product, and service names may be trademarks or service marks of others.

Appendix F. Special notices

357

358

DB2 Java Stored Procedures: Learning by Example

Appendix G. Related publications


The publications listed in this section are considered particularly suitable for a more detailed discussion of the topics covered in this redbook.

G.1 IBM Redbooks


For information on ordering these publications see How to get IBM Redbooks on page 363. Java Programming Guide for OS/390, SG24-5619 Getting Started with DB2 Stored Procedures: Give Them a Call through the Network , SG24-4693 Developing Cross-Platform DB2 Stored Procedures: SQL Procedures and DB2 Stored Procedure Builder, SG24-5485 DB2 UDB for OS/390 and Continuous Availability, SG24-5486

G.2 IBM Redbooks collections


Redbooks are also available on the following CD-ROMs. Click the CD-ROMs button at ibm.com/redbooks for information about all the CD-ROMs offered, updates and formats.
CD-ROM Title
System/390 Redbooks Collection Networking and Systems Management Redbooks Collection Transaction Processing and Data Management Redbooks Collection Lotus Redbooks Collection Tivoli Redbooks Collection AS/400 Redbooks Collection Netfinity Hardware and Software Redbooks Collection RS/6000 Redbooks Collection (BkMgr) RS/6000 Redbooks Collection (PDF Format) Application Development Redbooks Collection IBM Enterprise Storage and Systems Management Solutions

Collection Kit Number SK2T-2177 SK2T-6022 SK2T-8038 SK2T-8039 SK2T-8044 SK2T-2849 SK2T-8046 SK2T-8040 SK2T-8043 SK2T-8037 SK3T-3694

Copyright IBM Corp. 2000

359

G.3 Other resources


These publications are also relevant as further information sources: DB2 UDB for OS/390 Version 6 Whats New, GC26-9017-02 DB2 UDB for OS/390 Version 6 Application Programming and SQL Guide, SC26-9004 DB2 UDB for OS/390 Version 6 SQL Reference, SC26-9014-01 DB2 UDB for OS/390 Version 6 Administration Guide, SC26-9003-01 DB2 UDB for OS/390 Version 6 Installation Guide, SC26-9008-01 D B2 UDB for OS/390 Version 6 Command Reference, SC26-9006-01 DB2 UDB for OS/390 Version 6 Utility Guide and Reference, SC26-9015-01 DB2 UDB for OS/390 Version 6 ODBC Guide and Reference, SC26-9005-01 DB2 UDB for OS/390 Version 6 Application Programming and SQL Guide, SC26-9004-01 DB2 UDB for OS/390 Version 6 Messages and Codes, SC26-9011-01 DB2 UDB Version 6 Application Development Guide, SC09-2845 OS/390 V2R8.0 MVS Planning: Workload Management, GC28-1761-09 OS/390 WLM refer to OS/390 MVS Workload Management Services, GC28-1773 OS/390 V2R8 MVS Programming: Resource Recovery, GC28-1739-05 DB2 UDB Installation and Configuration Supplement V6 , GC09-2857 Java Application Programming Guide and Reference for Java , SC26-9018-01 DB2 for OS/390 Application Programming Guide and Reference for Java, SC26-9547 UNIX System Services Users Guide, SC28-1891 Using REXX and OS/390 UNIX System Services , SC28-1905-04

360

DB2 Java Stored Procedures: Learning by Example

G.4 Referenced Web sites


These Web sites are also relevant as further information sources: http://www-4.ibm.com/software/data/db2/java/ The most recent material about using JAVA with DB2. http://www.s390.ibm.com/oe/ OS/390 UNIX System Services home page. http://www.rs6000.ibm.com/cgi-bin/ds_form?config=/usr/share/man/info/
en_US/a_doc_lib/data/base.cfg

AIX documentation; many commands also work in UNIX System Services. http://service.software.ibm.com/db2/support/dbssup.html DB2 software updates. http://www.sqlj.org SQLJ home page. http://www.ibm.com/s390/corner/ Java on S/390. http://www.software.ibm.com/data/db2/ DB2 Family http://www.software.ibm.com/data/db2/os390/ DB2 for OS/390. http://www.ibm.com/software/db2os390/downloads.html DB2 downloads. http://www.ibm.com/solutions/businessintelligence/teraplex/index.html Teraplex Center.

Appendix G. Related publications

361

362

DB2 Java Stored Procedures: Learning by Example

How to get IBM Redbooks


This section explains how both customers and IBM employees can find out about IBM Redbooks, redpieces, and CD-ROMs. A form for ordering books and CD-ROMs by fax or e-mail is also provided. Redbooks Web Site ibm.com/redbooks Search for, view, download, or order hardcopy/CD-ROM Redbooks from the Redbooks Web site. Also read redpieces and download additional materials (code samples or diskette/CD-ROM images) from this Redbooks site. Redpieces are Redbooks in progress; not all Redbooks become redpieces and sometimes just a few chapters will be published this way. The intent is to get the information out much quicker than the formal publishing process allows. E-mail Orders Send orders by e-mail including information from the IBM Redbooks fax order form to: In United States Outside North America Telephone Orders United States (toll free) Canada (toll free) Outside North America 1-800-879-2755 1-800-IBM-4YOU Country coordinator phone number is in the How to Order section at this site: http://www.elink.ibmlink.ibm.com/pbl/pbl

e-mail address usib6fpl@ibmmail.com Contact information is in the How to Order section at this site: http://www.elink.ibmlink.ibm.com/pbl/pbl

Fax Orders United States (toll free) Canada Outside North America 1-800-445-9269 1-403-267-4455 Fax phone number is in the How to Order section at this site: http://www.elink.ibmlink.ibm.com/pbl/pbl

This information was current at the time of publication, but is continually subject to change. The latest information may be found at the Redbooks Web site.

IBM Intranet for Employees


IBM employees may register for information on workshops, residencies, and Redbooks by accessing the IBM Intranet Web site at http://w3.itso.ibm.com/ and clicking the ITSO Mailing List button. Look in the Materials repository for workshops, presentations, papers, and Web pages developed and written by the ITSO technical professionals; click the Additional Materials button. Employees may access MyNews at http://w3.ibm.com/ for redbook, residency, and workshop announcements.

Copyright IBM Corp. 2000

363

IBM Redbooks fax order form


Please send me the following: Title Order Number Quantity

First name Company Address City Telephone number Invoice to customer number Credit card number

Last name

Postal code Telefax number

Country VAT number

Credit card expiration date

Card issued to

Signature

We accept American Express, Diners, Eurocard, Master Card, and Visa. Payment by credit card not available in all countries. Signature mandatory for credit card payment.

364

DB2 Java Stored Procedures: Learning by Example

Glossary
The following terms and abbreviations are defined as they are used in the DB2 library. If you do not find the term you are looking for, refer to the index or to IBM Dictionary of Computing. Also, it brings term and abbreviations related to Java and other products, mentioned in this book.

AFC

See Application Foundation Classes.

allied address space. An area of storage external to DB2 that is connected to DB2 and is therefore capable of requesting DB2 services. American National Standards Institute (ANSI) . An organization consisting of producers, consumers, and general interest groups, that establishes the procedures by which accredited organizations create and maintain voluntary industry standards in the United States. ANSI. American National Standards Institute. API
See Application Program Interface.

A
abstract class A class that provides common information for subclasses, and therefore cannot be instantiated. Abstract classes provide at least one abstract method. abstract method A method with a signature, but no implementation. You provide the implementation of the method in the subclass of the abstract class that contains the abstract method. abstract window toolkit (AWT) The Abstract Window Toolkit API provides a layer between the application and the hosts windowing system. It enables programmers to port Java applications from one window system to another. The AWT provides access to basic interface components such as events, color, fonts, and controls such as button, scroll bars, text fields, frames, windows, dialogs, panels, canvases, and check boxes. actual parameter list Parameters specified in a call to a method. See also formal parameter list. address space. A range of virtual storage pages identified by a number (ASID) and a collection of segment and page tables which map the virtual pages to real pages of the computer's memory. address space connection. The result of connecting an allied address space to DB2. Each address space containing a task connected to DB2 has exactly one address space connection, even though more than one task control block (TCB) can be present. See allied address space and task control block.

applet A Java program designed to run within a Web browser. Contrast with application. application. (1) A program or set of programs that perform a task; for example, a payroll application. (2) In Java programming, a self-contained, stand-alone Java program that includes a static main method. It does not require an applet viewer. Contrast with applet. Application Foundation Classes (AFCs) Microsofts version on the Java Foundation Classes (JFCs). AFCs deliver similar functions to JFCs but only work on Windows 32-bit platforms. application plan. The control structure produced during the bind process and used by DB2 to process SQL statements encountered during statement execution. application program interface (API) . A functional interface supplied by the operating system or by a separately orderable licensed program that allows an application program written in a high-level language to use specific data or functions of the operating system or licensed program. application requester (AR) . See requester. AR. application requester. See requester. AS. application server.

Copyright IBM Corp. 2000

365

ASCII (1) American Standard Code for Information Interchange.A standard assignment of 7-bit numeric codes to characters. See also Unicode. (2) An encoding scheme used to represent strings in many environments, typically on PCs and workstations. Contrast with EBCDIC. attachment facility. An interface between DB2 and TSO, IMS, CICS, or batch address spaces. An attachment facility allows application programs to access DB2. authorization ID. A string that can be verified for connection to DB2 and to which a set of privileges are allowed. It can represent an individual, an organizational group, or a function, but DB2 does not determine this representation. AWT
See Abstract Window Toolkit.

selected and some authorization checking is performed.

automatic bind. (More correctly automatic rebind). A process by which SQL statements are bound automatically (without a user issuing a BIND command) when an application process begins execution and the bound application plan or package it requires is not valid. dynamic bind. A process by which SQL statements are bound as they are entered. incremental bind. A process by which SQL
statements are bound during the execution of an application process, because they could not be bound during the bind process, and VALIDATE(RUN) was specified.

B
base table. (1) A table created by the SQL CREATE TABLE statement that is used to hold persistent data. Contrast with result table and temporary table. (2) A table containing a LOB column definition. The actual LOB column data is not stored along with the base table. The base table contains a row identifier for each row and an indicator column for each of its LOB columns. Contrast with auxiliary table. base type In Java, a type establishes an interface to anything inherited from itself. See type, derived type . bean A definition or instance of a JavaBeans component. See JavaBeans. BeanInfo (1) A Java class that provides explicit information about the properties, events, and methods of a bean class. (2) In the VisualAge for Java Integrated Development Environment, a page in the class browser that provides bean information. binary large object (BLOB). See BLOB. bind. The process by which the output from the DB2 precompiler is converted to a usable control structure called a package or an application plan. During the process, access paths to the data are

static bind. A process by which SQL statements are bound after they have been precompiled. All static SQL statements are prepared for execution at the same time. Contrast with dynamic bind. BLOB. A sequence of bytes, where the size of the sequence ranges from 0 bytes to 2 GB - 1. Such a string does not have an associated CCSID. The size of binary large object values can be anywhere up to 2 GB - 1. browser (1) In VisualAge for Java, a window that provides information on program elements. There are browsers for projects, packages, classes, methods, and interfaces. (2) An Internet-based too that lets users browse Web sites. built-in function. A function that is supplied by DB2. Contrast with user-defined function. business object (1) An object that represents a business function. Business objects contain attributes that define the state of the object, and methods that define the behavior of the object. A business object also has relationships with other business objects. Business objects can be used in combination to perform a desired task. Typical examples of business objects are Customer, Invoice, or Account. (2) In the Enterprise Access Builder, a class that implements the IBusinessObject interface. Business objects are used to map interactions with an existing home.

366

DB2 Java Stored Procedures: Learning by Example

bytecode Machine-independent code generated by the Java compiler and executed by the Java interpreter.

class hierarchy The relationships between classes that share a single inheritance. All Java classes inherit from the Object class. class method Methods that apply to the class as a whole rather than its instances (also called a static method). class path When running a program in VisualAge for Java, a list of directories and JAR files that contain resource files or Java classes that a program can load dynamically at run time. A program's class path is set in its Properties notebook. CLASSPATH In your deployment environment, the environment variable keyword that specifies the directories in which to look for class and resource files. class variable Variables that apply to the class as a whole rather than its instances (also called a static field ). CLI. See call level interface. client. (1)A networked computer in which the IDE is connected to a repository on a team server. (2) See requester. CLOB. A sequence of bytes representing single-byte characters or a mixture of single and double-byte characters where the size can be up to 2 GB - 1. Although the size of character large object values can be anywhere up to 2 GB - 1, in general, they are used whenever a character string might exceed the limits of the VARCHAR type. codebase An attribute of the <APPLET> tag that provides the relative path name for the classes. Use this attribute when your class files reside in a different directory than your HTML files. column function. An SQL operation that derives its result from a collection of values across one or more rows. Contrast with scalar function. commit. The operation that ends a unit of work by releasing locks so that the database changes made by that unit of work can be perceived by other processes.

C
CAF. Call attachment facility. call attachment facility (CAF). A DB2 attachment facility for application programs running in TSO or MVS batch. The CAF is an alternative to the DSN command processor and allows greater control over the execution environment. call level interface (CLI). A callable application program interface (API) for database access, which is an alternative to using embedded SQL. In contrast to embedded SQL, DB2 CLI does not require the user to precompile or bind applications, but instead provides a standard set of functions to process SQL statements and related services at run time. cast function. A function used to convert instances of a (source) data type into instances of a different (target) data type. In general, a cast function has the name of the target data type. It has one single argument whose type is the source data type; its return type is the target data type. casting Explicitly converting an object or primitives data type. catalog. In DB2, a collection of tables that contains descriptions of objects such as tables, views, and indexes. catalog table. Any table in the DB2 catalog. C++ Access Builder A VisualAge fro Java, Enterprise Edition tool that generates beans and C++ wrappers that let your Java programs access C++ DLLs. character large object (CLOB) . See CLOB. class An encapsulated collection of data and methods to operate on the data. A class may be instantiated to produce an object that is an instance of the class.

367

Common Connector Framework In the Enterprise Access Builder, interface and class definitions that provide a consistent means of interacting with enterprise resources (for example, CICS and Encina transactions) from any Java execution environment. Common Object Request Broker Architecture (CORBA) Common Object Request Broker Architecture. A specification produced by the Object Management Group (OMG) that presents standards for various types of object request brokers (such as client-resident ORBs, server-based ORBs, system-based ORBs, and library-based ORBs). Implementation of CORBA standards enables object request brokers from different software vendors to interoperate. Common RFC Interface for Java A set of Java interfaces and classes that defines a middleware-independent layer to access R/3 systems from Java. If applications are built on top of this interface, they can leverage different middleware at run time without recoding. The generated beans are based on this interface and provide the same flexibility. common server. Describes the set of DB2 products that run on various platforms and have the same source code. These platforms include OS/2, Windows, and UNIX. component model An architecture and an API that allows developers to define reusable segments of code that can be combined to create a program. VisualAge for Java uses the JavaBeans component model. composite bean A bean that can contain both visual and nonvisual components. A composite bean is composed of embedded beans. connection In the VisualAge for Java Visual Composition Editor, a visual link between two components that represents the relationship between the components. Each connection has a source, a target, and other properties. connection handle. The data object that contains information associated with a connection managed by DB2 CLI. This includes general status information, transaction status, and diagnostic information.

Console In VisualAge for Java, the window that acts as the standard input (System.in) and standard output (System.out) device for programs running in the VisualAge for Java environment. constructor A method called to set up a new instance of a class. constant . A language element that specifies anunchanging value. Constants are classified as string constants or numeric constants. Contrast with variable. container A component that can hold other components. In Java, examples of containers include applets, frames, and dialogs. In the Visual Composition Editor, containers can be graphically represented and generated. context. The application's logical connection to the data source and associated internal DB2 ODBC connection information that allows the application to direct its operations to a data source. A DB2 ODBC context represents a DB2 thread. cookie (1) A small file stored on an individual's computer; this file allows a site to tag the browser with a unique identification. When a person visits a site, the site's server requests a unique ID from the person's browser. If this browser does not have an ID, the server delivers one. On the Wintel platform, the cookie is delivered to a file called'cookies.txt,' and on a Macintosh platform, it is delivered to 'MagicCookie.' Just as someone can track the origin of a phone call with Caller ID, companies can use cookies to track information about behavior. (2) Persistent data stored by the client in the Servlet Builder. CORBA Common Objects Request Broker Architecture. Core API Part of the minimal set of APIs that form the standard Java Platform. Core APIs are available on the Java Platform regardless of the underlying operating system. The Core API grows with each release of the JDK; the current core API is based on JDK 1.1. Also called core classes. cursor. A named control structure used by an application program to point to a row of interest

368

DB2 Java Stored Procedures: Learning by Example

within some set of rows, and to retrieve rows from the set, possibly making updates or deletions.

D
Data Access Bean In the VisualAge for Java Visual Composition Editor, a bean that accesses and manipulates the content of JDBC/ODBC-compliant relational databases. Data Access Builder A VisualAge for Java Enterprise tool that generates beans to access and manipulate the content of JDBC/ODBC-compliant relational databases. database management system (DBMS). A software system that controls the creation, organization, and modification of a database and access to the data stored within it. data source. A local or remote relational or non-relational data manager that is capable of supporting data access via an ODBC driver which supports the ODBC APIs. In the case of DB2 for OS/390, the data sources are always relational database managers. DBCLOB. A sequence of bytes representing double-byte characters where the size can be up to 2 gigabytes. Although the size of double-byte character large object values can be anywhere up to 2 gigabytes, in general, they are used whenever a double-byte character string might exceed the limits of the VARGRAPHIC type. DBMS. Database management system. DB2 thread. The DB2 structure that describes an application's connection, traces its progress, processes resource functions, and delimits its accessibility to DB2 resources. and services. debugger A component that assists in analyzing and correcting coding errors. declaration Statement that creates an identifier and its attributes, but does not reserve storage or provide an implementation. definition Statement that reserves storage or provides an implementation. deprecation An obsolete component that may be deleted from a future version of a product.

derived type In Java, a type that overrides the definitions of a base type to provide unique behavior. The derived type extends the base type. dipping A metaphor, introduced by BeanExtender on alphaWorks, for modifying a component by hooking a special kind of Java bean onto it. Dipping lets you add new behavior or modify the Java bean's existing behavior without having to manipulate the Java bean's code. A dip is a special kind of Java bean that can be hooked on to another Java bean; it is the new feature you want to add to the component. Software examples of dips include printing and security. Dippable Java beans can have one or more dips connected to them. Almost any Java bean or class can be made dippable by extending it, a process called morphing. dip A special kind of Java bean that can be hooked on to another Java bean; the new feature you want to add to the component. Software examples of dips include printing and security.
distributed processing Processing that takes place across two or more linked systems.

distinct type. A user-defined data type that is internally represented as an existing type (its source type), but is considered to be a separate and incompatible type for semantic purposes. distributed relational database architecture (DRDA). A connection protocol for distributed relational database processing that is used by IBM's relational database products. DRDA includes protocols for communication between an application and a remote relational database management system, and for communication between relational database management systems. DLL (dynamic link library) A file containing executable code and data bound to a program at load time or run time, rather than during linking. The code and data in a dynamic link library can be shared by several applications simultaneously. The DLLs. Enterprise Access Builders also generate platform-specific DLLs for the workstation and OS/390 platforms.

369

double-byte character large object (DBCLOB). See DBCLOB. double precision A floating-point number that contains 64 bits. See also single precision . DRDA. Distributed relational database architecture. dynamic SQL. SQL statements that are prepared and executed within an application program while the program is executing. In dynamic SQL, the SQL source is contained in host language variables rather than being coded into the application program. The SQL statement can change several times during the application program's execution.

encapsulation The grouping of both data and operations into neat, manageable units that can be developed, tested, and maintained independently of one another. Such grouping is a powerful technique for building better software. The object manages its own resources and limits their visibility. enclave. In Language Environment for MVS & VM, an independent collection of routines, one of which is designated as the main routine. An enclave is similar to a program or run unit. Enterprise Access Builder (EAB) Feature of Visual Age for Java, Enterprise Edition, that creates connectors to enterprise server products such as CICS, Encina, IMS TOC, and MQSeries. Enterprise Edition See VisualAge for Java, Enterprise Edition . Enterprise Java Includes Enterprise JavaBeans as well as open API specifications for: database connectivity, naming and directory services, CORBA/IIOP interoperability, pure Java distributed computing, messaging services, managing system and network resources, and transaction services. Enterprise JavaBeans A cross-platform component architecture for the development and deployment of multi-tier, distributed, scalable, object-oriented Java applications. Enterprise ToolKit A set of VisualAge for Java Enterprise tools that enable you to develop Java code that is targeted to specific platforms, such as AS/400, OS/390, OS/2, AIX, and Windows. Entry Edition Edition.
See VisualAge for Java, Entry

E
EBCDIC. Extended binary coded decimal interchange code. An encoding scheme used to represent character data in the MVS, VM, VSE, and OS/400 environments. Contrast with ASCII. EAB
See Enterprise Access Builder.

e-business Either (a) the transaction of business over an electronic medium such as the Internet or (b) a business that uses Internet technologies and network computing in their internal business processes (via intranets), their business relationships (via extranets), and the buying and selling of goods, services, and information (via electronic commerce.) e-commerce The subset of e-business that involves the exchange of money for goods or services purchased over an electronic medium such as the Internet. EmbeddedJava An API and application environment for high-volume embedded devices, such as mobile phones, pagers, process control, instrumentation, office peripherals, network routers and network switches. EmbeddedJava applications run on real-time operating systems and are optimized for the constraints of small-memory footprints and diverse visual displays. embedded SQL. SQL statements coded within an application program. See static SQL.

equi-join. A join operation in which the join-condition has the form expression = expression. event An action by a user, program, or system that may trigger specific behavior. In the JDK, events notify the relevant listener classes to take appropriate action. environment. A collection of names of logical and physical resources that are used to support the performance of a function.

370

DB2 Java Stored Procedures: Learning by Example

environment handle. In DB2 ODBC, the data object that contains global information regarding the state of the application. An environment handle must be allocated before a connection handle can be allocated. Only one environment handle can be allocated per application. exception An exception is an object that has caused some sort of new condition, such as an error. In Java, throwing an exception means passing that object to an interested party; a signal indicates what kind of condition has taken place. Catching an exception means receiving the sent object. Handling this exception usually means taking care of the problem after receiving the object, although it might mean doing nothing (which would be bad programming practice). executable content Code that runs from within an HTML file (such as an applet). extends A subclass or interface extends a class or interface if it add fields or methods, or overrides its methods. See also derived type. external function. A function for which the body is written in a programming language that takes scalar argument values and produces a scalar result for each invocation. Contrast with sourced function and built-in function.

that uses TCP and Telnet services to transfer bulk-data files between machines or hosts.

foreign key. A key that is specified in the definition of a referential constraint. Because of the foreign key, the table is a dependent table. The key must have the same number of columns, with the same descriptions, as the primary key of the parent table. form data A generated class representing the HTML form elements in a visual servlet. formal parameter list Parameters specified in a method's definition. See also actual parameter list. FTP
See File Transfer Protocol .

full outer join. The result of a join operation that includes the matched rows of both tables being joined and preserves the unmatched rows of both tables. See also join. function. A specific purpose of an entity or its characteristic action such as a column function or scalar function. (See column function and scalar function.). Furthermore, functions can be user-defined, built-in, or generated by DB2. (See built-in function, cast function, user-defined function, external function, sourced function.)

F
factory A bean that dynamically creates instances of beans. field A data object in a class; for example, a variable. first tier The client; the hardware and software with which the end user interacts. framework A set of object classes that provide a collection of related functions for a user or piece of software. free-form surface In the VisualAge for Java Visual Composition Editor, the large, open area where you can work with visual and nonvisual beans. You add, remove, and connect beans on the free-form surface. File Transfer Protocol (FTP) In the Internet suite of protocols, an application layer protocol

G
garbage collection Java's ability to clean up inaccessible unused memory areas ("garbage") on the fly. Garbage collection slows performance, but keeps the machine from running out of memory. Graphical User Interface (GUI) A type of computer interface consisting of a visual metaphor of a real-world scene, often of a desktop. Within that scene are icons, representing actual objects, that the user can access and manipulate with a pointing device.

H
handle. In DB2 CLI, a variable that refers to a data structure and associated resources. See statement handle, connection handle, and environment handle.

371

hierarchy The order of inheritance in object-oriented languages. Each class in the hierarchy inherits attributes and behavior from its superclass, except for the top-level Object class. HotJava A Java-enabled Web and intranet browser developed by Sun Microsystems, Inc. HotJava is written in Java. (Definition copyright 1996-1999 Sun Microsystems, Inc. All Rights Reserved. Used by permission.) Hypertext Markup Language (HTML) A file format, based on SGML, for hypertext documents on the Internet. Allows for the embedding of images, sounds, video streams, form fields and simple text formatting. References to other objects are embedded using URLs, enabling readers to jump directly to the referenced document. Hypertext Transfer Protocol (HTTP) The Internet protocol, based on TCP/IP, used to fetch hypertext objects from remote hosts.

to exchange data with eSuite and other InfoBus-enabled applications. The 100% Pure Java release and the InfoBus specification are available for free download from: http://java.sun.com/beans/infobus

inheritance The ability to create a subclass that automatically inherits properties and methods from its superclass. See also hierarchy. initialization file. For DB2 ODBC applications, a file containing values that can be set to adjust the performance of the database manager. inner join. The result of a join operation that includes only the matched rows of both tables being joined. See also join. Inspector In VisualAge for Java, a window in which you can evaluate code fragments in the context of an object, look at the entire contents of an object and its class, or access and modify the fields of an object. instance The specific representation of a class, also called an object.

I
IDE
See Integrated Development Environment . The name of an item in a program.

identifier

instance method A method that applies and operates on objects (usually called simply a method). Contrast with class method . instance variable A variable that defines the attributes of an object. The class defines the instance variable's type and identifier, but the object sets and changes its values. Integrated Development Environment (IDE) In VisualAge for Java, the set of windows that provide the user with access to development tools. The primary windows are the Workbench, Log, Console, Debugger, and Repository Explorer. interface A list of methods that enables a class to implement the interface itself by using the implements keyword. The Interfaces page in the Workbench lists all interfaces in the workspace. Internet Protocol (IP) In the Internet suite of protocols, a connectionless protocol that routes data through a network or interconnected networks. IP acts as an intermediary between the higher protocol layers and the physical network. However, this protocol does not provide error

IDL (Interface Definition Language) In CORBA, a declarative language that is used to describe object interfaces, without regard to object implementation. IDL Development Environment In VisualAge for Java, an integrated IDL and Java development environment. The IDL Development Environment allows you to work with IDL source code in the multipane IDLs page and generate Java code using an IDL-to-Java compiler. IDL group A container used to hold IDL objects in the IDL Development Environment. It is similar to a file system directory. IIOP (Internet Inter-ORB Protocol) A communications standard for distributed objects that reside in Web or enterprise computing environments. InfoBus A technology for flexible, vendor-independent data exchange which is used by eSuite and can be used by other applications

372

DB2 Java Stored Procedures: Learning by Example

recovery and flow control and does not guarantee the reliability of the physical network.

Machine, Java Class Libraries, Java Applet Viewer, Java Debugger, and other tools.

Internet Inter-ORB Protocol (IIOP) Access Builder A tool that edits and generates CORBA-compliant Java modules. See Common Object Request Broker Architecture (CORBA). interpreter A tool that translates and executes code line-by-line. introspection For a JavaBean to be reusable in development environments, there needs to be a way to query what the bean can do in terms of the methods it supports and the types of event it raises and listens for. Introspection allows a builder tool to analyze how a bean works. IP
See Internet Protocol.

Java Foundation Classes (JFC) Developed by Netscape, Sun, and IBM, JFCs are building blocks that are helpful in developing interfaces to Java applications. They allow Java applications to interact more completely with the existing operating systems. Also called Swing Set. Java IDL Java IDL is a language-neutral way to specify an interface between an object and its client on a different platform. Provides interoperability and integration with CORBA, the industry standard for distributed computing, allowing developers to build Java applications that are integrated with heterogeneous business information assets. Java Management Application Programming Interface (JMAPI) A specification proposed by Sun Microsystems that defines a core set of application programming interfaces for developing tightly integrated system, network, and service management applications. The application programming interfaces could be used in diverse computing environments that encompass many operating systems, architectures, and network protocols. Java Media and Communications APIs Allows developers to integrate a wide range of media types into their Web pages, applets, and applications. Includes: Media, Sound, Animation, 2D, 3D, Telephony, Speech and Collaboration. Java Media Framework (JMF) Java Media Framework API specifies a unified architecture, messaging protocol and programming interface for media players, capture and conferencing. JMF provides a set of building blocks useful by other areas of the Java Media API suite. For example, the JMF provides access to audio devices in a cross-platform, device-independent manner, which is required by both the Java Telephony and the Java Speech APIs. JMF will be published as three APIs: the Java Media Player, Java Media Capture, and Java Media Conference. Java Naming and Directory Interface (JNDI) A set of APIs that assist with the interfacing to multiple naming and directory services.

J
JAE
See Java Application Environment.

JAR file format JAR (Java Archive) is a platform-independent file format that aggregates many files into one. Multiple Java applets and their requisite components (.class files, images, sounds and other resource files) can be bundled in a JAR file and subsequently downloaded to a browser in a single HTTP transaction. Java An object-oriented programming language for portable, interpretive code that supports interaction among remote objects. Java was developed and specified by Sun Microsystems, Incorporated. The Java environment consists of the JavaOS, the Virtual Machines for various platforms, the object-oriented Java programming language, and several class libraries. Java Application Environment (JAE) The source code release of the Java (TM) Development Kit. (Definition copyright 1996-1999 Sun Microsystems, Inc. All Rights Reserved. Used by permission.) Java Development Kit (JDK) The Java Development Kit is the set of Java technologies made available to licensed developers by Sun Microsystems. Each release of the JDK contains the following: the Java Compiler, Java Virtual

373

(Definition copyright 1996-1999 Sun Microsystems, Inc. All Rights Reserved. Used by permission.)

the server and administrative system resources required for developers to quickly develop their own Java servers.

Java Native Interface (JNI) A native programming interface that allows Java code running inside a Java Virtual Machine (VM) to interoperate with applications and libraries written in other programming languages, such as C and C++. Java Platform The Java Virtual Machine and the Java Core classes make up the Java Platform. The Java Platform provides a uniform programming interface to a 100%. Pure Java program regardless of the underlying operating system. (Definition copyright 1996-1999 Sun Microsystems, Inc. All Rights Reserved. Used by permission.) Java Record Editor An editor that allows you to construct and refine dynamic record types. Java Record Framework A Java framework that describes and converts record data. Java Remote Method Invocation (RMI) Java Remote Method Invocation is method invocation between peers, or between client and server, when applications at both ends of the invocation are written in Java. Included in JDK 1.1. Java Runtime Environment (JRE) A subset of the Java Development Kit for end-users and developers who want to redistribute the JRE. The JRE consists of the Java Virtual Machine, the Java Core Classes, and supporting files. (Definition copyright 1996-1999 Sun Microsystems, Inc. All Rights Reserved. Used by permission.) Java Security API A framework for developers to include security functionality in their applets and applications. Includes: cryptography with digital signatures, encryption, and authentication. An intermediate subset of the Security API known as "Security and Signed Applets" is included in JDK 1.1. Java Server An extensible framework that enables and eases the development of Java-powered Internet and intranet servers. The APIs provide uniform and consistent access to

Java Virtual Machine (JVM) A software implementation of a central processing unit (CPU) that runs compiled Java code (applets and applications). JavaBeans Java's component architecture, developed by Sun, IBM, and others. The components, called Java beans, can be parts of Java programs, or they can exist as self-contained applications. Java beans can be assembled to create complex applications, and they can run within other component architectures (such as ActiveX and OpenDoc). JavaDoc Sun's tool for generating HTML documentation on classes by extracting comments from the Java source code files. JDBC (Java Database Connectivity) In the JDK, the specification that defines an API that enables programs to access databases that comply with this standard. JavaObjs In Remote Method Invocation, the name of the user-defined default file that contains a list of server objects to be instantiated when the Remote Object Instance Manager is started. JavaOS A basic, small-footprint operating system that supports Java. Java OS was originally designed to run in small electronic devices like phones and TV remotes, but it is also being targeted for use in network computers (NCs). JavaScript A scripting language used within an HTML page. Superficially similar to Java but JavaScript scripts appear as text within the HTML page. Java applets, on the other hand, are programs written in the Java language and are called from within HTML pages or run as stand-alone applications. JFC JIT
See Java Foundation Classes. See Just-In-Time Compiler.

JMF See Java Media Framework. JNDI


See Java Naming and Directory Interface.

374

DB2 Java Stored Procedures: Learning by Example

JNI JRE

See Java Native Interface. See Java Runtime Environment.

Just-In-Time compiler (JIT) A platform-specific software compiler often contained within JVMs. JITs compile Java bytecodes on-the-fly into native machine instructions, thereby reducing the need for interpretation. JVM
See Java Virtual Machine.

local . Refers to any object maintained by the local DB2 subsystem. A local table, for example, is a table maintained by the local DB2 subsystem. Contrast with remote. local variable A variable declared and used within a method or block. Log In the VisualAge for Java IDE, the window that displays messages and warnings during development.

L
large object (LOB) . See LOB. left outer join. The result of a join operation that includes the matched rows of both tables being joined, and preserves the unmatched rows of the first table. See also join. link-edit. To create a loadable computer program using a linkage editor. linker A computer program for creating load modules from one or more object modules or load modules by resolving cross references among the modules and, if necessary, adjusting addresses. In Java, the linker creates an executable from compiled classes. listener In the JDK, a class that receives and handles events. load module. A program unit that is suitable for loading into main storage for execution. The output of a linkage editor. LOB. A sequence of bytes representing bit data, single-byte characters, double-byte characters, or a mixture of single and double-byte characters. A LOB can be up to 2GB -1 byte in length. See also BLOB, CLOB, and DBCLOB. LOB locator. A mechanism that allows an application program to manipulate a large object value in the database system. A LOB locator is a fullword integer value that represents a single LOB value. An application program retrieves a LOB locator into a host variable; it can then apply SQL operations to the associated LOB value using the locator.

M
member In the Java language, an item belonging to a class, such as a field or method. method A fragment of Java code within a class that can be invoked and passed a set of parameters to perform a specific task. middleware A layer of software that sits between a database client and a database server, making it easier for clients to connect to heterogeneous databases. middle tier The hardware and software that resides between the client and the enterprise server resources and data. The software includes a Web server that receives requests from the client and invokes Java servlets to process these requests. The client communicates with the Web server via industry standard protocols such as HTTP and IIOP. morphing The process of extending a Java bean to accept dips. Morphed Java beans are called dippable Java beans and can have one or more dips connected to them. Almost any Java bean or class can be made dippable. See dipping. multithreaded A program where different parts can run at the same time without interfering with each other. multithreading. Multiple TCBs executing one copy of DB2 ODBC code concurrently (sharing a processor) or in parallel (on separate central processors). mutex. Pthread mutual exclusion; a lock. A Pthread mutex variable is used as a locking mechanism to allow serialization of critical

375

sections of code by temporarily blocking the execution of all but one thread.

MVS/ESA. Multiple Virtual Storage/Enterprise Systems Architecture.

object The principal building block of object-oriented programs. Objects are software programming modules. Each object is a programming unit consisting of related data and methods. ODBC. See Open Database Connectivity. ODBC driver. A dynamically-linked library (DLL) that implements ODBC function calls and interacts with a data source. Open Database Connectivity (ODBC) . A Microsoft database application programming interface (API) for C that allows access to database management systems by using callable SQL. ODBC does not require the use of an SQL preprocessor. In addition, ODBC provides an architecture that lets users add modules called database drivers that link the application to their choice of database management systems at run time. This means that applications no longer need to be directly linked to the modules of all the database management systems that are supported. outer join. The result of a join operation that includes the matched rows of both tables being joined and preserves some or all of the unmatched rows of the tables being joined. See also join. ORB (Object Request Broker) In object-oriented programming, software that serves as an intermediary by transparently enabling objects to exchange requests and responses. object-oriented design A software design method that models the characteristics of abstract or real objects using classes and objects. Object-oriented design focuses on the data and on the interfaces to it. For instance, an "object-oriented" carpenter would be mostly concerned with the chair he was building, and secondarily with the tools used to make it; a "non-object-oriented" carpenter would think primarily of his tools. Object-oriented design is also the mechanism for defining how modules "plug and play." The object-oriented facilities of Java are essentially those of C++, with

N
native class Machine-dependent C code that can be invoked from Java. For multi-platform work, the native routines for each platform need to be implemented. NCF
See Network Computing Framework.

Network Computing Framework (NCF) An architecture and programming model created to help customer and industry software development teams to design, deploy, and manage e-business solutions across the enterprise. Network News Transfer Protocol (NNTP) In the Internet suite of protocols, a protocol for the distribution, inquiry, retrieval, and posting of news articles that are stored in a central database. nonvisual bean A bean that is not visible to the end user in the graphical user interface, but is visually represented on the free-form surface of the Visual Composition Editor during development. Developers can manipulate nonvisual beans only as icons; that is, they cannot edit them in the Visual Composition Editor as they can edit visual beans. Examples of nonvisual beans include beans for business logic, communication access, and database queries. NNTP
See Network News Transfer Protocol.

NUL. In C, a single character that denotes the end of the string. null. A special value that indicates the absence of information. NUL-terminated host variable. A varying-length host variable in which the end of the data is indicated by the presence of a NUL terminator. NUL terminator. In C, the value that indicates the end of a string. For character strings, the NUL terminator is X'00'.

376

DB2 Java Stored Procedures: Learning by Example

extensions from Objective C for more dynamic method resolution.

overloading The ability to have different methods with the same identifier, distinguished by their return type, and number and type of arguments. overriding Implementing a method in a subclass that replaces a method in a superclass.

prepared SQL statement. A named object that is the executable form of an SQL statement that has been processed by the PREPARE statement. primary key. A unique, nonnull key that is part of the definition of a table. A table cannot be defined as a parent unless it has a unique key or primary key. process A program executing in its own address space, containing one or more threads. Professional Edition Professional Edition.
See VisualAge for Java,

P
package A program element that contains classes and interfaces. part An existing, reusable software component. All parts created with the Visual Composition Editor conform to the JavaBeans component model, and are referred to as beans. See visual bean and nonvisual bean . persistence In object models, a condition that allows instances of classes to be stored externally, for example in a relational database. Persistence Builder In VisualAge for Java, a persistence framework for object models, which enables the mapping of objects to information stored in relational databases and also provides linkages to legacy data on other systems. plan. See application plan. plan name. The name of an application plan. POSIX. Portable Operating System Interface. The IEEE operating system interface standard which defines the Pthread standard of threading. See Pthread. precompilation. A processing of application programs containing SQL statements that takes place before compilation. SQL statements are replaced with statements that are recognized by the host language compiler. Output from this precompilation includes source code that can be submitted to the compiler and the database request module (DBRM) that is input to the bind process. prepare. The first phase of a two-phase commit process in which all participants are requested to prepare for commit.

program In VisualAge for Java, a term that refers to both Java applets and applications. program element In VisualAge for Java, a generic term for a project, package, class, interface, or method. project In VisualAge for Java, the topmost kind of program element. A project contains Java packages. property An initial setting or characteristic of a bean, for example, a name, font, text, or positional characteristic. Pthread. The POSIX threading standard model for splitting an application into subtasks. The Pthread standard includes functions for creating threads, terminating threads, synchronizing threads through locking, and other thread control facilities.

R
RDBMS. Relational database management system. relational database management system (RDBMS). A relational database manager that operates consistently across supported IBM systems. reentrant . Executable code that can reside in storage as one shared copy for all threads. Reentrant code is not self-modifying and provides separate storage areas for each thread. Reentrancy is a compiler and operating system concept, and reentrancy alone is not enough to guarantee logically consistent results when multithreading. See threadsafe.

377

reference An object's address. In Java, objects are passed by reference rather than by value or by pointers. remote. Refers to any object maintained by a remote DB2 subsystem; that is, by a DB2 subsystem other than the local one. A remote view, for instance, is a view maintained by a remote DB2 subsystem. Contrast with local. remote debugger A debugging tool that debugs code on a remote platform. Remote Function Call (RFC) SAP's open programmable interface. External applications and tools can call ABAB/4 functions from the SAP System. You can also call third party applications from the SAP System using RFC. RFC is a means for communication that allows implementation on all R/3 platforms. Remote Method Invocation (RMI) RMI is a specific instance of the more general term RPC. RMI allows objects to be distributed over the network; that is, a Java program running on one computer can call the methods of an object running on another computer. RMI and java.net are the only 100% pure Java APIs for controlling Java objects in remote systems. Remote Object Instance Manager In Remote Method Invocation, a program that creates and manages instances of server beans through their associated server-side server proxies. Remote Procedure Calls (RPC) RPC is a generic term referring to any of a series of protocols used to execute procedure calls or method calls across a network. RPC allows a program running on one computer to call the services of a program running on another computer. repository In VisualAge for Java, the permanent storage area containing all open and versioned editions of all program elements, regardless of whether they are currently in the workspace. The repository contains the source code for classes developed in (and provided with) VisualAge for Java, and the bytecode for classes imported from the file system. Every time you save a method in the IDE, it is automatically

updated in the repository. See also SCM repository and shared repository.

Repository Explorer In VisualAge for Java, the window from which you can view and compare editions of program elements that are in the repository. requester. Also application requester (AR). The source of a request to a remote RDBMS, the system that requests the data. resource file A non-code file that may be referred to from your Java program in VisualAge for Java. Examples include graphic and audio files. result set. The set of rows returned to a client application by a stored procedure. result set locator. A 4-byte value used by DB2 to uniquely identify a query result set returned by a stored procedure. result table. The set of rows specified by a SELECT statement. right outer join. The result of a join operation that includes the matched rows of both tables being joined and preserves the unmatched rows of the second join operand. See also join. RMI (Remote Method Invocation) Remote Method Invocation.
See

RMI Access Builder A VisualAge for Java Enterprise tool that generates proxy beans and associated classes and interfaces so you can distribute code for remote access, enabling Java-to-Java solutions. RMI compiler The compiler that generates stub and skeleton files that facilitate RMI communication. This compiler can be automatically invoked by the RMI Access Builder, and can also be invoked from the Tools menu item. RMI registry A server program that allows remote clients to get a reference to a server bean. rollback . The process of restoring data changed by SQL statements to the state at its last commit point. All locks are freed. Contrast with commit.

378

DB2 Java Stored Procedures: Learning by Example

RPC

See Remote Procedure Calls.

runtime system The software environment where compiled programs run. Each Java runtime system includes an implementation of the Java Virtual Machine.

serialization Turning an object into a stream, and back again. server The computer that hosts the Web page that contains an applet. The .class files that make up the applet, and the HTML files that reference the applet reside on the server. When someone on the Internet connects to a Web page that contains an applet, the server delivers the .class files over the Internet to the client that made the request. The server is also known as the originating host. server bean The bean that is distributed using RMI services and is deployed on a server. servlet Server-side programs that execute on and add function to Web servers. Java servlets allow for the creation of complicated, high-performance, cross-platform Web applications. They are highly extensible and flexible, making it easy to expand from client or single-server applications to multi-tier applications. SGML See Standardized Generalized Markup Language. single precision A floating-point number that contains 32 bits. See also double precision. SmartGuide In IBM software products, an active form of help that guides you through common tasks. Software Configuration Management (SCM) The tracking and control of software development. SCM tools typically offer version control and team programming features. sourced function. A function that is implemented by another built-in or user-defined function already known to the database manager. This function can be a scalar function or a column (aggregating) function; it returns a single value from a set of values (for example, MAX or AVG). Contrast with external function and built-in function. source type. An existing type that is used to internally represent a distinct type.

S
sandbox A restricted environment, provided by the Web browser, in which Java applets run. The sandbox offers them services and prevents them from doing anything naughty, such as doing file I/O or talking to strangers (servers other than the one from which the applet was loaded). The analogy of applets to children led to calling the environment in which they run the "sandbox." scalar function. An SQL operation that produces a single value from another value and is expressed as a function name followed by a list of arguments enclosed in parentheses. See also column function. SCM
See Software Configuration Management.

SCM repository In VisualAge for Java, a generic term for the data store of any external software configuration management (SCM) tool. Some SCM tools refer to this as an archive. scope Determines where an identifier can be used. In Java, instance and class variables have a scope that extends to the entire class. All other identifiers are local to the method where they are declared. Scrapbook In VisualAge for Java, the window from which you can write, edit, and test fragments of code without having to define an encompassing class or method. Secure Socket Layer (SSL) SSL is a security protocol which allows communications between a browser and a server to be encrypted and secure. SSL prevents eavesdropping, tampering or message forgery on your Internet or intranet network. security Features in Java that prevent applets downloaded off the Web from deliberately or inadvertantly doing damage. One such feature is the digital signature, which ensures that an applet came unmodified from a reputable source.

379

SQL Structured Query Language. A language used by database engines and servers for data acquisition and definition. SQL authorization ID (SQL ID). The authorization ID that is used for checking dynamic SQL statements in some situations. SQL Communication Area (SQLCA). A structure
used to provide an application program with information about the execution of its SQL statements.

stored procedure. A user-written application program, that can be invoked through the use of the SQL CALL statement. stream A communication path between a source of information and its destination. Structured Query Language (SQL) . A standardized language for defining and manipulating data in a relational database. subclass A class that inherits all the methods and variables of another class (its superclass). Its superclass might be a subclass of another class in the hierarchy. subtype A type that extends another type (its supertype ). superclass A class that defines the methods and variables inherited by another class (its subclass). supertype A type that is extended by another type (its subtype). Swing Set A group of lightweight, ready-to-use components developed by JavaSoft. The components range from simple buttons to full-featured text areas to tree views and tabbed folders. synchronized This Java keyword specifies that only one thread can run inside a method at once.

SQL Descriptor Area (SQLDA). A structure that describes input variables, output variables, or the columns of a result table. SQLCA. SQL communication area. SQLDA. SQL descriptor area. SQL/DS. SQL/Data System. Also known as DB2 for VSE & VM. SSL
See secure socket layer.

Standardized Generalized Markup Language An ISO/ANSI/ECMA standard that specifies a way to annotate text documents with information about types of sections of a document. statement handle. In DB2 ODBC, the data object that contains information about an SQL statement that is managed by DB2 CLI. This includes information such as dynamic arguments, bindings for dynamic arguments and columns, cursor information, result values and status information. Each statement handle is associated with the connection handle. static field
See class variable. See class method.

T
table. A named data object consisting of a specific number of columns and some number of unordered rows. Synonymous with base table or temporary table. task control block (TCB). A control block used to communicate information about tasks within an address space that are connected to DB2. An address space can support many task connections (as many as one per task), but only one address space connection. See address space connection. TCB. MVS task control block. TCP/IP See Transmission Control Protocol based on IP.

static method

static SQL. SQL statements, embedded within a program, that are prepared during the program preparation process (before the program is executed). After being prepared, the SQL statement does not change (although values of host variables specified by the statement might change).

380

DB2 Java Stored Procedures: Learning by Example

temporary table. A table created by the SQL CREATE GLOBAL TEMPORARY TABLE statement that is used to hold temporary data. Contrast with result table. thin client Thin client usually refers to a system that runs on a resource-constrained machine or that runs a small operating system. Thin clients don't require local system administration, and they execute Java applications delivered over the network. third tier The third tier, or back end, is the hardware and software that provides database and transactional services. These back-end services are accessed through connectors between the middle-tier Web server and the third-tier server. Though this conceptual model depicts the second and third tier as two separate machines, the NCF model supports a logical three-tier implementation in which the software on the middle and third tier are on the same box. thread A separate flow of control within a program. threadsafe. Characteristic of code that allows multithreading both by providing private storage areas for each thread, and by properly serializing shared (global) storage areas. timestamp. A seven-part value that consists of a date and time expressed in years, months, days, hours, minutes, seconds, and microseconds. trace. A DB2 facility that provides the ability to monitor and collect DB2 monitoring, auditing, performance, accounting, statistics, and serviceability (global) data. transaction (1) In a CICS program, an event that queries or modifies a database that resides on a CICS server. (2) In the Persistence Builder, a representation of a path of code execution. (3) The code activity necessary to manipulate a persistent object. For example, a bank application might have a transaction that updates a company account. transient This Java keyword specifies that a field is not included in the serial representation of an object. See serialization .

Transmission Control Protocol based on IP (1) A network communication protocol used by computer systems to exchange information across telecommunication links. (2) An Internet protocol that provides for the reliable delivery of streams of data from one host to another. type In VisualAge for Java, a generic term for a class or interface.

U
UDF. User-defined function UDT. User-defined data type Uniform Resource Locator (URL) The unique address that tells a browser how to find a specific Web page or file. Unicode A 16-bit international character set defined by ISO 10646. See also ASCII. user-defined data type (UDT) . See distinct type. user-defined function (UDF). A function defined to DB2 using the CREATE FUNCTION statement that can be referenced thereafter in SQL statements. A user-defined function can be either an external function or a sourced function. Contrast with built-in function. URL
See Uniform Resource Locator.

V
variable (1) An identifier that represents a data item whose value can be changed while the program is running. The values of a variable are restricted to a certain data type. (2)A data element that specifies a value that can be changed. A COBOL elementary data item is an example of a variable. Contrast with constant. virtual machine A software or hardware implementation of a central processing unit (CPU) that manages the resources of a machine and can run compiled code. See Java Virtual Machine . visual bean In the Visual Composition Editor, a bean that is visible to the end user in the graphical user interface.

381

Visual Composition Editor In VisualAge for Java, the tool you can use to create graphical user interfaces from prefabricated beans, and to define relationships (called connections) between beans. The Visual Composition Editor is a page in the class browser. visual servlet A servlet that is designed to be built using the VisualAge for Java Visual Composition Editor. VisualAge for Java, Enterprise Edition An edition of VisualAge for Java that is designed for building enterprise Java applications, and has all of the Professional Edition features plus support for developers working in large teams, developing high-performance or heterogeneous applications, or needing to connect Java programs to existing enterprise systems. VisualAge for Java, Entry Edition An edition of VisualAge for Java suitable for learning and building small projects of 500 classes or less. It is available as a no-charge download from VisualAge for Java and VisualAge Developer Domain Web sites. VisualAge for Java, Professional Edition complete Java development environment, including easy access to JDBC-enabled databases for building Java applications.
A

Workbench In VisualAge for Java, the main window from which you can manage the workspace, create and modify code, and open browsers and other tools. workspace The work area that contains the Java code that you are developing and the class libraries on which your code depends. Program elements must be added to the workspace from the repository before they can be modified. wrapper Code that provides an interface for one program to access the functionality of another program. WWW
See World Wide Web.

X
X/Open. An independent, worldwide open systems organization that is supported by most of the world's largest information systems suppliers, user organizations, and software companies. X/Open's goal is to increase the portability of applications by combining existing and emerging standards. 100% Pure Java Sun Microsystems initiative to certify that applications and applets are purely Java-written.

W
WebSphere WebSphere is the cornerstone of IBM's overall Web strategy, offering customers a comprehensive solution to build, deploy and manage e-business Web sites. The product line provides companies with an open, standards-based, Web server deployment platform and Web site development and management tools to help accelerate the process of moving to e-business. world readable files A permission level on Web servers specifying that files can be read by any user. World Wide Web A network of servers that contain programs and files. Many of the files contain hypertext links to other documents available through the network.

382

DB2 Java Stored Procedures: Learning by Example

Abbreviations and acronyms


ACEE AER AIX APAR APF API APPC
access control environment application execution region Advanced Interactive eXecutive from IBM authorized program analysis report authorized program facility (MVS) application program interface advanced program-to-program communication application requester automatic restart manager application server American National Standard Code for Information Interchange binary large objects

CFRM CLI CLP CPU CSA DASD DB2 PM DBAT DBCTL DBD DBID DBRM DCL DDCS DDF DDL DLL DML DNS DRA DRDA DTT

coupling facility resource management call level interface command line processor central processing unit common storage area direct access storage device DB2 performance monitor database access thread database control subsystem database descriptor database identifier database request module data control language distributed database connection services distributed data facility data definition language dynamic load library manipulation language data manipulation language domain name server

AR ARM AS ASCII

BLOB CCSID CCA CFCC CGI CTT CEC CD CF

coded character set identifier


client configuration assistant coupling facility control code common gateway interface created temporary table central electronics complex compact disk coupling facility

database resource adapter


distributed relational database architecture declared temporary tables

Copyright IBM Corp. 2000

383

EA EBCDIC

extended addressability extended binary coded decimal interchange code enhanced catalog sharing extended common storage area environment descriptor management enterprise resource planning Enterprise Systems Architecture external CICS interface functional track directory File Transfer Program gigabyte (1,073,741,824 bytes) group buffer pool global resource serialization graphical user interface high performance Java or the high performance Java compiler International Business Machines Corporation integrated catalog facility integrated coupling facility internal coupling migration facility instrumentation facility component identifier instrumentation facility interface internal resource lock manager

ISPF ISV I/O ITSO IVP JDBC JFS JVM KB LPAR LOB LPL LRSN LVM MB MQ MQA MQI OBD ODBC OS/390 PAV PDS PSID PSP

interactive system productivity facility independent software vendor input/output International Technical Support Organization installation verification process Java Database Connectivity journaled file systems Java Virtual Machine kilobyte (1,024 bytes) logically partitioned mode large object logical page list log record sequence number logical volume manager megabyte (1,048,576 bytes) message and queueing (IBM software) message queue agent message queue interface object descriptor in DBD Open Data Base Connectivity Operating System/390 parallel access volume partioned data set pageset identifier preventive service planning

ECS ECSA EDM ERP ESA EXCI FDT FTP GB GBP GRS GUI HPJ

IBM ICF ICF ICMF IFCID IFI IRLM

384

DB2 Java Stored Procedures: Learning by Example

PTF PUNC QMF RACF RBA RID RRS RRSAF RS RR SDK SMIT SNA SP SRB STC TCB WLM

program temporary fix possibly uncommitted Query Management Facility Resource Access Control Facility relative byte address record identifier resource recovery services resource recovery services attach facility read stability repeatable read software developers kit System Management Interface Tool systems network architecture stored procedure system resource block started task task control block workload manager

385

386

DB2 Java Stored Procedures: Learning by Example

Index Symbols
"CALL" is not a valid database alias name 115 .class files 149 .jar file 150 .java file 149 .profile 59, 63, 64, 72, 80, 81, 170 DB2SQLJPROPERTIES 71 .ser files 149 EBCDIC 162 USS 162 COLLID 123, 126, 131, 168 COMMENT ON 197 COMMENT ON PROCEDURE 269 COMMIT ON RETURN 262, 274 CONNECT statement 187, 193 savepoint 209 connection pooling DDF 202 CREATE PROCEDURE 123, 181, 257 schema 269 CREATE TRIGGER 226 CURRENT PATH 181, 234, 237, 238, 239, 240 schema 236 CURRENT SERVER 192 CURRENT SQLID 233 customize 119

A
AIX JDBC program preparation 144 SQLJ program preparation 149 ALLOCATE CURSOR 193, 194 ALTER INDEX 183 ALTER PROCEDURE 182 ALTER TABLESPACE 183 ASSOCIATE LOCATORS 193 authorization client application 174 hopping 197 Java stored procedures 120 JDBC client 174 authorization checking 121

D
data propagation identity columns 229 data set passwords 181 Data sharing 73 data sharing identity columns 230 DB2 data set passwords 181 JDBC programs 7 package 89 schema 233 shared read-only data 181 SQLJ programs 8 type 1 indexe 181 type 2 indexes 181 DB2 Connect 106 DB2 package 119, 167 DB2 plan 167 DB2 Stored Procedure Builder 105 DB2 utilities identity columns 218 db2jdbc.cursors 71 db2profc 9, 79, 130, 133, 150, 160, 167 db2profile 80, 81 DB2SQLJATTACHTYPE 72 DB2SQLJDBRMLIB 73 DB2SQLJJDBCPROGRAM 72

B
BEGIN ATOMIC 226 Bind DBPROTOCOL option 193 PATH option 181, 240

C
CALL statement 171 Cannot call a schema-qualified stored procedure 118 CATMAINT 111 catmaint 183 class files 133 Class Not Found at runtime 106 Class.forName 162 CLASSPATH 60, 61, 65, 70, 80, 81, 143 COBOL 23, 172 Code translation 162 ASCII 162

Copyright IBM Corp. 2000

387

DB2SQLJPLANNAME 72, 167 DB2SQLJPROPERTIES 61, 64, 71, 167, 170 DB2SQLJSSID 72 DBPROTOCOL bind option 193 DBRM 119, 133, 167 DDF connection pooling 202 DRDA enhancements 197 MODE(SUSPEND) 203 debugging SPB 104 stored procedures 103 writing to a text file 104 DESCRIBE CURSOR 193, 194 DESCRIBE PROCEDURE 193 DISPLAY PROCEDURE command 280 DRDA 187 DDF enhancements 197 hopping 195 Loop back 195 OPTIMIZE FOR n ROWS 198 query block size 198 savepoint 209 SNA connections 188 stored procedures 243 TCP/IP connections 188 Three-part name 189 DROP PROCEDURE 151 DYNAMICRULES 120, 121 DYNAMICRULES(DEFINEBIND) JDBC 121 DYNAMICRULES(INVOKERUN) JDBC 122

E
Enterprise Toolkit for OS/390 4, 58 ENVAR 71 error message SQLCODE -965 77 error messages DB2 RC 00E79107 76, 77 00E79108 77 HPJ HPJ3115(S) 76, 106 Out of storage -- HPJ compile JDBC and

SQLJ classes 76 Unable to load HPJ module during HPJ compile 76 Java Class Not Found at runtime 106 JAR files - removing, refreshing 146 JNI panic during db2profc 118 Method Not Found at runtime 107 Path or file name "Java" not found 79 SQL20201N 114 Unable to find user class 76 Unable to find user method 77 Other Cannot call a schema-qualified stored procedure 118 other CEE5207E 77 DSNL065I 285 DSNL066I 285 DSNL067I 285 DSNL068 285 DSNL069I 285 DSNL070I 286 DSNL071I 286 DSNL072 286 DSNL073I 286 ICH408I 77 SQLCODE +585 239 -104 107 -113 108, 111 -151 218 -204 110 -390 111 -426 255 -440 108, 270, 272 -471 77, 117 -487 264 -577 264 -579 264 -585 239 -586 240 -713 239 -728 188 -729 274 -751 264 -805 191 -818 115 -950 111

388

DB2 Java Stored Procedures: Learning by Example

-965 78, 116 SQL10013N The specified library could not be loaded 113 SQL20201N JAR name is invalid during sqlj.install_jar 114 SQL4301N Java interpreter start-up 112 SQL4304N 116 SQLSTATE 01625 239 42602 108, 111 42705 111 42732 239 42808 218 42815 239 42907 240 51021 116 55023 117 executable-centric migration 159, 161 external savepoint 209

I
identity columns 210, 211 altering 215 copying tables 216 data definition 211 data manipulation 217 data propagation 229 data sharing 230 DB2 family 230 DB2 utilities 218 Indexing 222 properties 220 retrieving values 222 ROWID columns 228 IDENTITY_VAL_LOCAL 224, 225 INCREMENT BY 229 installVAJDLLs 68 Iterator SQLJ 100

F
Fallback Version 6 to Version 5 184

G
GENERATED ALWAYS 217 getConnection method 170 global transactions savepoint 210

H
HOME path 61, 73, 77 Home path 74 Hopping authorization 197 DRDA and pivate protocol 195 Loop back 195 host variables 181 HPJ 58, 62, 68, 70, 74, 93, 96 base libraries 60 dynamic load library 70 JDBC/SQLJ drivers 57 HPJ3115(S) message received during HPJ compile 106 HPJ3TBY 76

JAR file 146, 147, 148, 150, 151, 153, 154, 155 JAR routines sqlj.install_jar 146, 155 sqlj.remove_jar 146 sqlj.replace_jar 155 Java classes 4 CLASSPATH 4 JAR file 4, 88 methods 4 package 4, 86, 91, 93, 95, 96 Java Development Kit 4 Java method 86 Java package statement 124, 131 Java stored procedures case sensitive 92 data sharing 73 DB2 portability 24 deployment 157 execution OS/390 163 UNIX 163 Windows NT 163 LOBs 90 migrating between environments on S/390 157 naming 83

389

output parameters 90 parameters 90 preparation 119 system setup 76 OS/390 57 UNIX 80 Windows NT 78 Java stored procedures, compiled 57 JAVA_HOME 65, 80, 81 javac command 149 JAVAENV data set 57, 60, 62, 63, 69 contents 70 JDBC 7, 23, 120, 172 client call stored procedure 173 create SQL string 172 input parameters 173 output parameters 173 client applications 167 client authorization 174 client coding 170 cursors file 71 dynamic load libraries 70 DYNAMICRULES(DEFINEBIND) 121 DYNAMICRULES(INVOKEBIND) 122 insenting a null 99 migration 160 program preparation 122 OS/390 124 serialized profile 61 stored procedures 119 null handling 97 JDBC DBRM DSNJDBC1 76 DSNJDBC2 76 DSNJDBC3 76 DSNJDBC4 76 JDBC driver 11 JDK 57, 78, 79, 80, 123 JNI panic during db2profc 118 JSPDEBUG 67, 104 JVM 3, 5, 119

location name 170

M
Method Not Found at runtime 107 migration executable-centric 159 source-centric 158 MODE(SUSPEND) Command syntax 204 DDF 203

N
nested stored procedures 274 COMMIT ON RETURN 274 three-part name 275 NT JDBC program preparation 144 SQLJ program preparation 149 Null handling JDBC inserting 99 JDBC stored procedures 97 null values 97

O
ODBC 19 OPTIMIZE FOR n ROWS 197 OS/390 High Performance Java Compiler 5 OS/390 UNIX System Services 4, 143

P
PATH bind option 181, 240 PATH system variable 79 PDSE 62, 66, 124, 133 porting stored procedutes UNIX/NT and S/390 161 prepareCall 173 printStackTrace 102 private protocol hopping 195 SNA connections 188 program preparation JDBC 122 SQLJ 129

L
LABEL ON 197 LD_LIBRARY_PATH 65, 69, 70, 80, 81 LIBPATH 60, 65, 69, 70, 80, 81

390

DB2 Java Stored Procedures: Learning by Example

Q
Query_oi_summ 34

RACF 66, 329, 330, 335 PERMIT command 335 profiles 335 RDEFINE command 335 RACF user IDs stored procedures 335 RELEASE SAVEPOINT 208 ResultSet SQLJ 100 ROLLBACK TO SAVEPOINT 209 ROWID columns identity columns 228 RRS 57, 58, 59, 66

S
sample application 19 components 21 naming conventions 22 package names 22 savepoint 208 DRDA access 209 global transactions 210 roll back 209 stored procedures 210 triggers 210 UDFs 210 UNIQUE option 208 schema 125 characteristics 234 CURRENT PATH 236 DB2 support 233 explicit specification 234 implicit specification 235 SET CURRENT PATH 237 SYSFUN 237 SYSIBM 237 SYSPROC 237 Serialized profiles directory 61 SET CONNECTION 192, 193 SET CURRENT PATH 240 SET CURRENT SQLID 121 setNull 97 shared read-only dat 181 SNA connections

DRDA 188 private protocol 188 source-centric migration 158, 161 SPB 105 SQL string 172 preparation 173 SQL10013N 113 SQL4301N 112 SQL4304N 116 SQLJ 8, 23, 120, 174 client application 100 client applications 167 client coding 174 command 132 dynamic load libraries 70 Iterators 100 migration 160 program preparation OS/390 129 ResultSets 100 serialized profile 149 stored procedures 119, 160 authorization 120 error handling 102 inserting a null 100 receiving a null 100 SQLJ properties 57, 60, 61, 70, 71, 72 sqlj.install_jar 145, 146, 148, 151, 153, 155, 161 sqlj.remove_jar 146, 151, 153, 155 sqlj.replace_jar 148, 155 SQLJ/JDBC base libraries 60 SQLJPLAN 167, 170 -START DATABASE 183 START WITH 229 -STOP DATABASE 183 stored procedure 12 Stored Procedure Builder 164 stored procedures authorization 258, 275 calling with a null value 97 COMMIT_ON_RETURN 254 CONNECT statement 246, 248, 249 , 258 CONNECT TYPE 1 248, 249 CONNECT TYPE 2 248 debugging 103 DLI support 255 DML 258 LOBs 259

391

nested 274 parameters 97, 262 privileges 268 result sets 251, 252, 253 savepoint 210 SQL CALL 246 time line characteristics 247 triggers 259 UDFs 258 UDTs 259 usage of schemas 258, 268 SYSCAT.PROCEDURES 182 SYSIBM.SYSCOLDIST 183 SYSIBM.SYSCOLDISTSTATS 183 SYSIBM.SYSJARCONTENTS 145, 150 SYSIBM.SYSPARMS 181, 182, 257 , 267, 281 SYSIBM.SYSPROCEDURES 96, 123, 125, 181, 182, 250, 251, 257, 267, 270, 281, 335 SYSIBM.SYSROUTINES 96, 181, 182, 257, 267, 281 SYSIBM.SYSSEQUENCES 221 SYSIBM.SYSSEQUENCESDEP 221

compatibility mode 338, 345 enable stored procedure support 331 goal mode 339, 345 Java stored procedures 66 JAVAENV data set 67 RACF 335 recommendations 344 service definition 342 service policy 342

T
TCP/IP connections DRDA 188 Three-part name DRDA 189 Package requirements 191 trigger savepoint 210 type 1 indexes 181 type 2 indexes 181

U
UNIQUE OPTION savepoint 208 UNIX Systems Services 57

V
VisuaAge for Java Enterprise Edition 58 VisualAge for Java 4, 8 Enterprise Edition for OS/390 119

W
wasNull 99 WLM 58, 59, 66, 163

392

DB2 Java Stored Procedures: Learning by Example

IBM Redbooks review


Your feedback is valued by the Redbook authors. In particular we are interested in situations where a Redbook "made the difference" in a task or problem you encountered. Using one of the following methods, please review the Redbook, addressing value, subject matter, structure, depth and quality as appropriate. Use the online Contact us review redbook form found at ibm.com/redbooks Fax this form to: USA International Access Code + 1 914 432 8264 Send your comments in an Internet note to redbook@us.ibm.com

Document Number Redbook Title Review

SG24-5945-00 DB2 Java Stored Procedures: Learning by Example

What other subjects would you like to see IBM Redbooks address?

Please rate your overall satisfaction: Please identify yourself as belonging to one of the following groups: Your email address: The data you provide here may be used to provide you with information from IBM or our business partners about our products, services or activities. Questions about IBMs privacy policy?

O Very Good

O Good

O Average

O Poor O Solution Developer

O Customer O Business Partner O IBM, Lotus or Tivoli Employee O None of the above

O Please do not use the information collected here for future marketing or promotional contacts or other communications beyond the scope of this transaction.

The following link explains how we protect your personal information. ibm.com/privacy/yourprivacy/

Copyright IBM Corp. 2000

393

DB2 Java Stored Procedures: Learning by Example

(0.5 spine) 0.475<->0.875 250 <-> 459 pages

DB2 Java Stored Procedures


Learning by Example

Implementation guide for DB2 Java stored procedures DB2 Java stored procedures across platforms Reference guide for network computing enhancements in DB2 UDB for OS/390 V6

Stored procedures can provide major benefits in the areas of application performance, code re-use, security, and integrity. The DB2 Family of products has offered support for stored procedures for some time, with each release offering significant enhancements over the last. In the meantime, Javas inherent portability and openness, combined with the availability of skilled programming resource, has made it an increasingly attractive choice as the central plank in the e-business strategy of many organizations. Until recently, DB2 did not support stored procedures written in Java, so the advantages of the two technologies could not be combined. The latest releases of DB2 have changed all that, opening up new possibilities for secure, highly portable application development. This IBM Redbook aims to give the reader an in-depth understanding of the techniques and issues associated with the development of DB2 stored procedures written in SQLJ and JDBC. The extensive collection of sample code presented in this book and included on the accompanying CD-ROM was designed to run against DB2 UDB Server across the OS/390, Windows, and UNIX platforms.

INTERNATIONAL TECHNICAL SUPPORT ORGANIZATION

BUILDING TECHNICAL INFORMATION BASED ON PRACTICAL EXPERIENCE IBM Redbooks are developed by the IBM International Technical Support Organization. Experts from IBM, Customers and Partners from around the world create timely technical information based on realistic scenarios. Specific recommendations are provided to help you implement IT solutions more effectively in your environment.

For more information: ibm.com/redbooks


SG24-5945-00 ISBN 0738418773

Você também pode gostar