Download as pdf or txt
Download as pdf or txt
You are on page 1of 906

AS/400e

DB2 UDB for AS/400 SQL Programming


V ersion 4

RBAF-Y000-00

AS/400e

DB2 UDB for AS/400 SQL Programming


V ersion 4

RBAF-Y000-00

Copyright International Business Machines Corporation 1997, 1999. 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
About DB2 UDB for AS/400 SQL Programming. . . . Who should read this book . . . . . . . . . . . . Assumptions Relating to Examples of SQL Statements . How to Interpret Syntax Diagrams in this Guide . . . AS/400 Operations Navigator . . . . . . . . . . . Installing Operations Navigator. . . . . . . . . . How this book has changed . . . . . . . . . . . . Prerequisite and related information . . . . . . . . . How to send your comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii xvii xvii xviii xix xx xxi xxi xxi

Chapter 1. Introduction to DB2 UDB for AS/400 Structured Language . . . . . . . . . . . . . . . . . . SQL Concepts . . . . . . . . . . . . . . . . . . Relational Database and Terminology . . . . . . . . Types of SQL Statements . . . . . . . . . . . . SQL Objects . . . . . . . . . . . . . . . . . . Collections . . . . . . . . . . . . . . . . . . Tables, Rows, and Columns. . . . . . . . . . . . Aliases . . . . . . . . . . . . . . . . . . . Views . . . . . . . . . . . . . . . . . . . . Indexes . . . . . . . . . . . . . . . . . . . Constraints . . . . . . . . . . . . . . . . . . Triggers . . . . . . . . . . . . . . . . . . . Stored Procedures . . . . . . . . . . . . . . . User-dened functions . . . . . . . . . . . . . . Packages . . . . . . . . . . . . . . . . . . Application Program Objects . . . . . . . . . . . . User Source File Member . . . . . . . . . . . . Output Source File Member . . . . . . . . . . . . Program . . . . . . . . . . . . . . . . . . . Package . . . . . . . . . . . . . . . . . . . Module . . . . . . . . . . . . . . . . . . . Service Program . . . . . . . . . . . . . . . .

Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

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

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

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

. 1 . 1 . 3 . 4 . 5 . 6 . 6 . 7 . 7 . 8 . 8 . 8 . 9 . 9 . 9 . 9 . 11 . 11 . 11 . 12 . 12 . 12 . . . . . . . . . . . . . . . . . . . 13 13 13 13 14 14 16 16 18 18 20 23 25 25 28 28 28 29 30

Chapter 2. Getting Started with SQL . . . . . . . . . . . . . Starting Interactive SQL . . . . . . . . . . . . . . . . . . Creating an SQL Collection . . . . . . . . . . . . . . . . . Example: Creating the SQL Collection (SAMPLECOLL) . . . . . Creating and Using a Table . . . . . . . . . . . . . . . . . Example: Creating a Table (INVENTORY_LIST) . . . . . . . . Creating the Supplier Table (SUPPLIERS) . . . . . . . . . . Using the LABEL ON Statement . . . . . . . . . . . . . . . Inserting Information into a Table . . . . . . . . . . . . . . . Example: Inserting Information into a Table (INVENTORY_LIST) . . Getting Information from a Single Table . . . . . . . . . . . . Getting Information from More Than One Table. . . . . . . . . . Changing Information in a Table . . . . . . . . . . . . . . . Example: Changing Information in a Table . . . . . . . . . . Deleting Information from a Table. . . . . . . . . . . . . . . Example: Deleting Information from a Table (INVENTORY_LIST) . . Creating and Using a View . . . . . . . . . . . . . . . . . Example: Creating a view on a single table . . . . . . . . . . Example: Creating a view combining data from more than one table .
Copyright IBM Corp. 1997, 1999

iii

Chapter 3. Basic Concepts and Techniques . . . . . . . Using Basic SQL Statements and Clauses . . . . . . . . The INSERT Statement . . . . . . . . . . . . . . The UPDATE Statement . . . . . . . . . . . . . . The DELETE Statement . . . . . . . . . . . . . . The SELECT INTO Statement . . . . . . . . . . . . Data retrieval errors. . . . . . . . . . . . . . . . The SELECT Clause . . . . . . . . . . . . . . . The WHERE Clause . . . . . . . . . . . . . . . The GROUP BY Clause . . . . . . . . . . . . . . The HAVING Clause . . . . . . . . . . . . . . . The ORDER BY Clause . . . . . . . . . . . . . . Using Null Values . . . . . . . . . . . . . . . . . Using Special Registers . . . . . . . . . . . . . . . Using Date, Time, and Timestamp . . . . . . . . . . . Specifying Current Date and Time Values. . . . . . . . Date/Time Arithmetic . . . . . . . . . . . . . . . Creating and using ALIAS names. . . . . . . . . . . . Using LABEL ON. . . . . . . . . . . . . . . . . . Using COMMENT ON . . . . . . . . . . . . . . . . Getting Comments . . . . . . . . . . . . . . . . Using Sort Sequence in SQL . . . . . . . . . . . . . Sort Sequence Used with ORDER BY and Record Selection ORDER BY . . . . . . . . . . . . . . . . . . . Record selection . . . . . . . . . . . . . . . . . Sort Sequence and Views . . . . . . . . . . . . . Sort Sequence and the CREATE INDEX Statement . . . . Sort Sequence and Constraints . . . . . . . . . . . Chapter 4. Using a Cursor . . . . . . . . . . . . . Types of cursors . . . . . . . . . . . . . . . . . Serial cursor . . . . . . . . . . . . . . . . . Scrollable cursor . . . . . . . . . . . . . . . . Example of Using a Cursor . . . . . . . . . . . . . Step 1: Dene the Cursor . . . . . . . . . . . . Step 2: Open the Cursor . . . . . . . . . . . . . Step 3: Specify What to Do When End-of-Data Is Reached Step 4: Retrieve a Row Using a Cursor . . . . . . . Step 5a: Update the Current Row . . . . . . . . . Step 5b: Delete the Current Row . . . . . . . . . . Step 6: Close the Cursor . . . . . . . . . . . . . Using the Multiple-Row FETCH Statement . . . . . . . Multiple-Row FETCH Using a Host Structure Array . . . Multiple-Row FETCH Using a Row Storage Area . . . . Unit of Work and Open Cursors . . . . . . . . . . . Chapter 5. Advanced Coding Techniques . . . . . Advanced Insert Techniques . . . . . . . . . . Inserting Rows into a Table Using a Select-Statement Using the Blocked Insert Statement . . . . . . . Advanced Update Techniques . . . . . . . . . . Preventing Duplicate Rows . . . . . . . . . . . Performing Complex Search Conditions . . . . . . Keywords for Use in Search Conditions . . . . . Joining Data from More Than One Table . . . . . . Inner Join . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

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

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

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

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

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

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

31 31 31 33 34 35 36 38 38 40 42 43 45 45 47 47 47 48 48 49 50 50 50 51 52 53 53 54 55 55 55 55 56 58 59 59 60 61 61 62 62 63 64 68 69 69 69 70 70 71 72 72 75 75

iv

DB2 UDB for AS/400 SQL Programming V4R4

Left Outer Join . . . . . . . . . . . . . . . Exception Join. . . . . . . . . . . . . . . . Cross Join . . . . . . . . . . . . . . . . . Using multiple join types in one statement . . . . . Notes on Joins . . . . . . . . . . . . . . . Using Table Expressions . . . . . . . . . . . . . Using the UNION Keyword to Combine Subselects . . . Specifying UNION ALL. . . . . . . . . . . . . Using Subqueries . . . . . . . . . . . . . . . Correlation . . . . . . . . . . . . . . . . . Subqueries and Search Conditions . . . . . . . . How Subqueries Are Used . . . . . . . . . . . Using Subqueries with UPDATE and DELETE . . . . Notes on Using Subqueries . . . . . . . . . . . Correlated Subqueries . . . . . . . . . . . . . Using Correlated Subqueries in an UPDATE Statement Using Correlated Subqueries in a DELETE Statement . Notes on Using Correlated Subqueries. . . . . . . Changing a Table Denition . . . . . . . . . . . . Adding a column . . . . . . . . . . . . . . . Changing a column . . . . . . . . . . . . . . Allowable Conversions. . . . . . . . . . . . . Deleting a column . . . . . . . . . . . . . . Order of operations for ALTER TABLE statement . . . Creating and Using Views . . . . . . . . . . . . Adding Indexes . . . . . . . . . . . . . . . . Using the Catalog in Database Design . . . . . . . . Getting Catalog Information about a Table . . . . . Getting Catalog Information about a Column . . . . Chapter 6. Data Integrity . . . . . . . . . Adding and Using Check Constraints . . . . . Referential Integrity . . . . . . . . . . . . Adding or dropping referential constraints . . . Removing Referential Constraints . . . . . Inserting into Tables with Referential Constraints Updating Tables with Referential Constraints . Deleting from Tables with Referential Constraints Check Pending . . . . . . . . . . . . WITH CHECK OPTION on a View . . . . . . WITH CASCADED CHECK OPTION . . . . WITH LOCAL CHECK OPTION . . . . . . DB2 UDB for AS/400 Trigger Support . . . . . Trigger Sample . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

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

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

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

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

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

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

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

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

76 77 78 78 79 79 80 83 84 85 85 86 88 88 88 91 92 92 93 93 93 93 95 95 95 96 97 97 98 99 99 99 100 102 102 103 105 107 108 108 109 111 111 117 117 117 118 124 124 125 125 127 128 132

Chapter 7. Stored Procedures . . . . . . . . . . . . . . . . . Creating a Procedure . . . . . . . . . . . . . . . . . . . . . Dening an External Procedure . . . . . . . . . . . . . . . . . Dening an SQL Procedure . . . . . . . . . . . . . . . . . . . Invoking a Stored Procedure . . . . . . . . . . . . . . . . . . Using CALL Statement Where Procedure Denition Exists . . . . . . Using Embedded CALL Statement Where No Procedure Denition Exists . Using Embedded CALL Statement With an SQLDA . . . . . . . . . Using Dynamic CALL Statement Where No CREATE PROCEDURE Exists Parameter Passing Conventions for Stored Procedures . . . . . . . . Indicator Variables and Stored Procedures . . . . . . . . . . . . .

Contents

Returning a Completion Status to the Calling Program . . . . . . . . . . 134 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . 135 Example 1. ILE C and PL/I Procedures Called From ILE C Applications . . 136 Chapter 8. Using the Object-Relational Capabilities . . Why Use the DB2 Object Extensions? . . . . . . . . DB2 Approach to Supporting Objects . . . . . . . . Using Large Objects (LOBs) . . . . . . . . . . . Understanding Large Object Data Types (BLOB, CLOB, Understanding Large Object Locators . . . . . . . Example: Using a Locator to Work With a CLOB Value . Indicator Variables and LOB Locators . . . . . . . LOB File Reference Variables . . . . . . . . . . Example: Extracting a Document To a File . . . . . Example: Inserting Data Into a CLOB Column . . . . Display Layout of LOB Columns . . . . . . . . . Journal Entry Layout of LOB Columns . . . . . . . User-Dened Functions (UDF) . . . . . . . . . . . Why Use UDFs? . . . . . . . . . . . . . . . UDF Concepts. . . . . . . . . . . . . . . . Implementing UDFs . . . . . . . . . . . . . . Registering UDFs . . . . . . . . . . . . . . Examples of Registering UDFs . . . . . . . . . Using UDFs . . . . . . . . . . . . . . . . User-dened Distinct Types (UDT) . . . . . . . . . Why Use UDTs? . . . . . . . . . . . . . . . Dening a UDT . . . . . . . . . . . . . . . Resolving Unqualied UDTs . . . . . . . . . . . Examples of Using CREATE DISTINCT TYPE . . . . Dening Tables with UDTs . . . . . . . . . . . Manipulating UDTs . . . . . . . . . . . . . . Examples of Manipulating UDTs . . . . . . . . . Synergy Between UDTs, UDFs, and LOBs . . . . . . Combining UDTs, UDFs, and LOBs . . . . . . . . Examples of Complex Applications . . . . . . . . Using DataLinks . . . . . . . . . . . . . . . . NO LINK CONTROL . . . . . . . . . . . . . FILE LINK CONTROL (with File System Permissions) . FILE LINK CONTROL (with Database Permissions) . . Commands Used for Working with DataLinks . . . . Chapter 9. Writing User-Dened Functions UDF runtime environment . . . . . . . Length of time that the UDF runs . . . . Threads considerations . . . . . . . Parallel processing . . . . . . . . . Writing function code . . . . . . . . . Writing UDFs as SQL functions . . . . Writing UDFs as external functions . . . Examples of UDF code . . . . . . . . Example: Square of a number UDF . . . Example: Counter . . . . . . . . . (UDFs) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . DBCLOB) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 145 146 146 147 147 148 151 151 152 154 155 155 156 156 158 160 161 161 164 169 169 170 171 171 171 172 173 177 177 177 180 181 181 181 182 185 185 185 186 186 186 186 187 193 193 194

Chapter 10. Dynamic SQL Applications. . . . . . . . . . . . . . . 197 Designing and Running a Dynamic SQL Application . . . . . . . . . . . 199 Processing Non-SELECT statements . . . . . . . . . . . . . . . . 199

vi

DB2 UDB for AS/400 SQL Programming V4R4

CCSID of Dynamic SQL Statements. . . . . . . Using the PREPARE and EXECUTE Statements . . Processing SELECT Statements and Using an SQLDA. Fixed-List SELECT Statements . . . . . . . . Varying-List Select-Statements . . . . . . . . . The SQL Descriptor Area (SQLDA) . . . . . . . SQLDA Format . . . . . . . . . . . . . . Example of a Select-Statement for Allocating Storage Using a Cursor . . . . . . . . . . . . . . Using Parameter Markers . . . . . . . . . .

. . . . . . . for . .

. . . . . . . . . . . . . . . . . . . . . SQLDA . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

200 200 201 201 202 203 204 208 212 213

Chapter 11. Common Concepts and Rules for Using SQL with Host Languages . . . . . . . . . . . . . . . . . . . . . . Using Host Variables in SQL Statements . . . . . . . . . . . . Assignment Rules . . . . . . . . . . . . . . . . . . . Indicator Variables . . . . . . . . . . . . . . . . . . . Handling SQL Error Return Codes . . . . . . . . . . . . . . Handling Exception Conditions with the WHENEVER Statement . . . Chapter 12. Coding SQL Statements in C and C++ Applications Dening the SQL Communications Area . . . . . . . . . . Dening SQL Descriptor Areas. . . . . . . . . . . . . . Embedding SQL Statements . . . . . . . . . . . . . . Comments . . . . . . . . . . . . . . . . . . . . Continuation for SQL Statements . . . . . . . . . . . . Including Code . . . . . . . . . . . . . . . . . . Margins . . . . . . . . . . . . . . . . . . . . . Names . . . . . . . . . . . . . . . . . . . . . NULLs and NULs . . . . . . . . . . . . . . . . . Statement Labels . . . . . . . . . . . . . . . . . Preprocessor Sequence . . . . . . . . . . . . . . . Trigraphs. . . . . . . . . . . . . . . . . . . . . WHENEVER Statement . . . . . . . . . . . . . . . Using Host Variables . . . . . . . . . . . . . . . . . Declaring Host Variables . . . . . . . . . . . . . . . Using Host Structures . . . . . . . . . . . . . . . . . Host Structure Declarations . . . . . . . . . . . . . . Host Structure Indicator Array . . . . . . . . . . . . . Using Arrays of Host Structures . . . . . . . . . . . . . Host Structure Array . . . . . . . . . . . . . . . . Host Structure Array Indicator Structure . . . . . . . . . Using Pointer Data Types . . . . . . . . . . . . . . . Using ILE C for AS/400 External File Descriptions . . . . . . Determining Equivalent SQL and C or C++ Data Types. . . . . Notes on C and C++ Variable Declaration and Usage . . . . Using Indicator Variables . . . . . . . . . . . . . . . . Chapter 13. Coding SQL Statements in COBOL Applications Dening the SQL Communications Area . . . . . . . . . Dening SQL Descriptor Areas. . . . . . . . . . . . . Embedding SQL Statements . . . . . . . . . . . . . Comments . . . . . . . . . . . . . . . . . . . Continuation for SQL Statements . . . . . . . . . . . Including Code . . . . . . . . . . . . . . . . . Margins . . . . . . . . . . . . . . . . . . . . Sequence Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

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

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

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

215 215 216 219 221 222 225 225 226 227 228 228 228 229 229 229 229 229 229 230 230 230 239 240 241 241 242 244 244 245 246 249 249 251 251 252 253 253 253 254 254 254

Contents

vii

Names . . . . . . . . . . . . . . . . . . . COBOL Compile-Time Options. . . . . . . . . . . Statement Labels . . . . . . . . . . . . . . . WHENEVER Statement . . . . . . . . . . . . . Multiple source programs. . . . . . . . . . . . . Using Host Variables . . . . . . . . . . . . . . . Declaring Host Variables . . . . . . . . . . . . . Using Host Structures . . . . . . . . . . . . . . . Host Structure . . . . . . . . . . . . . . . . . Host Structure Indicator Array . . . . . . . . . . . Using Host Structure Arrays . . . . . . . . . . . . Host Structure Array . . . . . . . . . . . . . . Host Array Indicator Structure . . . . . . . . . . . Using External File Descriptions . . . . . . . . . . . Using External File Descriptions for Host Structure Arrays. Determining Equivalent SQL and COBOL Data Types . . . Notes on COBOL Variable Declaration and Usage . . . Using Indicator Variables . . . . . . . . . . . . . .

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

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

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

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

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

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

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

254 254 255 255 255 255 255 264 265 268 268 269 272 272 273 274 276 276 279 279 280 280 281 281 281 281 281 282 282 282 282 282 286 287 288 289 290 291 292 294 294 297 297 298 298 298 299 299 299 299 299 300 300 300

Chapter 14. Coding SQL Statements in PL/I Applications. . . . . Dening the SQL Communications Area . . . . . . . . . . . . Dening SQL Descriptor Areas. . . . . . . . . . . . . . . . Embedding SQL Statements . . . . . . . . . . . . . . . . Example . . . . . . . . . . . . . . . . . . . . . . . Comments . . . . . . . . . . . . . . . . . . . . . . Continuation for SQL Statements . . . . . . . . . . . . . . Including Code . . . . . . . . . . . . . . . . . . . . Margins . . . . . . . . . . . . . . . . . . . . . . . Names . . . . . . . . . . . . . . . . . . . . . . . Statement Labels . . . . . . . . . . . . . . . . . . . WHENEVER Statement . . . . . . . . . . . . . . . . . Using Host Variables . . . . . . . . . . . . . . . . . . . Declaring Host Variables . . . . . . . . . . . . . . . . . Using Host Structures . . . . . . . . . . . . . . . . . . . Host Structures . . . . . . . . . . . . . . . . . . . . Host Structure Indicator Arrays. . . . . . . . . . . . . . . Using Host Structure Arrays . . . . . . . . . . . . . . . . . Host Structure Array . . . . . . . . . . . . . . . . . . Using External File Descriptions . . . . . . . . . . . . . . . Determining Equivalent SQL and PL/I Data Types. . . . . . . . . Using Indicator Variables . . . . . . . . . . . . . . . . . . Differences in PL/I Because of Structure Parameter Passing Techniques Chapter 15. Coding SQL Statements in RPG for AS/400 Applications Dening the SQL Communications Area . . . . . . . . . . . . Dening SQL Descriptor Areas. . . . . . . . . . . . . . . . Embedding SQL Statements . . . . . . . . . . . . . . . . Example . . . . . . . . . . . . . . . . . . . . . . . Comments . . . . . . . . . . . . . . . . . . . . . . Continuation for SQL Statements . . . . . . . . . . . . . . Including Code . . . . . . . . . . . . . . . . . . . . Sequence Numbers . . . . . . . . . . . . . . . . . . . Names . . . . . . . . . . . . . . . . . . . . . . . Statement Labels . . . . . . . . . . . . . . . . . . . WHENEVER Statement . . . . . . . . . . . . . . . . . Using Host Variables . . . . . . . . . . . . . . . . . . .

viii

DB2 UDB for AS/400 SQL Programming V4R4

Declaring Host Variables . . . . . . . . . . . . . . . . . Using Host Structures . . . . . . . . . . . . . . . . . . . Using Host Structure Arrays . . . . . . . . . . . . . . . . . Using External File Descriptions . . . . . . . . . . . . . . . External File Description Considerations for Host Structure Arrays. . Determining Equivalent SQL and RPG for AS/400 Data Types . . . . Notes on RPG for AS/400 Variable Declaration and Usage . . . . Using Indicator Variables . . . . . . . . . . . . . . . . . . Example . . . . . . . . . . . . . . . . . . . . . . . Differences in RPG for AS/400 Because of Structure Parameter Passing Techniques . . . . . . . . . . . . . . . . . . . . . . Ending a Called RPG for AS/400 Program Correctly . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

300 300 301 302 303 303 306 306 306

. . . 307 . . . 307 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309 309 310 311 311 311 311 312 312 312 312 312 312 313 314 314 315 315 316 316 316 317 318 322 322 322 323 325 325 325 327 328 328 328 329 329 329 329 329 329 330 331

Chapter 16. Coding SQL Statements in ILE RPG for AS/400 Applications Dening the SQL Communications Area . . . . . . . . . . . . . . Dening SQL Descriptor Areas. . . . . . . . . . . . . . . . . . Embedding SQL Statements . . . . . . . . . . . . . . . . . . Example . . . . . . . . . . . . . . . . . . . . . . . . . Comments . . . . . . . . . . . . . . . . . . . . . . . . Continuation for SQL Statements . . . . . . . . . . . . . . . . Including Code . . . . . . . . . . . . . . . . . . . . . . Sequence Numbers . . . . . . . . . . . . . . . . . . . . . Names . . . . . . . . . . . . . . . . . . . . . . . . . Statement Labels . . . . . . . . . . . . . . . . . . . . . WHENEVER Statement . . . . . . . . . . . . . . . . . . . Using Host Variables . . . . . . . . . . . . . . . . . . . . . Declaring Host Variables . . . . . . . . . . . . . . . . . . . Using Host Structures . . . . . . . . . . . . . . . . . . . . . Using Host Structure Arrays . . . . . . . . . . . . . . . . . . . Declaring LOB Host Variables . . . . . . . . . . . . . . . . . . LOB Host Variables . . . . . . . . . . . . . . . . . . . . . LOB Locators . . . . . . . . . . . . . . . . . . . . . . . LOB File Reference Variables . . . . . . . . . . . . . . . . . Using External File Descriptions . . . . . . . . . . . . . . . . . External File Description Considerations for Host Structure Arrays. . . . Determining Equivalent SQL and RPG Data Types . . . . . . . . . . Notes on ILE/RPG 400 Variable Declaration and Usage . . . . . . . Using Indicator Variables . . . . . . . . . . . . . . . . . . . . Example . . . . . . . . . . . . . . . . . . . . . . . . . SQLDA Example of the SQLDA for a Multiple Row-Area Fetch . . . . . . Chapter 17. Coding SQL Statements in REXX Applications Using the SQL Communications Area . . . . . . . . . Using SQL Descriptor Areas . . . . . . . . . . . . Embedding SQL Statements . . . . . . . . . . . . Comments . . . . . . . . . . . . . . . . . . Continuation of SQL Statements . . . . . . . . . . Including Code . . . . . . . . . . . . . . . . Margins . . . . . . . . . . . . . . . . . . . Names . . . . . . . . . . . . . . . . . . . Nulls . . . . . . . . . . . . . . . . . . . . Statement Labels . . . . . . . . . . . . . . . Handling Errors and Warnings . . . . . . . . . . . Using Host Variables . . . . . . . . . . . . . . . Determining Data Types of Input Host Variables . . . . The Format of Output Host Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Contents

ix

Avoiding REXX Conversion . . . . . . . . . . . . . . . . . . . 332 Using Indicator Variables . . . . . . . . . . . . . . . . . . . . . 332 Chapter 18. Preparing and Running a Program with SQL Statements Basic Processes of the SQL Precompiler . . . . . . . . . . . . Input to the Precompiler . . . . . . . . . . . . . . . . . Source File CCSIDs . . . . . . . . . . . . . . . . . . Output from the Precompiler . . . . . . . . . . . . . . . Non-ILE Precompiler Commands . . . . . . . . . . . . . . . Compiling a Non-ILE Application Program . . . . . . . . . . ILE Precompiler Commands. . . . . . . . . . . . . . . . . Compiling an ILE Application Program . . . . . . . . . . . . Precompiling for the VisualAge C++ for OS/400 Compiler . . . . . Interpreting Application Program Compile Errors . . . . . . . . . Error and Warning Messages during a Compile . . . . . . . . Binding an Application . . . . . . . . . . . . . . . . . . . Program References . . . . . . . . . . . . . . . . . . Displaying Precompiler Options . . . . . . . . . . . . . . . Running a Program with Embedded SQL . . . . . . . . . . . . OS/400 DDM Considerations . . . . . . . . . . . . . . . Override Considerations . . . . . . . . . . . . . . . . . SQL Return Codes . . . . . . . . . . . . . . . . . . . Chapter 19. Using Interactive SQL Basic Functions of Interactive SQL . Starting Interactive SQL . . . . Using Statement Entry Function . Prompting . . . . . . . . . Using the List Selection Function . Session Services Description . . Exiting Interactive SQL . . . . Using an existing SQL Session . Recovering an SQL Session . . Accessing Remote Databases with . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Interactive . . . . . . . . . . . . . . . . . . . . SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333 333 334 334 335 340 340 341 341 342 343 343 344 345 345 346 346 346 347 349 349 350 351 351 354 356 357 358 358 359 361 362 362 362 363 365 365 366 366 366 366 367 368 369 373 375 375 376 376 377

Chapter 20. Using the SQL Statement Processor . . . Execution of Statements After Errors Occur . . . . . . Commitment Control in the SQL Statement Processor . . Schemas in the SQL Statement Processor . . . . . . Source Member Listing for the SQL Statement Processor . Chapter 21. DB2 UDB for AS/400 Security . . . . . . . . . . Authorization ID . . . . . . Views . . . . . . . . . . Auditing . . . . . . . . . Data Integrity . . . . . . . . Concurrency . . . . . . . Journaling . . . . . . . . Commitment Control . . . . Atomic Operations . . . . . Constraints . . . . . . . . Save/Restore . . . . . . . Damage Tolerance . . . . . Index Recovery . . . . . . Catalog Integrity . . . . . . Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . Protection. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

DB2 UDB for AS/400 SQL Programming V4R4

User Auxiliary Storage Pool (ASP) . . . . . . . . . . . . . . . . 378 Chapter 22. Testing SQL Statements in Application Programs . . Establishing a Test Environment . . . . . . . . . . . . . . Designing a Test Data Structure . . . . . . . . . . . . . Testing Your SQL Application Programs . . . . . . . . . . . The Program Debug Phase . . . . . . . . . . . . . . . The Performance Verication Phase. . . . . . . . . . . . CL Command Usage for SQL Application Performance Verication Performance Information Messages . . . . . . . . . . . . Performance Information Messages and Open Data Paths . . . Chapter 23. Using the DB2 UDB for AS/400 Predictive Query Cancelling a Query . . . . . . . . . . . . . . . . . General Implementation Considerations . . . . . . . . . User Application Implementation Considerations . . . . . . Controlling the Default Reply to the Inquiry Message . . . . Using the Governor for Performance Testing. . . . . . . . Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379 379 379 380 380 381 381 382 388 391 392 392 392 393 393 394

Governor . . . . . . . . . . . . . . . . . . . . . . . .

Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips . . . . . . . . . . . . . . . . . . . . . . . . . . General Optimization Tips . . . . . . . . . . . . . . . . . . . Data Management Methods . . . . . . . . . . . . . . . . . . . Access Path . . . . . . . . . . . . . . . . . . . . . . . Access Method . . . . . . . . . . . . . . . . . . . . . . Data Access Methods . . . . . . . . . . . . . . . . . . . . . The Optimizer . . . . . . . . . . . . . . . . . . . . . . . . Cost Estimation . . . . . . . . . . . . . . . . . . . . . . Access Plan Validation. . . . . . . . . . . . . . . . . . . . Optimizer Decision-Making Rules . . . . . . . . . . . . . . . . Join Optimization . . . . . . . . . . . . . . . . . . . . . . Grouping Optimization . . . . . . . . . . . . . . . . . . . . Effectively Using SQL Indexes . . . . . . . . . . . . . . . . . . Using Indexes With Sort Sequence . . . . . . . . . . . . . . . . Using Indexes and Sort Sequence With Selection, Joins, or Grouping . . Ordering . . . . . . . . . . . . . . . . . . . . . . . . . Example Indexes . . . . . . . . . . . . . . . . . . . . . . Tips for using VARCHAR and VARGRAPHIC data types . . . . . . . . Chapter 25. Additional SQL performance considerations . . . . . . . Improving Performance by Using Database Manager Blocking Considerations Improving Performance Using FETCH FOR n ROWS . . . . . . . . . Improving Performance with SQL Blocking . . . . . . . . . . . . . Improving Performance Using INSERT n ROWS . . . . . . . . . . . Improving Performance When Paging Interactively Displayed Data . . . . Improving Performance by Using SELECT Statements Effectively . . . . . Improving Performance by Using Live Data . . . . . . . . . . . . . Improving Performance by Using the ALWCPYDTA Parameter . . . . . . Improving Performance by Using the Optimize Clause . . . . . . . . . Improving Performance by Retaining Cursor Positions . . . . . . . . . Improving Performance by Retaining Cursor Positions for Non-ILE Program Calls . . . . . . . . . . . . . . . . . . . . . . . . . Improving Performance by Retaining Cursor Positions across ILE Program Calls . . . . . . . . . . . . . . . . . . . . . . . . . . General Rules for Retaining Cursor Positions For All Program Calls . . . .

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

395 395 396 396 397 420 422 423 425 425 426 442 446 449 449 450 450 456 459 461 462 462 463 463 464 464 465 466 467

. 467 . 468 . 469

Contents

xi

Improving Performance of SQL PREPARE Statements . . . . . . . . Effects on Performance When Using Long Object Names . . . . . . . Improving Performance Using the Precompile Options . . . . . . . . Improving Performance by Using Structure Parameter Passing Techniques Background Information on Parameter Passing. . . . . . . . . . Some Differences Because of Structure Parameter Passing Techniques Controlling Parallel Processing . . . . . . . . . . . . . . . . . Controlling Parallel Processing System Wide . . . . . . . . . . Controlling Parallel Processing for a Job . . . . . . . . . . . . Chapter 26. Monitoring and Optimizing Query Performance Tools Optimizing Query Performance Using Query Optimization Tools . . Query optimizer debug messages . . . . . . . . . . . . . Print SQL information . . . . . . . . . . . . . . . . . . Database monitor statistics . . . . . . . . . . . . . . . . Start Database Monitor (STRDBMON) Command . . . . . . . End Database Monitor (ENDDBMON) Command . . . . . . . Database Monitor Performance Records . . . . . . . . . . Query Optimizer Index Advisor . . . . . . . . . . . . . . Database Monitor Examples . . . . . . . . . . . . . . Database Monitor Physical File DDS . . . . . . . . . . . Database Monitor Logical File DDS . . . . . . . . . . . . Memory Resident Database Monitor APIs. . . . . . . . . . . External API Description . . . . . . . . . . . . . . . . External File Description . . . . . . . . . . . . . . . . Record Identication . . . . . . . . . . . . . . . . . Comparison table of query optimization tools . . . . . . . . Change query attributes . . . . . . . . . . . . . . . . . Query Options File QAQQINI . . . . . . . . . . . . . . . Specifying the QAQQINI le. . . . . . . . . . . . . . . Creating the QAQQINI Query Options File . . . . . . . . . Chapter 27. Solving Common Database Problems Paging through Retrieved Data . . . . . . . . Retrieving in Reverse Order. . . . . . . . . . Establishing Position at the End of a Table . . . . Adding Data to the End of a Table . . . . . . . Updating Data as It Is Retrieved from a Table . . . Restrictions . . . . . . . . . . . . . . . Updating Data Previously Retrieved . . . . . . . Changing the Table Denition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

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

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

470 470 471 472 472 473 473 474 474 477 477 477 478 478 479 480 481 482 482 489 493 524 525 525 542 542 543 543 544 544 551 551 551 551 552 552 553 553 554 555 555 556 557 558 558 561 561 561 562 563 563 565 565

Chapter 28. Distributed Relational Database Function . . . . . . DB2 UDB for AS/400 Distributed Relational Database Support . . . . DB2 UDB for AS/400 Distributed Relational Database Example Program SQL Package Support . . . . . . . . . . . . . . . . . . . Valid SQL Statements in an SQL Package . . . . . . . . . . Considerations for Creating an SQL Package . . . . . . . . . CCSID Considerations for SQL . . . . . . . . . . . . . . . Connection Management and Activation Groups . . . . . . . . . Connections and conversations . . . . . . . . . . . . . . Source Code for PGM1: . . . . . . . . . . . . . . . . . Source Code for PGM2: . . . . . . . . . . . . . . . . . Source Code for PGM3: . . . . . . . . . . . . . . . . . Multiple Connections to the Same Relational Database. . . . . . Implicit Connection Management for the Default Activation Group . .

xii

DB2 UDB for AS/400 SQL Programming V4R4

Implicit Connection Management for Nondefault Activation Groups Distributed Support . . . . . . . . . . . . . . . . . . . Determining Connection Type . . . . . . . . . . . . . . Connect and Commitment Control Restrictions . . . . . . . . Determining Connection Status . . . . . . . . . . . . . Distributed Unit of Work Connection Considerations . . . . . . Ending Connections. . . . . . . . . . . . . . . . . . Distributed Unit of Work . . . . . . . . . . . . . . . . . Managing Distributed Unit of Work Connections . . . . . . . Cursors and Prepared Statements . . . . . . . . . . . . Application Requester Driver Programs . . . . . . . . . . . Problem Handling . . . . . . . . . . . . . . . . . . . Appendix A. DB2 UDB for AS/400 Sample Tables . . . Department Table (CORPDATA.DEPARTMENT) . . . . DEPARTMENT . . . . . . . . . . . . . . . Employee Table (CORPDATA.EMPLOYEE) . . . . . . Employee to Project Activity Table (CORPDATA.EMP_ACT) EMP_ACT . . . . . . . . . . . . . . . . . Project Table (CORPDATA.PROJECT) . . . . . . . . PROJECT . . . . . . . . . . . . . . . . . Class Schedule Table (CL_SCHED) . . . . . . . . . In Tray Table (IN_TRAY) . . . . . . . . . . . . . Appendix B. SQLCODEs and SQLSTATEs SQLCODE and SQLSTATE Descriptions . . Positive SQLCODEs . . . . . . . . Negative SQLCODEs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

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

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

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

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

566 566 567 570 570 572 573 573 574 576 577 578 579 579 580 580 581 582 584 584 585 585 587 589 589 591 605 605 606 613 621 628 634 640 643 645 645 648 648 661 661 664 664 678 678 681 681 695 695 699 699 712

Appendix C. Sample Programs Using DB2 UDB for AS/400 Statements Examples of programs that use SQL statements . . . . . . . . . . SQL Statements in ILE C and C++ Programs . . . . . . . . . . . SQL Statements in COBOL and ILE COBOL Programs. . . . . . . . SQL Statements in PL/I . . . . . . . . . . . . . . . . . . . SQL Statements in RPG for AS/400 Programs . . . . . . . . . . . SQL Statements in ILE RPG for AS/400 Programs . . . . . . . . . SQL Statements in REXX Programs. . . . . . . . . . . . . . . Report Produced by Sample Programs. . . . . . . . . . . . . . Appendix D. DB2 UDB for AS/400 CL Command Descriptions . . . . CRTSQLCBL (Create Structured Query Language COBOL) Command . . Purpose . . . . . . . . . . . . . . . . . . . . . . . . Parameters . . . . . . . . . . . . . . . . . . . . . . . Example . . . . . . . . . . . . . . . . . . . . . . . . CRTSQLCBLI (Create SQL ILE COBOL Object) Command . . . . . . Purpose . . . . . . . . . . . . . . . . . . . . . . . . Parameters . . . . . . . . . . . . . . . . . . . . . . . Example . . . . . . . . . . . . . . . . . . . . . . . . CRTSQLCI (Create Structured Query Language ILE C Object) Command . Purpose . . . . . . . . . . . . . . . . . . . . . . . . Parameters . . . . . . . . . . . . . . . . . . . . . . . Example . . . . . . . . . . . . . . . . . . . . . . . . CRTSQLCPPI (Create Structured Query Language C++ Object) Command Purpose . . . . . . . . . . . . . . . . . . . . . . . . Parameters . . . . . . . . . . . . . . . . . . . . . . . Example . . . . . . . . . . . . . . . . . . . . . . . .

Contents

xiii

CRTSQLPLI (Create Structured Query Language PL/I) Command. . . . . Purpose . . . . . . . . . . . . . . . . . . . . . . . . . Parameters . . . . . . . . . . . . . . . . . . . . . . . . Example . . . . . . . . . . . . . . . . . . . . . . . . . CRTSQLRPG (Create Structured Query Language RPG) Command . . . . Purpose . . . . . . . . . . . . . . . . . . . . . . . . . Parameters . . . . . . . . . . . . . . . . . . . . . . . . Example . . . . . . . . . . . . . . . . . . . . . . . . . CRTSQLRPGI (Create SQL ILE RPG Object) Command . . . . . . . . Purpose . . . . . . . . . . . . . . . . . . . . . . . . . Parameters . . . . . . . . . . . . . . . . . . . . . . . . Example . . . . . . . . . . . . . . . . . . . . . . . . . CRTSQLPKG (Create Structured Query Language Package) Command . . Purpose . . . . . . . . . . . . . . . . . . . . . . . . . Parameters . . . . . . . . . . . . . . . . . . . . . . . . Example . . . . . . . . . . . . . . . . . . . . . . . . . CVTSQLCPP (Convert Structured Query Language C++ Source) Command . Purpose . . . . . . . . . . . . . . . . . . . . . . . . . Parameters . . . . . . . . . . . . . . . . . . . . . . . . Example . . . . . . . . . . . . . . . . . . . . . . . . . DLTSQLPKG (Delete Structured Query Language Package) Command. . . Purpose . . . . . . . . . . . . . . . . . . . . . . . . . Parameters . . . . . . . . . . . . . . . . . . . . . . . . Example . . . . . . . . . . . . . . . . . . . . . . . . . PRTSQLINF (Print Structured Query Language Information) Command . . . Purpose . . . . . . . . . . . . . . . . . . . . . . . . . Parameters . . . . . . . . . . . . . . . . . . . . . . . . Example . . . . . . . . . . . . . . . . . . . . . . . . . RUNSQLSTM (Run Structured Query Language Statement) Command . . . Purpose . . . . . . . . . . . . . . . . . . . . . . . . . Parameters . . . . . . . . . . . . . . . . . . . . . . . . Parameters for SQL procedures . . . . . . . . . . . . . . . . Example . . . . . . . . . . . . . . . . . . . . . . . . . STRSQL (Start Structured Query Language) Command . . . . . . . . Purpose . . . . . . . . . . . . . . . . . . . . . . . . . Parameters . . . . . . . . . . . . . . . . . . . . . . . . Example . . . . . . . . . . . . . . . . . . . . . . . . . Appendix E. Using the C for AS/400 and FORTRAN for AS/400 Precompilers . . . . . . . . . . . . . . . . . . . . . . . Using the C for AS/400 Precompiler . . . . . . . . . . . . . . . . Access plans . . . . . . . . . . . . . . . . . . . . . . . Host variable data types . . . . . . . . . . . . . . . . . . . Using external le descriptions . . . . . . . . . . . . . . . . . CRTSQLC (Create Structured Query Language C) Command . . . . . Using the FORTRAN/400 Precompiler . . . . . . . . . . . . . . . CRTSQLFTN (Create Structured Query Language FORTRAN) Command . Appendix F. Coding SQL Statements in FORTRAN Applications Dening the SQL Communications Area . . . . . . . . . . Dening SQL Descriptor Areas. . . . . . . . . . . . . . Embedding SQL Statements . . . . . . . . . . . . . . Comments . . . . . . . . . . . . . . . . . . . . Debug Lines . . . . . . . . . . . . . . . . . . . Continuation for SQL statements . . . . . . . . . . . . Including Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

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

712 715 715 728 728 731 732 744 744 748 748 761 762 763 763 765 766 769 769 781 781 782 782 783 783 783 783 784 784 786 786 792 794 794 796 796 801

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

803 803 803 803 803 804 819 819 837 837 838 839 839 839 839 840

xiv

DB2 UDB for AS/400 SQL Programming V4R4

Margins . . . . . . . . . . . . . . . . . Names . . . . . . . . . . . . . . . . . Statement Labels . . . . . . . . . . . . . WHENEVER Statement . . . . . . . . . . . FORTRAN Compile-Time Options . . . . . . . Using Host Variables . . . . . . . . . . . . . Declaring Host Variables . . . . . . . . . . . Determining Equivalent SQL and FORTRAN Data Types Notes on FORTRAN Variable Declaration and Usage Using Indicator Variables . . . . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

840 840 840 841 841 841 841 842 843 844

Bibliography . . . . . . . . . . . . . . . . . . . . . . . . . 845 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . 847 Readers Comments Wed Like to Hear from You. . . . . . . . . . 879

Contents

xv

xvi

DB2 UDB for AS/400 SQL Programming V4R4

About DB2 UDB for AS/400 SQL Programming


This book explains to programmers and database administrators: v How to use the DB2 SQL for AS/400 licensed program v How to access data in a database v How to prepare, run, test, and optimize an application program containing SQL statements. For more information on DB2 UDB for AS/400 SQL guidelines and examples for implementation in an application programming environment, see the following books: v DB2 UDB for AS/400 SQL Reference v DB2 UDB for AS/400 SQL Call Level Interface Note: The DB2 UDB for AS/400 library will only be available in the AS/400e Information Center beginning in Version 4, Release 4. v DATABASE 2/400 Advanced Database Functions, GG24-4249.

Who should read this book


| | | | | This guide should be used by application programmers and database administrators who are familiar with and can program with COBOL for AS/400, ILE COBOL for AS/400, AS/400 PL/I, ILE C for AS/400, ILE C++, VisualAge C++ for AS/400, REXX, RPG III (part of RPG for AS/400), or ILE RPG for AS/400 language and who can understand basic database applications.

Assumptions Relating to Examples of SQL Statements


The examples of SQL statements shown in this guide are based on the sample tables in Appendix A, DB2 UDB for AS/400 Sample Tables, and assume the following: v They are shown in the interactive SQL environment or they are written in ILE C or in COBOL. EXEC SQL and END-EXEC are used to delimit an SQL statement in a COBOL program. A description of how to use SQL statements in a COBOL program is provided in Coding SQL Statements in COBOL Applications. A description of how to use SQL statements in an ILE C program is provided in Coding SQL Statements in C Applications. v Each SQL example is shown on several lines, with each clause of the statement on a separate line. v SQL keywords are highlighted. v Table names provided in Appendix A, DB2 UDB for AS/400 Sample Tables, use the collection CORPDATA. Table names that are not found in Appendix A, DB2 UDB for AS/400 Sample Tables, should use collections you create. v Calculated columns are enclosed in parentheses, (), and brackets, []. v The SQL naming convention is used. v The APOST and APOSTSQL precompiler options are assumed although they are not the default options in COBOL. Character string literals within SQL and host language statements are delimited by apostrophes (). v A sort sequence of *HEX is used, unless otherwise noted.

Copyright IBM Corp. 1997, 1999

xvii

v The complete syntax of the SQL statement is usually not shown in any one example. For the complete description and syntax of any of the statements described in this guide, see the DB2 UDB for AS/400 SQL Reference Whenever the examples vary from these assumptions, it is stated. Because this guide is for the application programmer, most of the examples are shown as if they were written in an application program. However, many examples can be slightly changed and run interactively by using interactive SQL. The syntax of an SQL statement, when using interactive SQL, differs slightly from the format of the same statement when it is embedded in a program.

How to Interpret Syntax Diagrams in this Guide


Throughout this book, syntax is described using the structure dened as follows: v Read the syntax diagrams from left to right, from top to bottom, following the path of the line. The symbol indicates the beginning of a statement. The symbol indicates that the statement syntax is continued on the next line. The symbol indicates that a statement is continued from the previous line. The symbol indicates the end of a statement. Diagrams of syntactical units other than complete statements start with the symbol and end with the symbol. v Required items appear on the horizontal line (the main path).
required_item

v Optional items appear below the main path.


required_item optional_item

If an optional item appears above the main path, that item has no effect on the execution of the statement and is used only for readability.
optional_item required_item

v If you can choose from two or more items, they appear vertically, in a stack. If you must choose one of the items, one item of the stack appears on the main path.
required_item required_choice1 required_choice2

If choosing one of the items is optional, the entire stack appears below the main path.

xviii

DB2 UDB for AS/400 SQL Programming V4R4

required_item optional_choice1 optional_choice2

If one of the items is the default, it will appear above the main path and the remaining choices will be shown below.
default_choice required_item optional_choice optional_choice

v An arrow returning to the left, above the main line, indicates an item that can be repeated.

required_item

repeatable_item

If the repeat arrow contains a comma, you must separate repeated items with a comma.
, required_item repeatable_item

A repeat arrow above a stack indicates that you can repeat the items in the stack. v Keywords appear in uppercase (for example, FROM). They must be spelled exactly as shown. Variables appear in all lowercase letters (for example, column-name). They represent user-supplied names or values. v If punctuation marks, parentheses, arithmetic operators, or other such symbols are shown, you must enter them as part of the syntax.

AS/400 Operations Navigator


AS/400 Operations Navigator is a powerful graphical interface for Windows clients. With AS/400 Operations Navigator, you can manage and administer your AS/400 systems from your Windows desktop. You can use Operations Navigator to manage communications, printing, database, security, and other system operations. Operations Navigator includes Management Central for managing multiple AS/400 systems centrally. Figure 1 on page xx shows an example of the Operations Navigator display:

About DB2 UDB for AS/400 SQL Programming

xix

Figure 1. AS/400 Operations Navigator Display

This new interface has been designed to make you more productive and is the only user interface to new, advanced features of OS/400. Therefore, IBM recommends that you use AS/400 Operations Navigator, which has online help to guide you. While this interface is being developed, you may still need to use a traditional emulator such as PC5250 to do some of your tasks.

Installing Operations Navigator


To use AS/400 Operations Navigator, you must have Client Access installed on your Windows PC. For help in connecting your Windows PC to your AS/400 system, consult Client Access Express for Windows - Setup, SC41-5507-00. AS/400 Operations Navigator is a separately installable component of Client Access that contains many subcomponents. If you are installing for the rst time and you use the Typical installation option, the following options are installed by default: v Operations Navigator base support v Basic operations (messages, printer output, and printers) To select the subcomponents that you want to install, select the Custom installation option. (After Operations Navigator has been installed, you can add subcomponents by using Client Access Selective Setup.) 1. Display the list of currently installed subcomponents in the Component Selection window of Custom installation or Selective Setup. 2. Select AS/400 Operations Navigator. 3. Select any additional subcomponents that you want to install and continue with Custom installation or Selective Setup. After you install Client Access, double-click the AS400 Operations Navigator icon on your desktop to access Operations Navigator and create an AS/400 connection.

xx

DB2 UDB for AS/400 SQL Programming V4R4

How this book has changed


| | | | | The major new features covered in this manual include: v Large objects (LOBs) v DataLinks v User-dened types v User-dened functions v Derived tables

Prerequisite and related information


Use the AS/400 Information Center as your starting point for looking up AS/400 technical information. You can access the Information Center from the AS/400e Information Center CD-ROM (English version: SK3T-2027) or from one of these Web sites:
http://www.as400.ibm.com/infocenter http://publib.boulder.ibm.com/pubs/html/as400/infocenter.htm

The AS/400 Information Center contains important topics such as logical partitioning, clustering, Java, TCP/IP, Web serving, and secured networks. It also contains Internet links to Web sites such as the AS/400 Online Library and the AS/400 Technical Studio. Included in the Information Center is a link that describes at a high level the differences in information between the Information Center and the Online Library. For a list of related publications, see the Bibliography on page 845.

How to send your comments


Your feedback is important in helping to provide the most accurate and high-quality information. If you have any comments about this book or any other AS/400 documentation, ll out the readers comment form at the back of this book. v If you prefer to send comments by mail, use the readers comment form with the address that is printed on the back. If you are mailing a readers comment form from a country other than the United States, you can give the form to the local IBM branch office or IBM representative for postage-paid mailing. v If you prefer to send comments by FAX, use either of the following numbers: United States and Canada: 1-800-937-3430 Other countries: 1-507-253-5192 v If you prefer to send comments electronically, use one of these e-mail addresses: Comments on books: RCHCLERK@us.ibm.com IBMMAIL, to IBMMAIL(USIB56RZ) Comments on the AS/400 Information Center: RCHINFOC@us.ibm.com Be sure to include the following: v The name of the book. v The publication number of the book.
About DB2 UDB for AS/400 SQL Programming

xxi

v The page number or topic to which your comment applies.

xxii

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 1. Introduction to DB2 UDB for AS/400 Structured Query Language


This guide describes the AS/400* system implementation of the Structured Query Language (SQL) using DB2 UDB for AS/400 and the DB2 UDB Query Manager and SQL Development Kit Version 4 licensed program. SQL manages information based on the relational model of data. SQL statements can be embedded in high-level languages, dynamically prepared and run, or run interactively. SQL consists of statements and clauses that describe what you want to do with the data in a database and under what conditions you want to do it. SQL can access data in a remote relational database, using the IBM Distributed Relational Database Architecture* (DRDA*). This function is described in Chapter 28. Distributed Relational Database Function, of this guide. Further information about DRDA is contained in the Distributed Database Programming book.

SQL Concepts
DB2 UDB for AS/400 SQL consists of the following main parts: v SQL run-time support SQL run-time parses SQL statements and runs any SQL statements. This support is that part of the Operating System/400* (OS/400) licensed program which allows applications that contain SQL statements to be run on systems where the DB2 UDB Query Manager and SQL Development Kit licensed program is not installed. v SQL precompilers SQL precompilers support precompiling embedded SQL statements in host languages. The following languages are supported: ILE C for AS/400* ILE C++ for AS/400 VisualAge C++ for AS/400 ILE COBOL for AS/400* COBOL for AS/400* AS/400 PL/I* RPG III (part of RPG for AS/400*) ILE RPG for AS/400*

The SQL host language precompilers prepare an application program containing SQL statements. The host language compilers then compile the precompiled host source programs. For more information on precompiling, see Chapter 18. Preparing and Running a Program with SQL Statements. The precompiler support is part of the DB2 UDB Query Manager and SQL Development Kit licensed program. v SQL interactive interface SQL interactive interface allows you to create and run SQL statements. For more information on interactive SQL, see Chapter 19. Using Interactive SQL. Interactive SQL is part of the DB2 UDB Query Manager and SQL Development Kit licensed program. v Run SQL Statements CL command
Copyright IBM Corp. 1997, 1999

RUNSQLSTM allows you to run a series of SQL statements, which are stored in a source le. The RUNSQLSTM command is part of the DB2 UDB Query Manager and SQL Development Kit licensed program. See Chapter 20. Using the SQL Statement Processor for more information on the Run SQL Statements command. v DB2 Query Manager for AS/400 DB2 Query Manager for AS/400 provides a prompt-driven interactive interface that allows you to create data, add data, maintain data, and run reports on the databases. Query Manager is part of the DB2 UDB Query Manager and SQL Development Kit licensed program. For more information, refer to the DB2 UDB for AS/400 Query Manager Use book. v SQL REXX Interface The SQL REXX interface allows you to run SQL statements in a REXX procedure. This interface is part of the DB2 UDB Query Manager and SQL Development Kit licensed program. For more information on using SQL statements in REXX procedures, see Chapter 17. Coding SQL Statements in REXX Applications. v SQL Call Level Interface DB2 UDB for AS/400 supports the SQL Call Level Interface. This allows users of any of the ILE languages to access SQL functions directly through procedure calls to a service program provided by the system. Using the SQL Call Level Interface, one can perform all the SQL functions without the need for a precompile. This is a standard set of procedure calls to prepare SQL statements, execute SQL statements, fetch rows of data, and even do advanced functions such as accessing the catalogs and binding program variables to output columns. For a complete description of all the available functions, and their syntax, see the DB2 UDB for AS/400 SQL Call Level Interface book. QSQPRCED API This Application Program Interface (API) provides an extended dynamic SQL capability. SQL statements can be prepared into an SQL package and then executed using this API. Statements prepared into a package by this API persist until the package or statement is explicitly dropped. QSQPRCED is part of the OS/400 licensed program. For more information on the QSQPRCED API, see the System API Reference book. QSQCHKS API This API syntax checks SQL statements. QSQCHKS is part of the OS/400 licensed program. For more information on the QSQCHKS API, see the System API Reference book. DB2 Multisystem This feature of the operating system allows your data to be distributed across multiple AS/400 systems. For more information on DB2 Multisystem, see the DB2 Multisystem for AS/400 book. DB2 UDB Symmetric Multiprocessing This feature of the operating system provides the query optimizer with additional methods for retrieving data that include parallel processing. Symmetric multiprocessing (SMP) is a form of parallelism achieved on a single system where multiple processors (CPU and I/O processors) that share memory and disk resource work simultaneously towards achieving a single end result. This parallel processing means that the database manager can have more than one (or all) of the system processors working on a single query simultaneously. See Controlling Parallel Processing on page 473 for information on how to control parallel processing.

DB2 UDB for AS/400 SQL Programming V4R4

Relational Database and Terminology


In the relational model of data, all data is perceived as existing in tables. DB2 UDB for AS/400 objects are created and maintained as AS/400 system objects. The following table shows the relationship between AS/400 system terms and SQL relational database terms. For more information on database, see the DB2 UDB for AS/400 Database Programming book.
Table 1. Relationship of System Terms to SQL Terms System Terms SQL Terms Library. Groups related objects and allows Collection. Consists of a library, a journal, a you to nd the objects by name. journal receiver, an SQL catalog, and optionally a data dictionary. A collection groups related objects and allows you to nd the objects by name. Physical le. A set of records. Table. A set of columns and rows. Record. A set of elds. Row. The horizontal part of a table containing a serial set of columns. Field. One or more characters of related Column. The vertical part of a table of one information of one data type. data type. Logical le. A subset of elds and records View. A subset of columns and rows of one of one or more physical les. or more tables. SQL Package. An object type that is used to Package. An object type that is used to run run SQL statements. SQL statements. User Prole Authorization name or Authorization ID.

SQL Terminology
There are two naming conventions that can be used in DB2 UDB for AS/400 programming: system (*SYS) and SQL (*SQL). The naming convention used affects the method for qualifying le and table names and the terms used on the interactive SQL displays. The naming convention used is selected by a parameter on the SQL commands or, for REXX, selected through the SET OPTION statement.

System naming (*SYS): In the system naming convention, les are qualied by library name in the form:
library/file

If the table name is not explicitly qualied and a default collection name is specied for the default relational database collection (DFTRDBCOL) parameter of the CRTSQLxxx 1 or the CRTSQLPKG commands, the default collection name is used. If the table name is not explicitly qualied and the default collection name is not specied, the qualication rules are: v The following CREATE statements resolve to unqualied objects as follows: CREATE TABLE The table is created in the current library (*CURLIB). CREATE VIEW The view is created in the rst library referenced in the subselect. CREATE INDEX The index is created into the collection or library that contains the table on which the index is being built.

1. The xxx in this command refers to the host language indicators: CI for the ILE C for AS/400 language, CPPI for the ILE C++ for AS/400 language, CBL for the COBOL for AS/400 language, CBLI for the ILE COBOL for AS/400 language, PLI for the AS/400 PL/I language, RPG for the RPG for AS/400 language, and RPGI for the ILE RPG for AS/400 language. The CVTSQLCPP command is considered part of this group of commands even though it does not start with CRT. Chapter 1. Introduction to DB2 UDB for AS/400 Structured Query Language

| | |

CREATE ALIAS The alias is created into the collection or library that contains the table for which you dened the alias. If the table is not qualied or is not found, the alias is created in the current library (*CURLIB). v All other SQL statements cause SQL to search the library list (*LIBL) for the unqualied table. The default relational database collection (DFTRDBCOL) parameter applies only to static SQL statements.

SQL naming (*SQL): In the SQL naming convention, tables are qualied by the collection name in the form:
collection.table

If the table name is not explicitly qualied and the default collection name is specied in the default relational database collection (DFTRDBCOL) parameter of the CRTSQLxxx command, the default collection name is used. If the table name is not explicitly qualied and the default collection name is not specied, the rules are: v For static SQL, the default qualier is the user prole of the program owner. v For dynamic SQL or interactive SQL, the default qualier is the user prole of the job running the statement.

Types of SQL Statements


There are four basic types of SQL statements: data denition language (DDL) statements, data manipulation language (DML) statements, dynamic SQL statements, and miscellaneous statements. SQL statements can operate on objects that are created by SQL as well as AS/400 externally described physical les and AS/400 single-format logical les, whether or not they reside in an SQL collection. They do not refer to the IDDU dictionary denition for program-described les. Program-described les appear as a table with only a single column.

DB2 UDB for AS/400 SQL Programming V4R4

SQL DDL Statements ALTER TABLE COMMENT ON CREATE ALIAS CREATE COLLECTION CREATE DISTINCT TYPE CREATE FUNCTION CREATE INDEX CREATE PROCEDURE CREATE SCHEMA CREATE TABLE CREATE VIEW DROP ALIAS DROP COLLECTION DROP DISTINCT TYPE DROP FUNCTION DROP INDEX DROP PACKAGE DROP PROCEDURE DROP SCHEMA DROP TABLE DROP VIEW GRANT DISTINCT TYPE GRANT FUNCTION GRANT PACKAGE GRANT PROCEDURE GRANT TABLE LABEL ON RENAME REVOKE DISTINCT TYPE REVOKE FUNCTION REVOKE PACKAGE REVOKE PROCEDURE REVOKE TABLE Dynamic SQL Statements DESCRIBE EXECUTE EXECUTE IMMEDIATE PREPARE

SQL DML Statements CLOSE COMMIT DECLARE CURSOR DELETE FETCH INSERT LOCK TABLE OPEN ROLLBACK SELECT INTO SET variable UPDATE VALUES INTO

Miscellaneous Statements BEGIN DECLARE SECTION CALL CONNECT DECLARE PROCEDURE DECLARE STATEMENT DECLARE VARIABLE DESCRIBE TABLE DISCONNECT END DECLARE SECTION FREE LOCATOR INCLUDE RELEASE SET CONNECTION SET OPTION SET PATH SET RESULT SETS SET TRANSACTION WHENEVER

SQL Objects
SQL objects used on the AS/400 system are collections, tables, aliases, views, SQL packages, indexes, and catalogs. SQL creates and maintains these objects as AS/400 database objects. A brief description of these objects follows.
Chapter 1. Introduction to DB2 UDB for AS/400 Structured Query Language

Collections
A collection provides a logical grouping of SQL objects. A collection consists of a library, a journal, a journal receiver, a catalog, and optionally, a data dictionary. Tables, views, and system objects (such as programs) can be created, moved, or restored into any AS/400 library. All AS/400 les can be created or moved into an SQL collection if the SQL collection does not contain a data dictionary. If the SQL collection contains a data dictionary then: v AS/400 source physical les or nonsource physical les with one member can be created, moved, or restored into an SQL collection. v AS/400 logical les cannot be placed in an SQL collection because they cannot be described in the data dictionary. You can create and own many collections.

Data Dictionary
A collection contains a data dictionary if it was created prior to Version 3 Release 1 or if the WITH DATA DICTIONARY clause was specied on the CREATE COLLECTION or the CREATE SCHEMA statements. A data dictionary is a set of tables containing object denitions. If SQL created the dictionary, then it is automatically maintained by the system. You can work with data dictionaries by using the interactive data denition utility (IDDU), which is part of the OS/400 program. For more information on IDDU, see the IDDU Use book.

Journals and Journal Receivers


A journal and journal receiver are used to record changes to tables and views in the database. The journal and journal receiver are then used in processing SQL COMMIT and ROLLBACK statements. The journal and journal receiver can also be used as an audit trail or for forward or backward recovery. For more information on journaling, see the Backup and Recovery book.

Catalogs
An SQL catalog consists of a set of tables and views which describe tables, views, indexes, packages, procedures, les, and constraints. This information is contained in a set of cross-reference tables in libraries QSYS and QSYS2. Library QSYS2 also contains a set of catalog views built over the QSYS catalog tables which describe information about all the tables, views, indexes, packages, procedures, les, and constraints on the system. In each SQL collection there is a set of views built over the catalog tables which contains information about the tables, views, indexes, packages, les, and constraints in the collection. A catalog is automatically created when you create a collection. You cannot drop or explicitly change the catalog. For more information about SQL catalogs, see the DB2 UDB for AS/400 SQL Reference book.

Tables, Rows, and Columns


A table is a two-dimensional arrangement of data consisting of rows and columns. The row is the horizontal part containing one or more columns. The column is the vertical part containing one or more rows of data of one data type. All data for a

DB2 UDB for AS/400 SQL Programming V4R4

column must be of the same type. A table in SQL is a keyed or nonkeyed physical le. See the section on data types in the DB2 UDB for AS/400 SQL Reference book for a description of data types. Data in a table can be distributed across AS/400 systems. For more information about distributed tables, see the DB2 Multisystem for AS/400 book. The following is a sample SQL table:
Columns

PROJNO Rows MA2100 MA2110 MA2112 MA2113 ...

PROJNAME MFG AUTOMATION MFG PROGRAMMING ROBOT DESIGN PROD CONTROL PROG ...

DEPTNO D11 E21 E01 D11 ...

DEPTMGR 000060 000100 000050 000060 ...

PRSTAFF 12 3 3 3 ...
RV2W573-0

Aliases
An alias is an alternate name for a table or view. You can use an alias to refer to a table or view in those cases where an existing table or view can be referred to. For more information on aliases, see the DB2 UDB for AS/400 SQL Reference book.

Views
A view appears like a table to an application program; however, a view contains no data. It is created over one or more tables. A view can contain all the columns of given tables or some subset of them, and can contain all the rows of given tables or some subset of them. The columns can be arranged differently in a view than they are in the tables from which they are taken. A view in SQL is a special form of a nonkeyed logical le. The following gure shows a view created from the preceding example of an SQL table. Notice that the view is created only over the PROJNO and PROJNAME columns of the table and for rows MA2110 and MA2100.
Columns

PROJNO Rows MA2100 MA2110

PROJNAME MFG AUTOMATION MFG PROGRAMMING


RV2W574-0

Chapter 1. Introduction to DB2 UDB for AS/400 Structured Query Language

Indexes
An SQL index is a subset of the data in the columns of a table that are logically arranged in either ascending or descending order. Each index contains a separate arrangement. These arrangements are used for ordering (ORDER BY clause), grouping (GROUP BY clause), and joining. An SQL index is a keyed logical le. The index is used by the system for faster data retrieval. Creating an index is optional. You can create any number of indexes. You can create or drop an index at any time. The index is automatically maintained by the system. However, because the indexes are maintained by the system, a large number of indexes can adversely affect the performance of applications that change the table.

Constraints
Constraints are rules enforced by the database manager. DB2 UDB for AS/400 supports the following constraints: v Unique constraints A unique constraint is the rule that the values of the key are valid only if they are unique. Unique constraints can be created using the CREATE TABLE and ALTER TABLE statements. 2 Unique constraints are enforced during the execution of INSERT and UPDATE statements. A PRIMARY KEY constraint is a form of UNIQUE constraint. The difference is that a PRIMARY KEY cannot contain any nullable columns. v Referential constraints A referential constraint is the rule that the values of the foreign key are valid only if: They appear as values of a parent key, or Some component of the foreign key is null. Referential constraints are enforced during the execution of INSERT, UPDATE, and DELETE statements. v Check constraints A check constraint is a rule that limits the values allowed in a column or group of columns. Check constraints can be added using the CREATE TABLE and ALTER TABLE statements. Check constraints are enforced during the execution of INSERT and UPDATE statements. To satisfy the constraint, each row of data inserted or updated in the table must make the specied condition either TRUE or unknown (due to a null value). For more information on constraints, see Chapter 6. Data Integrity.

Triggers
A trigger is a set of actions that are executed automatically whenever a specied event occurs to a specied base table. An event can be an insert, update, or delete operation. The trigger can be run either before or after the event. For more information on triggers, see Chapter 6. Data Integrity in this book or see the DB2 UDB for AS/400 Database Programming book.

2. Although CREATE INDEX can create a unique index that also guarantees uniqueness, such an index is not a constraint.

DB2 UDB for AS/400 SQL Programming V4R4

Stored Procedures
| | | | | | | | | | | | | | | A stored procedure is a program that can be called using the SQL CALL statement. DB2 UDB for AS/400 supports external stored procedures and SQL procedures. External stored procedures can be any AS/400 program or REXX procedure. They cannot be System/36 programs or procedures, or service programs. An SQL procedure is dened entirely in SQL and can contain SQL statements including SQL control statements. For more information on stored procedures, see Chapter 7. Stored Procedures.

User-dened functions
A user-dened function is a program that can be invoked like any built-in function. DB2 UDB for AS/400 supports external functions, SQL functions, and sourced functions. External functions can be any AS/400 ILE program or service program. An SQL function is dened entirely in SQL and can contain SQL statements, including SQL control statements. A sourced function is built over any built-in or any existing user-dened function. For more information on user-dened functions, see Chapter 9. Writing User-Dened Functions (UDFs) on page 185.

Packages
An SQL package is an object that contains the control structure produced when the SQL statements in an application program are bound to a remote relational database management system (DBMS). The DBMS uses the control structure to process SQL statements encountered while running the application program. SQL packages are created when a relational database name (RDB parameter) is specied on a Create SQL (CRTSQLxxx) command and a program object is created. Packages can also be created using the CRTSQLPKG command. For more information about packages and distributed relational database function, see Chapter 28. Distributed Relational Database Function SQL packages can also be created using the QSQPRCED API. For more information on QSQPRCED, see the System API Reference book.

Application Program Objects


The process of creating a DB2 UDB for AS/400 application program may result in the creation of several objects. This section briey describes the process of creating a DB2 UDB for AS/400 application. DB2 UDB for AS/400 supports both non-ILE and ILE precompilers. Application programs may be either distributed or nondistributed. Additional information on creating DB2 UDB for AS/400 application programs is in Chapter 18. Preparing and Running a Program with SQL Statements. With DB2 UDB for AS/400 you may need to manage the following objects: v The original source v Optionally, the module object for ILE programs v The program or service program v The SQL package for distributed programs With a nondistributed non-ILE DB2 UDB for AS/400 program, you must manage only the original source and the resulting program. The following shows the objects
Chapter 1. Introduction to DB2 UDB for AS/400 Structured Query Language

involved and steps that happen during the precompile and compile processes for a nondistributed non-ILE DB2 UDB for AS/400 program:

User Source File Member

Precompile

Temporary Source File Member Processed SQL Statements

Compile

Program

Access Plan

RV2W565-1

With a nondistributed ILE DB2 UDB for AS/400 program, you may need to manage the original source, the modules, and the resulting program or service program. The following shows the objects involved and steps that happen during the precompile and compile processes for a nondistributed ILE DB2 UDB for AS/400 program when OBJTYPE(*PGM) is specied on the precompile command:

User Source Precompile File Member

Temporary Source File Member Processed SQL Statements

Compile

Module

Bind

Program

Processed SQL Statements

Access Plan

RV2W569-0

With a distributed non-ILE DB2 UDB for AS/400 program, you must manage the original source, the resulting program, and the resulting package. The following shows the objects and steps that occur during the precompile and compile processes for a distributed non-ILE DB2 UDB for AS/400 program:
Create Compile Program SQL Package Access Plan SQL Package

User Source File Member

Precompile

Temporary Source File Member Processed SQL Statements

Access Plan
RV2W566-2

With a distributed ILE DB2 UDB for AS/400 program, you must manage the original source, module objects, the resulting program or service program, and the resulting packages. An SQL package can be created for each distributed module in a distributed ILE program or service program. The following shows the objects and steps that occur during the precompile and compile processes for a distributed ILE DB2 UDB for AS/400 program:

10

DB2 UDB for AS/400 SQL Programming V4R4

User Source File Member

Precompile

Temporary Source File Member Processed SQL Statements

Compile

Module

Bind

Program

Create SQL Package

SQL Package

Processed SQL Statements

Access Plan

Access Plan

RV2W570-1

Note: The access plans associated with the DB2 UDB for AS/400 distributed program object are not created until the program is run locally.

User Source File Member


A source le member contains the programmers application language and SQL statements. You can create and maintain the source le member by using the source entry utility (SEU), a part of the AS/400 Application Development Tools licensed program.

Output Source File Member


The SQL precompile creates an output source le member. By default, the precompile process (CRTSQLxxx commands) creates a temporary source le called QSQLTEMP (QSQLTEMP1 for CRTSQLRPGI) in library QTEMP. If the precompile process uses the QTEMP library, the system automatically deletes the le when the job completes. You can specify the output source le as a permanent le name on the precompile commands. A member with the same name as the program name is added to the output source le. This member contains the following items: v Calls to the SQL run-time support, which have replaced embedded SQL statements v Parsed and syntax-checked SQL statements By default, the precompiler calls the host language compiler. For more information on precompilers, see Chapter 18. Preparing and Running a Program with SQL Statements.

Program
A program is the object which you can run that is created as a result of the compile process for non-ILE compiles or as a result of the bind process for ILE compiles. An access plan is a set of internal structures and information that tells SQL how to run an embedded SQL statement most effectively. It is created only when the program has successfully created. Access plans are not created during program creation for SQL statements if the statements: v Refer to a table or view that cannot be found v Refer to a table or view to which you are not authorized The access plans for such statements are created when the program is run. If, at that time, the table or view still cannot be found or you are still not authorized, a negative SQLCODE is returned. Access plans are stored and maintained in the program object for nondistributed SQL programs and in the SQL package for distributed SQL programs.

Chapter 1. Introduction to DB2 UDB for AS/400 Structured Query Language

11

Package
An SQL package contains the access plans for a distributed SQL program. An SQL package is an object that is created when: v A distributed SQL program is successfully created using the RDB parameter on CRTSQLxxx commands. v When the Create SQL Package (CRTSQLPKG) command is run. When a distributed SQL program is created, the name of the SQL package and an internal consistency token are saved in the program. These are used at run time to nd the SQL package and to verify that the SQL package is correct for this program. Because the name of the SQL package is critical for running distributed SQL programs, an SQL package cannot be: v v v v Moved Renamed Duplicated Restored to a different library

Module
A module is an Integrated Language Environment (ILE) object that is created by compiling source code using the CRTxxxMOD command (or any of the CRTBNDxxx commands where xxx is C, CBL, CPP, or RPG). You can run a module only if you use the Create Program (CRTPGM) command to bind it into a program. You usually bind several modules together, but you can bind a module by itself. Modules contain information about the SQL statements; however, the SQL access plans are not created until the modules are bound into either a program or service program.

Service Program
A service program is an Integrated Language Environment (ILE) object that provides a means of packaging externally supported callable routines (functions or procedures) into a separate object. Bound programs and other service programs can access these routines by resolving their imports to the exports provided by a service program. The connections to these services are made when the calling programs are created. This improves call performance to these routines without including the code in the calling program.

12

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 2. Getting Started with SQL


| | This chapter describes how to create and work with SQL collections, tables, and views using SQL statements. The syntax for each of the SQL statements used in this chapter is described in detail in the DB2 UDB for AS/400 SQL Reference book. A description of how to use SQL statements and clauses in more complex situations is provided in Chapter 3. Basic Concepts and Techniques and Chapter 5. Advanced Coding Techniques. | | | | | | In this chapter, the examples use the interactive SQL interface to show the execution of SQL statements. Each SQL interface provides methods for using SQL statements to dene tables, views, and other objects, methods for updating the objects, and methods for reading data from the objects. Some tasks described here can also be done using Operations Navigator. In those cases, the information about the task notes that it can be done using Operations Navigator.

Starting Interactive SQL


To start using interactive SQL for the following examples, type:
STRSQL NAMING(*SQL)

and press Enter. When the Enter SQL Statements display appears, you are ready to start typing SQL Statements. For more information on interactive SQL and the STRSQL command, see Chapter 19. Using Interactive SQL. If you are reusing an existing interactive SQL session, make sure that you set the naming mode to SQL naming. You can specify this on the F13 (Services) panel, option 1 (Change session attributes).

Creating an SQL Collection


| | | An SQL collection is the basic object in which tables, views, indexes, and packages are placed. One way to create a collection (called a library) is by using Operations Navigator. Or you can use the SQL CREATE COLLECTION statement. For an example of creating a collection using interactive SQL, see Example: Creating the SQL Collection (SAMPLECOLL).

Example: Creating the SQL Collection (SAMPLECOLL)


| | You can create a sample collection, named SAMPLECOLL, by typing the following SQL statement on the Enter SQL Statements display and pressing Enter:

Copyright IBM Corp. 1997, 1999

13

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

Enter SQL Statements Type SQL statement, press Enter. Current connection is to relational database SYSTEM1 ===> CREATE COLLECTION SAMPLECOLL_________________________________________ _____________________________________________________________________ _____________________________________________________________________ _____________________________________________________________________ Bottom F3=Exit F4=Prompt F6=Insert line F9=Retrieve F10=Copy line F12=Cancel F13=Services F24=More keys

Note: Running this statement causes several objects to be created and takes several seconds. After you have successfully created a collection, you can create tables, views, and indexes in it. Tables, views, and indexes can also be created in libraries instead of collections.

Creating and Using a Table


| | | | You can create a table by using the SQL CREATE TABLE statement or by using Operations Navigator. The CREATE TABLE statement allows you to create a table, dene the physical attributes of the columns in the table, and dene constraints to restrict the values that are allowed in the table. For an example of creating a table using interactive SQL, see Example: Creating a Table (INVENTORY_LIST). | | | | | | | | | | | | | | | | | | | When creating a table, you need to understand the concepts of null value and default value. A null value indicates the absence of a column value for a row. It is not the same as a value of zero or all blanks. It means unknown. It is not equal to any value, not even to other null values. If a column does not allow the null value, a value must be assigned to the column, either a default value or a user supplied value. A default value is assigned to a column when a row is added to a table and no value is specied for that column. If a specic default value is not dened for a column, the system default value will be used. For more information on the default values used by INSERT, see The INSERT Statement on page 31

Example: Creating a Table (INVENTORY_LIST)


We are going to create a table to maintain information about the current inventory of a business. It will have information about the items kept in the inventory, their cost, quantity currently on hand, the last order date, and the number last ordered. The item number will be a required value. It cannot be null. The item name, quantity on hand, and order quantity will have user supplied default values. The last order date and quantity ordered will allow the null value. On the Enter SQL Statements display, type CREATE TABLE and press F4 (Prompt). The following display is shown (with the input areas not yet lled in):

14

DB2 UDB for AS/400 SQL Programming V4R4

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

Specify CREATE TABLE Statement Type information, press Enter. Table . . . . . . . . . Collection . . . . . . Nulls: INVENTORY_LIST______ SAMPLECOLL__ Name Name, F4 for list

1=NULL, 2=NOT NULL, 3=NOT NULL WITH DEFAULT FOR Column ____________ ____________ ____________ ____________ ____________ ____________ ____________ Type CHAR___________ VARCHAR________ DECIMAL________ SMALLINT_______ DATE___________ SMALLINT_______ _______________ N N Length Scale 6____ __ 20___ __ 8____ 2_ _____ __ _____ __ _____ __ _____ __ Y=Yes, N=No Y=Yes, N=No Nulls 2 3 3 1 1 1 3 Bottom

Column ITEM_NUMBER_______ ITEM_NAME_________ UNIT_COST_________ QUANTITY_ON_HAND__ LAST_ORDER_DATE___ ORDER_QUANTITY____ __________________

Table CONSTRAINT . . . . . . . . . . . . . Distributed Table . . . . . . . . . . . . F3=Exit F4=Prompt F11=Display more attributes F5=Refresh F12=Cancel

F6=Insert line F14=Delete line

F10=Copy line F24=More keys

Type the table name and collection name of the table you are creating, INVENTORY_LIST in SAMPLECOLL, for the Table and Collection prompts. Each column you want to dene for the table is represented by an entry in the list on the lower part of the display. For each column, type the name of the column, the data type of the column, its length and scale, and the null attribute. Press F11 to see more attributes that can be specied for the columns. This is where a default value may be specied.
Specify CREATE TABLE Statement Type information, press Enter. Table . . . . . . . . . Collection . . . . . . Data: INVENTORY_LIST______ SAMPLECOLL__ Name Name, F4 for list

1=BIT, 2=SBCS, 3=MIXED, 4=CCSID Data _ _ _ _ _ _ _ Allocate _____ _____ _____ _____ _____ _____ _____

Column ITEM NUMBER_______ ITEM NAME_________ UNIT_COST_________ QUANTITY_ON_HAND__ LAST_ORDER_DATE___ ORDER_QUANTITY____ __________________

CCSID CONSTRAINT Default _____ N __________________ _____ N '***UNKNOWN***'___ _____ N __________________ _____ N NULL______________ _____ N __________________ _____ N 20________________ _____ _ __________________ Bottom Table CONSTRAINT . . . . . . . . . . . . . N Y=Yes, N=No Distributed Table . . . . . . . . . . . . N Y=Yes, N=No F5=Refresh F12=Cancel F6=Insert line F14=Delete line F10=Copy line F24=More keys

F3=Exit F4=Prompt F11=Display more attributes

Note: Another way of entering column denitions is to press F4 (Prompt) with your cursor on one of the column entries in the list. This will bring up a display that shows all of the attributes for dening a single column. When all the values have been entered, press Enter to create the table. The Enter SQL Statements display will be shown again with a message indicating that the table has been created.

Chapter 2. Getting Started with SQL

15

| | | | | | | | | |

You can directly key in this CREATE TABLE statement on the Enter SQL Statements display as follows:
CREATE TABLE SAMPLECOLL.INVENTORY_LIST (ITEM_NUMBER CHAR(6) NOT NULL, ITEM_NAME VARCHAR(20) NOT NULL WITH DEFAULT '***UNKNOWN***', UNIT_COST DECIMAL(8,2) NOT NULL WITH DEFAULT, QUANTITY_ON_HAND SMALLINT DEFAULT NULL, LAST_ORDER_DATE DATE, ORDER_QUANTITY SMALLINT DEFAULT 20)

Creating the Supplier Table (SUPPLIERS)


Later in our examples, we will need a second table as well. This table will contain information about suppliers of our inventory items, which items they supply, and the cost of the item from that supplier. To create it, either type it in directly on the Enter SQL Statements display or press F4 (Prompt) to use the interactive SQL displays to create the denition.
CREATE TABLE SAMPLECOLL.SUPPLIERS (SUPPLIER_NUMBER CHAR(4) NOT NULL, ITEM_NUMBER CHAR(6) NOT NULL, SUPPLIER_COST DECIMAL(8,2))

Using the LABEL ON Statement


Normally, the column name is used as the column heading when showing the output of a SELECT statement in interactive SQL. By using the LABEL ON statement, you can create a more descriptive label for the column name. Since we are going to be running our examples in interactive SQL, we will use the LABEL ON statement to change the column headings. Even though the column names are descriptive, it will be easier to read if the column headings show each part of the name on a single line. It will also allow us to see more columns of our data on a single display. To change the labels for our columns, type LABEL ON COLUMN on the Enter SQL Statements display and press F4 (Prompt). The following display will appear:

16

DB2 UDB for AS/400 SQL Programming V4R4

Specify LABEL ON Statement Type choices, press Enter. Label on . . . . 2 1=Table or view 2=Column 3=Package 4=Alias Name, F4 for list Name, F4 for list 1=Column heading 2=Text

Table or view Collection . . Option . . . . .

INVENTORY_LIST______ SAMPLECOLL__ 1

F3=Exit F4=Prompt F5=Refresh F21=Display statement

F12=Cancel

F20=Display full names

Type in the name of the table and collection containing the columns for which you want to add labels and press Enter. The following display will be shown, prompting you for each of the columns in the table.
Specify LABEL ON Statement Type information, press Enter. Column ITEM_NUMBER ITEM_NAME UNIT_COST QUANTITY_ON_HAND LAST_ORDER_DATE ORDER_QUANTITY Column Heading ....+....1....+....2....+....3....+....4....+....5.... 'ITEM NUMBER'___________________________ 'ITEM NAME'_____________________________ 'UNIT COST'_____________________________ 'QUANTITY ON HAND'_________ 'LAST ORDER DATE'_________ 'NUMBER ORDERED'__________________________

F3=Exit F14=Delete line

Bottom F5=Refresh F6=Insert line F10=Copy line F12=Cancel F19=Display system column names F24=More keys

Type the column headings for each of the columns. Column headings are dened in 20 character sections. Each section will be displayed on a different line when showing the output of a SELECT statement. The ruler across the top of the column heading entry area can be used to easily space the headings correctly. When the headings are typed, press Enter. The following message indicates that the LABEL ON statement was successful.
LABEL ON for INVEN00001 in SAMPLECOLL completed.

The table name in the message is the system table name for this table, not the name that was actually specied in the statement. DB2 UDB for AS/400 maintains
Chapter 2. Getting Started with SQL

17

two names for tables with names longer than ten characters. For more information on system table names, see the CREATE TABLE statement in the DB2 UDB for AS/400 SQL Reference book. The LABEL ON statement can also be keyed in directly on the Enter SQL statements display as follows:
LABEL ON SAMPLECOLL/INVENTORY_LIST (ITEM_NUMBER IS 'ITEM ITEM_NAME IS 'ITEM UNIT_COST IS 'UNIT QUANTITY_ON_HAND IS 'QUANTITY LAST_ORDER_DATE IS 'LAST ORDER_QUANTITY IS 'NUMBER NUMBER', NAME', COST', ON ORDER ORDERED')

HAND', DATE',

Inserting Information into a Table


After you create a table, you can insert, or add, information (data) into it by using Operations Navigator. Or you can use the SQL INSERT statement. | | | | | | | | | | | | | | | | | | | | | | | | | | | | For an example of inserting data into a table using interactive SQL, see Example: Inserting Information into a Table (INVENTORY_LIST).

Example: Inserting Information into a Table (INVENTORY_LIST)


To work with interactive SQL, on the Enter SQL Statements display, type INSERT and press F4 (Prompt). The Specify INSERT Statement display will be shown.
Specify INSERT Statement Type choices, press Enter. INTO table . . . . . . . Collection . . . . . . Select columns to insert INTO . . . . . . . . . Insertion method . . . . Type choices, press Enter. WITH isolation level . . 1 1=Current level, 2=NC (NONE) 3=UR (CHG), 4=CS, 5=RS (ALL) 6=RR INVENTORY_LIST______ SAMPLECOLL__ Y 1 Name, F4 for list Name, F4 for list Y=Yes, N=No 1=Input VALUES 2=Subselect

F3=Exit F4=Prompt F5=Refresh F21=Display statement

F12=Cancel

F20=Display full names

Type the table name and collection name in the input elds as shown. Change the Select columns to insert INTO prompt to Yes. Press Enter to see the display where the columns you want to insert values into can be selected.

18

DB2 UDB for AS/400 SQL Programming V4R4

Specify INSERT Statement Type sequence numbers (1-999) to make selections, press Enter. Seq 1__ 2__ 3__ 4__ ___ ___ Column ITEM_NUMBER ITEM_NAME UNIT_COST QUANTITY_ON_HAND LAST_ORDER_DATE ORDER_QUANTITY Type CHARACTER VARCHAR DECIMAL SMALLINT DATE SMALLINT Length Scale 6 20 8 2 4 4 Bottom

F3=Exit F5=Refresh F20=Display entire name

F12=Cancel F19=Display system column names F21=Display statement

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

In this example, we only want to insert into four of the columns. We will let the other columns have their default value inserted. The sequence numbers on this display indicate the order that the columns and values will be listed in the INSERT statement. Press Enter to show the display where values for the selected columns can be typed.
Specify INSERT Statement Type values to insert, press Enter. Column ITEM_NUMBER ITEM_NAME UNIT_COST QUANTITY_ON_HAND Value '153047'_____________________________________________ 'Pencils, red'_______________________________________ 10.00________________________________________________ 25___________________________________________________

F3=Exit F12=Cancel

Bottom F5=Refresh F6=Insert line F10=Copy line F11=Display type F14=Delete line F15=Split line F24=More keys

Note: To see the data type and length for each of the columns in the insert list, press F11 (Display type). This will show a different view of the insert values display, providing information about the column denition. Type the values to be inserted for all of the columns and press Enter. A row containing these values will be added to the table. The values for the columns that were not specied will have a default value inserted. For LAST_ORDER_DATE it will be the null value since no default was provided and the column allows the null value. For ORDER_QUANTITY it will be 20, the value specied as the default value on the CREATE TABLE statement. You can type the INSERT statement on the Enter SQL Statements display as:
INSERT INTO SAMPLECOLL.INVENTORY_LIST (ITEM_NUMBER, ITEM_NAME, UNIT_COST, QUANTITY_ON_HAND)

Chapter 2. Getting Started with SQL

19

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

VALUES('153047', 'Pencils, red', 10.00, 25)

To add the next row to the table, press F9 (Retrieve) on the Enter SQL Statements display. This will copy the previous INSERT statement to the typing area. You can either type over the values from the previous INSERT statement or press F4 (Prompt) to use the Interactive SQL displays to enter data. Continue using the INSERT statement to add the following rows to the table. Values not shown in the chart below should not be inserted so that the default will be used. In the INSERT statement column list, specify only the column names for which you want to insert a value. For example, to insert the third row, you would specify only ITEM_NUMBER and UNIT_COST for the column names and only the two values for these columns in the VALUES list.
ITEM_NUMBER 153047 229740 544931 303476 559343 291124 775298 073956 Paper clips Envelopes, legal Envelopes, standard Chairs, secretary Pens, black 225.00 20.00 6 25 ITEM_NAME Pencils, red Lined tablets UNIT_COST 10.00 1.50 5.00 2.00 3.00 100 500 QUANTITY_ON_HAND 25 120

Add the following rows to the SAMPLECOLL.SUPPLIERS table.


SUPPLIER_NUMBER 1234 1234 1234 9988 9988 2424 2424 5546 3366 3366 ITEM_NUMBER 153047 229740 303476 153047 559343 153047 303476 775298 303476 073956 SUPPLIER_COST 10.00 1.00 3.00 8.00 3.00 9.00 2.50 225.00 1.50 17.00

The sample collection now contains two tables with several rows of data in each.

Getting Information from a Single Table


Now that we have inserted all the information into our tables, we need to be able to look at it again. In SQL, this is done with the SELECT statement. The SELECT statement is the most complex of all SQL statements. This statement is composed of three main clauses:

20

DB2 UDB for AS/400 SQL Programming V4R4

1. The SELECT clause, which species those columns containing the desired data. 2. The FROM clause, which species the table or tables containing the columns with the desired data. 3. The WHERE clause, which supplies conditions that determine which rows of data are retrieved. In addition to the three main clauses, there are several other clauses described in Using Basic SQL Statements and Clauses on page 31, and in the DB2 UDB for AS/400 SQL Reference book, which affect the nal form of returned data. To see the values we inserted into the INVENTORY_LIST table, type SELECT and press F4 (prompt). The following display will be shown:
Specify SELECT Statement Type SELECT statement information. FROM tables . . . . . SELECT columns . . . . WHERE conditions . . . GROUP BY columns . . . HAVING conditions . . ORDER BY columns . . . FOR UPDATE OF columns . . . . . . . . . . . . . . . . . . . . . Press F4 for a list.

SAMPLECOLL.INVENTORY_LIST____________________ *____________________________________________ _____________________________________________ _____________________________________________ _____________________________________________ _____________________________________________ _____________________________________________ Bottom N N N Y=Yes, N=No Y=Yes, N=No Y=Yes, N=No

Type choices, press Enter. DISTINCT rows in result table . . . . . . . . . UNION with another SELECT . . . . . . . . . . . Specify additional options . . . . . . . . . . .

F3=Exit F10=Copy line

F4=Prompt F5=Refresh F6=Insert line F9=Specify subquery F12=Cancel F14=Delete line F15=Split line F24=More keys

Type the table name in the FROM tables eld on the display. To select all columns from the table, type * for the SELECT columns eld on the display. Press Enter and the statement will run to select all of the data for all of the columns in the table. The following output will be shown:
Data width . . . . . . : Position to line . . . . . Shift to column . . . . . . ....+....1....+....2....+....3....+....4....+....5....+....6....+....7. ITEM ITEM UNIT QUANTITY LAST NUMBER NUMBER NAME COST ON ORDER ORDERED HAND DATE 153047 Pencils, red 10.00 25 20 229740 Lined tablets 1.50 120 20 544931 ***UNKNOWN*** 5.00 - 20 303476 Paper clips 2.00 100 20 559343 Envelopes, legal 3.00 500 20 291124 Envelopes, standard .00 - 20 775298 Chairs, secretary 225.00 6 20 073956 Pens, black 20.00 25 20 ******** End of data ******** F3=Exit F12=Cancel F19=Left F20=Right F21=Split Display Data 71

The column headings that were dened using the LABEL ON statement are shown. The ITEM_NAME for the third entry has the default value that was specied in the CREATE TABLE statement. The QUANTITY_ON_HAND column has a null value for
Chapter 2. Getting Started with SQL

21

the rows where no value was inserted. The LAST_ORDER_DATE column contains all null values since that column is not in any of the INSERT statements and the column was not dened to have a default value. Similarly, the ORDER_QUANTITY column contains the default value for all rows. This statement could be entered on the Enter SQL Statements display as:
SELECT * FROM SAMPLECOLL.INVENTORY_LIST

To limit the number of columns returned by the SELECT statement, the columns you want to see must be specied. To restrict the number of output rows returned, the WHERE clause is used. To see only the items that cost more than 10 dollars, and only have the values for the columns ITEM_NUMBER, UNIT_COST, and ITEM_NAME returned, type SELECT and press F4 (Prompt). The Specify SELECT Statement display will be shown.
Specify SELECT Statement Type SELECT statement information. FROM tables . . . . . SELECT columns . . . . WHERE conditions . . . GROUP BY columns . . . HAVING conditions . . ORDER BY columns . . . FOR UPDATE OF columns . . . . . . . . . . . . . . . . . . . . . Press F4 for a list.

SAMPLECOLL.INVENTORY_LIST____________________ ITEM_NUMBER, UNIT_COST, ITEM_NAME____________ UNIT_COST > 10.00____________________________ _____________________________________________ _____________________________________________ _____________________________________________ _____________________________________________ Bottom N N N Y=Yes, N=No Y=Yes, N=No Y=Yes, N=No

Type choices, press Enter. DISTINCT rows in result table . . . . . . . . . UNION with another SELECT . . . . . . . . . . . Specify additional options . . . . . . . . . . .

F3=Exit F10=Copy line

F4=Prompt F5=Refresh F6=Insert line F9=Specify subquery F12=Cancel F14=Delete line F15=Split line F24=More keys

Although only one line is initially shown for each prompt on the Specify SELECT Statement display, F6 (Insert line) can be used to add more lines to any of the input areas in the top part of the display. This could be used if more columns were to be entered in the SELECT columns list, or a longer, more complex WHERE condition were needed. Fill in the display as shown above. When Enter is pressed, the SELECT statement is run. The following output will be seen:
Data width . . . . . . : Position to line . . . . . Shift to column . . . . . . ....+....1....+....2....+....3....+....4. ITEM UNIT ITEM NUMBER COST NAME 775298 225.00 Chairs, secretary 073956 20.00 Pens, black ******** End of data ******** F3=Exit F12=Cancel F19=Left F20=Right F21=Split Display Data 41

The only rows returned are those whose data values compare with the condition specied in the WHERE clause. Furthermore, the only data values returned are

22

DB2 UDB for AS/400 SQL Programming V4R4

from the columns you explicitly specied in the SELECT clause. Data values of columns other than those explicitly identied are not returned. This statement could have been entered on the Enter SQL Statements display as:
SELECT ITEM_NUMBER, UNIT_COST, ITEM_NAME FROM SAMPLECOLL.INVENTORY_LIST WHERE UNIT_COST > 10.00

Getting Information from More Than One Table


SQL allows you to get information from columns contained in more than one table. This operation is called a join operation. (For a more detailed description of the join operation, see Joining Data from More Than One Table on page 75). In SQL, a join operation is specied by placing the names of those tables you want to join together into the same FROM clause of a SELECT statement. Suppose you want to see a list of all the suppliers and the item numbers and item names for their supplied items. The item name is not in the SUPPLIERS table. It is in the INVENTORY_LIST table. Using the common column, ITEM_NUMBER, we can see all three of the columns as if they were from a single table. Whenever the same column name exists in two or more tables being joined, the column name must be qualied by the table name to specify which column is really being referenced. In this SELECT statement, the column name ITEM_NUMBER is dened in both tables so the column name needs to be qualied by the table name. If the columns had different names, there would be no confusion so qualication would not be needed. To perform this join, the following SELECT statement can be used. Enter it by typing it directly on the Enter SQL Statements display or by prompting. If using prompting, both table names need to be typed on the FROM tables input line.
SELECT SUPPLIER_NUMBER, SAMPLECOLL.INVENTORY_LIST.ITEM_NUMBER, ITEM_NAME FROM SAMPLECOLL.SUPPLIERS, SAMPLECOLL.INVENTORY_LIST WHERE SAMPLECOLL.SUPPLIERS.ITEM_NUMBER = SAMPLECOLL.INVENTORY_LIST.ITEM_NUMBER

Another way to enter the same statement is to use a correlation name. A correlation name provides another name for a table name to use in a statement. A correlation name must be used when the table names are the same. It can be specied following each table name in the FROM list. The previous statement could be rewritten as:
SELECT SUPPLIER_NUMBER, Y.ITEM_NUMBER, ITEM_NAME FROM SAMPLECOLL.SUPPLIERS X, SAMPLECOLL.INVENTORY_LIST Y WHERE X.ITEM_NUMBER = Y.ITEM_NUMBER

In this example, SAMPLECOLL.SUPPLIERS is given a correlation name of X and SAMPLECOLL.INVENTORY_LIST is given a correlation name of Y. The names X and Y are then used to qualify the ITEM_NUMBER column name. For more information on correlation names, see the DB2 UDB for AS/400 SQL Reference book. Running this example returns the following output:

Chapter 2. Getting Started with SQL

23

Data width . . . . . . : Position to line . . . . . Shift to column . . . . . . ....+....1....+....2....+....3....+....4....+ SUPPLIER_NUMBER ITEM ITEM NUMBER NAME 1234 153047 Pencils, red 9988 153047 Pencils, red 2424 153047 Pencils, red 1234 229740 Lined tablets 1234 303476 Paper clips 2424 303476 Paper clips 3366 303476 Paper clips 9988 559343 Envelopes, legal 5546 775298 Chairs, secretary 3366 073956 Pens, black ******** End of data ******** F3=Exit F12=Cancel F19=Left F20=Right F21=Split

Display Data

45

The data values in the result table represent a composite of the data values contained in the two tables INVENTORY_LIST and SUPPLIERS. This result table contains the supplier number from the SUPPLIER table and the item number and item name from the INVENTORY_LIST table. Any item numbers that do not appear in the SUPPLIER table are not shown in this result table. The results are not guaranteed to be in any order unless the ORDER BY clause is specied for the SELECT statement. Since we did not change any column headings for the SUPPLIER table, the SUPPLIER_NUMBER column name is used as the column heading. The following is an example of using ORDER BY to guarantee the order of the rows. The statement will rst order the result table by the SUPPLIER_NUMBER column. Rows with the same value for SUPPLIER_NUMBER will be ordered by their ITEM_NUMBER.
SELECT SUPPLIER_NUMBER, Y.ITEM_NUMBER, ITEM_NAME FROM SAMPLECOLL.SUPPLIERS X, SAMPLECOLL.INVENTORY_LIST Y WHERE X.ITEM_NUMBER = Y.ITEM_NUMBER ORDER BY SUPPLIER_NUMBER, Y.ITEM_NUMBER

Running the previous statement would produce the following output.

24

DB2 UDB for AS/400 SQL Programming V4R4

Data width . . . . . . : Position to line . . . . . Shift to column . . . . . . ....+....1....+....2....+....3....+....4....+ SUPPLIER_NUMBER ITEM ITEM NUMBER NAME 1234 153047 Pencils, red 1234 229740 Lined tablets 1234 303476 Paper clips 2424 153047 Pencils, red 2424 303476 Paper clips 3366 073956 Pens, black 3366 303476 Paper clips 5546 775298 Chairs, secretary 9988 153047 Pencils, red 9988 559343 Envelopes, legal ******** End of data ******** F3=Exit F12=Cancel F19=Left F20=Right F21=Split

Display Data

45

Changing Information in a Table


| | | You can use the SQL UPDATE statement to change the data values in some or all of the columns of a table. You may also use Operations Navigator to accomplish this task. For an example of changing information in a table using interactive SQL, see Example: Changing Information in a Table. | | | | | | | | | | | If you want to limit the number of rows being changed during a single statement execution, use the WHERE clause with the UPDATE statement. For more information see, The UPDATE Statement on page 33. If you do not specify the WHERE clause, all of the rows in the specied table are changed. However, if you use the WHERE clause, the system changes only the rows satisfying the conditions that you specify. For more information, see The WHERE Clause on page 38.

Example: Changing Information in a Table


Suppose we want to use interactive SQL and are placing an order for more paper clips today. To update the LAST_ORDER_DATE and ORDER_QUANTITY for item number 303476, type UPDATE and press F4 (Prompt). The Specify UPDATE Statement display will be shown.

Chapter 2. Getting Started with SQL

25

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

Specify UPDATE Statement Type choices, press Enter. Table . . . . . . . . Collection . . . . . Correlation . . . . . INVENTORY_LIST______ SAMPLECOLL__ ____________________ Name, F4 for list Name, F4 for list Name

F3=Exit F4=Prompt F5=Refresh F21=Display statement

F12=Cancel

F20=Display full names

After typing the table name and collection name, press Enter. The display will be shown again with the list of columns in the table.
Specify UPDATE Statement Type choices, press Enter. Table . . . . . . . . Collection . . . . . Correlation . . . . . INVENTORY_LIST______ SAMPLECOLL__ ____________________ Name, F4 for list Name, F4 for list Name

Type information, press Enter. Column ITEM_NUMBER ITEM_NAME UNIT_COST QUANTITY_ON_HAND LAST_ORDER_DATE ORDER_QUANTITY F3=Exit F4=Prompt F11=Display type Value _____________________________________________________ _____________________________________________________ _____________________________________________________ _____________________________________________________ CURRENT DATE_________________________________________ 50___________________________________________________ F5=Refresh F12=Cancel F6=Insert line F14=Delete line F10=Copy line F24=More keys Bottom

Specifying CURRENT DATE for a value will change the date in all the selected rows to be todays date. After typing the values to be updated for the table, press Enter to see the display on which the WHERE condition can be specied. If a WHERE condition is not specied, all the rows in the table will be updated using the values from the previous display.

26

DB2 UDB for AS/400 SQL Programming V4R4

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

Specify UPDATE Statement Type WHERE conditions, press Enter. Press F4 for a list. ITEM_NUMBER = '303476'________________________________________________ ______________________________________________________________________

Type choices, press Enter. WITH isolation level . . . 1

Bottom 1=Current level, 2=NC (NONE) 3=UR (CHG), 4=CS, 5=RS (ALL) 6=RR

F3=Exit F10=Copy line

F4=Prompt F5=Refresh F6=Insert line F9=Specify subquery F12=Cancel F14=Delete line F15=Split line F24=More keys

After typing the condition, press Enter to perform the update on the table. A message will indicate that the function is complete. This statement could have been typed on the Enter SQL Statements display as:
UPDATE SAMPLECOLL.INVENTORY_LIST SET LAST_ORDER_DATE = CURRENT DATE, ORDER_QUANTITY = 50 WHERE ITEM_NUMBER = '303476'

Running a SELECT statement to get all the rows from the table (SELECT * FROM SAMPLECOLL.INVENTORY_LIST), returns the following result:
Data width . . . . . . : 71 Position to line . . . . . Shift to column . . . . . . ....+....1....+....2....+....3....+....4....+....5....+....6....+....7. ITEM ITEM UNIT QUANTITY LAST NUMBER NUMBER NAME COST ON ORDER ORDERED HAND DATE 153047 Pencils, red 10.00 25 20 229740 Lined tablets 1.50 120 20 544931 ***UNKNOWN*** 5.00 - 20 303476 Paper clips 2.00 100 05/30/94 50 559343 Envelopes, legal 3.00 500 20 291124 Envelopes, standard .00 - 20 775298 Chairs, secretary 225.00 6 20 073956 Pens, black 20.00 25 20 ******** End of data ******** Bottom F3=Exit F12=Cancel F19=Left F20=Right F21=Split Display Data

Only the entry for Paper clips was changed. The LAST_ORDER_DATE was changed to be the current date. This date is always the date the update is run. The NUMBER_ORDERED shows its updated value.

Chapter 2. Getting Started with SQL

27

Deleting Information from a Table


| | | | | | | You can delete data from a table by using Operations Navigator. Or, using the SQL DELETE statement, you can delete entire rows from a table when they no longer contain needed information. You can use the WHERE clause with the DELETE statement to identify rows to be deleted during a single statement execution. For more information, see The DELETE Statement on page 34. For an example of deleting information in a table using interactive SQL, see Example: Deleting Information from a Table (INVENTORY_LIST).

Example: Deleting Information from a Table (INVENTORY_LIST)


If we want to remove all the rows in our table that have the null value for the QUANTITY_ON_HAND column, you could enter the following statement on the Enter SQL Statements display:
DELETE FROM SAMPLECOLL.INVENTORY_LIST WHERE QUANTITY_ON_HAND IS NULL

To check a column for the null value, the IS NULL comparison is used. Running another SELECT statement after the delete has completed will return the following result table:
Data width . . . . . . : Position to line . . . . . Shift to column . . . . . . ....+....1....+....2....+....3....+....4....+....5....+....6....+....7. ITEM ITEM UNIT QUANTITY LAST NUMBER NUMBER NAME COST ON ORDER ORDERED HAND DATE 153047 Pencils, red 10.00 25 20 229740 Lined tablets 1.50 120 20 303476 Paper clips 2.00 100 05/30/94 50 559343 Envelopes, legal 3.00 500 20 775298 Chairs, secretary 225.00 6 20 073956 Pens, black 20.00 25 20 ******** End of data ******** F3=Exit F12=Cancel F19=Left F20=Right F21=Split Display Data 71

Bottom

The rows with a null value for QUANTITY_ON_HAND were deleted.

Creating and Using a View


| | | | You may nd that no single table contains all the information you need. You may also want to give users access to only part of the data in a table. Views provide a way to subset the table so that you deal with only the data you need. A view reduces complexity and, at the same time, restricts access. You can create a view using Operations Navigator. Or you can use the SQL CREATE VIEW statement. Using the CREATE VIEW statement, dening a view on a table is like creating a new table containing just the columns and rows you want. When your application uses a view, it cannot access rows or columns of the table that are not included in the view. However, rows that do not match the selection criteria may still be inserted through a view if the SQL WITH CHECK OPTION is not used. See Chapter 6. Data Integrity for more information on using WITH CHECK OPTION.

28

DB2 UDB for AS/400 SQL Programming V4R4

| | | | |

For examples of creating a view using interactive SQL, see the following: v Example: Example: Creating a view on a single table or v Example: Example: Creating a view combining data from more than one table on page 30 In order to create a view you must have the proper authority to the tables or physical les on which the view is based. See the CREATE VIEW statement in the SQL Reference for a list of authorities needed. If you do not specify column names in the view denition, the column names will be the same as those for the table on which the view is based. You can make changes to a table through a view even if the view has a different number of columns or rows than the table. For INSERT, columns in the table that are not in the view must have a default value. You can use the view as though it were a table, even though the view is totally dependent on one or more tables for data. The view has no data of its own and therefore requires no storage for the data. Because a view is derived from a table that exists in storage, when you update the view data, you are really updating data in the table. Therefore, views are automatically kept up-to-date as the tables they depend on are updated. See Creating and Using Views on page 95 for additional information.

Example: Creating a view on a single table


The following example shows how to create a view on a single table. The view is built on the INVENTORY_LIST table. The table has six columns, but the view uses only three of the columns: ITEM_NUMBER, LAST_ORDER_DATE, and QUANTITY_ON_HAND. The order of the columns in the SELECT clause is the order in which they will appear in the view. The view will contain only the rows for items that were ordered in the last two weeks. The CREATE VIEW statement looks like this:
CREATE VIEW SAMPLECOLL.RECENT_ORDERS AS SELECT ITEM_NUMBER, LAST_ORDER_DATE, QUANTITY_ON_HAND FROM SAMPLECOLL.INVENTORY_LIST WHERE LAST_ORDER_DATE > CURRENT DATE - 14 DAYS

In the example above, the columns in the view have the same name as the columns in the table because no column list follows the view name. The collection that the view is created into does not need to be the same collection as the table it is built over. Any collection or library could be used. The following display is the result of running the SQL statement:
SELECT * FROM SAMPLECOLL.RECENT_ORDERS

Chapter 2. Getting Started with SQL

29

Display Data Position to line . . . . . ....+....1....+....2....+. ITEM LAST QUANTITY NUMBER ORDER ON DATE HAND 303476 05/30/94 100 ******** End of data ******** F3=Exit F12=Cancel F19=Left

Data width . . . . . . : Shift to column . . . . . .

26

F20=Right

F21=Split

Bottom

The only row selected by the view is the row that we updated to have the current date. All other dates in our table still have the null value so they are not returned.

Example: Creating a view combining data from more than one table
You can create a view that combines data from two or more tables by naming more than one table in the FROM clause. In the following example, the INVENTORY_LIST table contains a column of item numbers called ITEM_NUMBER, and a column with the cost of the item, UNIT_COST. These are joined with the ITEM_NUMBER column and the SUPPLIER_COST column of the SUPPLIERS table. A WHERE clause is used to limit the number of rows returned. The view will only contain those item numbers for suppliers that can supply an item at lower cost than the current unit cost. The CREATE VIEW statement looks like this:
CREATE VIEW SAMPLECOLL.LOWER_COST AS SELECT SUPPLIER_NUMBER, A.ITEM_NUMBER, UNIT_COST, SUPPLIER_COST FROM SAMPLECOLL.INVENTORY_LIST A, SAMPLECOLL.SUPPLIERS B WHERE A.ITEM_NUMBER = B.ITEM_NUMBER AND UNIT_COST > SUPPLIER_COST

The following table is the result of running the SQL statement:


SELECT * FROM SAMPLECOLL.LOWER_COST
Data width . . . . . . : Position to line . . . . . Shift to column . . . . . . ....+....1....+....2....+....3....+....4....+....5. SUPPLIER_NUMBER ITEM UNIT SUPPLIER_COST NUMBER COST 9988 153047 10.00 8.00 2424 153047 10.00 9.00 1234 229740 1.50 1.00 3366 303476 2.00 1.50 3366 073956 20.00 17.00 ******** End of data ******** F3=Exit F12=Cancel F19=Left F20=Right F21=Split Display Data 51

Bottom

The rows that can be seen through this view are only those rows that have a supplier cost that is less than the unit cost.

30

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 3. Basic Concepts and Techniques


This chapter explains some of the concepts used in SQL statements. It discusses many of the common statements and clauses in SQL. The examples in this chapter refer to the tables shown in Appendix A. DB2 UDB for AS/400 Sample Tables.

Using Basic SQL Statements and Clauses


This section shows the basic SQL statements and clauses that retrieve, update, delete, and insert data into tables and views. The SQL statements used are SELECT, UPDATE, DELETE, and INSERT. FETCH statements can be used in an application program to access data as well. This statement is covered in Chapter 4. Examples using these SQL statements are supplied to help you develop SQL applications. Detailed syntax and parameter descriptions for SQL statements are given in the DB2 UDB for AS/400 SQL Reference book. You can write SQL statements on one line or on many lines. The rules for the continuation of lines are the same as those of the host language (the language the program is written in). Notes: 1. The SQL statements described in this section can be run on SQL tables and views, and database physical and logical les. The tables, views, and les can be either in an SQL collection or in a library. 2. Character strings specied in an SQL statement (such as those used with WHERE or VALUES clauses) are case sensitive; that is, uppercase characters must be entered in uppercase and lowercase characters must be entered in lowercase.
WHERE ADMRDEPT='a00' WHERE ADMRDEPT='A00' (does not return a result) (returns a valid department number)

Comparisons may not be case sensitive if a shared-weight sort sequence is being used where uppercase and lowercase characters are treated as the same character.

The INSERT Statement


You can use the INSERT statement to add new rows to a table or view in one of the following ways: v Specifying values in the INSERT statement for columns of the single row to be added. v Specifying the blocked form of the INSERT statement to add multiple rows. Using the Blocked Insert Statement on page 70 explains how to use the blocked form of the INSERT statement to add multiple rows to a table. v Including a select-statement in the INSERT statement to tell SQL what data for the new row is contained in another table or view. Inserting Rows into a Table Using a Select-Statement on page 69 explains how to use the select-statement within an INSERT statement to add zero, one, or many rows to a table. Note: Because views are built on tables and actually contain no data, working with views can be confusing. See Creating and Using Views on page 95 for more information on inserting data by using a view.
Copyright IBM Corp. 1997, 1999

31

For every row you insert, you must supply a value for each column dened with the NOT NULL attribute if that column does not have a default value. The INSERT statement for adding a row to a table or view may look like this:
INSERT INTO table-name (column1, column2, ... ) VALUES (value-for-column1, value-for-column2, ... )

The INTO clause names the columns for which you specify values. The VALUES clause species a value for each column named in the INTO clause. You must provide a value in the VALUES clause for each column named in an INSERT statements column list. The column name list can be omitted if all columns in the table have a value provided in the VALUES clause. If a column has a default value, the keyword DEFAULT may be used as a value on the VALUES clause. It is a good idea to name all columns into which you are inserting values because: v Your INSERT statement is more descriptive. v You can verify that you are giving the values in the proper order based on the column names. v You have better data independence. The order in which the columns are dened in the table does not affect your INSERT statement. If the column is dened to allow null values or to have a default, you do not need to name it in the column name list or specify a value for it. The default value is used. If the column is dened to have a default value, the default value is placed in the column. If DEFAULT was specied for the column denition without an explicit default value, SQL places the default value for that data type in the column. If the column does not have a default value dened for it, but is dened to allow the null value (NOT NULL was not specied in the column denition), SQL places the null value in the column. v For numeric columns, the default value is 0. v For xed length character or graphic columns, the default is blanks. v For varying length character or graphic columns or LOB columns, the default is a zero length string. v For date, time, and timestamp columns, the default value is the current date, time, or timestamp. When inserting a block of records, the default date/time value is extracted from the system when the block is written. This means that the column will be assigned the same default value for each row in the block. v For DataLink columns, the default value corresponds to DLVALUE(,URL,). v For distinct-type columns, the default value is the default value of the corresponding source type. When your program attempts to insert a row that duplicates another row already in the table, an error might occur. Multiple null values may or may not be considered duplicate values, depending on the option used when the index was created. v If the table has a primary key, unique key, or unique index, the row is not inserted. Instead, SQL returns an SQLCODE of 803. v If the table does not have a primary key, unique key, or unique index, the row can be inserted without error. If SQL nds an error while running the INSERT statement, it stops inserting data. If you specify COMMIT(*ALL), COMMIT(*CS), COMMIT(*CHG), or COMMIT(*RR), no rows are inserted. Rows already inserted by this statement, in the case of INSERT

| |

| | |

32

DB2 UDB for AS/400 SQL Programming V4R4

with a select-statement or blocked insert, are deleted. If you specify COMMIT(*NONE), any rows already inserted are not deleted. A table created by SQL is created with the Reuse Deleted Records parameter of *YES. This allows the database manager to reuse any rows in the table that were marked as deleted. The CHGPF command can be used to change the attribute to *NO. This causes INSERT to always add rows to the end of the table. The order in which rows are inserted does not guarantee the order in which they will be retrieved. If the row is inserted without error, the SQLERRD(3) eld of the SQLCA has a value of 1. Note: For blocked INSERT or for INSERT with select-statement, more than one row can be inserted. The number of rows inserted is reected in SQLERRD(3).

The UPDATE Statement


To change the data in a table, use the UPDATE statement. With the UPDATE statement, you can change the value of one or more columns in each row that satises the search condition of the WHERE clause. The result of the UPDATE statement is one or more changed column values in zero or more rows of a table (depending on how many rows satisfy the search condition specied in the WHERE clause). The UPDATE statement looks like this:
UPDATE table-name SET column-1 = value-1, column-2 = value-2, ... WHERE search-condition ...

For example, suppose an employee was relocated. To update several items of the employees data in the CORPDATA.EMPLOYEE table to reect the move, you can specify:
UPDATE CORPDATA.EMPLOYEE SET JOB = :PGM-CODE, PHONENO = :PGM-PHONE WHERE EMPNO = :PGM-SERIAL

Use the SET clause to specify a new value for each column you want to update. The SET clause names the columns you want updated and provides the values you want them changed to. The value you specify can be: A column name. Replace the columns current value with the contents of another column in the same row. A constant. Replace the columns current value with the value provided in the SET clause. A null value. Replace the columns current value with the null value, using the keyword NULL. The column must be dened as capable of containing a null value when the table was created, or an error occurs. A host variable. Replace the columns current value with the contents of a host variable. A special register. Replace the columns current value with a special register value; for example, USER. An expression. Replace the columns current value with the value that results from an expression. The expression can contain any of the values in this list.
Chapter 3. Basic Concepts and Techniques

33

A scalar subselect. Replace the columns current value with the value that the subquery returns. The DEFAULT keyword. Replace the columns current value with the default value of the column. The column must have a default value dened for it or allow the NULL value, or an error occurs. The following is an example of a statement that uses many different values:
UPDATE WORKTABLE SET COL1 = 'ASC', COL2 = NULL, COL3 = :FIELD3, COL4 = CURRENT TIME, COL5 = AMT - 6.00, COL6 = COL7 WHERE EMPNO = :PGM-SERIAL

To identify the rows to be updated, use the WHERE clause: v To update a single row, use a WHERE clause that selects only one row. v To update several rows, use a WHERE clause that selects only the rows you want to update. You can omit the WHERE clause. If you do, SQL updates each row in the table or view with the values you supply. If the database manager nds an error while running your UPDATE statement, it stops updating and returns a negative SQLCODE. If you specify COMMIT(*ALL), COMMIT(*CS), COMMIT(*CHG), or COMMIT(*RR), no rows in the table are changed (rows already changed by this statement, if any, are restored to their previous values). If COMMIT(*NONE) is specied, any rows already changed are not restored to previous values. If the database manager cannot nd any rows that satisfy the search condition, an SQLCODE of +100 is returned. Note: UPDATE with a WHERE clause may have updated more than one row. The number of rows updated is reected in SQLERRD(3).

The DELETE Statement


To remove rows from a table, use the DELETE statement. When you DELETE a row, you remove the entire row. DELETE does not remove specic columns from the row. The result of the DELETE statement is the removal of zero or more rows of a table (depending on how many rows satisfy the search condition specied in the WHERE clause). If you omit the WHERE clause from a DELETE statement, SQL removes all the rows of the table. The DELETE statement looks like this:
DELETE FROM table-name WHERE search-condition ...

For example, suppose department D11 was moved to another place. You want to delete each row in the CORPDATA.EMPLOYEE table with a WORKDEPT value of D11 as follows:
DELETE FROM CORPDATA.EMPLOYEE WHERE WORKDEPT = 'D11'

The WHERE clause tells SQL which rows you want to delete from the table. SQL deletes all the rows that satisfy the search condition from the base table. You can

34

DB2 UDB for AS/400 SQL Programming V4R4

omit the WHERE clause, but it is best to include one, because a DELETE statement without a WHERE clause deletes all the rows from the table or view. To delete a table denition as well as the table contents, issue the DROP statement (described in the DB2 UDB for AS/400 SQL Reference book). If SQL nds an error while running your DELETE statement, it stops deleting data and returns a negative SQLCODE. If you specify COMMIT(*ALL), COMMIT(*CS), COMMIT(*CHG), or COMMIT(*RR), no rows in the table are deleted (rows already deleted by this statement, if any, are restored to their previous values). If COMMIT(*NONE) is specied, any rows already deleted are not restored to their previous values. If SQL cannot nd any rows that satisfy the search condition, an SQLCODE of +100 is returned. Note: DELETE with WHERE clause may have deleted more than one row. The number of rows deleted is reected in SQLERRD(3).

The SELECT INTO Statement


| | | | | | | You can use a variety of statements and clauses to query your data. One way to do this is to use the SELECT INTO statement in a program to retrieve a specic row (for example, the row for an employee). Furthermore, in this example, a variety of clauses are used to gather data in a specic way. You can use the The WHERE Clause on page 38, The GROUP BY Clause on page 40, The HAVING Clause on page 42, and The ORDER BY Clause on page 43 to tailor your query to gather data in a specic manner. The format and syntax shown here are very basic. SELECT INTO statements can be more varied than the examples presented in this chapter. A SELECT INTO statement can include the following: 1. The name of each column you want 2. The name of each host variable used to contain retrieved data 3. The name of the table or view that contains the data 4. A search condition to uniquely identify the row that contains the information you want 5. The name of each column used to group your data 6. A search condition that uniquely identies a group that contains the information you want 7. The order of the results so a specic row among duplicates can be returned. A SELECT INTO statement looks like this:
SELECT column names INTO host variables FROM table or view name WHERE search condition GROUP BY column names HAVING search condition ORDER BY column-name

The SELECT, INTO, and FROM clauses must be specied. The other clauses are optional.

Chapter 3. Basic Concepts and Techniques

35

The INTO clause names the host variables (variables in your program used to contain retrieved column values). The value of the rst column specied in the SELECT clause is put into the rst host variable named in the INTO clause; the second value is put into the second host variable, and so on. The result table for a SELECT INTO should contain just one row. For example, each row in the CORPDATA.EMPLOYEE table has a unique EMPNO (employee number) column. The result of a SELECT INTO statement for this table if the WHERE clause contains an equal comparison on the EMPNO column, would be exactly one row (or no rows). Finding more than one row is an error, but one row is still returned. You can control which row will be returned in this error condition by specifying the ORDER BY clause. If you use the ORDER BY clause, the rst row in the result table is returned. If you want more than one row to be the result of a select-statement, use a DECLARE CURSOR statement to select the rows, followed by a FETCH statement to move the column values into host variables one or many rows at a time. Using cursors is described in Chapter 4. Using a Cursor on page 55. The FROM clause names the table (or view) that contains the data you are interested in. For example, assume that each department listed in the CORPDATA.DEPARTMENT table has a unique department number. You want to retrieve the department name and manager number from the CORPDATA.DEPARTMENT table for department C01. To do this, your program can set PGM-DEPT to the value C01 and issue:
SELECT DEPTNAME, MGRNO INTO :PGM-DEPTNAME, :PGM-MGRNO FROM CORPDATA.DEPARTMENT WHERE DEPTNO = :PGM-DEPT

When the statement is run, the result is one row:


PGM-DEPTNAME INFORMATION CENTER PGM-MGRNO 000030

These values are assigned to the host variables PGM-DEPTNAME and PGM-MGRNO. If SQL is unable to nd a row that satises the search condition, an SQLCODE of +100 is returned. If SQL nds errors while running your select-statement, a negative SQLCODE is returned. If SQL nds more host variables than results, +326 is returned. You can retrieve data from a view in exactly the same way you retrieve data from a table. However, there are several restrictions when you attempt to update, insert, or delete data in a view. These restrictions are described in Creating and Using Views on page 95.

Data retrieval errors


If SQL nds that a retrieved character or graphic column is too long to be placed in a host variable, SQL does the following:

36

DB2 UDB for AS/400 SQL Programming V4R4

v Truncates the data while assigning the value to the host variable. v Sets SQLWARN0 and SQLWARN1 in the SQLCA to the value 'W'. v Sets the indicator variable, if provided, to the length of the value before truncation. If SQL nds a data mapping error while running a statement, one of two things occurs: v If the error occurs on an expression in the SELECT list and an indicator variable is provided for the expression in error: SQL returns a 2 for the indicator variable corresponding to the expression in error. SQL returns all valid data for that row. SQL returns a positive SQLCODE. v If an indicator variable is not provided, SQL returns the corresponding negative SQLCODE in the SQLCA. Data mapping errors include: v +138 - Argument of the substringing function is not valid. v +180 - Syntax for a string representation of a date, time, or timestamp is not valid. v +181 - String representation of a date, time, or timestamp is not a valid value. v +183 - Invalid result from a date/time expression. The resulting date or timestamp is not within the valid range of dates or timestamps. v +191 - MIXED data is not properly formed. v +304 - Numeric conversion error (for example, overow, underow, or division by zero). v +331 - Characters cannot be converted. v +420 - Character in the CAST argument is not valid. v +802 - Data conversion or data mapping error. For data mapping errors, the SQLCA reports only the last error detected. The indicator variable corresponding to each result column having an error is set to 2. If the full-select contains DISTINCT in the select list and a column in the select list contains numeric data that is not valid, the data is considered equal to a null value if the query is completed as a sort. If an existing index is used, the data is not considered equal to a null. The impact of data mapping errors on the ORDER BY clause depends on the situation: v If the data mapping error occurs while data is being assigned to a host variable in a SELECT INTO or FETCH statement, and that same expression is used in the ORDER BY clause, the result record is ordered based on the value of the expression. It is not ordered as if it were a null (higher than all other values). This is because the expression was evaluated before the assignment to the host variable is attempted. v If the data mapping error occurs while an expression in the select-list is being evaluated and the same expression is used in the ORDER BY clause, the result column is normally ordered as if it were a null value (higher than all other values). If the ORDER BY clause is implemented by using a sort, the result column is ordered as if it were a null value. If the ORDER BY clause is
Chapter 3. Basic Concepts and Techniques

37

implemented by using an existing index, in the following cases, the result column is ordered based on the actual value of the expression in the index: The expression is a date column with a date format of *MDY, *DMY, *YMD, or *JUL, and a date conversion error occurs because the date is not within the valid range for dates. The expression is a character column and a character could not be converted. The expression is a decimal column and a numeric value that is not valid is detected.

The SELECT Clause


With the SELECT clause (the rst part of a select-statement), you specify the name of each column you want to retrieve. For example:
SELECT EMPNO, LASTNAME, WORKDEPT . . .

You can specify that only one column be retrieved, or as many as 8000 columns. The value of each column you name is retrieved in the order specied in the SELECT clause. If you want to retrieve all columns (in the same order as they appear in the row), use an asterisk (*) instead of naming the columns:
SELECT * . . .

When using the select-statement in an application program, list the column names to give your program more data independence. There are two reasons for this: 1. When you look at the source code statement, you can easily see the one-to-one correspondence between the column names in the SELECT clause and the host variables named in the INTO clause. 2. If a column is added to a table or view you access and you use SELECT * ..., and you create the program again from source, the INTO clause does not have a matching host variable named for the new column. The extra column causes you to get a warning (not an error) in the SQLCA (SQLWARN4 will contain a W).

The WHERE Clause


The WHERE clause species a search condition that identies the row or rows you want to retrieve, update, or delete. The number of rows you process with an SQL statement then depends on the number of rows that satisfy the WHERE clause search condition. A search condition consists of one or more predicates. A predicate species a test that you want SQL to apply to a specied row or rows of a table. In the following example, WORKDEPT = 'C01' is a predicate, WORKDEPT and 'C01' are expressions, and the equal sign (=) is a comparison operator. Note that character values are enclosed in apostrophes ('); numeric values are not. This applies to all constant values wherever they are coded within an SQL statement. For example, to specify that you are interested in the rows where the department number is C01, you would say:
... WHERE WORKDEPT = 'C01'

38

DB2 UDB for AS/400 SQL Programming V4R4

In this case, the search condition consists of one predicate: WORKDEPT = 'C01'. If the search condition contains character or UCS-2 graphic column predicates, the sort sequence that is in effect when the query is run is applied to those predicates. See Using Sort Sequence in SQL on page 50 for more information on sort sequence and selection.

Using Expressions in the WHERE Clause


An expression in a WHERE clause names or species something you want to compare to something else. Each expression, when evaluated by SQL, is a character string, date/time/timestamp, or a numeric value. The expressions you specify can be: v A column name names a column. For example:
... WHERE EMPNO = '000200'

EMPNO names a column that is dened as a 6-byte character value. Equality comparisons (that is, X = Y or X <> Y) can be performed on character data. Other types of comparisons can also be evaluated for character data.
However, you cannot compare character strings to numbers. You also cannot perform arithmetic operations on character data (even though EMPNO is a character string that appears to be a number). You can add and subtract date/time values. v An expression identies two values that are added (+), subtracted (), multiplied (*), divided (/), have exponentiation (**), or concatenated (CONCAT or ||) to result in a value. The operands of an expression can be: A constant (that is, a literal value) A column A host variable A value returned from a function A special register Another expression For example:
... WHERE INTEGER(PRENDATE - PRSTDATE) > 100

When the order of evaluation is not specied by parentheses, the expression is evaluated in the following order: 1. Prex operators 2. Exponentiation 3. Multiplication, division, and concatenation 4. Addition and subtraction Operators on the same precedence level are applied from left to right. v A constant species a literal value for the expression. For example:
... WHERE 40000 < SALARY

SALARY names a column that is dened as an 9-digit packed decimal value (DECIMAL(9,2)). It is compared to the numeric constant 40000. v A host variable identies a variable in an application program. For example:
... WHERE EMPNO = :EMP
Chapter 3. Basic Concepts and Techniques

39

v A special register identies a special value generated by the database manager. For example:
... WHERE LASTNAME = USER

v The NULL value species the condition of having an unknown value.


... WHERE DUE_DATE IS NULL

A search condition need not be limited to two column names or constants separated by arithmetic or comparison operators. You can develop a complex search condition that species several predicates separated by AND and OR. No matter how complex the search condition, it supplies a TRUE or FALSE value when evaluated against a row. There is also an unknown truth value, which is effectively false. That is, if the value of a row is null, this null value is not returned as a result of a search because it is not less than, equal to, or greater than the value specied in the search condition. More complex search conditions and predicates are described in Performing Complex Search Conditions on page 72. To fully understand the WHERE clause, you need to know how SQL evaluates search conditions and predicates, and compares the values of expressions. This topic is discussed in the DB2 UDB for AS/400 SQL Reference book.

Comparison Operators
SQL supports the following comparison operators:
= <> or = < > <= or > > = or < Equal to Not equal to Less than Greater than Less than or equal to (or not greater than) Greater than or equal to (or not less than)

The NOT Keyword


You can precede a predicate with the NOT keyword to specify that you want the opposite of the predicates value (that is, TRUE if the predicate is FALSE, or vice versa). NOT applies only to the predicate it precedes, not to all predicates in the WHERE clause. For example, to indicate that you are interested in all employees except those working in department C01, you could say:
... WHERE NOT WORKDEPT = 'C01'

which is equivalent to:


... WHERE WORKDEPT <> 'C01'

The GROUP BY Clause


Without a GROUP BY clause, the application of SQL column functions returns one row. When GROUP BY is used, the function is applied to each group, thereby returning as many rows as there are groups. | | | | | The GROUP BY clause allows you to nd the characteristics of groups of rows rather than individual rows. When you specify a GROUP BY clause, SQL divides the selected rows into groups such that the rows of each group have matching values in one or more columns or expressions. Next, SQL processes each group to produce a single-row result for the group. You can specify one or more columns or

40

DB2 UDB for AS/400 SQL Programming V4R4

| | |

expressions in the GROUP BY clause to group the rows. The items you specify in the SELECT statement are properties of each group of rows, not properties of individual rows in a table or view. For example, the CORPDATA.EMPLOYEE table has several sets of rows, and each set consists of rows describing members of a specic department. To nd the average salary of people in each department, you could issue:

The SQL statement:

Results in: fetch WORK-DEPT AVG-SALARY 1 2 ... A00 B01 ... 42833 41250 ...

RV2W551-1

The result is several rows, one for each department. Notes: 1. Grouping the rows does not mean ordering them. Grouping puts each selected row in a group, which SQL then processes to derive characteristics of the group. Ordering the rows puts all the rows in the results table in ascending or descending collating sequence. ( The ORDER BY Clause on page 43 describes how to do this.) 2. If there are null values in the column you specify in the GROUP BY clause, a single-row result is produced for the data in the rows with null values. 3. If the grouping occurs over character or UCS-2 graphic columns, the sort sequence in effect when the query is run is applied to the grouping. See Using Sort Sequence in SQL on page 50 for more information on sort sequence and selection. | | | | When you use GROUP BY, you list the columns or expressions you want SQL to use to group the rows. For example, suppose you want a list of the number of people working on each major project described in the CORPDATA.PROJECT table. You could issue:

The SQL statement:

Results in: fetch SUM-PR 1 2 3 ... 6 5 10 ... MAJ-PROJ AD3100 AD3110 MA2100 ...

RV2W552-3

Chapter 3. Basic Concepts and Techniques

41

The result is a list of the companys current major projects and the number of people working on each project. | | | | You can also specify that you want the rows grouped by more than one column or expression. For example, you could issue a select-statement to nd the average salary for men and women in each department, using the CORPDATA.EMPLOYEE table. To do this, you could issue:

The SQL statement:

Results in: fetch DEPT 1 2 3 4 ... A00 A00 B01 C01 ... SEX F M M F ... AVG-WAGES 52750 37875 41250 30156 ...

RV2W553-1

Because you did not include a WHERE clause in this example, SQL examines and process all rows in the CORPDATA.EMPLOYEE table. The rows are grouped rst by department number and next (within each department) by sex before SQL derives the average SALARY value for each group.

The HAVING Clause


You can use the HAVING clause to specify a search condition for the groups selected based on a GROUP BY clause. The HAVING clause says that you want only those groups that satisfy the condition in that clause. Therefore, the search condition you specify in the HAVING clause must test properties of each group rather than properties of individual rows in the group. The HAVING clause follows the GROUP BY clause and can contain the same kind of search condition you can specify in a WHERE clause. In addition, you can specify column functions in a HAVING clause. For example, suppose you wanted to retrieve the average salary of women in each department. To do this, you would use the AVG column function and group the resulting rows by WORKDEPT and specify a WHERE clause of SEX = 'F'. To specify that you want this data only when all the female employees in the selected department have an education level equal to or greater than 16 (a college graduate), use the HAVING clause. The HAVING clause tests a property of the group. In this case, the test is on MIN(EDLEVEL), which is a group property:

42

DB2 UDB for AS/400 SQL Programming V4R4

The SQL statement:

Results in: fetch DEPT 1 2 3 A00 C01 D11 AVG-WAGES 52750 30156 24476 MIN-EDUC 18 16 17

RV2W554-3

You can use multiple predicates in a HAVING clause by connecting them with AND and OR, and you can use NOT for any predicate of a search condition. Note: If you intend to update a column or delete a row, you cannot include a GROUP BY or HAVING clause in the SELECT statement within a DECLARE CURSOR statement. (The DECLARE CURSOR statement is described in Chapter 4. Using a Cursor on page 55.) Predicates with arguments that are not column functions can be coded in either WHERE or HAVING clauses. It is usually more efficient to code the selection criteria in the WHERE clause. It is processed during the initial phase of the query processing. The HAVING selection is performed in post processing of the result table. If the search condition contains predicates involving character or UCS-2 graphic columns, the sort sequence in effect when the query is run is applied to those predicates. See Using Sort Sequence in SQL on page 50 for more information on sort sequence and selection.

The ORDER BY Clause


| | | | | You can specify that you want selected rows retrieved in a particular order, sorted by ascending or descending collating sequence of a columns value, with the ORDER BY clause. You can use an ORDER BY clause as you would a GROUP BY clause: specify the columns or expressions you want SQL to use when retrieving the rows in a collated sequence. For example, to retrieve the names and department numbers of female employees listed in the alphanumeric order of their department numbers, you could use this select-statement:

Chapter 3. Basic Concepts and Techniques

43

The SQL statement:

Results in: fetch PGM-NAME3 1 2 3 4 5 6 7 8 9 10 11 12 13 HAAS KWAN QUINTANA NICHOLLS PIANKA SCOUTTEN LUTZ PULASKI JOHNSON PEREZ HENDERSON SCHNEIDER SETRIGHT DEPT A00 C01 C01 C01 D11 D11 D11 D21 D21 D21 E11 E11 E11
RV2W555-3

Notes: 1. All columns named in the ORDER BY clause must also be named in the SELECT list. 2. Null values are ordered as the highest value. | | | | To order by a column function, or something other than a column name, you can specify an AS clause in the select-list. To order by an expression, you can either specify the exact same expression in the ORDER BY clause, or you can specify an AS clause in the select-list. The AS clause names the result column. This name can be specied in the ORDER BY clause. To order by a name specied in the AS clause: v The name must be unique in the select-list. v The name must not be qualied. For example, to retrieve the full name of employees listed in alphabetic order, you could use this select-statement:
SELECT LASTNAME CONCAT FIRSTNAME AS FULLNAME ... ORDER BY FULLNAME

| | | |

This select-statement could optionally be written as:


SELECT LASTNAME CONCAT FIRSTNAME ORDER BY LASTNAME CONCAT FIRSTNAME

Instead of naming the columns to order the results, you can use a number. For example, ORDER BY 3 species that you want the results ordered by the third column of the results table, as specied by the select-statement. Use a number to order the rows of the results table when the sequencing value is not a named column. You can also specify whether you want SQL to collate the rows in ascending (ASC) or descending (DESC) sequence. An ascending collating sequence is the default. In the above select-statement, SQL rst returns the row with the lowest department

44

DB2 UDB for AS/400 SQL Programming V4R4

number (alphabetically and numerically), followed by rows with higher department numbers. To order the rows in descending collating sequence based on the department number, specify:
... ORDER BY WORKDEPT DESC

As with GROUP BY, you can specify a secondary ordering sequence (or several levels of ordering sequences) as well as a primary one. In the example above, you might want the rows ordered rst by department number, and within each department, ordered by employee name. To do this, specify:
... ORDER BY WORKDEPT, LASTNAME

If character columns or UCS-2 graphic columns are used in the ORDER BY clause, ordering for these columns is based on the sort sequence in effect when the query is run. See Using Sort Sequence in SQL on page 50 for more information on sort sequence and its affect on ordering.

Using Null Values


A null value indicates the absence of a column value in a row. A null value is not the same as zero or all blanks. A null value is the same as unknown. Null values can be used as a condition in the WHERE and HAVING clauses, and as a mathematical argument. For example, a WHERE clause can specify a column that, for some rows, contains a null value. Normally, a comparison predicate using a column that contains null values does not select a row that has a null value for the column. This is because a null value is neither less than, equal to, nor greater than the value specied in the condition. To select the values for all rows that contain a null value for the manager number, you could specify:
SELECT DEPTNO, DEPTNAME, ADMRDEPT FROM CORPDATA.DEPARTMENT WHERE MGRNO IS NULL

The result would be:


DEPTNO DEPTNAME D01 DEVELOPMENT CENTER ADMRDEPT A00

To get the rows that do not have a null value for the manager number, you could change the WHERE clause like this:
WHERE MGRNO IS NOT NULL

For more information on the use of null values, see the DB2 UDB for AS/400 SQL Reference book.

Using Special Registers


You can specify certain special registers in SQL statements. For locally run SQL statements, the special registers and their contents are shown in the following table:
Special Registers CURRENT DATE CURRENT_DATE Contents The current date.

Chapter 3. Basic Concepts and Techniques

45

Special Registers CURRENT TIME CURRENT_TIME CURRENT TIMESTAMP CURRENT_TIMESTAMP CURRENT TIMEZONE CURRENT_TIMEZONE

Contents The current time. The current date and time in timestamp format. A duration of time that links local time to Universal Coordinated Time (UTC) using the formula: local time - CURRENT TIMEZONE = UTC It is taken from the system value QUTCOFFSET.

CURRENT SERVER CURRENT_SERVER USER CURRENT PATH CURRENT_PATH CURRENT FUNCTION PATH

The name of the relational database as contained in the relational database directory table in the relational database directory. The run-time authorization identier (user prole) of the job. The SQL path used to resolve unqualied data type names, procedure names, and function names.

If a single statement contains more than one reference to any of CURRENT DATE, CURRENT TIME, or CURRENT TIMESTAMP special registers, or the CURDATE, CURTIME, or NOW scalar functions, all values are based on a single clock reading. For remotely run SQL statements, the special registers and their contents are shown in the following table:
Special Registers CURRENT DATE CURRENT_DATE CURRENT TIME CURRENT_TIME CURRENT TIMESTAMP CURRENT_TIMESTAMP CURRENT TIMEZONE CURRENT_TIMEZONE CURRENT SERVER CURRENT_SERVER USER CURRENT PATH CURRENT_PATH CURRENT FUNCTION PATH Contents The current date and time at the remote system, not the local system.

A duration of time that links the remote system time to UTC. The name of the relational database as contained in the relational database directory table in the relational database directory. The run-time authorization identier of the server job on the remote system. The current path value at the remote system.

When a query over a distributed table references a special register, the contents of the special register on the system that requests the query are used. For more information on distributed tables, see DB2 Multisystem for AS/400 book.

46

DB2 UDB for AS/400 SQL Programming V4R4

Using Date, Time, and Timestamp


Date, time, and timestamp are data types represented in an internal form not seen by the SQL user. Date, time, and timestamp can be represented by character string values and assigned to character string variables. The database manager recognizes the following as date, time, and timestamp values: v A value returned by the DATE, TIME, or TIMESTAMP scalar functions. v A value returned by the CURRENT DATE, CURRENT TIME, or CURRENT TIMESTAMP special registers. v A character string when it is an operand of an arithmetic expression or a comparison and the other operand is a date, time, or timestamp. For example, in the predicate:
... WHERE HIREDATE < '1950-01-01'

if HIREDATE is a date column, the character string 1950-01-01 is interpreted as a date. v A character string variable or constant used to set a date, time, or timestamp column in either the SET clause of an UPDATE statement, or the VALUES clause of an INSERT statement. For more information on character string formats of date, time, and timestamp values, see Chapter 2 of the DB2 UDB for AS/400 SQL Reference book .

Specifying Current Date and Time Values


You can specify a current date, time, or timestamp in an expression by specifying one of three special registers: CURRENT DATE, CURRENT TIME, or CURRENT TIMESTAMP. The value of each is based on a time-of-day clock reading obtained during the running of the statement. Multiple references to CURRENT DATE, CURRENT TIME, or CURRENT TIMESTAMP within the same SQL statement use the same value. The following statement returns the age (in years) of each employee in the EMPLOYEE table when the statement is run:
SELECT YEAR(CURRENT DATE - BIRTHDATE) FROM CORPDATA.EMPLOYEE

The CURRENT TIMEZONE special register allows a local time to be converted to Universal Coordinated Time (UTC). For example, if you have a table named DATETIME, containing a time column type with a name of STARTT, and you want to convert STARTT to UTC, you can use the following statement:
SELECT STARTT - CURRENT TIMEZONE FROM DATETIME

Date/Time Arithmetic
Addition and subtraction are the only arithmetic operators applicable to date, time, and timestamp values. You can increment and decrement a date, time, or timestamp by a duration; or subtract a date from a date, a time from a time, or a timestamp from a timestamp. For a detailed description of date and time arithmetic, see Chapter 2 of the DB2 UDB for AS/400 SQL Reference book.

Chapter 3. Basic Concepts and Techniques

47

Creating and using ALIAS names


| | | | When you refer to an existing table or view to an AS/400 physical le that consists of multiple members, you can avoid using le overrides by creating an alias. You can use the SQL CREATE ALIAS statement to do this. Or you can use Operations Navigator. You can create an alias for v A table or view v A member of a table A table alias denes a name for the le, including the specic member name. You can use this alias name in an SQL statement in the same way that you would use a table name. Unlike overrides, alias names are objects that exist until they are dropped. For example, if there is a multiple member le MYLIB.MYFILE with members MBR1 and MBR2, an alias can be created for the second member so that SQL can easily refer to it.
CREATE ALIAS MYLIB.MYMBR2_ALIAS FOR MYLIB.MYFILE (MBR2)

| | | | |

When alias MYLIB.MYMBR2_ALIAS is specied on the following insert statement, the values are inserted into member MBR2 in MYLIB.MYFILE.
INSERT INTO MYLIB.MYMBR2_ALIAS VALUES('ABC', 6)

Alias names can also be specied on DDL statements. Assume that alias MYLIB.MYALIAS exists and is an alias for table MYLIB.MYTABLE. The following DROP statement will drop table MYLIB.MYTABLE.
DROP TABLE MYLIB.MYALIAS

If you really want to drop the alias name instead, specify the ALIAS keyword on the drop statement:
DROP ALIAS MYLIB.MYALIAS

Using LABEL ON
Sometimes the table name, column name, view name, alias name, or SQL package name does not clearly dene data that is shown on an interactive display of the table. By using the LABEL ON statement, you can create a more descriptive label for the table name, column name, view name, alias name, or SQL package name. These labels can be seen in the SQL catalog in the LABEL column. The LABEL ON statement looks like this:
LABEL ON TABLE CORPDATA.DEPARTMENT IS 'Department Structure Table' LABEL ON COLUMN CORPDATA.DEPARTMENT.ADMRDEPT IS 'Reports to Dept.'

After these statements are run, the table named DEPARTMENT displays the text description as Department Structure Table and the column named ADMRDEPT displays the heading Reports to Dept. The label for tables, views, SQL packages,

48

DB2 UDB for AS/400 SQL Programming V4R4

and column text cannot be more than 50 characters and the label for column headings cannot be more than 60 characters (blanks included). The following are examples of LABEL ON statements: This LABEL ON statement provides column heading 1 and column heading 2.
*...+....1....+....2....+....3....+....4....+....5....+....6..* LABEL ON COLUMN CORPDATA.EMPLOYEE.EMPNO IS 'Employee Number'

This LABEL ON statement provides 3 levels of column headings for the SALARY column.
*...+....1....+....2....+....3....+....4....+....5....+....6..* LABEL ON COLUMN CORPDATA.EMPLOYEE.SALARY IS 'Yearly Salary (in dollars)'

This LABEL ON statement removes the column heading for SALARY.


*...+....1....+....2....+....3....+....4....+....5....+....6..* LABEL ON COLUMN CORPDATA.EMPLOYEE.SALARY IS ''

An example of a DBCS column heading with two levels specied.


*...+....1....+....2....+....3....+....4....+....5....+....6..* LABEL ON COLUMN CORPDATA.EMPLOYEE.SALARY IS '<AABBCCDD> <EEFFGG>'

This LABEL ON statement provides column text for the EDLEVEL column.
*...+....1....+....2....+....3....+....4....+....5....+....6..* LABEL ON COLUMN CORPDATA.EMPLOYEE.EDLEVEL TEXT IS 'Number of years of formal education'

For more information about the LABEL ON statement, see the DB2 UDB for AS/400 SQL Reference book.

Using COMMENT ON
| | | | | After you create an SQL object such as a table, view, index, package, procedure, parameter, user-dened type, or function, you can supply information about it for future referral, such as the purpose of the object, who uses it, and anything unusual or special about it. You can also include similar information about each column of a table or view. Your comment must not be more than 2000 bytes. A comment is especially useful if your names do not clearly indicate the contents of the columns or objects. In that case, use a comment to describe the specic contents of the column or objects. An example of using COMMENT ON follows:
COMMENT ON TABLE CORPDATA.EMPLOYEE IS 'Employee table. Each row in this table represents one employee of the company.'

Chapter 3. Basic Concepts and Techniques

49

Getting Comments
| | | | | | | | | | After running a COMMENT ON statement for a table, your comments are stored in the REMARKS column of SYSTABLES. Comments for the other objects are stored in the REMARKS column of the appropriate catalog table. (If the indicated row had already contained a comment, the old comment is replaced by the new one.) The following example gets the comments added by the COMMENT ON statement in the previous example:
SELECT REMARKS FROM CORPDATA.SYSTABLES WHERE NAME = 'EMPLOYEE'

Using Sort Sequence in SQL


A sort sequence denes how characters in a character set relate to each other when they are compared or ordered. For more information on sort sequences, see Chapter 1 in DB2 UDB for AS/400 SQL Reference book. The sort sequence is used for all character and UCS-2 graphic comparisons performed in SQL statements. There are sort sequence tables for both single byte and double byte character data. Each single byte sort sequence table has an associated double byte sort sequence table, and vice versa. Conversion between the two tables is performed when necessary to implement a query. In addition, the CREATE INDEX statement has the sort sequence (in effect at the time the statement was run) applied to the character columns referred to in the index.

Sort Sequence Used with ORDER BY and Record Selection


To see how to use a sort sequence, run the examples in this section against the STAFF table shown in Table 2. Notice that the values in the JOB column are in mixed case. You can see the values 'Mgr', 'MGR', and 'mgr'.
Table 2. The STAFF Table
ID 10 20 30 40 50 60 70 80 90 100 NAME Sanders Pernal Merenghi OBrien Hanes Quigley Rothman James Koonitz Plotz DEPT 20 20 38 38 15 38 15 20 42 42 JOB Mgr Sales MGR Sales Mgr SALES Sales Clerk sales mgr YEARS 7 8 5 6 10 0 7 0 6 6 SALARY 18357.50 18171.25 17506.75 18006.00 20659.80 16808.30 16502.83 13504.60 18001.75 18352.80 COMM 0 612.45 0 846.55 0 650.25 1152.00 128.20 1386.70 0

In the following examples, the results are shown for each statement using: v *HEX sort sequence v Shared-weight sort sequence using the language identier ENU v Unique-weight sort sequence using the language identier ENU

50

DB2 UDB for AS/400 SQL Programming V4R4

Note: ENU is chosen as a language identier by specifying either SRTSEQ(*LANGIDUNQ), or SRTSEQ(*LANGIDSHR) and LANGID(ENU), on the CRTSQLxxx, STRSQL, or RUNSQLSTM commands, or by using the SET OPTION statement.

ORDER BY
The following SQL statement causes the result table to be sorted using the values in the JOB column:
SELECT * FROM STAFF ORDER BY JOB

Table 3 shows the result table using a *HEX sort sequence. The rows are sorted based on the EBCDIC value in the JOB column. In this case, all lowercase letters sort before the uppercase letters.
Table 3. SELECT * FROM STAFF ORDER BY JOB Using the *HEX Sort Sequence.
ID 100 90 80 10 50 30 20 40 70 60 NAME Plotz Koonitz James Sanders Hanes Merenghi Pernal OBrien Rothman Quigley DEPT 42 42 20 20 15 38 20 38 15 38 JOB mgr sales Clerk Mgr Mgr MGR Sales Sales Sales SALES YEARS 6 6 0 7 10 5 8 6 7 0 SALARY 18352.80 18001.75 13504.60 18357.50 20659.80 17506.75 18171.25 18006.00 16502.83 16808.30 COMM 0 1386.70 128.20 0 0 0 612.45 846.55 1152.00 650.25

Table 4 shows how sorting is done for a unique-weight sort sequence. After the sort sequence is applied to the values in the JOB column, the rows are sorted. Notice that after the sort, lowercase letters are before the same uppercase letters, and the values 'mgr', 'Mgr', and 'MGR' are adjacent to each other.
Table 4. SELECT * FROM STAFF ORDER BY JOB Using the Unique-Weight Sort Sequence for the ENU Language Identier.
ID 80 100 10 50 30 90 20 40 70 60 NAME James Plotz Sanders Hanes Merenghi Koonitz Pernal OBrien Rothman Quigley DEPT 20 42 20 15 38 42 20 38 15 38 JOB Clerk mgr Mgr Mgr MGR sales Sales Sales Sales SALES YEARS 0 6 7 10 5 6 8 6 7 0 SALARY 13504.60 18352.80 18357.50 20659.80 17506.75 18001.75 18171.25 18006.00 16502.83 16808.30 COMM 128.20 0 0 0 0 1386.70 612.45 846.55 1152.00 650.25

Table 5 on page 52 shows how sorting is done for a shared-weight sort sequence. After the sort sequence is applied to the values in the JOB column, the rows are sorted. For the
Chapter 3. Basic Concepts and Techniques

51

sort comparison, each lowercase letter is treated the same as the corresponding uppercase letter. In Table 5, notice that all the values 'MGR', 'mgr' and 'Mgr' are mixed together.
Table 5. SELECT * FROM STAFF ORDER BY JOB Using the Shared-Weight Sort Sequence for the ENU Language Identier.
ID 80 10 30 50 100 20 40 60 70 90 NAME James Sanders Merenghi Hanes Plotz Pernal OBrien Quigley Rothman Koonitz DEPT 20 20 38 15 42 20 38 38 15 42 JOB Clerk Mgr MGR Mgr mgr Sales Sales SALES Sales sales YEARS 0 7 5 10 6 8 6 0 7 6 SALARY 13504.60 18357.50 17506.75 20659.80 18352.80 18171.25 18006.00 16808.30 16502.83 18001.75 COMM 128.20 0 0 0 0 612.45 846.55 650.25 1152.00 1386.70

Record selection
The following SQL statement selects records with the value 'MGR' in the JOB column:
SELECT * FROM STAFF WHERE JOB='MGR'

Table 6 shows how record selection is done with a *HEX sort sequence. In Table 6, the rows that match the record selection criteria for the column 'JOB' are selected exactly as specied in the select statement. Only the uppercase 'MGR' is selected.
Table 6. SELECT * FROM STAFF WHERE JOB=MGR Using the *HEX Sort Sequence.
ID 30 NAME Merenghi DEPT 38 JOB MGR YEARS 5 SALARY 17506.75 COMM 0

Table 7 shows how record selection is done with a unique-weight sort sequence. In Table 7, the lowercase and uppercase letters are treated as unique. The lowercase 'mgr' is not treated the same as uppercase 'MGR'. Therefore, the lower case 'mgr' is not selected.
Table 7. SELECT * FROM STAFF WHERE JOB = MGR Using Unique-Weight Sort Sequence for the ENU Language Identier.
ID 30 NAME Merenghi DEPT 38 JOB MGR YEARS 5 SALARY 17506.75 COMM 0

Table 8 shows how record selection is done with a shared-weight sort sequence. In Table 8, the rows that match the record selection criteria for the column 'JOB' are selected by treating uppercase letters the same as lowercase letters. Notice that in Table 8 all the values 'mgr', 'Mgr' and 'MGR' are selected.
Table 8. SELECT * FROM STAFF WHERE JOB = MGR Using the Shared-Weight Sort Sequence for the ENU Language Identier.
ID 10 NAME Sanders DEPT 20 JOB Mgr YEARS 7 SALARY 18357.50 COMM 0

52

DB2 UDB for AS/400 SQL Programming V4R4

Table 8. SELECT * FROM STAFF WHERE JOB = MGR Using the Shared-Weight Sort Sequence for the ENU Language Identier. (continued)
ID 30 50 100 NAME Merenghi Hanes Plotz DEPT 38 15 42 JOB MGR Mgr mgr YEARS 5 10 6 SALARY 17506.75 20659.80 18352.80 COMM 0 0 0

Sort Sequence and Views


Views are created with the sort sequence that was in effect when the CREATE VIEW statement was run. When the view is referred to in a FROM clause, that sort sequence is used for any character comparisons in the subselect of the CREATE VIEW. At that time, an intermediate result table is produced from the view subselect. The sort sequence in effect when the query is being run is then applied to all the character and UCS-2 graphic comparisons (including those comparisons involving implicit conversions to character or UCS-2 graphic) specied in the query. The following SQL statements and tables show how views and sort sequences work. View V1, used in the following examples, was created with a shared-weight sort sequence of SRTSEQ(*LANGIDSHR) and LANGID(ENU). The CREATE VIEW statement would be as follows:
CREATE VIEW V1 AS SELECT * FROM STAFF WHERE JOB = 'MGR' AND ID < 100

Table 9 shows the result table from the view.


Table 9. SELECT * FROM V1
ID 10 30 50 NAME Sanders Merenghi Hanes DEPT 20 38 15 JOB Mgr MGR Mgr YEARS 7 5 10 SALARY 18357.50 17506.75 20659.80 COMM 0 0 0

Any queries run against view V1 are run against the result table shown in Table 9. The query shown below is run with a sort sequence of SRTSEQ(*LANGIDUNQ) and LANGID(ENU).
Table 10. SELECT * FROM V1 WHERE JOB = MGR Using the Unique-Weight Sort Sequence for Language Identier ENU
ID 30 NAME Merenghi DEPT 38 JOB MGR YEARS 5 SALARY 17506.75 COMM 0

Sort Sequence and the CREATE INDEX Statement


Indexes are created using the sort sequence that was in effect when the CREATE INDEX statement was run. An entry is added to the index every time an insert is made into the table over which the index is dened. Index entries contain the weighted value for character key and UCS-2 graphic key columns. The system gets the weighted value by converting the key value based on the sort sequence of the index.

Chapter 3. Basic Concepts and Techniques

53

When selection is made using that sort sequence and that index, the character or UCS-2 graphic keys do not need to be converted prior to comparison. This improves the performance of the query.

Sort Sequence and Constraints


Unique constraints are implemented with indexes. If the table on which a unique constraint is added was dened with a sort sequence, the index will be created with that same sort sequence. If dening a referential constraint, the sort sequence between the parent and dependent table must match. For more information on sort sequence and constraints, see the DB2 UDB for AS/400 Database Programming book. The sort sequence used at the time a check constraint is dened is the same sort sequence the system uses to validate adherence to the constraint at the time of an INSERT or UPDATE.

54

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 4. Using a Cursor


When SQL runs a select statement, the resulting rows comprise the result table. A cursor provides a way to access a result table. It is used within an SQL program to maintain a position in the result table. SQL uses a cursor to work with the rows in the result table and to make them available to your program. Your program can have several cursors, although each must have a unique name. Statements related to using a cursor include the following: v A DECLARE CURSOR statement to dene and name the cursor and specify the rows to be retrieved with the embedded select statement. v OPEN and CLOSE statements to open and close the cursor for use within the program. The cursor must be opened before any rows can be retrieved. v A FETCH statement to retrieve rows from the cursors result table or to position the cursor on another row. v An UPDATE ... WHERE CURRENT OF statement to update the current row of a cursor. v A DELETE ... WHERE CURRENT OF statement to delete the current row of a cursor.

Types of cursors
SQL supports serial and scrollable cursors. The type of cursor determines the positioning methods which can be used with the cursor.

Serial cursor
A serial cursor is one dened without the SCROLL keyword. For a serial cursor, each row of the result table can be fetched only once per OPEN of the cursor. When the cursor is opened, it is positioned before the rst row in the result table. When a FETCH is issued, the cursor is moved to the next row in the result table. That row is then the current row. If host variables are specied (with the INTO clause on the FETCH statement), SQL moves the current rows contents into your programs host variables. This sequence is repeated each time a FETCH statement is issued until the end-of-data (SQLCODE = 100) is reached. When you reach the end-of-data, close the cursor. You cannot access any rows in the result table after you reach the end-of-data. To use the cursor again, you must rst close the cursor and then re-issue the OPEN statement. You can never back up.

Scrollable cursor
For a scrollable cursor, the rows of the result table can be fetched many times. The cursor is moved through the result table based on the position option specied on the FETCH statement. When the cursor is opened, it is positioned before the rst row in the result table. When a FETCH is issued, the cursor is positioned to the row in the result table that is specied by the position option. That row is then the current row. If host variables are specied (with the INTO clause on the FETCH

Copyright IBM Corp. 1997, 1999

55

statement), SQL moves the current rows contents into your programs host variables. Host variables cannot be specied for the BEFORE and AFTER position options. This sequence is repeated each time a FETCH statement is issued. The cursor does not need to be closed when an end-of-data or beginning-of-data condition occurs. The position options enable the program to continue fetching rows from the table. The following scroll options are used to position the cursor when issuing a FETCH statement. These positions are relative to the current cursor location in the result table.
NEXT PRIOR FIRST LAST BEFORE AFTER CURRENT RELATIVE n Positions the cursor on the next row. This is the default if no position is specied. Positions the cursor on the previous row. Positions the cursor on the rst row. Positions the cursor on the last row. Positions the cursor before the rst row. Positions the cursor after the last row. Does not change the cursor position. Evaluates a host variable or integer n in relationship to the cursors current position. For example, if n is -1, the cursor is positioned on the previous row of the result table. If n is +3, the cursor is positioned three rows after the current row.

Example of Using a Cursor


Suppose your program examines data about people in department D11. The following examples show the SQL statements you would include in a program to dene and use a serial and a scrollable cursor. These cursors can be used to obtain information about the department from the CORPDATA.EMPLOYEE table. For the serial cursor example, the program processes all of the rows from the table, updating the job for all members of department D11 and deleting the records of employees from the other departments.
Table 11. A Serial Cursor Example
Serial Cursor SQL Statement EXEC SQL DECLARE THISEMP CURSOR FOR SELECT EMPNO, LASTNAME, WORKDEPT, JOB FROM CORPDATA.EMPLOYEE FOR UPDATE OF JOB END-EXEC. EXEC SQL OPEN THISEMP END-EXEC. EXEC SQL WHENEVER NOT FOUND GO TO CLOSE-THISEMP END-EXEC. Described in Section Step 1: Dene the Cursor on page 58.

Step 2: Open the Cursor on page 59.

Step 3: Specify What to Do When End-of-Data Is Reached on page 59.

56

DB2 UDB for AS/400 SQL Programming V4R4

Table 11. A Serial Cursor Example (continued)


Serial Cursor SQL Statement EXEC SQL FETCH THISEMP INTO :EMP-NUM, :NAME2, :DEPT, :JOB-CODE END-EXEC. ... for all employees in department D11, update the JOB value: EXEC SQL UPDATE CORPDATA.EMPLOYEE SET JOB = :NEW-CODE WHERE CURRENT OF THISEMP END-EXEC. ... then print the row. ... for other employees, delete the row: EXEC SQL DELETE FROM CORPDATA.EMPLOYEE WHERE CURRENT OF THISEMP END-EXEC. Branch back to fetch and process the next row. CLOSE-THISEMP. EXEC SQL CLOSE THISEMP END-EXEC. Step 6: Close the Cursor on page 62. Step 5b: Delete the Current Row on page 61. Described in Section Step 4: Retrieve a Row Using a Cursor on page 60.

Step 5a: Update the Current Row on page 61.

For the scrollable cursor example, the program uses the RELATIVE position option to obtain a representative sample of salaries from department D11.
Table 12. Scrollable Cursor Example
Scrollable Cursor SQL Statement Described in Section

Step 1: Dene the Cursor on page 58. EXEC SQL DECLARE THISEMP DYNAMIC SCROLL CURSOR FOR SELECT EMPNO, LASTNAME, SALARY FROM CORPDATA.EMPLOYEE WHERE WORKDEPT = D11 END-EXEC. EXEC SQL OPEN THISEMP END-EXEC. EXEC SQL WHENEVER NOT FOUND GO TO CLOSE-THISEMP END-EXEC. Step 2: Open the Cursor on page 59.

Step 3: Specify What to Do When End-of-Data Is Reached on page 59.

Chapter 4. Using a Cursor

57

Table 12. Scrollable Cursor Example (continued)


Scrollable Cursor SQL Statement ...initialize program summation salary variable EXEC SQL FETCH RELATIVE 3 FROM THISEMP INTO :EMP-NUM, :NAME2, :JOB-CODE END-EXEC. ...add the current salary to program summation salary ...branch back to fetch and process the next row. ...calculate the average salary CLOSE-THISEMP. EXEC SQL CLOSE THISEMP END-EXEC. Step 6: Close the Cursor on page 62. Described in Section Step 4: Retrieve a Row Using a Cursor on page 60.

Step 1: Dene the Cursor


To dene a result table to be accessed with a cursor, use the DECLARE CURSOR statement. The DECLARE CURSOR statement names a cursor and species a select-statement. The select-statement denes a set of rows that, conceptually, make up the result table. For a serial cursor, the statement looks like this (the FOR UPDATE OF clause is optional):
EXEC SQL DECLARE cursor-name CURSOR FOR SELECT column-1, column-2 ,... FROM table-name , ... FOR UPDATE OF column-2 ,... END-EXEC.

For a scrollable cursor, the statement looks like this (the WHERE clause is optional):
EXEC SQL DECLARE cursor-name DYNAMIC SCROLL CURSOR FOR SELECT column-1, column-2 ,... FROM table-name ,... WHERE column-1 = expression ... END-EXEC.

The select-statements shown here are rather simple. However, you can code several other types of clauses in a select-statement within a DECLARE CURSOR statement for a serial and a scrollable cursor. If you intend to update any columns in any or all of the rows of the identied table (the table named in the FROM clause), include the FOR UPDATE OF clause. It names each column you intend to update. If you do not specify the names of columns, and you specify either the ORDER BY clause or FOR READ ONLY clause, a negative SQLCODE is returned if an update is attempted. If you do not

58

DB2 UDB for AS/400 SQL Programming V4R4

specify the FOR UPDATE OF clause, the FOR READ ONLY clause, or the ORDER BY clause, and the result table is not read-only, you can update any of the columns of the specied table. You can update a column of the identied table even though it is not part of the result table. In this case, you do not need to name the column in the SELECT statement. When the cursor retrieves a row (using FETCH) that contains a column value you want to update, you can use UPDATE ... WHERE CURRENT OF to update the row. For example, assume that each row of the result table includes the EMPNO, LASTNAME, and WORKDEPT columns from the CORPDATA.EMPLOYEE table. If you want to update the JOB column (one of the columns in each row of the CORPDATA.EMPLOYEE table), the DECLARE CURSOR statement should include FOR UPDATE OF JOB ... even though JOB is omitted from the SELECT statement. The result table and cursor are read-only if any of the following are true: v The rst FROM clause identies more than one table or view. v The rst FROM clause identies a read-only view. v The rst SELECT clause species the keyword DISTINCT. v The outer subselect contains a GROUP BY clause. v The outer subselect contains a HAVING clause. v The rst SELECT clause contains a column function. v The select-statement contains a subquery such that the base object of the outer subselect and of the subquery is the same table. v The select-statement contains a UNION or UNION ALL operator. v The select-statement contains an ORDER BY clause, and the FOR UPDATE OF clause and DYNAMIC SCROLL are not specied. v The select-statement includes a FOR READ ONLY clause. | | v The SCROLL keyword is specied without DYNAMIC. v The select-list includes a DataLink column and a FOR UPDATE OF clause is not specied.

Step 2: Open the Cursor


To begin processing the rows of the result table, issue the OPEN statement. When your program issues the OPEN statement, SQL processes the select-statement within the DECLARE CURSOR statement to identify a set of rows, called a result table 3, using the current value of any host variables specied in the select-statement. The OPEN statement looks like this:
EXEC SQL OPEN cursor-name END-EXEC.

Step 3: Specify What to Do When End-of-Data Is Reached


To nd out when the end of the result table is reached, test the SQLCODE eld for a value of 100 or test the SQLSTATE eld for a value of '02000' (that is,

3. A result table can contain zero, one, or many rows, depending on the extent to which the search condition is satised. Chapter 4. Using a Cursor

59

end-of-data). This condition occurs when the FETCH statement has retrieved the last row in the result table and your program issues a subsequent FETCH. For example:
... IF SQLCODE =100 GO TO DATA-NOT-FOUND. or IF SQLSTATE ='02000' GO TO DATA-NOT-FOUND.

An alternative to this technique is to code the WHENEVER statement. Using WHENEVER NOT FOUND can result in a branch to another part of your program, where a CLOSE statement is issued. The WHENEVER statement looks like this:
EXEC SQL WHENEVER NOT FOUND GO TO symbolic-address END-EXEC.

Your program should anticipate an end-of-data condition whenever a cursor is used to fetch a row, and should be prepared to handle this situation when it occurs. When you are using a serial cursor and the end-of-data is reached, every subsequent FETCH statement returns the end-of-data condition. You cannot position the cursor on rows that are already processed. The CLOSE statement is the only operation that can be performed on the cursor. When you are using a scrollable cursor and the end-of-data is reached, the result table can still process more data. You can position the cursor anywhere in the result table using a combination of the position options. You do not need to CLOSE the cursor when the end-of-data is reached.

Step 4: Retrieve a Row Using a Cursor


To move the contents of a selected row into your programs host variables, use the FETCH statement. The SELECT statement within the DECLARE CURSOR statement identies rows that contain the column values your program wants. However, SQL does not retrieve any data for your application program until the FETCH statement is issued. When your program issues the FETCH statement, SQL uses the current cursor position as a starting point to locate the requested row in the result table. This changes that row to the current row. If an INTO clause was specied, SQL moves the current rows contents into your programs host variables. This sequence is repeated each time the FETCH statement is issued. SQL maintains the position of the current row (that is, the cursor points to the current row) until the next FETCH statement for the cursor is issued. The UPDATE statement does not change the position of the current row within the result table, although the DELETE statement does. The serial cursor FETCH statement looks like this:
EXEC SQL FETCH cursor-name INTO :host variable-1[, :host variable-2] ... END-EXEC.

The scrollable cursor FETCH statement looks like this:

60

DB2 UDB for AS/400 SQL Programming V4R4

EXEC SQL FETCH RELATIVE integer FROM cursor-name INTO :host variable-1[, :host variable-2] ... END-EXEC.

Step 5a: Update the Current Row


When your program has positioned the cursor on a row, you can update its data by using the UPDATE statement with the WHERE CURRENT OF clause. The WHERE CURRENT OF clause species a cursor that points to the row you want to update. The UPDATE ... WHERE CURRENT OF statement looks like this:
EXEC SQL UPDATE table-name SET column-1 = value [, column-2 = value] ... WHERE CURRENT OF cursor-name END-EXEC.

When used with a cursor, the UPDATE statement: v Updates only one rowthe current row v Identies a cursor that points to the row to be updated v Requires that the columns updated be named previously in the FOR UPDATE OF clause of the DECLARE CURSOR statement, if an ORDER BY clause was also specied After you update a row, the cursors position remains on that row (that is, the current row of the cursor does not change) until you issue a FETCH statement for the next row.

Step 5b: Delete the Current Row


When your program has retrieved the current row, you can delete the row by using the DELETE statement. To do this, you issue a DELETE statement designed for use with a cursor; the WHERE CURRENT OF clause species a cursor that points to the row you want to delete. The DELETE ... WHERE CURRENT OF statement looks like this:
EXEC SQL DELETE FROM table-name WHERE CURRENT OF cursor-name END-EXEC.

When used with a cursor, the DELETE statement: v Deletes only one rowthe current row v Uses the WHERE CURRENT OF clause to identify a cursor that points to the row to be deleted After you delete a row, you cannot update or delete another row using that cursor until you issue a FETCH statement to position the cursor. The DELETE Statement on page 34 shows you how to use the DELETE statement to delete all rows that meet a specic search condition. You can also use the FETCH and DELETE ... WHERE CURRENT OF statements when you want to obtain a copy of the row, examine it, then delete it.

Chapter 4. Using a Cursor

61

Step 6: Close the Cursor


If you processed the rows of a result table for a serial cursor, and you want to use the cursor again, issue a CLOSE statement to close the cursor prior to re-opening it.
EXEC SQL CLOSE cursor-name END-EXEC.

If you processed the rows of a result table and you do not want to use the cursor again, you can let the system close the cursor. The system automatically closes the cursor when: v A COMMIT without HOLD statement is issued and the cursor is not declared using the WITH HOLD clause. v A ROLLBACK without HOLD statement is issued. v The job ends. v The activation group ends and CLOSQLCSR(*ENDACTGRP) was specied on the precompile. v The rst SQL program in the call stack ends and neither CLOSQLCSR(*ENDJOB) or CLOSQLCSR(*ENDACTGRP) was specied when the program was precompiled. v The connection to the application server is ended using the DISCONNECT statement. v The connection to the application server was released and a successful COMMIT occurred. v An *RUW CONNECT occurred. Because an open cursor still holds locks on referred-to-tables or views, you should explicitly close any open cursors as soon as they are no longer needed.

Using the Multiple-Row FETCH Statement


The multiple-row FETCH statement can be used to retrieve multiple rows from a table or view with a single FETCH. The program controls the blocking of rows by the number of rows requested on the FETCH statement (OVRDBF has no effect). The maximum number of rows that can be requested on a single fetch call is 32767. Once the data is retrieved, the cursor is positioned on the last row retrieved. There are two ways to dene the storage where fetched rows are placed: a host structure array or a row storage area with an associated descriptor. Both methods can be coded in all of the languages supported by the SQL precompilers, with the exception of the host structure array in REXX. Refer to Chapter 12. Coding SQL Statements in C and C++ Applications, through Chapter 17. Coding SQL Statements in REXX Applications, for more information on the programming languages. Both forms of the multiple-row FETCH statement allow the application to code a separate indicator array. The indicator array should contain one indicator for each host variable that is null capable. The multiple-row FETCH statement can be used with both serial and scrollable cursors. The operations used to dene, open, and close a cursor for a multiple-row FETCH remain the same. Only the FETCH statement changes to specify the number of rows to retrieve and the storage where the rows are placed.

62

DB2 UDB for AS/400 SQL Programming V4R4

After each multiple-row FETCH, information is returned to the program through the SQLCA. In addition to the SQLCODE and SQLSTATE elds, the SQLERRD provides the following information: v SQLERRD3 contains the number of rows retrieved on the multiple-row FETCH statement. If SQLERRD3 is less than the number of rows requested, then an error or end-of-data condition occurred. v SQLERRD4 contains the length of each row retrieved. v SQLERRD5 contains an indication that the last row in the table was fetched. It can be used to detect the end-of-data condition in the table being fetched when the cursor does not have immediate sensitivity to updates. Cursors which do have immediate sensitivity to updates should continue fetching until an SQLCODE +100 is received to detect an end-of-data condition.

Multiple-Row FETCH Using a Host Structure Array


To use the multiple-row FETCH with the host structure array, the application must dene a host structure array that can be used by SQL. Each language has its own conventions and rules for dening a host structure array. Host structure arrays can be dened by using variable declarations or by using compiler directives to retrieve External File Descriptions (such as the COBOL COPY directive). The host structure array consists of an array of structures. Each structure corresponds to one row of the result table. The rst structure in the array corresponds to the rst row, the second structure in the array corresponds to the second row, and so on. SQL determines the attributes of elementary items in the host structure array based on the declaration of the host structure array. To maximize performance, the attributes of the items that make up the host structure array should match the attributes of the columns being retrieved. Consider the following COBOL example:
EXEC SQL INCLUDE SQLCA END-EXEC. ... 01 TABLE-1. 02 DEPT OCCURS 10 TIMES. 05 EMPNO PIC X(6). 05 LASTNAME. 49 LASTNAME-LEN PIC S9(4) BINARY. 49 LASTNAME-TEXT PIC X(15). 05 WORKDEPT PIC X(3). 05 JOB PIC X(8). 01 TABLE-2. 02 IND-ARRAY OCCURS 10 TIMES. 05 INDS PIC S9(4) BINARY OCCURS 4 TIMES. ... EXEC SQL DECLARE D11 CURSOR FOR SELECT EMPNO, LASTNAME, WORKDEPT, JOB FROM CORPDATA.EMPLOYEE WHERE WORKDEPT = "D11" END-EXEC.

... EXEC SQL OPEN D11


Chapter 4. Using a Cursor

63

END-EXEC. PERFORM FETCH-PARA UNTIL SQLCODE NOT EQUAL TO ZERO. ALL-DONE. EXEC SQL CLOSE D11 END-EXEC. ... FETCH-PARA. EXEC SQL WHENEVER NOT FOUND GO TO ALL-DONE END-EXEC. EXEC SQL FETCH D11 FOR 10 ROWS INTO :DEPT :IND-ARRAY END-EXEC. ...

In this example, a cursor was dened for the CORPDATA.EMPLOYEE table to select all rows where the WORKDEPT column equals 'D11'. The result table contains eight rows. The DECLARE CURSOR and OPEN statements do not have any special syntax when they are used with a multiple-row FETCH statement. Another FETCH statement that returns a single row against the same cursor can be coded elsewhere in the program. The multiple-row FETCH statement is used to retrieve all of the rows in the result table. Following the FETCH, the cursor position remains on the last row retrieved. The host structure array DEPT and the associated indicator array IND-ARRAY are dened in the application. Both arrays have a dimension of ten. The indicator array has an entry for each column in the result table. The attributes of type and length of the DEPT host structure array elementary items match the columns that are being retrieved. When the multiple-row FETCH statement has successfully completed, the host structure array contains the data for all eight rows. The indicator array, IND_ARRAY, contains zeros for every column in every row because no NULL values were returned. The SQLCA that is returned to the application contains the following information: v SQLCODE contains 0 v SQLSTATE contains '00000' v SQLERRD3 contains 8, the number of rows fetched v SQLERRD4 contains 34, the length of each row v SQLERRD5 contains +100, indicating the last row in the result table is in the block See Appendix B of the DB2 UDB for AS/400 SQL Reference book for a description of the SQLCA.

Multiple-Row FETCH Using a Row Storage Area


The application must dene a row storage area and an associated description area before the application can use a multiple-row FETCH with a row storage area. The row storage area is a host variable dened in the application program. The row storage area contains the results of the multiple-row FETCH. A row storage area can be a character variable with enough bytes to hold all of the rows requested on the multiple-row FETCH.

64

DB2 UDB for AS/400 SQL Programming V4R4

An SQLDA that contains the SQLTYPE and SQLLEN for each returned column is dened by the associated descriptor used on the row storage area form of the multiple-row FETCH. The information provided in the descriptor determines the data mapping from the database to the row storage area. To maximize performance, the attribute information in the descriptor should match the attributes of the columns retrieved. See Appendix C of the DB2 UDB for AS/400 SQL Reference book for a description of the SQLDA. Consider the following PL/I example:

Chapter 4. Using a Cursor

65

*....+....1....+....2....+....3....+....4....+....5....+....6....+....7...* EXEC SQL INCLUDE SQLCA; EXEC SQL INCLUDE SQLDA; ... DCL DEPTPTR PTR; DCL 1 DEPT(10) BASED(DEPTPTR), 3 EMPNO CHAR(6), 3 LASTNAME CHAR(15) VARYING, 3 WORKDEPT CHAR(3), 3 JOB CHAR(8); DCL I BIN(31) FIXED; DEC J BIN(31) FIXED; DCL ROWAREA CHAR(2000); ... ALLOCATE SQLDA SET(SQLDAPTR); EXEC SQL DECLARE D11 CURSOR FOR SELECT EMPNO, LASTNAME, WORKDEPT, JOB FROM CORPDATA.EMPLOYEE WHERE WORKDEPT = 'D11'; ... EXEC SQL OPEN D11; /* SET UP THE DESCRIPTOR FOR THE MULTIPLE-ROW FETCH */ /* 4 COLUMNS ARE BEING FETCHED */ SQLD = 4; SQLN = 4; SQLDABC = 366; SQLTYPE(1) = 452; /* FIXED LENGTH CHARACTER - */ /* NOT NULLABLE */ SQLLEN(1) = 6; SQLTYPE(2) = 456; /*VARYING LENGTH CHARACTER */ /* NOT NULLABLE */ SQLLEN(2) = 15; SQLTYPE(3) = 452; /* FIXED LENGTH CHARACTER - */ SQLLEN(3) = 3; SQLTYPE(4) = 452; /* FIXED LENGTH CHARACTER - */ /* NOT NULLABLE */ SQLLEN(4) = 8; /*ISSUE THE MULTIPLE-ROW FETCH STATEMENT TO RETRIEVE*/ /*THE DATA INTO THE DEPT ROW STORAGE AREA */ /*USE A HOST VARIABLE TO CONTAIN THE COUNT OF */ /*ROWS TO BE RETURNED ON THE MULTIPLE-ROW FETCH */ J = 10; ... /*REQUESTS 10 ROWS ON THE FETCH */

Figure 2. Example of Multiple-Row FETCH Using a Row Storage Area (Part 1 of 2)

66

DB2 UDB for AS/400 SQL Programming V4R4

EXEC SQL WHENEVER NOT FOUND GOTO FINISHED; EXEC SQL WHENEVER SQLERROR GOTO FINISHED; EXEC SQL FETCH D11 FOR :J ROWS USING DESCRIPTOR :SQLDA INTO :ROWAREA; /* ADDRESS THE ROWS RETURNED DEPTPTR = ADDR(ROWAREA); /*PROCESS EACH ROW RETURNED IN THE ROW STORAGE /*AREA BASED ON THE COUNT OF RECORDS RETURNED /*IN SQLERRD3. DO I = 1 TO SQLERRD(3); IF EMPNO(I) = '000170' THEN DO; : END; END; IF SQLERRD(5) = 100 THEN DO; /* PROCESS END OF FILE */ END; FINISHED:

*/ */ */ */

Figure 2. Example of Multiple-Row FETCH Using a Row Storage Area (Part 2 of 2)

In this example, a cursor has been dened for the CORPDATA.EMPLOYEE table to select all rows where the WORKDEPT column equal 'D11'. The sample EMPLOYEE table in Appendix A. DB2 UDB for AS/400 Sample Tables shows the result table contains eight rows. The DECLARE CURSOR and OPEN statements do not have special syntax when they are used with a multiple-row FETCH statement. Another FETCH statement that returns a single row against the same cursor can be coded elsewhere in the program. The multiple-row FETCH statement is used to retrieve all rows in the result table. Following the FETCH, the cursor position remains on the eighth record in the block. The row area, ROWAREA, is dened as a character array. The data from the result table is placed in the host variable. In this example, a pointer variable is assigned to the address of ROWAREA. Each item in the rows that are returned is examined and used with the based structure DEPT. The attributes (type and length) of the items in the descriptor match the columns that are retrieved. In this case, no indicator area is provided. After the FETCH statement is completed, the ROWAREA contains eight rows. The SQLCA that is returned to the application contains the following: v SQLCODE contains 0 v SQLSTATE contains '00000' v SQLERRD3 contains 8, the number of rows returned v SQLERRD4 contains 34, for the length of the row fetched v SQLERRD5 contains +100, indicating the last row in the result table was fetched In this example, the application has taken advantage of the fact that SQLERRD5 contains an indication of the end of the le being reached. As a result, the application does not need to call SQL again to attempt to retrieve more rows. If the
Chapter 4. Using a Cursor

67

cursor has immediate sensitivity to inserts, you should call SQL in case any records were added. Cursors have immediate sensitivity when the commitment control level is something other than *RR.

Unit of Work and Open Cursors


When your program completes a unit of work, it should commit or rollback the changes you made. Unless you specied HOLD on the COMMIT or ROLLBACK statement, all open cursors are automatically closed by SQL. Cursors that are declared with the WITH HOLD clause are not automatically closed on COMMIT. They are automatically closed on a ROLLBACK (the WITH HOLD clause specied on the DECLARE CURSOR statement is ignored). If you want to continue processing from the current cursor position after a COMMIT or ROLLBACK, you must specify COMMIT HOLD or ROLLBACK HOLD. When HOLD is specied, any open cursors are left open and keep their cursor position so processing can resume. On a COMMIT statement, the cursor position is maintained. On a ROLLBACK statement, the cursor position is restored to just after the last row retrieved from the previous unit of work. All record locks are still released. After issuing a COMMIT or ROLLBACK statement without HOLD, all locks are released and all cursors are closed. You can open the cursor again, but you will begin processing at the rst row of the result table. Note: Specication of the ALWBLK(*ALLREAD) parameter of the CRTSQLxxx commands can change the restoration of the cursor position for read-only cursors. See Chapter 10. Dynamic SQL Applications for information on the use of the ALWBLK parameter and other performance related options on the CRTSQLxxx commands.

68

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 5. Advanced Coding Techniques


This chapter covers the more advanced SQL coding techniques. The topics included in this chapter are: v inserting rows v updating rows v preventing duplicate rows v searching v joining v v v v v using using using using using UNION subqueries views indexes the system catalog

Advanced Insert Techniques


The next two sections cover two advanced techniques on how to insert rows into a table. The rst section Inserting Rows into a Table Using a Select-Statement discusses how to insert more than one row at a time using a select statement. The second section Using the Blocked Insert Statement discusses how to insert multiple rows that are in a host structure array. The second method can be used with all languages except REXX.

Inserting Rows into a Table Using a Select-Statement


You can use a select-statement within an INSERT statement to insert zero, one, or more rows selected from the table or view you specify into another table. The table you select the rows from can be the same table you are inserting into. If they are the same table, SQL will create a temporary result table containing the selected rows and then insert from the temporary table into the target table. One use for this kind of INSERT statement is to move data into a table you created for summary data. For example, suppose you want a table that shows each employees time commitments to projects. You could create a table called EMPTIME with the columns EMPNUMBER, PROJNUMBER, STARTDATE, ENDDATE, and TTIME, and then use the following INSERT statement to ll the table:
INSERT INTO CORPDATA.EMPTIME (EMPNUMBER, PROJNUMBER, STARTDATE, ENDDATE) SELECT EMPNO, PROJNO, EMSTDATE, EMENDATE FROM CORPDATA.EMP_ACT

The select-statement embedded in the INSERT statement is no different from the select-statement you use to retrieve data. With the exception of FOR READ ONLY, FOR UPDATE OF, or the OPTIMIZE clause, you can use all the keywords, column functions, and techniques used to retrieve data. SQL inserts all the rows that meet the search conditions into the table you specify. Inserting rows from one table into another table does not affect any existing rows in either the source table or the target table.

Copyright IBM Corp. 1997, 1999

69

Notes on Multiple-Row Insertion


You should consider the following when inserting multiple rows into a table: v The number of columns implicitly or explicitly listed in the INSERT statement must equal the number of columns listed in the select-statement. v The data in the columns you are selecting must be compatible with the columns you are inserting into when using the INSERT with select-statement. v In the event the select-statement embedded in the INSERT returns no rows, an SQLCODE of 100 is returned to alert you that no rows were inserted. If you successfully insert rows, the SQLERRD(3) eld of the SQLCA has an integer representing the number of rows SQL actually inserted. v If SQL nds an error while running the INSERT statement, SQL stops the operation. If you specify COMMIT (*CHG), COMMIT(*CS), COMMIT (*ALL), or COMMIT(*RR), nothing is inserted into the table and a negative SQLCODE is returned. If you specify COMMIT(*NONE), any rows inserted prior to the error remain in the table. v You can join two or more tables with a select-statement in an INSERT statement. Loaded in this manner, the table can be operated on with UPDATE, DELETE, and INSERT statements, because the rows exist as physically stored rows in a table.

Using the Blocked Insert Statement


A blocked INSERT can be used to insert multiple rows into a table with a single statement. The blocked INSERT statement is supported in all of the languages except REXX. The data inserted into the table must be in a host structure array. If indicator variables are used with a blocked INSERT, they must also be in a host structure array. For information on host structure arrays for a particular language, refer to the chapter on that language. For example, to add ten employees to the CORPDATA.EMPLOYEE table:
INSERT INTO CORPDATA.EMPLOYEE (EMPNO,FIRSTNME,MIDINIT,LASTNAME,WORKDEPT) 10 ROWS VALUES(:DSTRUCT:ISTRUCT)

DSTRUCT is a host structure array with ve elements that is declared in the program. The ve elements correspond to EMPNO, FIRSTNME, MIDINIT, LASTNAME, and WORKDEPT. DSTRUCT has a dimension of at least ten to accommodate inserting ten rows. ISTRUCT is a host structure array that is declared in the program. ISTRUCT has a dimension of at least ten small integer elds for the indicators. Blocked INSERT statements are supported for non-distributed SQL applications and for distributed applications where both the application server and the application requester are AS/400 systems.

Advanced Update Techniques


The SET clause of an UPDATE statement can be used in many ways to determine the actual values to be set in each row being updated. The following example lists each column with its corresponding value:

70

DB2 UDB for AS/400 SQL Programming V4R4

UPDATE EMPLOYEE SET WORKDEPT = 'D11', PHONENO = '7213', JOB = 'DESIGNER' WHERE EMPNO = '000270'

The previous update can also be written by specifying all of the columns and then all of the values:
UPDATE EMPLOYEE SET (WORKDEPT, PHONENO, JOB) = ('D11', '7213', 'DESIGNER') WHERE EMPNO = '000270'

Another way to select a value (or multiple values) for an update is to use a scalar-subselect. The scalar-subselect allows you to update one or more columns by setting them to one or more values selected from another table. In the following example, an employee moves to a different department but continues working on the same projects. The employee table has already been updated to contain the new department number. Now the project table needs to be updated to reect the new department number of this employee (employee number is 000030).
UPDATE PROJECT SET DEPTNO = (SELECT WORKDEPT FROM EMPLOYEE WHERE PROJECT.RESPEMP = EMPLOYEE.EMPNO) WHERE RESPEMP='000030'

This same technique could be used to update a list of columns with multiple values returned from a single select. It is also possible to update an entire row in one table with values from a row in another table. Suppose there is a master class schedule table that needs to be udpated with changes that have been made in a copy of the table. The changes are made to the work copy and merged into the master table every night. The two tables have exactly the same columns and one column, CLASS_CODE, is a unique key column.
UPDATE CL_SCHED SET ROW = (SELECT * FROM MYCOPY WHERE CL_SCHED.CLASS_CODE = MYCOPY.CLASS_CODE)

This update will update all of the rows in CL_SCHED with the values from MYCOPY.

Preventing Duplicate Rows


When SQL evaluates a select-statement, several rows might qualify to be in the result table, depending on the number of rows that satisfy the select-statements search condition. Some of the rows in the result table might be duplicates. You can specify that you do not want any duplicates by using the DISTINCT keyword, followed by the list of column names:
SELECT DISTINCT JOB, SEX ...

DISTINCT means you want to select only the unique rows. If a selected row duplicates another row in the result table, the duplicate row is ignored (it is not put
Chapter 5. Advanced Coding Techniques

71

into the result table). For example, suppose you want a list of employee job codes. You do not need to know which employee has what job code. Because it is probable that several people in a department have the same job code, you can use DISTINCT to ensure that the result table has only unique values. The following example shows how to do this:
DECLARE XMP2 CURSOR FOR SELECT DISTINCT JOB FROM CORPDATA.EMPLOYEE WHERE WORKDEPT = :JOB-DEPT ... FETCH XMP2 INTO :JOB

The result is two rows (in this example, JOB-DEPT is set to D11).
fetch 1 JOB Designer
RV2W557-2

If you do not include DISTINCT in a SELECT clause, you might nd duplicate rows in your result, because SQL retrieves the JOB columns value for each row that satises the search condition. Null values are treated as duplicate rows for DISTINCT. If you include DISTINCT in a SELECT clause and you also include a shared-weight sort sequence, fewer values are returned. The sort sequence causes values that contain the same characters to be weighted the same. If 'MGR', 'Mgr', and 'mgr' were all in the same table, only one of these values would be returned.

Performing Complex Search Conditions


The following section explains more advanced things you can do with search conditions.

Keywords for Use in Search Conditions


A search condition can contain any of the keywords BETWEEN, IN, IS NULL, and LIKE. Note: Constants are shown in the following examples to keep the examples simple. However, you could just as easily code host variables instead. Remember to precede each host variable with a colon. For character and UCS-2 graphic column predicates, the sort sequence is applied to the operands before evaluation of the predicates for BETWEEN, IN, EXISTS, and LIKE clauses. See Using Sort Sequence in SQL on page 50 for more information on the using sort sequence with selection. v BETWEEN ... AND ... is used to specify a search condition that is satised by any value that falls on or between two other values. For example, to nd all employees who were hired in 1987, you could use this:
... WHERE HIREDATE BETWEEN '1987-01-01' AND '1987-12-31'

72

DB2 UDB for AS/400 SQL Programming V4R4

The BETWEEN keyword is inclusive. A more complex, but explicit, search condition that produces the same result is:
... WHERE HIREDATE >= '1987-01-01' AND HIREDATE <= '1987-12-31'

v IN says you are interested in rows in which the value of the specied expression is among the values you listed. For example, to nd the names of all employees in departments A00, C01, and E21, you could specify:
... WHERE WORKDEPT IN ('A00', 'C01', 'E21')

v LIKE says you are interested in rows in which a column value is similar to the value you supply. When you use LIKE, SQL searches for a character string similar to the one you specify. The degree of similarity is determined by two special characters used in the string that you include in the search condition: _ % An underline character stands for any single character. A percent sign stands for an unknown string of 0 or more characters. If the percent sign starts the search string, then SQL allows 0 or more character(s) to precede the matching value in the column. Otherwise, the search string must begin in the rst position of the column.

Note: If you are operating on MIXED data, the following distinction applies: an SBCS underline character refers to one SBCS character. No such restriction applies to the percent sign; that is, a percent sign refers to any number of SBCS or DBCS characters. See the DB2 UDB for AS/400 SQL Reference book for more information on the LIKE predicate and MIXED data. Use the underline character or percent sign either when you do not know or do not care about all the characters of the columns value. For example, to nd out which employees live in Minneapolis, you could specify:
... WHERE ADDRESS LIKE '%MINNEAPOLIS%'

In this case, you should be sure that MINNEAPOLIS was not part of a street address or part of another city name. SQL returns any row with the string MINNEAPOLIS in the ADDRESS column, no matter where the string occurs. In another example, to list the towns whose names begin with 'SAN', you could specify:
... WHERE TOWN LIKE 'SAN%'

If you want to search for a character string that contains either the underscore or percent character, use the ESCAPE clause to specify an escape character. For example, to see all businesses that have a percent in their name, you could specify:
... WHERE BUSINESS_NAME LIKE '%@%%' ESCAPE '@'

The rst and last percent characters are interpreted as usual. The combination @% is taken as the actual percent character.

Special Considerations for LIKE


v When host variables are used in place of string constants in a search pattern, you should consider using varying length host variables. This allows you to: Assign previously used string constants to host variables without any change. Obtain the same selection criteria and results as if a string constant was used. v When xed-length host variables are used in place of string constants in a search pattern, you should ensure the value specied in the host variable
Chapter 5. Advanced Coding Techniques

73

matches the pattern previously used by the string constants. All characters in a host variable that are not assigned a value are initialized with a blank. For example, if you did a search using the string pattern ABC%, these are some of the values that could be returned:
'ABCD ' 'ABCDE' 'ABCxxx' 'ABC '

For example, if you did a search using the search pattern ABC% contained in a host variable with a xed length of 10, these are some the values that could be returned assuming the column has a length of 12:
'ABCDE ' 'ABCD ' 'ABCxxx ' 'ABC '

Note that all returned values start with ABC and end with at least six blanks. This is because the last six characters in the host variable were not assigned a specic value so blanks were used. If you wanted to do a search on a xed-length host variable where the last 7 characters could be anything, you would search for ABC%%%%%%%. These are some values that could be returned:
'ABCDEFGHIJ' 'ABCXXXXXXX' 'ABCDE' 'ABCDD'

Multiple Search Conditions within a WHERE Clause


You saw how to qualify a request using one search condition. You can qualify your request further by coding a search condition that includes several predicates. The search condition you specify can contain any of the comparison operators or the keywords BETWEEN, IN, LIKE, IS NULL, and IS NOT NULL. You can join any two predicates with the connectors AND and OR. In addition, you can use the NOT keyword to specify that the desired search condition is the negated value of the specied search condition. A WHERE clause can have as many predicates as you want. v AND says that, for a row to qualify, the row must satisfy both predicates of the search condition. For example, to nd out which employees in department D21 were hired after December 31, 1987, you would specify:
... WHERE WORKDEPT = 'D21' AND HIREDATE > '1987-12-31'

v OR says that, for a row to qualify, the row can satisfy the condition set by either or both predicates of the search condition. For example, to nd out which employees are in either department C01 or D11, you could specify 4:
... WHERE WORKDEPT = 'C01' OR WORKDEPT = 'D11'

v NOT says that, to qualify, a row must not meet the criteria set by the search condition or predicate that follows the NOT. For example, to nd all employees in department E11 except those with a job code equal to analyst, you could specify:
... WHERE WORKDEPT = 'E11' AND NOT JOB = 'ANALYST'

When SQL evaluates search conditions that contain these connectors, it does so in a specic order. SQL rst evaluates the NOT clauses, next evaluates the AND clauses, and then the OR clauses.

4. You could also use IN to specify this request: WHERE WORKDEPT IN ('C01', 'D11').

74

DB2 UDB for AS/400 SQL Programming V4R4

You can change the order of evaluation by using parentheses. The search conditions enclosed in parentheses are evaluated rst. For example, to select all employees in departments E11 and E21 who have education levels greater than 12, you could specify:
... WHERE EDLEVEL > 12 AND (WORKDEPT = 'E11' OR WORKDEPT = 'E21')

The parentheses determine the meaning of the search condition. In this example, you want all rows that have a: WORKDEPT value of E11 or E21, and EDLEVEL value greater than 12 If you did not use parentheses:
... WHERE EDLEVEL > 12 AND WORKDEPT = 'E11' OR WORKDEPT = 'E21'

Your result is different. The selected rows are rows that have: WORKDEPT = E11 and EDLEVEL > 12, or WORKDEPT = E21, regardless of the EDLEVEL value

Joining Data from More Than One Table


Sometimes the information you want to see is not in a single table. To form a row of the result table, you might want to retrieve some column values from one table and some column values from another table. You can retrieve and join column values from two or more tables into a single row. Four different types of joins are supported by DB2 UDB for AS/400: inner join, left outer join, exception join, and cross join. v An Inner Join returns only the rows from each table that have matching values in the join columns. Any rows that do not have a match between the tables will not appear in the result table. v A Left Outer Join on page 76 returns values for all of the rows from the rst table (the table on the left) and the values from the second table for the rows that match. Any rows that do not have a match in the second table will return the null value for all columns from the second table. v An Exception Join on page 77 returns only the rows from the left table that do not have a match in the right table. Columns in the result table that come from the right table have the null value. v A Cross Join on page 78 returns a row in the result table for each combination of rows from the tables being joined (a Cartesian Product).

Inner Join
With an inner join, column values from one row of a table are combined with column values from another row of another (or the same) table to form a single row of data. SQL examines both tables specied for the join to retrieve data from all the rows that meet the search condition for the join. There are two ways of specifying an inner join: using the JOIN syntax, and using the WHERE clause.

Chapter 5. Advanced Coding Techniques

75

Suppose you want to retrieve the employee numbers, names, and project numbers for all employees that are responsible for a project. In other words, you want the EMPNO and LASTNAME columns from the CORPDATA.EMPLOYEE table and the PROJNO column from the CORPDATA.PROJECT table. Only employees with last names starting with S or later should be considered. To nd this information, you need to join the two tables.

Inner Join Using JOIN Syntax


To use the inner join syntax, both of the tables you are joining are listed in the FROM clause, along with the join condition that applies to the tables. The join condition is specied after the ON keyword and determines how the two tables are to be compared to each other to produce the join result. The condition can be any comparison operator; it does not need to be the equal operator. Multiple join conditions can be specied in the ON clause separated by the AND keyword. Any additional conditions that do not relate to the actual join are specied in either the WHERE clause or as part of the actual join in the ON clause.
SELECT EMPNO, LASTNAME, PROJNO FROM CORPDATA.EMPLOYEE INNER JOIN CORPDATA.PROJECT ON EMPNO = RESPEMP WHERE LASTNAME > 'S'

In this example, the join is done on the two tables using the EMPNO and RESPEMP columns from the tables. Since only employees that have last names starting with at least S are to be returned, this additional condition is provided in the WHERE clause. This query returns the following output:
EMPNO 000020 000060 000100 000250 LASTNAME THOMPSON STERN SPENSER SMITH PROJNO PL2100 MA2110 OP2010 AD3112

Inner Join Using the WHERE Clause


Using the WHERE clause to perform this same join is written with both the join condition and the additional selection condition in the WHERE clause. The tables to be joined are listed in the FROM clause, separated by commas.
SELECT EMPNO, LASTNAME, PROJNO FROM CORPDATA.EMPLOYEE, CORPDATA.PROJECT WHERE EMPNO = RESPEMP AND LASTNAME > 'S'

This query returns the same output as the previous example.

Left Outer Join


A left outer join will return all the rows that an inner join returns plus one row for each of the other rows in the rst table that did not have a match in the second table. Suppose you want to nd all employees and the projects they are currently responsible for. You want to see those employees that are not currently in charge of

76

DB2 UDB for AS/400 SQL Programming V4R4

a project as well. The following query will return a list of all employees whose names are greater than S, along with their assigned project numbers.
SELECT EMPNO, LASTNAME, PROJNO FROM CORPDATA.EMPLOYEE LEFT OUTER JOIN CORPDATA.PROJECT ON EMPNO = RESPEMP WHERE LASTNAME > 'S'

The result of this query contains some employees that do not have a project number. They are listed in the query, but have the null value returned for their project number.
EMPNO 000020 000060 000100 000170 000180 000190 000250 000280 000300 000310 LASTNAME THOMPSON STERN SPENSER YOSHIMURA SCOUTTEN WALKER SMITH SCHNEIDER SMITH SETRIGHT PROJNO PL2100 MA2110 OP2010 AD3112 -

Notes
Using the RRN scalar function to return the relative record number for a column in the table on the right in a left outer join or exception join will return a value of 0 for the unmatched rows.

Exception Join
An exception join returns only the records from the rst table that do NOT have a match in the second table. Using the same tables as before, return those employees that are not responsible for any projects.
SELECT EMPNO, LASTNAME, PROJNO FROM CORPDATA.EMPLOYEE EXCEPTION JOIN CORPDATA.PROJECT ON EMPNO = RESPEMP WHERE LASTNAME > 'S'

This join returns the output:


EMPNO 000170 000180 000190 000280 000300 000310 LASTNAME YOSHIMURA SCOUTTEN WALKER SCHNEIDER SMITH SETRIGHT PROJNO -

An exception join can also be written as a subquery using the NOT EXISTS predicate. The previous query could be rewritten in the following way:

Chapter 5. Advanced Coding Techniques

77

SELECT EMPNO, LASTNAME FROM CORPDATA.EMPLOYEE WHERE LASTNAME > 'S' AND NOT EXISTS (SELECT * FROM CORPDATA.PROJECT WHERE EMPNO = RESPEMP)

The only difference in this query is that it cannot return values from the PROJECT table.

Cross Join
A cross join (or Cartesian Product join) will return a result table where each row from the rst table is combined with each row from the second table. The number of rows in the result table is the product of the number of rows in each table. If the tables involved are large, this join can take a very long time. A cross join can be specied in two ways: using the JOIN syntax or by listing the tables in the FROM clause separated by commas without using a WHERE clause to supply join criteria. Suppose the following tables exist.
Table 13. Table A
T1COL1 A1 A2 A3 T1COL2 AA1 AA2 AA3

Table 14. Table B


T2COL1 B1 B2 T2COL2 BB1 BB2

The following two select statements produce identical results.


SELECT * FROM A CROSS JOIN B SELECT * FROM A, B

The result table for either of these select statements looks like this:
T1COL1 A1 A1 A2 A2 A3 A3 T1COL2 AA1 AA1 AA2 AA2 AA3 AA3 T2COL1 B1 B2 B1 B2 B1 B2 T2COL2 BB1 BB2 BB1 BB2 BB1 BB2

Using multiple join types in one statement


There are times when more than two tables need to be joined to produce the desired result. If you wanted to return all the employees, their department name, and the project they are responsible for, if any, the EMPLOYEE table,

78

DB2 UDB for AS/400 SQL Programming V4R4

DEPARTMENT table, and PROJECT table would all need to be joined to get the information. The following example shows the query and the results.
SELECT EMPNO, LASTNAME, DEPTNAME, PROJNO FROM CORPDATA.EMPLOYEE INNER JOIN CORPDATA.DEPARTMENT ON WORKDEPT = DEPTNO LEFT OUTER JOIN CORPDATA.PROJECT ON EMPNO = RESPEMP WHERE LASTNAME > 'S' EMPNO 000020 000060 000100 000170 000180 000190 000250 000280 000300 000310 LASTNAME THOMPSON STERN SPENSER YOSHIMURA SCOUTTEN WALKER SMITH SCHNEIDER SMITH SETRIGHT DEPTNAME PLANNING MANUFACTURING SYSTEMS SOFTWARE SUPPORT MANUFACTURING SYSTEMS MANUFACTURING SYSTEMS MANUFACTURING SYSTEMS ADMINISTRATION SYSTEMS OPERATIONS OPERATIONS OPERATIONS PROJNO PL2100 MA2110 OP2010 AD3112 -

Notes on Joins
When you join two or more tables: v If there are common column names, you must qualify each common name with the name of the table (or a correlation name). Column names that are unique do not need to be qualied. v If you do not list the column names you want, but instead use SELECT *, SQL returns rows that consist of all the columns of the rst table, followed by all the columns of the second table, and so on. v You must be authorized to select rows from each table or view specied in the FROM clause. v The sort sequence is applied to all character and UCS-2 graphic columns being joined. | | | | | | | | | | | | | | |

Using Table Expressions


You can use table expressions to specify an intermediate result table. They can be used in place of a view to avoid creating the view when general use of the view is not required. Table expressions consist of nested table expressions and common table expressions. Nested table expressions are specied within parentheses in the FROM clause. For example, suppose you want a result table that shows the manager number, department number, and maximum salary for each department. The manager number is in the DEPARTMENT table, the department number is in both the DEPARTMENT and EMPLOYEE tables, and the salaries are in the EMPLOYEE table. You can use a table expression in the from clause to select the maximum salary for each department. You add a correlation name, T2, following the nested table expression to name the derived table. The outer select then uses T2 to qualify columns that are selected from the derived table, in this case MAXSAL and
Chapter 5. Advanced Coding Techniques

79

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

WORKDEPT. Note that the MAX(SALARY) column selected in the nested table expression must be named in order to be referenced in the outer select. The AS clause is used to do that.
SELECT MGRNO, T1.DEPTNO, MAXSAL FROM CORPDATA.DEPARTMENT T1, (SELECT MAX(SALARY) AS MAXSAL, WORKDEPT FROM CORPDATA.EMPLOYEE E1 GROUP BY WORKDEPT) T2 WHERE T1.DEPTNO = T2.WORKDEPT ORDER BY DEPTNO

The result of the query is:


MGRNO DEPTNO 000010 A00 000020 B01 000030 C01 000060 D11 000070 D21 000050 E01 000090 E11 000100 E21 MAXSAL 52,750.00 41,250.00 38,250.00 32,250.00 36,170.00 40,175.00 29,750.00 26,150.00

Common table expressions can be specied prior to the full-select in a SELECT statement, an INSERT statement, or a CREATE VIEW statement. They can be used when the same result table needs to be shared in a full-select. Common table expressions are preceeded with the keyword WITH. For example, suppose you want a table that shows the minimum and maximum of the average salary of a certain set of departments. The rst character of the department number has some meaning and you want to get the minimum and maximum for those departments that start with the letter D and those that start with the letter E. You can use a common table expression to select the average salary for each department. Again, you must name the derived table; in this case, the name is DT. You can then specify a SELECT statement using a WHERE clause to restrict the selection to only the departments that begin with a certain letter. Specify the minimum and maximum of column AVGSAL from the derived table DT. Specify a UNION to get the results for the letter E and the results for the letter D.
WITH DT AS (SELECT E.WORKDEPT AS DEPTNO, AVG(SALARY) AS AVGSAL FROM CORPDATA.DEPARTMENT D , CORPDATA.EMPLOYEE E WHERE D.DEPTNO = E.WORKDEPT GROUP BY E.WORKDEPT) SELECT 'E', MAX(AVGSAL), MIN(AVGSAL) FROM DT WHERE DEPTNO LIKE 'E%' UNION SELECT 'D', MAX(AVGSAL), MIN(AVGSAL) FROM DT WHERE DEPTNO LIKE 'D%'

The result of the query is:


E D MAX ( AVGSAL ) 40,175.00 25,153.33 MIN ( AVGSAL ) 20,998.00 24,677.77

Using the UNION Keyword to Combine Subselects


Using the UNION keyword, you can combine two or more subselects to form a single select-statement. When SQL encounters the UNION keyword, it processes each subselect to form an interim result table, then it combines the interim result table of each subselect and deletes duplicate rows to form a combined result table.

80

DB2 UDB for AS/400 SQL Programming V4R4

You use UNION to merge lists of values from two or more tables. You can use any of the clauses and techniques you have learned so far when coding select-statements, including ORDER BY. You can use UNION to eliminate duplicates when merging lists of values obtained from several tables. For example, you can obtain a combined list of employee numbers that includes: v People in department D11 v People whose assignments include projects MA2112, MA2113, and AD3111 The combined list is derived from two tables and contains no duplicates. To do this, specify:
MOVE 'D11' TO WORK-DEPT. ... EXEC SQL DECLARE XMP6 CURSOR FOR SELECT EMPNO FROM CORPDATA.EMPLOYEE WHERE WORKDEPT = :WORK-DEPT UNION SELECT EMPNO FROM CORPDATA.EMP_ACT WHERE PROJNO = 'MA2112' OR PROJNO = 'MA2113' OR PROJNO = 'AD3111' ORDER BY EMPNO END-EXEC. ... EXEC SQL FETCH XMP6 INTO :EMP-NUMBER END-EXEC.

To better understand what results from these SQL statements, imagine that SQL goes through the following process:

Chapter 5. Advanced Coding Techniques

81

Step 1: SQL processes the first SELECT statement:

Which results in an interim result table: (from CORPDATA.EMPLOYEE) 000060 000150 000160 000170 ...

Step 2: SQL processes the second SELECT statement:

Which results in another interim result table: (from CORPDATA.EMP ACT) 000230 000230 000230 ...

Step 3: SQL combines the two interim result tables:

Which results in a combined result table with values in ascending sequence: fetch EMP-NUMBER 1 2 3 4 5 ... 000060 000150 000160 000170 000180 ...
RV3W186-0

When you use UNION: v Any ORDER BY clause must appear after the last subselect that is part of the union. In this example, the results are sequenced on the basis of the rst selected column, EMPNO. The ORDER BY clause species that the combined result table is to be in collated sequence. v A name may be specied on the ORDER BY clause if the result columns are named. A result column is named if the corresponding columns in each of the unioned select-statements have the same name. An AS clause can be used to assign a name to columns in the select list.
SELECT A + B AS X ... UNION SELECT X ... ORDER BY X

If the result columns are unnamed, use numbers to order the result. The number refers to the position of the expression in the list of expressions you include in your subselects.
SELECT A + B ... UNION SELECT X ... ORDER BY 1

You cannot use UNION when creating a view.

82

DB2 UDB for AS/400 SQL Programming V4R4

To identify which subselect each row is from, you can include a constant at the end of the select list of each subselect in the union. When SQL returns your results, the last column contains the constant for the subselect that is the source of that row. For example, you can specify:
SELECT A, B, 'A1' ... UNION SELECT X, Y, 'B2'

When a row is presented to your program, it includes a value (either A1 or B2) to indicate the table that is the source of the rows values. If the column names in the union are different, SQL uses the set of column names specied in the rst subselect when interactive SQL displays or prints the results, or in the SQLDA resulting from processing an SQL DESCRIBE statement. For information on compatibility of the length and data type for columns in a UNION, see chapter 4 of the DB2 UDB for AS/400 SQL Reference book. Note: Sort sequence is applied after the elds across the UNION pieces are made compatible. The sort sequence is used for the distinct processing that implicitly occurs during UNION processing.

Specifying UNION ALL


If you want to keep duplicates in the result of a UNION, specify UNION ALL instead of just UNION.

Step 3. SQL combines two interim result tables:

Resulting in a result table that includes duplicates: fetch EMP-NUMBER 1 2 3 4 5 6 7 8 ... 000060 000150 000150 000150 000160 000160 000170 000170 ...
RV3W187-0

v The UNION ALL operation is associative, for example:


(SELECT PROJNO FROM CORPDATA.PROJECT UNION ALL SELECT PROJNO FROM CORPDATA.PROJECT) UNION ALL SELECT PROJNO FROM CORPDATA.EMP_ACT

gives the same result as:


SELECT PROJNO FROM CORPDATA.PROJECT UNION ALL (SELECT PROJNO FROM CORPDATA.PROJECT UNION ALL SELECT PROJNO FROM CORPDATA.EMP_ACT)

v When you include the UNION ALL in the same SQL statement as a UNION operator, however, the result of the operation depends on the order of evaluation.
Chapter 5. Advanced Coding Techniques

83

Where there are no parentheses, evaluation is from left to right. Where parentheses are included, the parenthesized subselect is evaluated rst, followed, from left to right, by the other parts of the statement.

Using Subqueries
In the WHERE and HAVING clauses you have seen so far, you specied a search condition by using a literal value, a column name, an expression, or the registers. In those search conditions, you know that you are searching for a specic value, but sometimes you cannot supply that value until you have retrieved other data from a table. For example, suppose you want a list of the employee numbers, names, and job codes of all employees working on a particular project, say project number MA2100. The rst part of the statement is easy to write:
DECLARE XMP CURSOR FOR SELECT EMPNO, LASTNAME, JOB FROM CORPDATA.EMPLOYEE WHERE EMPNO ...

But you cannot go further because the CORPDATA.EMPLOYEE table does not include project number data. You do not know which employees are working on project MA2100 without issuing another SELECT statement against the CORPDATA.EMP_ACT table. With SQL, you can nest one SELECT statement within another to solve this problem. The inner SELECT statement is called a subquery. The SELECT statement surrounding the subquery is called the outer-level SELECT. Using a subquery, you could issue just one SQL statement to retrieve the employee numbers, names, and job codes for employees who work on project MA2100:
DECLARE XMP CURSOR FOR SELECT EMPNO, LASTNAME, JOB FROM CORPDATA.EMPLOYEE WHERE EMPNO IN (SELECT EMPNO FROM CORPDATA.EMP_ACT WHERE PROJNO = 'MA2100')

To better understand what will result from this SQL statement, imagine that SQL goes through the following process:

84

DB2 UDB for AS/400 SQL Programming V4R4

Step 1: SQL evaluates the subquery to obtain a list of EMPNO values:

Which results in an interim results table: (from CORPDATA.EMP ACT) 000010 000110

Step 2: The interim results table then serves as a list in the search condition of the outer-level SELECT. Essentially, this is what is executed.

The final result table looks like this:

fetch 1 2

EMPNO 000010 000110

LASTNAME HAAS LUCCHESSI

JOB PRES SALESREP

RV2W559-2

Correlation
The purpose of a subquery is to supply information needed to qualify a row (WHERE clause) or a group of rows (HAVING clause). This is done through the result table that the subquery produces. Conceptually, the subquery is evaluated whenever a new row or group of rows must be qualied. In fact, if the subquery is the same for every row or group, it is evaluated only once. For example, the previous subquery has the same content for every row of the table CORPDATA.EMPLOYEE. Subqueries like this are said to be uncorrelated. Some subqueries vary in content from row to row or group to group. The mechanism that allows this is called correlation, and the subqueries are said to be correlated. More information on correlated subqueries can be found in Correlated Subqueries on page 88. Even so, what is said before that point applies equally to correlated and uncorrelated subqueries.

Subqueries and Search Conditions


A subquery is always part of a search condition. The search condition is in the form operand operator (subquery). In the example, the operand is EMPNO and operator is IN. The search condition can be part of a WHERE or HAVING clause. The clause can include more than one search condition that contains a subquery. A search condition containing a subquery, like any other search condition, can be enclosed in parentheses, can be preceded by the keyword NOT, and can be linked

Chapter 5. Advanced Coding Techniques

85

to other search conditions through the keywords AND and OR. For example, the WHERE clause of some query could look something like this:
WHERE X IN (subquery1) AND (Y > SOME (subquery2) OR Z = 100)

Subqueries can also appear in the search conditions of other subqueries. Such subqueries are said to be nested at some level of nesting. For example, a subquery within a subquery within an outer-level SELECT is nested at a nesting level of two. SQL allows nesting down to a nesting level of 32, but few queries require a nesting level greater than 1.

How Subqueries Are Used


There are four ways to include a subquery in either a WHERE or HAVING clause:

Basic Comparisons
You can use a subquery immediately after any of the comparison operators. If you do, the subquery can return at most one value. The value can be the result of a column function or an arithmetic expression. SQL then compares the value that results from the subquery with the value to the left of the comparison operator. For example, suppose you want to nd the employee numbers, names, and salaries for employees whose education level is higher than the average education level throughout the company.
DECLARE XMP CURSOR FOR SELECT EMPNO, LASTNAME, SALARY FROM CORPDATA.EMPLOYEE WHERE EDLEVEL > (SELECT AVG(EDLEVEL) FROM CORPDATA.EMPLOYEE)

SQL rst evaluates the subquery and then substitutes the result in the WHERE clause of the SELECT statement. In this example, the result is (as it should be) the company-wide average educational level. Besides returning a single value, a subquery could return no value at all. If it does, the result of the compare is unknown. Consider, for example, the rst query shown in this section, and assume that there are not any employees currently working on project MA2100. Then the subquery would return no value, and the search condition would be unknown for every row. In this case, then, the result produced by the query would be an empty table.

Quantied Comparisons (ALL, ANY, and SOME)


You can use a subquery after a comparison operator followed by the keyword ALL, ANY, or SOME. When used in this way, the subquery can return zero, one, or many values, including null values. You can use ALL, ANY, and SOME in the following ways: v Use ALL to indicate that the value you supplied must compare in the indicated way to ALL the values the subquery returns. For example, suppose you use the greater-than comparison operator with ALL:
... WHERE expression > ALL (subquery)

To satisfy this WHERE clause, the value in the expression must be greater than all the values (that is, greater than the highest value) returned by the subquery. If the subquery returns an empty set (that is, no values were selected), the condition is satised.

86

DB2 UDB for AS/400 SQL Programming V4R4

v Use ANY or SOME to indicate that the value you supplied must compare in the indicated way to at least one of the values the subquery returns. For example, suppose you use the greater-than comparison operator with ANY:
... WHERE expression > ANY (subquery)

To satisfy this WHERE clause, the value in the expression must be greater than at least one of the values (that is, greater than the lowest value) returned by the subquery. If what the subquery returns is empty, the condition is not satised. Note: The results when a subquery returns one or more null values may surprise you, unless you are familiar with formal logic. For applicable rules, read the discussion of quantied predicates in the DB2 UDB for AS/400 SQL Reference .

Using the IN Keyword


You can use IN to say that the value in the expression must be among the values returned by the subquery. The rst example in this chapter illustrates this type of usage. Using IN is equivalent to using =ANY or =SOME. Using ANY and SOME were previously described. You could also use the IN keyword with the NOT keyword in order to select rows when the value is not among the values returned by the subquery. For example, you could use:
... WHERE WORKDEPT NOT IN (SELECT ...)

Using the EXISTS Keyword


In the subqueries presented so far, SQL evaluates the subquery and uses the result as part of the WHERE clause of the outer-level SELECT. In contrast, when you use the keyword EXISTS, SQL simply checks whether the subquery returns one or more rows. If it does, the condition is satised. If it does not (if it returns no rows), the condition is not satised. For example:
DECLARE XMP CURSOR FOR SELECT EMPNO,LASTNAME FROM CORPDATA.EMPLOYEE WHERE EXISTS (SELECT * FROM CORPDATA.PROJECT WHERE PRSTDATE > '1982-01-01');

In the example, the search condition holds if any project represented in the CORPDATA.PROJECT table has an estimated start date that is later than January 1, 1982. Please note that this example does not show the full power of EXISTS, because the result is always the same for every row examined for the outer-level SELECT. As a consequence, either every row appears in the results, or none appear. In a more powerful example, the subquery itself would be correlated, and would change from row to row. See Correlated Subqueries on page 88 for more information on correlated subqueries. As shown in the example, you do not need to specify column names in the subquery of an EXISTS clause. Instead, you can code SELECT *. You could also use the EXISTS keyword with the NOT keyword in order to select rows when the data or condition you specify does not exist. That is, you could use:
... WHERE NOT EXISTS (SELECT ...)

For all general types of usage for subqueries but one (using a subquery with the EXISTS keyword), the subquery must produce a one-column result table. This
Chapter 5. Advanced Coding Techniques

87

means that the SELECT clause in a subquery must name a single column, or contain a single expression. For example, both of the following SELECT clauses would be allowed for all four usage types:
SELECT AVG(SALARY) SELECT EMPNO

The result table produced by a subquery can have zero or more rows. For some usages, no more than one row is allowed.

Using Subqueries with UPDATE and DELETE


In the examples shown so far, you have seen subqueries within SELECT statements. You can also use subqueries in the WHERE clause of the UPDATE or DELETE statements or in the SET clause of an UPDATE. For the most part, this is not very different from using subqueries with outer-level SELECTs.

Notes on Using Subqueries


| | | | 1. When nesting SELECT statements, you can use as many as you need to satisfy your requirements (1 to 31 subqueries), although performance is slower for each additional subquery. A maximum of 128 tables can be specied in an SQL statement. 2. When the outer statement is a SELECT statement (at any level of nesting): v The subquery can be based on the same table or view as the outer statement, or on a different table or view. v You can use a subquery in the WHERE clause of the outer-level SELECT, even when the outer-level SELECT is part of a DECLARE CURSOR, CREATE VIEW, or INSERT statement. v You can use a subquery in the HAVING clause of a SELECT statement. When you do, SQL evaluates the subquery and uses it to qualify each group. 3. When the statement is an UPDATE or DELETE statement, you can use subqueries in the WHERE clause of the UPDATE or DELETE statement. 4. When a subquery is used in the SET clause of an UPDATE statement, the result table of a subselect must contain the same number of values as the corresponding list of columns to be updated. In all other cases, the result table for a subquery must consist of a single column, unless the subquery is being used with the EXISTS keyword. The number of rows in this table can vary from zero to many, but for comparisons not involving the keywords ALL, ANY, or SOME, the number of rows must be zero or one. 5. A subquery cannot include the ORDER BY, UNION, UNION ALL, FOR READ ONLY, UPDATE, or OPTIMIZE clauses. 6. In any subquery, as in any search condition, the values compared must be compatible. 7. Using a column function or an arithmetic expression with a column name in a subquery does not make it incompatible. The data type of the column does not change after SQL applies a column function or arithmetic operator.

Correlated Subqueries
In the subqueries previously discussed, SQL evaluates the subquery once, substitutes the result of the subquery in the right side of the search condition, and evaluates the outer-level SELECT based on the value of the search condition. You can also write a subquery that SQL may have to re-evaluate as it examines each

88

DB2 UDB for AS/400 SQL Programming V4R4

new row (WHERE clause) or group of rows (HAVING clause) in the outer-level SELECT. This is called a correlated subquery.

Example of a Correlated Subquery in a WHERE Clause


Suppose that you want a list of all the employees whose education levels are higher than the average education levels in their respective departments. To get this information, SQL must search the CORPDATA.EMPLOYEE table. For each employee in the table, SQL needs to compare the employees education level to the average education level for the employees department. In the subquery, you tell SQL to calculate the average education level for the department number in the current row. For example:
DECLARE XMP CURSOR FOR SELECT EMPNO, LASTNAME, WORKDEPT, EDLEVEL FROM CORPDATA.EMPLOYEE X WHERE EDLEVEL > (SELECT AVG(EDLEVEL) FROM CORPDATA.EMPLOYEE WHERE WORKDEPT = X.WORKDEPT)

A correlated subquery looks like an uncorrelated one, except for the presence of one or more correlated references. In the example, the single correlated reference is the occurrence of X.WORKDEPT in the subselects FROM clause. Here, the qualier X is the correlation name dened in the FROM clause of the outer SELECT statement. In that clause, X is introduced as the correlation name of the table CORPDATA.EMPLOYEE. Now, consider what happens when the subquery is executed for a given row of CORPDATA.EMPLOYEE. Before it is executed, the occurrence of X.WORKDEPT is replaced with the value of the WORKDEPT column for that row. Suppose, for example, that the row is for CHRISTINE I HAAS. Her work department is A00, which is the value of WORKDEPT for this row. The subquery executed for this row is:
(SELECT AVG(EDLEVEL) FROM CORPDATA.EMPLOYEE WHERE WORKDEPT = 'A00')

Thus, for the row considered, the subquery produces the average education level of Christines department. This is then compared in the outer statement to Christines own education level. For some other row for which WORKDEPT has a different value, that value appears in the subquery in place of A00. For example, for the row for MICHAEL L THOMPSON, this value would be B01, and the subquery for his row would deliver the average education level for department B01. The result table produced by the query would have the following values:

Chapter 5. Advanced Coding Techniques

89

(from CORPDATA.EMPLOYEE)

fetch EMPNO 1 2 3 4 000010 000030 000070 000090

LASTNAME HAAS KWAN PULASKI HENDERSON

WORKDEPT A00 C01 D21 E11

EDLEVEL 18 20 16 16

RV2W560-3

Example of a Correlated Subquery in a HAVING Clause


Suppose that you want a list of all the departments whose average salary is higher than the average salary of their area (all departments whose WORKDEPT begins with the same letter belong to the same area). To get this information, SQL must search the CORPDATA.EMPLOYEE table. For each department in the table, SQL compares the departments average salary to the average salary of the area. In the subquery, SQL calculates the average salary for the area of the department in the current group. For example:
DECLARE XMP CURSOR FOR SELECT WORKDEPT, DECIMAL(AVG(SALARY),8,2) FROM CORPDATA.EMPLOYEE X GROUP BY WORKDEPT HAVING AVG(SALARY) > (SELECT AVG(SALARY) FROM CORPDATA.EMPLOYEE WHERE SUBSTR(X.WORKDEPT,1,1) = SUBSTR(WORKDEPT,1,1))

Consider what happens when the subquery is executed for a given department of CORPDATA.EMPLOYEE. Before it is executed, the occurrence of X.WORKDEPT is replaced with the value of the WORKDEPT column for that group. Suppose, for example, that the rst group selected has A00 for the value of WORKDEPT. The subquery executed for this group is:
(SELECT AVG(SALARY) FROM CORPDATA.EMPLOYEE WHERE SUBSTR('A00',1,1) = SUBSTR(WORKDEPT,1,1))

Thus, for the group considered, the subquery produces the average salary for the area. This is then compared in the outer statement to the average salary for department 'A00'. For some other group for which WORKDEPT is B01, the subquery would result in the average salary for the area where department B01 belongs. The result table produced by the query would have the following values:

90

DB2 UDB for AS/400 SQL Programming V4R4

(from CORPDATA.EMPLOYEE) fetch WORKDEPT 1 2 D21 E01 AVG SALARY 25153.33 40175.00
RV2W561-3

Correlated Names and References


A correlated reference can appear only in a search condition in a subquery. The reference is always of the form X.C, where X is a correlation name and C is the name of a column in the table that X represents. In the preceding example, for instance, X represents the table CORPDATA.EMPLOYEE, and C identies the column WORKDEPT in this table. The correlation name is dened in the FROM clause of some query. This query could be the outer-level SELECT, or any of the subqueries that contain the one with the reference. Suppose, for example, that a query contains subqueries A, B, and C, and that A contains B and B contains C. Then a correlation name used in C could be dened in B, A, or the outer-level SELECT. You can dene a correlation name for each table name appearing in a FROM clause. Simply include the correlation names after the table names. Leave one or more blanks between a table name and its correlation name, and place a comma after the correlation name if it is followed by another table name. The following FROM clause, for example, denes the correlation names TA and TB for the tables TABLEA and TABLEB, and no correlation name for the table TABLEC.
FROM TABLEA TA, TABLEC, TABLEB TB

Any number of correlated references can appear in a subquery. There are no restrictions on variety. For example, one correlated name in a reference could be dened in the outer-level SELECT, while another could be dened in a containing subquery. Before the subquery is executed, a value from the referenced column is always substituted for the correlated reference. The value is determined as follows: Note: Use D to designate the query in which the correlation name is dened. Then the subquery is either in the WHERE clause of D, or in its HAVING clause. v If the subquery is in the WHERE clause, its results are used by D to qualify a row. The substituted value is then taken from this row. This is the case for the example, where the dening query is the outer one and the subquery appears in the outer querys WHERE clause. v If the subquery is in the HAVING clause, its results are used by D to qualify a group of rows. The substituted value is then taken from this group. Note that in this case, the column specied must be identied in the GROUP BY clause in D. If it is not, the specied column could have more than one value for the group.

Using Correlated Subqueries in an UPDATE Statement


When you use a correlated subquery in an UPDATE statement, the correlation name refers to the rows you are interested in updating. For example, when all
Chapter 5. Advanced Coding Techniques

91

activities of a project must be completed before September 1983, your department considers that project to be a priority project. You could use the SQL statement below to evaluate the projects in the CORPDATA.PROJECT table, and write a 1 (a ag to indicate PRIORITY) in the PRIORITY column (a column you added to CORPDATA.PROJECT for this purpose) for each priority project.
UPDATE CORPDATA.PROJECT X SET PRIORITY = 1 WHERE '1983-09-01' > (SELECT MAX(EMENDATE) FROM CORPDATA.EMP_ACT WHERE PROJNO = X.PROJNO)

As SQL examines each row in the CORPDATA.EMP_ACT table, it determines the maximum activity end date (EMENDATE) for all activities of the project (from the CORPDATA.PROJECT table). If the end date of each activity associated with the project is prior to September 1983, the current row in the CORPDATA.PROJECT table qualies and is updated.

Using Correlated Subqueries in a DELETE Statement


When you use a correlated subquery in a DELETE statement, the correlation name represents the row you delete. SQL evaluates the correlated subquery once for each row in the table named in the DELETE statement to decide whether or not to delete the row. Suppose a row in the CORPDATA.PROJECT table was deleted. Rows related to the deleted project in the CORPDATA.EMP_ACT table must also be deleted. To do this, you can use:
DELETE FROM CORPDATA.EMP_ACT X WHERE NOT EXISTS (SELECT * FROM CORPDATA.PROJECT WHERE PROJNO = X.PROJNO)

SQL determines, for each row in the CORPDATA.EMP_ACT table, whether a row with the same project number exists in the CORPDATA.PROJECT table. If not, the CORPDATA.EMP_ACT row is deleted.

Notes on Using Correlated Subqueries


v The correlation name is separated from its associated table name with a space. To specify another table name, precede the table name with a comma, for example:
FROM CORPDATA.EMPLOYEE X, CORPDATA.PROJECT ....

v The correlated subquery and the outer-level statement can refer to the same table or to different tables. v In an INSERT statement, neither the correlated subquery nor an outer-level SELECT within the INSERT statement can be based on the same table into which you are inserting. v The outer-level SELECT that denes the correlation name can join two or more tables. v You can use correlated subqueries in HAVING clauses. When you do, SQL evaluates the subquery, once per group, of the outer-level SELECT. The column you refer to in the HAVING clause must specify a property of each group (for example, WORKDEPT) either the columns you grouped the rows by or another column with one of the column functions.

92

DB2 UDB for AS/400 SQL Programming V4R4

v You can nest correlated subqueries.

Changing a Table Denition


| | | | Changing the denition of a table allows you to add new columns, change an existing column denition (change its length, default value, and so on), drop existing columns, and add and remove constraints. You can change the denition of a table using Operations Navigator. Or, use the SQL ALTER TABLE statement. You can add, change, or drop columns and add or remove constraints all with one ALTER TABLE statement. However, a single column can be referenced only once in the ADD COLUMN, ALTER COLUMN, and DROP COLUMN clauses. That is, you cannot add a column and then alter that column in the same ALTER TABLE statement.

Adding a column
| | You can add a column to a table using Operations Navigator. Or use the ADD COLUMN clause of the SQL ALTER TABLE statement. When you add a new column to a table, the column is initialized with its default value for all existing rows. If NOT NULL is specied, a default value must also be specied. | | | | The altered table may consist of up to 8000 columns. The sum of the byte counts of the columns must not be greater than 32766 or, if a VARCHAR or VARGRAPHIC column is specied, 32740. If a LOB column is specied, the sum of record data byte counts of the columns must not be greater than 15 728 640.

Changing a column
| | | | | | | | | | | | | | You can change a column in a table using Operations Navigator. Or, you can use the ALTER COLUMN clause of the ALTER TABLE statement. When you change the data type of an existing column, the old and new attributes must be compatible. Allowable Conversions shows the conversions with compatible attributes. When you convert to a data type with a longer length, data will be padded with the appropriate pad character. When you convert to a data type with a shorter length, data may be lost due to truncation. An inquiry message prompts you to conrm the request. If you have a column that does not allow the null value and you want to change it to now allow the null value, use the DROP NOT NULL clause. If you have a column that allows the null value and you want to prevent the use of null values, use the SET NOT NULL clause. If any of the existing values in that column are the null value, the ALTER TABLE will not be performed and an SQLCODE of -190 will result.

Allowable Conversions
Table 15. Allowable Conversions
FROM data type Decimal TO data type Numeric

Chapter 5. Advanced Coding Techniques

93

Table 15. Allowable Conversions (continued)


FROM data type Decimal Decimal Numeric Numeric Numeric Integer, Smallint Integer, Smallint Integer, Smallint Float Float Character Character DBCS-open DBCS-open DBCS-either DBCS-either DBCS-either DBCS-only DBCS-only DBCS-only DBCS graphic UCS-2 graphic UCS-2 graphic UCS-2 graphic TO data type Integer, Smallint Float Decimal Integer, Smallint Float Decimal Numeric Float Numeric Integer, Smallint DBCS-open UCS-2 graphic Character UCS-2 graphic Character DBCS-open UCS-2 graphic DBCS-open DBCS graphic UCS-2 graphic UCS-2 graphic Character DBCS-open DBCS graphic source type distinct type

| | | | | | | | | |

distinct type source type

When modifying an existing column, only the attributes that you specify will be changed. All other attributes will remain unchanged. For example, given the following table denition:
CREATE TABLE EX1 (COL1 CHAR(10) DEFAULT 'COL1', COL2 VARCHAR(20) ALLOCATE(10) CCSID 937, COL3 VARGRAPHIC(20) ALLOCATE(10) NOT NULL WITH DEFAULT)

After running the following ALTER TABLE statement:


ALTER TABLE EX1 ALTER COLUMN COL2 SET DATA TYPE VARCHAR(30) ALTER COLUMN COL3 DROP NOT NULL

COL2 would still have an allocated length of 10 and CCSID 937, and COL3 would still have an allocated length of 10.

94

DB2 UDB for AS/400 SQL Programming V4R4

Deleting a column
| | You can delete a column using Operations Navigator. Or you can delete a column using the DROP COLUMN clause of the ALTER TABLE statement. Dropping a column deletes that column from the table denition. If CASCADE is specied, any views, indexes, and constraints dependent on that column will also be dropped. If RESTRICT is specied, and any views, indexes, or constraints are dependent on the column, the column will not be dropped and SQLCODE of -196 will be issued.

Order of operations for ALTER TABLE statement


| | | | | | | An ALTER TABLE statement is performed as a set of steps as follows: 1. Drop constraints 2. Drop columns for which the RESTRICT option was specied 3. Alter column denitions (this includes adding columns and dropping columns for which the CASCADE option was specied) 4. Add constraints Within each of these steps, the order in which you specify the clauses is the order in which they are performed, with one exception. If any columns are being dropped, that operation is logically done before any column denitions are added or altered, in case record length is increased as a result of the ALTER TABLE statement.

Creating and Using Views


A view can be used to access part of the data in one or more tables. You can dene the columns of the view in the SELECT clause and the tables the view is based on in the FROM clause. To dene the rows in the view, you can specify a WHERE clause, a GROUP by clause, or a HAVING clause. For example, to create a view that selects only the last name and the department of all the managers, specify:
CREATE VIEW CORPDATA.EMP_MANAGERS AS SELECT LASTNAME, WORKDEPT FROM CORPDATA.EMPLOYEE WHERE JOB = 'MANAGER'

If the select list contains elements other than columns such as expressions, functions, constants, or special registers, and the AS clause was not used to name the columns, a column list must be specied for the view. In the following example, the columns of the view are LASTNAME and YEARSOFSERVICE.
CREATE VIEW CORPDATA.EMP_YEARSOFSERVICE (LASTNAME, YEARSOFSERVICE) AS SELECT LASTNAME, YEARS (CURRENT DATE - HIREDATE) FROM CORPDATA.EMPLOYEE

The previous view can also be dened by using the AS clause in the select list to name the columns in the view. For example:
CREATE VIEW CORPDATA.EMP_YEARSOFSERVICE AS SELECT LASTNAME, YEARS (CURRENT_DATE - HIREDATE) AS YEARSOFSERVICE FROM CORPDATA.EMPLOYEE

Chapter 5. Advanced Coding Techniques

95

Once you have created the view, you can use it to select the data or possibly change the data in the base table. The following restrictions must be considered when creating the view: v You cannot change, insert, or delete data in a read-only view. A view is read-only if it includes any of the following: The rst FROM clause identies more than one table (join). The rst FROM clause identies a read-only view. The rst SELECT clause contains any of the SQL column functions (SUM, MAX, MIN, AVG, COUNT, STDDEV, or VAR). The rst SELECT clause species the keyword DISTINCT. The outer subselect contains a GROUP BY or HAVING clause. A subquery, such that the base object of the outer-most subselect and a table of a subquery are the same table In the above cases, you can get data from the views by means of the SQL SELECT statement, but you cannot use statements such as INSERT, UPDATE, or DELETE. v You cannot insert a row in a view if: The table on which the view is based has a column that has no default value, does not allow nulls, and is not in the view. The view has a column resulting from an expression, a constant, a function, or a special register and the column was specied in the INSERT column list. The WITH CHECK OPTION was specied when the view was created and the row does not match the selection criteria. v You cannot update a column of a view that results from an expression, a constant, a function, or a special register. v You cannot use UNION, UNION ALL, FOR UPDATE OF, FOR READ ONLY, ORDER BY, or OPTIMIZE FOR n ROWS in the denition of a view. Views are created with the sort sequence in effect at the time the CREATE VIEW statement is run. The sort sequence applies to all character and UCS-2 graphic comparisons in the CREATE VIEW statement subselect. See Using Sort Sequence in SQL on page 50 for more information on sort sequences. Views can also be created using the WITH CHECK OPTION to specify the level of checking that should be done when data is inserted or updated through the view. See WITH CHECK OPTION on a View on page 108 for more information.

Adding Indexes
| | | | | | You can use indexes to sort and select data. In addition, indexes help the system retrieve data faster for better query performance. You can create an index when creating a table using Operations Navigator. Or use the SQL CREATE INDEX statement. The following example creates an index over the column LASTNAME in the CORPDATA.EMPLOYEE table:
CREATE INDEX CORPDATA.INX1 ON CORPDATA.EMPLOYEE (LASTNAME)

96

DB2 UDB for AS/400 SQL Programming V4R4

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

You can create a number of indexes. However, because the indexes are maintained by the system, a large number of indexes can adversely affect performance. For more information about indexes and query performance, see Effectively Using SQL Indexes on page 446. A new type of index, the encoded vector index, allows for faster scans that can be more easily processed in parallel. You create encoded vector indexes by using the SQL CREATE INDEX statement. For more information about accelerating your queries with encoded vector indexes , go to the DB2 for AS/400 webpages. If an index is created that has exactly the same attributes as an existing index, the new index shares the existing indexes binary tree. Otherwise, another binary tree is created. If the attributes of the new index are exactly the same as another index, except the new index has fewer columns, another binary tree is still created. It is still created because the extra columns would prevent the index from being used by cursors or UPDATE statements which update those extra columns. Indexes are created with the sort sequence in effect at the time the CREATE INDEX statement is run. The sort sequence applies to all SBCS character elds and UCS-2 graphic elds of the index. See Using Sort Sequence in SQL on page 50 for more information on sort sequences.

Using the Catalog in Database Design


A catalog is automatically created when you create a collection. There is also a system-wide catalog that is always in the QSYS2 library. When an SQL object is created in a collection, information is added to both the system catalog tables and the collections catalog tables. When an SQL object is created in a library, only the QSYS2 catalog is updated. For more information about catalogs, see the DB2 UDB for AS/400 SQL Reference book. As the following examples show, you can display catalog information. You cannot INSERT, DELETE, or UPDATE catalog information. You must have SELECT privileges on the catalog views to run the following examples. Attention: Operations that normally update the SQL catalog for a collection can no longer update the catalog if the collection is saved, restored, and given a different name. Saving in one collection and restoring to another is not supported by the product.

Getting Catalog Information about a Table


SYSTABLES contains a row for every table and view in the SQL collection. It tells you if the object is a table or view, the object name, the owner of the object, what SQL collection it is in, and so forth. The following sample statement displays information for the CORPDATA.DEPARTMENT table:
SELECT * FROM CORPDATA.SYSTABLES WHERE NAME = 'DEPARTMENT'

Chapter 5. Advanced Coding Techniques

97

Getting Catalog Information about a Column


SYSCOLUMNS contains a row for each column of every table and view in the collection. The following sample statement displays all the column names in the CORPDATA.DEPARTMENT table:
SELECT * FROM CORPDATA.SYSCOLUMNS WHERE TBNAME = 'DEPARTMENT'

The result of the previous sample statement is a row of information for each column in the table. Some of the information is not visible because the width of the information is wider than the display screen. For more information about each column, specify a select-statement like this:
SELECT NAME, TBNAME, COLTYPE, LENGTH, DEFAULT FROM CORPDATA.SYSCOLUMNS WHERE TBNAME = 'DEPARTMENT'

In addition to the column name for each column, the select-statement shows: v The name of the table that contains the column v The data type of the column v The length attribute of the column v If the column allows default values The result looks like this:
NAME DEPTNO DEPTNAME MGRNO ADMRDEPT TBNAME DEPARTMENT DEPARTMENT DEPARTMENT DEPARTMENT COLTYPE CHAR VARCHAR CHAR CHAR LENGTH 3 29 6 3 DEFAULT N N Y N

98

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 6. Data Integrity


Data integrity is the principle of ensuring data values between tables of a collection are kept in a state which makes sense to the business. For example, if a bank has a list of customers in table A and a list of customer accounts in table B, it would not make sense to allow a new account to be added to table B unless an associated customer exists in table A. This chapter describes the different ways the system automatically enforces these kinds of relationships. Referential integrity, check constraints, and triggers are all ways of accomplishing data integrity. Additionally, the WITH CHECK OPTION clause on a CREATE VIEW constrains the inserting or updating of data through a view. For comprehensive information about data integrity, see the DB2 UDB for AS/400 Database Programming book.

Adding and Using Check Constraints


| | | | A check constraint assures the validity of data during inserts and updates by limiting the allowable values in a column or group of columns. You can add check constraints using Operations Navigator when creating a table. Or use the SQL CREATE TABLE and ALTER TABLE statements to add or drop check constraints. In this example, the following statement creates a table with three columns and a check constraint over COL2 which limits the values allowed in that column to positive integers:
CREATE TABLE T1 (COL1 INT, COL2 INT CHECK (COL2>0), COL3 INT)

Given this table, the following statement:


INSERT INTO T1 VALUES (-1, -1, -1)

would fail because the value to be inserted into COL2 does not meet the check constraint; that is, -1 is not greater than 0. The following statement would be successful:
INSERT INTO T1 VALUES (1, 1, 1)

Once that row is inserted, the following statement would fail:


ALTER TABLE T1 ADD CONSTRAINT C1 CHECK (COL1=1 AND COL1<COL2)

This ALTER TABLE statement attempts to add a second check constraint which limits the value allowed in COL1 to 1 and also effectively rules that values in COL2 be greater than 1. This constraint would not be be allowed because the second part of the constraint is not met by the existing data (the value of 1 in COL2 is not less than the value of 1 in COL1).

Referential Integrity
| | Referential integrity is the condition of a set of tables in a database in which all references from one table to another are valid.

Copyright IBM Corp. 1997, 1999

99

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

Consider the following example: (These sample tables are given in Appendix A. DB2 UDB for AS/400 Sample Tables: v CORPDATA.EMPLOYEE serves as a master list of employees. v CORPDATA.DEPARTMENT acts as a master list of all valid department numbers. v CORPDATA.EMP_ACT provides a master list of activities performed for projects. Other tables refer to the same entities described in these tables. When a table contains data for which there is a master list, that data should actually appear in the master list, or the reference is not valid. The table that contains the master list is the parent table, and the table that refers to it is a dependent table. When the references from the dependent table to the parent table are valid, the condition of the set of tables is called referential integrity. Stated another way, referential integrity is the state of a database in which all values of all foreign keys are valid. Each value of the foreign key must also exist in the parent key or be null. This denition of referential integrity requires an understanding of the following terms: v A unique key is a column or set of columns in a table which uniquely identify a row. Although a table can have several unique keys, no two rows in a table can have the same unique key value. v A primary key is a unique key that does not allow nulls. A table cannot have more than one primary key. v A parent key is either a unique key or a primary key which is referenced in a referential constraint. v A foreign key is a column or set of columns whose values must match those of a parent key. If any column value used to build the foreign key is null, then the rule does not apply. v A parent table is a table that contains the parent key. v A dependent table is the table that contains the foreign key. v A descendent table is a table that is a dependent table or a descendent of a dependent table. Enforcement of referential integrity prevents the violation of the rule which states that every non-null foreign key must have a matching parent key. SQL supports the referential integrity concept with the CREATE TABLE and ALTER TABLE statements. For detailed descriptions of these commands, see the DB2 UDB for AS/400 SQL Reference book.

Adding or dropping referential constraints


| | | | | | | | | | Constraints on page 375 are rules that ensure that references from one table, a dependent table, to data in another table, the parent table, are valid. You use referential constraints to ensure Referential Integrity on page 99. You can add referential constraints using Operations Navigator when creating a table. Or, use the SQL CREATE TABLE and ALTER TABLE statements to add or change referential constraints. With a referential constraint, non-null values of the foreign key are valid only if they also appear as values of a parent key. When you dene a referential constraint, you specify: v A primary or unique key

100

DB2 UDB for AS/400 SQL Programming V4R4

| | | | | | | | |

v A foreign key v Delete and update rules that specify the action taken with respect to dependent rows when the parent row is deleted or updated. Optionally, you can specify a name for the constraint. If a name is not specied, one is automatically generated. Once a referential constraint is dened, the system enforces the constraint on every INSERT, DELETE, and UPDATE operation performed through SQL or any other interface including Operations Navigator, CL commands, utilities, or high-level language statements.

Example: adding referential constraints


The rule that every department number shown in the sample employee table must appear in the department table is a referential constraint. This constraint ensures that every employee belongs to an existing department. The following SQL statements create the CORPDATA.DEPARTMENT and CORPDATA.EMPLOYEE tables with those constraint relationships dened.
CREATE TABLE CORPDATA.DEPARTMENT (DEPTNO CHAR(3) NOT NULL PRIMARY KEY, DEPTNAME VARCHAR(29) NOT NULL, MGRNO CHAR(6), ADMRDEPT CHAR(3) NOT NULL CONSTRAINT REPORTS_TO_EXISTS REFERENCES CORPDATA.DEPARTMENT (DEPTNO) ON DELETE CASCADE) CREATE TABLE CORPDATA.EMPLOYEE (EMPNO CHAR(6) NOT NULL PRIMARY KEY, FIRSTNAME VARCHAR(12) NOT NULL, MIDINIT CHAR(1) NOT NULL, LASTNAME VARCHAR(15) NOT NULL, WORKDEPT CHAR(3) CONSTRAINT WORKDEPT_EXISTS REFERENCES CORPDATA.DEPARTMENT (DEPTNO) ON DELETE SET NULL ON UPDATE RESTRICT, PHONENO CHAR(4), HIREDATE DATE, JOB CHAR(8), EDLEVEL SMALLINT NOT NULL, SEX CHAR(1), BIRTHDATE DATE, SALARY DECIMAL(9,2), BONUS DECIMAL(9,2), COMM DECIMAL(9,2), CONSTRAINT UNIQUE_LNAME_IN_DEPT UNIQUE (WORKDEPT, LASTNAME))

In this case, the DEPARTMENT table has a column of unique department numbers (DEPTNO) which functions as a primary key, and is a parent table in two constraint relationships: REPORTS_TO_EXISTS is a self-referencing constraint in which the DEPARTMENT table is both the parent and the dependent in the same relationship. Every non-null value of ADMRDEPT must match a value of DEPTNO. A department must report to an existing department in the database. The DELETE CASCADE rule indicates that if a row with a DEPTNO value n is deleted, every row in the table for which the ADMRDEPT is n is also deleted. WORKDEPT_EXISTS establishes the EMPLOYEE table as a dependent table, and the column of
Chapter 6. Data Integrity

101

employee department assignments (WORKDEPT) as a foreign key. Thus, every value of WORKDEPT must match a value of DEPTNO. The DELETE SET NULL rule says that if a row is deleted from DEPARTMENT in which the value of DEPTNO is n, then the value of WORKDEPT in EMPLOYEE is set to null in every row in which the value was n. The UPDATE RESTRICT rule says that a value of DEPTNO in DEPARTMENT cannot be updated if there are values of WORKDEPT in EMPLOYEE that match the current DEPTNO value. Constraint UNIQUE_LNAME_IN_DEPT in the EMPLOYEE table causes last names to be unique within a department. While this constraint is unlikely, it illustrates how a constraint made up of several columns can be dened at the table level.

Removing Referential Constraints


| | | | The ALTER TABLE statement can be used to add or drop one constraint at a time for a table. If the constraint being dropped is the parent key in some referential constraint relationship, the constraint between this parent le and any dependent les is also removed. DROP TABLE and DROP COLLECTION statements also remove any constraints on the table or collection being dropped.

Example of Removing Constraints


The following example removes the primary key over column DEPTNO in table DEPARTMENT. The constraints REPORTS_TO_EXISTS and WORKDEPT_EXISTS dened on tables DEPARTMENT and EMPLOYEE respectively will be removed as well, since the primary key being removed is the parent key in those constraint relationships.
ALTER TABLE CORPDATA.EMPLOYEE DROP PRIMARY KEY

You can also remove a constraint by name, as in the following example:


ALTER TABLE CORPDATA.DEPARTMENT DROP CONSTRAINT UNIQUE_LNAME_IN_DEPT

Inserting into Tables with Referential Constraints


There are some important things to remember when inserting data into tables with referential constraints. If you are inserting data into a parent table with a parent key, SQL does not allow: v Duplicate values for the parent key v If the parent key is a primary key, a null value for any column of the primary key If you are inserting data into a dependent table with foreign keys: v Each non-null value you insert into a foreign key column must be equal to some value in the corresponding parent key of the parent table. v If any column in the foreign key is null, the entire foreign key is considered null. If all foreign keys that contain the column are null, the INSERT succeeds (as long as there are no unique index violations).

Example of Inserting Data with Constraints


Alter the sample application project table (PROJECT) to dene two foreign keys:

102

DB2 UDB for AS/400 SQL Programming V4R4

v A foreign key on the department number (DEPTNO) which references the department table v A foreign key on the employee number (RESPEMP) which references the employee table.
ALTER TABLE CORPDATA.PROJECT ADD CONSTRAINT RESP_DEPT_EXISTS FOREIGN KEY (DEPTNO) REFERENCES CORPDATA.DEPARTMENT ON DELETE RESTRICT ALTER TABLE CORPDATA.PROJECT ADD CONSTRAINT RESP_EMP_EXISTS FOREIGN KEY (RESPEMP) REFERENCES CORPDATA.EMPLOYEE ON DELETE RESTRICT

Notice that the parent table columns are not specied in the REFERENCES clause. The columns are not required to be specied as long as the referenced table has a primary key or eligible unique key which can be used as the parent key. Every row inserted into the PROJECT table must have a value of DEPTNO that is equal to some value of DEPTNO in the department table. (The null value is not allowed because DEPTNO in the project table is dened as NOT NULL.) The row must also have a value of RESPEMP that is either equal to some value of EMPNO in the employee table or is null. The tables with the sample data as they appear in Appendix A. DB2 UDB for AS/400 Sample Tables conform to these constraints. The following INSERT statement fails because there is no matching DEPTNO value (A01) in the DEPARTMENT table.
INSERT INTO CORPDATA.PROJECT (PROJNO, PROJNAME, DEPTNO, RESPEMP) VALUES ('AD3120', 'BENEFITS ADMIN', 'A01', '000010')

Likewise, the following INSERT statement would be unsuccessful since there is no EMPNO value of 000011 in the EMPLOYEE table.
INSERT INTO CORPDATA.PROJECT (PROJNO, PROJNAME, DEPTNO, RESPEMP) VALUES ('AD3130', 'BILLING', 'D21', '000011')

The following INSERT statement completes successfully because there is a matching DEPTNO value of E01 in the DEPARTMENT table and a matching EMPNO value of 000010 in the EMPLOYEE table.
INSERT INTO CORPDATA.PROJECT (PROJNO, PROJNAME, DEPTNO, RESPEMP) VALUES ('AD3120', 'BENEFITS ADMIN', 'E01', '000010')

Updating Tables with Referential Constraints


If you are updating a parent table, you cannot modify a primary key for which dependent rows exist. Changing the key violates referential constraints for dependent tables and leaves some rows without a parent. Furthermore, you cannot give any part of a primary key a null value.

Update Rules
The action taken on dependent tables when an UPDATE is performed on a parent table depends on the update rule specied for the referential constraint. If no update rule was dened for a referential constraint, the UPDATE NO ACTION rule is used. v UPDATE NO ACTION
Chapter 6. Data Integrity

103

Species that the row in the parent table can be updated if no other row depends on it. If a dependent row exists in the relationship, the UPDATE fails. The check for dependent rows is performed at the end of the statement. v UPDATE RESTRICT Species that the row in the parent table can be updated if no other row depends on it. If a dependent row exists in the relationship, the UPDATE fails. The check for dependent rows is performed immediately. The subtle difference between RESTRICT and NO ACTION rules is easiest seen when looking at the interaction of triggers and referential constraints. Triggers can be dened to re either before or after an operation (an UPDATE statement, in this case). A before trigger res before the UPDATE is performed and therefore before any checking of constraints. An after trigger is red after the UPDATE is performed, and after a constraint rule of RESTRICT (where checking is performed immediately), but before a constraint rule of NO ACTION (where checking is performed at the end of the statement). The triggers and rules would occur in the following order: 1. A before trigger would be red before the UPDATE and before a constraint rule of RESTRICT or NO ACTION. 2. An after trigger would be red after a constraint rule of RESTRICT, but before a NO ACTION rule. If you are updating a dependent table, any non-null foreign key values that you change must match the primary key for each relationship in which the table is a dependent. For example, department numbers in the employee table depend on the department numbers in the department table. You can assign an employee to no department (the null value), but not to a department that does not exist. If an UPDATE against a table with a referential constraint fails, all changes made during the update operation are undone. For more information on the implications of commitment control and journaling when working with constraints, see Journaling on page 368 and Commitment Control on page 369.

Examples of UPDATE Rules


For example, you cannot update a department number from the department table if it is still responsible for some project, which is described by a dependent row in the project table. The following UPDATE fails because the PROJECT table has rows which are dependent on DEPARTMENT.DEPTNO having a value of D01 (the row targeted by the WHERE statement). If this UPDATE were allowed, the referential constraint between the PROJECT and DEPARTMENT tables would be broken.
UPDATE CORPDATA.DEPARTMENT SET DEPTNO = 'D99' WHERE DEPTNAME = 'DEVELOPMENT CENTER'

The following statement fails because it violates the referential constraint that exists between the primary key DEPTNO in DEPARTMENT and the foreign key DEPTNO in PROJECT:
UPDATE CORPDATA.PROJECT SET DEPTNO = 'D00' WHERE DEPTNO = 'D01';

104

DB2 UDB for AS/400 SQL Programming V4R4

The statement attempts to change all department numbers of D01 to department number D00. Since D00 is not a value of the primary key DEPTNO in DEPARTMENT, the statement fails.

Deleting from Tables with Referential Constraints


If a table has a primary key but no dependents, DELETE operates as it does without referential constraints. The same is true if a table has only foreign keys, but no primary key. If a table has a primary key and dependent tables, DELETE deletes or updates rows according to the delete rules specied. All delete rules of all affected relationships must be satised in order for the delete operation to succeed. If a referential constraint is violated, the DELETE fails. The action to be taken on dependent tables when a DELETE is performed on a parent table depends on the delete rule specied for the referential constraint. If no delete rule was dened, the DELETE NO ACTION rule is used. v DELETE NO ACTION Species that the row in the parent table can be deleted if no other row depends on it. If a dependent row exists in the relationship, the DELETE fails. The check for dependent rows is performed at the end of the statement. v DELETE RESTRICT Species that the row in the parent table can be deleted if no other row depends on it. If a dependent row exists in the relationship, the DELETE fails. The check for dependent rows is performed immediately. For example, you cannot delete a department from the department table if it is still responsible for some project which is described by a dependent row in the project table. v DELETE CASCADE Species that rst the designated rows in the parent table are deleted. Then, the dependent rows are deleted. For example, you can delete a department by deleting its row in the department table. Deleting the row from the department table also deletes: The rows for all departments that report to it All departments that report to those departments and so forth. v DELETE SET NULL Species that each nullable column of the foreign key in each dependent row is set to its default value. This means that the column is only set to its default value if it is a member of a foreign key that references the row being deleted. Only the dependent rows that are immediate descendents are affected. v DELETE SET DEFAULT Species that each column of the foreign key in each dependent row is set to its default value. This means that the column is only set to its default value if it is a member of a foreign key that references the row being deleted. Only the dependent rows that are immediate descendants are affected. For example, you can delete an employee from the employee table even if the employee manages some department. In that case, the value of MGRNO for each employee who reported to the manager is set to blanks in the department table. If some other default value was specied on the create of the table, that value is used. This is due to the REPORTS_TO_EXISTS constraint dened for the department table.

Chapter 6. Data Integrity

105

If a descendent table has a delete rule of RESTRICT or NO ACTION and a row is found such that a descendant row cannot be deleted, the entire DELETE fails. When running this statement with a program, the number of rows deleted is returned in SQLERRD(3) in the SQLCA. This number includes only the number of rows deleted in the table specied in the DELETE statement. It does not include those rows deleted according to the CASCADE rule. SQLERRD(5) in the SQLCA contains the number of rows that were affected by referential constraints in all tables. The subtle difference between RESTRICT and NO ACTION rules is easiest seen when looking at the interaction of triggers and referential constraints. Triggers can be dened to re either before or after an operation (a DELETE statement, in this case). A before trigger res before the DELETE is performed and therefore before any checking of constraints. An after trigger is red after the DELETE is performed, and after a constraint rule of RESTRICT (where checking is performed immediately), but before a constraint rule of NO ACTION (where checking is performed at the end of the statement). The triggers and rules would occur in the following order: 1. A before trigger would be red before the DELETE and before a constraint rule of RESTRICT or NO ACTION. 2. An after trigger would be red after a constraint rule of RESTRICT, but before a NO ACTION rule.

Example of DELETE Cascade Rule


Deleting a department from the department table sets WORKDEPT (in the employee table) to null for every employee assigned to that department. Consider the following DELETE statement:
DELETE FROM CORPDATA.DEPARTMENT WHERE DEPTNO = 'E11'

Given the tables and the data as they appear in Appendix A. DB2 UDB for AS/400 Sample Tables, one row is deleted from table DEPARTMENT, and table EMPLOYEE is updated to set the value of WORKDEPT to its default wherever the value was E11. A question mark (?) in the sample data below reects the null value. The results would appear as follows:
Table 16. DEPARTMENT Table. Contents of the table after the DELETE statement is complete.
DEPTNO A00 B01 C01 D01 D11 D21 E01 E21 DEPTNAME SPIFFY COMPUTER SERVICE DIV. PLANNING INFORMATION CENTER DEVELOPMENT CENTER MANUFACTURING SYSTEMS ADMINISTRATION SYSTEMS SUPPORT SERVICES SOFTWARE SUPPORT MGRNO 000010 000020 000030 ? 000060 000070 000050 000100 ADMRDEPT A00 A00 A00 A00 D01 D01 A00 E01

Note that there were no cascaded deletes in the DEPARTMENT table because no department reported to department E11.

106

DB2 UDB for AS/400 SQL Programming V4R4

Below are snapshots of the affected portion of the EMPLOYEE table before and after the DELETE statement is completed.
Table 17. Partial EMPLOYEE Table. Partial contents before the DELETE statement.
EMPNO 000230 000240 000250 000260 000270 000280 000290 000300 000310 000320 000330 000340 FIRSTNME MI JAMES J LASTNAME WORKDEPT PHONENO JEFFERSON D21 MARINO SMITH JOHNSON PEREZ D21 D21 D21 D21 2094 3780 0961 8953 9001 0997 4502 2095 3332 9990 2103 5696 HIREDATE 1966-11-21 1979-12-05 1960-10-30 1975-09-11 1980-09-30 1967-03-24 1980-05-30 1972-06-19 1964-09-12 1965-07-07 1976-02-23 1947-05-05

SALVATORE M DANIEL SYBIL MARIA ETHEL JOHN PHILIP MAUDE RAMLAL WING JASON R S P L R R X F V

SCHNEIDER E11 PARKER SMITH SETRIGHT MEHTA LEE GOUNOT E11 E11 E11 E21 E21 E21

Table 18. Partial EMPLOYEE Table. Partial contents after the DELETE statement.
EMPNO 000230 000240 000250 000260 000270 000280 000290 000300 000310 000320 000330 000340 FIRSTNME MI JAMES J LASTNAME WORKDEPT PHONENO JEFFERSON D21 MARINO SMITH JOHNSON PEREZ D21 D21 D21 D21 2094 3780 0961 8953 9001 0997 4502 2095 3332 9990 2103 5696 HIREDATE 1966-11-21 1979-12-05 1960-10-30 1975-09-11 1980-09-30 1967-03-24 1980-05-30 1972-06-19 1964-09-12 1965-07-07 1976-02-23 1947-05-05

SALVATORE M DANIEL SYBIL MARIA ETHEL JOHN PHILIP MAUDE RAMLAL WING JASON R S P L R R X F V

SCHNEIDER ? PARKER SMITH SETRIGHT MEHTA LEE GOUNOT ? ? ? E21 E21 E21

Check Pending
Referential constraints and check constraints can be in a state known as check pending, where potential violations of the constraint exist. For referential constraints, a violation occurs when potential mismatches exist between parent and foreign keys. For check constraints, a violation occurs when potential values exist in columns which are limited by the check constraint. When the system determines that the constraint may have been violated (such as after a restore operation), the constraint is marked as check pending. When this happens, restrictions are placed on the use of tables involved in the constraint. For referential constraints, the following restrictions apply: v No input or output operations are allowed on the dependent le. v Only read and insert operations are allowed on the parent le.

Chapter 6. Data Integrity

107

When a check constraint is in check pending, the following restrictions apply: v Read operations are not allowed on the le. v Inserts and updates are allowed and the constraint is enforced. To get a constraint out of check pending, you must: 1. Disable the relationship with the Change Physical File Constraint (CHGPFCST) CL command. 2. Correct the key (foreign, parent, or both) data for referential constraints or column data for check constraints. 3. Enable the constraint again with the CHGPFCST CL command. You can identify the rows that are in violation of the constraint with the Display Check Pending Constraint (DSPCPCST) CL command. For more information on working with tables in check pending, see the DB2 UDB for AS/400 Database Programming book.

WITH CHECK OPTION on a View


WITH CHECK OPTION is an optional clause on the CREATE VIEW statement that species the level of checking to be done when inserting or updating data through a view. If the option is specied, every row that is inserted or updated through the view must conform to the denition of that view. WITH CHECK OPTION cannot be specied if the view is read-only. The denition of the view must not include a subquery. If the view is created without a WITH CHECK OPTION clause, insert and update operations that are performed on the view are not checked for conformance to the view denition. Some checking might still occur if the view is directly or indirectly dependent on another view that includes WITH CHECK OPTION. Because the denition of the view is not used, rows might be inserted or updated through the view that do not conform to the denition of the view. This means that the rows could not be selected again using the view. The checking can either be CASCADED or LOCAL. See the DB2 UDB for AS/400 SQL Reference book for additional discussion of WITH CHECK OPTION.

WITH CASCADED CHECK OPTION


The WITH CASCADED CHECK OPTION species that every row that is inserted or updated through the view must conform to the denition of the view. In addition, the search conditions of all dependent views are checked when a row is inserted or updated. If a row does not conform to the denition of the view, that row cannot be retrieved using the view. For example, consider the following updateable view:
CREATE VIEW V1 AS SELECT COL1 FROM T1 WHERE COL1 > 10

Because no WITH CHECK OPTION is specied, the following INSERT statement is successful even though the value being inserted does not meet the search condition of the view.
INSERT INTO V1 VALUES (5)

108

DB2 UDB for AS/400 SQL Programming V4R4

Create another view over V1, specifying the WITH CASCADED CHECK OPTION:
CREATE VIEW V2 AS SELECT COL1 FROM V1 WITH CASCADED CHECK OPTION

The following INSERT statement fails because it would produce a row that does not conform to the denition of V2:
INSERT INTO V2 VALUES (5)

Consider one more view created over V2:


CREATE VIEW V3 AS SELECT COL1 FROM V2 WHERE COL1 < 100

The following INSERT statement fails only because V3 is dependent on V2, and V2 has a WITH CASCADED CHECK OPTION.
INSERT INTO V3 VALUES (5)

However, the following INSERT statement is successful because it conforms to the denition of V2. Because V3 does not have a WITH CASCADED CHECK OPTION, it does not matter that the statement does not conform to the denition of V3.
INSERT INTO V3 VALUES (200)

WITH LOCAL CHECK OPTION


WITH LOCAL CHECK OPTION is identical to WITH CASCADED CHECK OPTION except that you can update a row so that it no longer can be retrieved through the view. This can only happen when the view is directly or indirectly dependent on a view that was dened with no WITH CHECK OPTION clause. For example, consider the same updateable view used in the previous example:
CREATE VIEW V1 AS SELECT COL1 FROM T1 WHERE COL1 > 10

Create second view over V1, this time specifying WITH LOCAL CHECK OPTION:
CREATE VIEW V2 AS SELECT COL1 FROM V1 WITH LOCAL CHECK OPTION

The same INSERT that failed in the previous CASCADED CHECK OPTION example would succeed now because V2 does not have any search conditions, and the search conditions of V1 do not need to be checked since V1 does not specify a check option.
INSERT INTO V2 VALUES (5)

If we again consider one more view created over V2:


CREATE VIEW V3 AS SELECT COL1 FROM V2 WHERE COL1 < 100

The following INSERT is successful again because the search condition on V1 is not checked due to the WITH LOCAL CHECK OPTION on V2, versus the WITH CASCADED CHECK OPTION in the previous example.
INSERT INTO V3 VALUES (5)

The difference between LOCAL and CASCADED CHECK OPTION lies in how many of the dependent views search conditions are checked when a row is inserted or updated.

Chapter 6. Data Integrity

109

v WITH LOCAL CHECK OPTION species that the search conditions of only those dependent views that have the WITH LOCAL CHECK OPTION or WITH CASCADED CHECK OPTION are checked when a row is inserted or updated. v WITH CASCADED CHECK OPTION species that the search conditions of all dependent views are checked when a row is inserted or updated.

Example
Use the following table and views:
CREATE TABLE T1 (COL1 CHAR(10)) CREATE VIEW V1 AS SELECT COL1 FROM T1 WHERE COL1 LIKE 'A%' CREATE VIEW V2 AS SELECT COL1 FROM V1 WHERE COL1 LIKE '%Z' WITH LOCAL CHECK OPTION CREATE VIEW V3 AS SELECT COL1 FROM V2 WHERE COL1 LIKE 'AB%' CREATE VIEW V4 AS SELECT COL1 FROM V3 WHERE COL1 LIKE '%YZ' WITH CASCADED CHECK OPTION CREATE VIEW V5 AS SELECT COL1 FROM V4 WHERE COL1 LIKE 'ABC%'

Different search conditions are going to be checked depending on which view is being operated on with an INSERT or UPDATE. v If V1 is operated on, no conditions are checked because V1 does not have a WITH CHECK OPTION specied. v If V2 is operated on, COL1 must end in the letter Z, but it doesnt have to start with the letter A. This is because the check option is LOCAL, and view V1 does not have a check option specied. v If V3 is operated on, COL1 must end in the letter Z, but it does not have to start with the letter A. V3 does not have a check option specied, so its own search condition must not be met. However, the search condition for V2 must be checked since V3 is dened on V2, and V2 has a check option. v If V4 is operated on, COL1 must start with AB, and must end with YZ. Because V4 has the WITH CASCADED CHECK OPTION specied, every search condition for every view on which V4 is dependent must be checked. v If V5 is operated on, COL1 must start with AB, but not necessarily ABC. This is because V5 does not specify a check option, so its own search condition does not need to be checked. However, because V5 is dened on V4, and V4 had a cascaded check option, every search condition for V4, V3, V2, and V1 must be checked. That is, COL1 must start with AB and end with YZ. If V5 were created WITH LOCAL CHECK OPTION, operating on V5 would mean that COL1 must start with ABC and end with YZ. The LOCAL CHECK OPTION adds the additional requirement that the third character must be a C.

110

DB2 UDB for AS/400 SQL Programming V4R4

DB2 UDB for AS/400 Trigger Support


A trigger is a set of actions that are run automatically when a specied change operation is performed on a specied physical database le. In this discussion, a table is a physical le. The change operation can be an insert, update, or delete high level language statement in an application program, or an SQL INSERT, UPDATE, or DELETE statement. Triggers are useful for tasks such as enforcing business rules, validating input data, and keeping an audit trail. In DB2 UDB for AS/400, the program containing the set of trigger actions can be dened in any supported high level language. The trigger program can have SQL embedded in it. To use trigger support, you must create a trigger program and add it to a physical le using the ADDPFTRG CL command. To add a trigger to a le, you must: v Identify the physical le v Identify the kind of operation v Identify the program that performs the desired actions. There is no SQL statement to associate a physical le with a trigger program. SQL is only involved in that the trigger program can contain embedded SQL statements, and that it could be an SQL INSERT, UPDATE, or DELETE that causes the trigger to be red. Once a trigger program is associated with a physical le, the system trigger support calls the trigger program when a change operation is initiated against the physical le or table, or any logical le or view created over the physical le. Each change operation can call a trigger before or after the change operation occurs. Thus, a physical le can be associated with a maximum of six triggers v Before delete trigger v v v v Before insert trigger Before update trigger After delete trigger After insert trigger

v After update trigger

Trigger Sample
A sample trigger program follows. It is written in ILE C, with embedded SQL. See the DB2 UDB for AS/400 Database Programming book for a full discussion and more examples of trigger usage in DB2 UDB for AS/400.

Chapter 6. Data Integrity

111

#include "string.h" #include "stdlib.h" #include "stdio.h" #include <recio.h> #include <xxcvt.h> #include "qsysinc/h/trgbuf" /* Trigger input parameter */ #include "lib1/csrc/msghand1" /* User defined message handler */ /*********************************************************************/ /* This is a trigger program which is called whenever there is an */ /* update to the EMPLOYEE table. If the employee's commission is */ /* greater than the maximum commission, this trigger program will */ /* increase the employee's salary by 1.04 percent and insert into */ /* the RAISE table. */ /* */ /* The EMPLOYEE record information is passed from the input parameter*/ /* to this trigger program. */ /*********************************************************************/ Qdb_Trigger_Buffer_t *hstruct; char *datapt; /*******************************************************/ /* Structure of the EMPLOYEE record which is used to */ /* store the old or the new record that is passed to */ /* this trigger program. */ /* */ /* Note : You must ensure that all the numeric fields */ /* are aligned at 4 byte boundary in C. */ /* Used either Packed struct or filler to reach */ /* the byte boundary alignment. */ /*******************************************************/ _Packed struct rec{ char empn[6]; _Packed struct { short fstlen ; char fstnam[12]; } fstname; char minit[1]; _Packed struct { short lstlen; char lstnam[15]; } lstname; char dept[3]; char phone[4]; char hdate[10]; char jobn[8]; short edclvl; char sex1[1]; char bdate[10]; decimal(9,2) salary1; decimal(9,2) bonus1; decimal(9,2) comm1; } oldbuf, newbuf; EXEC SQL INCLUDE SQLCA;

Figure 3. Sample Trigger Program (Part 1 of 5)

112

DB2 UDB for AS/400 SQL Programming V4R4

main(int argc, char **argv) { int i; int obufoff; /* int nuloff; /* int nbufoff; /* int nul2off; /* short work_days = 253; /* decimal(9,2) commission = 2000.00; /* decimal(9,2) percentage = 1.04; /* char raise_date[12] = "1982-06-01";/* struct { char empno[6]; char name[30]; decimal(9,2) salary; decimal(9,2) new_salary; } rpt1;

old buffer offset old null byte map offset new buffer offset new null byte map offset work days during in one year cutoff to qualify for raised salary as percentage effective raise date

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

/*******************************************************/ /* Start to monitor any exception. */ /*******************************************************/ _FEEDBACK fc; _HDLR_ENTRY hdlr = main_handler; /****************************************/ /* Make the exception handler active. */ /****************************************/ CEEHDLR(&hdlr, NULL, &fc); /****************************************/ /* Ensure exception handler OK */ /****************************************/ if (fc.MsgNo != CEE0000) { printf("Failed to register exception handler.\n"); exit(99); }; /*******************************************************/ /* Move the data from the trigger buffer to the local */ /* structure for reference. */ /*******************************************************/ hstruct = (Qdb_Trigger_Buffer_t *)argv[1]; datapt = (char *) hstruct; obufoff = hstruct ->Old_Record_Offset; /* old buffer memcpy(&oldbuf,datapt+obufoff,; hstruct->Old_Record_Len); nbufoff = hstruct ->New_Record_Offset; /* new buffer memcpy(&newbuf,datapt+nbufoff,; hstruct->New_Record_Len); */ */

Figure 3. Sample Trigger Program (Part 2 of 5)

Chapter 6. Data Integrity

113

EXEC SQL WHENEVER SQLERROR

GO TO ERR_EXIT;

/*******************************************************/ /* Set the transaction isolation level to the same as */ /* the application based on the input parameter in the */ /* trigger buffer. */ /*******************************************************/ if(strcmp(hstruct->Commit_Lock_Level,"0") == 0) EXEC SQL SET TRANSACTION ISOLATION LEVEL NONE; else{ if(strcmp(hstruct->Commit_Lock_Level,"1") == 0) EXEC SQL SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED, READ WRITE; else { if(strcmp(hstruct->Commit_Lock_Level,"2") == 0) EXEC SQL SET TRANSACTION ISOLATION LEVEL READ COMMITTED; else if(strcmp(hstruct->Commit_Lock_Level,"3") == 0) EXEC SQL SET TRANSACTION ISOLATION LEVEL ALL; } } /********************************************************/ /* If the employee's commission is greater than maximum */ /* commission, then increase the employee's salary */ /* by 1.04 percent and insert into the RAISE table. */ /********************************************************/ if (newbuf.comm1 >= commission) { EXEC SQL SELECT EMPNO, EMPNAME, SALARY INTO :rpt1.empno, :rpt1.name, :rpt1.salary FROM TRGPERF/EMP_ACT WHERE EMP_ACT.EMPNO=:newbuf.empn ; if (sqlca.sqlcode == 0) then { rpt1.new_salary = salary * percentage; EXEC SQL INSERT INTO TRGPERF/RAISE VALUES(:rpt1); } goto finished;

} err_exit: exit(1);

/* All done */ finished: return; } /* end of main line

*/

Figure 3. Sample Trigger Program (Part 3 of 5)

114

DB2 UDB for AS/400 SQL Programming V4R4

/******************************************************************/ /* INCLUDE NAME : MSGHAND1 */ /* */ /* DESCRIPTION : Message handler to signal an exception to */ /* the application to inform that an */ /* error occured in the trigger program. */ /* */ /* NOTE : This message handler is a user defined routine. */ /* */ /******************************************************************/ #include <stdio.h> #include <stdlib.h> #include <recio.h> #include <leawi.h> #pragma linkage (QMHSNDPM, OS) void QMHSNDPM(char *, void *, void *, int, char *, char *, int, void *, void *, ...); Message identifier */ Qualified message file name */ Message data or text */ Length of message data or text */ Message type */ Call message queue */ Call stack counter */ Message key */ Error code */ Optionals: length of call message queue name Call stack entry qualification display external messages screen wait time */ /*********************************************************************/ /******** This is the start of the exception handler function. */ /*********************************************************************/ void main_handler(_FEEDBACK *cond, _POINTER *token, _INT4 *rc, _FEEDBACK *new) { /****************************************/ /* Initialize variables for call to */ /* QMHSNDPM. */ /* User must create a message file and */ /* define a message ID to match the */ /* following data. */ /****************************************/ char message_id[7] = "TRG9999"; char message_file[20] = "MSGF LIB1 "; char message_data[50] = "Trigger error " ; int message_len = 30; char message_type[10] = "*ESCAPE "; char message_q[10] = "_C_pep "; int pgm_stack_cnt = 1; char message_key[4]; /* /* /* /* /* /* /* /* /* /*

Figure 3. Sample Trigger Program (Part 4 of 5)

Chapter 6. Data Integrity

115

struct error_code { int bytes_provided; int bytes_available; char message_id[7]; } error_code;

/****************************************/ /* Declare error code structure for */ /* QMHSNDPM. */ /****************************************/

error_code.bytes_provided = 15; /****************************************/ /* Set the error handler to resume and */ /* mark the last escape message as */ /* handled. */ /****************************************/ *rc = CEE_HDLR_RESUME; /****************************************/ /* Send my own *ESCAPE message. */ /****************************************/ QMHSNDPM(message_id, &message_file, &message_data, message_len, message_type, message_q, pgm_stack_cnt, &message_key, &error_code ); /****************************************/ /* Check that the call to QMHSNDPM */ /* finished correctly. */ /****************************************/ if (error_code.bytes_available != 0) { printf("Error in QMHOVPM : %s\n", error_code.message_id); } }

Figure 3. Sample Trigger Program (Part 5 of 5)

116

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 7. Stored Procedures


DB2 SQL for AS/400 stored procedure support provides a way for an SQL application to dene and then invoke a procedure through SQL statements. Stored procedures can be used in both distributed and non-distributed DB2 SQL for AS/400 applications. One of the big advantages in using stored procedures is that for distributed applications, the execution of one CALL statement on the application requester, or client, can perform any amount of work on the application server. You may dene a procedure as either an SQL procedure or an external procedure. An external procedure can be any supported high level language program (except System/36* programs and procedures) or a REXX procedure. The procedure does not need to contain SQL statements, but it may contain SQL statements. An SQL procedure is dened entirely in SQL, and can contain SQL statements that include SQL control statements. Coding stored procedures requires that the user understand the following: v Stored procedure denition through the CREATE PROCEDURE statement v Stored procedure invocation through the CALL statement v Parameter passing conventions v Methods for returning a completion status to the program invoking the procedure. | | | | You may dene stored procedures by using the CREATE PROCEDURE statement. The CREATE PROCEDURE statement adds procedure and parameter denitions to the catalog tables SYSROUTINES and SYSPARMS. These denitions are then accessible by any SQL CALL statement on the system. The following sections describe the SQL statements used to dene and invoke the stored procedure, information on passing parameters to the stored procedure, and examples of stored procedure usage.

Creating a Procedure
A procedure (often called a stored procedure) is a program that can be called to perform operations that can include both host language statements and SQL statements. Procedures in SQL provide the same benets as procedures in a host language. That is, a common piece of code need only be written and maintained once and can be called from several programs. To create an external procedure or an SQL procedure, you can use the SQL CREATE PROCEDURE statement. Or, you can use Operations Navigator.

Dening an External Procedure


The CREATE PROCEDURE statement for an external procedure: v Names the procedure v Denes the parameters and their attributes v Gives other information about the procedure which will the system uses when it calls the procedure. Consider the following example:

Copyright IBM Corp. 1997, 1999

117

EXEC SQL CREATE PROCEDURE P1 (INOUT PARM1 CHAR(10)) EXTERNAL NAME MYLIB.PROC1 LANGUAGE C GENERAL WITH NULLS;

This CREATE PROCEDURE statement: v Names the procedure P1 v Denes one parameter which is used both as an input parameter and an output parameter. The parameter is a character eld of length ten. Parameters can be dened to be type IN, OUT, or INOUT. The parameter type determines when the values for the parameters get passed to and from the procedure. v Denes the name of the program which corresponds to the procedure, which is PROC1 in MYLIB. MYLIB.PROC1 is the program which is called when the procedure is invoked on a CALL statement. v Indicates that the procedure P1 (program MYLIB.PROC1) is written in C. The language is important since it impacts the types of parameters that can be passed. It also affects how the parameters are passed to the procedure (for example, for ILE C procedures, a NUL-terminator is passed on character, graphic, date, time, and timestamp parameters). v Denes the CALL type to be GENERAL WITH NULLS. This indicates that the parameter for the procedure can possibly contain the NULL value, and therefore would like an additional argument passed to the procedure on the CALL statement. The additional argument is an array of N short integers, where N is the number of parameters that are declared in the CREATE PROCEDURE statement. In this example, the array contains only one element since there is only parameter. It is important to note that it is not necessary to dene a procedure in order to call it. However, if no procedure denition is found, either from a prior CREATE PROCEDURE or from a DECLARE PROCEDURE in this program, certain restrictions and assumptions are made when the procedure is invoked on the CALL statement. For example, the NULL indicator argument cannot be passed. See Using Embedded CALL Statement Where No Procedure Denition Exists on page 125 for an example of a CALL statement without a corresponding procedure denition.

Dening an SQL Procedure


The CREATE PROCEDURE statement for SQL procedures: v Names the procedure v Denes the parameters and their attributes v Provides other information about the procedure which will be used when the procedure is called v Denes the procedure body. The procedure body is the executable part of the procedure and is a single SQL statement. Consider the following simple example that takes as input an employee number and a rate and updates the employees salary:
EXEC SQL CREATE PROCEDURE UPDATE_SALARY_1 (IN EMPLOYEE_NUMBER CHAR(10), IN RATE DECIMAL(6,2))

118

DB2 UDB for AS/400 SQL Programming V4R4

LANGUAGE SQL MODIFIES SQL DATA UPDATE CORPDATA.EMPLOYEE SET SALARY = SALARY * RATE WHERE EMPNO = EMPLOYEE_NUMBER;

This CREATE PROCEDURE statement: v Names the procedure UPDATE_SALARY_1. v Denes parameter EMPLOYEE_NUMBER which is an input parameter and is a character data type of length 6 and parameter RATE which is an input parameter and is a decimal data type. v Indicates the procedure is an SQL procedure that modies SQL data. v Denes the procedure body as a single UPDATE statement. When the procedure is called, the UPDATE statement is executed using the values passed for EMPLOYEE_NUMBER and RATE. Instead of a single UPDATE statement, logic can be added to the SQL procedure using SQL control statements. SQL control statements consist of the following: v an assignment statement v a CALL statement v v v v v a CASE statement a compound statement a FOR statement an IF statement a LOOP statement

v a REPEAT statement v a WHILE statement | | | | | | | | | | | | | | | | | | | | | | | | | The following example takes as input the employee number and a rating that was received on the last evaluation. The procedure uses a CASE statement to determine the appropriate increase and bonus for the update:
EXEC SQL CREATE PROCEDURE UPDATE_SALARY_2 (IN EMPLOYEE_NUMBER CHAR(6), IN RATING INT) LANGUAGE SQL MODIFIES SQL DATA CASE RATING WHEN 1 THEN UPDATE CORPDATA.EMPLOYEE SET SALARY = SALARY * 1.10, BONUS = 1000 WHERE EMPNO = EMPLOYEE_NUMBER; WHEN 2 THEN UPDATE CORPDATA.EMPLOYEE SET SALARY = SALARY * 1.05, BONUS = 500 WHERE EMPNO = EMPLOYEE_NUMBER; ELSE UPDATE CORPDATA.EMPLOYEE SET SALARY = SALARY * 1.03 BONUS = 0 WHERE EMPNO = EMPLOYEE_NUMBER; END CASE;

This CREATE PROCEDURE statement: v Names the procedure UPDATE_SALARY_2.

Chapter 7. Stored Procedures

119

v Denes parameter EMPLOYEE_NUMBER which is an input parameter and is a character data type of length 6 and parameter RATING which is an input parameter and is an integer data type. v Indicates the procedure is an SQL procedure that modies SQL data. v Denes the procedure body. When the procedure is called, input parameter RATING is checked and the appropriate update statement is executed. Multiple statements can be added to a procedure body by adding a compound statement. Within a compound statement, any number of SQL statements can be specied. In addition, SQL variables, cursors, and handlers can be declared. The following example takes as input the department number. It returns the total salary of all the employees in that department and the number of employees in that department who get a bonus.
EXEC SQL CREATE PROCEDURE RETURN_DEPT_SALARY (IN DEPT_NUMBER CHAR(3), OUT DEPT_SALARY DECIMAL(15,2), OUT DEPT_BONUS_CNT INT) LANGUAGE SQL READS SQL DATA P1: BEGIN DECLARE EMPLOYEE_SALARY DECIMAL(9,2); DECLARE EMPLOYEE_BONUS DECIMAL(9,2); DECLARE TOTAL_SALARY DECIMAL(15,2); DECLARE BONUS_CNT INT DEFAULT 0; DECLARE END_TABLE INT DEFAULT 0; DECLARE C1 CURSOR FOR SELECT SALARY, BONUS FROM CORPDATA.EMPLOYEE WHERE WORKDEPT = DEPT_NUMBER; DECLARE CONTINUE HANDLER FOR NOT FOUND SET END_TABLE = 1; DECLARE EXIT HANDLER FOR SQLEXCEPTION SET DEPT_SALARY = NULL; OPEN C1; FETCH C1 INTO EMPLOYEE_SALARY, EMPLOYEE_BONUS; WHILE END_TABLE = 0 DO SET TOTAL_SALARY = TOTAL_SALARY + EMPLOYEE_SALARY + EMPLOYEE_BONUS; IF EMPLOYEE_BONUS > 0 THEN SET BONUS_CNT = BONUS_CNT + 1; END IF; FETCH C1 INTO EMPLOYEE_SALARY, EMPLOYEE_BONUS; END WHILE; CLOSE C1; SET DEPT_SALARY = TOTAL_SALARY; SET DEPT_BONUS_CNT = BONUS_CNT; END P1;

This CREATE PROCEDURE statement: v Names the procedure RETURN_DEPT_SALARY. v Denes parameter DEPT_NUMBER which is an input parameter and is a character data type of length 3, parameter DEPT_SALARY which is an output parameter and is a decimal data type, and parameter DEPT_BONUS_CNT which is an output parameter and is an integer data type. v Indicates the procedure is an SQL procedure that reads SQL data v Denes the procedure body. Declares SQL variables EMPLOYEE_SALARY and TOTAL_SALARY as decimal elds. Declares SQL variables BONUS_CNT and END_TABLE which are integers and are initialized to 0.

120

DB2 UDB for AS/400 SQL Programming V4R4

Declares cursor C1 that selects the columns from the employee table. Declares a continue handler for NOT FOUND, which, when invoked sets variable END_TABLE to 1. This handler is invoked when the FETCH has no more rows to return. When the handler is invoked, SQLCODE and SQLSTATE are reinitialized to 0. Declares an exit handler for SQLEXCEPTION. If invoked, DEPT_SALARY is set to NULL and the processing of the compound statement is terminated. This handler is invoked if any errors occur, ie, the SQLSTATE class is not 00, 01 or 02. Since indicators are always passed to SQL procedures, the indicator value for DEPT_SALARY is 1 when the procedure returns. If this handler is invoked, SQLCODE and SQLSTATE are reinitialized to 0. If the handler for SQLEXCEPTION is not specied and an error occurs that is not handled in another handler, execution of the compound statement is terminated and the error is returned in the SQLCA. Similar to indicators, the SQLCA is always returned from SQL procedures. Includes an OPEN, FETCH, and CLOSE of cursor C1. If a CLOSE of the cursor is not specied, the cursor is closed at the end of the compound statement since SET RESULT SETS is not specied in the CREATE PROCEDURE statement. Includes a WHILE statement which loops until the last record is fetched. For each row retrieved, the TOTAL_SALARY is incremented and, if the employees bonus is more than 0, the BONUS_CNT is incremented. Returns DEPT_SALARY and DEPT_BONUS_CNT as output parameters. Compound statements can be made atomic so if an error occurs that is not expected, the statements within the atomic statement are rolled back. When a procedure that contains an atomic compound statement is called, the transaction must be at a commit boundary. If the compound statement is successful, the transaction is committed. The following example takes as input the department number. It ensures the EMPLOYEE_BONUS table exists, and inserts the name of all employees in the department who get a bonus. The procedure returns the total count of all employees who get a bonus.
EXEC SQL CREATE PROCEDURE CREATE_BONUS_TABLE (IN DEPT_NUMBER CHAR(3), INOUT CNT INT) LANGUAGE SQL MODIFIES SQL DATA CS1: BEGIN ATOMIC DECLARE NAME VARCHAR(30) DEFAULT NULL; DECLARE CONTINUE HANDLER FOR 42710 SELECT COUNT(*) INTO CNT FROM DATALIB.EMPLOYEE_BONUS; DECLARE CONTINUE HANDLER FOR 23505 SET CNT = CNT + 1; DECLARE UNDO HANDLER FOR SQLEXCEPTION SET CNT = NULL; IF DEPT_NUMBER IS NOT NULL THEN CREATE TABLE DATALIB.EMPLOYEE_BONUS (FULLNAME VARCHAR(30), BONUS DECIMAL(10,2)) PRIMARY KEY (FULLNAME); FOR_1:FOR V1 AS C1 CURSOR FOR SELECT FIRSTNME, MIDINIT, LASTNAME, BONUS FROM CORPDATA.EMPLOYEE WHERE WORKDEPT = CREATE_BONUS_TABLE.DEPT_NUMBER; IF BONUS > 0 THEN
Chapter 7. Stored Procedures

121

SET NAME = FIRSTNME || ' ' || MIDINIT || ' '||LASTNAME; INSERT INTO DATALIB.EMPLOYEE_BONUS VALUES(CS1.NAME, FOR_1.BONUS); SET CNT = CNT + 1; END IF; END FOR FOR_1; END IF; END CS1;

This CREATE PROCEDURE statement: v Names the procedure CREATE_BONUS_TABLE. v Denes parameter DEPT_NUMBER which is an input parameter and is a character data type of length 3 and parameter CNT which is an input/output parameter and is an integer data type. v Indicates the procedure is an SQL procedure that modies SQL data v Denes the procedure body. Declares SQL variable NAME as varying character. Declares a continue handler for SQLSTATE 42710, table already exists. If the EMPLOYEE_BONUS table already exists, the handler is invoked and retrieves the number of records in the table. The SQLCODE and SQLSTATE are reset to 0 and processing continues with the FOR statement. Declares a continue handler for SQLSTATE 23505, duplicate key. If the procedure attempts to insert a name that already exists in the table, the handler is invoked and decrements CNT. Processing continues on the SET statement following the INSERT statement. Declares an UNDO handler for SQLEXCEPTION. If invoked, the previous statements are rolled back, CNT is set to 0, and processing continues after the compound statement. In this case, since there is no statement following the compound statement, the procedure returns. Uses the FOR statement to declare cursor C1 to read the records from the EMPLOYEE table. Within the FOR statement, the column names from the select list are used as SQL variables that contain the data from the row fetched. For each row, data from columns FIRSTNME, MIDINIT, and LASTNAME are concatenated together with a blank in between and the result is put in SQL variable NAME. SQL variables NAME and BONUS are inserted into the EMPLOYEE_BONUS table. Because the data type of the select list items must be known when the procedure is created, the table specied in the FOR statement must exist when the procedure is created. An SQL variable name can be qualied with the label name of the FOR statement or compound statement in which it is dened. In the example, FOR_1.BONUS refers to the SQL variable that contains the value of column BONUS for each row selected. CS1.NAME is the variable NAME dened in the compound statement with the beginning label CS1. Parameter names can also be qualied with the procedure name. CREATE_BONUS_TABLE.DEPT_NUMBER is the DEPT_NUMBER parameter for the procedure CREATE_BONUS_TABLE. If unqualied SQL variable names are used in SQL statements where column names are also allowed, and the variable name is the same as a column name, the name will be used to refer to the column. You can also use dynamic SQL in an SQL procedure. The following example creates a table that contains all employees in a specic department. The department number is passed as input to the procedure and is concatenated to the table name.

122

DB2 UDB for AS/400 SQL Programming V4R4

CREATE PROCEDURE CREATE_DEPT_TABLE (IN P_DEPT CHAR(3)) LANGUAGE SQL BEGIN DECLARE STMT CHAR(1000); DECLARE MESSAGE CHAR(20); DECLARE TABLE_NAME CHAR(30); DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET MESSAGE = 'ok'; SET TABLE_NAME = 'DEPT_' P_DEPT '_T'; SET STMT = 'DROP TABLE ' TABLE_NAME; PREPARE S1 FROM STMT; EXECUTE S1; SET STMT = 'CREATE TABLE ' TABLE_NAME '( EMPNO CHAR(6) NOT NULL, FIRSTNME VARCHAR(6) NOT NULL, MIDINIT CHAR(1) NOT NULL, LASTNAME CHAR(15) NOT NULL, SALARY DECIMAL(9,2))'; PREPARE S2 FROM STMT; EXECUTE S2; SET STMT = 'INSERT INTO ' TABLE_NAME 'SELECT EMPNO, FIRSTNME, MIDINIT, LASTNAME, SALARY FROM EMPLOYEE WHERE WORKDEPT = ?'; PREPARE S3 FROM STMT; EXECUTE S3 USING P_DEPT; END;

This CREATE PROCEDURE statement: v Names the procedure CREATE_DEPT_TABLE v Denes parameter P_DEPT which is an input parameter and is a character data type of length 3. v Indicates the procedure is an SQL procedure. v Denes the procedure body. Declares SQL variable STMT and an SQL variable TABLE_NAME as character. Declares a CONTINUE handler. The procedure attempts to DROP the table in case it already exists. If the table does not exist, the rst EXECUTE would fail. With the handler, processing will continue. Sets variable TABLE_NAME to DEPT_ followed by the characters passed in parameter P_DEPT, followed by _T. Sets variable STMT to the DROP statement, and prepares and executes the statement. Sets variable STMT to the CREATE statement, and prepares and executes the statement. Sets variable STMT to the INSERT statement, and prepares and executes the statement. A parameter marker is specied in the where clause. When the statement is executed, the variable P_DEPT is passed on the USING clause. If the procedure is called passing value D21 for the department, table DEPT_D21_T is created and the table is initialized with all the employees that are in department D21.

Chapter 7. Stored Procedures

123

Invoking a Stored Procedure


The CALL statement invokes a stored procedure. On the CALL statement, the name of the stored procedure and any arguments are specied. Arguments may be constants, special registers, or host variables. The external stored procedure specied in the CALL statement does not need to have a corresponding CREATE PROCEDURE statement. Programs created by SQL procedures can only be called by invoking the procedure name specied on the CREATE PROCEDURE statement. There are three types of CALL statements which need to be addressed since DB2 SQL for AS/400 has different rules for each type. They are: v Embedded or dynamic CALL statement where a procedure denition exists v Embedded CALL statement where no procedure denition exists v Dynamic CALL statement where no CREATE PROCEDURE exists Note: Dynamic here refers to: v A dynamically prepared and executed CALL statement v A CALL statement issued in an interactive environment (for example, through STRSQL or Query Manager) v A CALL statement executed in an EXECUTE IMMEDIATE statement. Following is a discussion of each type.

Using CALL Statement Where Procedure Denition Exists


This type of CALL statement gets all the information about the procedure and the argument attributes from the CREATE PROCEDURE catalog denition. The following PL/I example shows a CALL statement which corresponds to the CREATE PROCEDURE statement shown.
DCL HV1 CHAR(10); DCL IND1 FIXED BIN(15); : EXEC SQL CREATE P1 PROCEDURE (INOUT PARM1 CHAR(10)) EXTERNAL NAME MYLIB.PROC1 LANGUAGE C GENERAL WITH NULLS; : EXEC SQL CALL P1 (:HV1 :IND1); :

When this CALL statement is invoked, a call to program MYLIB/PROC1 is made and two arguments are passed. Since the language of the program is ILE C, the rst argument is a C NUL-terminated string eleven characters long containing the contents of host variable HV1. Note that on a call to an ILE C procedure, DB2 SQL for AS/400 adds one character to the parameter declaration if the parameter is declared to be a character, graphic, date, time, or timestamp variable. The second argument is the indicator array. In this case, it is one short integer since there is only one parameter in the CREATE PROCEDURE statement. This argument contains the contents of indicator variable IND1 on entry to the procedure. Since the rst parameter is declared as INOUT, SQL updates the host variable HV1 and the indicator variable IND1 with the values returned from MYLIB.PROC1 before returning to the user program.

124

DB2 UDB for AS/400 SQL Programming V4R4

Note: The procedure names specied on the CREATE PROCEDURE and CALL statements must match EXACTLY in order for the link between the two to be made during the SQL precompile of the program. Note: For an embedded CALL statement where both a CREATE PROCEDURE and a DECLARE PROCEDURE statement exist, the DECLARE PROCEDURE statement will be used.

Using Embedded CALL Statement Where No Procedure Denition Exists


A static CALL statement without a corresponding CREATE PROCEDURE statement is processed with the following rules: v All host variable arguments are treated as INOUT type parameters. v The CALL type is GENERAL (no indicator argument is passed). v The program to call is determined based on the procedure name specied on the CALL, and, if necessary, the naming convention. v The language of the program to call is determined based on information retrieved from the system about the program.

Example of Embedded CALL Statement Where No Procedure Denition Exists


The following is a PL/I example of an embedded CALL statement where no procedure denition exists:
DCL HV2 CHAR(10); : EXEC SQL CALL P2 (:HV2); :

When the CALL statement is invoked, DB2 SQL for AS/400 attempts to nd the program based on standard SQL naming conventions. For the above example, assume that the naming option of *SYS (system naming) is used and that a DFTRDBCOL parameter was not specied on the CRTSQLPLI command. In this case, the library list is searched for a program named P2. Since the call type is GENERAL, no additional argument is passed to the program for indicator variables. Note: If an indicator variable is specied on the CALL statement and its value is less than zero when the CALL statement is executed, an error results because there is no way to pass the indicator to the procedure. Assuming program P2 is found in the library list, the contents of host variable HV2 are passed in to the program on the CALL and the argument returned from P2 is mapped back to the host variable after P2 has completed execution.

Using Embedded CALL Statement With an SQLDA


In either type of embedded CALL (where a procedure denition may or may not exist), an SQLDA may be passed rather than a parameter list, as illustrated in the following C example. Assume that the stored procedure is expecting 2 parameters, the rst of type SHORT INT and the second of type CHAR with a length of 4.

Chapter 7. Stored Procedures

125

#define SQLDA_HV_ENTRIES 2 #define SHORTINT 500 #define NUL_TERM_CHAR 460 exec sql include sqlca; exec sql include sqlda; ... typedef struct sqlda Sqlda; typedef struct sqlda* Sqldap; ... main() { Sqldap dap; short col1; char col2[4]; int bc; dap = (Sqldap) malloc(bc=SQLDASIZE(SQLDA_HV_ENTRIES)); /* SQLDASIZE is a macro defined in the sqlda include */ col1 = 431; strcpy(col2,"abc"); strncpy(dap->sqldaid,"SQLDA ",8); dap->sqldabc = bc; /* bc set in the malloc statement above */ dap->sqln = SQLDA_HV_ENTRIES; dap->sqld = SQLDA_HV_ENTRIES; dap->sqlvar[0].sqltype = SHORTINT; dap->sqlvar[0].sqllen = 2; dap->sqlvar[0].sqldata = (char*) &col1; dap->sqlvar[0].sqlname.length = 0; dap->sqlvar[1].sqltype = NUL_TERM_CHAR; dap->sqlvar[1].sqllen = 4; dap->sqlvar[1].sqldata = col2; ... EXEC SQL CALL P1 USING DESCRIPTOR :*dap; ... }

It should be noted that the name of the called procedure may also be stored in a host variable and the host variable used in the CALL statement, instead of the hard-coded procedure name. For example:
... main() { char proc_name[15]; ... strcpy (proc_name, "MYLIB.P3"); ... EXEC SQL CALL :proc_name ...; ... }

In the above example, if MYLIB.P3 is expecting parameters, then either a parameter list or an SQLDA passed with the USING DESCRIPTOR clause may be used, as shown in the previous example. When a host variable containing the procedure name is used in the CALL statement and a CREATE PROCEDURE catalog denition exists, it will be used. The procedure name cannot be specied as a parameter marker. More examples for calling stored procedures may be found later in this chapter and also in the DATABASE 2 Advanced Database Functions book.

126

DB2 UDB for AS/400 SQL Programming V4R4

Using Dynamic CALL Statement Where No CREATE PROCEDURE Exists


The following rules pertain to the processing of a dynamic CALL statement when there is no CREATE PROCEDURE denition: v All arguments are treated as IN type parameters. v The CALL type is GENERAL (no indicator argument is passed). v The program to call is determined based on the procedure name specied on the CALL and the naming convention. v The language of the program to call is determined based on information retrieved from the system about the program.

Example of Dynamic CALL Statement Where No CREATE PROCEDURE Exists


The following is a C example of a dynamic CALL statement:
char hv3[10],string[100]; : strcpy(string,"CALL MYLIB.P3 ('P3 TEST')"); EXEC SQL EXECUTE IMMEDIATE :string; :

This example shows a dynamic CALL statement executed through an EXECUTE IMMEDIATE statement. The call is made to program MYLIB.P3 with one parameter passed as a character variable containing P3 TEST. When executing a CALL statement and passing a constant, as in the previous example, the length of the expected argument in the program must be kept in mind. If program MYLIB.P3 expected an argument of only 5 characters, the last 2 characters of the constant specied in the example would be lost to the program. Note: For this reason, it is always safer to use host variables on the CALL statement so that the attributes of the procedure can be matched exactly and so that characters are not lost. For dynamic SQL, host variables can be specied for CALL statement arguments if the PREPARE and EXECUTE statements are used to process it. For numeric constants passed on a CALL statement, the following rules apply: v All integer constants are passed as fullword binary integers. v All decimal constants are passed as packed decimal values. Precision and scale are determined based on the constant value. For instance, a value of 123.45 is passed as a packed decimal(5,2). Likewise, a value of 001.01 is also passed with a precision and scale of 5 and 2, respectively. v All oating point constants are passed as double-precision oating point. Special registers specied on a dynamic CALL statement are passed as follows: v CURRENT DATE Passed as a 10-byte character string in ISO format. v CURRENT TIME Passed as an 8-byte character string in ISO format. v CURRENT TIMESTAMP Passed as a 26-byte character string in IBM SQL format.
Chapter 7. Stored Procedures

127

v CURRENT TIMEZONE Passed as a packed decimal number with a precision of 6 and a scale of 0. v CURRENT SERVER Passed as an 18-byte varying length character string. v USER Passed as an 18-byte varying length character string. v CURRENT PATH Passed as a 558-byte varying character length character string.

Parameter Passing Conventions for Stored Procedures


The CALL statement can pass arguments to programs written in all supported host languages and REXX procedures. Each language supports different data types which are tailored to it. The SQL data type is contained in the leftmost column of the following table. Other columns in that row contain an indication of whether that data type is supported as a parameter type for a particular language. If the column contains a dash (-), the data type is not supported as a parameter type for that language. A host variable declaration indicates that DB2 SQL for AS/400 supports this data type as a parameter in this language. The declaration indicates how host variables must be declared to be received and set properly by the procedure. When calling an SQL procedure, all SQL data types are supported so no column is provided in the table.
Table 19. Data Types of Parameters
SQL Data Type SMALLINT INTEGER DECIMAL(p,s) C and C++ short long decimal(p,s) CL TYPE(*DEC) LEN(p s) COBOL for AS/400 and ILE COBOL for AS/400 PIC S9(4) BINARY PIC S9(9) BINARY PIC S9(p-s)V9(s) PACKED-DECIMAL Note: Precision must not be greater than 18. PIC S9(p-s)V9(s) DISPLAY SIGN LEADING SEPARATE Note: Precision must not be greater than 18. COMP-1 Note: Only supported for ILE COBOL for AS/400. COMP-2 Note: Only supported for ILE COBOL for AS/400. PIC X(n) Varying-Length Character String (see COBOL chapter) Note: Only supported for ILE COBOL for AS/400. Varying-Length Character String (see COBOL chapter) Note: Only supported for ILE COBOL for AS/400.

NUMERIC(p,s)

REAL or FLOAT(p)

oat

DOUBLE PRECISION or FLOAT or FLOAT(p) CHARACTER(n) VARCHAR(n)

double

char ... [n+1] char ... [n+1]

TYPE(*CHAR) LEN(n) -

VARCHAR(n) FOR BIT DATA

VARCHAR structured form (see C chapter)

128

DB2 UDB for AS/400 SQL Programming V4R4

Table 19. Data Types of Parameters (continued)


SQL Data Type GRAPHIC(n) C and C++ wchar_t ... [n+1] CL COBOL for AS/400 and ILE COBOL for AS/400 PIC G(n) DISPLAY-1 or PIC N(n) Note: Only supported for ILE COBOL for AS/400. Varying-Length Graphic String (see COBOL chapter) Note: Only supported for ILE COBOL for AS/400. PIC X(10) For ILE COBOL for AS/400 only, FORMAT DATE. PIC X(8) For ILE COBOL for AS/400 only, FORMAT TIME. PIC X(26) For ILE COBOL for AS/400 only, FORMAT TIMESTAMP. PIC S9(4) BINARY CLOB string (see COBOL chapter). Note: only supported for ILE COBOL for AS/400. BLOB string (see COBOL chapter). Note: only supported for ILE COBOL for AS/400. DBCLOB string (see COBOL chapter). Note: only supported for ILE COBOL for AS/400.

VARGRAPHIC(n)

VARGRAPHIC structured form (see C chapter)

DATE

char ... [11]

TYPE(*CHAR) LEN(10)

TIME

char ... [9]

TYPE(*CHAR) LEN(8)

TIMESTAMP

char ... [27]

TYPE(*CHAR) LEN(26)

Indicator Variable

short CLOB structured form (see C chapter)

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

CLOB

BLOB

BLOB structured form (see C chapter)

DBCLOB

DBCLOB structured form (see C chapter)

Table 20. Data Types of Parameters


SQL Data Type SMALLINT INTEGER FORTRAN INTEGER*2 INTEGER*4 PL/I FIXED BIN(15) FIXED BIN(31) REXX numeric string with no decimal (and an optional leading sign). numeric string with a decimal (and an optional leading sign) string with digits, then an E, (then an optional sign), then digits string with digits, then an E, (then an optional sign), then digits string with n characters within two apostrophes
Chapter 7. Stored Procedures

DECIMAL(p,s)

FIXED DEC(p,s)

NUMERIC(p,s) REAL or FLOAT(p)

REAL*4

FLOAT BIN(p)

DOUBLE PRECISION or FLOAT or FLOAT(p) CHARACTER(n)

REAL*8

FLOAT BIN(p)

CHARACTER*n

CHAR(n)

129

Table 20. Data Types of Parameters (continued)


SQL Data Type VARCHAR(n) VARCHAR(n) FOR BIT DATA GRAPHIC(n) FORTRAN PL/I CHAR(n) VAR CHAR(n) VAR REXX string with n characters within two apostrophes string with n characters within two apostrophes string starting with G, then n double byte characters, then string starting with G, then n double byte characters, then string with 10 characters within two apostrophes string with 8 characters within two apostrophes string with 26 characters within two apostrophes numeric string with no decimal (and an optional leading sign). -

VARGRAPHIC(n)

DATE TIME TIMESTAMP Indicator Variable

CHARACTER*10 CHARACTER*8 CHARACTER*26 INTEGER*2

CHAR(10) CHAR(8) CHAR(26) FIXED BIN(15)

| | | | | |

CLOB BLOB DBCLOB

CLOB structured form (see PL/I chapter) BLOB structured form (see PL/I chapter) DBCLOB structured form (see PL/I chapter)

Table 21. Data Types of Parameters


SQL Data Type SMALLINT RPG Data structure that contains a single sub-eld. B in position 43, length must be 2, and 0 in position 52 of the sub-eld specication. Data structure that contains a single sub-eld. B in position 43, length must be 4, and 0 in position 52 of the sub-eld specication. ILE RPG Data specication. B in position 40, length must be <= 4, and 00 in positions 41-42 of the sub-eld specication. Data specication. B in position 40, length must be <=09 and >=05, and 00 in positions 41-42 of the sub-eld specication.

INTEGER

DECIMAL(p,s)

Data specication. P in position 40 and 00 Data structure that contains a single sub-eld. P in position 43 and 0 through 9 through 31 in positions 41-42 of the in position 52 of the sub-eld specication. sub-eld specication. or A numeric input eld or calculation result eld. Data structure that contains a single sub-eld. Blank in position 43 and 0 through 9 in position 52 of the sub-eld specication. Data specication. S in position 40, or Blank in position 40 and 00 through 31 in position 41-42 of the sub-eld specication. Data specication. F in position 40, length must be 4. Data specication. F in position 40, length must be 8.

NUMERIC(p,s)

REAL or FLOAT(p) DOUBLE PRECISION or FLOAT or FLOAT(p)

130

DB2 UDB for AS/400 SQL Programming V4R4

Table 21. Data Types of Parameters (continued)


SQL Data Type CHARACTER(n) RPG Data structure eld without sub-elds or data structure that contains a single sub-eld. Blank in position 43 and 52 of the sub-eld specication. or A character input eld or calculation result eld. ILE RPG Data specication. A in position 40, or Blank in position 40 and 41-42 of the sub-eld specication.

VARCHAR(n)

Data specication. A in position 40, or Blank in position 40 and 41-42 of the sub-eld specication and the keyword VARYING in positions 44-80. Data specication. A in position 40, or Blank in position 40 and 41-42 of the sub-eld specication and the keyword VARYING in positions 44-80. Data specication. G in position 40 of the sub-eld specication. Data specication. G in position 40 of the sub-eld specication and the keyword VARYING in positions 44-80. Data specication. D in position 40 of the sub-eld specication. DATFMT(*ISO) in position 44-80.

VARCHAR(n) FOR BIT DATA

GRAPHIC(n) VARGRAPHIC(n)

DATE

Data structure eld without sub-elds or data structure that contains a single sub-eld. Blank in position 43 and 52 of the sub-eld specication. Length is 10. or A character input eld or calculation result eld.

TIME

Data specication. T in position 40 of the Data structure eld without sub-elds or sub-eld specication. TIMFMT(*ISO) in data structure that contains a single position 44-80. sub-eld. Blank in position 43 and 52 of the sub-eld specication. Length is 8. or A character input eld or calculation result eld. Data structure eld without sub-elds or data structure that contains a single sub-eld. Blank in position 43 and 52 of the sub-eld specication. Length is 26. or A character input eld or calculation result eld. Data structure that contains a single sub-eld. B in position 43, length must be 2, and 0 in position 52 of the sub-eld specication. Data specication. Z in position 40 of the sub-eld specication.

TIMESTAMP

Indicator Variable

Data specication. B in position 40, length must be <=4, and 00 in positions 41-42 of the sub-eld specication. CLOB structured form (see RPG chapter) BLOB structured form (see RPG chapter) DBCLOB structured form (see RPG chapter)

| | | |

CLOB BLOB DBCLOB

Chapter 7. Stored Procedures

131

Indicator Variables and Stored Procedures


Indicator variables can be used with the CALL statement, provided host variables are used for the parameters, to pass additional information to and from the procedure. Indicator variables are the SQL standard means of denoting that the associated host variable should be interpreted as containing the null value, and this is their primary use. To indicate that an associated host variable contains the null value, the indicator variable, which is a two-byte integer, is set to a negative value. A CALL statement with indicator variables is processed as follows: v If the indicator variable is negative, this denotes the null value. A default value is passed for the associated host variable on the CALL and the indicator variable is passed unchanged. v If the indicator variable is not negative, this denotes that the host variable contains a non-null value. In this case, the host variable and the indicator variable are passed unchanged. Note that these rules of processing are the same for input parameters to the procedure as well as output parameters returned from the procedure. When indicator variables are used with stored procedures, the correct method of coding their handling is to check the value of the indicator variable rst before using the associated host variable. The following example illustrates the handling of indicator variables in CALL statements. Notice that the logic checks the value of the indicator variable before using the associated variable. Also note the method that the indicator variables are passed into procedure PROC1 (as a third argument consisting of an array of two-byte values). Assume a procedure was dened as follows:
CREATE PROCEDURE PROC1 (INOUT DECIMALOUT DECIMAL(7,2), INOUT DECOUT2 DECIMAL(7,2)) EXTERNAL NAME LIB1.PROC1 LANGUAGE RPGLE GENERAL WITH NULLS)

132

DB2 UDB for AS/400 SQL Programming V4R4

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Program CRPG ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ D INOUT1 S 7P 2 D INOUT1IND S 4B 0 D INOUT2 S 7P 2 D INOUT2IND S 4B 0 C EVAL INOUT1 = 1 C EVAL INOUT1IND = 0 C EVAL INOUT2 = 1 C EVAL INOUT2IND = -2 C/EXEC SQL CALL PROC1 (:INOUT1 :INOUT1IND , :INOUT2 C+ :INOUT2IND) C/END-EXEC C EVAL INOUT1 = 1 C EVAL INOUT1IND = 0 C EVAL INOUT2 = 1 C EVAL INOUT2IND = -2 C/EXEC SQL CALL PROC1 (:INOUT1 :INOUT1IND , :INOUT2 C+ :INOUT2IND) C/END-EXEC C INOUT1IND IFLT 0 C* : C* HANDLE NULL INDICATOR C* : C ELSE C* : C* INOUT1 CONTAINS VALID DATA C* : C ENDIF C* : C* HANDLE ALL OTHER PARAMETERS C* IN A SIMILAR FASHION C* : C RETURN ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ End of PROGRAM CRPG ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Figure 4. Handling of Indicator Variables in CALL Statements (Part 1 of 2)

Chapter 7. Stored Procedures

133

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Program PROC1 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ D INOUTP S 7P 2 D INOUTP2 S 7P 2 D NULLARRAY S 4B 0 DIM(2) C *ENTRY PLIST C PARM INOUTP C PARM INOUTP2 C PARM NULLARRAY C NULLARRAY(1) IFLT 0 C* : C* INOUTP DOES NOT CONTAIN MEANINGFUL DATA C* C ELSE C* : C* INOUTP CONTAINS MEANINGFUL DATA C* : C ENDIF C* PROCESS ALL REMAINING VARIABLES C* C* BEFORE RETURNING, SET OUTPUT VALUE FOR FIRST C* PARAMETER AND SET THE INDICATOR TO A NON-NEGATIV C* VALUE SO THAT THE DATA IS RETURNED TO THE CALLING C* PROGRAM C* C EVAL INOUTP2 = 20.5 C EVAL NULLARRAY(2) = 0 C* C* INDICATE THAT THE SECOND PARAMETER IS TO CONTAIN C* THE NULL VALUE UPON RETURN. THERE IS NO POINT C* IN SETTING THE VALUE IN INOUTP SINCE IT WON'T BE C* PASSED BACK TO THE CALLER. C EVAL NULLARRAY(1) = -5 C RETURN ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ End of PROGRAM PROC1 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Figure 4. Handling of Indicator Variables in CALL Statements (Part 2 of 2)

Returning a Completion Status to the Calling Program


One method of returning a status to the SQL program issuing the CALL statement is to code an extra INOUT type parameter and set it prior to returning from the procedure. When the procedure being called is an existing program, this is not always possible. Another method of returning a status to the SQL program issuing the CALL statement is to send an escape message to the calling program (operating system program QSQCALL) which invokes the procedure. The calling program that invokes the procedure is QSQCALL. Each language has methods for signalling conditions and sending messages. Refer to the respective language reference to determine the proper way to signal a message. When the message is signalled, QSQCALL turns the error into SQLCODE/SQLSTATE -443/38501.

134

DB2 UDB for AS/400 SQL Programming V4R4

Examples
These examples show how the arguments of the CALL statement are passed to the procedure for several languages. They also show how to receive the arguments into local variables in the procedure. The rst example shows the calling ILE C program that uses the CREATE PROCEDURE denitions to call the P1 and P2 procedures. Procedure P1 is written in C and has 10 parameters. Procedure P2 is written in PL/I and also has 10 parameters. Assume two procedures are dened as follows:
EXEC SQL CREATE PROCEDURE P1 (INOUT PARM1 CHAR(10), INOUT PARM2 INTEGER, INOUT PARM3 SMALLINT, INOUT PARM4 FLOAT(22), INOUT PARM5 FLOAT(53), INOUT PARM6 DECIMAL(10,5), INOUT PARM7 VARCHAR(10), INOUT PARM8 DATE, INOUT PARM9 TIME, INOUT PARM10 TIMESTAMP) EXTERNAL NAME TEST12.CALLPROC2 LANGUAGE C GENERAL WITH NULLS EXEC SQL CREATE PROCEDURE P2 (INOUT PARM1 CHAR(10), INOUT PARM2 INTEGER, INOUT PARM3 SMALLINT, INOUT PARM4 FLOAT(22), INOUT PARM5 FLOAT(53), INOUT PARM6 DECIMAL(10,5), INOUT PARM7 VARCHAR(10), INOUT PARM8 DATE, INOUT PARM9 TIME, INOUT PARM10 TIMESTAMP) EXTERNAL NAME TEST12.CALLPROC LANGUAGE PLI GENERAL WITH NULLS

Chapter 7. Stored Procedures

135

Example 1. ILE C and PL/I Procedures Called From ILE C Applications


/**************************************************************/ /*********** START OF SQL C Application ***********************/ #include <stdio.h> #include <string.h> #include <decimal.h> main() { EXEC SQL INCLUDE SQLCA; char PARM1[10]; signed long int PARM2; signed short int PARM3; float PARM4; double PARM5; decimal(10,5) PARM6; struct { signed short int parm7l; char parm7c[10]; } PARM7; char PARM8[10]; /* FOR DATE */ char PARM9[8]; /* FOR TIME */ char PARM10[26]; /* FOR TIMESTAMP */

Figure 5. Sample of CREATE PROCEDURE and CALL (Part 1 of 2)

136

DB2 UDB for AS/400 SQL Programming V4R4

/*******************************************************/ /* Initialize variables for the call to the procedures */ /*******************************************************/ strcpy(PARM1,"PARM1"); PARM2 = 7000; PARM3 = -1; PARM4 = 1.2; PARM5 = 1.0; PARM6 = 10.555; PARM7.parm7l = 5; strcpy(PARM7.parm7c,"PARM7"); strncpy(PARM8,"1994-12-31",10); /* FOR DATE */ strncpy(PARM9,"12.00.00",8); /* FOR TIME */ strncpy(PARM10,"1994-12-31-12.00.00.000000",26); /* FOR TIMESTAMP */ /***********************************************/ /* Call the C procedure */ /* */ /* */ /***********************************************/ EXEC SQL CALL P1 (:PARM1, :PARM2, :PARM3, :PARM4, :PARM5, :PARM6, :PARM7, :PARM8, :PARM9, :PARM10 ); if (strncmp(SQLSTATE,"00000",5)) { /* Handle error or warning returned on CALL statement */ } /* Process return values from the CALL. : /***********************************************/ /* Call the PLI procedure */ /* */ /* */ /***********************************************/ /* Reset the host variables prior to making the CALL /* : EXEC SQL CALL P2 (:PARM1, :PARM2, :PARM3, :PARM4, :PARM5, :PARM6, :PARM7, :PARM8, :PARM9, :PARM10 ); if (strncmp(SQLSTATE,"00000",5)) { /* Handle error or warning returned on CALL statement } /* Process return values from the CALL. : } */

*/ */

*/ */

/******** END OF C APPLICATION **********************************/ /****************************************************************/

Figure 5. Sample of CREATE PROCEDURE and CALL (Part 2 of 2)

Chapter 7. Stored Procedures

137

/******** START OF C PROCEDURE P1 *******************************/ /* PROGRAM TEST12/CALLPROC2 */ /****************************************************************/ #include <stdio.h> #include <string.h> #include <decimal.h> main(argc,argv) int argc; char *argv[]; { char parm1[11]; long int parm2; short int parm3,i,j,*ind,ind1,ind2,ind3,ind4,ind5,ind6,ind7, ind8,ind9,ind10; float parm4; double parm5; decimal(10,5) parm6; char parm7[11]; char parm8[10]; char parm9[8]; char parm10[26]; /* *********************************************************/ /* Receive the parameters into the local variables */ /* Character, date, time, and timestamp are passed as */ /* NUL terminated strings - cast the argument vector to */ /* the proper data type for each variable. Note that */ /* the argument vector could be used directly instead of */ /* copying the parameters into local variables - the copy */ /* is done here just to illustrate the method. */ /* *********************************************************/ /* Copy 10 byte character string into local variable strcpy(parm1,argv[1]); /* Copy 4 byte integer into local variable parm2 = *(int *) argv[2]; /* Copy 2 byte integer into local variable parm3 = *(short int *) argv[3]; /* Copy floating point number into local variable parm4 = *(float *) argv[4]; /* Copy double precision number into local variable parm5 = *(double *) argv[5]; /* Copy decimal number into local variable parm6 = *(decimal(10,5) *) argv[6]; */ */ */ */ */ */

Figure 6. Sample Procedure P1 (Part 1 of 2)

138

DB2 UDB for AS/400 SQL Programming V4R4

/**********************************************************/ /* Copy NUL terminated string into local variable. */ /* Note that the parameter in the CREATE PROCEDURE was */ /* declared as varying length character. For C, varying */ /* length are passed as NUL terminated strings unless */ /* FOR BIT DATA is specified in the CREATE PROCEDURE */ /**********************************************************/ strcpy(parm7,argv[7]); /**********************************************************/ /* Copy date into local variable. */ /* Note that date and time variables are always passed in */ /* ISO format so that the lengths of the strings are */ /* known. strcpy would work here just as well. */ /**********************************************************/ strncpy(parm8,argv[8],10); /* Copy time into local variable strncpy(parm9,argv[9],8); */

/**********************************************************/ /* Copy timestamp into local variable. */ /* IBM SQL timestamp format is always passed so the length*/ /* of the string is known. */ /**********************************************************/ strncpy(parm10,argv[10],26); /**********************************************************/ /* The indicator array is passed as an array of short */ /* integers. There is one entry for each parameter passed */ /* on the CREATE PROCEDURE (10 for this example). */ /* Below is one way to set each indicator into separate */ /* variables. */ /**********************************************************/ ind = (short int *) argv[11]; ind1 = *(ind++); ind2 = *(ind++); ind3 = *(ind++); ind4 = *(ind++); ind5 = *(ind++); ind6 = *(ind++); ind7 = *(ind++); ind8 = *(ind++); ind9 = *(ind++); ind10 = *(ind++); : /* Perform any additional processing here */ : return; } /******** END OF C PROCEDURE P1 *******************************/

Figure 6. Sample Procedure P1 (Part 2 of 2)

Chapter 7. Stored Procedures

139

/******** START OF PL/I PROCEDURE P2 **************************/ /******** PROGRAM TEST12/CALLPROC *****************************/ /**************************************************************/ CALLPROC :PROC( PARM1,PARM2,PARM3,PARM4,PARM5,PARM6,PARM7, PARM8,PARM9,PARM10,PARM11); DCL SYSPRINT FILE STREAM OUTPUT EXTERNAL; OPEN FILE(SYSPRINT); DCL PARM1 CHAR(10); DCL PARM2 FIXED BIN(31); DCL PARM3 FIXED BIN(15); DCL PARM4 BIN FLOAT(22); DCL PARM5 BIN FLOAT(53); DCL PARM6 FIXED DEC(10,5); DCL PARM7 CHARACTER(10) VARYING; DCL PARM8 CHAR(10); /* FOR DATE */ DCL PARM9 CHAR(8); /* FOR TIME */ DCL PARM10 CHAR(26); /* FOR TIMESTAMP */ DCL PARM11(10) FIXED BIN(15); /* Indicators */ /* PERFORM LOGIC - Variables can be set to other values for */ /* return to the calling program. */ : END CALLPROC;

Figure 7. Sample Procedure P2

The next example shows a REXX procedure called from an ILE C program. Assume a procedure is dened as follows:
EXEC SQL CREATE PROCEDURE REXXPROC (IN PARM1 CHARACTER(20), IN PARM2 INTEGER, IN PARM3 DECIMAL(10,5), IN PARM4 DOUBLE PRECISION, IN PARM5 VARCHAR(10), IN PARM6 GRAPHIC(4), IN PARM7 VARGRAPHIC(10), IN PARM8 DATE, IN PARM9 TIME, IN PARM10 TIMESTAMP) EXTERNAL NAME 'TEST.CALLSRC(CALLREXX)' LANGUAGE REXX GENERAL WITH NULLS

140

DB2 UDB for AS/400 SQL Programming V4R4

Example 2. Sample REXX Procedure Called From C Application


/**************************************************************/ /*********** START OF SQL C Application ***********************/ #include <decimal.h> #include <stdio.h> #include <string.h> #include <wcstr.h> /*-----------------------------------------------------------*/ exec sql include sqlca; exec sql include sqlda; /* ***********************************************************/ /* Declare host variable for the CALL statement */ /* ***********************************************************/ char parm1[20]; signed long int parm2; decimal(10,5) parm3; double parm4; struct { short dlen; char dat[10]; } parm5; wchar_t parm6[4] = { 0xC1C1, 0xC2C2, 0xC3C3, 0x0000 }; struct { short dlen; wchar_t dat[10]; } parm7 = {0x0009, 0xE2E2,0xE3E3,0xE4E4, 0xE5E5, 0xE6E6, 0xE7E7, 0xE8E8, 0xE9E9, 0xC1C1, 0x0000 }; char parm8[10]; char parm9[8]; char parm10[26]; main() {

Figure 8. Sample REXX Procedure Called From C Application (Part 1 of 4)

Chapter 7. Stored Procedures

141

/* *************************************************************/ /* Call the procedure - on return from the CALL statement the */ /* SQLCODE should be 0. If the SQLCODE is non-zero, */ /* the procedure detected an error. */ /* *************************************************************/ strcpy(parm1,"TestingREXX"); parm2 = 12345; parm3 = 5.5; parm4 = 3e3; parm5.dlen = 5; strcpy(parm5.dat,"parm6"); strcpy(parm8,"1994-01-01"); strcpy(parm9,"13.01.00"); strcpy(parm10,"1994-01-01-13.01.00.000000"); EXEC SQL CALL REXXPROC (:parm1, :parm2, :parm3,:parm4, :parm5, :parm6, :parm7, :parm8, :parm9, :parm10); if (strncpy(SQLSTATE,"00000",5)) { /* handle error or warning returned on CALL : } :

*/

/****** END OF SQL C APPLICATION ************************************/ /**********************************************************************/

Figure 8. Sample REXX Procedure Called From C Application (Part 2 of 4)

142

DB2 UDB for AS/400 SQL Programming V4R4

/**********************************************************************/ /****** START OF REXX MEMBER TEST/CALLSRC CALLREXX ********************/ /**********************************************************************/ /* REXX source member TEST/CALLSRC CALLREXX */ /* Note the extra parameter being passed for the indicator*/ /* array. */ /* */ /* ACCEPT THE FOLLOWING INPUT VARIABLES SET TO THE */ /* SPECIFIED VALUES : */ /* AR1 CHAR(20) = 'TestingREXX' */ /* AR2 INTEGER = 12345 */ /* AR3 DECIMAL(10,5) = 5.5 */ /* AR4 DOUBLE PRECISION = 3e3 */ /* AR5 VARCHAR(10) = 'parm6' */ /* AR6 GRAPHIC = G'C1C1C2C2C3C3' */ /* AR7 VARGRAPHIC = */ /* G'E2E2E3E3E4E4E5E5E6E6E7E7E8E8E9E9EAEA' */ /* AR8 DATE = '1994-01-01' */ /* AR9 TIME = '13.01.00' */ /* AR10 TIMESTAMP = */ /* '1994-01-01-13.01.00.000000' */ /* AR11 INDICATOR ARRAY = +0+0+0+0+0+0+0+0+0+0 */ /**********************************************************/ /* Parse the arguments into individual parameters */ /**********************************************************/ parse arg ar1 ar2 ar3 ar4 ar5 ar6 ar7 ar8 ar9 ar10 ar11 /**********************************************************/ /* Verify that the values are as expected */ /**********************************************************/ if ar1<>"'TestingREXX'" then signal ar1tag if ar2<>12345 then signal ar2tag if ar3<>5.5 then signal ar3tag if ar4<>3e3 then signal ar4tag if ar5<>"'parm6'" then signal ar5tag if ar6 <>"G'AABBCC'" then signal ar6tag if ar7 <>"G'SSTTUUVVWWXXYYZZAA'" then , signal ar7tag if ar8 <> "'1994-01-01'" then signal ar8tag if ar9 <> "'13.01.00'" then signal ar9tag if ar10 <> "'1994-01-01-13.01.00.000000'" then signal ar10tag if ar11 <> "+0+0+0+0+0+0+0+0+0+0" then signal ar11tag

Figure 8. Sample REXX Procedure Called From C Application (Part 3 of 4)

Chapter 7. Stored Procedures

143

/************************************************************/ /* Perform other processing as necessary .. */ /************************************************************/ : /************************************************************/ /* Indicate the call was successful by exiting with a */ /* return code of 0 */ /************************************************************/ exit(0) ar1tag: say "ar1 did not match" ar1 exit(1) ar2tag: say "ar2 did not match" ar2 exit(1) : : /************ END OF REXX MEMBER **********************************/

Figure 8. Sample REXX Procedure Called From C Application (Part 4 of 4)

144

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 8. Using the Object-Relational Capabilities


This chapter discusses the object-oriented capabilities of DB2. v Why Use the DB2 Object Extensions? v DB2 Approach to Supporting Objects v Using Large Objects (LOBs) v User-Dened Functions (UDF) v User-dened Distinct Types (UDT) v Synergy Between UDTs, UDFs, and LOBs One of the most important recent developments in modern programming language technology is object-orientation. Object orientation is the notion that entities in the application domain can be modeled as independent objects that are related to one another by means of classication. Object-orientation lets you capture the similarities and differences among objects in your application domain and group those objects together into related types. Objects of the same type behave in the same way because they share the same set of type-specic functions. These functions reect the behavior of your objects in the application domain.

Why Use the DB2 Object Extensions?


| | | | | | | With the object extensions of DB2, you can incorporate object-oriented (OO) concepts and methodologies into your relational database. You accomplish this by extending it with richer sets of types and functions. With these extensions, you can store instances of object-oriented data types in columns of tables, and operate on them by means of functions in SQL statements. In addition, you can make the semantic behavior of stored objects an important resource that can be shared among all your applications by means of the database. To incorporate object-orientation into your relational database systems, you can dene new types and functions of your own. These new types and functions should reect the semantics of the objects in your application domain. Some of the data objects you want to model may be large and complex (for example, text, voice, image, and nancial data). Therefore, you may also need mechanisms for the storage and manipulation of large objects. User-dened Distinct types (UDTs), user-dened functions (UDFs), and Large Objects (LOBs) are the mechanisms that are provided by DB2. With DB2, you can now dene new types and functions of your own to store and manipulate application objects within the database. As described in subsequent sections, there is an important synergy among these object-oriented features. You can model a complex object in the application domain as a UDT. The UDT may in turn be internally represented as a LOB. In turn, the UDTs behavior may be implemented in terms of UDFs. This section shows you how to use LOBs along with the steps that are required to dene UDTs and UDFs. You will also learn how UDTs, UDFs, and LOBs can better represent the objects in your application and thus work together. Note: The use of the DB2 object-oriented mechanisms (UDTs, UDFs, and LOBs) is not restricted to the support of object-oriented applications. Just as the C++ programming language implements all sorts of non-object-oriented applications, the object-oriented mechanisms provided by DB2 can also support all kinds of non-object-oriented applications. UDTs, UDFs, and LOBs are general-purpose mechanisms that can be used to model any database
Copyright IBM Corp. 1997, 1999

145

application. For this reason, these DB2 object extensions offer extensive support for both non-traditional, that is, object-oriented applications, in addition to improving support for traditional ones.

DB2 Approach to Supporting Objects


The object extensions of DB2 enable you to realize the benets of object technology while building on the strengths of relational technology. In a relational system, data types describe the data stored in columns of tables where the instances (or objects) of these data types are stored. Operations on these instances are supported by means of operators or functions that can be invoked anywhere that expressions are allowed. | | | | | | | The DB2 approach to support object extensions ts exactly into the relational paradigm. UDTs are data types that you dene. UDTs, like built-in types, can be used to describe the data that is stored in columns of tables. UDFs are functions that you dene. UDFs, like built-in functions or operators, support the manipulation of UDT instances. Thus, UDT instances are stored in columns of tables and manipulated by UDFs in SQL queries. UDTs can be internally represented in different ways. LOBs are just one example of this.

Using Large Objects (LOBs)


The VARCHAR and VARGRAPHIC data types have a limit of 32K bytes of storage. While this may be sufficient for small to medium size text data, applications often need to store large text documents. They may also need to store a wide variety of additional data types such as audio, video, drawings, mixed text and graphics, and images. DB2 provides three data types to store these data objects as strings of up to fteen (15) megabytes (MB) in size. The three data types are: Binary Large OBjects (BLOBs), single-byte Character Large OBjects (CLOBs), and Double-Byte Character Large OBjects (DBCLOBs). Along with storing large objects (LOBs), you will also need a method to refer to, use, and modify each LOB in the database. Each DB2 table may have a large amount of associated LOB data. Although a single row containing one or more LOB values cannot exceed 15 megabytes, a table may contain nearly 256 gigabytes of LOB data. The content of the LOB column of a particular row at any point in time has a large object value. You can refer to and manipulate LOBs using host variables just as you would any other data type. However, host variables use the client memory buffer which may not be large enough to hold LOB values. Other means are necessary to manipulate these large values. Locators are useful to identify and manipulate a large object value at the database server and for extracting pieces of the LOB value. File reference variables are useful for physically moving a large object value (or a large part of it) to and from the client. The subsections that follow discuss the topics that are introduced above in more detail.

146

DB2 UDB for AS/400 SQL Programming V4R4

Understanding Large Object Data Types (BLOB, CLOB, DBCLOB)


| Large object data types store data ranging in size from zero bytes to 15 megabytes. The three large object data types have the following denitions: v Character Large OBjects (CLOBs) A character string made up of single-byte characters with an associated code page. This data type is best for holding text-oriented information where the amount of information could grow beyond the limits of a regular VARCHAR data type (upper limit of 32K bytes). Code page conversion of the information is supported as well as compatibility with the other character types. v Double-Byte Character Large OBjects (DBCLOBs) A character string made up of double-byte characters with an associated code page. This data type is best for holding text-oriented information where double-byte character sets are used. Again, code page conversion of the information is supported as well as compatibility with the other double-byte character types. v Binary Large OBjects (BLOBs) A binary string made up of bytes with no associated code page. This data type may be the most useful because it can store binary data. Therefore, it is a perfect source type for use by User-dened Distinct Types (UDTs). UDTs using BLOBs as the source type are created to store image, voice, graphical, and other types of business or application-specic data. For more information on UDTs, see User-dened Distinct Types (UDT) on page 169.

| | | | |

Understanding Large Object Locators


Conceptually, LOB locators represent a simple idea that has been around for a while; use a small, easily managed value to refer to a much larger value. Specically, a LOB locator is a 4-byte value stored in a host variable that a program uses to refer to a LOB value (or LOB expression) held in the database system. Using a LOB locator, a program can manipulate the LOB value as if the LOB value was stored in a regular host variable. When you use the LOB locator, there is no need to transport the LOB value from the server to the application (and possibly back again). The LOB locator is associated with a LOB value or LOB expression, not a row or physical storage location in the database. Therefore, after selecting a LOB value into a locator, you cannot perform an operation on the original row(s) or tables(s) that would have any effect on the value referenced by the locator. The value associated with the locator is valid until the unit of work ends, or the locator is explicitly freed, whichever comes rst. The FREE LOCATOR statement releases a locator from its associated value. In a similar way, a commit or roll-back operation frees all LOB locators associated with the transaction. LOB locators can also be passed between DB2 and UDFs. Within the UDF, those functions that work on LOB data are available to manipulate the LOB values using LOB locators. When selecting a LOB value, you have three options. v Select the entire LOB value into a host variable. The entire LOB value is copied into the host variable. v Select the LOB value into a LOB locator. The LOB value remains on the server; it is not copied to the host variable.

| |

Chapter 8. Using the Object-Relational Capabilities

147

v Select the entire LOB value into a le reference variable. The LOB value is moved to an Integrated File System (IFS) le. The use of the LOB value within the program can help the programmer determine which method is best. If the LOB value is very large and is needed only as an input value for one or more subsequent SQL statements, keep the value in a locator. | | | | | If the program needs the entire LOB value regardless of the size, then there is no choice but to transfer the LOB. Even in this case, there are still three options available to you. You can select the entire value into a regular or le reference host variable. You may also select the LOB value into a locator and read it piecemeal from the locator into a regular host variable, as suggested in the following example.

Example: Using a Locator to Work With a CLOB Value


In this example, the application program retrieves a locator for a LOB value; then it uses the locator to extract the data from the LOB value. Using this method, the program allocates only enough storage for one piece of LOB data (the size is determined by the program). In addition, the program needs to issue only one fetch call using the cursor.

How the Sample LOBLOC Program Works


1. Declare host variables. The BEGIN DECLARE SECTION and END DECLARE SECTION statements delimit the host variable declarations. Host variables are prexed with a colon (:) when referenced in an SQL statement. CLOB LOCATOR host variables are declared. 2. Fetch the LOB value into the locator host variable. A CURSOR and FETCH routine is used to obtain the location of a LOB eld in the database to a locator host variable. 3. Free the LOB LOCATORS. The LOB LOCATORS used in this example are freed, releasing the locators from their previously associated values. The CHECKERR macro/function is an error checking utility which is external to the program. The location of this error checking utility depends on the programming language that is used: C check_error is redened as CHECKERR and is located in the util.c le.

| | |

148

DB2 UDB for AS/400 SQL Programming V4R4

C Sample: LOBLOC.SQC
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "util.h" EXEC SQL INCLUDE SQLCA; #define CHECKERR(CE_STR) if (check_error (CE_STR, &sqlca) != 0) return 1;

int main(int argc, char *argv[]) { #ifdef DB2MAC char * bufptr; #endif EXEC SQL BEGIN DECLARE SECTION; 1 char number[7]; long deptInfoBeginLoc; long deptInfoEndLoc; SQL TYPE IS CLOB_LOCATOR resume; SQL TYPE IS CLOB_LOCATOR deptBuffer; short lobind; char buffer[1000]=""; char userid[9]; char passwd[19]; EXEC SQL END DECLARE SECTION; printf( "Sample C program: LOBLOC\n" ); if (argc == 1) { EXEC SQL CONNECT TO sample; CHECKERR ("CONNECT TO SAMPLE"); } else if (argc == 3) { strcpy (userid, argv[1]); strcpy (passwd, argv[2]); EXEC SQL CONNECT TO sample USER :userid USING :passwd; CHECKERR ("CONNECT TO SAMPLE"); } else { printf ("\nUSAGE: lobloc [userid passwd]\n\n"); return 1; } /* endif */ /* Employee A10030 is not included in the following select, because the lobeval program manipulates the record for A10030 so that it is not compatible with lobloc */ EXEC SQL DECLARE c1 CURSOR FOR SELECT empno, resume FROM emp_resume WHERE resume_format='ascii' AND empno <> 'A00130'; EXEC SQL OPEN c1; CHECKERR ("OPEN CURSOR"); do { EXEC SQL FETCH c1 INTO :number, :resume :lobind; 2 if (SQLCODE != 0) break; if (lobind < 0) { printf ("NULL LOB indicated\n"); } else { /* EVALUATE the LOB LOCATOR */ /* Locate the beginning of "Department Information" section */ EXEC SQL VALUES (POSSTR(:resume, 'Department Information')) INTO :deptInfoBeginLoc; CHECKERR ("VALUES1"); /* Locate the beginning of "Education" section (end of "Dept.Info" */ EXEC SQL VALUES (POSSTR(:resume, 'Education')) INTO :deptInfoEndLoc; CHECKERR ("VALUES2"); /* Obtain ONLY the "Department Information" section by using SUBSTR */ EXEC SQL VALUES(SUBSTR(:resume, :deptInfoBeginLoc, :deptInfoEndLoc - :deptInfoBeginLoc)) INTO :deptBuffer; CHECKERR ("VALUES3"); /* Append the "Department Information" section to the :buffer var. */ EXEC SQL VALUES(:buffer || :deptBuffer) INTO :buffer; CHECKERR ("VALUES4"); } /* endif */ } while ( 1 ); #ifdef DB2MAC /* Need to convert the newline character for the Mac */ bufptr = &(buffer[0]); while ( *bufptr != '\0' ) { if ( *bufptr == 0x0A ) *bufptr = 0x0D; bufptr++; } #endif printf ("%s\n",buffer); EXEC SQL FREE LOCATOR :resume, :deptBuffer; 3

Chapter 8. Using the Object-Relational Capabilities

149

CHECKERR ("FREE LOCATOR"); EXEC SQL CLOSE c1; CHECKERR ("CLOSE CURSOR"); EXEC SQL CONNECT RESET; CHECKERR ("CONNECT RESET"); return 0;

} /* end of program : LOBLOC.SQC */

COBOL Sample: LOBLOC.SQB


Identification Division. Program-ID. "lobloc". Data Division. Working-Storage Section. copy "sqlenv.cbl". copy "sql.cbl". copy "sqlca.cbl". EXEC SQL BEGIN DECLARE SECTION END-EXEC. 1 01 userid pic x(8). 01 passwd. 49 passwd-length pic s9(4) comp-5 value 0. 49 passwd-name pic x(18). 01 empnum pic x(6). 01 di-begin-loc pic s9(9) comp-5. 01 di-end-loc pic s9(9) comp-5. 01 resume USAGE IS SQL TYPE IS CLOB-LOCATOR. 01 di-buffer USAGE IS SQL TYPE IS CLOB-LOCATOR. 01 lobind pic s9(4) comp-5. 01 buffer USAGE IS SQL TYPE IS CLOB(1K). EXEC SQL END DECLARE SECTION END-EXEC. 77 errloc pic x(80).

Procedure Division. Main Section. display "Sample COBOL program: LOBLOC". * Get database connection information. display "Enter your user id (default none): " with no advancing. accept userid. if userid = spaces EXEC SQL CONNECT TO sample END-EXEC else display "Enter your password : " with no advancing accept passwd-name. * Passwords in a CONNECT * format with the length inspect passwd-name before initial " statement must be entered in a VARCHAR of the input string. tallying passwd-length for characters ".

EXEC SQL CONNECT TO sample USER :userid USING :passwd END-EXEC. move "CONNECT TO" to errloc. call "checkerr" using SQLCA errloc. * Employee A10030 is not included in the following select, because * the lobeval program manipulates the record for A10030 so that it is * not compatible with lobloc EXEC SQL DECLARE c1 CURSOR FOR SELECT empno, resume FROM emp_resume WHERE resume_format = 'ascii' AND empno <> 'A00130' END-EXEC. EXEC SQL OPEN c1 END-EXEC. move "OPEN CURSOR" to errloc. call "checkerr" using SQLCA errloc. Move 0 to buffer-length. perform Fetch-Loop thru End-Fetch-Loop until SQLCODE not equal 0. * display contents of the buffer. display buffer-data(1:buffer-length). EXEC SQL FREE LOCATOR :resume, :di-buffer END-EXEC. move "FREE LOCATOR" to errloc. call "checkerr" using SQLCA errloc. EXEC SQL CLOSE c1 END-EXEC. move "CLOSE CURSOR" to errloc. call "checkerr" using SQLCA errloc. EXEC SQL CONNECT RESET END-EXEC. move "CONNECT RESET" to errloc. call "checkerr" using SQLCA errloc. End-Main. 3

150

DB2 UDB for AS/400 SQL Programming V4R4

go to End-Prog. Fetch-Loop Section. EXEC SQL FETCH c1 INTO :empnum, :resume :lobind 2 END-EXEC. if SQLCODE not equal 0 go to End-Fetch-Loop. * check to see if the host variable indicator returns NULL. if lobind less than 0 go to NULL-lob-indicated. * Value exists. Evaluate the LOB locator. * Locate the beginning of "Department Information" section. EXEC SQL VALUES (POSSTR(:resume, 'Department Information')) INTO :di-begin-loc END-EXEC. move "VALUES1" to errloc. call "checkerr" using SQLCA errloc. * Locate the beginning of "Education" section (end of Dept.Info) EXEC SQL VALUES (POSSTR(:resume, 'Education')) INTO :di-end-loc END-EXEC. move "VALUES2" to errloc. call "checkerr" using SQLCA errloc. subtract di-begin-loc from di-end-loc. * Obtain ONLY the "Department Information" section by using SUBSTR EXEC SQL VALUES (SUBSTR(:resume, :di-begin-loc, :di-end-loc)) INTO :di-buffer END-EXEC. move "VALUES3" to errloc. call "checkerr" using SQLCA errloc. * Append the "Department Information" section to the :buffer var EXEC SQL VALUES (:buffer || :di-buffer) INTO :buffer END-EXEC. move "VALUES4" to errloc. call "checkerr" using SQLCA errloc. go to End-Fetch-Loop. NULL-lob-indicated. display "NULL LOB indicated". End-Fetch-Loop. exit. End-Prog. stop run.

Indicator Variables and LOB Locators


For normal host variables in an application program, when selecting a NULL value into a host variable, a negative value is assigned to the indicator variable signifying that the value is NULL. In the case of LOB locators, however, the meaning of indicator variables is slightly different. Since a locator host variable itself can never be NULL, a negative indicator variable value indicates that the LOB value represented by the LOB locator is NULL. The NULL information is kept local to the client using the indicator variable value the server does not track NULL values with valid locators.

LOB File Reference Variables


File reference variables are similar to host variables except they are used to transfer data to and from IFS les (not to and from memory buffers). A le reference variable represents (rather than contains) the le, just as a LOB locator represents (rather than contains) the LOB value. Database queries, updates, and inserts may use le reference variables to store, or to retrieve, single LOB values. For very large objects, les are natural containers. It is likely that most LOBs begin as data stored in les on the client before they are moved to the database on the server. The use of le reference variables assists in moving LOB data. Programs use le reference variables to transfer LOB data from the IFS le directly to the database engine. To carry out the movement of LOB data, the application does not have to write utility routines to read and write les using host variables.

Chapter 8. Using the Object-Relational Capabilities

151

Note: The le referenced by the le reference variable must be accessible from (but not necessarily resident on) the system on which the program runs. For a stored procedure, this would be the server. A le reference variable has a data type of BLOB, CLOB, or DBCLOB. It is used either as the source of data (input) or as the target of data (output). The le reference variable may have a relative le name or a complete path name of the le (the latter is advised). The le name length is specied within the application program. The data length portion of the le reference variable is unused during input. During output, the data length is set by the application requestor code to the length of the new data that is written to the le. | | | | When using le reference variables there are different options on both input and output. You must choose an action for the le by setting the file_options eld in the le reference variable structure. Choices for assignment to the eld covering both input and output values are shown below. Values (shown for C) and options when using input le reference variables are as follows: v SQL_FILE_READ (Regular le) This option has a value of 2. This is a le that can be open, read, and closed. DB2 determines the length of the data in the le (in bytes) when opening the le. DB2 then returns the length through the data_length eld of the le reference variable structure. (The value for COBOL is SQL-FILE-READ.) Values and options when using output le reference variables are as follows: | | | | | | | | | | v SQL_FILE_CREATE (New le) This option has a value of 8. This option creates a new le. Should the le already exist, an error message is returned. (The value for COBOL is SQL-FILE-CREATE.) v SQL_FILE_OVERWRITE (Overwrite le) This option has a value of 16. This option creates a new le if none already exists. If the le already exists, the new data overwrites the data in the le. (The value for COBOL is SQL-FILE-OVERWRITE.) v SQL_FILE_APPEND (Append le) This option has a value of 32. This option has the output appended to the le, if it exists. Otherwise, it creates a new le. (The value for COBOL is SQL-FILE-APPEND.) Note: If a LOB le reference variable is used in an OPEN statement, do not delete the le associated with the LOB le reference variable until the cursor is closed. For more information about integrated le system, see Integrated File System Introduction.

| | | | |

Example: Extracting a Document To a File


This program example shows how CLOB elements can be retrieved from a table into an external le.

How the Sample LOBFILE Program Works


1. Declare host variables. The BEGIN DECLARE SECTION and END DECLARE SECTION statements delimit the host variable declarations. Host variables are prexed with a colon (:) when referenced in an SQL statement. A CLOB FILE REFERENCE host variable is declared.

152

DB2 UDB for AS/400 SQL Programming V4R4

| | | | | |

2. CLOB FILE REFERENCE host variable is set up. The attributes of the FILE REFERENCE are set up. A le name without a fully declared path is, by default, placed in the users current directory. If the pathname does not begin with the forward slash (/) character, it is not qualied. 3. Select into the CLOB FILE REFERENCE host variable. The data from the resume eld is selected into the lename that is referenced by the host variable. The CHECKERR macro/function is an error checking utility which is external to the program. The location of this error checking utility depends upon the programming language used: C COBOL check_error is redened as CHECKERR and is located in the util.c le. CHECKERR is an external program named checkerr.cbl

C Sample: LOBFILE.SQC
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sql.h> #include "util.h" EXEC SQL INCLUDE SQLCA; #define CHECKERR(CE_STR) if (check_error (CE_STR, &sqlca) != 0) return 1;

int main(int argc, char *argv[]) { EXEC SQL BEGIN DECLARE SECTION; 1 SQL TYPE IS CLOB_FILE resume; short lobind; char userid[9]; char passwd[19]; EXEC SQL END DECLARE SECTION; printf( "Sample C program: LOBFILE\n" ); if (argc == 1) { EXEC SQL CONNECT TO sample; CHECKERR ("CONNECT TO SAMPLE"); } else if (argc == 3) { strcpy (userid, argv[1]); strcpy (passwd, argv[2]); EXEC SQL CONNECT TO sample USER :userid USING :passwd; CHECKERR ("CONNECT TO SAMPLE"); } else { printf ("\nUSAGE: lobfile [userid passwd]\n\n"); return 1; } /* endif */ strcpy (resume.name, "RESUME.TXT"); 2 resume.name_length = strlen("RESUME.TXT"); resume.file_options = SQL_FILE_OVERWRITE; EXEC SQL SELECT resume INTO :resume :lobind FROM emp_resume WHERE resume_format='ascii' AND empno='000130'; 3

if (lobind < 0) { printf ("NULL LOB indicated \n"); } else { printf ("Resume for EMPNO 000130 is in file : RESUME.TXT\n"); } /* endif */ EXEC SQL CONNECT RESET; CHECKERR ("CONNECT RESET"); return 0;

} /* end of program : LOBFILE.SQC */

COBOL Sample: LOBFILE.SQB


Identification Division. Program-ID. "lobfile". Data Division. Working-Storage Section. copy "sqlenv.cbl". copy "sql.cbl". copy "sqlca.cbl". EXEC SQL BEGIN DECLARE SECTION END-EXEC. 1

Chapter 8. Using the Object-Relational Capabilities

153

01 userid pic x(8). 01 passwd. 49 passwd-length pic s9(4) comp-5 value 0. 49 passwd-name pic x(18). 01 resume USAGE IS SQL TYPE IS CLOB-FILE. 01 lobind pic s9(4) comp-5. EXEC SQL END DECLARE SECTION END-EXEC. 77 errloc pic x(80).

Procedure Division. Main Section. display "Sample COBOL program: LOBFILE". * Get database connection information. display "Enter your user id (default none): " with no advancing. accept userid. if userid = spaces EXEC SQL CONNECT TO sample END-EXEC else display "Enter your password : " with no advancing accept passwd-name. * Passwords in a CONNECT * format with the length inspect passwd-name before initial " statement must be entered in a VARCHAR of the input string. tallying passwd-length for characters ".

EXEC SQL CONNECT TO sample USER :userid USING :passwd END-EXEC. move "CONNECT TO" to errloc. call "checkerr" using SQLCA errloc. move "RESUME.TXT" to resume-NAME. move 10 to resume-NAME-LENGTH. move SQL-FILE-OVERWRITE to resume-FILE-OPTIONS. EXEC SQL SELECT resume INTO :resume :lobind 3 FROM emp_resume WHERE resume_format = 'ascii' AND empno = '000130' END-EXEC. if lobind less than 0 go to NULL-LOB-indicated. display "Resume for EMPNO 000130 is in file : RESUME.TXT". go to End-Main. NULL-LOB-indicated. display "NULL LOB indicated". End-Main. EXEC SQL CONNECT RESET END-EXEC. move "CONNECT RESET" to errloc. call "checkerr" using SQLCA errloc. End-Prog. stop run. 2

Example: Inserting Data Into a CLOB Column


In v v v the path description of the following C program segment: userid represents the directory for one of your users. dirname represents a subdirectory name of userid. filnam.1 can become the name of one of your documents that you wish to insert into the table. v clobtab is the name of the table with the CLOB data type. The following example shows how to insert data from a regular le referenced by :hv_text_file into a CLOB column:
strcpy(hv_text_file.name, "/home/userid/dirname/filnam.1"); hv_text_file.name_length = strlen("/home/userid/dirname/filnam.1"); hv_text_file.file_options = SQL_FILE_READ; /* this is a 'regular' file */ EXEC SQL INSERT INTO CLOBTAB VALUES(:hv_text_file);

| | | | | | | |

154

DB2 UDB for AS/400 SQL Programming V4R4

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

Display Layout of LOB Columns


When a row of data from a table holding LOB columns is displayed using CL commands such as Display Physical File Member (DSPPFM), the LOB data stored in that row will not be displayed. Instead, the Database will show a special value for the LOB columns. The layout of this special value is as follows: v 13 to 28 bytes of hex zeros. v 16 bytes beginning with *POINTER and followed by blanks. The number of bytes in the rst portion of the value is set to the number needed to 16 byte boundary align the second part of the value. For example, say you have a table that holds three columns: ColumnOne Char(10), ColumnTwo CLOB(40K), and ColumnThree BLOB(10M). If you were to issue a DSPPFM of this table, each row of data would look as follows. v For ColumnOne: 10 bytes lled with character data. v For ColumnTwo: 22 bytes lled with hex zeros and 16 bytes lled with *POINTER . v For ColumnThree: 16 bytes lled with hex zeros and 16 bytes lled with *POINTER . The full set of commands that display LOB columns in this way is: v Display Physical File Member (DSPPFM) v Copy File (CPYF) when the value *PRINT is specied for the TOFILE keyword v Display Journal (DSPJRN) v Retrieve Journal Entry (RTVJRNE) v Receive Journal Entry (RCVJRNE) when the values *TYPE1, *TYPE2, *TYPE3 and *TYPE4 are specied for the ENTFMT keyword.

Journal Entry Layout of LOB Columns


Two commands return a buffer that gives the user addressability to LOB data that had been journaled: v Receive Journal Entry (RCVJRNE) CL command, when the value *TYPEPTR is specied for the ENTFMT keyword v Retrieve Journal Entries (QjoRetrieveJournalEntries) API The layout of the LOB columns in these entries is as follows: v 0 to 15 bytes of hex zeros v 1 byte of system information set to 00x v 4 bytes holding the length of the LOB data addressed by the pointer, below v 8 bytes of hex zeros v 16 bytes holding a pointer to the LOB data stored in the Journal Entry. The rst part of this layout is intended to 16 byte boundary align the pointer to the LOB data. The number of bytes in this area depends on the length of the columns that proceed the LOB column. Refer to the section above on the Display Layout of LOB Columns for an example of how the length of this rst part is calculated. For more information on the Journal handling of LOB columns, refer to the Working with Journal Entries, Journals and Journal Receivers chapter of the Backup and Recovery book.

Chapter 8. Using the Object-Relational Capabilities

155

User-Dened Functions (UDF)


A user-dened function is a mechanism with which you can write your own extensions to SQL. The built-in functions supplied with DB2 are a useful set of functions, but they may not satisfy all of your requirements. Thus, you may need to extend SQL for the following reasons: v Customization. The function specic to your application does not exist in DB2. Whether the function is a simple transformation, a trivial calculation, or a complicated multivariate analysis, you can probably use a UDF to do the job. v Flexibility. The DB2 built-in function does not quite permit the variations that you wish to include in your application. v Standardization. Many of the programs at your site implement the same basic set of functions, but there are minor differences in all the implementations. Thus, you are unsure about the consistency of the results you receive. If you correctly implement these functions once, in a UDF, then all these programs can use the same implementation directly in SQL and provide consistent results. v Object-relational support. As discussed in User-dened Distinct Types (UDT) on page 169, UDTs can be very useful in extending the capability and increasing the safety of DB2. UDFs act as the methods for UDTs, by providing behavior and encapsulating the types. | | | | | In addition, SQL UDFs provide the support to manipulate Large Objects and DataLink types. While the database provides several built-in functions which are useful in working with these datatypes, SQL UDFs provide a way for users to further manipulate and enhance the capabilities of the database (to the specialization required) in this area.

Why Use UDFs?


In writing DB2 applications, you have a choice when implementing desired actions or operations: v As a UDF v As a subroutine or function in your application. Although it appears easier to implement new operations as subroutines or functions in your application, you should still consider: v Re-use. | | | | | | | | | | | If the new operation is something of which other users or programs at your site can take advantage, then UDFs can help to reuse it. In addition, the function can be invoked directly in SQL wherever an expression can be used by any user of the database. The database will take care of many data type promotions of the function arguments automatically. For example, with DECIMAL to DOUBLE, the database will allow your function to be applied to different, but compatible data types. It may seem easier to implement your new function as a normal function. (You would not have to dene the function to DB2.) If you did this, you would have to inform all other interested application developers, and package the function effectively for their use. However, this process ignores the interactive users like

156

DB2 UDB for AS/400 SQL Programming V4R4

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

those who normally use the Command Line Processor (CLP) to access the database. However, functions written for use only within programs ignores those (interactive) users who do not have associated programs. This includes commands such as STRSQL, STRQM, and RUNSQLSTM, in addition to many clients such as ODBC, JDBC, etc. CLP users cannot use your function unless it is a UDF in the database. This also applies to any other tools that use SQL (such as Visualizer), that do not get recompiled. v Performance. In certain cases, invoking the UDF directly from the database engine instead of from your application can have a considerable performance advantage. You willl notice this advantage when the function may be used in the qualication of data for further processing. These cases occur when the function is used in record selection processing. Consider a simple scenario where you want to process some data. You can meet some selection criteria which can be expressed as a function SELECTION_CRITERIA(). Your application could issue the following select statement:
SELECT A, B, C FROM T

When it receives each row, it runs SELECTION_CRITERIA against the data to decide if it is interested in processing the data further. Here, every row of table T must be passed back to the application. But, if SELECTION_CRITERIA() is implemented as a UDF, your application can issue the following statement:
SELECT C FROM T WHERE SELECTION_CRITERIA(A,B)=1

In this case, only the rows and column of interest are passed across the interface between the application and the database. Another case where a UDF can offer a performance benet is when dealing with Large Objects (LOB). Suppose you have a function that extracts some information from a value of one of the LOB types. You can perform this extraction right on the database server and pass only the extracted value back to the application. This is more efficient than passing the entire LOB value back to the application and then performing the extraction. The performance value of packaging this function as a UDF could be enormous, depending on the particular situation. (Note that you can also extract a portion of a LOB by using a LOB locator. See Indicator Variables and LOB Locators on page 151 for an example of a similar scenario.) v Object Orientation. You can implement the behavior of a user-dened distinct type (UDT), also called distinct type, using a UDF. For more information on UDTs, see User-dened Distinct Types (UDT) on page 169. For additional details on UDTs and the important concept of castability discussed herein, see the CREATE DISTINCT TYPE statement in the DB2 UDB for AS/400 SQL Reference. When you create a distinct type, you are automatically provided cast functions between the distinct type and its source type. You may also be provided comparison operators such as =, >, <, and so on, depending on the source type. You have to provide any additional behavior yourself. It is best to keep the behavior of a distinct type in the database where all of the users of the distinct type can easily access it. You can use UDFs, therefore, as the implementation mechanism. For example, suppose that you have a BOAT distinct type, dened over a one megabyte BLOB. The type create statement:
CREATE DISTINCT TYPE BOAT AS BLOB(1MEG)

Chapter 8. Using the Object-Relational Capabilities

157

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

The BLOB contains the various nautical specications, and some drawings. You may wish to compare sizes of boats. However, with a distinct type dened over a BLOB source type, you do not get the comparison operations automatically generated for you. You can implement a BOAT_COMPARE function which decides if one boat is bigger than another based on a measure that you choose. These could be: displacement, length over all, metric tonnage, or another calculation based on the BOAT object. You create the BOAT_COMPARE function as follows:
CREATE SQL FUNCTION BOAT_COMPARE (BOAT, BOAT) RETURNS INTEGER ...

If your function returns: 1 the rst BOAT is bigger 2 the second is bigger and 0 they are equal. You could use this function in your SQL code to compare boats. Suppose you create the following tables:
CREATE TABLE BOATS_INVENTORY ( BOAT_ID CHAR(5), BOAT_TYPE VARCHAR(25), DESIGNER VARCHAR(40), OWNER VARCHAR(40), DESIGN_DATE DATE, SPEC BOAT, ... ) CREATE TABLE MY_BOATS ( BOAT_ID CHAR(5), BOAT_TYPE VARCHAR(25), DESIGNER VARCHAR(40), DESIGN_DATE DATE, ACQUIRE_DATE DATE, ACQUIRE_PRICE CANADIAN_DOLLAR, CURR_APPRAISL CANADIAN_DOLLAR, SPEC BOAT, ... )

You can execute the following SQL SELECT statement:


SELECT INV.BOAT_ID, INV.BOAT_TYPE, INV.DESIGNER, INV.OWNER, INV.DESIGN_DATE FROM BOATS_INVENTORY INV, MY_BOATS MY WHERE MY.BOAT_ID = '19GCC' AND BOAT_COMPARE(INV.SPEC, MY.SPEC) = 1 AND INV.DESIGNER = MY.DESIGNER

This simple example returns all the boats from BOATS_INVENTORY from the same designer that are bigger than a particular boat in MY_BOATS. Note that the example only passes the rows of interest back to the application because the comparison occurs in the database server. In fact, it completely avoids passing any values of data type BOAT. This is a signicant improvement in storage and performance as BOAT is based on a one megabyte BLOB data type.

UDF Concepts
The following is a discussion of the important concepts you need to know prior to coding UDFs:

Function Name
| v Full name of a function.

158

DB2 UDB for AS/400 SQL Programming V4R4

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

The full name of a function using *SQL naming is <schema-name>.<functionname>. The full name of a function in *SYS naming is <schema-name>/<function-name>. Function names cannot be qualied using *SYS naming in DML statements. You can use this full name anywhere you refer to a function. For example:
QGPL.SNOWBLOWER_SIZE SMITH.FOO QSYS2.SUBSTR QSYS2.FLOOR

However, you may also omit the <schema-name>., in which case, DB2 must determine the function to which you are referring. For example:
SNOWBLOWER_SIZE FOO SUBSTR FLOOR

v Path The concept of path is central to DB2s resolution of unqualied references that occur when schema-name is not specied. For the use of path in DDL statements that refer to functions, see the description of the corresponding CREATE FUNCTION statement in the DB2 UDB for AS/400 SQL Reference. The path is an ordered list of schema names. It provides a set of schemas for resolving unqualied references to UDFs as well as UDTs. In cases where a function reference matches functions in more than one schema in the path, the order of the schemas in the path is used to resolve this match. The path is established by means of the SQLPATH option on the precompile and bind commands for static SQL. The path is set by the SET PATH statement for dynamic SQL. When the rst SQL statement that runs in an activation group runs with SQL naming, the path has the following default value:
"QSYS","QSYS2","<ID>"

This applies to both static and dynamic SQL, where <ID> represents the current statement authorization ID. When the rst SQL statement in an activation group runs with system naming, the default path is *LIBL. v Overloaded function names. Function names can be overloaded, which means that multiple functions, even in the same schema, can have the same name. Two functions cannot, however, have the same signature, which can be dened to be the qualied function name concatenated with the dened data types of all the function parameters in the order in which they are dened. For an example of an overloaded function, see Example: BLOB String Search on page 162. See the DB2 UDB for AS/400 SQL Reference book for more information on signature and function resolution. v Function resolution. It is the function resolution algorithm that takes into account the facts of overloading and function path to choose the best t for every function reference, whether it is a qualied or an unqualied reference. All functions, even built-in functions, are processed through the function selection algorithm. v Types of function. There are several types of functions: Built-in. These are functions provided by and shipped with the database. SUBSTR() is an example. System-generated. These are functions implicitly generated by the database engine when a DISTINCT TYPE is created. These functions provide casting operations between the DISTINCT TYPE and its base type. User-dened. These are functions created by users and registered to the database.
Chapter 8. Using the Object-Relational Capabilities

159

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

In addition, each function can be further classied as a scalar or column function. A scalar function returns a single value answer each time it is called. For example, the built-in function SUBSTR() is a scalar function, as are many built-in functions. System-generated functions are always scalar functions. Scalar UDFs can either be external (coded in a programming language such as C, or in SQLan SQL function), or sourced (using the implementation of an existing function). A column function receives a set of like values (a column of data) and returns a single value answer from this set of values. These are also called aggregating functions in DB2. Some built-in functions are column functions. An example of a column function is the built-in function AVG(). An external UDF cannot be dened as a column function. However, a sourced UDF is dened to be a column function if it is sourced on one of the built-in column functions. The latter is useful for distinct types. For example, if a distinct type SHOESIZE exists that is dened with base type INTEGER, you could dene a UDF, AVG(SHOESIZE), as a column function sourced on the existing built-in column function, AVG(INTEGER). The concept of path, the SET PATH statement, and the function resolution algorithm are discussed in detail in the DB2 UDB for AS/400 SQL Reference. The SQLPATH precompile option is discussed in the command appendix.

Implementing UDFs
There are three types of UDFs: sourced, external, and SQL. The implementation of each type is considerably different. v Sourced UDFs. These are simply functions registered to the database that themselves reference another function. They, in effect, map the sourced function. As such, nothing more is required in implementing these functions than registering them to the database using the CREATE FUNCTION statement. v External functions. These are references to programs and service programs written in a high level language such as C, COBOL, or RPG. Once the function is registered to the database, the database will invoke the program or service program whenever the function is referenced in a DML statement. As such, external UDFs require that the UDF writer, besides knowing the high level language and how to develop code in it, must understand the interface between the program and the database. See Chapter 9. Writing User-Dened Functions (UDFs) on page 185 for more information on writing external functions. v SQL UDFs. SQL UDFs are functions written entirely in the SQL language. Their code is actually SQL statements embedded within the CREATE FUNCTION statement itself. SQL UDFs provide several advantages: They are written in SQL, making them quite portable. Dening the interface between the database and the function is by use of SQL declares, with no need to worry about details of actual parameter passing. They allow the passing of large objects, datalinks, and UDTs as parameters, and subsequent manipulation of them in the function itself. More information about SQL functions can be found in Chapter 9. Writing User-Dened Functions (UDFs) on page 185. 1. Registering the UDF with DB2. Regardless of which type of UDF is being created, they all need to be registered to the database using the CREATE FUNCTION statement. In the case of source functions, this registration step does everything necessary to dene the function to the database. For SQL UDFs, the CREATE FUNCTION statement contains everything necessary to

160

DB2 UDB for AS/400 SQL Programming V4R4

dene the function as well, except that the syntax of the CREATE statement is much more complex (contains actual SQL executable code). For external UDFs, the CREATE FUNCTION statement only registers the function to the database; the supporting code that actually implements the function must be written separately. See Registering UDFs for more information. 2. Debugging the UDF. See Chapter 9. Writing User-Dened Functions (UDFs) on page 185. | | | | | | | | | | | | | | | | | After these steps are successfully completed, your UDF is ready for use in data manipulation language (DML) or data denition language (DDL) statements such as CREATE VIEW.

Registering UDFs
A UDF must be registered in the database before the function can be recognized and used by the database. You can register a UDF using the CREATE FUNCTION statement. You can nd detailed explanations for this statement and its options in the DB2 UDB for AS/400 SQL Reference. The statement allows you to specify the language and name of the program, along with options such as DETERMINISTIC, ALLOW PARALLEL, and RETURN NULLS ON NULL INPUT. These options help to more specically identify to the database the intention of the function and how calls to the database can be optimized. You should register the UDF to DB2 after you have written and completely tested the actual code. It is possible to dene the UDF prior to actually writing it. However, to avoid any problems with running your UDF, you are encouraged to write and test it extensively before registering it. For information on testing your UDF, see Chapter 9. Writing User-Dened Functions (UDFs) on page 185.

Examples of Registering UDFs


| | | | | | | | | | | | | | | | | The examples which follow illustrate a variety of typical situations where UDFs can be registered. The examples include: v Example: Exponentiation v Example: String Search v v v v Example: String Search over UDT Example: External Function with UDT Parameter Example: AVG over a UDT Example: Counting

Example: Exponentiation
Suppose you have written an external UDF to perform exponentiation of oating point values, and wish to register it in the MATH schema.
CREATE FUNCTION MATH.EXPON (DOUBLE, DOUBLE) RETURNS DOUBLE EXTERNAL NAME 'MYLIB/MYPGM(MYENTRY)' LANGUAGE C PARAMETER STYLE DB2SQL NO SQL

Chapter 8. Using the Object-Relational Capabilities

161

| | | | | | | | |

DETERMINISTIC NO EXTERNAL ACTION RETURNS NULL ON NULL INPUT ALLOW PARALLEL

In this example, the system uses the RETURNS NULL ON NULL INPUT default value. This is desirable since you want the result to be NULL if either argument is NULL. Since you do not require a scratchpad and no nal call is necessary, the NO SCRATCHPAD and NO FINAL CALL default values are used. As there is no reason why EXPON cannot be parallel, the ALLOW PARALLEL value is specied.

Example: String Search


Your associate, Willie, has written a UDF to look for the existence of a given short string, passed as an argument, within a given CLOB value, which is also passed as an argument. The UDF returns the position of the string within the CLOB if it nds the string, or zero if it does not. Additionally, Willie has written the function to return a FLOAT result. Suppose you know that when it is used in SQL, it should always return an INTEGER. You can create the following function:
CREATE FUNCTION FINDSTRING (CLOB(500K), VARCHAR(200)) RETURNS INTEGER CAST FROM FLOAT SPECIFIC "willie_find_feb95" EXTERNAL NAME 'MYLIB/MYPGM(FINDSTR)' LANGUAGE C PARAMETER STYLE DB2SQL NO SQL DETERMINISTIC NO EXTERNAL ACTION RETURNS NULL ON NULL INPUT

| | | | | | | | | |

Note that a CAST FROM clause is used to specify that the UDF body really returns a FLOAT value but you want to cast this to INTEGER before returning the value to the statement which used the UDF. As discussed in the DB2 UDB for AS/400 SQL Reference, the INTEGER built-in function can perform this cast for you. Also, you wish to provide your own specic name for the function and later reference it in DDL (see Example: String Search over UDT on page 163). Because the UDF was not written to handle NULL values, you use the RETURNS NULL ON NULL INPUT. And because there is no scratchpad, you use the NO SCRATCHPAD and NO FINAL CALL default values. As there is no reason why FINDSTRING cannot be parallel, the ALLOW PARALLELISM default value is used.

Example: BLOB String Search


| | | | | | | | | | | | Because you want this function to work on BLOBs as well as on CLOBs, you dene another FINDSTRING taking BLOB as the rst parameter:
CREATE FUNCTION FINDSTRING (BLOB(500K), VARCHAR(200)) RETURNS INTEGER CAST FROM FLOAT SPECIFIC "willie_fblob_feb95" EXTERNAL NAME 'MYLIB/MYPGM(FINDSTR)' LANGUAGE C PARAMETER STYLE DB2SQL NO SQL DETERMINISTIC NO EXTERNAL ACTION

162

DB2 UDB for AS/400 SQL Programming V4R4

This example illustrates overloading of the UDF name, and shows that multiple UDFs can share the same body. Note that although a BLOB cannot be assigned to a CLOB, the same source code can be used. There is no programming problem in the above example as the programming interface for BLOB and CLOB between DB2 and UDF is the same; length followed by data. DB2 does not check if the UDF using a particular function body is in any way consistent with any other UDF using the same body.

Example: String Search over UDT


This example is a continuation of the previous example. Say you are satised with the FINDSTRING functions from Example: BLOB String Search on page 162, but now you have dened a distinct type BOAT with source type BLOB. You also want FINDSTRING to operate on values having data type BOAT, so you create another FINDSTRING function. This function is sourced on the FINDSTRING which operates on BLOB values in Example: BLOB String Search on page 162. Note the further overloading of FINDSTRING in this example:
CREATE FUNCTION FINDSTRING (BOAT, VARCHAR(200)) RETURNS INT SPECIFIC "slick_fboat_mar95" SOURCE SPECIFIC "willie_fblob_feb95"

Note that this FINDSTRING function has a different signature from the FINDSTRING functions in Example: BLOB String Search on page 162, so there is no problem overloading the name. You wish to provide your own specic name for possible later reference in DDL. Because you are using the SOURCE clause, you cannot use the EXTERNAL NAME clause or any of the related keywords specifying function attributes. These attributes are taken from the source function. Finally, observe that in identifying the source function you are using the specic function name explicitly provided in Example: BLOB String Search on page 162. Because this is an unqualied reference, the schema in which this source function resides must be in the function path, or the reference will not be resolved.

Example: External Function with UDT Parameter


You have written another UDF to take a BOAT and examine its design attributes and generate a cost for the boat in Canadian dollars. Even though internally, the labor cost may be priced in German marks, or Japanese yen, or US dollars, this function needs to generate the cost to build the boat in the required currency, Canadian dollars. This means it has to get current exchange rate information from the exchange_rate le, managed outside of DB2, and the answer depends on what it nds in this le. This makes the function NOT DETERMINISTIC.
CREATE FUNCTION BOAT_COST (BOAT) RETURNS INTEGER EXTERNAL NAME 'MYLIB/COSTS(BOATCOST)' LANGUAGE C PARAMETER STYLE DB2SQL NO SQL NOT DETERMINISTIC NO EXTERNAL ACTION

| |

Observe that CAST FROM and SPECIFIC are not specied, but that NOT DETERMINISTIC is specied.

Chapter 8. Using the Object-Relational Capabilities

163

Example: AVG over a UDT


| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This example implements the AVG column function over the CANADIAN_DOLLAR distinct type. See Example: Money on page 171 for the denition of CANADIAN_DOLLAR. Strong typing prevents you from using the built-in AVG function on a distinct type. It turns out that the source type for CANADIAN_DOLLAR was DECIMAL, and so you implement the AVG by sourcing it on the AVG(DECIMAL) built-in function. The ability to do this depends on being able to cast from DECIMAL to CANADIAN_DOLLAR and vice versa, but since DECIMAL is the source type for CANADIAN_DOLLAR you know these casts will work.
CREATE FUNCTION AVG (CANADIAN_DOLLAR) RETURNS CANADIAN_DOLLAR SOURCE "QSYS2".AVG(DECIMAL(9,2))

Note that in the SOURCE clause you have qualied the function name, just in case there might be some other AVG function lurking in your SQL path.

Example: Counting
Your simple counting function returns a 1 the rst time and increments the result by one each time it is called. This function takes no SQL arguments, and by denition it is a NOT DETERMINISTIC function since its answer varies from call to call. It uses the scratchpad to save the last value returned, and each time it is invoked it increments this value and returns it.
CREATE FUNCTION COUNTER () RETURNS INT EXTERNAL NAME 'MYLIB/MYFUNCS(CTR)' LANGUAGE C PARAMETER STYLE DB2SQL NO SQL NOT DETERMINISTIC NOT FENCED SCRATCHPAD 4 DISALLOW PARALLEL

Note that no parameter denitions are provided, just empty parentheses. The above function species SCRATCHPAD, and uses the default specication of NO FINAL CALL. In this case, the size of the scratchpad is set to only 4 bytes, which is sufficient for a counter. Since the COUNTER function requires that a single scratchpad be used to operate properly, DISALLOW PARALLEL is added to prevent DB2 from operating it in parallel.

Using UDFs
Scalar and column UDFs can be invoked within an SQL statement almost everywhere that an expression is valid. There are a few restrictions of UDF usage, however: v UDFs and system generated functions cannot be specied in check constraints. Check constraints also cannot contain references to the built-in functions DLVALUE, DLURLPATH, DLURLPATHONLY, DLURLSCHEME, DLURLCOMPLETE, or DLURLSERVER. v External UDFs, SQL UDFS and the built-in functions DLVALUE, DLURLPATH, DLURLPATHONLY, DLURLSCHEME, DLURLCOMPLETE, and DLURLSERVER cannot be referenced in an ORDER BY or GROUP BY clause, unless the SQL statement is read-only and allows temporary processing (ALWCPYDTA(*YES) or (*OPTIMIZE).

164

DB2 UDB for AS/400 SQL Programming V4R4

The DB2 UDB for AS/400 SQL Reference discusses all these contexts in detail. The discussion and examples used in this section focus on relatively simple SELECT statement contexts, but note that their use is not restricted to these contexts. Refer to UDF Concepts on page 158 for a summary of the use and importance of the path and the function resolution algorithm. You can nd the details for both of these concepts in the DB2 UDB for AS/400 SQL Reference. The resolution of any Data Manipulation Language (DML) reference to a function uses the function resolution algorithm, so it is important to understand how it works.

Referring to Functions
Each reference to a function, whether it is a UDF, or a built-in function, contains the following syntax:
function_name ( ALL DISTINCT , expression )

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

In the above, function_name can be either an unqualied or a qualied function name. Note that when using the *SYS naming convention, functions cannot be qualied. The arguments can number from 0 to 90, and are expressions which may contain: v A column name, qualied or unqualied v A constant v A host variable v A special register v A parameter marker with a CAST function v An expression v A function The position of the arguments is important and must conform to the function denition for the semantics to be correct. Both the position of the arguments and the function denition must conform to the function body itself. DB2 does not attempt to shuffle arguments to better match a function denition, and DB2 does not attempt to determine the semantics of the individual function parameters.

Examples of Function Invocations


| | | | | | | | | | | | Some valid examples of function invocations are:
AVG(FLOAT_COLUMN) BLOOP(COLUMN1) BLOOP(FLOAT_COLUMN + CAST(? AS INTEGER)) BLOOP(:hostvar :indicvar) BRIAN.PARSE(CONCAT(CHAR_COLUMN,USER, 1, 0, 0, 1) CTR() FLOOR(FLOAT_COLUMN) PABLO.BLOOP(A+B) PABLO.BLOOP(:hostvar) "search_schema"(CURRENT PATH, 'GENE') SUBSTR(COLUMN2,8,3)

Chapter 8. Using the Object-Relational Capabilities

165

| | | |

QSYS2.FLOOR(AVG(EMP.SALARY)) QSYS2.AVG(QSYS2.FLOOR(EMP.SALARY)) QSYS2.SUBSTR(COLUMN2,11,LENGTH(COLUMN3))

Using Parameter Markers in Functions


An important restriction involves parameter markers; you cannot simply code the following:
BLOOP(?)

As the function selection logic does not know what data type the argument may turn out to be, it cannot resolve the reference. You can use the CAST specication to provide a type for the parameter marker, for example INTEGER, and then the function selection logic can proceed:
BLOOP(CAST(? AS INTEGER))

Using Qualied Function Reference


If you use a qualied function reference, you restrict DB2s search for a matching function to that schema. For example, you have the following statement:
SELECT PABLO.BLOOP(COLUMN1) FROM T

Only the BLOOP functions in schema PABLO are considered. It does not matter that user SERGE has dened a BLOOP function, or whether or not there is a built-in BLOOP function. Now suppose that user PABLO has dened two BLOOP functions in his schema:
CREATE FUNCTION BLOOP (INTEGER) RETURNS ... CREATE FUNCTION BLOOP (DOUBLE) RETURNS ...

BLOOP is thus overloaded within the PABLO schema, and the function selection algorithm would choose the best BLOOP, depending on the data type of the argument, column1. In this case, both of the PABLO.BLOOPs take numeric arguments, and if column1 is not one of the numeric types, the statement will fail. On the other hand if column1 is either SMALLINT or INTEGER, function selection will resolve to the rst BLOOP, while if column1 is DECIMAL or DOUBLE, the second BLOOP will be chosen. Several points about this example: 1. It illustrates argument promotion. The rst BLOOP is dened with an INTEGER parameter, yet you can pass it a SMALLINT argument. The function selection algorithm supports promotions among the built-in data types (for details, see the DB2 UDB for AS/400 SQL Reference) and DB2 performs the appropriate data value conversions. 2. If for some reason you want to invoke the second BLOOP with a SMALLINT or INTEGER argument, you have to take an explicit action in your statement as follows:
SELECT PABLO.BLOOP(DOUBLE(COLUMN1)) FROM T

3. Alternatively, if you want to invoke the rst BLOOP with a DECIMAL or DOUBLE argument, you have your choice of explicit actions, depending on your exact intent: | | | |
SELECT PABLO.BLOOP(INTEGER(COLUMN1)) FROM T SELECT PABLO.BLOOP(FLOOR(COLUMN1)) FROM T

You should investigate these other functions in the DB2 UDB for AS/400 SQL Reference. The INTEGER function is a built-in function in the QSYS2 schema.

166

DB2 UDB for AS/400 SQL Programming V4R4

Using Unqualied Function Reference


| | | | | | | | | | | | | | | | If, instead of a qualied function reference, you use an unqualied function reference, DB2s search for a matching function normally uses the function path to qualify the reference. In the case of the DROP FUNCTION or COMMENT ON FUNCTION functions, the reference is qualied using the current authorization ID, if they are unqualied for *SQL naming, or *LIBL for *SYS naming. Thus, it is important that you know what your function path is, and what, if any, conicting functions exist in the schemas of your current function path. For example, suppose you are PABLO and your static SQL statement is as follows, where COLUMN1 is data type INTEGER:
SELECT BLOOP(COLUMN1) FROM T

You have created the two BLOOP functions cited in Using Qualied Function Reference on page 166, and you want and expect one of them to be chosen. If the following default function path is used, the rst BLOOP is chosen (since column1 is INTEGER), if there is no conicting BLOOP in QSYS or QSYS2:
"QSYS","QSYS2","PABLO"

However, suppose you have forgotten that you are using a script for precompiling and binding which you previously wrote for another purpose. In this script, you explicitly coded your SQLPATH parameter to specify the following function path for another reason that does not apply to your current work:
"KATHY","QSYS","QSYS2","PABLO"

If Kathy has written a BLOOP function for her own purposes, the function selection could very well resolve to Kathys function, and your statement would execute without error. You are not notied because DB2 assumes that you know what you are doing. It becomes your responsibility to identify the incorrect output from your statement and make the required correction.

Summary of Function References


For both qualied and unqualied function references, the function selection algorithm looks at all the applicable functions, both built-in and user-dened, that have: v The given name v The same number of dened parameters as arguments in the function reference v Each parameter identical to or promotable from the type of the corresponding argument. (Applicable functions means functions in the named schema for a qualied reference, or functions in the schemas of the function path for an unqualied reference.) The algorithm looks for an exact match, or failing that, a best match among these functions. The current function path is used, in the case of an unqualied reference only, as the deciding factor if two identically good matches are found in different schemas. The details of the algorithm can be found in the DB2 UDB for AS/400 SQL Reference. An interesting feature, illustrated by the examples at the end of Using Qualied Function Reference on page 166, is the fact that function references can be nested, even references to the same function. This is generally true for built-in functions as well as UDFs; however, there are some limitations when column functions are involved.

Chapter 8. Using the Object-Relational Capabilities

167

Rening an earlier example:


CREATE FUNCTION BLOOP (INTEGER) RETURNS INTEGER ... CREATE FUNCTION BLOOP (DOUBLE) RETURNS INTEGER ...

Now consider the following DML statement:


SELECT BLOOP( BLOOP(COLUMN1)) FROM T

If column1 is a DECIMAL or DOUBLE column, the inner BLOOP reference resolves to the second BLOOP dened above. Because this BLOOP returns an INTEGER, the outer BLOOP resolves to the rst BLOOP. Alternatively, if column1 is a SMALLINT or INTEGER column, the inner bloop reference resolves to the rst BLOOP dened above. Because this BLOOP returns an INTEGER, the outer BLOOP also resolves to the rst BLOOP. In this case, you are seeing nested references to the same function. A few additional points important for function references are: v You can dene a function with the name of one of the SQL operators. For example, suppose you can attach some meaning to the "+" operator for values which have distinct type BOAT. You can dene the following UDF:
CREATE FUNCTION "+" (BOAT, BOAT) RETURNS ...

Then you can write the following valid SQL statement:


SELECT "+"(BOAT_COL1, BOAT_COL2) FROM BIG_BOATS WHERE BOAT_OWNER = 'Nelson Mattos'

Note that you are not permitted to overload the built-in conditional operators such as >, =, LIKE, IN, and so on, in this way. v The function selection algorithm does not consider the context of the reference in resolving to a particular function. Look at these BLOOP functions, modied a bit from before:
CREATE FUNCTION BLOOP (INTEGER) RETURNS INTEGER ... CREATE FUNCTION BLOOP (DOUBLE) RETURNS CHAR(10)...

Now suppose you write the following SELECT statement:


SELECT 'ABCDEFG' CONCAT BLOOP(SMALLINT_COL) FROM T

| | | | | | | | | |

Because the best match, resolved using the SMALLINT argument, is the rst BLOOP dened above, the second operand of the CONCAT resolves to data type INTEGER. The statement fails because CONCAT demands string arguments. If the rst BLOOP was not present, the other BLOOP would be chosen and the statement execution would be successful. v UDFs can be dened with parameters or results having any of the LOB types: BLOB, CLOB, or DBCLOB. DB2 will materialize the entire LOB value in storage before invoking such a function, even if the source of the value is a LOB locator host variable. For example, consider the following fragment of a C language application:
EXEC SQL BEGIN DECLARE SECTION; SQL TYPE IS CLOB(150K) clob150K ; /* LOB host var */ SQL TYPE IS CLOB_LOCATOR clob_locator1; /* LOB locator host var */ char string[40]; /* string host var */ EXEC SQL END DECLARE SECTION;

168

DB2 UDB for AS/400 SQL Programming V4R4

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

Either host variable :clob150K or :clob_locator1 is valid as an argument for a function whose corresponding parameter is dened as CLOB(500K). Thus, referring to the FINDSTRING dened in Example: String Search on page 162, both of the following are valid in the program:
... SELECT FINDSTRING (:clob150K, :string) FROM ... ... SELECT FINDSTRING (:clob_locator1, :string) FROM ...

v Non-SQL UDF parameters or results which have one of the LOB types can be created with the AS LOCATOR modier. In this case, the entire LOB value is not materialized prior to invocation. Instead, a LOB LOCATOR is passed to the UDF. You can also use this capability on UDF parameters or results which have a distinct type that is based on a LOB. This capability is limited to non-SQL UDFs. Note that the argument to such a function can be any LOB value of the dened type; it does not have to be a host variable dened as one of the LOCATOR types. The use of host variable locators as arguments is completely unrelated to the use of AS LOCATOR in UDF parameters and result denitions. v UDFs can be dened with distinct types as parameters or as the result. (Earlier examples have illustrated this.) DB2 will pass the value to the UDF in the format of the source data type of the distinct type. Distinct type values which originate in a host variable and which are used as arguments to a UDF which has its corresponding parameter dened as a distinct type, must be explicitly cast to the distinct type by the user. There is no host language type for distinct types. DB2s strong typing necessitates this. Otherwise your results may be ambiguous. So, consider the BOAT distinct type which is dened over a BLOB, and consider the BOAT_COST UDF from Example: External Function with UDT Parameter on page 163, which takes an object of type BOAT as its argument. In the following fragment of a C language application, the host variable :ship holds the BLOB value that is to passed to the BOAT_COST function:
EXEC SQL BEGIN DECLARE SECTION; SQL TYPE IS BLOB(150K) ship; EXEC SQL END DECLARE SECTION;

Both of the following statements correctly resolve to the BOAT_COST function, because both cast the :ship host variable to type BOAT:
... SELECT BOAT_COST (BOAT(:ship)) FROM ... ... SELECT BOAT_COST (CAST(:ship AS BOAT)) FROM ...

If there are multiple BOAT distinct types in the database, or BOAT UDFs in other schema, you must exercise care with your function path. Otherwise your results may be ambiguous.

User-dened Distinct Types (UDT)


Enabling you to dene new data types to DB2 gives you considerable power and extends your capabilities with the built-in data types. You are no longer restricted to using system-supplied built-in data types to model your businesses and capture the semantics of your data. A user-dened distinct type is the DB2 mechanism you can use for this purpose.

Why Use UDTs?


There are several benets associated with UDTs: 1. Extensibility.
Chapter 8. Using the Object-Relational Capabilities

169

By dening new types, you can indenitely increase the set of types provided by DB2 to support your applications. 2. Flexibility. You can specify any semantics and behavior for your new type by using user-dened functions (UDFs) to augment the diversity of the types available in the system. 3. Consistent behavior. Strong typing insures that your UDTs will behave appropriately. It guarantees that only functions dened on your UDT can be applied to instances of the UDT. 4. Encapsulation. The behavior of your UDTs is restricted by the functions and operators that can be applied on them. This provides exibility in the implementation since running applications do not depend on the internal representation that you chose for your type. 5. Extensible behavior. The denition of user-dened functions on types can augment the functionality provided to manipulate your UDT at any time. (See User-Dened Functions (UDF) on page 156) 6. Performance. Distinct types are highly integrated into the database manager. Because distinct types are internally represented the same way as built-in data types, they share the same efficient code used to implement built-in functions, comparison operators, indexes, etc. for built-in data types. 7. Foundation for object-oriented extensions. UDTs are the foundation for most object-oriented features. They represent the most important step towards object-oriented extensions.

Dening a UDT
UDTs, like other objects such as tables, indexes, and UDFs, need to be dened with a CREATE statement. Use the CREATE DISTINCT TYPE statement to dene your new UDT. Detailed explanations for the statement syntax and all its options are found in the DB2 UDB for AS/400 SQL Reference. | | | | | For the CREATE DISTINCT TYPE statement, note that: 1. The name of the new UDT can be a qualied or an unqualied name. 2. The source type of the UDT is the type used by DB2 to internally represent the UDT. For this reason, it must be a built-in data type. Previously dened UDTs cannot be used as source types of other UDTs. As part of a UDT denition, DB2 always generates cast functions to: v Cast from the UDT to the source type, using the standard name of the source type. For example, if you create a distinct type based on FLOAT, the cast function called DOUBLE is created. v Cast from the source type to the UDT. See the DB2 UDB for AS/400 SQL Reference for a discussion of when additional casts to the UDTs are generated. These functions are important for the manipulation of UDTs in queries.

170

DB2 UDB for AS/400 SQL Programming V4R4

Resolving Unqualied UDTs


The function path is used to resolve any references to an unqualied type name or function, except if the type name or function is v Created v Dropped v Commented on. For information on how unqualied function references are resolved, see Using Qualied Function Reference on page 166.

Examples of Using CREATE DISTINCT TYPE


The following are examples of using CREATE DISTINCT TYPE: v Example: Money v Example: Resume

Example: Money
Suppose you are writing applications that need to handle different currencies and wish to ensure that DB2 does not allow these currencies to be compared or manipulated directly with one another in queries. Remember that conversions are necessary whenever you want to compare values of different currencies. So you dene as many UDTs as you need; one for each currency that you may need to represent: | | | | | | | | | | |
CREATE DISTINCT TYPE US_DOLLAR AS DECIMAL (9,2) CREATE DISTINCT TYPE CANADIAN_DOLLAR AS DECIMAL (9,2) CREATE DISTINCT TYPE GERMAN_MARK AS DECIMAL (9,2)

Example: Resume
Suppose you would like to keep the form lled by applicants to your company in a DB2 table and you are going to use functions to extract the information from these forms. Because these functions cannot be applied to regular character strings (because they are certainly not able to nd the information they are supposed to return), you dene a UDT to represent the lled forms:
CREATE DISTINCT TYPE PERSONAL.APPLICATION_FORM AS CLOB(32K)

Dening Tables with UDTs


After you have dened several UDTs, you can start dening tables with columns whose types are UDTs. Following are examples using CREATE TABLE: v Example: Sales v Example: Application Forms

Example: Sales
Suppose you want to dene tables to keep your companys sales in different countries as follows:
CREATE TABLE US_SALES (PRODUCT_ITEM INTEGER, MONTH INTEGER CHECK (MONTH BETWEEN 1 AND 12), YEAR INTEGER CHECK (YEAR > 1985), TOTAL US_DOLLAR)

Chapter 8. Using the Object-Relational Capabilities

171

CREATE TABLE CANADIAN_SALES (PRODUCT_ITEM INTEGER, MONTH INTEGER CHECK (MONTH BETWEEN 1 AND 12), YEAR INTEGER CHECK (YEAR > 1985), TOTAL CANADIAN_DOLLAR) CREATE TABLE GERMAN_SALES (PRODUCT_ITEM INTEGER, MONTH INTEGER CHECK (MONTH BETWEEN 1 AND 12), YEAR INTEGER CHECK (YEAR > 1985), TOTAL GERMAN_MARK)

The UDTs in the above examples are created using the same CREATE DISTINCT TYPE statements in Example: Money on page 171. Note that the above examples use check constraints. For information on check constraints see the DB2 UDB for AS/400 SQL Reference.

Example: Application Forms


Suppose you need to dene a table where you keep the forms lled out by applicants as follows: | | | | | | | | | | |
CREATE TABLE APPLICATIONS (ID INTEGER, NAME VARCHAR (30), APPLICATION_DATE DATE, FORM PERSONAL.APPLICATION_FORM)

You have fully qualied the UDT name because its qualier is not the same as your authorization ID and you have not changed the default function path. Remember that whenever type and function names are not fully qualied, DB2 searches through the schemas listed in the current function path and looks for a type or function name matching the given unqualied name. .

Manipulating UDTs
One of the most important concepts associated with UDTs is strong typing. Strong typing guarantees that only functions and operators dened on the UDT can be applied to its instances. Strong typing is important to ensure that the instances of your UDTs are correct. For example, if you have dened a function to convert US dollars to Canadian dollars according to the current exchange rate, you do not want this same function to be used to convert German marks to Canadian dollars because it will certainly return the wrong amount. As a consequence of strong typing, DB2 does not allow you to write queries that compare, for example, UDT instances with instances of the UDT source type. For the same reason, DB2 will not let you apply functions dened on other types to UDTs. If you want to compare instances of UDTs with instances of another type, you have to cast the instances of one or the other type. In the same sense, you have to cast the UDT instance to the type of the parameter of a function that is not dened on a UDT if you want to apply this function to a UDT instance.

172

DB2 UDB for AS/400 SQL Programming V4R4

Examples of Manipulating UDTs


The following are examples of manipulating UDTs: v Example: Comparisons Between UDTs and Constants v Example: Casting Between UDTs v Example: Comparisons Involving UDTs v v v v v Example: Sourced UDFs Involving UDTs Example: Assignments Involving UDTs Example: Assignments in Dynamic SQL Example: Assignments Involving Different UDTs Example: Use of UDTs in UNION

Example: Comparisons Between UDTs and Constants


Suppose you want to know which products sold more than US $100 000.00 in the US in the month of July, 1992 (7/92).
SELECT PRODUCT_ITEM FROM US_SALES WHERE TOTAL > US_DOLLAR (100000) AND month = 7 AND year = 1992

Because you cannot compare US dollars with instances of the source type of US dollars (that is, DECIMAL) directly, you have used the cast function provided by DB2 to cast from DECIMAL to US dollars. You can also use the other cast function provided by DB2 (that is, the one to cast from US dollars to DECIMAL) and cast the column total to DECIMAL. Either way you decide to cast, from or to the UDT, you can use the cast specication notation to perform the casting, or the functional notation. That is, you could have written the above query as:
SELECT PRODUCT_ITEM FROM US_SALES WHERE TOTAL > CAST (100000 AS us_dollar) AND MONTH = 7 AND YEAR = 1992

Example: Casting Between UDTs


Suppose you want to dene a UDF that converts Canadian dollars to U.S. dollars. Suppose you can obtain the current exchange rate from a le managed outside of DB2. You would then dene a UDF that obtains a value in Canadian dollars, accesses the exchange rate le, and returns the corresponding amount in U.S. dollars. At rst glance, such a UDF may appear easy to write. However, not all C compilers support DECIMAL values. The UDTs representing different currencies have been dened as DECIMAL. Your UDF will need to receive and return DOUBLE values, since this is the only data type provided by C that allows the representation of a DECIMAL value without losing the decimal precision. Thus, your UDF should be dened as follows: | | | | | |
CREATE FUNCTION CDN_TO_US_DOUBLE(DOUBLE) RETURNS DOUBLE EXTERNAL NAME 'MYLIB/CURRENCIES(C_CDN_US)' LANGUAGE C PARAMETER STYLE DB2SQL NO SQL NOT DETERMINISTIC

Chapter 8. Using the Object-Relational Capabilities

173

The exchange rate between Canadian and U.S. dollars may change between two invocations of the UDF, so you declare it as NOT DETERMINISTIC. The question now is, how do you pass Canadian dollars to this UDF and get U.S. dollars from it? The Canadian dollars must be cast to DECIMAL values. The DECIMAL values must be cast to DOUBLE. You also need to have the returned DOUBLE value cast to DECIMAL and the DECIMAL value cast to U.S. dollars. Such casts are performed automatically by DB2 anytime you dene sourced UDFs, whose parameter and return type do not exactly match the parameter and return type of the source function. Therefore, you need to dene two sourced UDFs. The rst brings the DOUBLE values to a DECIMAL representation. The second brings the DECIMAL values to the UDT. That is, you dene the following:
CREATE FUNCTION CDN_TO_US_DEC (DECIMAL(9,2)) RETURNS DECIMAL(9,2) SOURCE CDN_TO_US_DOUBLE (DOUBLE) CREATE FUNCTION US_DOLLAR (CANADIAN_DOLLAR) RETURNS US_DOLLAR SOURCE CDN_TO_US_DEC (DECIMAL())

Note that an invocation of the US_DOLLAR function as in US_DOLLAR(C1), where C1 is a column whose type is Canadian dollars, has the same effect as invoking:
US_DOLLAR (DECIMAL(CDN_TO_US_DOUBLE (DOUBLE (DECIMAL (C1)))))

That is, C1 (in Canadian dollars) is cast to decimal which in turn is cast to a double value that is passed to the CDN_TO_US_DOUBLE function. This function accesses the exchange rate le and returns a double value (representing the amount in U.S. dollars) that is cast to decimal, and then to U.S. dollars. A function to convert German marks to U.S. dollars would be similar to the example above: | | | | | | | | | | | | | |
CREATE FUNCTION GERMAN_TO_US_DOUBLE(DOUBLE) RETURNS DOUBLE EXTERNAL NAME 'MYLIB/CURRENCIES(C_GER_US)' LANGUAGE C PARAMETER STYLE DB2SQL NO SQL NOT DETERMINISTIC CREATE FUNCTION GERMAN_TO_US_DEC (DECIMAL(9,2)) RETURNS DECIMAL(9,2) SOURCE GERMAN_TO_US_DOUBLE(DOUBLE) CREATE FUNCTION US_DOLLAR(GERMAN_MARK) RETURNS US_DOLLAR SOURCE GERMAN_TO_US_DEC (DECIMAL())

Example: Comparisons Involving UDTs


Suppose you want to know which products sold more in the US than in Canada and Germany for the month of March, 1989 (3/89):
SELECT US.PRODUCT_ITEM, US.TOTAL FROM US_SALES AS US, CANADIAN_SALES AS CDN, GERMAN_SALES AS GERMAN WHERE US.PRODUCT_ITEM = CDN.PRODUCT_ITEM AND US.PRODUCT_ITEM = GERMAN.PRODUCT_ITEM AND US.TOTAL > US_DOLLAR (CDN.TOTAL) AND US.TOTAL > US_DOLLAR (GERMAN.TOTAL) AND US.MONTH = 3 AND US.YEAR = 1989

174

DB2 UDB for AS/400 SQL Programming V4R4

AND AND AND AND

CDN.MONTH = 3 CDN.YEAR = 1989 GERMAN.MONTH = 3 GERMAN.YEAR = 1989

Because you cannot directly compare US dollars with Canadian dollars or German Marks, you use the UDF to cast the amount in Canadian dollars to US dollars, and the UDF to cast the amount in German Marks to US dollars. You cannot cast them all to DECIMAL and compare the converted DECIMAL values because the amounts are not monetarily comparable. That is, the amounts are not in the same currency.

Example: Sourced UDFs Involving UDTs


Suppose you have dened a sourced UDF on the built-in SUM function to support SUM on German Marks:
CREATE FUNCTION SUM (GERMAN_MARKS) RETURNS GERMAN_MARKS SOURCE SYSIBM.SUM (DECIMAL())

You want to know the total of sales in Germany for each product in the year of 1994. You would like to obtain the total sales in US dollars:
SELECT PRODUCT_ITEM, US_DOLLAR (SUM (TOTAL)) FROM GERMAN_SALES WHERE YEAR = 1994 GROUP BY PRODUCT_ITEM

You could not write SUM (us_dollar (total)), unless you had dened a SUM function on US dollar in a manner similar to the above.

Example: Assignments Involving UDTs


Suppose you want to store the form lled by a new applicant into the database. You have dened a host variable containing the character string value used to represent the lled form:
EXEC SQL BEGIN DECLARE SECTION; SQL TYPE IS CLOB(32K) hv_form; EXEC SQL END DECLARE SECTION; /* Code to fill hv_form */ INSERT INTO APPLICATIONS VALUES (134523, 'Peter Holland', CURRENT DATE, :hv_form)

You do not explicitly invoke the cast function to convert the character string to the UDT personal.application_form . This is because DB2 lets you assign instances of the source type of a UDT to targets having that UDT.

Example: Assignments in Dynamic SQL


If you want to use the same statement given in Example: Assignments Involving UDTs in dynamic SQL, you can use parameter markers as follows:
EXEC SQL BEGIN DECLARE SECTION; long id; char name[30]; SQL TYPE IS CLOB(32K) form; char command[80]; EXEC SQL END DECLARE SECTION; /* Code to fill host variables */

Chapter 8. Using the Object-Relational Capabilities

175

strcpy(command,"INSERT INTO APPLICATIONS VALUES"); strcat(command,"(?, ?, CURRENT DATE, ?)"); EXEC SQL PREPARE APP_INSERT FROM :command; EXEC SQL EXECUTE APP_INSERT USING :id, :name, :form;

You made use of DB2s cast specication to tell DB2 that the type of the parameter marker is CLOB(32K), a type that is assignable to the UDT column. Remember that you cannot declare a host variable of a UDT type, since host languages do not support UDTs. Therefore, you cannot specify that the type of a parameter marker is a UDT.

Example: Assignments Involving Different UDTs


Suppose you have dened two sourced UDFs on the built-in SUM function to support SUM on US and Canadian dollars, similar to the UDF sourced on German Marks in Example: Sourced UDFs Involving UDTs on page 175:
CREATE FUNCTION SUM (CANADIAN_DOLLAR) RETURNS CANADIAN_DOLLAR SOURCE SYSIBM.SUM (DECIMAL()) CREATE FUNCTION SUM (US_DOLLAR) RETURNS US_DOLLAR SOURCE SYSIBM.SUM (DECIMAL())

Now suppose your supervisor requests that you maintain the annual total sales in US dollars of each product and in each country, in separate tables:
CREATE TABLE US_SALES_94 (PRODUCT_ITEM INTEGER, TOTAL US_DOLLAR) CREATE TABLE GERMAN_SALES_94 (PRODUCT_ITEM INTEGER, TOTAL US_DOLLAR) CREATE TABLE CANADIAN_SALES_94 (PRODUCT_ITEM INTEGER, TOTAL US_DOLLAR) INSERT INTO US_SALES_94 SELECT PRODUCT_ITEM, SUM (TOTAL) FROM US_SALES WHERE YEAR = 1994 GROUP BY PRODUCT_ITEM INSERT INTO GERMAN_SALES_94 SELECT PRODUCT_ITEM, US_DOLLAR (SUM (TOTAL)) FROM GERMAN_SALES WHERE YEAR = 1994 GROUP BY PRODUCT_ITEM INSERT INTO CANADIAN_SALES_94 SELECT PRODUCT_ITEM, US_DOLLAR (SUM (TOTAL)) FROM CANADIAN_SALES WHERE YEAR = 1994 GROUP BY PRODUCT_ITEM

176

DB2 UDB for AS/400 SQL Programming V4R4

You explicitly cast the amounts in Canadian dollars and German Marks to US dollars since different UDTs are not directly assignable to each other. You cannot use the cast specication syntax because UDTs can only be cast to their own source type.

Example: Use of UDTs in UNION


Suppose you would like to provide your American users with a view containing all the sales of every product of your company:
CREATE VIEW ALL_SALES AS SELECT PRODUCT_ITEM, MONTH, YEAR, TOTAL FROM US_SALES UNION SELECT PRODUCT_ITEM, MONTH, YEAR, US_DOLLAR (TOTAL) FROM CANADIAN_SALES UNION SELECT PRODUCT_ITEM, MONTH, YEAR, US_DOLLAR (TOTAL) FROM GERMAN_SALES

You cast Canadian dollars to US dollars and German Marks to US dollars because UDTs are union compatible only with the same UDT. You must use the functional notation to cast between UDTs since the cast specication only lets you cast between UDTs and their source types.

Synergy Between UDTs, UDFs, and LOBs


In previous sections, you learned how to dene and use the individual DB2 object extensions (UDTs, UDFs, and LOBs). However, as you will see in this section, there is a lot of synergy between these three object extensions.

Combining UDTs, UDFs, and LOBs


According to the concept of object-orientation, similar objects in the application domain are grouped into related types. Each of these types have a name, an internal representation, and behavior. By using UDTs, you can tell DB2 the name of your new type and how it is internally represented. A LOB is one of the possible internal representations for your new type and is the most suitable representation for large, complex structures. By using UDFs, you can dene the behavior of the new type. Consequently, there is an important synergy between UDTs, UDFs, and LOBs. An application type with a complex data structure and behavior is modeled as a UDT that is internally represented as a LOB, with its behavior implemented by UDFs. The rules governing the semantic integrity of your application type will be represented as constraints and triggers. To have better control and organization of your related UDTs and UDFs, you should keep them in the same schema.

Examples of Complex Applications


The following examples show how you can use UDTs, UDFs, and LOBs together in complex applications: Example: Dening the UDT and UDFs Example: Exploiting LOB Function to Populate the Database Example: Exploiting UDFs to Query Instances of UDTs Example: Exploiting LOB Locators to Manipulate UDT Instances

Chapter 8. Using the Object-Relational Capabilities

177

Example: Dening the UDT and UDFs


Suppose you would like to keep the electronic mail (e-mail) sent to your company in DB2 tables. Ignoring any issues of privacy, you plan to write queries over such e-mail to nd out their subject, how often your e-mail service is used to receive customer orders, and so on. E-mail can be quite large, and it has a complex internal structure (a sender, a receiver, the subject, date, and the e-mail content). Therefore, you decide to represent the e-mail by means of a UDT whose source type is a large object. You dene a set of UDFs on your e-mail type, such as functions to extract the subject of the e-mail, the sender, the date, and so on. You also dene functions that can perform searches on the content of the e-mail. You do the above using the following CREATE statements: | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
CREATE DISTINCT TYPE E_MAIL AS BLOB (1M) CREATE FUNCTION SUBJECT (E_MAIL) RETURNS VARCHAR (200) EXTERNAL NAME 'LIB/PGM(SUBJECT)' LANGUAGE C PARAMETER STYLE DB2SQL NO SQL DETERMINISTIC NO EXTERNAL ACTION CREATE FUNCTION SENDER (E_MAIL) RETURNS VARCHAR (200) EXTERNAL NAME 'LIB/PGM(SENDER)' LANGUAGE C PARAMETER STYLE DB2SQL NO SQL DETERMINISTIC NO EXTERNAL ACTION CREATE FUNCTION RECEIVER (E_MAIL) RETURNS VARCHAR (200) EXTERNAL NAME 'LIB/PGM(RECEIVER)' LANGUAGE C PARAMETER STYLE DB2SQL NO SQL DETERMINISTIC NO EXTERNAL ACTION CREATE FUNCTION SENDING_DATE (E_MAIL) RETURNS DATE CAST FROM VARCHAR(10) EXTERNAL NAME 'LIB/PGM(SENDING_DATE)' LANGUAGE C PARAMETER STYLE DB2SQL NO SQL DETERMINISTIC NO EXTERNAL ACTION CREATE FUNCTION CONTENTS (E_MAIL) RETURNS BLOB (1M) EXTERNAL NAME 'LIB/PGM(CONTENTS)' LANGUAGE C PARAMETER STYLE DB2SQL NO SQL DETERMINISTIC NO EXTERNAL ACTION CREATE FUNCTION CONTAINS (E_MAIL, VARCHAR (200)) RETURNS INTEGER EXTERNAL NAME 'LIB/PGM(CONTAINS)' LANGUAGE C PARAMETER STYLE DB2SQL

178

DB2 UDB for AS/400 SQL Programming V4R4

| | | | | | |

NO SQL DETERMINISTIC NO EXTERNAL ACTION CREATE TABLE ELECTRONIC_MAIL (ARRIVAL_TIMESTAMP TIMESTAMP, MESSAGE E_MAIL)

Example: Exploiting LOB Function to Populate the Database


Suppose you populate your table by transferring your e-mail that is maintained in les into DB2. You would execute the following INSERT statement multiple times with different values of the HV_EMAIL_FILE until you have stored all your e_mail into DB2:
EXEC SQL BEGIN DECLARE SECTION SQL TYPE IS BLOB_FILE HV_EMAIL_FILE; EXEC SQL END DECLARE SECTION strcpy (HV_EMAIL_FILE.NAME, "/u/mail/email/mbox"); HV_EMAIL_FILE.NAME_LENGTH = strlen(HV_EMAIL_FILE.NAME); HV_EMAIL_FILE.FILE_OPTIONS = 2; EXEC SQL INSERT INTO ELECTRONIC_MAIL VALUES (CURRENT TIMESTAMP, :hv_email_file);

| | | | |

All the function provided by DB2 LOB support is applicable to UDTs whose source type are LOBs. Therefore, you have used LOB le reference variables to assign the contents of the le into the UDT column. You have not used the cast function to convert values of BLOB type into your e-mail type. This is because DB2 let you assign values of the source type of a distinct type to targets to the distinct type.

Example: Exploiting UDFs to Query Instances of UDTs


Suppose you need to know how much e-mail was sent by a specic customer regarding customer orders and you have the e-mail address of your customers in the customers table.
SELECT COUNT (*) FROM ELECTRONIC_MAIL AS EMAIL, CUSTOMERS WHERE SUBJECT (EMAIL.MESSAGE) = 'customer order' AND CUSTOMERS.EMAIL_ADDRESS = SENDER (EMAIL.MESSAGE) AND CUSTOMERS.NAME = 'Customer X'

You have used the UDFs dened on the UDT in this SQL query since they are the only means to manipulate the UDT. In this sense, your UDT e-mail is completely encapsulated. That is, its internal representation and structure are hidden and can only be manipulated by the dened UDFs. These UDFs know how to interpret the data without the need to expose its representation. Suppose you need to know the details of all the e-mail your company received in 1994 which had to do with the performance of your products in the marketplace.
SELECT SENDER (MESSAGE), SENDING_DATE (MESSAGE), SUBJECT (MESSAGE) FROM ELECTRONIC_MAIL WHERE CONTAINS (MESSAGE, '"performance" AND "products" AND "marketplace"') = 1

You have used the contains UDF which is capable of analyzing the contents of the message searching for relevant keywords or synonyms.

Chapter 8. Using the Object-Relational Capabilities

179

Example: Exploiting LOB Locators to Manipulate UDT Instances


Suppose you would like to obtain information about a specic e-mail without having to transfer the entire e-mail into a host variable in your application program. (Remember that an e-mail can be quite large.) Since your UDT is dened on a LOB, you can use LOB locators for that purpose:
EXEC SQL BEGIN DECLARE SECTION long hv_len; char hv_subject[200]; char hv_sender[200]; char hv_buf[4096]; char hv_current_time[26]; SQL TYPE IS BLOB_LOCATOR hv_email_locator; EXEC SQL END DECLARE SECTION EXEC SQL SELECT MESSAGE INTO :hv_email_locator FROM ELECTRONIC MAIL WHERE ARRIVAL_TIMESTAMP = :hv_current_time; EXEC SQL VALUES (SUBJECT (E_MAIL(:hv_email_locator)) INTO :hv_subject; .... code that checks if the subject of the e_mail is relevant .... .... if the e_mail is relevant, then............................... EXEC SQL VALUES (SENDER (CAST (:hv_email_locator AS E_MAIL))) INTO :hv_sender;

Because your host variable is of type BLOB locator (the source type of the UDT), you have explicitly converted the BLOB locator to your UDT, whenever it was used as an argument of a UDF dened on the UDT.

Using DataLinks
The DataLink data type is one of the basic building blocks for extending the types of data that can be stored in database les. The idea of a DataLink is that the actual data stored in the column is only a pointer to the object. This object can be anything, an image le, a voice recording, a text le, etc. The method used for resolving to the object is to store a Uniform Resource Locator (URL). This means that a row in a table can be used to contain information about the object in traditional data types, and the object itself can be referenced using the DataLink data type. The user can use new SQL scalar functions to get back the path to the object and the server on which the object is stored. With the DataLink data type, there is a fairly loose relationship between the row and the object. For instance, deleting a row will sever the relationship to the object referenced by the DataLink, but the object itself might not be deleted. An SQL table created with a DataLink column can be used to hold information about an object, without actually containing the object itself. This concept gives the user much more exibility in the types of data that can be managed using an SQL table. If, for instance, the user has thousands of video clips stored in the integrated le system of their AS/400, they may want to use an SQL table to contain information about these video clips. But since the user already has the objects stored in a directory, they simply want the SQL table to contain references to the objects, not contain the actual bytes of storage. A good solution would be to use DataLinks. The SQL table would use traditional SQL data types to contain information about each clip, such as title, length, date, etc. But the clip itself would be referenced using a DataLink column. Each row in the table would store a URL

180

DB2 UDB for AS/400 SQL Programming V4R4

for the object and an optional comment. Then an application that is working with the clips can retrieve the URL using SQL interfaces, and then use a browser or other playback software to work with the URL and display the video clip. There are several advantages to using this technique: v The integrated le system can store any type of stream le. v The integrated le system can store extremely large objects, that would not t into a character column, or perhaps even a LOB column. v The hierarchical nature of the integrated le system is well-suited to organizing and working with the stream le objects. v By leaving the bytes of the object outside the database and in the integrated le system, applications can achieve better performance by allowing the SQL runtime engine to handle queries and reports, and allowing the le system to handle streaming of video, displaying images, text, etc. Using DataLinks also gives control over the objects while they are in linked status. A DataLink column can be created such that the referenced object cannot be deleted, moved, or renamed while there is a row in the SQL table that references that object. This object would be considered linked. Once the row containing that reference is deleted, the object is unlinked. To understand this concept fully, one should know the levels of control that can be specied when creating a DataLink column. Refer to the SQL Reference for the exact syntax used when creating DataLink columns.

NO LINK CONTROL
When a column is created with NO LINK CONTROL, there is no linking that takes place when rows are added to the SQL table. The URL is veried to be syntactically correct, but there is no check to make sure that the server is accessible, or that the le even exists.

FILE LINK CONTROL (with File System Permissions)


When the DataLink column is created as FILE LINK CONTROL with le system (FS) permissions, the system will verify that any DataLink value is a valid URL, with a valid server name and le name. The le must exist at the time that row is being inserted into the SQL table. When the object is found, it will be marked as linked. This means that the object cannot be moved, deleted, or renamed during the time that it is linked. Also, an object cannot be linked more than once. If the server name portion of the URL species a remote system, that system must be accessible. If a row containing a DataLink value is deleted, the object is unlinked. If a DataLink value is updated to a different value, the old object is unlinked, and the new object is linked. The integrated le system is still responsible for managing permissions for the linked object. The permissions are not modied during the link or unlink processes. This option provides control of the objects existence for the duration of time that it is linked.

FILE LINK CONTROL (with Database Permissions)


When the DataLink column is create as FILE LINK CONTROL with database permissions, the URL is veried, and all existing permissions to the object are removed. The ownership of the object is changed to a special system-supplied user
Chapter 8. Using the Object-Relational Capabilities

181

prole. During the time that the object is linked, the only access to the object is by obtaining the URL from the SQL table that has the object linked. This is handled by using a special access token that is appended to the URL returned by SQL. Without the access token, all attempts to access the object will fail with an authority violation. If the URL with the access token is retrieved from the SQL table by normal means (FETCH, SELECT INTO, etc.) the le system lter will validate the access token and allow the access to the object. This option provides the control of preventing updates to the linked object for users trying to access the object by direct means. Since the only access to the object is by obtaining the access token from an SQL operation, an administrator can effectively control access to the linked objects by using the database permissions to the SQL table that contains the DataLink column.

Commands Used for Working with DataLinks


Support for the DataLink data type can be broken down into 3 different components: 1. The DB2 database support has a data type called DATALINK. This can be specied on SQL statements such as CREATE TABLE and ALTER TABLE. The column cannot have any default other than NULL. Access to the data must be using SQL interfaces. This is because the DATALINK itself is not compatible with any host variable type. SQL scalar functions can be used to retrieve the DATALINK value in character form. There is a DLVALUE scalar function that must be used in SQL to INSERT and UPDATE the values in the column. 2. The DataLink File Manager (DLFM) is the component that maintains the link status for the les on a server, and keeps track of meta-data for each le. This code handles linking, unlinking, and commitment control issues. An important aspect of DataLinks is that the DLFM need not be on the same physical system as the SQL table that contains the DataLink column. So an SQL table can link an object that resides in either the same systems integrated le system, or a remote AS/400s integrated le system. 3. The DataLink lter must be executed when the le system tries operations against les that are in directories designated as containing linked objects. This component determines if the le is linked, and optionally, if the user is authorized to access the le. If the le name includes an access token, the token will be veried. Since there is extra overhead in this lter process, it is only executed when the accessed object exists in one of the directories within a DataLink prex. See the discussion below on prexes. When working with DataLinks, there are several steps that must be taken to properly congure the system: v TCP/IP must be congured on any systems that are going to be used when working with DataLinks. This would include the systems on which the SQL tables with DataLink columns are going to be created, as well as the systems that will contain the objects to be linked. In most cases, this will be the same system. Since the URL that is used to reference the object contains a TCP/IP server name, this name must be recognized by the system that is going to contain the DataLink. The command CFGTCP can be used to congure the TCP/IP names, or to register a TCP/IP name server. v The system that contains the SQL tables must have the Relational Database Directory updated to reect the local database system, and any optional remote systems. The command WRKRDBDIRE can be used to add or modify

182

DB2 UDB for AS/400 SQL Programming V4R4

information in this directory. For consistency, it is recommended that the same names be used as the TCP/IP server name and the Relational Database name. v The DLFM server must be started on any systems that will contain objects to be linked. The command STRTCPSVR *DLFM can be used to start the DLFM server. The DLFM server can be ended by using the CL command ENDTCPSVR *DLFM. Once the DLFM has been started, there are some steps needed to congure the DLFM. These DLFM functions are available via an executable script that can be entered from the QShell interface. To get to the interactive shell interface, use the CL command QSH. This will bring up a command entry screen from which you can enter the DLFM script commands. The script command dfmadmin -help can be used to display help text and syntax diagrams. For the most commonly used functions, CL commands have also been provided. Using the CL commands, most or all of the DLFM conguration can be accomplished without using the script interface. Depending on your preferences, you can choose to use either the script commands from the QSH command entry screen or the CL commands from the CL command entry screen. Since these functions are meant for a system administrator or a database administrator, they all require the *IOSYSCFG special authority.

Adding a prex - A prex is a path or directory that will contain objects to be linked. When setting up the DLFM on a system, the administrator must add any prexes that will be used for DataLinks. The script command dfmadmin -add_prex is used to add prexes. The CL command to add prexes is ADDPFXDLFM.
For instance, on server TESTSYS1, there is a directory called /mydir/datalinks/ that contains the objects that will be linked. The administrator uses the command ADDPFXDLFM PREFIX((/mydir/datalinks/)) to add the prex. Now links for URLs such as:
http://TESTSYS1/mydir/datalinks/videos/file1.mpg or file://TESTSYS1/mydir/datalinks/text/story1.txt

would be valid since their path begins with a valid prex. It is also possible to remove a prex using the script command dfmadmin -del_prex. This is not a commonly used function since it can only be executed if there are no linked objects anywhere in the directory structure contained within the prex name.

Adding a Host Database - A host database is a relational database system from which a link request originates. If the DLFM is on the same system as the SQL tables that will contain the DataLinks, then only the local database name needs to be added. If the DLFM will have link requests coming from remote systems, then all of their names must be registered with the DLFM. The script command to add a host database is dfmadmin -add_db and the CL command is ADDHDBDLFM. This function also requires that the libraries containing the SQL tables also be registered.
For instance, on server TESTSYS1, where you have already added the /mydir/datalinks/ prex, you want SQL tables on the local system in either library

Chapter 8. Using the Object-Relational Capabilities

183

TESTDB or PRODDB to be allowed to link objects on this server. Use the following command: ADDHDBDLFM HOSTDBLIB((TESTDB) (PRODDB)) HOSTDB(TESTSYS1) Once the DLFM has been started, and the prexes and host database names have been registered, you can begin linking objects in the le system.

184

DB2 UDB for AS/400 SQL Programming V4R4

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

Chapter 9. Writing User-Dened Functions (UDFs)


User Dened Functions (UDFs) consist of three types: sourced, external, and SQL. Sourced function UDFs call other functions to perform the operation. SQL and external function UDFs require that you write and execute separate code. This chapter is about writing SQL and external functions. To write external and SQL functions, you need to do the following: v understand the UDF runtime environment v register the UDF, so that it is known to the database v write the function code to perform the function and pass the appropriate parameters v debug and test the function.

UDF runtime environment


There are several things to consider about the environment in which a UDF executes and the limitations of that environment. These factors should be considered carefully if you are contemplating writing complex function code for UDFs.

Length of time that the UDF runs


UDFs are invoked from within an SQL statement execution, which is normally a query operation that potentially runs against thousands of rows in a table. Because of this, the UDF needs to be invoked from a low level of the database. As a consequence of being invoked from such a low level, there are certain resources (locks and seizes) being held at the time the UDF is invoked and for the duration of the UDF execution. These resources are primarily locks on any tables and indexes involved in the SQL statement that is invoking the UDF. Due to these held resources, it is important that the UDF not perform operations that may take an extended period of time (minutes or hours). Because of the critical nature of holding resources for long periods of time, the database only waits for a certain period of time for the UDF to nish. If the UDF does not nish in the time allocated, the SQL statement will fail, which can be quite aggravating to the end user. The default UDF wait time used by the database should be more than sufficient to allow a normal UDF to run to completion. However, if you have a long running UDF and wish to increase the wait time, this can be done using the UDF_TIME_OUT option in the query INI le. See Query Options File QAQQINI on page 543 for more information on the INI le. Note, however, that there is a maximum time limit that the database will not exceed, regardless of the value specied for UDF_TIME_OUT. Since resources are held while the UDF is run, it is important that the UDF not operate on the same tables or indexes allocated for the original SQL statement or, if it does, that it does not perform an operation that conicts with the one being performed in the SQL statement. Specically, the UDF should not try to perform any insert, update or delete record operation on those tables.

Copyright IBM Corp. 1997, 1999

185

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

Threads considerations
A UDF runs in the same job as the SQL statement that invoked it. However, the UDF runs in a system thread, separate from the thread that is running the SQL statement. For more information about threads, see Database considerations for multithreaded programming. Because the UDF runs in the same job as the SQL statement, it shares much of the same environment as the SQL statement. However, because it runs under a separate thread, the following threads considerations apply: v the UDF will conict with thread level resources held by the SQL statements thread. Primarily, these are the table resources discussed above. v UDFs do not inherent any program adopted authority that may have been active at the time the SQL statement was invoked. UDF authority comes from either the authority associated with the UDF program itself or the authority of the user running the SQL statement. v the UDF cannot perform any operation that is blocked from being run in a secondary thread. v the UDF program must be created such that it either runs under a named activation group or in the activation group of its caller (ACTGRP parameter). Programs that specify ACTGRP(*NEW) will not be allowed to run as UDFs.

Parallel processing
A UDF can be dened to allow parallel processing. This means that the same UDF program can be running in multiple threads at the same time. Therefore, if ALLOW PARALLEL is specied for the UDF, ensure that it is thread safe. For more information about threads, see Database considerations for multithreaded programming.

Writing function code


Writing function code involves knowing how to write the SQL or external function to perform the function. It also involves understanding the interface between the database and the function code to dene it correctly, and determining packaging options when creating the executable program.

Writing UDFs as SQL functions


SQL functions are UDFs that you have dened, written, and registered using the CREATE FUNCTION statement. As such, they are written using only the SQL language and their denition is completely contained within one (potentially large) CREATE FUNCTION statement. The CREATE FUNCTION statement for SQL functions follow the general ow of:
CREATE FUNCTION function name(parameters) RETURNS return value LANGUAGE SQL BEGIN sql statements END

For example, a function that returns a priority based on a date:

186

DB2 UDB for AS/400 SQL Programming V4R4

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

CREATE FUNCTION PRIORITY(indate date) RETURNS CHAR(7) LANGUAGE SQL BEGIN RETURN( CASE WHEN indate>CURRENT DATE-3 DAYS THEN 'HIGH' WHEN indate>CURRENT DATE-7 DAYS THEN 'MEDIUM' ELSE 'LOW' END ); END

The function could then be invoked as:


SELECT ORDERNBR, PRIORITY(ORDERDUEDATE) FROM ORDERS

The creation of an SQL function causes the registration of the UDF, generates the executable code for the function, and denes to the database the details of how parameters are actually passed. Therefore, writing these functions is quite clean and provides less chance of introducing errors into the function.

Writing UDFs as external functions


You can also write the executable code of a UDF in a language other than SQL. While this method is slightly more cumbersome than an SQL function, it provides the exibility for you to use whatever language is most effective for you. The executable code can be contained in either a program or service program.

Passing arguments from DB2 to external functions


DB2 provides the storage for all parameters passed to a UDF. Therefore, parameters are passed to the external function by address. This is the normal parameter passing method for programs. For service programs, ensure that the parameters are dened correctly in the function code. When dening and using the parameters in the UDF, care should be taken to ensure that no more storage is referenced for a given parameter than is dened for that parameter. The parameters are all stored in the same space and exceeding a given parameters storage space can overwrite another parameters value. This, in turn, can cause the function to see invalid input data or cause the value returned to the database to be invalid. There are four supported parameter styles available to external UDFs. For the most part, the styles differ in how many parameters are passed to the external program or service program.

Parameter style SQL: The parameter style SQL conforms to the industry standard Structured Query Language (SQL). With parameter style SQL, the parameters are passed into the external program as follows (in the order specied):
SQL-result

SQL-argument

SQL-argument-ind

|
Chapter 9. Writing User-Dened Functions (UDFs)

187

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

SQL-result-ind

SQL-state

function-name

specific-name

diagnostic-message

SQL-argument This argument is set by DB2 before calling the UDF. This value repeats n times, where n is the number of arguments specied in the function reference. The value of each of these arguments is taken from the expression specied in the function invocation. It is expressed in the data type of the dened parameter in the create function statement. Note: These parameters are treated as input only; any changes to the parameter values made by the UDF are ignored by DB2. SQL-result This argument is set by the UDF before returning to DB2. The database provides the storage for the return value. Since the parameter is passed by address, the address is of the storage where the return value should be placed. The database provides as much storage as needed for the return value as dened on the CREATE FUNCTION statement. If the CAST FROM clause is used in the CREATE FUNCTION statement, DB2 assumes the UDF returns the value as dened in the CAST FROM clause, otherwise DB2 assumes the UDF returns the value as dened in the RETURNS clause. SQL-argument-ind This argument is set by DB2 before calling the UDF. It can be used by the UDF to determine if the corresponding SQL-argument is null or not. The nth SQL-argument-ind corresponds to the nth SQL-argument, described previously. Each indicator is dened as a two-byte signed integer. It is set to one of the following values:
0 -1 The argument is present and not null. The argument is null.

If the function is dened with RETURNS NULL ON NULL INPUT, the UDF does not need to check for a null value. However, if it is dened with CALLS ON NULL INPUT, any argument can be NULL and the UDF should check for null input. Note: these parameters are treated as input only; any changes to the parameter values made by the UDF are ignored by DB2.

SQL-result-ind This argument is set by the UDF before returning to DB2. The database provides the storage for the return value. The argument is dened as a two-byte signed integer. If set to a negative value, the database interprets the result of the function as null. If set to zero or a positive value, the database uses the value returned in SQL-result. The database provides the storage for the return value indicator. Since the parameter is passed by address, the address is of the storage where the indicator value should be placed. SQL-state This argument is a CHAR(5) value that represents the SQLSTATE.
This parameter is passed in from the database set to '00000' and can be set by the function as a result state for the function. While normally the SQLSTATE is not set by the function, it can be used to signal an error or warning to the database as follows:

01Hxx The function code detected a warning situation. This results in an SQL warning, Here xx may be one of several possible strings.

188

DB2 UDB for AS/400 SQL Programming V4R4

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

38xxx The function code detected an error situation. It results in a SQL error. Here xxx may be one of several possible strings.
See Appendix B for more information on valid SQLSTATEs that the function may use.

function-name This argument is set by DB2 before calling the UDF. It is a VARCHAR(139) value that contains the name of the function on whose behalf the function code is being invoked.
The form of the function name that is passed is:
<schema-name>.<function-name>

This parameter is useful when the function code is being used by multiple UDF denitions so that the code can distinguish which denition is being invoked. Note: This parameter is treated as input only; any changes to the parameter value made by the UDF are ignored by DB2.

specic-name This argument is set by DB2 before calling the UDF. It is a VARCHAR(128) value that contains the specic name of the function on whose behalf the function code is being invoked.
Like function-name, this parameter is useful when the function code is being used by multiple UDF denitions so that the code can distinguish which denition is being invoked. See the CREATE FUNCTION for more information about specic-name. Note: This parameter is treated as input only; any changes to the parameter value made by the UDF are ignored by DB2.

diagnostic-message This argument is set by DB2 before calling the UDF. It is a VARCHAR(70) value that can be used by the UDF to send message text back when an SQLSTATE warning or error is signaled by the UDF.
It is initialized by the database on input to the UDF and may be set by the UDF with descriptive information. Message text is ignored by DB2 unless the SQL-state parameter is set by the UDF.

Parameter style DB2SQL: With the DB2SQL parameter style, the same parameters and same order of parameters are passed into the external program or service program as are passed in for parameter style SQL. However, DB2SQL allows additional optional parameters to be passed along as well. If more than one of the optional parameters below is specied in the UDF denition, they are passed to the UDF in the order dened below. Refer to parameter style SQL for the common parameters.
SQL-result

SQL-argument

SQL-argument-ind

| | |

SQL-result-ind

SQL-state function-name

specific-name

diagnostic-message

Chapter 9. Writing User-Dened Functions (UDFs)

189

|
scratchpad call-type dbinfo

| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
SQL-result = func ( SQL-argument )

scratchpad This argument is set by DB2 before calling the UDF. It is only present if the CREATE FUNCTION statement for the UDF specied the SCRATCHPAD keyword. This argument is a structure with the following elements: v An INTEGER containing the length of the scratchpad. v The actual scratchpad, initialized to all binary 0s by DB2 before the rst call to the UDF.
The scratchpad can be used by the UDF either as working storage or as persistent storage, since it is maintained across UDF invocations.

call-type This argument is set by DB2 before calling the UDF. It is only present if the CREATE FUNCTION statement for the UDF specied the FINAL CALL keyword. It is an INTEGER value that contains one of the following values:
-1 0 1 This is the rst call to the UDF for this statement. A rst call is a normal call in that all SQL argument values are passed. This is a normal call. (All the normal input argument values are passed). This is a nal call. No SQL-argument or SQL-argument-ind values are passed. A UDF should not return any answer using the SQL-result or SQL-result-ind arguments. Both of these are ignored by DB2 upon return from the UDF. However, the UDF may set the SQL-state and diagnostic-message arguments. These arguments are handled in a way similar to other calls to the UDF.

dbinfo This argument is set by DB2 before calling the UDF. It is only present if the CREATE FUNCTION statement for the UDF species the DBINFO keyword. The argument is a structure whose denition is contained in the sqludf include. Parameter Style GENERAL (or SIMPLE CALL): With parameter style GENERAL, the parameters are passed into the external service program just as they are specied in the CREATE FUNCTION statement. The format is:

| | | | | | | | |

SQL-argument This argument is set by DB2 before calling the UDF. This value repeats n times, where n is the number of arguments specied in the function reference. The value of each of these arguments is taken from the expression specied in the function invocation. It is expressed in the data type of the dened parameter in the CREATE FUNCTION statement. Note: These parameters are treated as input only; any changes to the parameter values made by the UDF are ignored by DB2.

190

DB2 UDB for AS/400 SQL Programming V4R4

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

SQL-result This value is returned by the UDF. DB2 copies the value into database storage. In order to return the value correctly, the function code must be a value-returning function. The database copies only as much of the value as dened for the return value as specied on the CREATE FUNCTION statement. If the CAST FROM clause is used in the CREATE FUNCTION statement, DB2 assumes the UDF returns the value as dened in the CAST FROM clause, otherwise DB2 assumes the UDF returns the value as dened in the RETURNS clause.
In addition, in order to be returned correctly, the return value dened in the function code must be dened as a simple structure. For example, in C, to return an INTEGER, the function code would be dened as follows:
typedef struct { int rtnint; } rtnval_t; rtnval_t func1() { rtnval_t rtnval; . . return(rtnval); };

Note: The return value must be dened as a simple structure. If, instead, the function was dened as simply int func1(), the return value would not be available for DB2 to use. Because of the requirement that the function code be a value-returning function, any function code used for parameter style GENERAL must be created into a service program.

Parameter Style GENERAL WITH NULLS: With parameter style GENERAL WITH NULLS, the parameters are passed into the service program as follows (in the order specied):

SQL-result = funcname

( SQL-argument

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

SQL-result-ind ) SQL-argument-ind-array

SQL-argument This argument is set by DB2 before calling the UDF. This value repeats n times, where n is the number of arguments specied in the function reference. The value of each of these arguments is taken from the expression specied in the function invocation. It is expressed in the data type of the dened parameter in the CREATE FUNCTION statement. Note: These parameters are treated as input only; any changes to the parameter values made by the UDF are ignored by DB2. SQL-argument-ind-array This argument is set by DB2 before calling the UDF. It can be used by the UDF to determine if one or moreSQL-arguments are null or not. It is an
Chapter 9. Writing User-Dened Functions (UDFs)

191

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

array of two-byte signed integers (indicators). Thenth array argument corresponds corresponds to the nth SQL-argument. Each array entry is set to one of the following values: 0 -1 The argument is present and not null. The argument is null.

The UDF should check for null input. Note: This parameter is treated as input only; any changes to the parameter value made by the UDF is ignored by DB2.

SQL-result-ind This argument is set by the UDF before returning to DB2. The database provides the storage for the return value. The argument is dened as a two-byte signed integer. If set to a negative value, the database interprets the result of the function as null. If set to zero or a positive value, the database uses the value returned in SQL-result. The database provides the storage for the return value indicator. Since the parameter is passed by address, the address is of the storage where the indicator value should be placed. SQL-result This value is returned by the UDF. DB2 copies the value into database storage. In order to return the value correctly, the function code must be a value-returning function. The database copies only as much of the value as dened for the return value as specied on the CREATE FUNCTION statement. If the CAST FROM clause is used in the CREATE FUNCTION statement, DB2 assumes the UDF returns the value as dened in the CAST FROM clause, otherwise DB2 assumes the UDF returns the value as dened in the RETURNS clause.
In order to be returned correctly, the return value dened in the function code must be dened as a simple structure. For example, in C, to return an INTEGER, the function code would be dened as follows:
typedef struct { int rtnint; } rtnval_t; rtnval_t func1(short *parm1, short parmind[], short *rtnind) { rtnval_t rtnval; . . . return(rtnval); };

Note: The return value must be dened as a simple structure. If, instead, the function was dened as simply int func1(...), the return value would not be available for DB2 to use. Because of the requirement that the function code be a value-returning function, any function code used for parameter style GENERAL WITH NULLS must be created into a service program.

192

DB2 UDB for AS/400 SQL Programming V4R4

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

Examples of UDF code


These examples show how to implement UDF code by using SQL functions and external functions.

Example: Square of a number UDF


Suppose that you wanted a function that returns the square of a number. The query statement is:
SELECT SQUARE(myint) FROM mytable

The following examples show how to dene the UDF several different ways. v Using an SQL function
CREATE FUNCTION SQUARE( inval INT) RETURNS INT LANGUAGE SQL BEGIN RETURN(inval*inval); END

v Using an external function, parameter style SQL: The CREATE FUNCTION statement:
CREATE FUNCTION SQUARE(INT) RETURNS INT CAST FROM FLOAT LANGUAGE C EXTERNAL NAME 'MYLIB/MATH(SQUARE)' DETERMINISTIC NO SQL NO EXTERNAL ACTION PARAMETER STYLE SQL ALLOW PARALLEL

The code:
void SQUARE(int *inval, double *outval, short *inind, short *outind, char *sqlstate, char *funcname, char *specname, char *msgtext) { if (*inind<0) *outind=-1; else { *outval=*inval; *outval=(*outval)*(*outval); *outind=0; } return; }

To create the external service program so it can be debugged:


CRTCMOD MODULE(mylib/square) DBGVIEW(*SOURCE) CRTSRVPGM SRVPGM(mylib/math) MODULE(mylib/square) EXPORT(*ALL) ACTGRP(*CALLER)

v Using an external function, parameter style GENERAL: The CREATE FUNCTION statement:

Chapter 9. Writing User-Dened Functions (UDFs)

193

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

CREATE FUNCTION SQUARE(INT) RETURNS INT CAST FROM FLOAT LANGUAGE C EXTERNAL NAME 'MYLIB/MATH(SQUARE)' DETERMINISTIC NO SQL NO EXTERNAL ACTION PARAMETER STYLE GENERAL ALLOW PARALLEL

The code:
typedef struct { double outf; } outval_t; outval_t SQUARE(int *inval) { outval_t outval; outval.outf=*inval; outval.outf=(outval.outf)*(outval.outf); return(outval); }

To create the external service program so it can be debugged:


CRTCMOD MODULE(mylib/square) DBGVIEW(*SOURCE) CRTSRVPGM SRVPGM(mylib/math) MODULE(mylib/square) EXPORT(*ALL) ACTGRP(*CALLER)

Example: Counter
Suppose you want to simply number the rows in your SELECT statement. So you write a UDF which increments and returns a counter. This example uses an external function with DB2 SQL parameter style and a scratchpad.
CREATE FUNCTION COUNTER() RETURNS INT SCRATCHPAD NOT DETERMINISTIC NO SQL NO EXTERNAL ACTION LANGUAGE C PARAMETER STYLE DB2SQL EXTERNAL NAME 'MYLIB/MATH(ctr)' DISALLOW PARALLELISM; /* structure scr defines the passed scratchpad for the function "ctr" */ struct scr { long len; long countr; char not_used[96]; }; void ctr ( long *out, short *outnull, char *sqlstate, char *funcname, char *specname, char *mesgtext, struct scr *scratchptr) { *out = ++scratchptr->countr; *outnull = 0; return; /* /* /* /* /* /* /* output answer (counter) */ output NULL indicator */ SQL STATE */ function name */ specific function name */ message text insert */ scratch pad */

/* increment counter & copy out */

} /* end of UDF : ctr */

For this UDF, observe that: v It has no input SQL arguments dened, but returns a value. v It appends the scratchpad input argument after the four standard trailing arguments, namely SQL-state, function-name, specic-name, and message-text.

194

DB2 UDB for AS/400 SQL Programming V4R4

| | | | | | | |

v It includes a structure denition to map the scratchpad which is passed. v No input parameters are dened. This agrees with the code. v SCRATCHPAD is coded, causing DB2 to allocate, properly initialize and pass the scratchpad argument. v You have specied it to be NOT DETERMINISTIC, because it depends on more than the SQL input arguments, (none in this case). v You have correctly specied DISALLOW PARALLELISM, because correct functioning of the UDF depends on a single scratchpad.

Chapter 9. Writing User-Dened Functions (UDFs)

195

196

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 10. Dynamic SQL Applications


Dynamic SQL allows an application to dene and run SQL statements at program run time. An application that provides for dynamic SQL accepts as input (or builds) an SQL statement in the form of a character string. The application does not need to know what type of SQL statement it will run. The application: v Builds or accepts as input an SQL statement v Prepares the SQL statement for running v Runs the statement v Handles SQL return codes Interactive SQL (described in Chapter 19. Using Interactive SQL) is an example of a dynamic SQL program. SQL statements are processed and run dynamically by interactive SQL. Notes: 1. The run-time overhead is greater for statements processed using dynamic SQL than for static SQL statements. The additional process is similar to that required for precompiling, binding, and then running a program, instead of only running it. Therefore, only applications requiring the exibility of dynamic SQL should use it. Other applications should access data from the database using normal (static) SQL statements. 2. Programs that contain an EXECUTE or EXECUTE IMMEDIATE statement and that use a FOR READ ONLY clause to make a cursor read-only experience better performance because blocking is used to retrieve rows for the cursor. The ALWBLK(*ALLREAD) CRTSQLxxx option will imply a FOR READ ONLY declaration for all cursors that do not explicitly code FOR UPDATE OF or have positioned deletes or updates that refer to the cursor. Cursors with an implied FOR READ ONLY will benet from the second item in this list. Some dynamic SQL statements require use of address variables. RPG for AS/400 programs require the aid of PL/I, COBOL, C, or ILE RPG for AS/400 programs to manage the address variables. The examples in this chapter are PL/I examples. The following table shows all the statements supported by DB2 UDB for AS/400 and indicates if they can be used in a dynamic application. Note: In the following table, the numbers in the Dynamic SQL column correspond to the notes on the next page.
Table 22. List of SQL Statements Allowed in Dynamic Applications
SQL Statement ALTER TABLE BEGIN DECLARE SECTION CALL CLOSE COMMENT ON COMMIT CONNECT CREATE ALIAS
Copyright IBM Corp. 1997, 1999

Static SQL Y Y Y Y Y Y Y Y

Dynamic SQL Y N Y N Y Y N Y

197

Table 22. List of SQL Statements Allowed in Dynamic Applications (continued)


SQL Statement CREATE COLLECTION CREATE DISTINCT TYPE CREATE FUNCTION CREATE INDEX CREATE PROCEDURE CREATE SCHEMA CREATE TABLE CREATE VIEW DECLARE CURSOR DECLARE PROCEDURE DECLARE STATEMENT DECLARE VARIABLE DELETE DESCRIBE DESCRIBE TABLE DISCONNECT DROP END DECLARE SECTION EXECUTE EXECUTE IMMEDIATE FETCH FREE LOCATOR GRANT INCLUDE INSERT LABEL ON LOCK TABLE OPEN PREPARE RELEASE RENAME REVOKE ROLLBACK SELECT INTO SELECT statement SET CONNECTION SET OPTION SET PATH SET RESULT SETS SET TRANSACTION Static SQL Y Y Y Y Y N Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Dynamic SQL Y Y Y Y Y See Note 8. Y Y See Note 4. N N N Y See Note 7. N N Y N See Note 1. See Note 2. N Y Y N Y Y Y N See Note 3. N Y Y Y See Note 5. See Note 6. N See Note 9. Y N Y

198

DB2 UDB for AS/400 SQL Programming V4R4

Table 22. List of SQL Statements Allowed in Dynamic Applications (continued)


SQL Statement SET variable UPDATE VALUES INTO WHENEVER Static SQL Y Y Y Y Dynamic SQL N Y N N

Notes: 1. Cannot be prepared, but used to run prepared SQL statements. The SQL statement must be previously prepared by the PREPARE statement prior to using the EXECUTE statement. See example for PREPARE under Using the PREPARE and EXECUTE Statements on page 200. 2. Cannot be prepared, but used with dynamic statement strings that do not have any ? parameter markers. The EXECUTE IMMEDIATE statement causes the statement strings to be prepared and run dynamically at program run time. See example for EXECUTE IMMEDIATE under Processing Non-SELECT statements. 3. Cannot be prepared, but used to parse, optimize, and set up dynamic SELECT statements prior to running. See example for PREPARE under Processing Non-SELECT statements. 4. Cannot be prepared, but used to dene the cursor for the associated dynamic SELECT statement prior to running. 5. A SELECT INTO statement cannot be prepared or used in EXECUTE IMMEDIATE. 6. Cannot be used with EXECUTE or EXECUTE IMMEDIATE but can be prepared and used with OPEN. 7. Cannot be prepared, but used to return a description of a prepared statement. 8. Can only be run using the Run SQL Statements (RUNSQLSTM) command. 9. Can only be used when running a REXX procedure.

Designing and Running a Dynamic SQL Application


To issue a dynamic SQL statement, you must use the statement with either an EXECUTE statement or an EXECUTE IMMEDIATE statement, because dynamic SQL statements are not prepared at precompile time and therefore must be prepared at run time. The EXECUTE IMMEDIATE statement causes the SQL statement to be prepared and run dynamically at program run time. There are two basic types of dynamic SQL statements: SELECT statements and non-SELECT statements. Non-SELECT statements include such statements as DELETE, INSERT, and UPDATE. Client server applications that use interfaces such as ODBC typically use dynamic SQL to access the database. For more information on developing client server applications that use Client Access, see the Client Access for Windows 3.1 ODBC Users Guide.

Processing Non-SELECT statements


To build a dynamic SQL non-SELECT statement:
Chapter 10. Dynamic SQL Applications

199

1. Verify that the SQL statement you want to build is one that can be run dynamically (see Table 22 on page 197). 2. Build the SQL statement. (Use Interactive SQL for an easy way to build, verify, and run your SQL statement. See Chapter 19. Using Interactive SQL for more information.) To run a dynamic SQL non-SELECT statement: 1. Run the SQL statement using EXECUTE IMMEDIATE, or PREPARE the SQL statement, then EXECUTE the prepared statement. 2. Handle any SQL return codes that might result. The following is an example of an application running a dynamic SQL non-SELECT statement (stmtstrg):
EXEC SQL EXECUTE IMMEDIATE :stmtstrg;

CCSID of Dynamic SQL Statements


The SQL statement is normally a host variable. The CCSID of the host variable is used as the CCSID of the statement text. In PL/I, it also can be a string expression. In this case, the job CCSID is used as the CCSID of the statement text. Dynamic SQL statements are processed using the CCSID of the statement text. This affects variant characters the most. For example, the not sign () is located at 'BA'X in CCSID 500. This means that if the CCSID of your statement text is 500, SQL expects the not sign () to be located at 'BA'X. If the statement text CCSID is 65535, SQL processes variant characters as if they had a CCSID of 37. This means that SQL looks for the not sign () at '5F'X.

Using the PREPARE and EXECUTE Statements


If non-SELECT statements contain no parameter markers, they can be run dynamically using the EXECUTE IMMEDIATE statement. However, if the non-SELECT statements have parameter markers, they must be run using PREPARE and EXECUTE. The PREPARE statement prepares the non-SELECT statement (for example, the DELETE statement) and gives it a name of your choosing. If DLYPRP (*YES) is specied on the CRTSQLxxx command, the preparation is delayed until the rst time the statement is used in an EXECUTE or DESCRIBE statement, unless the USING clause is specied on the PREPARE statement. In this instance, let us call it S1. After the statement has been prepared, it can be run many times within the same program, using different values for the parameter markers. The following example is of a prepared statement being run multiple times:
DSTRING = 'DELETE FROM CORPDATA.EMPLOYEE WHERE EMPNO = ?'; /*The ? is a parameter marker which denotes that this value is a host variable that is to be substituted each time the statement is run.*/ EXEC SQL PREPARE S1 FROM :DSTRING; /*DSTRING is the delete statement that the PREPARE statement is naming S1.*/

200

DB2 UDB for AS/400 SQL Programming V4R4

DO UNTIL (EMP =0); /*The application program reads a value for EMP from the display station.*/ EXEC SQL EXECUTE S1 USING :EMP; END;

In routines similar to the example above, you must know the number of parameter markers and their data types, because the host variables that provide the input data are declared when the program is being written. Note: All prepared statements that are associated with an application server are destroyed whenever the connection to the application server ends. Connections are ended by a CONNECT (Type 1) statement, a DISCONNECT statement, or a RELEASE followed by a successful COMMIT.

Processing SELECT Statements and Using an SQLDA


There are two basic types of SELECT statements: xed-list and varying-list. To process a xed-list SELECT statement, an SQLDA is not necessary. To process a varying-list SELECT statement, you must rst declare an SQLDA structure. The SQLDA is a control block used to pass host variable input values from an application program to SQL and to receive output values from SQL. In addition, information about SELECT list expressions can be returned in a PREPARE or DESCRIBE statement.

Fixed-List SELECT Statements


In dynamic SQL, xed-list SELECT statements are those statements designed to retrieve data of a predictable number and type. When using these statements, you can anticipate and dene host variables to accommodate the retrieved data, so that an SQLDA is not necessary. Each successive FETCH returns the same number of values as the last, and these values have the same data formats as those returned for the last FETCH. You can specify host variables the same as you would for any SQL application. You can use xed-list dynamic SELECT statements with any SQL-supported application program. To run xed-list SELECT statements dynamically, your application must: 1. Place the input SQL statement into a host variable. 2. Issue a PREPARE statement to validate the dynamic SQL statement and put it into a form that can be run. If DLYPRP (*YES) is specied on the CRTSQLxxx command, the preparation is delayed until the rst time the statement is used in an EXECUTE or DESCRIBE statement, unless the USING clause is specied on the PREPARE statement. 3. Declare a cursor for the statement name. 4. Open the cursor. 5. FETCH a row into a xed list of variables (rather than into a descriptor area, as you would if you were using a varying-list SELECT statement, described in the following section, Varying-List Select-Statements).
Chapter 10. Dynamic SQL Applications

201

6. When end of data occurs, close the cursor. 7. Handle any SQL return codes that result. For example:
MOVE 'SELECT EMPNO, LASTNAME FROM CORPDATA.EMPLOYEE WHERE EMPNO>?' TO DSTRING. EXEC SQL PREPARE S2 FROM :DSTRING END-EXEC. EXEC SQL DECLARE C2 CURSOR FOR S2 END-EXEC. EXEC SQL OPEN C2 USING :EMP END-EXEC. PERFORM FETCH-ROW UNTIL SQLCODE NOT=0. EXEC SQL CLOSE C2 END-EXEC. STOP-RUN. FETCH-ROW. EXEC SQL FETCH C2 INTO :EMP, :EMPNAME END-EXEC.

Note: Remember that because the SELECT statement, in this case, always returns the same number and type of data items as previously run xed-list SELECT statements, you do not have to use the SQL descriptor area (SQLDA).

Varying-List Select-Statements
In dynamic SQL, varying-list SELECT statements are ones for which the number and format of result columns to be returned are not predictable; that is, you do not know how many variables you need, or what the data types are. Therefore, you cannot dene host variables in advance to accommodate the result columns returned. Note: In REXX, steps 5.b on page 203, 6 on page 203, and 7 on page 203 are not applicable. If your application accepts varying-list SELECT statements, your program has to: 1. Place the input SQL statement into a host variable. 2. Issue a PREPARE statement to validate the dynamic SQL statement and put it into a form that can be run. If DLYPRP (*YES) is specied on the CRTSQLxxx command, the preparation is delayed until the rst time the statement is used in an EXECUTE or DESCRIBE statement, unless the USING clause is specied on the PREPARE statement. 3. Declare a cursor for the statement name. 4. Open the cursor (declared in step 3) that includes the name of the dynamic SELECT statement. 5. Issue a DESCRIBE statement to request information from SQL about the type and size of each column of the result table. Notes: a. You can also code the PREPARE statement with an INTO clause to perform the functions of PREPARE and DESCRIBE with a single statement.

202

DB2 UDB for AS/400 SQL Programming V4R4

b. If the SQLDA is not large enough to contain column descriptions for each retrieved column, the program must determine how much space is needed, get storage for that amount of space, build a new SQLDA, and reissue the DESCRIBE statement. 6. Allocate the amount of storage needed to contain a row of retrieved data. 7. Put storage addresses into the SQLDA (SQL descriptor area) to tell SQL where to put each item of retrieved data. 8. FETCH a row. 9. When end of data occurs, close the cursor. 10. Handle any SQL return codes that might result.

The SQL Descriptor Area (SQLDA)


You can use the SQLDA to pass information about an SQL statement between SQL and your application. The SQLDA is a collection of variables required for running the DESCRIBE and DESCRIBE TABLE statements. It also can be used on the PREPARE, OPEN, FETCH, CALL, and EXECUTE statements. An SQLDA is used with dynamic SQL. It can be used in a DESCRIBE statement, changed with the addresses of host variables, and then reused in a FETCH statement. The meaning of the information in an SQLDA depends on its use. In PREPARE and DESCRIBE, an SQLDA provides information to an application program about a prepared statement. In DESCRIBE TABLE, the SQLDA provides information to an application program about the columns in a table or view. In OPEN, EXECUTE, CALL, and FETCH, an SQLDA provides information about host variables. SQLDA is required for: v DESCRIBE v DESCRIBE TABLE SQLDA is an option for: v EXECUTE v FETCH v OPEN v PREPARE v CALL If your application lets you have several cursors open at the same time, you can code several SQLDAs, one for each dynamic SELECT statement. For more information on SQLDA and SQLCA, see the DB2 UDB for AS/400 SQL Reference book. SQLDAs can be used in C, COBOL, PL/I, REXX, and RPG. Because RPG for AS/400 does not provide a way to set pointers, pointers must be set outside the RPG for AS/400 program by a PL/I, C, COBOL, or ILE RPG for AS/400 program. Since the area used must be declared by the PL/I, C, COBOL, or ILE RPG for AS/400 program, that program must call the RPG for AS/400 program.

Chapter 10. Dynamic SQL Applications

203

SQLDA Format
The SQLDA consists of four variables followed by an arbitrary number of occurrences of a sequence of six variables collectively named SQLVAR. Note: The SQLDA in REXX is different. For more information, see Chapter 17. Coding SQL Statements in REXX Applications. When an SQLDA is used in OPEN, FETCH, CALL, and EXECUTE, each occurrence of SQLVAR describes a host variable. The variables of SQLDA are as follows (variable names are in lowercase for C): SQLDAID SQLDAID is used for storage dumps. Byte 7 of SQLDAID is used to indicate if there are extension SQL VARs used for LOBs or UDTs. It is a string of 8 characters that have the value 'SQLDA' after the SQLDA that is used in a PREPARE or DESCRIBE statement. It is not used for FETCH, OPEN, CALL or EXECUTE. | | | Byte 7 can be used to determine if more than one SQLVAR entry is needed for each column. This ag is set to a blank if there are not any LOBs or distinct types. SQLDAID is not applicable in REXX. SQLDABC SQLDABC indicates the length of the SQLDA. It is a 4-byte integer that has the value SQLN*LENGTH(SQLVAR) + 16 after the SQLDA is used in a PREPARE or DESCRIBE statement. SQLDABC must have a value equal to or greater than SQLN*LENGTH(SQLVAR) + 16 prior to use by FETCH, OPEN, CALL, or EXECUTE. SQLABC is not applicable in REXX. SQLN SQLN is a 2-byte integer that species the total number of occurrences of SQLVAR. It must be set prior to use by any SQL statement to a value greater than or equal to 0. SQLN is not applicable in REXX. SQLD SQLD is a 2-byte integer that species the pertinent number of occurrences of SQLVAR; that is, the number of host variables described by the SQLDA. This eld is set by SQL on a DESCRIBE or PREPARE statement. In other statements, this eld must be set prior to use to a value greater than or equal to 0 and less than or equal to SQLN. SQLVAR The variables of SQLVAR are SQLTYPE, SQLLEN, SQLRES, SQLDATA, SQLIND, and SQLNAME. These variables are set by SQL on a DESCRIBE or PREPARE statement. In other statements, they must be set prior to use. These variables are dened as follows: SQLTYPE SQLTYPE is a 2-byte integer that species the data type of the host variable as shown in the table below. Odd values for SQLTYPE show that the host variable has an associated indicator variable addressed by SQLIND. SQLLEN SQLLEN is a 2-byte integer variable that species the length attributes of the host variables shown in Figure 10-2.

204

DB2 UDB for AS/400 SQL Programming V4R4

Table 23. SQLTYPE and SQLLEN Values for PREPARE, DESCRIBE, FETCH, OPEN, CALL, or EXECUTE
For PREPARE and DESCRIBE SQLTYPE 384/385 COLUMN DATA TYPE Date SQLLEN 10 For FETCH, OPEN, CALL, and EXECUTE HOST VARIABLE DATA TYPE Fixed-length character string representation of a date Fixed-length character string representation of a time Fixed-length character string representation of a timestamp SQLLEN Length attribute of the host variable Length attribute of the host variable Length attribute of the host variable N/A Length attribute of the host variable Length attribute of the host variable Not used.7 Not used.7 Not used.7 Length attribute of the host variable Length attribute of the host variable Length attribute of the host variable Length attribute of the host variable Length attribute of the host variable Length attribute of the host variable Length attribute of the host variable 4 for single precision, 8 for double precision Precision in byte 1; scale in byte 2 Precision in byte 1; scale in byte 2 4 2 Precision in byte 1; scale in byte 2

388/389

Time

392/393

Timestamp

26

| |

396/397 400/401 392/393

DataLink6 N/A Timestamp

Length attribute of N/A the column N/A 26 NUL-terminated graphic string Fixed-length character string representation of a timestamp BLOB CLOB DBCLOB

| | |

404/405 408/409 412/413 452/453 456/457 460/461 464/465 468/469 472/473 476/477 480/481

BLOB CLOB DBCLOB Fixed-length character string Long varying-length character string N/A Varying-length graphic string Fixed-length graphic string Long varying-length graphic string N/A Floating point

07 07 07

Length attribute of Fixed-length character the column string Length attribute of Long varying-length the column character string N/A NUL-terminated character string

Length attribute of Varying-length graphic the column string Length attribute of Fixed-length graphic string the column Length attribute of Long graphic string the column N/A 4 for single precision, 8 for double precision Precision in byte 1; scale in byte 2 Precision in byte 1; scale in byte 2 4 2
5 5

PASCAL L-string Floating point

484/485 488/489 496/497 500/501 504/505

Packed decimal Zoned decimal Large integer Small integer N/A

Packed decimal Zoned decimal Large integer Small integer DISPLAY SIGN LEADING SEPARATE

N/A

Chapter 10. Dynamic SQL Applications

205

Table 23. SQLTYPE and SQLLEN Values for PREPARE, DESCRIBE, FETCH, OPEN, CALL, or EXECUTE (continued)
For PREPARE and DESCRIBE SQLTYPE COLUMN DATA TYPE N/A N/A N/A N/A N/A N/A SQLLEN N/A N/A N/A N/A N/A N/A For FETCH, OPEN, CALL, and EXECUTE HOST VARIABLE DATA TYPE BLOB le reference variable CLOB le reference variable DBCLOB le reference variable BLOB locator CLOB locator DBCLOB locator SQLLEN 267 267 267 4 4 4

| | | | | | | | |

916/917 920/921 924/925 960/961 964/965 968/969

SQLRES SQLRES is a 12-byte reserved area for boundary alignment purposes. Note that, in OS/400, pointers must be on a quad-word boundary. SQLRES is not applicable in REXX. SQLDATA SQLDATA is a 16-byte pointer variable that species the address of the host variables when the SQLDA is used on OPEN, FETCH, CALL, and EXECUTE. When the SQLDA is used on PREPARE and DESCRIBE, this area is overlaid with the following information: The CCSID of a character, date, time, timestamp, and graphic eld is stored in the third and fourth bytes of SQLDATA. For BIT data, the CCSID is 65535. In REXX, the CCSID is returned in the variable SQLCCSID. SQLIND SQLIND is a 16-byte pointer that species the address of a small integer host variable that is used as an indication of null or not null when the SQLDA is used on OPEN, FETCH, CALL, and EXECUTE. A negative value indicates null and a non-negative indicates not null. This pointer is only used if SQLTYPE contains an odd value. When the SQLDA is used on PREPARE and DESCRIBE, this area is reserved for future use. SQLNAME SQLNAME is a variable-length character variable with a maximum length of 30, which contains the name of selected column, label, or system column name after a PREPARE or DESCRIBE. In OPEN, FETCH, EXECUTE, or CALL, it can be used to pass the CCSID of character strings. CCSIDs can be passed for character, graphic, date, time, and timestamp host variables. The SQLNAME eld in an SQLVAR array entry of an input SQLDA can be set to specify the CCSID:

5. Binary numbers can be represented in the SQLDA as either lengths 2 or 4, or with the precision in byte 1 and the scale in byte 2. If the rst byte is greater than X00, it indicates precision and scale. 6. The DataLink datatype is only returned on DESCRIBE TABLE. 7. The len.sqllonglen eld in the secondary SQLVAR contains the length attribute of the column.

206

DB2 UDB for AS/400 SQL Programming V4R4

Data Type Character Character Character GRAPHIC Any other data type

Sub-type SBCS MIXED BIT not applicable not applicable

Length of SQLNAME 8 8 8 8 not applicable

SQLNAME Bytes 1 & 2 X0000 X0000 X0000 X0000 not applicable

SQLNAME Bytes 3 & 4 CCSID CCSID XFFFF CCSID not applicable

Note: It is important to remember that the SQLNAME eld is only for overriding the CCSID. Applications that use the defaults do not need to pass CCSID information. If a CCSID is not passed, the default CCSID for the job is used. The default for graphic host variables is the associated double-byte CCSID for the job CCSID. If an associated double-byte CCSID does not exist, 65535 is used. | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | SQLVAR2 The Extended SQLVAR structure. Extended SQLVARs are only needed (for all columns of the result) if the result includes any LOB or distinct type columns. For distinct types, they contain the distinct type name. For LOBs, they contain the length attribute of the host variable and a pointer to the buffer that contains the actual length. If locators are used to represent LOBs, these entries are not necessary. The number of Extended SQLVAR occurrences needed depends on the statement that the SQLDA was provided for and the data types of the columns or parameters being described. Byte 7 of SQLDAID is always set to the number of sets of SQLVARs necessary. If SQLD is not set to a sufficient number of SQLVAR occurrences: v SQLD is set to the total number of SQLVAR occurrences needed for all sets. v A +237 warning is returned in the SQLCODE eld of the SQLCA if at least enough were specied for the Base SQLVAR Entries. The Base SQLVAR entries are returned, but no Extended SQLVARs are returned. v A +239 warning is returned in the SQLCODE eld of the SQLCA if enough SQLVARs were not specied for even the Base SQLVAR Entries. No SQLVAR entries are returned. SQLLONGLEN SQLLONGLEN is part of the Extended SQLVAR. It is a 4-byte integer variable that species the length attributes of a LOB (BLOB, CLOB, or DBCLOB) host variable. SQLDATALEN SQLDATALEN is part of the Extended SQLVAR. It is a 16-byte pointer variable that species the address of the length of the host variable. It is used for LOB (BLOB, CLOB, and DBCLOB) host variables only. If this eld is NULL, then the actual length is stored in the 4 bytes immediately before the start of the data, and SQLDATA points to the rst byte of the eld length. The actual length indicates the number of bytes for a BLOB or CLOB, and the number of characters for a DBCLOB. If this eld is not NULL, it contains a pointer to a 4-byte long buffer that contains the actual length in bytes (even for DBCLOB) of the data in the buffer pointed to from the SQLDATA eld in the matching base SQLVAR.
Chapter 10. Dynamic SQL Applications

207

| | | | | | | | | | |

SQLDATATYPE_NAME SQLDATATYPE_NAME is part of the Extended SQLVAR. It is a variable-length character variable with a maximum length of 30. It is set to one of the following: v For a distinct type column, the database manager sets this to the fully qualied distinct type name. v If the qualied name is longer than 30 bytes, it is truncated. v For a label, the database manager sets this to the rst 20 bytes of the label. For a column name, the database manager sets this to the column name.

Example of a Select-Statement for Allocating Storage for SQLDA


The SELECT statement can be read from a display station or from a host variable, or it can be developed within an application program. The following example shows a SELECT statement read from a display station:
SELECT WORKDEPT, PHONENO FROM CORPDATA.EMPLOYEE WHERE LASTNAME = 'PARKER'

Note: The SELECT statement has no INTO clause. Dynamic SELECT statements must not have an INTO clause, even if they return only one row. When the statement is read, it is assigned to a host variable. The host variable (for example, named DSTRING) is then processed, using the PREPARE statement, as shown:
EXEC SQL PREPARE S1 FROM :DSTRING;

Allocating Storage
You can allocate storage for the SQLDA. (Allocating storage is not necessary in REXX.) The techniques for acquiring storage are language dependent. The SQLDA must be allocated on a 16-byte boundary. The SQLDA consists of a xed-length header, 16 bytes long. The header is followed by a varying-length array section (SQLVAR), each element of which is 80 bytes in length. The amount of storage you need to allocate depends on how many elements you want to have in the SQLVAR array. Each column you select must have a corresponding SQLVAR array element. Therefore, the number of columns listed in your SELECT statement determines how many SQLVAR array elements you should allocate. Because SELECT statements are specied at run time, however, it is impossible to know how many columns will be accessed. Consequently, you must estimate the number of columns. Suppose, in this example, that no more than 20 columns are ever expected to be accessed by a single SELECT statement. This means that the SQLVAR array should have a dimension of 20 (for an SQLDA size 20 x 80, or 1600, plus 16 for a total of 1616 bytes), because each item in the select-list must have a corresponding entry in SQLVAR. Having allocated what you estimated to be enough space for your SQLDA in the SQLN eld of the SQLDA, set an initial value equal to the number of SQLVAR array elements. In the following example, set SQLN to 20:
Allocate space for an SQLDA of 1616 bytes on a quadword boundary SQLN = 20;

Note: In PL/I the ALLOCATE statement is the only way to ensure the allocation of a quadword boundary.

208

DB2 UDB for AS/400 SQL Programming V4R4

Having allocated storage, you can now issue a DESCRIBE statement.


EXEC SQL DESCRIBE S1 INTO :SQLDA;

When the DESCRIBE statement is run, SQL places values in the SQLDA that provide information about the select-list. The following Figure 9 shows the contents of the SQLDA after the DESCRIBE is run:
SQLDA Size SQLDA (8 bytes) 453 37 SQLVAR Element 1 (80 bytes) 8 0 WORKDEPT 3 1616 SQLDA (4 bytes) (reserved) 20 SQLN (2 bytes) 2 SQLD (2 bytes)

453 37 SQLVAR Element 2 (80 bytes) 7 0

(reserved)

P H O N E N O

RV3W188-0

Figure 9. Contents of SQLDA after a DESCRIBE Is Run

SQLDAID is an identier eld initialized by SQL when a DESCRIBE is run. SQLDABC is the byte count or size of the SQLDA. You can ignore these for now. The example for running the SELECT statement for S1 is:
SELECT WORKDEPT, PHONENO FROM CORPDATA.EMPLOYEE WHERE LASTNAME = 'PARKER'

Your program might have to alter the SQLN value if the SQLDA is not large enough to contain the described SQLVAR elements. For example, let the SELECT statement contain 27 select-list expressions instead of the 20 or less that you estimated. Because the SQLDA was only allocated with an SQLVAR dimension of 20 elements, SQL cannot describe the select-list, because the SQLVAR has too many elements. SQL sets the SQLD to the actual number of columns specied by the SELECT statement, and the remainder of the structure is ignored. Therefore, after a DESCRIBE, you should compare the SQLN to the SQLD. If the value of SQLD is greater than the value of SQLN, allocate a larger SQLDA based on the value in SQLD, as follows:
EXEC SQL DESCRIBE S1 INTO :SQLDA; IF SQLN <= SQLD THEN DO; /*Allocate a larger SQLDA using the value of SQLD.*/ /*Reset SQLN to the larger value.*/ EXEC SQL DESCRIBE S1 INTO :SQLDA; END;
Chapter 10. Dynamic SQL Applications

209

If you use DESCRIBE on a non SELECT statement, SQL sets SQLD to 0. Therefore, if your program is designed to process both SELECT and non SELECT statements, you can describe each statement (after it is prepared) to determine whether it is a SELECT statement. This sample routine is designed to process only SELECT statements; the SQLD is not checked. Your program must now analyze the elements of SQLVAR. Remember that each element describes a single select-list expression. Consider again the SELECT statement that is being processed:
SELECT WORKDEPT, PHONENO FROM CORPDATA.EMPLOYEE WHERE LASTNAME = 'PARKER'

The rst item in the select-list is WORKDEPT. At the beginning of this section, we identied that each SQLVAR element contains the elds SQLTYPE, SQLLEN, SQLRES, SQLDATA, SQLIND, and SQLNAME. SQL returns, in the SQLTYPE eld, a code that describes the data type of the expressions and whether nulls are applicable or not. For example, SQL sets SQLTYPE to 453 in SQLVAR element 1 (see Figure 9 on page 209). This species that WORKDEPT is a xed-length character string (CHAR) column and that nulls are permitted in the column. SQL sets SQLLEN to the length of the column. Because the data type of WORKDEPT is CHAR, SQL sets SQLLEN equal to the length of the character string. For WORKDEPT, that length is 3. Therefore, when the SELECT statement is later run, a storage area large enough to hold a CHAR(3) string is needed. Because the data type of WORKDEPT is CHAR FOR SBCS DATA, the rst 4 bytes of SQLDATA were set to the CCSID of the character column (see Figure 9 on page 209). The last eld in an SQLVAR element is a varying-length character string called SQLNAME. The rst 2 bytes of SQLNAME contain the length of the character data. The character data itself is usually the name of a column used in the SELECT statement (WORKDEPT in the above example.) The exceptions to this are select-list items that are unnamed, such as functions (for example, SUM(SALARY)), expressions (for example, A+BC), and constants. In these cases, SQLNAME is an empty string. SQLNAME can also contain a label rather than a name. One of the parameters associated with the PREPARE and DESCRIBE statements is the USING clause. You can specify it this way:
EXEC SQL DESCRIBE S1 INTO:SQLDA USING LABELS;

If you specify NAMES (or omit the USING parameter entirely), only column names are placed in the SQLNAME eld. If you specify SYSTEM NAMES, only the system column names are placed in the SQLNAME eld. If you specify LABELS, only labels associated with the columns listed in your SQL statement are entered here. If you specify ANY, labels are placed in the SQLNAME eld for those columns that have labels; otherwise, the column names are entered. If you specify BOTH, names and labels are both placed in the eld with their corresponding lengths. If you specify BOTH, however, you must remember to double the size of the SQLVAR array because you are including twice the number of elements. If you specify ALL, column names, labels, and system column names are placed in the eld with their corresponding lengths. If you specify ALL, remember to triple the size of the SQLVAR array. If you specify ALL: v Names, and labels are placed in the eld with their corresponding lengths.

210

DB2 UDB for AS/400 SQL Programming V4R4

v The size of the SQLVAR array must triple because you are including the number of elements. For more information on the USING option and on column labels, see the DB2 UDB for AS/400 SQL Reference book. In the example, the second SQLVAR element contains the information for the second column used in the select: PHONENO. The 453 code in SQLTYPE species that PHONENO is a CHAR column. For a CHAR data type of length 4, SQL sets SQLLEN to 4. After analyzing the result of the DESCRIBE, you can allocate storage for variables containing the result of the SELECT statement. For WORKDEPT, a character eld of length 3 must be allocated; for PHONENO, a character eld of length 4 must be allocated. After the storage is allocated, you must set SQLDATA and SQLIND to point to the appropriate areas. For each element of the SQLVAR array, SQLDATA points to the place where the results are to be put. SQLIND points to the place where the null indicator is to be put. The following gure shows what the structure looks like now:
SQLDA Size S 453 Q 3 L D A (reserved) 1616 20 2 FLDA: (CHAR(3))

Address of FLDA SQLVAR Element 1 (80 bytes) Address of FLDAI 8 WORKDEPT FLDB: (CHAR(4))

453 SQLVAR Element 2 (80 bytes)

(reserved)

Address of FLDB Address of FLDBI 7 P H O N E N O

Indicator Variables: (halfword) FLDAI: FLDBI:

RV3W189-0

This is what was done so far:


EXEC SQL INCLUDE SQLDA; /*Read a statement into the DSTRING varying-length character string host variable.*/ EXEC SQL PREPARE S1 FROM :DSTRING; /*Allocate an SQLDA of 1616 bytes.*/ SQLN =20; EXEC SQL DESCRIBE S1 INTO :SQLDA; /*Analyze the results of the DESCRIBE.*/ /*Allocate storage to hold one row of the result table.*/ /*Set SQLDATA and SQLIND for each column of the result table.*/

Chapter 10. Dynamic SQL Applications

211

Using a Cursor
You are now ready to retrieve the SELECT statements results. Dynamically dened SELECT statements must not have an INTO statement. Therefore, all dynamically dened SELECT statements must use a cursor. Special forms of the DECLARE, OPEN, and FETCH are used for dynamically dened SELECT statements. The DECLARE statement for the example statement is:
EXEC SQL DECLARE C1 CURSOR FOR S1;

As you can see, the only difference is that the name of the prepared SELECT statement (S1) is used instead of the SELECT statement itself. The actual retrieval of result rows is made as follows:
EXEC SQL OPEN C1; EXEC SQL FETCH C1 USING DESCRIPTOR :SQLDA; DO WHILE (SQLCODE = 0); /*Display ... the results pointed to by SQLDATA*/ END; /*Display ('END OF LIST')*/ EXEC SQL CLOSE C1;

The cursor is opened, and the result table is evaluated. Notice that there are no input host variables needed for the example SELECT statement. The SELECT result rows are then returned using FETCH. On the FETCH statement, there is no list of output host variables. Rather, the FETCH statement tells SQL to return results into areas described by the descriptor called SQLDA. The same SQLDA that was set up by DESCRIBE is now being used for the output of the SELECT statement. In particular, the results are returned into the storage areas pointed to by the SQLDATA and SQLIND elds of the SQLVAR elements. The following gure shows what the structure looks like after the FETCH statement has been processed.
SQLDA Size S 453 Q 3 L D A (reserved) 1616 20 2 FLDA: (CHAR(3)) E11

Address of FLDA SQLVAR Element 1 (80 bytes) Address of FLDAI 8 WORKDEPT FLDB: (CHAR(4)) 4502

453 SQLVAR Element 2 (80 bytes)

(reserved)

Address of FLDB Address of FLDBI 7 P H O N E N O

Indicator Variables: (halfword) FLDAI: FLDBI: 0 0

RV3W190-0

The meaning of the SMALLINT pointed to by SQLIND is the same as any other indicator variable:

212

DB2 UDB for AS/400 SQL Programming V4R4

0 <0 >0

Denotes that the returned value is not null. Denotes that the returned value is null. Denotes that the returned value was truncated because the storage area furnished was not large enough. The indicator variable contains the length before truncation.

Note: Unless HOLD is specied, dynamic cursors are closed during COMMIT or ROLLBACK.

Using Parameter Markers


In the example we are using, the SELECT statement that was dynamically run had predictable parameters (input host variables) in the WHERE clause. In the example, it was:
WHERE LASTNAME = 'PARKER'

If you want to run the same SELECT statement several times, using different values for LASTNAME, you can use an SQL statement such as PREPARE or EXECUTE (as described in Using the PREPARE and EXECUTE Statements on page 200) like this:
SELECT WORKDEPT, PHONENO FROM CORPDATA.EMPLOYEE WHERE LASTNAME = ?

When your parameters are not predictable, your application cannot know the number or types of the parameters until run time. You can arrange to receive this information at the time your application is run, and by using a USING DESCRIPTOR on the OPEN statement, you can substitute the values contained in specic host variables for the parameter markers included in the WHERE clause of the SELECT statement. To code such a program, you need to use the OPEN statement with the USING DESCRIPTOR clause. This SQL statement is used to not only open a cursor, but to replace each parameter marker with the value of the corresponding host variable. The descriptor name that you specify with this statement must identify an SQLDA that contains a valid description of those host variables. This SQLDA, unlike those previously described, is not used to return information on data items that are part of a SELECT list. That is, it is not used as output from a DESCRIBE statement, but as input to the OPEN statement. It provides information on host variables that are used to replace parameter markers in the WHERE clause of the SELECT statement. It gets this information from the application, which must be designed to place appropriate values into the necessary elds of the SQLDA. The SQLDA is then ready to be used as a source of information for SQL in the process of replacing parameter markers with host variable data. When you use the SQLDA for input to the OPEN statement with the USING DESCRIPTOR clause, not all of its elds have to be lled in. Specically, SQLDAID, SQLRES, and SQLNAME can be left blank (SQLNAME (SQLCCSID in REXX) can be set if a specic CCSID is needed.) Therefore, when you use this method for replacing parameter markers with host variable values, you need to determine: v How many ? parameter markers are there? v What are the data types and attributes of these parameters markers (SQLTYPE, SQLLEN, and SQLNAME)? v Do you want an indicator variable?

Chapter 10. Dynamic SQL Applications

213

In addition, if the routine is to handle both SELECT and non SELECT statements, you may want to determine what category of statement it is. (Alternatively, you can write code to look for the SELECT keyword.) If your application uses parameter markers, your program has to: 1. Read a statement into the DSTRING varying-length character string host variable. 2. Determine the number of ? parameter markers. 3. Allocate an SQLDA of that size. This is not applicable in REXX. 4. Set SQLN and SQLD to the number of ? parameter markers. SQLN is not applicable in REXX. 5. Set SQLDABC equal to SQLN*LENGTH(SQLVAR) + 16. This is not applicable in REXX. 6. For each ? parameter marker: a. Determine the data types, lengths, and indicators. b. Set SQLTYPE and SQLLEN. c. Allocate storage to hold the input values (the ? values). d. Set these values. e. Set SQLDATA and SQLIND (if applicable) for each ? parameter marker. f. If character variables are used, and they are in a CCSID other than the job default CCSID, set SQLNAME (SQLCCSID in REXX) accordingly. g. If graphic variables are used and they have a CCSID other than the associated DBCS CCSID for the job CCSID, set the SQLNAME (SQLCCSID in REXX) to that CCSID. h. Issue the OPEN statement with a USING DESCRIPTOR clause to open your cursor and substitute a host variable value for each of the parameter markers. The statement can then be processed normally.

214

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 11. Common Concepts and Rules for Using SQL with Host Languages
This chapter describes some concepts and rules that are common to using SQL statements in a host language that involve: v Using host variables in SQL statements v Handling SQL error and return codes v Handling exception conditions with the WHENEVER statement

Using Host Variables in SQL Statements


When your program retrieves data, the values are put into data items dened by your program and specied with the INTO clause of a SELECT INTO or FETCH statement. The data items are called host variables. A host variable is a eld in your program that is specied in an SQL statement, usually as the source or target for the value of a column. The host variable and column must be data type compatible. Host variables may not be used to identify SQL objects, such as tables or views, except in the DESCRIBE TABLE statement. A host structure is a group of host variables used as the source or target for a set of selected values (for example, the set of values for the columns of a row). A host structure array is an array of host structures used in the multiple-row FETCH and blocked INSERT statements. Note: By using a host variable instead of a literal value in an SQL statement, you give the application program the exibility it needs to process different rows in a table or view. For example, instead of coding an actual department number in a WHERE clause, you can use a host variable set to the department number you are currently interested in. Host variables are commonly used in SQL statements in these ways: 1. In a WHERE clause: You can use a host variable to specify a value in the predicate of a search condition, or to replace a literal value in an expression. For example, if you have dened a eld called EMPID that contains an employee number, you can retrieve the name of the employee whose number is 000110 with:
MOVE '000110' TO EMPID. EXEC SQL SELECT LASTNAME INTO :PGM-LASTNAME FROM CORPDATA.EMPLOYEE WHERE EMPNO = :EMPID END-EXEC.

2. As a receiving area for column values (named in an INTO clause): You can use a host variable to specify a program data area that is to contain the column values of a retrieved row. The INTO clause names one or more host variables that you want to contain column values returned by SQL. For example, suppose you are retrieving the EMPNO, LASTNAME, and WORKDEPT column values from rows in the CORPDATA.EMPLOYEE table. You could dene a host variable in your program to hold each column, then name the host variables with an INTO clause. For example:
Copyright IBM Corp. 1997, 1999

215

EXEC SQL SELECT EMPNO, LASTNAME, WORKDEPT INTO :CBLEMPNO, :CBLNAME, :CBLDEPT FROM CORPDATA.EMPLOYEE WHERE EMPNO = :EMPID END-EXEC.

In this example, the host variable CBLEMPNO receives the value from EMPNO, CBLNAME receives the value from LASTNAME, and CBLDEPT receives the value from WORKDEPT. 3. As a value in a SELECT clause: When specifying a list of items in the SELECT clause, you are not restricted to the column names of tables and views. Your program can return a set of column values intermixed with host variable values and literal constants. For example:
MOVE '000220' TO PERSON. EXEC SQL SELECT "A", LASTNAME, SALARY, :RAISE, SALARY + :RAISE INTO :PROCESS, :PERSON-NAME, :EMP-SAL, :EMP-RAISE, :EMP-TTL FROM CORPDATA.EMPLOYEE WHERE EMPNO = :PERSON END-EXEC.

The results are:


PROCESS A PERSON-NAME LUTZ EMP-SAL 29840 EMP-RAISE EMP-TTL 4476 34316

4. As a value in other clauses of an SQL statement: The SET clause in an UPDATE statement The VALUES clause in an INSERT statement The CALL statement For more information on these statements, see the DB2 UDB for AS/400 SQL Reference book.

Assignment Rules
SQL column values are set to (or assigned to) host variables during the running of FETCH and SELECT INTO statements. SQL column values are set from (or assigned from) host variables during the running of INSERT, UPDATE, and CALL statements. All assignment operations observe the following rules: v Numbers and strings are not compatible: Numbers cannot be assigned to string columns or string host variables. Strings cannot be assigned to numeric columns or numeric host variables. v All character and DBCS graphic strings are compatible with UCS-2 graphic columns if conversion is supported between the CCSIDs. All graphic strings are compatible if the CCSIDs are compatible. All numeric values are compatible. Conversions are performed by SQL whenever necessary. All character and DBCS graphic strings are compatible with UCS-2 graphic columns for assignment operations, if conversion is supported between the CCSIDs. For the CALL statement, character and DBCS graphic parameters are compatible with UCS-2 parameters if conversion is supported. v A null value cannot be assigned to a host variable that does not have an associated indicator variable.

216

DB2 UDB for AS/400 SQL Programming V4R4

v Different types of date/time values are not compatible. Dates are only compatible with dates or string representations of dates; times are only compatible with times or string representations of times; and timestamps are only compatible with timestamps or string representations of timestamps. A date can be assigned only to a date column, a character column, a DBCS-open or DBCS-either column or variable, or a character variable 8. The insert or update value of a date column must be a date or a string representation of a date. A time can be assigned only to a time column, a character column, a DBCS-open or DBCS-either column or variable, or a character variable. The insert or update value of a time column must be a time or a string representation of a time. A timestamp can be assigned only to a timestamp column, a character column, a DBCS-open or DBCS-either column or variable, or a character variable. The insert or update value of a timestamp column must be a timestamp or a string representation of a timestamp.

Rules for String Assignment


Rules regarding character string assignment are: v When a string is assigned to a column, the length of the string value must not be greater than the length attribute of the column. (Trailing blanks are normally included in the length of the string. However, for string assignment trailing blanks are not included in the length of the string.) v When a MIXED character result column is assigned to a MIXED column, the value of the MIXED character result column must be a valid MIXED character string. v When the value of a result column is assigned to a host variable and the string value of the result column is longer than the length attribute of the host variable, the string is truncated on the right by the necessary number of characters. If this occurs, SQLWARN0 and SQLWARN1 (in the SQLCA) are set to W. v When the value of a result column is assigned to a xed-length host variable or when the value of a host variable is assigned to a xed-length CHAR result column and the length of the string value is less than the length attribute of the target, the string is padded on the right with the necessary number of blanks. v When a MIXED character result column is truncated because the length of the host variable into which it was being assigned was less than the length of the string, the shift-in character at the end of the string is preserved. The result, therefore, is still a valid MIXED character string.

Rules for CCSIDs


CCSIDs must be considered when you assign one character or graphic value to another. This includes the assignment of host variables. The database manager uses a common set of system services for converting SBCS data, DBCS data, MIXED data, and graphic data. The rules for CCSIDs are as follows: v If the CCSID of the source matches the CCSID of the target, the value is assigned without conversion.

8. A DBCS-open or DBCS-either column or variable is a variable that was declared in the host language by including the denition of an externally described le. DBCS-open variables are also declared if the job CCSID indicates MIXED data, or the DECLARE VARIABLE statement is used and a MIXED CCSID or the FOR MIXED DATA clause is specied. See DECLARE VARIABLE in the DB2 UDB for AS/400 SQL Reference book. Chapter 11. Common Concepts and Rules for Using SQL with Host Languages

217

v If the sub-type for the source or target is BIT, the value is assigned without conversion. v If the value is either null or an empty string, the value is assigned without conversion. v If conversion is not dened between specic CCSIDs, the value is not assigned and an error message is issued. v If conversion is dened and needed, the source value is converted to the CCSID of the target before the assignment is performed. For more information on CCSIDs, see the International Application Development book.

Rules for Numeric Assignment


Rules regarding numeric assignment are: v The whole part of a number may be altered when converting it to oating-point. A single-precision oating-point eld can only contain seven decimal digits. Any whole part of a number that contains more than seven digits is altered due to rounding. A double-precision oating point eld can only contain 16 decimal digits. Any whole part of a number that contains more than 16 digits is altered due to rounding. v The whole part of a number is never truncated. If necessary, the fractional part of a number is truncated. If the number, as converted, does not t into the target host variable or column, a negative SQLCODE is returned. v Whenever a decimal, numeric, or binary number is assigned to a decimal, numeric, or binary column or host variable, the number is converted, if necessary, to the precision and scale of the target. The necessary number of leading zeros is added or deleted; in the fractional part of the number, the necessary number of trailing zeros is added, or the necessary number of trailing digits is eliminated. v When a binary or oating-point number is assigned to a decimal or numeric column or host variable, the number is rst converted to a temporary decimal or numeric number and then converted, if necessary, to the precision and scale of the target. When a halfword binary integer (SMALLINT) with 0 scale is converted to decimal or numeric, the temporary result has a precision of 5 and a scale of 0. When a fullword binary integer (INTEGER) is converted to decimal or numeric, the temporary result has a precision of 11 and a scale of 0. When a oating-point number is converted to decimal or numeric, the temporary result has a precision of 31 and the maximum scale that allows the whole part of the number to be represented without loss of either signicance or accuracy.

Rules for Date, Time, and Timestamp Assignment


When a date is assigned to a host variable, the date is converted to the string representation specied by the DATFMT and DATSEP parameters of the CRTSQLxxx command. Leading zeros are not omitted from any part of the date representation. The host variable must be a xed or variable-length character string variable with a length of at least 10 bytes for *USA, *EUR, *JIS, or *ISO date formats, 8 bytes for *MDY, *DMY, or *YMD date formats, or 6 bytes for the *JUL date format. If the length is greater than 10, the string is padded on the right with blanks. In ILE RPG, the host variable can also be a date variable.

218

DB2 UDB for AS/400 SQL Programming V4R4

When a time is assigned to a host variable, the time is converted to the string representation by the TIMFMT and TIMSEP parameters of the CRTSQLxxx command. Leading zeros are not omitted. The host variable must be a xed or variable-length character string variable. If the length of the host variable is greater than the string representation of the time, the string is padded on the right with blanks. v If the *USA format is used, the length of the host variable must not be less than 8. v If the *HMS, *ISO, *EUR, or *JIS format is used, the length of the host variable must be at least 8 bytes if seconds are to be included, and 5 bytes if only hours and minutes are needed. In this case, SQLWARN0 and SQLWARN1 (in the SQLCA) are set to W, and if an indicator variable is specied, it is set to the actual number of seconds truncated. In ILE RPG, the host variable can also be a time variable. When a timestamp is assigned to a host variable, the timestamp is converted to its string representation. Leading zeros are not omitted from any part. The host variable must be a xed or variable-length character string variable with a length of at least 19 bytes. If the length is less than 26, the host variable does not include all the digits of the microseconds. If the length is greater than 26, the host variable is padded on the right with blanks. In ILE RPG, the host variable can also be a timestamp variable.

Indicator Variables
An indicator variable is a halfword integer variable used to indicate whether its associated host variable has been assigned a null value: v If the value for the result column is null, SQL puts a -1 in the indicator variable. v If you do not use an indicator variable and the result column is a null value, a negative SQLCODE is returned. v If the value for the result column causes a data mapping error. SQL sets the indicator variable to 2. You can also use an indicator variable to verify that a retrieved string value has not been truncated. If truncation occurs, the indicator variable contains a positive integer that species the original length of the string. When the database manager returns a value from a result column, you can test the indicator variable. If the value of the indicator variable is less than zero, you know the value of the results column is null. When the database manager returns a null value, the host variable will be set to the default value for the result column. You specify an indicator variable (preceded by a colon) immediately after the host variable or immediately after the keyword INDICATOR. For example:
EXEC SQL SELECT COUNT(*), AVG(SALARY) INTO :PLICNT, :PLISAL:INDNULL FROM CORPDATA.EMPLOYEE WHERE EDLEVEL < 18 END-EXEC.

You can then test INDNULL to see if it contains a negative value. If it does, you know SQL returned a null value.

Chapter 11. Common Concepts and Rules for Using SQL with Host Languages

219

Always test for NULL in a column by using the IS NULL predicate. For example:
WHERE expression IS NULL

Do not test for NULL in this way:


MOVE -1 TO HUIND. EXEC SQL...WHERE column-name = :HUI :HUIND

The EQUAL predicate will always be evaluated as false when it compares a null value. The result of this example will select no rows.

Used with Host Structures


You can also specify an indicator structure (dened as an array of halfword integer variables) to support a host structure. If the results column values returned to a host structure can be null, you can add an indicator structure name to the host structure name. This allows SQL to notify your program about each null value returned to a host variable in the host structure. For example, in COBOL:
01 SAL-REC. 10 MIN-SAL PIC S9(6)V99 USAGE COMP-3. 10 AVG-SAL PIC S9(6)V99 USAGE COMP-3. 10 MAX-SAL PIC S9(6)V99 USAGE COMP-3. 01 SALTABLE. 02 SALIND PIC S9999 USAGE COMP-4 OCCURS 3 TIMES. 01 EDUC-LEVEL PIC S9999 COMP-4. ... MOVE 20 TO EDUC-LEVEL. ... EXEC SQL SELECT MIN(SALARY), AVG(SALARY), MAX(SALARY) INTO :SAL-REC:SALIND FROM CORPDATA.EMPLOYEE WHERE EDLEVEL>:EDUC-LEVEL END-EXEC.

In this example, SALIND is an array containing 3 values, each of which can be tested for a negative value. If, for example, SALIND(1) contains a negative value, then the corresponding host variable in the host structure (that is, MIN-SAL) is not changed for the selected row. In the above example, SQL selects the column values of the row into a host structure. Therefore, you must use a corresponding structure for the indicator variables to determine which (if any) selected column values are null.

Used to Set Null Values


You can use an indicator variable to set a null value in a column. When processing UPDATE or INSERT statements, SQL checks the indicator variable (if it exists). If it contains a negative value, the column value is set to null. If it contains a value greater than -1, the associated host variable contains a value for the column. For example, you can specify that a value be put in a column (using an INSERT or UPDATE statement), but you may not be sure that the value was specied with the input data. To provide the capability to set a column to a null value, you can write the following statement:

220

DB2 UDB for AS/400 SQL Programming V4R4

EXEC SQL UPDATE CORPDATA.EMPLOYEE SET PHONENO = :NEWPHONE:PHONEIND WHERE EMPNO = :EMPID END-EXEC.

When NEWPHONE contains other than a null value, set PHONEIND to zero by preceding the statement with:
MOVE 0 to PHONEIND.

Otherwise, to tell SQL that NEWPHONE contains a null value, set PHONEIND to a negative value, as follows:
MOVE -1 TO PHONEIND.

Handling SQL Error Return Codes


When an SQL statement is processed in your program, SQL places a return code in the SQLCODE and SQLSTATE elds. The return codes indicate the success or failure of the running of your statement. If SQL encounters an error while processing the statement, the SQLCODE is a negative number and SUBSTR(SQLSTATE,1,2) is not '00', '01', or '02'. If SQL encounters an exception but valid condition while processing your statement, the SQLCODE is a positive number and SUBSTR(SQLSTATE,1,2) is '01' or '02'. If your SQL statement is processed without encountering an error or warning condition, the SQLCODE is zero and the SQLSTATE is '00000'. Note: There are situations when a zero SQLCODE is returned to your program and the result might not be satisfactory. For example, if a value was truncated as a result of running your program, the SQLCODE returned to your program is zero. However, one of the SQL warning ags (SQLWARN1) indicates truncation. In this case, the SQLSTATE is not '00000'. Attention: If you do not test for negative SQLCODEs or specify a WHENEVER SQLERROR statement, your program will continue to the next statement. Continuing to run after an error can produce unpredictable results. The main purpose for SQLSTATE is to provide common return codes for common return conditions among the different IBM relational database systems. SQLSTATEs are particularly useful when handling problems with distributed database operations. For more information, see the DB2 UDB for AS/400 SQL Reference book. Because the SQLCA is a valuable problem-diagnosis tool, it is a good idea to include in your application programs the instructions necessary to display some of the information contained in the SQLCA. Especially important are the following SQLCA elds: SQLCODE SQLSTATE SQLERRD(3) SQLWARN0 Return code. Return code. The number of rows updated, inserted, or deleted by SQL. If set to W, at least one of the SQL warning ags (SQLWARN1 through SQLWARNA) is set.

Chapter 11. Common Concepts and Rules for Using SQL with Host Languages

221

For more information about the SQLCA, see Appendix B, SQL Communication Area in the DB2 UDB for AS/400 SQL Reference book. For a listing of DB2 UDB for AS/400 SQLCODEs and SQLSTATEs, see Appendix B.

Handling Exception Conditions with the WHENEVER Statement


The WHENEVER statement causes SQL to check the SQLSTATE and SQLCODE and continue processing your program, or branch to another area in your program if an error, exception, or warning exists as a result of running an SQL statement. An exception condition handling subroutine (part of your program) can then examine the SQLCODE or SQLSTATE eld to take an action specic to the error or exception situation. Note: The WHENEVER statement is not allowed in REXX procedures. For information on handling exception conditions in REXX, see Chapter 17. Coding SQL Statements in REXX Applications. The WHENEVER statement allows you to specify what you want to do whenever a general condition is true. You can specify more than one WHENEVER statement for the same condition. When you do this, the rst WHENEVER statement applies to all subsequent SQL statements in the source program until another WHENEVER statement is specied. The WHENEVER statement looks like this:
EXEC SQL WHENEVER condition action END-EXEC.

There are three conditions you can specify: SQLWARNING Specify SQLWARNING to indicate what you want done when SQLWARN0 = W or SQLCODE contains a positive value other than 100 (SUBSTR(SQLSTATE,1,2) =01). Note: SQLWARN0 could be set for several different reasons. For example, if the value of a column was truncated when it was moved into a host variable, your program might not regard this as an error. SQLERROR Specify SQLERROR to indicate what you want done when an error code is returned as the result of an SQL statement (SQLCODE < 0) (SUBSTR(SQLSTATE,1,2) > 02). Specify NOT FOUND to indicate what you want done when an SQLCODE of +100 and a SQLSTATE of '02000' is returned because: v After a single-row SELECT is issued or after the rst FETCH is issued for a cursor, the data the program species does not exist. v After a subsequent FETCH, no more rows satisfying the cursor select-statement are left to retrieve.

NOT FOUND

222

DB2 UDB for AS/400 SQL Programming V4R4

v After an UPDATE, a DELETE, or an INSERT, no row meets the search condition. You can also specify the action you want taken: CONTINUE GO TO label This causes your program to continue to the next statement. This causes your program to branch to an area in the program. The label for that area may be preceded with a colon. The WHENEVER ... GO TO statement: v Must be a section name or an unqualied paragraph name in COBOL v Is a label in PL/I and C v Is the label of a TAG in RPG

For example, if you are retrieving rows using a cursor, you expect that SQL will eventually be unable to nd another row when the FETCH statement is issued. To prepare for this situation, specify a WHENEVER NOT FOUND GO TO ... statement to cause SQL to branch to a place in the program where you issue a CLOSE statement in order to close the cursor properly. Note: A WHENEVER statement affects all subsequent source SQL statements until another WHENEVER is encountered. In other words, all SQL statements coded between two WHENEVER statements (or following the rst, if there is only one) are governed by the rst WHENEVER statement, regardless of the path the program takes. Because of this, the WHENEVER statement must precede the rst SQL statement it is to affect. If the WHENEVER follows the SQL statement, the branch is not taken on the basis of the value of the SQLCODE and SQLSTATE set by that SQL statement. However, if your program checks the SQLCODE or SQLSTATE directly, the check must be done after the SQL statement is run. The WHENEVER statement does not provide a CALL to a subroutine option. For this reason, you might want to examine the SQLCODE or SQLSTATE value after each SQL statement is run and call a subroutine, rather than use a WHENEVER statement.

Chapter 11. Common Concepts and Rules for Using SQL with Host Languages

223

224

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 12. Coding SQL Statements in C and C++ Applications


This chapter describes the unique application and coding requirements for embedding SQL statements in a C or C++ program. C program refers to ILE C for AS/400 programs. C++ program refers to ILE C++ programs or programs that are created with the VisualAge C++ for AS/400 compiler. This chapter also denes the requirements for host structures and host variables. A detailed sample C program, showing how SQL statements can be used, is provided in Appendix C. Sample Programs Using DB2 UDB for AS/400 Statements.

Dening the SQL Communications Area


A C or C++ program that contains SQL statements must include one or both of the following: v An SQLCODE variable declared as long SQLCODE v An SQLSTATE variable declared as char SQLSTATE[6] Or, v An SQLCA (which contains an SQLCODE and SQLSTATE variable). The SQLCODE and SQLSTATE values are set by the database manager after each SQL statement is executed. An application can check the SQLCODE or SQLSTATE value to determine whether the last SQL statement was successful. You can code the SQLCA in a C or C++ program either directly or by using the SQL INCLUDE statement. Using the SQL INCLUDE statement requests the inclusion of a standard declaration:
EXEC SQL INCLUDE SQLCA ;

A standard declaration includes both a structure denition and a static data area named 'sqlca'. The SQLCODE, SQLSTATE, and SQLCA variables must appear before any executable statements. The scope of the declaration must include the scope of all SQL statements in the program. The included C and C++ source statements for the SQLCA are:
#ifndef SQLCODE struct sqlca { unsigned char sqlcaid[8]; long sqlcabc; long sqlcode; short sqlerrml; unsigned char sqlerrmc[70]; unsigned char sqlerrp[8]; long sqlerrd[6]; unsigned char sqlwarn[11]; unsigned char sqlstate[5]; }; #define SQLCODE sqlca.sqlcode #define SQLWARN0 sqlca.sqlwarn[0] #define SQLWARN1 sqlca.sqlwarn[1] #define SQLWARN2 sqlca.sqlwarn[2] #define SQLWARN3 sqlca.sqlwarn[3]
Copyright IBM Corp. 1997, 1999

225

#define SQLWARN4 sqlca.sqlwarn[4] #define SQLWARN5 sqlca.sqlwarn[5] #define SQLWARN6 sqlca.sqlwarn[6] #define SQLWARN7 sqlca.sqlwarn[7] #define SQLWARN8 sqlca.sqlwarn[8] #define SQLWARN9 sqlca.sqlwarn[9] #define SQLWARNA sqlca.sqlwarn[10] #define SQLSTATE sqlca.sqlstate #endif struct sqlca sqlca;

When a declare for SQLCODE is found in the program and the precompiler provides the SQLCA, SQLCADE replaces SQLCODE. When a declare for SQLSTATE is found in the program and the precompiler provides the SQLCA, SQLSTOTE replaces SQLSTATE. Note: Many SQL error messages contain message data that is of varying length. The lengths of these data elds are embedded in the value of the SQLCA sqlerrmc eld. Because of these lengths, printing the value of sqlerrmc from a C or C++ program might give unpredictable results. For more information on SQLCA, see Appendix B, SQL Communication Area in the DB2 UDB for AS/400 SQL Reference book.

Dening SQL Descriptor Areas


The following statements require an SQLDA: EXECUTE...USING DESCRIPTOR descriptor-name FETCH...USING DESCRIPTOR descriptor-name OPEN...USING DESCRIPTOR descriptor-name DESCRIBE statement-name INTO descriptor-name DESCRIBE TABLE host-variable INTO descriptor-name PREPARE statement-name INTO descriptor-name CALL...USING DESCRIPTOR descriptor-name Unlike the SQLCA, more than one SQLDA can be in the program, and an SQLDA can have any valid name. You can code an SQLDA in a C or C++ program either directly or by using the SQL INCLUDE statement. Using the SQL INCLUDE statement requests the inclusion of a standard SQLDA declaration:
EXEC SQL INCLUDE SQLDA;

A standard declaration includes only a structure denition with the name sqlda. C and C++ declarations that are included for the SQLDA are:
#ifndef SQLDASIZE struct sqlda { unsigned char sqldaid[8]; long sqldabc; short sqln; short sqld; struct sqlvar { short sqltype; short sqllen; unsigned char *sqldata; short *sqlind; struct sqlname {

226

DB2 UDB for AS/400 SQL Programming V4R4

} sqlvar[1]; }; #define SQLDASIZE(n) (sizeof(struct sqlda) + (n-1)* sizeof(struct sqlvar)) #endif

short length; unsigned char data[30]; } sqlname;

One benet from using the INCLUDE SQLDA SQL statement is that you also get the following macro denition:
#define SQLDASIZE(n) (sizeof(struct sqlda) + (n-1)* sizeof(struc sqlvar))

This macro makes it easy to allocate storage for an SQLDA with a specied number of SQLVAR elements. In the following example, the SQLDASIZE macro is used to allocate storage for an SQLDA with 20 SQLVAR elements.
#include <stdlib.h> EXEC SQL INCLUDE SQLDA; struct sqlda *mydaptr; short numvars = 20; . . mydaptr = (struct sqlda *) malloc(SQLDASIZE(numvars)); mydaptr->sqln = 20;

When you have declared an SQLDA as a pointer, you must reference it exactly as declared when you use it in an SQL statement, just as you would for a host variable that was declared as a pointer. To avoid compiler errors, the type of the value that is assigned to the sqldata eld of the SQLDA must be a pointer of unsigned character. This helps avoid compiler errors. The type casting is only necessary for the EXECUTE, OPEN, CALL, and FETCH statements where the application program is passing the address of the host variables in the program. For example, if you declared a pointer to an SQLDA called mydaptr, you would use it in a PREPARE statement as:
EXEC SQL PREPARE mysname INTO :*mydaptr FROM :mysqlstring;

SQLDA declarations can appear wherever a structure denition is allowed. Normal C scope rules apply. Dynamic SQL is an advanced programming technique described in Chapter 10. Dynamic SQL Applications. With dynamic SQL, your program can develop and then run SQL statements while the program is running. A SELECT statement with a variable SELECT list (that is a list of the data to be returned as part of the query) that runs dynamically requires an SQL descriptor area (SQLDA). This is because you will not know in advance how many or what type of variables to allocate in order to receive the results of the SELECT. For more information on the SQLDA, see the DB2 UDB for AS/400 SQL Reference book.

Embedding SQL Statements


An SQL statement can be placed wherever a C or C++ statement that can be run can be placed.

Chapter 12. Coding SQL Statements in C and C++ Applications

227

Each SQL statement must begin with EXEC SQL and end with a semicolon (;). The EXEC SQL keywords must be on one line. The remaining part of the SQL statement can be on more than one line.

Example: An UPDATE statement coded in a C or C++ program might be coded in the following way:
EXEC SQL UPDATE DEPARTMENT SET MGRNO = :MGR_NUM WHERE DEPTNO = :INT_DEPT ;

Comments
In addition to using SQL comments (--), you can include C comments (/*...*/) within embedded SQL statements whenever a blank is allowed, except between the keywords EXEC and SQL. Comments can span any number of lines. You cannot nest comments. You can use single-line comments (comments that start with //) in C++, but you cannot use them in C.

Continuation for SQL Statements


SQL statements can be contained on one or more lines. You can split an SQL statement wherever a blank can appear. The backslash (\) can be used to continue a string constant or delimited identier. Constants containing DBCS data may be continued across multiple lines in two ways: v If the character at the right margin of the continued line is a shift-in and the character at the left margin of the continuation line is a shift-out, then the shift characters located at the left and right margin are removed. This SQL statement has a valid graphic constant of G<AABBCCDDEEFFGGHHIIJJKK>. The redundant shifts at the margin are removed.
*...+....1....+....2....+....3....+....4....+....5....+....6....+....7....*....8 EXEC SQL SELECT * FROM GRAPHTAB WHERE GRAPHCOL = G'<AABBCCDDEEFFGGHH> <IIJJKK>';

v If you are not using the default margins of 1 and 80, it is possible to place the shift characters outside of the margins. For this example, assume the margins are 5 and 75. This SQL statement has a valid graphic constant of G<AABBCCDDEEFFGGHHIIJJKK>.
*...(....1....+....2....+....3....+....4....+....5....+....6....+....7....)....8 EXEC SQL SELECT * FROM GRAPHTAB WHERE GRAPHCOL = G'<AABBCCDD> <EEFFGGHHIIJJKK>';

Including Code
You can include SQL statements, C, or C++ statements by embedding the following SQL statement in the source code:
EXEC SQL INCLUDE member-name;

You cannot use C and C++ #include statements to include SQL statements or declarations of C or C++ host variables that are referred to in SQL statements.

228

DB2 UDB for AS/400 SQL Programming V4R4

Margins
You must code SQL statements within the margins that are specied by the MARGINS parameter on the CRTSQLCI, CRTSQLCPPI, or CVTSQLCPP command. If EXEC SQL does not start within the specied margins, the SQL precompiler does not recognize the SQL statement. For more information about CRTSQLCI, CRTSQLCPPI, and CVTSQLCPP, see Appendix D. DB2 UDB for AS/400 CL Command Descriptions.

Names
You can use any valid C or C++ variable name for a host variable. It is subject to the following restrictions: Do not use host variable names or external entry names that begin with 'SQL', 'RDI', or 'DSN' in any combination of uppercase or lowercase letters. These names are reserved for the database manager. The length of host variable names is limited to 64.

NULLs and NULs


C, C++, and SQL use the word null, but for different meanings. The C and C++ languages have a null character (NUL), a null pointer (NULL), and a null statement (just a semicolon). The C NUL is a single character that compares equal to 0. The C NULL is a special reserved pointer value that does not point to any valid data object. The SQL null value is a special value that is distinct from all nonnull values and denotes the absence of a (non-null) value.

Statement Labels
Executable SQL statements can be preceded with a label.

Preprocessor Sequence
You must run the SQL preprocessor before the C or C++ preprocessor. You cannot use C or C++ preprocessor directives within SQL statements.

Trigraphs
Some characters from the C and C++ character set are not available on all keyboards. You can enter these characters into a C or C++ source program by using a sequence of three characters that is called a trigraph. The following trigraph sequences are supported within host variable declarations: v ??( left bracket v ??) right bracket v ??< left brace v ??> right brace v ??= pound v ??/ backslash

Chapter 12. Coding SQL Statements in C and C++ Applications

229

WHENEVER Statement
The target for the GOTO clause in an SQL WHENEVER statement must be within the scope of any SQL statements affected by the WHENEVER statement.

Using Host Variables


All host variables used in SQL statements must be explicitly declared. A host variable used in an SQL statement must be declared prior to the rst use of the host variable in an SQL statement. In C, the C statements that are used to dene the host variables should be preceded by a BEGIN DECLARE SECTION statement and followed by an END DECLARE SECTION statement. If a BEGIN DECLARE SECTION and END DECLARE SECTION are specied, all host variable declarations used in SQL statements must be between the BEGIN DECLARE SECTION and the END DECLARE SECTION statements. In C++, the C++ statements that are used to dene the host variables must be preceded by a BEGIN DECLARE SECTION statement and followed by an END DECLARE SECTION statement. You cannot use any variable that is not between the BEGIN DECLARE SECTION statement and the END DECLARE SECTION statement as a host variable. All host variables within an SQL statement must be preceded by a colon (:). The names of host variables must be unique within the program, even if the host variables are in different blocks or procedures. An SQL statement that uses a host variable must be within the scope of the statement in which the variable was declared. Host variables cannot be union elements.

Declaring Host Variables


The C and C++ precompilers recognize only a subset of valid C and C++ declarations as valid host variable declarations.

Numeric Host Variables


The following gure shows the syntax for valid numeric host variable declarations.

230

DB2 UDB for AS/400 SQL Programming V4R4

Numeric
auto extern static const volatile

float double decimal ( precision , scale signed long short int

, variable-name = expression ;

Notes: 1. Precision and scale must be integer constants. Precision may be in the range from 1 to 31. Scale may be in the range from 0 to the precision. 2. If using the decimal data type, the header le decimal.h must be included.

Character Host Variables


There are three valid forms for character host variables: v Single-character form v NUL-terminated character form v VARCHAR structured form All character types are treated as unsigned.

Single-Character Form
char auto extern static const volatile unsigned signed

, variable-name [ 1 ] = expression ;

Chapter 12. Coding SQL Statements in C and C++ Applications

231

NUL-Terminated Character Form


char auto extern static const volatile unsigned signed

, variable-name [ length ] = expression ;

Notes: 1. The length must be an integer constant that is greater than 1 and not greater than 32741. 2. If the *CNULRQD option is specied on the CRTSQLCI, CRTSQLCPPI, or CVTSQLCPP command, the input host variables must contain the NUL-terminator. Output host variables are padded with blanks, and the last character is the NUL-terminator. If the output host variable is too small to contain both the data and the NUL-terminator, the following actions are taken: v The data is truncated v The last character is the NUL-terminator v SQLWARN1 is set to W 3. If the *NOCNULRQD option is specied on the CRTSQLCI, CRTSQLCPPI, or CVTSQLCPP command, the input variables do not need to contain the NUL-terminator. The following applies to output host variables. v If the host variable is large enough to contain the data and the NUL-terminator, then the following actions are taken: The data is returned, but the data is not padded with blanks The NUL-terminator immediately follows the data v If the host variable is large enough to contain the data but not the NUL-terminator, then the following actions are taken: The data is returned A NUL-terminator is not returned SQLWARN1 is set to N v If the host variable is not large enough to contain the data, the following actions are taken: The data is truncated A NUL-terminator is not returned SQLWARN1 is set to W

232

DB2 UDB for AS/400 SQL Programming V4R4

VARCHAR Structured Form


struct auto extern static const volatile _Packed tag {

short signed int

var-1 ; unsigned signed

char var-2 [

length ]

, variable-name = { expression , expression } ;

Notes: 1. length must be an integer constant that is greater than 0 and not greater than 32740. 2. var-1 and var-2 must be simple variable references and cannot be used individually as integer and character host variables. 3. The struct tag can be used to dene other data areas, but these cannot be used as host variables. 4. The VARCHAR structured form should be used for bit data that may contain the NULL character. The VARCHAR structured form will not be ended using the nul-terminator.

Example:
EXEC SQL BEGIN DECLARE SECTION; /* valid declaration of host variable vstring */ struct VARCHAR { short len; char s[10]; } vstring; /* invalid declaration of host variable wstring */ struct VARCHAR wstring;

Graphic host variables


There are three valid forms for graphic host variables: v Single-graphic form v NUL-terminated graphic form v VARGRAPHIC structured form

Chapter 12. Coding SQL Statements in C and C++ Applications

233

Single-Graphic Form
wchar_t auto extern static const volatile

, variable-name = expression ;

NUL-Terminated Graphic Form


wchar_t auto extern static const volatile

, variable-name [ length ] = expression ;

Notes: 1. length must be an integer constant that is greater than 1 and not greater than 16371. 2. If the *CNULRQD option is specied on the CRTSQLCI, CRTSQLCPPI, or CVTSQLCPP command, then input host variables must contain the graphic NUL-terminator (/0/0). Output host variables are padded with DBCS blanks, and the last character is the graphic NUL-terminator. If the output host variable is too small to contain both the data and the NUL-terminator, the following actions are taken: v The data is truncated v The last character is the graphic NUL-terminator v SQLWARN1 is set to W If the *NOCNULRQD option is specied on the CRTSQLCI, CRTSQLCPPI, or CVTSQLCPP command, the input host variables do not need to contain the graphic NUL-terminator. The following is true for output host variables. v If the host variable is large enough to contain the data and the graphic NUL-terminator, the following actions are taken: The data is returned, but is not padded with DBCS blanks The graphic NUL-terminator immediately follows the data

234

DB2 UDB for AS/400 SQL Programming V4R4

v If the host variable is large enough to contain the data but not the graphic NUL-terminator, the following actions are taken: The data is returned A graphic NUL-terminator is not returned SQLWARN1 is set to N v If the host variable is not large enough to contain the data, the following actions are taken: The data is truncated A graphic NUL-terminator is not returned SQLWARN1 is set to W

VARGRAPHIC Structured Form


struct auto extern static const volatile _Packed tag {

short signed , variable-name = { int

var-1 ;

wchar_t var-2 [ length ]

; expression , expression }

Notes: 1. length must be an integer constant that is greater than 0 and not greater than 16370. 2. var-1 and var-2 must be simple variable references and cannot be used as host variables. 3. The struct tag can be used to dene other data areas, but these cannot be used as host variables.

Example:
EXEC SQL BEGIN DECLARE SECTION; /* valid declaration of host variable graphic string */ struct VARGRAPH { short len; wchar_t s[10]; } vstring; /* invalid declaration of host variable wstring */ struct VARGRAPH wstring;

Chapter 12. Coding SQL Statements in C and C++ Applications

235

| | | | |

LOB Host Variables


LOB Host Variable
SQL TYPE IS auto extern static const volatile BLOB CLOB DBCLOB

| |

lob-length K M

| |

, variable-name = = = = { init-len,init-data } SQL_BLOB_INIT(init-data) SQL_CLOB_INIT(init-data) SQL_DBCLOB_INIT(init-data) ;

| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Notes: 1. The SQL TYPE IS clause is needed in order to distinguish the three LOB-types from each other so that type-checking and function resolution can be carried out for LOB-type host variables that are passed to functions. 2. For BLOB and CLOB, 1 <= lob-length <= 15,728,640 3. For DBCLOB, 1 <= lob-length <= 7,864,320 4. SQL TYPE IS, BLOB, CLOB, DBCLOB, K, M can be in mixed case. 5. The maximum length allowed for the initialization string is 32,766 bytes. 6. The initialization length, init-len, must be a numeric constant (that is, it cannot include K, M, or G). 7. A length for the LOB must be specied; that is, the following declaration is not permitted
SQL TYPE IS BLOB my_blob;

8. If the LOB is not initialized within the declaration, then no initialization will be done within the precompiler generated code. 9. The precompiler generates a structure tag which can be used to cast to the host variables type. 10. LOB Host Variables can be declared in host structures and host structure arrays. 11. Pointers to LOB Host Variables can be declared, with the same rules and restrictions as for pointers to other host variable types. 12. CCSID processing for LOB Host Variables will be the same as the processing for other character and graphic host variable types. 13. If a DBCLOB is initialized, it is the users responsibility to prex the string with an L (indicating a wide-character string).

BLOB Example

236

DB2 UDB for AS/400 SQL Programming V4R4

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

The following declaration:


static SQL TYPE IS BLOB(128K) my_blob=SQL_BLOB_INIT("mydata");

Results in the generation of the following structure:


static struct my_blob_t { unsigned long length; char data[131072]; } my_blob=SQL_BLOB_INIT("my_data");

CLOB Example
The following declaration:
auto SQL TYPE IS CLOB(128K) var1, var2 = {10, "data2data2"};

Results in the generation of the following structure:


auto struct var1_t { unsigned long length; char data[131072]; } var1, var2 = {10, "data2data2"};

DBCLOB Example
The following declaration:
auto SQL TYPE IS DBCLOB(128K) my_dbclob;

Results in the generation of the following structure:


auto struct my_dbclob_t { unsigned long length; wchar_t data[131072]; } my_dbclob;

LOB Locators
LOB Locator
SQL TYPE IS auto extern static const volatile BLOB_LOCATOR CLOB_LOCATOR DBCLOB_LOCATOR

| |

, variable-name = init-value ;

|| | | | | | | | Notes: 1. SQL TYPE IS, BLOB_LOCATOR, CLOB_LOCATOR, DBCLOB_LOCATOR can be in mixed case. 2. init-value permits the initialization of pointer locator variables. Other types of initialization will have no meaning. 3. LOB Locators can be declared in host structures and host structure arrays.
Chapter 12. Coding SQL Statements in C and C++ Applications

237

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

4. Pointers to LOB Locators can be declared, with the same rules and restrictions as for pointers to other host variable types.

CLOB Locator Example


The following declaration:
static SQL TYPE IS CLOB_LOCATOR my_locator;

Results in the generation of the following structure:


static long int unsigned my_locator;

BLOB and DBCLOB locators have similar syntax.

LOB File Reference Variables


LOB File Reference Variable
SQL TYPE IS auto extern static const volatile BLOB_FILE CLOB_FILE DBCLOB_FILE

| |

, variable-name = init-value ;

| | | | | | | | | | | | | | | | | | | | | | Notes: 1. SQL TYPE IS, BLOB_FILE, CLOB_FILE, DBCLOB_FILE can be in mixed case. 2. LOB File Reference Variables can be declared as part of a host structure. 3. Pointers to LOB File Reference Variables can be declared, with the same rules and restrictions as for pointers to other host variable types.

CLOB File Reference Example


The following declaration:
static SQL TYPE IS CLOB_FILE my_file;

Results in the generation of the following structure:


static struct unsigned unsigned unsigned } my_file; { long long long char name_length; data_length; file_options; name[255];

BLOB and DBCLOB le reference variables have similar syntax. The pre-compiler will generate declarations for the following le option constants: v SQL_FILE_READ (2) v SQL_FILE_CREATE (8)

238

DB2 UDB for AS/400 SQL Programming V4R4

| | |

v SQL_FILE_OVERWRITE (16) v SQL_FILE_APPEND (32)

Using Host Structures


In C and C++ programs, you can dene a host structure, which is a named set of elementary C or C++ variables. Host structures have a maximum of two levels, even though the host structure might itself occur within a multilevel structure. An exception is the declaration of a varying-length string, which requires another structure. A host structure name can be a group name whose subordinate levels name elementary C or C++ variables. For example:
struct { struct { char c1; char c2; } b_st;

} a_st;

In this example, b_st is the name of a host structure consisting of the elementary items c1 and c2. You can use the structure name as a shorthand notation for a list of scalars, but only for a two-level structure. You can qualify a host variable with a structure name (for example, structure.eld). Host structures are limited to two levels. (For example, in the above host structure example, the a_st cannot be referred to in SQL.) A structure cannot contain an intermediate level structure. In the previous example, a_st could not be used as a host variable or referred to in an SQL statement. A host structure for SQL data has two levels and can be thought of as a named set of host variables. After the host structure is dened, you can refer to it in an SQL statement instead of listing the several host variables (that is, the names of the host variables that make up the host structure). For example, you can retrieve all column values from selected rows of the table CORPDATA.EMPLOYEE with:
struct { char empno[7]; struct char midint, struct { short int firstname_len; char firstname_text[12]; } firstname;

..... strcpy("000220",pemp1.empno); ..... exec sql select * into :pemp1 from corpdata.employee where empno=:pemp1.empno;

{ short int lastname_len; char lastname_text[15]; } lastname; char workdept[4]; } pemp1;

Notice that in the declaration of pemp1, two varying-length string elements are included in the structure: rstname and lastname.

Chapter 12. Coding SQL Statements in C and C++ Applications

239

Host Structure Declarations


The following gure shows the valid syntax for host structure declarations.

Host Structures
struct auto extern static const volatile _Packed tag {

, float double decimal ( precision , long signed short varchar-structure vargraphic-structure , char signed unsigned , wchar_t var-5 [ , variable-name = expression ; length ] ; var-2 [ length ] scale int var-1 ) ; }

varchar-structure:
struct tag { signed short int var-3 ; signed unsigned

char

var-4

length ]

vargraphic-structure:
struct tag var-6 ; { signed length ] short int ; }

wchar_t var-7 [

Note:

240

DB2 UDB for AS/400 SQL Programming V4R4

1. For details on declaring numeric, character, and graphic host variables, see the notes under numeric host variables, character host variables, and graphic host variables. 2. A structure of a short int followed by either a char or wchar_t array is always interpreted by the SQL C and C++ compilers as either a VARCHAR or VARGRAPHIC structure.

Host Structure Indicator Array


The following gure shows the valid syntax for host structure indicator array declarations.

Host Structure Indicator Array


short auto extern static const volatile signed int

, variable-name [ dimension ] = expression ;

Note: Dimension must be an integer constant between 1 and 32767.

Using Arrays of Host Structures


In C and C++ programs, you can dene a host structure array that has the dimension attribute. Host structure arrays have a maximum of two levels, even though the array might occur within a multiple-level structure. Another structure is not needed if a varying-length character string or a varying-length graphic string is not used. In this example,
struct { _Packed struct{ char c1_var[20]; short c2_var; } b_array[10]; } a_struct;

the following are true: v All of the members in b_array must be valid variable declarations. v The _Packed attribute must be specied for the struct tag. v b_array is the name of an array of host structures containing the members c1_var and c2_var. v b_array may only be used on the blocked forms of FETCH and INSERT statements.
Chapter 12. Coding SQL Statements in C and C++ Applications

241

v c1_var and c2_var are not valid host variables in any SQL statement. v A structure cannot contain an intermediate level structure. For example, you can retrieve 10 rows from the cursor with:
_Packed struct {char first_initial; char middle_initial; _Packed struct {short lastname_len; char lastname_data[15]; } lastname; double total_salary; } employee_rec[10]; struct { short inds[4]; } employee_inds[10]; ... EXEC SQL DECLARE C1 CURSOR FOR SELECT SUBSTR(FIRSTNME,1,1), MIDINIT, LASTNAME, SALARY+BONUS+COMM FROM CORPDATA.EMPLOYEE; EXEC SQL OPEN C1; EXEC SQL FETCH C1 FOR 10 ROWS INTO :employee_rec:employee_inds; ...

Host Structure Array


The following gure shows the valid syntax for host structure array declarations.

242

DB2 UDB for AS/400 SQL Programming V4R4

Host Structure Array


_Packed auto extern static const volatile struct tag {

, float double decimal ( precision , long signed short varchar-structure vargraphic-structure , char signed unsigned , wchar_t var-5 [ , variable-name [ dimension ] = expression ; length ] ; var-2 [ length ] scale int var-1 ) ; }

varchar-structure:
_Packed struct tag { signed short int var-3 ; signed unsigned

char

var-4 [

length ]

vargraphic-structure:
_Packed struct tag wchar_t var-7 [ length ] { signed ; } short int var-6 ;

Notes: 1. For details on declaring numeric, character, and graphic host variables, see the notes under numeric-host variables, character-host, and graphic-host variables. 2. The struct tag can be used to dene other data areas, but these cannot be used as host variables.
Chapter 12. Coding SQL Statements in C and C++ Applications

243

3. Dimension must be an integer constant between 1 and 32767.

Host Structure Array Indicator Structure


The following gure shows the valid syntax for host structure array indicator structure declarations.

Host Structure Array Indicator Structure


struct auto extern static const volatile _Packed tag {

short signed int

var-1

[ dimension-1 ]

, variable-name [ dimension-2 ] = expression ;

Notes: 1. The struct tag can be used to dene other data areas, but they cannot be used as host variables. 2. dimension-1 and dimension-2 must both be integer constants between 1 and 32767.

Using Pointer Data Types


You can also declare host variables that are pointers to the supported C and C++ data types, with the following restrictions: v If a host variable is declared as a pointer, then that host variable must be declared with asterisks followed by a host variable. The following examples are all valid:
short *mynum; long **mynumptr; char *mychar; char(*mychara)[20] struct { short mylen; char mydata[30]; } *myvarchar; /* /* /* /* /* /* Ptr Ptr Ptr Ptr Ptr to an integer to a ptr to a long integer to a single character to a char array of 20 bytes to a variable char array of 30 bytes. */ */ */ */ */ */

Note: Parentheses are only allowed when declaring a pointer to a NUL-terminated character array, in which case they are required. If the parentheses were not used, you would be declaring an array of pointers rather than the desired pointer to an array. For example:

244

DB2 UDB for AS/400 SQL Programming V4R4

char (*a)[10]; char *a[10];

/* pointer to a null-terminated char array */ /* pointer to an array of pointers */

v If a host variable is declared as a pointer, then no other host variable can be declared with that same name within the same source le. For example, the second declaration below would be invalid:
char *mychar; char mychar; /* This declaration is valid /* But this one is invalid */ */

v When a host variable is referenced within an SQL statement, that host variable must be referenced exactly as declared, with the exception of pointers to NUL-terminated character arrays. For example, the following declaration required parentheses:
char (*mychara)[20]; /* ptr to char array of 20 bytes */

However, the parentheses are not allowed when the host variable is referenced in an SQL statement, such as a SELECT:
EXEC SQL SELECT name INTO :*mychara FROM mytable;

v Only the asterisk can be used as an operator over a host variable name. v The maximum length of a host variable name is affected by the number of asterisks specied, as these asterisks are considered part of the name. v Pointers to structures are not usable as host variables except for variable character structures. Also, pointer elds in structures are not usable as host variables. v SQL requires that all specied storage for based host variables be allocated. If the storage is not allocated, unpredictable results can occur.

Using ILE C for AS/400 External File Descriptions


You can use the C or C++ #pragma mapinc directive with the #include directive to include external le descriptions in your program. When used with SQL, only a particular format of the #pragma mapinc directive is recognized by the SQL precompiler. If all of the required elements are not specied, the precompiler ignores the directive and does not generate host variable structures. The required elements are: v Include name v Externally described le name v Format name or a list of format names v Options v Conversion options The library name, union name, conversion options, and prex name are optional. Although typedef statements coded by the user are not recognized by the precompiler, those created by the #pragma mapinc and #include directives are recognized. SQL supports input, output, both, and key values for the options parameter. For the conversion options, the supported values are D, p, z, _P, and 1BYTE_CHAR. These options may be specied in any order except that both D and p can not be specied. Unions declared using the typedef union created by the #pragma mapinc and #include directive cannot be used as host variables in SQL statements; the members of the unions can be used. Structures that contain the typedef structure cannot be used in SQL statements; the structure declared using the typedef can be used.

Chapter 12. Coding SQL Statements in C and C++ Applications

245

To retrieve the denition of the sample table DEPARTMENT described in Appendix A. DB2 UDB for AS/400 Sample Tables, you can code the following:
#pragma mapinc ("dept","CORPDATA/DEPARTMENT(*ALL)","both") #include "dept" CORPDATA_DEPARTMENT_DEPARTMENT_both_t Dept_Structure;

A host structure named Dept_Structure is dened with the following elements: DEPTNO, DEPTNAME, MGRNO, and ADMRDEPT. These eld names can be used as host variables in SQL statements. Note: DATE, TIME, and TIMESTAMP columns generate character host variable denitions. They are treated by SQL with the same comparison and assignment rules as a DATE, TIME, and TIMESTAMP column. For example, a date host variable can only compared against a DATE column or a character string which is a valid representation of a date. If the GRAPHIC or VARGRAPHIC column has a UCS-2 CCSID, the generated host variable will have the UCS-2 CCSID assigned to it. Although zoned, binary (with non-zero scale elds), and optionally decimal are mapped to character elds in ILE C for AS/400, SQL will treat these elds as numeric. By using the extended program model (EPM) routines, you can manipulate these elds to convert zoned and packed decimal data. For more information, see the ILE C for AS/400 Language Reference book.

Determining Equivalent SQL and C or C++ Data Types


The precompiler determines the base SQLTYPE and SQLLEN of host variables based on the following table. If a host variable appears with an indicator variable, the SQLTYPE is the base SQLTYPE plus one.
Table 24. C or C++ Declarations Mapped to Typical SQL Data Types
C or C++ Data Type short int long int decimal(p,s) oat double single-character form NUL-terminated character form VARCHAR structured form where length < 255 VARCHAR structure form where length > 254 single-graphic form SQLTYPE of Host Variable 500 496 484 480 480 452 460 448 SQLLEN of Host Variable 2 4 p in byte 1, s in byte 2 4 8 1 length length SQL Data Type SMALLINT INTEGER DECIMAL (p,s) FLOAT (single precision) FLOAT (double precision) CHAR(1) VARCHAR (length 1) VARCHAR (length)

456

length

VARCHAR(length)

468

GRAPHIC(1)

246

DB2 UDB for AS/400 SQL Programming V4R4

Table 24. C or C++ Declarations Mapped to Typical SQL Data Types (continued)
C or C++ Data Type NUL-terminated single-graphic form SQLTYPE of Host Variable 400 SQLLEN of Host Variable length length SQL Data Type VARGRAPHIC (length - 1) VARGRAPHIC (length) VARGRAPHIC (length)

VARGRAPHIC 464 structured form where length < 128 VARGRAPHIC 472 structured form where length > 127

length

You can use the following table to determine the C or C++ data type that is equivalent to a given SQL data type.
Table 25. SQL Data Types Mapped to Typical C or C++ Declarations
SQL Data Type SMALLINT INTEGER DECIMAL(p,s) C or C++ Data Type short int long int decimal(p,s) p is a positive integer from 1 to 31, and s is a positive integer from 0 to 31. Use decimal(p,s). Notes

NUMERIC(p,s) or nonzero scale binary FLOAT (single precision) FLOAT (double precision) CHAR(1) CHAR(n) VARCHAR(n)

No exact equivalent oat double single-character form No exact equivalent NUL-terminated character form

If n>1, use NUL-terminated character form If data can contain character NULs (\0), use VARCHAR structured form. Allow at least n+1 to accommodate the NUL-terminator.

n is a positive integer. The maximum value of n is 32740.


VARCHAR structured form BLOB CLOB GRAPHIC (1) GRAPHIC (n) None None single-graphic form No exact equivalent If n > 1, use NUL-terminated graphic form. The maximum value of n is 32740. Use SQL TYPE IS to declare a BLOB in C or C++. Use SQL TYPE IS to declare a CLOB in C or C++.

Chapter 12. Coding SQL Statements in C and C++ Applications

247

Table 25. SQL Data Types Mapped to Typical C or C++ Declarations (continued)
SQL Data Type VARGRAPHIC(n) C or C++ Data Type NUL-terminated graphic form Notes If data can contain graphic NUL values (/0/0), use VARGRAPHIC structured form. Allow at least n + 1 to accommodate the NUL-terminator.

n is a positive integer. The maximum value of n is 16370.


VARGRAPHIC structured form DBCLOB DATE None NUL-terminated character form

n is a positive integer. The maximum value of n is 16370.


Use SQL TYPE IS to declare a DBCLOB in C or C++. If the format is *USA, *ISO, *JIS, or *EUR, allow at least 11 characters to accommodate the NUL-terminator. If the format is *MDY, *YMD, or *DMY, allow at least 9 characters to accommodate the NUL-terminator. If the format is *JUL, allow at least 7 characters to accommodate the NUL-terminator. If the format is *USA, *ISO, *JIS, or *EUR, allow at least 10 characters. If the format is *MDY, *YMD, or *DMY, allow at least 8 characters. If the format is *JUL, allow at least 6 characters. Allow at least 7 characters (9 to include seconds) to accommodate the NUL-terminator. Allow at least 6 characters; 8 to include seconds. Allow at least 20 characters (27 to include microseconds at full precision) to accommodate the NUL-terminator. If n is less than 27, truncation occurs on the microseconds part. Allow at least 19 characters. To include microseconds at full precision, allow 26 characters. If the number of characters is less than 26, truncation occurs on the microseconds part.

VARCHAR structured form

TIME

NUL-terminated character form

VARCHAR structured form TIMESTAMP NUL-terminated character form

VARCHAR structured form

248

DB2 UDB for AS/400 SQL Programming V4R4

Table 25. SQL Data Types Mapped to Typical C or C++ Declarations (continued)
SQL Data Type DATALINK C or C++ Data Type Not supported Notes

Notes on C and C++ Variable Declaration and Usage


Apostrophes and quotation marks have different meanings in C, C++, and SQL. C and C++ use quotation marks to delimit string constants and apostrophes to delimit character constants. SQL does not have this distinction, but uses quotation marks for delimited identiers and uses apostrophes to delimit character string constants. Character data in SQL is distinct from integer data.

Using Indicator Variables


An indicator variable is a two-byte integer (short int). You can also specify an indicator structure (dened as an array of halfword integer variables) to support a host structure. On retrieval, an indicator variable is used to show if its associated host variable has been assigned a null value. On assignment to a column, a negative indicator variable is used to indicate that a null value should be assigned. See DB2 UDB for AS/400 SQL Reference book for more information on the use of indicator variables. Indicator variables are declared in the same way as host variables. The declarations of the two can be mixed in any way that seems appropriate to you.

Example:
Given the statement:
EXEC SQL FETCH CLS_CURSOR INTO :ClsCd, :Day :DayInd, :Bgn :BgnInd, :End :EndInd;

Variables can be declared as follows:


EXEC SQL BEGIN DECLARE SECTION; char ClsCd[8]; char Bgn[9]; char End[9]; short Day, DayInd, BgnInd, EndInd; EXEC SQL END DECLARE SECTION;

Chapter 12. Coding SQL Statements in C and C++ Applications

249

250

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 13. Coding SQL Statements in COBOL Applications


The AS/400 system supports more than one COBOL compiler. The DB2 UDB Query Manager and SQL Development Kit licensed program only supports the COBOL for AS/400 and ILE COBOL for AS/400 languages. This chapter describes the unique application and coding requirements for embedding SQL statements in a COBOL program. Requirements for host structures and host variables are dened. A detailed sample COBOL program, showing how SQL statements can be used, is provided in Appendix C. Sample Programs Using DB2 UDB for AS/400 Statements.

Dening the SQL Communications Area


A COBOL program that contains SQL statements must include one or both of the following: v An SQLCODE variable declared as PICTURE S9(9) BINARY, PICTURE S9(9) COMP-4, or PICTURE S9(9) COMP. v An SQLSTATE variable declared as PICTURE X(5) Or, v An SQLCA (which contains an SQLCODE and SQLSTATE variable). The SQLCODE and SQLSTATE values are set by the database manager after each SQL statement is executed. An application can check the SQLCODE or SQLSTATE value to determine whether the last SQL statement was successful. The SQLCA can be coded in a COBOL program either directly or by using the SQL INCLUDE statement. Using the SQL INCLUDE statement requests the inclusion of a standard declaration:
EXEC SQL INCLUDE SQLCA END-EXEC.

The SQLCODE, SQLSTATE, and SQLCA variable declarations must appear in the WORKING-STORAGE SECTION or LINKAGE SECTION of your program and can be placed wherever a record description entry can be specied in those sections. When you use the INCLUDE statement, the SQL COBOL precompiler includes COBOL source statements for the SQLCA:
01 SQLCA. 05 SQLCAID 05 SQLCABC 05 SQLCODE 05 SQLERRM. 49 SQLERRML 49 SQLERRMC 05 SQLERRP 05 SQLERRD 05 SQLWARN. 10 SQLWARN0 10 SQLWARN1 10 SQLWARN2 10 SQLWARN3 10 SQLWARN4 10 SQLWARN5 10 SQLWARN6 10 SQLWARN7
Copyright IBM Corp. 1997, 1999

PIC X(8). PIC S9(9) BINARY. PIC S9(9) BINARY. PIC S9(4) BINARY. PIC X(70). PIC X(8). OCCURS 6 TIMES PIC S9(9) BINARY. PIC PIC PIC PIC PIC PIC PIC PIC X. X. X. X. X. X. X. X.

251

10 SQLWARN8 10 SQLWARN9 10 SQLWARNA 05 SQLSTATE

PIC PIC PIC PIC

X. X. X. X(5).

For ILE COBOL for AS/400, the SQLCA is declared using the GLOBAL clause. SQLCODE is replaced with SQLCADE when a declare for SQLCODE is found in the program and the SQLCA is provided by the precompiler. SQLSTATE is replaced with SQLSTOTE when a declare for SQLSTATE is found in the program and the SQLCA is provided by the precompiler. For more information on SQLCA, see Appendix B, SQL Communication Area in the DB2 UDB for AS/400 SQL Reference book.

Dening SQL Descriptor Areas


The following statements require an SQLDA: EXECUTE...USING DESCRIPTOR descriptor-name FETCH...USING DESCRIPTOR descriptor-name OPEN...USING DESCRIPTOR descriptor-name CALL...USING DESCRIPTOR descriptor-name DESCRIBE statement-name INTO descriptor-name DESCRIBE TABLE host-variable INTO descriptor-name PREPARE statement-name INTO descriptor-name Unlike the SQLCA, there can be more than one SQLDA in a program. The SQLDA can have any valid name. An SQLDA can be coded in a COBOL program directly or added with the INCLUDE statement. Using the SQL INCLUDE statement requests the inclusion of a standard SQLDA declaration:
EXEC SQL INCLUDE SQLDA END-EXEC.

The COBOL declarations included for the SQLDA are:


1 SQLDA. 05 SQLDAID PIC X(8). 05 SQLDABC PIC S9(9) BINARY. 05 SQLN PIC S9(4) BINARY. 05 SQLD PIC S9(4) BINARY. 05 SQLVAR OCCURS 0 TO 409 TIMES DEPENDING ON SQLD. 10 SQLTYPE PIC S9(4) BINARY. 10 SQLLEN PIC S9(4) BINARY. 10 FILLER REDEFINES SQLLEN. 15 SQLPRECISION PIC X. 15 SQLSCALE PIC X. 10 SQLRES PIC X(12). 10 SQLDATA POINTER. 10 SQLIND POINTER. 10 SQLNAME. 49 SQLNAMEL PIC S9(4) BINARY. 49 SQLNAMEC PIC X(30).

Figure 10. INCLUDE SQLDA Declarations for COBOL

SQLDA declarations must appear in the WORKING-STORAGE SECTION or LINKAGE SECTION of your program and can be placed wherever a record

252

DB2 UDB for AS/400 SQL Programming V4R4

description entry can be specied in those sections. For ILE COBOL for AS/400, the SQLDA is declared using the GLOBAL clause. Dynamic SQL is an advanced programming technique described in Chapter 10. Dynamic SQL Applications. With dynamic SQL, your program can develop and then run SQL statements while the program is running. A SELECT statement with a variable SELECT list (that is, a list of the data to be returned as part of the query) that runs dynamically requires an SQL descriptor area (SQLDA). This is because you cannot know in advance how many or what type of variables to allocate in order to receive the results of the SELECT. For more information, refer to the DB2 UDB for AS/400 SQL Reference book.

Embedding SQL Statements


SQL statements can be coded in COBOL program sections as follows:
SQL Statement BEGIN DECLARE SECTION END DECLARE SECTION DECLARE VARIABLE DECLARE STATEMENT INCLUDE SQLCA INCLUDE SQLDA INCLUDE member-name Other WORKING-STORAGE SECTION or LINKAGE SECTION DATA DIVISION or PROCEDURE DIVISION PROCEDURE DIVISION Program Section WORKING-STORAGE SECTION or LINKAGE SECTION

Each SQL statement in a COBOL program must begin with EXEC SQL and end with END-EXEC. If the SQL statement appears between two COBOL statements, the period is optional and might not be appropriate. The EXEC SQL keywords must appear all on one line, but the remainder of the statement can appear on the next and subsequent lines.

Example:
An UPDATE statement coded in a COBOL program might be coded as follows:
EXEC SQL UPDATE DEPARTMENT SET MGRNO = :MGR-NUM WHERE DEPTNO = :INT-DEPT END-EXEC.

Comments
In addition to SQL comments (--), you can include COBOL comment lines (* or / in column 7) within embedded SQL statements except between the keywords EXEC and SQL. COBOL debugging lines (D in column 7) are treated as comment lines by the precompiler.

Continuation for SQL Statements


The line continuation rules for SQL statements are the same as those for other COBOL statements, except that EXEC SQL must be specied within one line.
Chapter 13. Coding SQL Statements in COBOL Applications

253

If you continue a string constant from one line to the next, the rst nonblank character in the next line must be either an apostrophe or a quotation mark. If you continue a delimited identier from one line to the next, the rst nonblank character in the next line must be either an apostrophe or a quotation mark. Constants containing DBCS data can be continued across multiple lines by placing the shift-in character in column 72 of the continued line and the shift-out after the rst string delimiter of the continuation line. This SQL statement has a valid graphic constant of G<AABBCCDDEEFFGGHHIIJJKK>. The redundant shifts are removed.
*...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 EXEC SQL SELECT * FROM GRAPHTAB WHERE GRAPHCOL = G'<AABB> '<CCDDEEFFGGHHIIJJKK>' END-EXEC.

Including Code
SQL statements or COBOL host variable declaration statements can be included by embedding the following SQL statement at the point in the source code where the statements are to be embedded:
EXEC SQL INCLUDE member-name END-EXEC.

COBOL COPY statements cannot be used to include SQL statements or declarations of COBOL host variables that are referenced in SQL statements.

Margins
Code SQL statements in columns 12 through 72. If EXEC SQL starts before the specied margin (that is, before column 12), the SQL precompiler will not recognize the statement.

Sequence Numbers
The source statements generated by the SQL precompiler are generated with the same sequence number as the SQL statement.

Names
Any valid COBOL variable name can be used for a host variable and is subject to the following restrictions: Do not use host variable names or external entry names that begin with 'SQL', 'RDI', or 'DSN'. These names are reserved for the database manager.

COBOL Compile-Time Options


The COBOL PROCESS statement can be used to specify the compile-time options for the COBOL compiler. Although the PROCESS statement will be recognized by the COBOL compiler when it is called by the precompiler to create the program; the SQL precompiler itself does not recognize the PROCESS statement. Therefore, options that affect the syntax of the COBOL source such as APOST and QUOTE

254

DB2 UDB for AS/400 SQL Programming V4R4

should not be specied in the PROCESS statement. Instead *APOST and *QUOTE should be specied in the OPTION parameter of the CRTSQLCBL and CRTSQLCBLI commands.

Statement Labels
Executable SQL statements in the PROCEDURE DIVISION can be preceded by a paragraph name.

WHENEVER Statement
The target for the GOTO clause in an SQL WHENEVER statement must be a section name or unqualied paragraph name in the PROCEDURE DIVISION.

Multiple source programs


The SQL COBOL precompiler does not support precompiling multiple source programs separated with the PROCESS statement.

Using Host Variables


All host variables used in SQL statements must be explicitly declared. A host variable used in an SQL statement must be declared prior to the rst use of the host variable in an SQL statement. The COBOL statements that are used to dene the host variables should be preceded by a BEGIN DECLARE SECTION statement and followed by an END DECLARE SECTION statement. If a BEGIN DECLARE SECTION and END DECLARE SECTION are specied, all host variable declarations used in SQL statements must be between the BEGIN DECLARE SECTION and the END DECLARE SECTION statements. All host variables within an SQL statement must be preceded by a colon (:). Host variables cannot be records or elements. To accommodate using dashes within a COBOL host variable name, blanks must precede and follow a minus sign.

Declaring Host Variables


The COBOL precompiler only recognizes a subset of valid COBOL declarations as valid host variable declarations.

Numeric Host Variables


The following gure shows the syntax for valid integer host variable declarations.

Chapter 13. Coding SQL Statements in COBOL Applications

255

INTEGER and SMALLINT


01 77 level-1 variable-name PICTURE PIC picture-string IS

USAGE IS

BINARY COMPUTATIONAL-4 COMP-4

. VALUE IS numeric-constant

Notes: 1. BINARY, COMPUTATIONAL-4, and COMP-4 are equivalent. A portable application should code BINARY, because COMPUTATIONAL-4 and COMP-4 are IBM extensions that are not supported in ISO/ANSI COBOL. The picture-string associated with these types must have the form S9(i)V9(d) (or S9...9V9...9, with i and d instances of 9). i + d must be less than or equal to 9. 2. level-1 indicates a COBOL level between 2 and 48. The following gure shows the syntax for valid decimal host variable declarations.

DECIMAL
01 77 level-1 variable-name PICTURE PIC picture-string IS

USAGE IS

PACKED-DECIMAL COMPUTATIONAL-3 COMP-3 COMPUTATIONAL COMP

. VALUE IS numeric-constant

Notes: 1. PACKED-DECIMAL, COMPUTATIONAL-3, and COMP-3 are equivalent. A portable application should code PACKED-DECIMAL, because COMPUTATIONAL-3 and COMP-3 are IBM extensions that are not supported in

256

DB2 UDB for AS/400 SQL Programming V4R4

ISO/ANS COBOL. The picture-string associated with these types must have the form S9(i)V9(d) (or S9...9V9...9, with i and d instances of 9). i + d must be less than or equal to 18. 2. COMPUTATIONAL and COMP are equivalent. The picture strings associated with these and the data types they represent are product specic. Therefore, COMP and COMPUTATIONAL should not be used in a portable application. In the COBOL for AS/400 program, the picture-string associated with these types must have the form S9(i)V9(d) (or S9...9V9...9, with i and d instances of 9). i + d must be less than or equal to 18. 3. level-1 indicates a COBOL level between 2 and 48. The following gure shows the syntax for valid numeric host variable declarations.

Numeric
01 77 level-1 variable-name PICTURE PIC picture-string IS

USAGE IS

DISPLAY display clause

. VALUE IS numeric-constant

display clause:
SIGN DISPLAY IS LEADING SEPARATE CHARACTER

Notes: 1. The picture-string associated with SIGN LEADING SEPARATE and DISPLAY must have the form S9(i)V9(d) (or S9...9V9...9, with i and d instances of 9). i + d must be less than or equal to 18. 2. level-1 indicates a COBOL level between 2 and 48.

Floating Point Host Variables


The following gure shows the syntax for valid oating point host variable declarations. Floating point host variables are only supported for ILE COBOL for AS/400.

Chapter 13. Coding SQL Statements in COBOL Applications

257

Floating-point
01 77 level-1 variable-name USAGE IS COMPUTATIONAL-1 COMP-1 COMPUTATIONAL-2 COMP-2

. VALUE IS numeric-constant

Notes: 1. COMPUTATIONAL-1 and COMP-1 are equivalent. COMPUTATIONAL-2 and COMP-2 are equivalent. 2. level-1 indicates a COBOL level between 2 and 48.

Character Host Variables


There are two valid forms of character host variables: v Fixed-Length Strings v Varying-Length Strings

Fixed-Length Character Strings


01 77 level-1 variable-name PICTURE PIC picture-string IS

DISPLAY USAGE IS

VALUE IS

string-constant

Notes: 1. The picture string associated with these forms must be X(m) (or XXX...X, with m instance of X) with 1 m 32 766. 2. level-1 indicates a COBOL level between 2 and 48.

258

DB2 UDB for AS/400 SQL Programming V4R4

Varying-Length Character Strings


01 level-1 variable-name . 49 var-1 PICTURE PIC

picture-string-1 IS USAGE IS

BINARY COMPUTATIONAL-4 COMP-4

. VALUE IS numeric-constant

49

var-2

PICTURE PIC

picture-string-2 IS USAGE IS DISPLAY

. VALUE IS string-constant

Notes: 1. The picture-string-1 associated with these forms must be S9(m) or S9...9 with m instances of 9. m must be from 1 to 4. Note that the database manager will use the full size of the S9(m) variable even though COBOL on the AS/400 only recognizes values up to the specied precision. This can cause data truncation errors when COBOL statements are being run and may effectively limit the maximum length of variable-length character strings to the specied precision. 2. The picture-string-2 associated with these forms must be either X(m), or XX...X, with m instances of X, and with 1 m 32 740. 3. var-1 and var-2 cannot be used as host variables. 4. level-1 indicates a COBOL level between 2 and 48.

Graphic Host Variables


Graphic host variables are only supported in ILE COBOL for AS/400. There are two valid forms of graphic host variables: v Fixed-Length Graphic Strings v Varying-Length Graphic Strings

Chapter 13. Coding SQL Statements in COBOL Applications

259

Fixed-Length Graphic Strings


01 77 level-1 variable-name PICTURE PIC picture-string IS

DISPLAY-1 USAGE IS

VALUE IS

string-constant

Notes: 1. The picture string associated with these forms must be G(m) (or GGG...G, with m instance of G) or N(m) (or NNN...N, with m instance of N) with 1 m 16 383. 2. level-1 indicates a COBOL level between 2 and 48.

Varying-Length Graphic Strings


01 level-1 variable-name . 49 var-1 PICTURE PIC

picture-string-1 IS USAGE IS

BINARY COMPUTATIONAL-4 COMP-4

. VALUE IS numeric-constant

49

var-2

PICTURE PIC

picture-string-2 IS USAGE IS DISPLAY-1

. VALUE IS string-constant

Notes: 1. The picture-string-1 associated with these forms must be S9(m) or S9...9 with m instances of 9. m must be from 1 to 4.

260

DB2 UDB for AS/400 SQL Programming V4R4

Note that the database manager will use the full size of the S9(m) variable even though COBOL on the AS/400 only recognizes values up to the specied precision. This can cause data truncation errors when COBOL statements are being run and may effectively limit the maximum length of variable-length graphic strings to the specied precision. 2. The picture-string-2 associated with these forms must be G(m), GG...G with m instances of G, N(m), or NN...N with m instances of N, and with 1 m 16 370. 3. var-1 and var-2 cannot be used as host variables. 4. level-1 indicates a COBOL level between 2 and 48. | | | | | |

LOB Host Variables


LOB host variables are only supported in ILE COBOL for AS/400.

LOB Host Variables


01 variable-name USAGE IS SQL TYPE IS BLOB CLOB DBCLOB

| |

lob-length K M

|| | | | | | | | | | | | | | | | | | | | | Notes: 1. For BLOB and CLOB, 1 <= lob-length <= 15,728,640 2. For DBCLOB, 1 <= lob-length <= 7,864,320 3. SQL TYPE IS, BLOB, CLOB, DBCLOB can be in mixed case. 4. LOB Host Variables can be declared in host structures.

BLOB Example
The following declaration:
01 MY-BLOB SQL TYPE IS BLOB(16384).

Results in the generation of the following structure:


01 MY-BLOB. 49 MY-BLOB-LENGTH PIC 9(9) BINARY. 49 MY-BLOB-DATA PIC X(16384).

CLOB Example
The following declaration:
01 MY-CLOB SQL TYPE IS CLOB(16384).

Results in the generation of the following structure:


01 MY-CLOB. 49 MY-CLOB-LENGTH PIC 9(9) BINARY. 49 MY-CLOB-DATA PIC X(16384).

Chapter 13. Coding SQL Statements in COBOL Applications

261

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

DBCLOB Example
The following declaration:
01MY-DBCLOB SQL TYPE IS DBCLOB(8192).

Results in the generation of the following structure:


01 MY-DBCLOB. 49 MY-DBCLOB-LENGTH PIC 9(9) BINARY. 49 MY-DBCLOB-DATA PIC G(8192) DISPLAY-1.

LOB Locators
LOB locators are only supported in ILE COBOL for AS/400.

LOB Locator
01 variable-name USAGE IS

| |

SQL TYPE IS

BLOB-LOCATOR CLOB-LOCATOR DBCLOB-LOCATOR

| | | | | | | | | | | | | | | | Notes: 1. SQL TYPE IS, BLOB-LOCATOR, CLOB-LOCATOR, DBCLOB-LOCATOR can be in mixed case. 2. LOB Locators cannot be initialized in the SQL TYPE IS statement. 3. LOB Locators can be declared as a part of a host structure.

BLOB Example
The following declaration:
01 MY-LOCATOR SQL TYPE IS BLOB_LOCATOR.

Results in the generation of the following structure:


01 MY-LOCATOR PIC 9(9) BINARY.

CLOB and DBCLOB locators have similar syntax.

LOB File Reference Variables


LOB variables are only supported in ILE COBOL for AS/400.

262

DB2 UDB for AS/400 SQL Programming V4R4

| | | | LOB File Reference Variable


01 variable-name USAGE IS SQL TYPE IS BLOB-FILE CLOB-FILE DBCLOB-FILE

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

Notes: 1. SQL TYPE IS, BLOB-FILE, CLOB-FILE, DBCLOB-FILE can be in mixed case. 2. LOB File Reference Variables can be declared as part of a host structure.

BLOB Example
The following declaration:
01 MY-FILE SQL TYPE IS BLOB-FILE.

Results in the generation of the following structure:


01 MY-FILE. 49 MY-FILE-NAME-LENGTH PIC S9(9) COMP-5. 49 MY-FILE-DATA-LENGTH PIC S9(9) COMP-5. 49 MY-FILE-FILE-OPTIONS PIC S9(9) COMP-5. 49 MY-FILE-NAME PIC X(255).

CLOB and DBCLOB le reference variables have similar syntax. The pre-compiler will generate declarations for the following le option constants: v SQL-FILE-READ (2) v SQL-FILE-CREATE (8) v SQL-FILE-OVERWRITE (16) v SQL-FILE-APPEND (32)

Datetime Host Variables


The following gure shows the syntax for valid date, time, and timestamp host variable declarations. Datetime host variables are supported only for ILE COBOL for AS/400.

Datetime Host Variable


01 77 level-1 variable-name FORMAT OF DATE TIME TIMESTAMP IS

| | || |

format-options

Chapter 13. Coding SQL Statements in COBOL Applications

263

| | | | | |

Notes: 1. level-1 indicates a COBOL level between 2 and 48. 2. format-options indicates valid datetime options that are supported by the COBOL compiler. See the ILE COBOL for AS/400 Reference, SC09-2539-01 book for details.

Using Host Structures


A host structure is a named set of host variables that is dened in your programs DATA DIVISION. Host structures have a maximum of two levels, even though the host structure might itself occur within a multilevel structure. An exception is the declaration of a varying-length character string, which requires another level that must be level 49. A host structure name can be a group name whose subordinate levels name basic data items. For example:
01 A 02 B 03 C1 PICTURE ... 03 C2 PICTURE ...

In this example, B is the name of a host structure consisting of the basic items C1 and C2. When writing an SQL statement using a qualied host variable name (for example, to identify a eld within a structure), use the name of the structure followed by a period and the name of the eld (that is, PL/I style). For example, specify B.C1 rather than C1 OF B or C1 IN B. However, PL/I style applies only to qualied names within SQL statements; you cannot use this technique for writing qualied names in COBOL statements. A host structure is considered complete if any of the following items are found: v A COBOL item that must begin in area A v Any SQL statement (except SQL INCLUDE) After the host structure is dened, you can refer to it in an SQL statement instead of listing the several host variables (that is, the names of the data items that comprise the host structure). For example, you can retrieve all column values from selected rows of the table CORPDATA.EMPLOYEE with:
01 PEMPL. 10 EMPNO 10 FIRSTNME. 49 FIRSTNME-LEN 49 FIRSTNME-TEXT 10 MIDINIT 10 LASTNAME. 49 LASTNAME-LEN 49 LASTNAME-TEXT 10 WORKDEPT ... MOVE "000220" TO EMPNO. ... EXEC SQL SELECT * PIC X(6). PIC S9(4) USAGE BINARY. PIC X(12). PIC X(1). PIC S9(4) USAGE BINARY. PIC X(15). PIC X(3).

264

DB2 UDB for AS/400 SQL Programming V4R4

INTO :PEMPL FROM CORPDATA.EMPLOYEE WHERE EMPNO = :EMPNO END-EXEC.

Notice that in the declaration of PEMPL, two varying-length string elements are included in the structure: FIRSTNME and LASTNAME.

Host Structure
The following gure shows the syntax for the valid host structure.

Chapter 13. Coding SQL Statements in COBOL Applications

265

Host Structure
level-1 variable-name .

level-2

var-1

PICTURE picture-string PIC IS floating-point . . varchar-string . . vargraphic-string . datetime .

usage-clause .

oating-point:
COMPUTATIONAL-1 COMP-1 COMPUTATIONAL-2 COMP-2 VALUE IS constant

USAGE IS

usage-clause:
BINARY COMPUTATIONAL-4 COMP-4 PACKED-DECIMAL COMPUTATIONAL-3 COMP-3 COMPUTATIONAL COMP DISPLAY display-clause DISPLAY-1 VALUE IS constant

USAGE IS

display-clause:
SIGN DISPLAY IS LEADING SEPARATE CHARACTER

266

DB2 UDB for AS/400 SQL Programming V4R4

Host Structure (continued) varchar-string:


49 var-2 PICTURE PIC picture-string-1 IS USAGE IS . VALUE IS numeric-constant 49 var-3 PICTURE PIC BINARY COMPUTATIONAL-4 COMP-4 picture-string-2 IS

DISPLAY USAGE IS

VALUE IS

constant

vargraphic-string:
49 var-2 PICTURE PIC picture-string-1 IS USAGE IS . VALUE IS numeric-constant 49 var-3 PICTURE PIC BINARY COMPUTATIONAL-4 COMP-4 picture-string-2 IS

DISPLAY-1 USAGE IS

VALUE IS

constant

datetime:
variable-name FORMAT OF DATE TIME TIMESTAMP format-options IS

Notes: 1. level-1 indicates a COBOL level between 1 and 47. 2. level-2 indicates a COBOL level between 2 and 48 where level-2 > level-1. 3. Graphic host variables and oating-point host variables are only supported for ILE COBOL for AS/400. 4. For details on declaring numeric, character, and graphic host variables, see the notes under numeric-host variables, character-host variables, and graphic-host variables. 5. format-options indicates valid datetime options that are supported by the COBOL compiler. See the ILE COBOL for AS/400 Reference, SC09-2539-01 book for details.

Chapter 13. Coding SQL Statements in COBOL Applications

267

Host Structure Indicator Array


The following gure shows the syntax for valid indicator array declarations.

Host Structure Indicator Array


level-1 variable-name PICTURE PIC picture-string IS

USAGE IS

BINARY COMPUTATIONAL-4 COMP-4

OCCURS dimension TIMES

. VALUE IS constant

Notes: 1. Dimension must be an integer between 1 and 32767. 2. level-1 must be an integer between 2 and 48. 3. BINARY, COMPUTATIONAL-4, and COMP-4 are equivalent. A portable application should code BINARY, because COMPUTATIONAL-4 and COMP-4 are IBM extensions that are not supported in ISO/ANSI COBOL. The picture-string associated with these types must have the form S9(i) (or S9...9, with i instances of 9). i must be less than or equal to 4.

Using Host Structure Arrays


A host structure array is a named set of host variables that is dened in the programs Data Division and has an OCCURS clause. Host structure arrays have a maximum of two levels, even though the host structure can occur within a multiple level structure. A varying-length string requires another level, level 49. A host structure array name can be a group name whose subordinate levels name basic data items. In v v v these examples, the following are true: All members in B-ARRAY must be valid. B-ARRAY cannot be qualied. B-ARRAY can only be used on the blocked form of the FETCH and INSERT statements. v B-ARRAY is the name of an array of host structures containing items C1-VAR and C2-VAR. v The SYNCHRONIZED attribute must not be specied. v C1-VAR and C2-VAR are not valid host variables in any SQL statement. A structure cannot contain an intermediate level structure.

268

DB2 UDB for AS/400 SQL Programming V4R4

01

A-STRUCT. 02 B-ARRAY OCCURS 10 TIMES. 03 C1-VAR PIC X(20). 03 C2-VAR PIC S9(4).

To retrieve 10 rows from the CORPDATA.DEPARTMENT table, use the following example:
01 TABLE-1. 02 DEPT OCCURS 10 TIMES. 05 DEPTNO PIC X(3). 05 DEPTNAME. 49 DEPTNAME-LEN PIC S9(4) BINARY. 49 DEPTNAME-TEXT PIC X(29). 05 MGRNO PIC X(6). 05 ADMRDEPT PIC X(3). 01 TABLE-2. 02 IND-ARRAY OCCURS 10 TIMES. 05 INDS PIC S9(4) BINARY OCCURS 4 TIMES. .... EXEC SQL DECLARE C1 CURSOR FOR SELECT * FROM CORPDATA.DEPARTMENT END-EXEC. .... EXEC SQL FETCH C1 FOR 10 ROWS INTO :DEPT :IND-ARRAY END-EXEC.

Host Structure Array


The following gures show the syntax for valid host structure array declarations.

Chapter 13. Coding SQL Statements in COBOL Applications

269

Host Structure Array


level-1 variable-name OCCURS dimension TIMES .

level-2

var-1

PICTURE picture-string-1 PIC IS floating-point . . varchar-string . . vargraphic-string . datetime .

usage-clause .

oating-point:
COMPUTATIONAL-1 COMP-1 COMPUTATIONAL-2 COMP-2 VALUE IS constant

USAGE IS

usage-clause:
BINARY COMPUTATIONAL-4 COMP-4 PACKED-DECIMAL COMPUTATIONAL-3 COMP-3 COMPUTATIONAL COMP DISPLAY display-clause DISPLAY-1 VALUE IS constant

USAGE IS

display-clause:
SIGN DISPLAY IS LEADING SEPARATE CHARACTER

270

DB2 UDB for AS/400 SQL Programming V4R4

Host Structure Array (continued) varchar-string:


49 var-2 PICTURE PIC picture-string-2 IS USAGE IS . VALUE IS numeric-constant 49 var-3 PICTURE PIC BINARY COMPUTATIONAL-4 COMP-4 picture-string-3 IS

DISPLAY USAGE IS

VALUE IS

constant

vargraphic-string:
49 var-2 PICTURE PIC picture-string-2 IS USAGE IS . VALUE IS numeric-constant 49 var-3 PICTURE PIC BINARY COMPUTATIONAL-4 COMP-4 picture-string-3 IS

DISPLAY-1 USAGE IS

VALUE IS

constant

datetime:
variable-name FORMAT OF DATE TIME TIMESTAMP format-options IS

Notes: 1. level-1 indicates a COBOL level between 2 and 47. 2. level-2 indicates a COBOL level between 3 and 48 where level-2 > level-1. 3. Graphic host variables and oating-point host variables are only supported for ILE COBOL for AS/400. 4. For details on declaring numeric, character, and graphic host variables, see the notes under numeric-host variables, character-host variables, and graphic-host variables. 5. Dimension must be an integer constant between 1 and 32767. 6. format-options indicates valid datetime options that are supported by the COBOL compiler. See the ILE COBOL for AS/400 Reference, SC09-2539-01 book for details.

Chapter 13. Coding SQL Statements in COBOL Applications

271

Host Array Indicator Structure


This gure shows the valid syntax for host structure array indicators.

Host Structure Array Indicator Structure


level-1 variable-name OCCURS dimension TIMES .

level-2 var-1

PICTURE PIC

picture-string IS

USAGE IS

BINARY COMPUTATIONAL-4 COMP-4

VALUE IS

constant

Notes: 1. level-1 indicates a COBOL level between 2 and 48. 2. level-2 indicates a COBOL level between 3 and 48 where level-2 > level-1. 3. Dimension must be an integer constant between 1 and 32767. 4. BINARY, COMPUTATIONAL-4, and COMP-4 are equivalent. A portable application should code BINARY, because COMPUTATIONAL-4 and COMP-4 are IBM extensions that are not supported in ISO/ANSI COBOL. The picture-string associated with these types must have the form S9(i) (or S9...9, with i instances of 9). i must be less than or equal to 4.

Using External File Descriptions


SQL uses the COPY DD-format-name, COPY DD-ALL-FORMATS, COPY DDS-format-name, COPY DDR-format-name, COPY DDR-ALL-FORMATS, COPY DDSR-format-name, COPY DDS-ALL-FORMATS, and COPY DDSR-ALLFORMATS to retrieve host variables from the le denitions. If the REPLACING option is specied, only complete name replacing is done. Var-1 is compared against the format name and the eld name. If they are equal, var-2 is used as the new name. Note: You cannot retrieve host variables from le denitions that have eld names which are COBOL reserved words. You must place the COPY DDx-format statement within a COBOL host structure. To retrieve the denition of the sample table DEPARTMENT described in Appendix A. DB2 UDB for AS/400 Sample Tables, you can code the following:
01 DEPARTMENT-STRUCTURE. COPY DDS-ALL-FORMATS OF DEPARTMENT.

| | | | |

A host structure named DEPARTMENT-STRUCTURE is dened with an 05 level eld named DEPARTMENT-RECORD that contains four 06 level elds named

272

DB2 UDB for AS/400 SQL Programming V4R4

DEPTNO, DEPTNAME, MGRNO, and ADMRDEPT. These eld names can be used as host variables in SQL statements. For more information on the COBOL COPY verb, see the COBOL/400 Users Guide book and the ILE COBOL for AS/400 Reference book.

Using External File Descriptions for Host Structure Arrays


Because COBOL creates an extra level when including externally described data, the OCCURS clause must be placed on the preceding 04 level. The structure cannot contain any additional declares at the 05 level. If the le contains elds that are generated as FILLER, the structure cannot be used as a host structure array. For device les, if INDARA was not specied and the le contains indicators, the declaration cannot be used as a host structure array. The indicator area is included in the generated structure and causes the storage for records to not be contiguous. For example, the following shows how to use COPYDDS to generate a host structure array and fetch 10 rows into the host structure array:
01 DEPT. 04 DEPT-ARRAY OCCURS 10 TIMES. COPY DDS-ALL-FORMATS OF DEPARTMENT. :

EXEC SQL DECLARE C1 CURSOR FOR SELECT * FROM CORPDATA.DEPARTMENT END EXEC. EXEC SQL OPEN C1 END-EXEC. EXEC SQL FETCH C1 FOR 10 ROWS INTO :DEPARTMENT END-EXEC.

Note: DATE, TIME, and TIMESTAMP columns will generate character host variable denitions that are treated by SQL with the same comparison and assignment rules as the DATE, TIME, or TIMESTAMP column. For example, a date host variable can only be compared against a DATE column or a character string which is a valid representation of a date. Although GRAPHIC and VARGRAPHIC are mapped to character variables in COBOL for AS/400, SQL considers these GRAPHIC and VARGRAPHIC variables. If the GRAPHIC or VARGRAPHIC column has a UCS-2 CCSID, the generated host variable will have the UCS-2 CCSID assigned to it.

Chapter 13. Coding SQL Statements in COBOL Applications

273

Determining Equivalent SQL and COBOL Data Types


The precompiler determines the base SQLTYPE and SQLLEN of host variables based on the following table. If a host variable appears with an indicator variable, the SQLTYPE is the base SQLTYPE plus one.
Table 26. COBOL Declarations Mapped to Typical SQL Data Types
COBOL Data Type S9(i)V9(d) COMP-3 or S9(i)V9(d) COMP or S9(i)V9(d) PACKED-DECIMAL S9(i)V9(d) DISPLAY SIGN LEADING SEPARATE SQLTYPE of Host Variable 484 SQLLEN of Host Variable SQL Data Type i+d in byte 1, d in DECIMAL(i+d,d) byte 2 i+d in byte 1, d in No exact byte 2 equivalent use DECIMAL(i+d,d) or NUMERIC (i+d,d) i+d in byte 1, d in NUMERIC(i+d,d) byte 2 2 4 SMALLINT INTEGER

504

S9(i)V9(d)DISPLAY S9(i) BINARY or S9(i) COMP-4 where i is from 1 to 4 S9(i) BINARY or S9(i) COMP-4 where i is from 5 to 9 S9(i)V9(d) BINARY or S9(i)V9(d) COMP-4 where i+d 4

488 500 496 500

i+d in byte 1, d in No exact byte 2 equivalent use DECIMAL(i+d,d) or NUMERIC (i+d,d) i+d in byte 1, d in No exact byte 2 equivalent use DECIMAL(i+d,d) or NUMERIC (i+d,d) 4 8 m m m m m m FLOAT(single precision) FLOAT(double precision) CHAR(m) VARCHAR(m) VARCHAR(m) GRAPHIC(m) VARGRAPHIC(m) VARGRAPHIC(m) DATE TIME 26 TIMESTAMP

S9(i)V9(d) BINARY or S9(i)V9(d) COMP-4 where 4 < i+d 9

496

COMP-1 COMP-2 Fixed-length character data Varying-length character data where m < 255 Varying-length character data where m > 254 Fixed-length graphic data Varying-length graphic data where m < 128 Varying-length graphic data where m > 127

480 480 452 448 456 468 464 472 384 388 392

| | |

DATE TIME TIMESTAMP

274

DB2 UDB for AS/400 SQL Programming V4R4

The following table can be used to determine the COBOL data type that is equivalent to a given SQL data type.
Table 27. SQL Data Types Mapped to Typical COBOL Declarations
SQL Data Type SMALLINT INTEGER DECIMAL(p,s) COBOL Data Type S9(m) COMP-4 S9(m) COMP-4 If p<19: S9(p-s)V9(s) PACKED-DECIMAL or S9(p-s)V9(s) COMP or S9(p-s)V9(s) COMP-3 If p>18: Not supported If p<19: S9(p-s)V9(s) DISPLAY If p>18: Not supported COMP-1 for ILE COBOL for AS/400. Not supported for COBOL for AS/400. COMP-2 for ILE COBOL for AS/400. Not supported for COBOL for AS/400. Fixed-length character string Varying-length character string None 32766n1 32740n1 Use SQL TYPE IS to declare a BLOB. For ILE COBOL for AS/400. Not supported for COBOL for AS/400. Use SQL TYPE IS to declare a CLOB. For ILE COBOL for AS/400. Not supported for COBOL for AS/400. Notes m is from 1 to 4 m is from 5 to 9

p is precision; s is scale. 0<=s<=p<=18. If s=0, use S9(p) or S9(p)V. If s=p, use SV9(s). p is precision; s is scale. 0<=s<=p<=18. If s=0, use S9(p) or S9(p)V. If s=p, use SV9(s).

NUMERIC(p,s)

FLOAT(single precision)

FLOAT(double precision)

CHAR(n) VARCHAR(n) BLOB

CLOB

None

GRAPHIC(n)

Fixed-length graphic string for 16383n1 ILE COBOL for AS/400. Not supported for COBOL for AS/400. Varying-length graphic string for ILE COBOL for AS/400. Not supported for COBOL for AS/400. None 16370n1

VARGRAPHIC(n)

DBCLOB

Use SQL TYPE IS to declare a DBCLOB. For ILE COBOL for AS/400. Not supported for COBOL for AS/400. Fixed-length character string If the format is *USA, *JIS, *EUR, or *ISO, allow at least 10 characters. If the format is *YMD, *DMY, or *MDY, allow at least 8 characters. If the format is *JUL, allow at least 6 characters.

DATE

or DATE (for ILE COBOL for AS/400)

Chapter 13. Coding SQL Statements in COBOL Applications

275

Table 27. SQL Data Types Mapped to Typical COBOL Declarations (continued)
SQL Data Type TIME COBOL Data Type Fixed-length character string Notes Allow at least 6 characters; 8 to include seconds.

or TIME (for ILE COBOL for AS/400) TIMESTAMP n must be at least 19. To include microseconds at full precision, n must be 26. If n is less than 26, truncation occurs on the microseconds part.

Fixed-length character string

or TIMESTAMP (for ILE COBOL for AS/400) DATALINK Not supported

Notes on COBOL Variable Declaration and Usage


Any level 77 data description entry can be followed by one or more REDEFINES entries. However, the names in these entries cannot be used in SQL statements. Unpredictable results may occur when a structure contains levels dened below a FILLER item. The COBOL declarations for SMALLINT and INTEGER data types are expressed as a number of decimal digits. The database manager uses the full size of the integers and can place larger values in the host variable than would be allowed in the specied number of digits in the COBOL declaration. However, this can cause data truncation or size errors when COBOL statements are being run. Ensure that the size of numbers in your application is within the declared number of digits.

Using Indicator Variables


An indicator variable is a two-byte integer (PIC S9(m) USAGE BINARY, where m is from 1 to 4). You can also specify an indicator structure (dened as an array of halfword integer variables) to support a host structure. On retrieval, an indicator variable is used to show whether its associated host variable has been assigned a null value. On assignment to a column, a negative indicator variable is used to indicate that a null value should be assigned. See DB2 UDB for AS/400 SQL Reference for more information on the use of indicator variables. Indicator variables are declared in the same way as host variables, and the declarations of the two can be mixed in any way that seems appropriate to the programmer.

Example:
Given the statement:

276

DB2 UDB for AS/400 SQL Programming V4R4

EXEC SQL FETCH CLS_CURSOR INTO :CLS-CD, :NUMDAY :NUMDAY-IND, :BGN :BGN-IND, :ENDCLS :ENDCLS-IND END-EXEC.

The variables can be declared as follows:


EXEC SQL BEGIN DECLARE SECTION END-EXEC. 77 CLS-CD PIC X(7). 77 NUMDAY PIC S9(4) BINARY. 77 BGN PIC X(8). 77 ENDCLS PIC X(8). 77 NUMDAY-IND PIC S9(4) BINARY. 77 BGN-IND PIC S9(4) BINARY. 77 ENDCLS-IND PIC S9(4) BINARY. EXEC SQL END DECLARE SECTION END-EXEC.

Chapter 13. Coding SQL Statements in COBOL Applications

277

278

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 14. Coding SQL Statements in PL/I Applications


This chapter describes the unique application and coding requirements for embedding SQL statements in an AS/400 PL/I program. Requirements for host structures and host variables are dened. A detailed sample PL/I program, showing how SQL statements can be used, is provided in Appendix C. Sample Programs Using DB2 UDB for AS/400 Statements.

Dening the SQL Communications Area


A PL/I program that contains SQL statements must include one or both of the following: v An SQLCODE variable declared as FIXED BINARY(31) v An SQLSTATE variable declared as CHAR(5) Or, v An SQLCA (which contains an SQLCODE and SQLSTATE variable). The SQLCODE and SQLSTATE values are set by the database manager after each SQL statement is executed. An application can check the SQLCODE or SQLSTATE value to determine whether the last SQL statement was successful. The SQLCA can be coded in a PL/I program either directly or by using the SQL INCLUDE statement. Using the SQL INCLUDE statement requests the inclusion of a standard SQLCA declaration:
EXEC SQL INCLUDE SQLCA ;

The scope of the SQLCODE, SQLSTATE, and SQLCA variables must include the scope of all SQL statements in the program. The included PL/I source statements for the SQLCA are:
DCL 1 SQLCA, 2 SQLCAID 2 SQLCABC 2 SQLCODE 2 SQLERRM 2 SQLERRP 2 SQLERRD(6) 2 SQLWARN, 3 SQLWARN0 3 SQLWARN1 3 SQLWARN2 3 SQLWARN3 3 SQLWARN4 3 SQLWARN5 3 SQLWARN6 3 SQLWARN7 3 SQLWARN8 3 SQLWARN9 3 SQLWARNA 2 SQLSTATE CHAR(8), FIXED(31) BINARY, FIXED(31) BINARY, CHAR(70) VAR, CHAR(8), FIXED(31) BINARY, CHAR(1), CHAR(1), CHAR(1), CHAR(1), CHAR(1), CHAR(1), CHAR(1), CHAR(1), CHAR(1), CHAR(1), CHAR(1), CHAR(5);

Copyright IBM Corp. 1997, 1999

279

SQLCODE is replaced with SQLCADE when a declare for SQLCODE is found in the program and the SQLCA is provided by the precompiler. SQLSTATE is replaced with SQLSTOTE when a declare for SQLSTATE is found in the program and the SQLCA is provided by the precompiler. For more information on SQLCA, see Appendix B, SQL Communication Area in the DB2 UDB for AS/400 SQL Reference book.

Dening SQL Descriptor Areas


The following statements require an SQLDA: EXECUTE...USING DESCRIPTOR descriptor-name FETCH...USING DESCRIPTOR descriptor-name OPEN...USING DESCRIPTOR descriptor-name CALL...USING DESCRIPTOR descriptor-name DESCRIBE statement-name INTO descriptor-name DESCRIBE TABLE host-variable INTO descriptor-name PREPARE statement-name INTO descriptor-name Unlike the SQLCA, there can be more than one SQLDA in a program, and an SQLDA can have any valid name. An SQLDA can be coded in a PL/I program either program directly or by using the SQL INCLUDE statement. Using the SQL INCLUDE statement requests the inclusion of a standard SQLDA declaration:
EXEC SQL INCLUDE SQLDA ;

The included PL/I source statements for the SQLDA are:


DCL 1 SQLDA BASED(SQLDAPTR), 2 SQLDAID CHAR(8), 2 SQLDABC FIXED(31) BINARY, 2 SQLN FIXED(15) BINARY, 2 SQLD FIXED(15) BINARY, 2 SQLVAR(99), 3 SQLTYPE FIXED(15) BINARY, 3 SQLLEN FIXED(15) BINARY, 3 SQLRES CHAR(12), 3 SQLDATA PTR, 3 SQLIND PTR, 3 SQLNAME CHAR(30) VAR; DCL SQLDAPTR PTR;

Dynamic SQL is an advanced programming technique described in Chapter 10. Dynamic SQL Applications. With dynamic SQL, your program can develop and then run SQL statements while the program is running. A SELECT statement with a variable SELECT list (that is, a list of the data to be returned as part of the query) that runs dynamically requires an SQL descriptor area (SQLDA). This is because you cannot know in advance how many or what type of variables to allocate in order to receive the results of the SELECT. For more information on SQLDA, see the DB2 UDB for AS/400 SQL Reference book.

Embedding SQL Statements


The rst statement of the PL/I program must be a PROCEDURE statement.

280

DB2 UDB for AS/400 SQL Programming V4R4

SQL statements can be coded in a PL/I program wherever executable statements can appear. Each SQL statement in a PL/I program must begin with EXEC SQL and end with a semicolon (;). The key words EXEC SQL must appear all on one line, but the remainder of the statement can appear on the next and subsequent lines.

Example
An UPDATE statement coded in a PL/I program might be coded as follows:
EXEC SQL UPDATE DEPARTMENT SET MGRNO = :MGR_NUM WHERE DEPTNO = :INT_DEPT ;

Comments
In addition to SQL comments (--), you can include PL/I comments (/*...*/) in embedded SQL statements wherever a blank is allowed, except between the keywords EXEC and SQL.

Continuation for SQL Statements


The line continuation rules for SQL statements are the same as those for other PL/I statements, except that EXEC SQL must be specied within one line. Constants containing DBCS data can be continued across multiple lines by placing the shift-in and shift-out characters outside of the margins. This example assumes margins of 2 and 72. This SQL statement has a valid graphic constant of G<AABBCCDDEEFFGGHHIIJJKK>.
*(..+....1....+....2....+....3....+....4....+....5....+....6....+....7.).. EXEC SQL SELECT * FROM GRAPHTAB WHERE GRAPHCOL = G'<AABBCCDD> <EEFFGGHHIIJJKK>';

Including Code
SQL statements or PL/I host variable declaration statements can be included by placing the following SQL statement at the point in the source code where the statements are to be embedded:
EXEC SQL INCLUDE member-name ;

No PL/I preprocessor directives are permitted within SQL statements. PL/I %INCLUDE statements cannot be used to include SQL statements or declarations of PL/I host variables that are referenced in SQL statements.

Margins
Code SQL statements within the margins specied by the MARGINS parameter on the CRTSQLPLI command. If EXEC SQL does not start within the specied margins, the SQL precompiler will not recognize the SQL statement. For more information about the CRTSQLPLI command, see Appendix D. DB2 UDB for AS/400 CL Command Descriptions.

Chapter 14. Coding SQL Statements in PL/I Applications

281

Names
Any valid PL/I variable name can be used for a host variable and is subject to the following restrictions: Do not use host variable names or external entry names that begin with 'SQL', 'RDI', or 'DSN'. These names are reserved for the database manager.

Statement Labels
All executable SQL statements, like PL/I statements, can have a label prex.

WHENEVER Statement
The target for the GOTO clause in an SQL WHENEVER statement must be a label in the PL/I source code and must be within the scope of any SQL statements affected by the WHENEVER statement.

Using Host Variables


All host variables used in SQL statements must be explicitly declared. The PL/I statements that are used to dene the host variables should be preceded by a BEGIN DECLARE SECTION statement and followed by an END DECLARE SECTION statement. If a BEGIN DECLARE SECTION and END DECLARE SECTION are specied, all host variable declarations used in SQL statements must be between the BEGIN DECLARE SECTION and the END DECLARE SECTION statements. All host variables within an SQL statement must be preceded by a colon (:). The names of host variables must be unique within the program, even if the host variables are in different blocks or procedures. An SQL statement that uses a host variable must be within the scope of the statement in which the variable was declared. Host variables must be scalar variables. They cannot be elements of an array.

Declaring Host Variables


The PL/I precompilers only recognize a subset of valid PL/I declarations as valid host variable declarations. Only the names and data attributes of the variables are used by the precompilers; the alignment, scope, and storage attributes are ignored. Even though alignment, scope, and storage are ignored, there are some restrictions on their use that, if ignored, may result in problems when compiling PL/I source code that is created by the precompiler. These restrictions are: v A declaration with the EXTERNAL scope attribute and the STATIC storage attribute must also have the INITIAL storage attribute. v If the BASED storage attribute is coded, it must be followed by a PL/I element-locator-expression.

282

DB2 UDB for AS/400 SQL Programming V4R4

Numeric-Host Variables
The following gure shows the syntax for valid scalar numeric-host variable declarations.

Numeric
DECLARE DCL variable-name , ( variable-name )

BINARY BIN

FIXED ( precision ) FLOAT ( precision )

DECIMAL DEC

FIXED ( precision ,scale FLOAT ( precision ) )

PICTURE picture-string

; Alignment and/or Scope and/or Storage

Notes: 1. (BINARY, BIN, DECIMAL, or DEC) and (FIXED or FLOAT) and (precision, scale) can be specied in any order. 2. A picture-string in the form 9...9V9...R indicates a numeric host variable. The R is required. The optional V indicates the implied decimal point. 3. A picture-string in the form S9...9V9...9 indicates a sign leading separate host variable. The S is required. The optional V indicates the implied decimal point.

Character-Host Variables
The following gure shows the syntax for valid scalar character-host variables.

Chapter 14. Coding SQL Statements in PL/I Applications

283

Character
DECLARE DCL variable-name , ( variable-name ) CHARACTER CHAR

length )

VARYING VAR

; Alignment and/or Scope and/or Storage

Notes: 1. Length must be an integer constant not greater than 32766 if VARYING or VAR is not specied. 2. If VARYING or VAR is specied, length must be a constant no greater than 32740. | | | | | |

LOB Host Variables


The following gure shows the syntax for valid LOB host variables.

LOB
DECLARE DCL variable-name , ( variable-name ) SQL TYPE IS BLOB CLOB

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

lob-length K

; Alignment and/or Scope and/or Storage

Notes: 1. The SQL TYPE IS clause is needed in order to distinguish the three LOB-types from each other so that type-checking and function resolution can be carried out for LOB-type host variables that are passed to functions. 2. For BLOB and CLOB, 1 <= lob-length <= 32,766 3. SQL TYPE IS, BLOB, CLOB can be in mixed case. 4. LOB Host Variables can be declared in host structures.

284

DB2 UDB for AS/400 SQL Programming V4R4

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

BLOB Example:
The following declaration:
DCL MY_BLOB SQL TYPE IS BLOB(16384);

Results in the generation of the following structure:


DCL 1 MY_BLOB, 3 MY_BLOB_LENGTH BINARY FIXED (31), 3 MY_BLOB_DATA CHARACTER (16384);

CLOB Example:
The following declaration:
DCL MY_CLOB SQL TYPE IS CLOB(16384);

Results in the generation of the following structure:


DCL 1 MY_CLOB, 3 MY_CLOB_LENGTH BINARY FIXED (31), 3 MY_CLOB_DATA CHARACTER (16384);

LOB Locators
The following gure shows the syntax for valid LOB locators.

LOB locator
DECLARE DCL variable-name , ( variable-name )

| |

SQL TYPE IS

BLOB_LOCATOR CLOB_LOCATOR DBCLOB_LOCATOR

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

; Alignment and/or Scope and/or Storage

Notes: 1. SQL TYPE IS, BLOB_LOCATOR, CLOB_LOCATOR, DBCLOB_LOCATOR can be in mixed case. 2. LOB Locators can be declared as part of a host structure.

CLOB Example:
The following declaration:
DCL MY_LOCATOR SQL TYPE IS CLOB_LOCATOR;

Results in the generation of the following structure:


DCL MY_LOCATOR BINARY FIXED(32);

Chapter 14. Coding SQL Statements in PL/I Applications

285

| | | | | | |

BLOB and DBCLOB locators have similar syntax.

LOB File Reference Variables


The following gure shows the syntax for valid LOB le reference variables.

LOB le reference variable


DECLARE DCL variable-name , ( variable-name )

| |

SQL TYPE IS

BLOB_FILE CLOB_FILE DBCLOB_FILE

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

; Alignment and/or Scope and/or Storage

Notes: 1. SQL TYPE IS, BLOB_LOCATOR, CLOB_LOCATOR, DBCLOB_LOCATOR can be in mixed case. 2. LOB File Reference Variables can be declared as part of a host structure.

CLOB Example:
The following declaration:
DCL MY_FILE SQL TYPE IS CLOB_FILE;

Results in the generation of the following structure:


DCL 1 MY_FILE, 3 MY_FILE_NAME_LENGTH BINARY FIXED(32), 3 MY_FILE_DATA_LENGTH BINARY FIXED(32), 3 MY_FILE_FILE_OPTIONS BINARY FIXED(32), 3 MY_FILE_NAME CHAR(255);

BLOB and DBCLOB locators have similar syntax. The pre-compiler will generate declarations for the following le option constants: v SQL_FILE_READ (2) v SQL_FILE_CREATE (8) v SQL_FILE_OVERWRITE (16) v SQL_FILE_APPEND (32)

Using Host Structures


In PL/I programs, you can dene a host structure, which is a named set of elementary PL/I variables. A host structure name can be a group name whose subordinate levels name elementary PL/I variables. For example:

286

DB2 UDB for AS/400 SQL Programming V4R4

DCL 1 A, 2 B, 3 C1 CHAR(...), 3 C2 CHAR(...);

In this example, B is the name of a host structure consisting of the elementary items C1 and C2. You can use the structure name as shorthand notation for a list of scalars. You can qualify a host variable with a structure name (for example, STRUCTURE.FIELD). Host structures are limited to two levels. (For example, in the above host structure example, the A cannot be referred to in SQL.) A structure cannot contain an intermediate level structure. In the previous example, A could not be used as a host variable or referred to in an SQL statement. However, B is the rst level structure. B can be referred to in an SQL statement. A host structure for SQL data is two levels deep and can be thought of as a named set of host variables. After the host structure is dened, you can refer to it in an SQL statement instead of listing the several host variables (that is, the names of the host variables that make up the host structure). For example, you can retrieve all column values from selected rows of the table CORPDATA.EMPLOYEE with:
DCL 1 PEMPL, 5 EMPNO CHAR(6), 5 FIRSTNME CHAR(12) VAR, 5 MIDINIT CHAR(1), 5 LASTNAME CHAR(15) VAR, 5 WORKDEPT CHAR(3); ... EMPID = '000220'; ... EXEC SQL SELECT * INTO :PEMPL FROM CORPDATA.EMPLOYEE WHERE EMPNO = :EMPID;

Host Structures
The following gure shows the syntax for valid host structure declarations.

Chapter 14. Coding SQL Statements in PL/I Applications

287

Host Structures
DECLARE 1 variable-name DCL level-1 variable-name , , level-2 var-1 , ( var-2 ) data-types ; , Scope and/or storage

data-types:
BINARY BIN DECIMAL DEC FIXED FLOAT FIXED ( FLOAT ( precision ) UNALIGNED PICTURE picture-string CHARACTER CHAR ( length ) VARYING VAR ALIGNED ( precision ) precision , scale UNALIGNED )

Notes: 1. Level-1 indicates that there is an intermediate level structure. 2. Level-1 must be an integer constant between 1 and 254. 3. Level-2 must be an integer constant between 2 and 255. 4. For details on declaring numeric and character host variables, see the notes under numeric-host variables and character-host variables.

Host Structure Indicator Arrays


The following gure shows the syntax for valid indicator arrays.

288

DB2 UDB for AS/400 SQL Programming V4R4

Host Structure Indicator Array


DECLARE DCL variable-name ( dimension ) , ( variable-name ( dimension ) )

BINARY BIN

FIXED ( precision )

; Alignment and/or scope and/or storage

Note: Dimension must be an integer constant between 1 and 32766.

Using Host Structure Arrays


In PL/I programs, you can dene a host structure array. In these examples, the following are true: v B_ARRAY is the name of a host structure array that contains the items C1_VAR and C2_VAR. v B_ARRAY cannot be qualied. v B_ARRAY can only be used with the blocked forms of the FETCH and INSERT statements. v All items in B_ARRAY must be valid host variables. v C1_VAR and C2_VAR are not valid host variables in any SQL statement. A structure cannot contain an intermediate level structure. A_STRUCT cannot contain the dimension attribute.
DCL 1 A_STRUCT, 2 B_ARRAY(10), 3 C1_VAR CHAR(20), 3 C2_FIXED BIN(15) UNALIGNED;

To retrieve 10 rows from the CORPDATA.DEPARTMENT table, do the following:


DCL 1 DEPT(10), 5 DEPTPNO CHAR(3), 5 DEPTNAME CHAR(29) VAR, 5 MGRNO CHAR(6), 5 ADMRDEPT CHAR (3); DCL 1 IND_ARRAY(10), 5 INDS(4) FIXED BIN(15); EXEC SQL DECLARE C1 CURSOR FOR SELECT * FROM CORPDATA.DEPARTMENT; EXEC SQL FETCH C1 FOR 10 ROWS INTO :DEPT :IND_ARRAY;

Chapter 14. Coding SQL Statements in PL/I Applications

289

Host Structure Array


The following syntax diagram shows the syntax for valid structure array declarations.

Host Structure Array


DECLARE 1 variable-name ( dimension ) DCL level-1 variable-name , , level-2 var-1 , ( var-2 ) data-types ; , Scope and/or storage

data-types:
BINARY BIN DECIMAL DEC FIXED FLOAT FIXED ( FLOAT UNALIGNED ( precision ) precision ) , scale UNALIGNED

( precision ) PICTURE picture-string CHARACTER CHAR ( length ) VARYING VAR

Notes: 1. Level-1 indicates that there is an intermediate level structure. 2. Level-1 must be an integer constant between 1 and 254. 3. Level-2 must be an integer constant between 2 and 255. 4. For details on declaring numeric and character host variables, see the notes under numeric-host variables and character-host variables. 5. Dimension must be an integer constant between 1 and 32767.

Host Structure Array Indicator


The following gure shows the syntax diagram for valid host structure array indicator structure declarations.

290

DB2 UDB for AS/400 SQL Programming V4R4

Host Structure Array Indicator Structure


DECLARE 1 variable-name ( dimension ) DCL level-1 variable-name , level-2 identifier ( dimension-2 ) BINARY BIN , Scope and/or storage

FIXED ( precision )

Notes: 1. Level-1 indicates that there is an intermediate level structure. 2. Level-1 must be an integer constant between 1 and 254. 3. Level-2 must be an integer constant between 2 and 255. 4. Dimension-1 and dimension-2 must be integer constants between 1 and 32767.

Using External File Descriptions


You can use the PL/I %INCLUDE directive to include the denitions of externally described les in a source program. When used with SQL, only a particular format of the %INCLUDE directive is recognized by the SQL precompiler. That directive format must have the following three elements or parameter values, otherwise the precompiler ignores the directive. The required elements are le name, format name, and element type. There are two optional elements supported by the SQL precompiler: prex name and COMMA. The structure is ended normally by the last data element of the record or key structure. However, if in the %INCLUDE directive the COMMA element is specied, then the structure is not ended. For more information about the %INCLUDE directive, see the PL/I Reference Summary book, SX09-1290, and the PL/I Users Guide and Reference book, SC09-1825. To include the denition of the sample table DEPARTMENT described in Appendix A. DB2 UDB for AS/400 Sample Tables, you can code:
DCL 1 TDEPT_STRUCTURE, %INCLUDE DEPARTMENT(DEPARTMENT,RECORD);

In the above example, a host structure named TDEPT_STRUCTURE would be dened having four elds. The elds would be DEPTNO, DEPTNAME, MGRNO, and ADMRDEPT. For device les, if INDARA was not specied and the le contains indicators, the declaration cannot be used as a host structure array. The indicator area is included in the generated structure and causes the storage to not be contiguous.
DCL : 1 DEPT_REC(10), %INCLUDE DEPARTMENT(DEPARTMENT,RECORD);

EXEC SQL DECLARE C1 CURSOR FOR SELECT * FROM CORPDATA.DEPARTMENT; EXEC SQL OPEN C1;
Chapter 14. Coding SQL Statements in PL/I Applications

291

EXEC SQL FETCH C1 FOR 10 ROWS INTO :DEPT_REC;

Note: DATE, TIME, and TIMESTAMP columns will generate host variable denitions that are treated by SQL with the same comparison and assignment rules as a DATE, TIME, and TIMESTAMP column. For example, a date host variable can only be compared with a DATE column or a character string that is a valid representation of a date. Although decimal and zoned elds with precision greater than 15 and binary with nonzero scale elds are mapped to character eld variables in PL/I, SQL considers these elds to be numeric. Although GRAPHIC and VARGRAPHIC are mapped to character variables in PL/I, SQL considers these to be GRAPHIC and VARGRAPHIC host variables. If the GRAPHIC or VARGRAPHIC column has a UCS-2 CCSID, the generated host variable will have the UCS-2 CCSID assigned to it.

Determining Equivalent SQL and PL/I Data Types


The precompiler determines the base SQLTYPE and SQLLEN of host variables based on the following table. If a host variable appears with an indicator variable, the SQLTYPE is the base SQLTYPE plus one.
Table 28. PL/I Declarations Mapped to Typical SQL Data Types
PL/I Data Type BIN FIXED(p) where p is in the range 1 to 15 BIN FIXED(p) where p is in the range 16 to 31 DEC FIXED(p,s) BIN FLOAT(p) p is in the range 1 to 24 BIN FLOAT(p) p is in the range 25 to 53 SQLTYPE of Host Variable 500 496 484 480 480 SQLLEN of Host Variable SQL Data Type 2 4 p in byte 1, s in byte 2 4 8 4 8 p in byte 1, s in byte 2 p in byte 1, s in byte 2 n n n SMALLINT INTEGER DECIMAL(p,s) FLOAT (single precision) FLOAT (double precision) FLOAT (single precision) FLOAT (double precision) NUMERIC (p,s) No exact equivalent, use NUMERIC(p,s). CHAR(n) VARCHAR(n) VARCHAR(n)

DEC FLOAT(m) m is in the range 1 480 to 7 DEC FLOAT(m) m is in the range 8 480 to 16 PICTURE picture string (numeric) PICTURE picture string (sign leading separate) CHAR(n) CHAR(n) VARYING where n <255 CHAR(n) varying where n > 254 488 504

452 448 456

292

DB2 UDB for AS/400 SQL Programming V4R4

The following table can be used to determine the PL/I data type that is equivalent to a given SQL data type.
Table 29. SQL Data Types Mapped to Typical PL/I Declarations
SQL Data Type SMALLINT INTEGER DECIMAL(p,s) or NUMERIC(p,s) PL/I Equivalent BIN FIXED(p) BIN FIXED(p) DEC FIXED(p) or DEC FIXED(p,s) or PICTURE picture-string Explanatory Notes p is a positive integer from 1 to 15. p is a positive integer from 16 to 31.

s (the scale factor) and p (the precision) are positive integers. p is a positive integer from 1 to 31. s is a positive integer from 0 to p. p is a positive integer from 1 to 24. m is a positive integer from 1 to 7.

FLOAT (single precision)

BIN FLOAT(p) or DEC FLOAT(m)

FLOAT (double precision)

BIN FLOAT(p) or DEC FLOAT(m)

p is a positive integer from 25 to 53. m is a positive integer from 8 to 16.

CHAR(n) VARCHAR(n) BLOB CLOB GRAPHIC(n) VARGRAPHIC(n) DBCLOB DATE

CHAR(n) CHAR(n) VAR None None Not supported Not supported None CHAR(n)

n is a positive integer from 1 to 32766. n is a positive integer from 1 to 32740.


Use SQL TYPE IS to declare a BLOB. Use SQL TYPE IS to declare a CLOB. Not supported. Not supported. Use SQL TYPE IS to declare a DBCLOB. If the format is *USA, *JIS, *EUR, or *ISO, n must be at least 10 characters. If the format is *YMD, *DMY, or *MDY, n must be at least 8 characters. If the format is *JUL, n must be at least 6 characters.

TIME

CHAR(n)

n must be at least 6; to include seconds, n must be at least 8. n must be at least 19. To include microseconds at full precision, n must be 26; if n is less than 26, truncation occurs on the microseconds part.

TIMESTAMP

CHAR(n)

Chapter 14. Coding SQL Statements in PL/I Applications

293

Table 29. SQL Data Types Mapped to Typical PL/I Declarations (continued)
SQL Data Type DATALINK PL/I Equivalent Not supported Explanatory Notes Not supported

Using Indicator Variables


An indicator variable is a two-byte integer (BIN FIXED(p), where p is 1 to 15). You can also specify an indicator structure (dened as an array of halfword integer variables) to support a host structure. On retrieval, an indicator variable is used to show whether its associated host variable has been assigned a null value. On assignment to a column, a negative indicator variable is used to indicate that a null value should be assigned. See DB2 UDB for AS/400 SQL Reference book for more information about using indicator variables. Indicator variables are declared in the same way as host variables and the declarations of the two can be mixed in any way that seems appropriate to the programmer.

Example:
Given the statement:
EXEC SQL FETCH CLS_CURSOR INTO :CLS_CD, :DAY :DAY_IND, :BGN :BGN_IND, :END :END_IND;

Variables can be declared as follows:


EXEC SQL BEGIN DECLARE SECTION; DCL CLS_CD CHAR(7); DCL DAY BIN FIXED(15); DCL BGN CHAR(8); DCL END CHAR(8); DCL (DAY_IND, BGN_IND, END_IND) EXEC SQL END DECLARE SECTION;

BIN FIXED(15);

Differences in PL/I Because of Structure Parameter Passing Techniques


The PL/I precompiler attempts to use the structure parameter passing technique, if possible. This structure parameter passing technique provides better performance for most PL/I programs using SQL. The precompiler generates code where each host variable is a separate parameter when the following conditions are true: v A PL/I %INCLUDE compiler directive is found that copies external text into the source program. v The data length of the host variables referred to in the statement is greater than 32703. Because SQL uses 64 bytes of the structure, 32703 + 64 = 32767, the maximum length of a data structure. v The PL/I precompiler estimates that it could possibly exceed the PL/I limit for user-dened names. v A sign leading separate host variable is found in the host variable list for the SQL statement.

294

DB2 UDB for AS/400 SQL Programming V4R4

For more information on the structure parameter passing technique, see Improving Performance by Using Structure Parameter Passing Techniques on page 472.

Chapter 14. Coding SQL Statements in PL/I Applications

295

296

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 15. Coding SQL Statements in RPG for AS/400 Applications


The RPG for AS/400 licensed program supports both RPG II and RPG III programs. SQL statements can only be used in RPG III programs. RPG II and AutoReport are NOT supported. All referrals to RPG in this guide apply to RPG III or ILE RPG only. This chapter describes the unique application and coding requirements for embedding SQL statements in a RPG for AS/400 program. Requirements for host variables are dened. A detailed sample RPG for AS/400 program, showing how SQL statements can be used, is provided in Appendix C. Sample Programs Using DB2 UDB for AS/400 Statements.

Dening the SQL Communications Area


The SQL precompiler automatically places the SQLCA in the input specications of the RPG for AS/400 program prior to the rst calculation specication. INCLUDE SQLCA should not be coded in the source program. If the source program species INCLUDE SQLCA, the statement will be accepted, but it is redundant. The SQLCA, as dened for RPG for AS/400:
ISQLCA DS I* SQL Communications area I I I I I I I I I I I I I I I I I I I I I I I I I I I* End of SQLCA 1 9 13 17 19 89 97 97 101 105 109 113 117 121 121 122 123 124 125 126 127 128 129 130 131 132 8 SQLAID 120SQLABC 160SQLCOD 180SQLERL 88 SQLERM 96 SQLERP 120 SQLERR 1000SQLER1 1040SQLER2 1080SQLER3 1120SQLER4 1160SQLER5 1200SQLER6 131 SQLWRN 121 SQLWN0 122 SQLWN1 123 SQLWN2 124 SQLWN3 125 SQLWN4 126 SQLWN5 127 SQLWN6 128 SQLWN7 129 SQLWN8 130 SQLWN9 131 SQLWNA 136 SQLSTT SQL SQL SQL SQL SQL SQL SQL SQL SQL SQL SQL SQL SQL SQL SQL SQL SQL SQL SQL SQL SQL SQL SQL SQL SQL SQL SQL SQL SQL

B B B

B B B B B B

Note: Variable names in RPG for AS/400 are limited to 6 characters. The standard SQLCA names have been changed to a length of 6. RPG for AS/400 does not have a way of dening arrays in a data structure without also dening them in the extension specication. SQLERR is dened as character with SQLER1 through 6 used as the names of the elements.

Copyright IBM Corp. 1997, 1999

297

See the DB2 UDB for AS/400 SQL Reference book for more information.

Dening SQL Descriptor Areas


The following statements require an SQLDA: EXECUTE...USING DESCRIPTOR descriptor-name FETCH...USING DESCRIPTOR descriptor-name OPEN...USING DESCRIPTOR descriptor-name CALL...USING DESCRIPTOR descriptor-name DESCRIBE statement-name INTO descriptor-name DESCRIBE TABLE host-variable INTO descriptor-name PREPARE statement-name INTO descriptor-name Unlike the SQLCA, there can be more than one SQLDA in a program and an SQLDA can have any valid name. Dynamic SQL is an advanced programming technique described in Chapter 10. Dynamic SQL Applications. With dynamic SQL, your program can develop and then run SQL statements while the program is running. A SELECT statement with a variable SELECT list (that is, a list of the data to be returned as part of the query) that runs dynamically requires an SQL descriptor area (SQLDA). This is because you cannot know in advance how many or what type of variables to allocate in order to receive the results of the SELECT. Because the SQLDA uses pointer variables which are not supported by RPG for AS/400, an INCLUDE SQLDA statement cannot be specied in an RPG for AS/400 program. An SQLDA must be set up by a C, COBOL, PL/I, or ILE RPG program and passed to the RPG program in order to use it.

Embedding SQL Statements


SQL statements coded in an RPG for AS/400 program must be placed in the calculation section. This requires that a C be placed in position 6. SQL statements can be placed in detail calculations, in total calculations, or in an RPG for AS/400 subroutine. The SQL statements are executed based on the logic of the RPG for AS/400 statements. The keywords EXEC SQL indicate the beginning of an SQL statement. EXEC SQL must occupy positions 8 through 16 of the source statement, preceded by a / in position 7. The SQL statement may start in position 17 and continue through position 74. The keyword END-EXEC ends the SQL statement. END-EXEC must occupy positions 8 through 16 of the source statement, preceded by a slash (/) in position 7. Positions 17 through 74 must be blank. Both uppercase and lowercase letters are acceptable in SQL statements.

Example
An UPDATE statement coded in an RPG for AS/400 program might be coded as follows:

298

DB2 UDB for AS/400 SQL Programming V4R4

*...1....+....2....+....3....+....4....+....5....+....6....+....7...* C/EXEC SQL UPDATE DEPARTMENT C+ SET MANAGER = :MGRNUM C+ WHERE DEPTNO = :INTDEP C/END-EXEC

Comments
In addition to SQL comments (--), RPG for AS/400 comments can be included within SQL statements wherever a blank is allowed, except between the keywords EXEC and SQL. To embed an RPG for AS/400 comment within the SQL statement, place an asterisk (*) in position 7.

Continuation for SQL Statements


When additional records are needed to contain the SQL statement, positions 9 through 74 can be used. Position 7 must be a + (plus sign), and position 8 must be blank. Constants containing DBCS data can be continued across multiple lines by placing the shift-in character in position 75 of the continued line and placing the shift-out character in position 8 of the continuation line. This SQL statement has a valid graphic constant of G<AABBCCDDEEFFGGHHIIJJKK>.
*...1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 C/EXEC SQL SELECT * FROM GRAPHTAB WHERE GRAPHCOL = G'<AABB> C+<CCDDEEFFGGHHIIJJKK>' C/END-EXEC

Including Code
SQL statements and RPG for AS/400 calculation specications can be included by embedding the SQL statement:
*...1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 C/EXEC SQL INCLUDE member-name C/END-EXEC

The /COPY statement can be used to include SQL statements or RPG for AS/400 specications.

Sequence Numbers
The sequence numbers of the source statements generated by the SQL precompiler are based on the *NOSEQSRC/*SEQSRC keywords of the OPTION parameter on the CRTSQLRPG command. When *NOSEQSRC is specied, the sequence number from the input source member is used. For *SEQSRC, the sequence numbers start at 000001 and are incremented by 1.

Names
Any valid RPG variable name can be used for a host variable and is subject to the following restrictions: Do not use host variable names or external entry names that begin with 'SQ', 'SQL', 'RDI', or 'DSN'. These names are reserved for the database manager.

Chapter 15. Coding SQL Statements in RPG for AS/400 Applications

299

Statement Labels
A TAG statement can precede any SQL statement. Code the TAG statement on the line preceding EXEC SQL.

WHENEVER Statement
The target for the GOTO clause must be the label of the TAG statement. The scope rules for the GOTO/TAG must be observed.

Using Host Variables


| | All host variables used in SQL statements must be explicitly declared. LOB host variables are not supported in RPG for AS/400. SQL embedded in RPG for AS/400 does not use the SQL BEGIN DECLARE SECTION and END DECLARE SECTION statements to identify host variables. Do not put these statements in the source program. All host variables within an SQL statement must be preceded by a colon (:). The names of host variables must be unique within the program.

Declaring Host Variables


The SQL RPG for AS/400 precompiler only recognizes a subset of RPG for AS/400 declarations as valid host variable declarations. All variables dened in RPG for AS/400 can be used in SQL statements, except for the following: Indicator eld names (*INxx) Tables UDATE UDAY UMONTH UYEAR Look-ahead elds Named constants Fields used as host variables are passed to SQL, using the CALL/PARM functions of RPG for AS/400. If a eld cannot be used in the result eld of the PARM, it cannot be used as a host variable.

Using Host Structures


The RPG for AS/400 data structure name can be used as a host structure name if subelds exist in the data structure. The use of the data structure name in an SQL statement implies the list of subeld names making up the data structure. When subelds are not present for the data structure, then the data structure name is a host variable of character type. This allows character variables larger than 256, because data structures can be up to 9999.

300

DB2 UDB for AS/400 SQL Programming V4R4

In the following example, BIGCHR is an RPG for AS/400 data structure without subelds. SQL treats any referrals to BIGCHR as a character string with a length of 642.
*...1....+....2....+....3....+....4....+....5....+....6....+....7...* IBIGCHR DS 642

In the next example, PEMPL is the name of the host structure consisting of the subelds EMPNO, FIRSTN, MIDINT, LASTNAME, and DEPTNO. The referral to PEMPL uses the subelds. For example, the rst column of EMPLOYEE is placed in EMPNO, the second column is placed in FIRSTN, and so on.
*...1....+....2....+....3....+....4....+....5....+....6....+....7. ..* IPEMPL DS I 01 06 EMPNO I 07 18 FIRSTN I 19 19 MIDINT I 20 34 LASTNA I 35 37 DEPTNO C MOVE '000220' EMPNO

... ...

C/EXEC SQL C+ SELECT * INTO :PEMPL C+ FROM CORPDATA.EMPLOYEE C+ WHERE EMPNO = :EMPNO C/END-EXEC

When writing an SQL statement, referrals to subelds can be qualied. Use the name of the data structure, followed by a period and the name of the subeld. For example, PEMPL.MIDINT is the same as specifying only MIDINT.

Using Host Structure Arrays


A host structure array is dened as an occurrence data structure. An occurrence data structure can be used on the SQL FETCH statement when fetching multiple rows. In these examples, the following are true: v All items in BARRAY must be valid host variables. v All items in BARRAY must be contiguous. The rst FROM position must be 1 and there cannot be overlaps in the TO and FROM positions. v For all statements other than the multiple-row FETCH and blocked INSERT, if an occurrence data structure is used, the current occurrence is used. For the multiple-row FETCH and blocked INSERT, the occurrence is set to 1.
*...1....+....2....+....3....+....4....+....5....+....6....+....7. ..* IBARRAY DS 10 I 01 20 C1VAR I B 21 220C2VAR

The following example uses a host structure array called DEPT and a multiple-row FETCH statement to retrieve 10 rows from the DEPARTMENT table.
*...1....+....2....+....3....+....4....+....5....+....6....+....7...* E INDS 4 4 0 IDEPT DS 10 I 01 03 DEPTNO I 04 32 DEPTNM I 33 38 MGRNO I 39 41 ADMRD IINDARR DS 10
Chapter 15. Coding SQL Statements in RPG for AS/400 Applications

301

...

80INDS

C/EXEC SQL C+ DECLARE C1 CURSOR FOR C+ SELECT * C+ FROM CORPDATA.DEPARTMENT C/END-EXEC C/EXEC SQL C+ OPEN C1 C/END-EXEC C/EXEC SQL C+ FETCH C1 FOR 10 ROWS INTO :DEPT:INDARR C/END-EXEC

Using External File Descriptions


The SQL precompiler processes the RPG for AS/400 source in much the same manner as the ILE RPG for AS/400 compiler. This means that the precompiler processes the /COPY statement for denitions of host variables. Field denitions for externally described les are obtained and renamed, if different names are specied. The external denition form of the data structure can be used to obtain a copy of the column names to be used as host variables. In the following example, the sample table DEPARTMENT is used as a le in an ILE RPG for AS/400 program. The SQL precompiler retrieves the eld (column) denitions for DEPARTMENT for use as host variables.
*...1....+....2....+....3....+....4....+....5....+....6....+....7....* FTDEPT IP E DISK F TDEPT KRENAMEDEPTREC IDEPTREC I DEPTNAME DEPTN I ADMRDEPT ADMRD

Note: Code an F-spec for a le in your RPG program only if you use RPG for AS/400 statements to do I/O operations to the le. If you use only SQL statements to do I/O operations to the le, you can include the external denition by using an external data structure. In the following example, the sample table is specied as an external data structure. The SQL precompiler retrieves the eld (column) denitions as subelds of the data structure. Subeld names can be used as host variable names, and the data structure name TDEPT can be used as a host structure name. The eld names must be changed because they are greater than six characters.
*...1....+....2....+....3....+....4....+....5....+....6....+....7....* ITDEPT E DSDEPARTMENT I DEPTNAME DEPTN I ADMRDEPT ADMRD

Note: DATE, TIME, and TIMESTAMP columns will generate host variable denitions which are treated by SQL with the same comparison and assignment rules as a DATE, TIME, and TIMESTAMP column. For example, a date host variable can only be compared against a DATE column or a character string which is a valid representation of a date. Although varying-length columns generate xed-length character-host variable denitions, to SQL they are varying-length character variables.

302

DB2 UDB for AS/400 SQL Programming V4R4

Although GRAPHIC and VARGRAPHIC columns are mapped to character variables in RPG for AS/400, SQL considers these GRAPHIC and VARGRAPHIC variables. If the GRAPHIC or VARGRAPHIC column has a UCS-2 CCSID, the generated host variable will have the UCS-2 CCSID assigned to it.

External File Description Considerations for Host Structure Arrays


If the le contains oating-point elds, it cannot be used as a host structure array. For device les, if INDARA was not specied and the le contains indicators, the declaration is not used as a host structure array. The indicator area is included in the structure that is generated and would cause the storage to not be contiguous. In the following example, the DEPARTMENT table is included in the RPG for AS/400 program and is used to declare a host structure array. A multiple-row FETCH statement is then used to retrieve 10 rows into the host structure array.
*...1....+....2....+....3....+....4....+....5....+....6....* ITDEPT E DSDEPARTMENT 10 I DEPARTMENT DEPTN I ADMRDEPT ADMRD ... C/EXEC SQL C+ DECLARE C1 CURSOR FOR C+ SELECT * C+ FROM CORPDATA.DEPARTMENT C/END-EXEC ... C/EXEC SQL C+ FETCH C1 FOR 10 ROWS INTO :TDEPT C/END-EXEC

Determining Equivalent SQL and RPG for AS/400 Data Types


The precompiler determines the base SQLTYPE and SQLLEN of host variables based on the following table. If a host variable appears with an indicator variable, the SQLTYPE is the base SQLTYPE plus one.
Table 30. RPG for AS/400 Declarations Mapped to Typical SQL Data Types
RPG for AS/400 Data Type Data Structure subeld Data structure (without subelds) Input eld Calculation result eld Data Structure subeld Other RPG for AS/400 Coding Length = n where n 256 Length = n where n 9999 Length = n where n 256 Length = n where n 256 Length = 2 SQLTYPE of SQLLEN of Host Variable Host Variable 452 452 n n SQL Data Type CHAR(n) CHAR(n)

Col 43 blank n/a

Col 52 blank n/a

blank n/a B

blank blank 0

452 452 500

n n 2

CHAR(n) CHAR(n) SMALLINT

Chapter 15. Coding SQL Statements in RPG for AS/400 Applications

303

Table 30. RPG for AS/400 Declarations Mapped to Typical SQL Data Types (continued)
RPG for AS/400 Data Type Data Structure subeld Data Structure subeld Data Structure subeld Data Structure subeld Other RPG for AS/400 Coding Length = 4 Length = 2 SQLTYPE of SQLLEN of Host Variable Host Variable 496 500 4 2 SQL Data Type INTEGER DECIMAL(4,s) where s=column 52 DECIMAL(9,s) where s=column 52 DECIMAL(p,s) where p = n*2-1 and s = column 52 DECIMAL(p,s) where p = n*2-1 and s = column 52 DECIMAL(p,s) where p = n and s = column 52 DECIMAL(p,s) where p=4 if n=2 or 9 if n=4 and s = column 52 DECIMAL(p,s) where p = n and s = column 52 NUMERIC(p,s) where p = n and s = column 52

Col 43 B B

Col 52 0 1-4

1-9

Length = 4

496

0 to 9

Length = n where n is 1 to 16

484

p in byte 1, s in byte 2

Input eld

0 to 9

Length = n where n is 1 to 16

484

p in byte 1, s in byte 2

Input eld

blank

0 to 9

Length = n where n is 1 to 30

484

p in byte 1, s in byte 2

Input eld

0 to 4 if n Length = 2 or 4 = 2; 0 to 9 if n = 4

484

p in byte 1, s in byte 2

Calculation result eld

n/a

0 to 9

Length = n where n is 1 to 30

484

p in byte 1, s in byte 2

Data Structure subeld

blank

0 to 9

Length = n where n is 1 to 30

488

p in byte 1, s in byte 2

The following table can be used to determine the RPG for AS/400 data type that is equivalent to a given SQL data type.
Table 31. SQL Data Types Mapped to Typical RPG for AS/400 Declarations
SQL Data Type SMALLINT RPG for AS/400 Data Type Subeld of a data structure. B in position 43, length must be 2 and 0 in position 52 of the subeld specication. Subeld of a data structure. B in position 43, length must be 4 and 0 in position 52 of the subeld specication. Notes

INTEGER

304

DB2 UDB for AS/400 SQL Programming V4R4

Table 31. SQL Data Types Mapped to Typical RPG for AS/400 Declarations (continued)
SQL Data Type DECIMAL RPG for AS/400 Data Type Subeld of a data structure. P in position 43 and 0 through 9 in position 52 of the subeld specication. OR Dened as numeric and not a subeld of a data structure. NUMERIC Subeld of the data structure. Blank in position 43 and 0 through 9 in position 52 of the subeld No exact equivalent No exact equivalent Subeld of a data structure or input eld. Blank in positions 43 and 52 of the specication. OR Calculation result eld dened without decimal places. CHAR(n) VARCHAR(n) Data structure name with no subelds in the data structure. No exact equivalent Maximum length of 30 (precision 30) and maximum scale of 9. Use one of the alternative numeric data types described above. Use one of the alternative numeric data types described above. n can be from 1 to 256. Notes Maximum length of 16 (precision 30) and maximum scale of 9.

FLOAT (single precision) FLOAT (double precision) CHAR(n)

n can be from 1 to 9999.


Use a character host variable large enough to contain the largest expected VARCHAR value. Not supported Not supported Not supported Not supported Not supported If the format is *USA, *JIS, *EUR, or *ISO, the length must be at least 10. If the format is *YMD, *DMY, or *MDY, the length must be at least 8. If the format is *JUL, the length must be at least 6. Length must be at least 6; to include seconds, length must be at least 8.

BLOB CLOB GRAPHIC(n) VARGRAPHIC(n) DBCLOB DATE

Not supported Not supported Not supported Not supported Not supported Subeld of a data structure. Blank in position 52 of the subeld specication. OR Field dened without decimal places.

TIME

Subeld of a data structure. Blank in position 52 of the subeld specication. OR Field dened without decimal places.

TIMESTAMP

Subeld of a data structure. Blank in position 52 of the subeld specication. OR Field dened without decimal places.

Length must be at least 19. To include microseconds at full precision, length must be 26. If length is less than 26, truncation occurs on the microseconds part.

DATALINK

Not supported

Not supported

Chapter 15. Coding SQL Statements in RPG for AS/400 Applications

305

Notes on RPG for AS/400 Variable Declaration and Usage


Assignment rules
RPG for AS/400 associates precision and scale with all numeric types. RPG for AS/400 denes numeric operations, assuming the data is in packed format. This means that operations involving binary variables include an implicit conversion to packed format before the operation is performed (and back to binary, if necessary). Data is aligned to the implied decimal point when SQL operations are performed.

Using Indicator Variables


An indicator variable is a two-byte integer (see the entry for the SMALLINT SQL data type in Table 30 on page 303). An indicator structure can be dened by declaring the variable as an array with an element length of 4,0 and declaring the array name as a subeld of a data structure with B in position 43. On retrieval, an indicator variable is used to show whether its associated host variable has been assigned a null value. on assignment to a column, a negative indicator variable is used to indicate that a null value should be assigned. See the DB2 UDB for AS/400 SQL Referencefor more information on the use of indicator variables. Indicator variables are declared in the same way as host variables and the declarations of the two can be mixed in any way that seems appropriate to the programmer.

Example
Given the statement:
*...1....+....2....+....3....+....4....+....5....+....6....+....7...* C/EXEC SQL FETCH CLS_CURSOR INTO :CLSCD, C+ :DAY :DAYIND, C+ :BGN :BGNIND, C+ :END :ENDIND C/END-EXEC

variables can be declared as follows:


*...1....+....2....+....3....+....4....+....5....+....6....+....7...* I DS I 1 7 CLSCD I B 8 90DAY I B 10 110DAYIND I 12 19 BGN I B 20 210BGNIND I 22 29 END I B 30 310ENDIND

306

DB2 UDB for AS/400 SQL Programming V4R4

Differences in RPG for AS/400 Because of Structure Parameter Passing Techniques


The SQL RPG for AS/400 precompiler attempts to use the structure parameter passing technique, if possible. The precompiler generates code where each host variable is a separate parameter when the following conditions are true: v The data length of the host variables, referred to in the statement, is greater than 9935. Because SQL uses 64 bytes of the structure, 9935 + 64 = 9999, the maximum length of a data structure. v An indicator is specied on the statement where the length of the indexed indicator name plus the required index value is greater than six characters. The precompiler must generate an assignment statement for the indicator with the indicator name in the result eld that is limited to six characters (INDIC,1 requires seven characters). v The length of a host variable is greater than 256. This can happen when a data structure without subelds is used as a host variable, and its length exceeds 256. Subelds cannot be dened with a length greater than 256. For more information on the structure parameter passing technique, see Improving Performance by Using Structure Parameter Passing Techniques on page 472.

Ending a Called RPG for AS/400 Program Correctly


SQL run time builds and maintains data areas (internal SQLDAs) for each SQL statement which contains host variables. These internal SQLDAs are built the rst time the statement is run and then reused on subsequent executions of the statement to increase performance. The internal SQLDAs can be reused as long as there is at least one SQL program active. The SQL precompiler allocates static storage used by SQL run time to manage the internal SQLDAs properly. If an RPG for AS/400 program containing SQL is called from another program which also contains SQL, the RPG for AS/400 program should not set the Last Record (LR) indicator on. Setting the LR indicator on causes the static storage to be re-initialized the next time the RPG for AS/400 program is run. Re-initializing the static storage causes the internal SQLDAs to be rebuilt, thus causing a performance degradation. An RPG for AS/400 program containing SQL statements that is called by a program that also contains SQL statements, should be ended one of two ways: v By the RETRN statement v By setting the RT indicator on. This allows the internal SQLDAs to be used again and reduces the total run time.

Chapter 15. Coding SQL Statements in RPG for AS/400 Applications

307

308

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 16. Coding SQL Statements in ILE RPG for AS/400 Applications
This chapter describes the unique application and coding requirements for embedding SQL statements in an ILE RPG for AS/400 program. The coding requirements for host variables are dened.

Dening the SQL Communications Area


The SQL precompiler automatically places the SQLCA in the denition specications of the ILE RPG for AS/400 program prior to the rst calculation specication. INCLUDE SQLCA should not be coded in the source program. If the source program species INCLUDE SQLCA, the statement will be accepted, but it is redundant. The SQLCA, as dened for ILE RPG for AS/400:
D* SQL Communications area D SQLCA DS D SQLAID 1 8A D SQLABC 9 12B D SQLCOD 13 16B D SQLERL 17 18B D SQLERM 19 88A D SQLERP 89 96A D SQLERRD 97 120B D SQLERR 97 120A D SQLER1 97 100B D SQLER2 101 104B D SQLER3 105 108B D SQLER4 109 112B D SQLER5 113 116B D SQLER6 117 120B D SQLWRN 121 131A D SQLWN0 121 121A D SQLWN1 122 122A D SQLWN2 123 123A D SQLWN3 124 124A D SQLWN4 125 125A D SQLWN5 126 126A D SQLWN6 127 127A D SQLWN7 128 128A D SQLWN8 129 129A D SQLWN9 130 130A D SQLWNA 131 131A D SQLSTT 132 136A D* End of SQLCA

0 0 0 0 DIM(6) 0 0 0 0 0 0

Note: Variable names in RPG for AS/400 are limited to 6 characters. The standard SQLCA names were changed to a length of 6 for RPG for AS/400. To maintain compatibility with RPG for AS/400 programs which are converted to ILE RPG for AS/400, the names for the SQLCA will remain as used with RPG for AS/400. The SQLCA dened for the ILE RPG for AS/400 has added the eld SQLERRD which is dened as an array of six integers. SQLERRD is dened to overlay the SQLERR denition.

Copyright IBM Corp. 1997, 1999

309

Dening SQL Descriptor Areas


The following statements require an SQLDA: EXECUTE...USING DESCRIPTOR descriptor-name FETCH...USING DESCRIPTOR descriptor-name OPEN...USING DESCRIPTOR descriptor-name CALL...USING DESCRIPTOR descriptor-name DESCRIBE statement-name INTO descriptor-name DESCRIBE TABLE host-variable INTO descriptor-name PREPARE statement-name INTO descriptor-name Unlike the SQLCA, there can be more than one SQLDA in a program and an SQLDA can have any valid name. Dynamic SQL is an advanced programming technique described in the SQL programmers guide. With dynamic SQL, your program can develop and then run SQL statements while the program is running. A SELECT statement with a variable SELECT list (that is, a list of the data to be returned as part of the query) that runs dynamically requires an SQL descriptor area (SQLDA). This is because you cannot know in advance how many or what type of variables to allocate in order to receive the results of the SELECT. An INCLUDE SQLDA statement can be specied in an ILE RPG for AS/400 program. The format of the statement is:
*...1....+....2....+....3....+....4....+....5....+....6....+....7....+....8. C/EXEC SQL INCLUDE SQLDA C/END-EXEC

The INCLUDE SQLDA generates the following data structure.


D* SQL Descriptor area D SQLDA DS D SQLDAID 1 D SQLDABC 9 D SQLN 13 D SQLD 15 D SQL_VAR D 17 D 19 D 21 D 33 D 49 D 65 D 67 D* D SQLVAR DS D SQLTYPE 1 D SQLLEN 3 D SQLRES 5 D SQLDATA 17 D SQLIND 33 D SQLNAMELEN 49 D SQLNAME 51 D* End of SQLDA 8A 12B 14B 16B 80A 18B 20B 32A 48* 64* 66B 96A

0 0 0 0 0

DIM(SQL_NUM)

2B 0 4B 0 16A 32* 48* 50B 0 80A

The user is responsible for the denition of SQL_NUM. SQL_NUM must be dened as a numeric constant with the dimension required for SQL_VAR.

310

DB2 UDB for AS/400 SQL Programming V4R4

Since ILE RPG for AS/400 does not support structures within arrays, the INCLUDE SQLDA generates two data structures. The second data structure is used to setup/reference the part of the SQLDA which contains the eld descriptions. To set the eld descriptions of the SQLDA the program sets up the eld description in the subelds of SQLVAR and then does a MOVEA of SQLVAR to SQL_VAR,n where n is the number of the eld in the SQLDA. This is repeated until all the eld descriptions are set. When the SQLDA eld descriptions are to be referenced the user does a MOVEA of SQL_VAR,n to SQLVAR where n is the number of the eld description to be processed.

Embedding SQL Statements


SQL statements coded in an ILE RPG for AS/400 program must be placed in the calculation section. This requires that a C be placed in position 6. SQL statements can be placed in detail calculations, in total calculations, or in an RPG subroutines. The SQL statements are executed based on the logic of the RPG statements. The keywords EXEC SQL indicate the beginning of an SQL statement. EXEC SQL must occupy positions 8 through 16 of the source statement, preceded by a / in position 7. The SQL statement may start in position 17 and continue through position 80. The keyword END-EXEC ends the SQL statement. END-EXEC must occupy positions 8 through 16 of the source statement, preceded by a slash (/) in position 7. Positions 17 through 80 must be blank. Both uppercase and lowercase letters are acceptable in SQL statements.

Example
An UPDATE statement coded in an ILE RPG for AS/400 program might be coded as follows:
*...1....+....2....+....3....+....4....+....5....+....6....+....7....+....8. C/EXEC SQL UPDATE DEPARTMENT C+ SET MANAGER = :MGRNUM C+ WHERE DEPTNO = :INTDEP C/END-EXEC

Comments
In addition to SQL comments (--), ILE RPG for AS/400 comments can be included within SQL statements wherever SQL allows a blank character. To embed an ILE RPG for AS/400 comment within the SQL statement, place an asterisk (*) in position 7.

Continuation for SQL Statements


When additional records are needed to contain the SQL statement, positions 9 through 80 can be used. Position 7 must be a + (plus sign), and position 8 must be blank. Position 80 of the continued line is concatenated with position 9 of the continuation line.

Chapter 16. Coding SQL Statements in ILE RPG for AS/400 Applications

311

Constants containing DBCS data can be continued across multiple lines by placing the shift-in character in position 81 of the continued line and placing the shift-out character in position 8 of the continuation line. In this example the SQL statement has a valid graphic constant of G<AABBCCDDEEFFGGHHIIJJKK>.
*...1....+....2....+....3....+....4....+....5....+....6....+....7....+....8. C/EXEC SQL SELECT * FROM GRAPHTAB WHERE GRAPHCOL = G'<AABBCCDDEE> C+<FFGGHHIIJJKK>' C/END-EXEC

Including Code
SQL statements and RPG calculation specications can be included by using the SQL statement:
*...1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 C/EXEC SQL INCLUDE member-name C/END-EXEC

The RPG /COPY statement can be used to include SQL statements or RPG specications.

Sequence Numbers
The sequence numbers of the source statements generated by the SQL precompiler are based on the *NOSEQSRC/*SEQSRC keywords of the OPTION parameter on the CRTSQLRPGI command. When *NOSEQSRC is specied, the sequence number from the input source member is used. For *SEQSRC, the sequence numbers start at 000001 and are incremented by 1.

Names
Any valid ILE RPG for AS/400 variable name can be used for a host variable and is subject to the following restrictions: Do not use host variable names or external entry names that begin with the characters 'SQ', 'SQL', 'RDI', or 'DSN'. These names are reserved for the database manager. The length of host variable names is limited to 64.

Statement Labels
A TAG statement can precede any SQL statement. Code the TAG statement on the line preceding EXEC SQL.

WHENEVER Statement
The target for the GOTO clause must be the label of the TAG statement. The scope rules for the GOTO/TAG must be observed.

Using Host Variables


All host variables used in SQL statements must be explicitly declared.

312

DB2 UDB for AS/400 SQL Programming V4R4

SQL embedded in ILE RPG for AS/400 does not use the SQL BEGIN DECLARE SECTION and END DECLARE SECTION statements to identify host variables. Do not put these statements in the source program. All host variables within an SQL statement must be preceded by a colon (:). The names of host variables must be unique within the program, even if the host variables are in different procedures. An SQL statement that uses a host variable must be within the scope of the statement in which the variable was declared.

Declaring Host Variables


The SQL ILE RPG for AS/400 precompiler only recognizes a subset of valid ILE RPG for AS/400 declarations as valid host variable declarations. All variables dened in ILE RPG for AS/400 can be used in SQL statements, except for the following: Pointer Tables UDATE UDAY UMONTH UYEAR Look-ahead elds Named constants Multiple dimension arrays Denitions requiring the resolution of *SIZE or *ELEM Denitions requiring the resolution of constants unless the constant is used in OCCURS or DIM. Fields used as host variables are passed to SQL, using the CALL/PARM functions of ILE RPG for AS/400. If a eld cannot be used in the result eld of the PARM, it cannot be used as a host variable. Date and time host variables are always assigned to corresponding date and time subelds in the structures generated by the SQL precompiler. The generated date and time subelds are declared using the format and separator specied by the DATFMT, DATSEP, TIMFMT, and TIMSEP parameters on the CRTSQLRPGI command. Conversion from the user declared host variable format to the precompile specied format occurs on assignment to and from the SQL generated structure. If the DATFMT parameter value is a system format (*MDY, *YMD, *DMY, or *JUL), then all input and output host variables must contain date values within the range 1940-2039. If any date value is outside of this range, then the DATFMT on the precompile must be specied as one of the IBM SQL formats of *ISO, *USA, *EUR, or *JIS.

Chapter 16. Coding SQL Statements in ILE RPG for AS/400 Applications

313

Using Host Structures


The ILE RPG for AS/400 data structure name can be used as a host structure name if subelds exist in the data structure. The use of the data structure name in an SQL statement implies the list of subeld names making up the data structure. When subelds are not present for the data structure, then the data structure name is a host variable of character type. This allows character variables larger than 256. While this support does not provide additional function since a eld can be dened with a maximum length of 32766 it is required for compatibility with RPG for AS/400 programs. In the following example, BIGCHR is an ILE RPG for AS/400 data structure without subelds. SQL treats any referrals to BIGCHR as a character string with a length of 642.
*...1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 DBIGCHR DS 642

In the next example, PEMPL is the name of the host structure consisting of the subelds EMPNO, FIRSTN, MIDINT, LASTNAME, and DEPTNO. The referral to PEMPL uses the subelds. For example, the rst column of CORPDATA.EMPLOYEE is placed in EMPNO, the second column is placed in FIRSTN, and so on.
*...1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 DPEMPL DS D EMPNO 01 06A D FIRSTN 07 18A D MIDINT 19 19A D LASTNA 20 34A D DEPTNO 35 37A ... C MOVE '000220' EMPNO

... C/EXEC SQL C+ SELECT * INTO :PEMPL C+ FROM CORPDATA.EMPLOYEE C+ WHERE EMPNO = :EMPNO C/END-EXEC

When writing an SQL statement, referrals to subelds can be qualied. Use the name of the data structure, followed by a period and the name of the subeld. For example, PEMPL.MIDINT is the same as specifying only MIDINT.

Using Host Structure Arrays


A host structure array is dened as an occurrence data structure. An occurrence data structure can be used on the SQL FETCH or INSERT statement when processing multiple rows. The following list of items must be considered when using a data structure with multiple row blocking support. v All subelds must be valid host variables. v All subelds must be contiguous. The rst FROM position must be 1 and there cannot be overlaps in the TO and FROM positions.

314

DB2 UDB for AS/400 SQL Programming V4R4

v If the date and time format and separator of date and time subelds within the host structure are not the same as the DATFMT, DATSEP, TIMFMT, and TIMSEP parameters on the CRTSQLRPGI command, then the host structure array is not usable. For all statements, other than the blocked FETCH and blocked INSERT, if an occurrence data structure is used, the current occurrence is used. For the blocked FETCH and blocked INSERT, the occurrence is set to 1. The following example uses a host structure array called DEPT and a blocked FETCH statement to retrieve 10 rows from the DEPARTMENT table.
*...1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 DDEPARTMENT DS OCCURS(10) D DEPTNO 01 03A D DEPTNM 04 32A D MGRNO 33 38A D ADMRD 39 41A DIND_ARRAY DS OCCURS(10) D INDS 4B 0 DIM(4) ... C/EXEC SQL C+ DECLARE C1 FOR C+ SELECT * C+ FROM CORPDATA.DEPARTMENT C/END-EXEC ... C/EXEC SQL C+ FETCH C1 FOR 10 ROWS C+ INTO :DEPARTMENT:IND_ARRAY C/END-EXEC

Declaring LOB Host Variables


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

LOB Host Variables


BLOB Example
The following declaration:
D MYBLOB S SQLTYPE(BLOB:500)

Results in the generation of the following structure:


D MYBLOB D MYBLOB_LEN D MYBLOB_DATA DS 10U 500A

CLOB Example
The following declaration:
D MYCLOB S SQLTYPE(CLOB:1000)

Results in the generation of the following structure:


D MYCLOB D MYCLOB_LEN D MYCLOB_DATA DS 10U 1000A

Chapter 16. Coding SQL Statements in ILE RPG for AS/400 Applications

315

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

DBCLOB Example
The following declaration:
D MYDBCLOB S SQLTYPE(DBCLOB:400)

Results in the generation of the following structure:


D MYDBCLOB D MYDBCLOB_LEN D MYDBCLOB_DATA DS 10U 400G

LOB Locators
BLOB Example
The following declaration:
D MYBLOB S SQLTYPE(BLOB_LOCATOR)

Results in the generation of the following structure:


D MYBLOB S 10U

CLOB and DBCLOB locators have similar syntax.

LOB File Reference Variables


BLOB Example
The following declaration:
D MYFILE S SQLTYPE(CLOB_FILE)

Results in the generation of the following structure:


D D D D D MY_FILE MY_FILE_NL MY_FILE_DL MY_FILE_FO MY_FILE_NAME DS 10U 10U 10U 255A

BLOB and DBCLOB locators have similar syntax. The pre-compiler will generate declarations for the following le option constants: v SQFRD (2) v SQFCRT (8) v SQFOVR (16) v SQFAPP (32)

Using External File Descriptions


The SQL precompiler processes the ILE RPG for AS/400 source in much the same manner as the ILE RPG for AS/400 compiler. This means that the precompiler processes the /COPY statement for denitions of host variables. Field denitions for externally described les are obtained and renamed, if different names are specied. The external denition form of the data structure can be used to obtain a copy of the column names to be used as host variables.

316

DB2 UDB for AS/400 SQL Programming V4R4

How date and time eld denition are retrieved and processed by the SQL precompiler depends on whether *NOCVTDT or *CVTDT is specied on the OPTION parameter of the CRTSQLRPGI command. If *NOCVTDT is specied, then date and time eld denitions are retrieved including the format and separator. If *CVTDT is specied, then the format and separator is ignored when date and time eld denitions are retrieved, and the precompiler assumes that the variable declarations are date/time host variables in character format. *CVTDT is a compatibility option for the RPG for AS/400 precompiler. In the following example, the sample table DEPARTMENT is used as a le in an ILE RPG for AS/400 program. The SQL precompiler retrieves the eld (column) denitions for DEPARTMENT for use as host variables.
*...1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 FDEPARTMENTIP E DISK RENAME(ORIGREC:DEPTREC)

Note: Code an F-spec for a le in your ILE RPG for AS/400 program only if you use ILE RPG for AS/400 statements to do I/O operations to the le. If you use only SQL statements to do I/O operations to the le, you can include the external denition of the le (table) by using an external data structure. In the following example, the sample table is specied as an external data structure. The SQL precompiler retrieves the eld (column) denitions as subelds of the data structure. Subeld names can be used as host variable names, and the data structure name TDEPT can be used as a host structure name. The example shows that the eld names can be renamed if required by the program.
*...1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 DTDEPT E DS EXTNAME(DEPARTMENT) D DEPTN E EXTFLD(DEPTNAME) D ADMRD E EXTFLD(ADMRDEPT)

If the GRAPHIC or VARGRAPHIC column has a UCS-2 CCSID, the generated host variable will have the UCS-2 CCSID assigned to it.

External File Description Considerations for Host Structure Arrays


For device les, if INDARA was not specied and the le contains indicators, the declaration is not used as a host structure array. The indicator area is included in the structure that is generated and would cause the storage to be separated. If OPTION(*NOCVTDT) is specied and the date and time format and separator of date and time eld denitions within the le are not the same as the DATFMT, DATSEP, TIMFMT, and TIMSEP parameters on the CRTSQLRPGI command, then the host structure array is not usable. In the following example, the DEPARTMENT table is included in the ILE RPG for AS/400 program and used to declare a host structure array. A blocked FETCH statement is then used to retrieve 10 rows into the host structure array.
*...1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 DDEPARTMENT E DS OCCURS(10) ... C/EXEC SQL C+ DECLARE C1 CURSOR FOR C+ SELECT * C+ FROM CORPDATA.DEPARTMENT
Chapter 16. Coding SQL Statements in ILE RPG for AS/400 Applications

317

C/END-EXEC ... C/EXEC SQL C+ FETCH C1 FOR 10 ROWS C+ INTO :DEPARTMENT C/END-EXEC

Determining Equivalent SQL and RPG Data Types


The precompiler will determine the base SQLTYPE and SQLLEN of host variables according to the following table. If a host variable appears with an indicator variable, the SQLTYPE is the base SQLTYPE plus one.
Table 32. ILE RPG for AS/400 Declarations Mapped to Typical SQL Data Types
RPG Data Type Data structure (without subelds) D spec Pos D spec Pos 40 41,42 Other RPG Coding blank blank Length = n where n 32766 Length = n where n 32766 (pos 59-63) length=n where n is 1 to 254. VARYING in columns 44-80. length=n where n > 254. VARYING in columns 44-80 Length 4 Length = 5 Length 9 and 5 Length = 10 Length = 2 Length = 4 Length = n where n is 1 to 16 SQLTYPE of Host Variable 452 SQLLEN of Host Variable n

SQL Data Type CHAR(n)

n/a Calculation result eld (pos 69,70 = blank) Denition specication Denition specication Denition specication Denition specication Denition specication Denition specication Denition specication Denition specication Denition specication A

n/a

452

CHAR(n)

blank

448

VARCHAR (n)

blank

456

VARCHAR (n)

B I B I B B P

0 0 0 0 1-4 1-9 0 to 30

500 500 496 496 500 496 484

2 2 4 4 2 4

SMALLINT SMALLINT INTEGER INTEGER DECIMAL(4,s) s=col 41, 42 DECIMAL(9,s) s=col 41, 42

p in byte 1, s in DECIMAL(p,s) byte 2 where p = n*2-1 and s = pos 41, 42 4 8 FLOAT (single precision) FLOAT (double precision)

Denition specication Denition specication

F F

blank blank

Length = 4 Length = 8

480 480

318

DB2 UDB for AS/400 SQL Programming V4R4

Table 32. ILE RPG for AS/400 Declarations Mapped to Typical SQL Data Types (continued)
RPG Data Type Denition specication not a subeld Input eld (pos 36 = P) D spec Pos D spec Pos 40 41,42 Other RPG Coding blank 0 to 30 Length = n where n is 1 to 16 SQLTYPE of Host Variable 484 SQLLEN of Host Variable

SQL Data Type

p in byte 1, s in DECIMAL(p,s) byte 2 where p = n*2-1 and s = pos 41, 42 p in byte 1, s in DECIMAL(p,s) byte 2 where p = n*2-1 and s = pos 47, 48 p in byte 1, s in DECIMAL(p,s) byte 2 where p = n and s = pos 47, 48 p in byte 1, s in DECIMAL(p,s) byte 2 where p=4 if n=2 or 9 if n=4 s = pos 47, 48 p in byte 1, s in DECIMAL(p,s) byte 2 where p = n and s = pos 64, 65 p in byte 1, s in NUMERIC(p,s) byte 2 where p = n and s = pos 41, 42 p in byte 1, s in NUMERIC(p,s) byte 2 where p = n and s = pos 41, 42 m GRAPHIC(m) where m = n/2 m = (TO-FROM-1)/2 VARGRAPHIC (n) VARGRAPHIC (n) DATE (DATFMT, DATSEP specied in pos 44-80) DATE (format specied in pos 31-34) TIME (TIMFMT, TIMSEP specied in pos 44-80) TIME (format specied in pos 31-34) TIMESTAMP

n/a

n/a

Length = n where n is 1 to 16 (pos 37-46)

484

Input eld (pos 36 = blank or S) Input eld (pos 36 = B)

n/a

n/a

Length = n where n is 1 to 30 (pos 37-46) Length = n where n is 2 or 4 (pos 37-46)

484

n/a

n/a

484

Calculation n/a result eld (pos 69,70 blank) Data Structure subeld Denition specication Input eld (pos 36 = G) Denition specication Denition specication Denition specication blank

n/a

Length = n where n is 1 to 30 (pos 59-63) Length = n where n is 1 to 30 Length = n where n is 1 to 30

484

0 to 30

488

0 to 30

488

n/a

n/a

Length = n where n is 468 1 to 32766 (pos 37-46) length=n where n is 1 to 127. VARYING in columns 44-80. length=n where n > 127. VARYING in columns 44-80. Length = n where n is 6, 8 or 10 464

blank

blank

472

blank

384

Input eld (pos 36 = D) Denition specication Input eld (pos 36 = T) Denition specication

n/a

n/a

Length = n where n is 6, 8, or 10 (pos 37-46) Length = n where n is 8 Length = n where n is 8 (pos 37-46) Length = n where n is 26

384

blank

388

n/a

n/a

388

blank

392

Chapter 16. Coding SQL Statements in ILE RPG for AS/400 Applications

319

Table 32. ILE RPG for AS/400 Declarations Mapped to Typical SQL Data Types (continued)
RPG Data Type Input eld (pos 36 = Z) D spec Pos D spec Pos 40 41,42 Other RPG Coding n/a n/a Length = n where n is 26 (pos 37-46) SQLTYPE of Host Variable 392 SQLLEN of Host Variable n

SQL Data Type TIMESTAMP

Notes: 1. In the rst column the term denition specication includes data structure subelds unless explicitly stated otherwise. 2. In denition specications the length of binary elds (B in pos 40) is determined by the following: v FROM (pos 26-32) is not blank, then length = TO-FROM+1. v FROM (pos 26-32) is blank, then length = 2 if pos 33-39 < 5, or length = 4 if pos 33-39 > 4. 3. SQL will create the date/time subeld using the DATE/TIME format specied on the CRTSQLRPGI command. The conversion to the host variable DATE/TIME format will occur when the mapping is done between the host variables and the SQL generated subelds. The following table can be used to determine the RPG data type that is equivalent to a given SQL data type.
Table 33. SQL Data Types Mapped to Typical RPG Declarations
SQL Data Type SMALLINT RPG Data Type Denition specication. I in position 40, length must be 5 and 0 in position 42. OR Denition specication. B in position 40, length must be 4 and 0 in position 42. INTEGER Denition specication. I in position 40, length must be 10 and 0 in position 42. OR Denition specication. B in position 40, length must be 9 and 5 and 0 in position 42. DECIMAL Denition specication. P in position 40 or blank in position 40 for a non-subeld, 0 through 30 in position 41,42. OR Dened as numeric on non-denition specication. NUMERIC Denition specication. S in position 40 or blank in position 40 for a subeld, 0 through 30 in position 41,42. Denition specication. F in position 40, length must be 4. Maximum length of 30 (precision 30) and maximum scale of 30. Maximum length of 16 (precision 30) and maximum scale of 30. Notes

FLOAT (single precision)

320

DB2 UDB for AS/400 SQL Programming V4R4

Table 33. SQL Data Types Mapped to Typical RPG Declarations (continued)
SQL Data Type FLOAT (double precision) CHAR(n) RPG Data Type Denition specication. F in position 40, length must be 8. Denition specication. A or blank in positions 40 and blanks in position 41,42. OR Input eld dened without decimal places. OR Calculation result eld dened without decimal places. CHAR(n) VARCHAR(n) Data structure name with no subelds n can be from 1 to 32766. in the data structure. Denition specication. A or blank in n can be from 1 to 32740. position 40 and VARYING in positions 44-80. Not supported Not supported Denition specication. G in position 40. OR Input eld dened with G in position 36. VARGRAPHIC(n) DBCLOB DATE Denition specication. G in position 40 and VARYING in positions 44-80. Not supported A character eld OR Denition specication with a D in position 40. OR Input eld dened with D in position 36. TIME A character eld OR Denition specication with a T in position 40. OR Input eld dened with T in position 36. Length must be at least 6; to include seconds, length must be at least 8. n can be from 1 to 16370. Use SQL TYPE IS to declare a DBCLOB. If the format is *USA, *JIS, *EUR, or *ISO, the length must be at least 10. If the format is *YMD, *DMY, or *MDY, the length must be at least 8. If the format is *JUL, the length must be at least 6. Use SQL TYPE IS to declare a BLOB. Use SQL TYPE IS to declare a CLOB. n can be 1 to 16383. n can be from 1 to 32766. Notes

BLOB CLOB GRAPHIC(n)

Chapter 16. Coding SQL Statements in ILE RPG for AS/400 Applications

321

Table 33. SQL Data Types Mapped to Typical RPG Declarations (continued)
SQL Data Type TIMESTAMP RPG Data Type A character eld OR Denition specication with a Z in position 40. OR Input eld dened with Z in position 36. DATALINK Not supported Notes Length must be at least 19; to include microseconds, length must be at least 26. If length is less than 26, truncation occurs on the microsecond part.

Notes on ILE/RPG 400 Variable Declaration and Usage


Assignment rules
ILE RPG for AS/400 associates precision and scale with all numeric types. ILE RPG for AS/400 denes numeric operations, assuming the data is in packed format. This means that operations involving binary variables include an implicit conversion to packed format before the operation is performed (and back to binary, if necessary). Data is aligned to the implied decimal point when SQL operations are performed.

Using Indicator Variables


An indicator variable is a binary eld with length less then 5 (2 bytes). An indicator array can be dened by declaring the variable element length of 4,0 and specifying the DIM on the denition specication. On retrieval, an indicator variable is used to show if its associated host variable has been assigned a null value. On assignment to a column, a negative indicator variable is used to indicate that a null value should be assigned. See the DB2 UDB for AS/400 SQL Reference book for more information on the use of indicator variables. Indicator variables are declared in the same way as host variables and the declarations of the two can be mixed in any way that seems appropriate to the programmer.

Example
Given the statement:
*...1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 C/EXEC SQL FETCH CLS_CURSOR INTO :CLSCD, C+ :DAY :DAYIND, C+ :BGN :BGNIND, C+ :END :ENDIND C/END-EXEC

variables can be declared as follows:


*...1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 D CLSCD S 7 D DAY S 2B 0

322

DB2 UDB for AS/400 SQL Programming V4R4

D D D D D

DAYIND BGN BGNIND END ENDIND

S S S S S

2B 0 8A 2B 0 8 2B 0

SQLDA Example of the SQLDA for a Multiple Row-Area Fetch


*...1....+....2....+....3....+....4....+....5....+....6....+....7....+....8. C/EXEC SQL INCLUDE SQLDA C/END-EXEC DDEPARTMENT DS OCCURS(10) D DEPTNO 01 03A D DEPTNM 04 32A D MGRNO 33 38A D ADMRD 39 41A ... DIND_ARRAY DS OCCURS(10) D INDS 4B 0 DIM(4) ... C* setup number of sqlda entries and length of the sqlda C eval sqld = 4 C eval sqln = 4 C eval sqldabc = 336 C* C* setup the first entry in the sqlda C* C eval sqltype = 453 C eval sqllen = 3 C eval sql_var(1) = sqlvar C* C* setup the second entry in the sqlda C* C eval sqltype = 453 C eval sqllen = 29 C eval sql_var(2) = sqlvar ... C* C* setup the forth entry in the sqlda C* C eval sqltype = 453 C eval sqllen = 3 C eval sql_var(4) = sqlvar ... C/EXEC SQL C+ DECLARE C1 FOR C+ SELECT * C+ FROM CORPDATA.DEPARTMENT C/END-EXEC ... C/EXEC SQL C+ FETCH C1 FOR 10 ROWS C+ USING DESCRIPTOR :SQLDA C+ INTO :DEPARTMENT:IND_ARRAY C/END-EXEC

Chapter 16. Coding SQL Statements in ILE RPG for AS/400 Applications

323

324

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 17. Coding SQL Statements in REXX Applications


REXX procedures do not have to be preprocessed. At runtime, the REXX interpreter passes statements that it does not understand to the current active command environment for processing. The command environment can be changed to *EXECSQL to send all unknown statements to the database manager in two ways: 1. CMDENV parameter on the STRREXPRC CL command 2. address positional parameter on the ADDRESS REXX command For more information on the STRREXPRC CL command or the ADDRESS REXX command, see the REXX/400 Programmers Guide book.

Using the SQL Communications Area


The elds that make up the SQL Communications Area (SQLCA) are automatically included by the SQL/REXX interface. An INCLUDE SQLCA statement is not required and is not allowed. The SQLCODE and SQLSTATE elds of the SQLCA contain SQL return codes. These values are set by the database manager after each SQL statement is executed. An application can check the SQLCODE or SQLSTATE value to determine whether the last SQL statement was successful. The SQL/REXX interface uses the SQLCA in a manner consistent with the typical SQL usage. However, the SQL/REXX interface maintains the elds of the SQLCA in separate variables rather than in a contiguous data area. The variables that the SQL/REXX interface maintains for the SQLCA are dened as follows: SQLCODE SQLERRMC SQLERRP SQLERRD.n SQLWARN.n SQLSTATE The primary SQL return code. Error and warning message tokens. Product code and, if there is an error, the name of the module that returned the error. Six variables (n is a number between 1 and 6) containing diagnostic information. Eleven variables (n is a number between 0 and 10) containing warning ags. The alternate SQL return code.

Using SQL Descriptor Areas


The following statements require an SQLDA: EXECUTE...USING DESCRIPTOR descriptor-name FETCH...USING DESCRIPTOR descriptor-name OPEN...USING DESCRIPTOR descriptor-name CALL...USING DESCRIPTOR descriptor-name DESCRIBE statement-name INTO descriptor-name DESCRIBE TABLE host-variable INTO descriptor-name Unlike the SQLCA, more than one SQLDA can be in a procedure, and an SQLDA can have any valid name. Each SQLDA consists of a set of REXX variables with a common stem, where the name of the stem is the descriptor-name from the
Copyright IBM Corp. 1997, 1999

325

appropriate SQL statements. This must be a simple stem; that is, the stem itself must not contain any periods. The SQL/REXX interface automatically provides the elds of the SQLDA for each unique descriptor name. An INCLUDE SQLDA statement is not required and is not allowed. The SQL/REXX interface uses the SQLDA in a manner consistent with the typical SQL usage. However, the SQL/REXX interface maintains the elds of the SQLDA in separate variables rather than in a contiguous data area. See the DB2 UDB for AS/400 SQL Reference book for more information on the SQLDA. The following variables are returned to the application after a DESCRIBE, a DESCRIBE TABLE, or a PREPARE INTO statement: stem.n.SQLNAME The name of the nth column in the result table. The following variables must be provided by the application before an EXECUTE...USING DESCRIPTOR, an OPEN...USING DESCRIPTOR, a CALL...USING DESCRIPTOR, or a FETCH...USING DESCRIPTOR statement. They are returned to the application after a DESCRIBE, a DESCRIBE TABLE, or a PREPARE INTO statement: stem.SQLD Number of variable elements that the SQLDA actually contains. stem.n.SQLTYPE An integer representing the data type of the nth element (for example, the rst element is in stem.1.SQLTYPE). The following data types are not allowed: 400/401 404/405 408/409 412/413 460/461 476/477 496/497 500/501 504/505 916/917 920/921 924/925 960/961 964/965 968/969 NUL-terminated graphic string BLOB host variable CLOB host variable DBCLOB host variable NUL-terminated character string PASCAL L-string Large integer (where scale is greater than 0) Small integer (where scale is greater than 0) DISPLAY SIGN LEADING SEPARATE BLOB le reference variables CLOB le reference variables DBCLOB le reference variables BLOB locator CLOB locator DBCLOB locator

stem.n.SQLLEN If SQLTYPE does not indicate a DECIMAL or NUMERIC data type, the maximum length of the data contained in stem.n.SQLDATA.

326

DB2 UDB for AS/400 SQL Programming V4R4

stem.n.SQLLEN.SQLPRECISION If the data type is DECIMAL or NUMERIC, this contains the precision of the number. stem.n.SQLLEN.SQLSCALE If the type is DECIMAL or NUMERIC, this contains the scale of the number. stem.n.SQLCCSID The CCSID of the nth column of the data. The following variables must be provided by the application before an EXECUTE...USING DESCRIPTOR or an OPEN...USING DESCRIPTOR statement, and they are returned to the application after a FETCH...USING DESCRIPTOR statement. They are not used after a DESCRIBE, a DESCRIBE TABLE, or a PREPARE INTO statement: stem.n.SQLDATA This contains the input value supplied by the application, or the output value fetched by SQL. This value is converted to the attributes specied in SQLTYPE, SQLLEN, SQLPRECISION, and SQLSCALE. stem.n.SQLIND If the input or output value is null, this is a negative number.

Embedding SQL Statements


An SQL statement can be placed anywhere a REXX command can be placed. Each SQL statement in a REXX procedure must begin with EXECSQL (in any combination of uppercase and lowercase letters), followed by either: v The SQL statement enclosed in single or double quotes, or v A REXX variable containing the statement. Note that a colon must not precede a REXX variable when it contains an SQL statement. For example:
EXECSQL COMMIT

is equivalent to:
rexxvar = COMMIT EXECSQL rexxvar

The command follows normal REXX rules. For example, it can optionally be followed by a semicolon (;) to allow a single line to contain more than one REXX statement. REXX also permits command names to be included within single quotes, for example:
'EXECSQL COMMIT'

Chapter 17. Coding SQL Statements in REXX Applications

327

The SQL/REXX interface supports the following SQL statements:


ALTER TABLE CALL 10 CLOSE COMMENT ON COMMIT CREATE ALIAS CREATE COLLECTION CREATE DISTINCT TYPE CREATE FUNCTION CREATE INDEX CREATE PROCEDURE CREATE TABLE CREATE VIEW DECLARE CURSOR 10 DELETE 10 DESCRIBE DESCRIBE TABLE DROP EXECUTE EXECUTE IMMEDIATE FETCH 9 GRANT INSERT 9, 10 LABEL ON LOCK TABLE OPEN PREPARE RENAME REVOKE ROLLBACK SET OPTION 11 SET PATH SET TRANSACTION SET variable 10 UPDATE 10 VALUES INTO 10

The following SQL statements are not supported by the SQL/REXX interface:
BEGIN DECLARE SECTION CONNECT CREATE SCHEMA DECLARE PROCEDURE DECLARE STATEMENT DECLARE VARIABLE DISCONNECT END DECLARE SECTION FREE LOCATOR INCLUDE RELEASE SELECT INTO SET CONNECTION SET RESULT SETS WHENEVER12

Comments
Neither SQL comments (--) nor REXX comments are allowed in strings representing SQL statements.

Continuation of SQL Statements


The string containing an SQL statement can be split into several strings on several lines, separated by commas or concatenation operators, according to standard REXX usage.

Including Code
Unlike the other host languages, support is not provided for including externally dened statements.

9. The blocked form of this statement is not supported. 10. These statements cannot be executed directly if they contain host variables; they must be the object of a PREPARE and then an EXECUTE. 11. The SET OPTION statement can be used in a REXX procedure to change some of the processing options used for running SQL statements. These options include the commitment control level and date format. See the DB2 UDB for AS/400 SQL Reference book for more information on the SET OPTION statement. 12. See Handling Errors and Warnings on page 329 for more information.

328

DB2 UDB for AS/400 SQL Programming V4R4

Margins
There are no special margin rules for the SQL/REXX interface.

Names
Any valid REXX name not ending in a period (.) can be used for a host variable. The name must be 64 characters or less. Variable names should not begin with the characters 'SQL', 'RDI', 'DSN', 'RXSQL', or 'QRW'.

Nulls
Although the term null is used in both REXX and SQL, the term has different meanings in the two languages. REXX has a null string (a string of length zero) and a null clause (a clause consisting only of blanks and comments). The SQL null value is a special value that is distinct from all non-null values and denotes the absence of a (non-null) value.

Statement Labels
REXX command statements can be labeled as usual.

Handling Errors and Warnings


The WHENEVER statement is not supported by the SQL/REXX interface. Any of the following may be used instead: v A test of the REXX SQLCODE or SQLSTATE variables after each SQL statement to detect error and warning conditions issued by the database manager, but not for those issued by the SQL/REXX interface. v A test of the REXX RC variable after each SQL statement to detect error and warning conditions. Each use of the EXECSQL command sets the RC variable to: 0 +10 -10 -100 Statement completed successfully. A SQL warning occurred. An SQL error occurred An SQL/REXX interface error occurred.

This can be used to detect errors and warnings issued by either the database manager or by the SQL/REXX interface. v The SIGNAL ON ERROR and SIGNAL ON FAILURE facilities can be used to detect errors (negative RC values), but not warnings.

Using Host Variables


| | | | REXX does not provide for variable declarations. LOB host variables are not supported in REXX. New variables are recognized by their appearance in assignment statements. Therefore, there is no declare section, and the BEGIN DECLARE SECTION and END DECLARE SECTION statements are not supported.

Chapter 17. Coding SQL Statements in REXX Applications

329

All host variables within an SQL statement must be preceded by a colon (:). The SQL/REXX interface performs substitution in compound variables before passing statements to the database manager. For example:
a = 1 b = 2 EXECSQL 'OPEN c1 USING :x.a.b'

causes the contents of x.1.2 to be passed to SQL.

Determining Data Types of Input Host Variables


All data in REXX is in the form of strings. The data type of input host variables (that is, host variables used in a 'USING host variable' clause in an EXECUTE or OPEN statement) is inferred by the database manager at run time from the contents of the variable according to Table 34. These rules dene either numeric, character, or graphic values. A numeric value can be used as input to a numeric column of any type. A character value can be used as input to a character column of any type, or to a date, time, or timestamp column. A graphic value can be used as input to a graphic column of any type.
Table 34. Determining Data Types of Host Variables in REXX
Host Variable Contents Undened Variable Assumed Data Type Variable for which a value has not been assigned Varying-length character string SQL Type Code None SQL Type Description Data that is not valid was detected. VARCHAR(n)

A string with leading and trailing apostrophes () or quotation marks (), which has length n after removing the two delimiters, or a string with a leading X or x followed by an apostrophe () or quotation mark (), and a trailing apostrophe () or quotation mark (). The string has a length of 2n after removing the X or x and the two delimiters. Each remaining pair of characters is the hexadecimal representation of a single character. or a string of length n, which cannot be recognized as character, numeric, or graphic through other rules in this table

448/449

330

DB2 UDB for AS/400 SQL Programming V4R4

Table 34. Determining Data Types of Host Variables in REXX (continued)


Host Variable Contents A string with a leading and trailing apostrophe () or quotation marks () preceded by: 13 v A string that starts with a G, g, N or n. This is followed by an apostrophe or quote and a shift-out (x0E). This is followed by n graphic characters, each 2 characters long. The string must end with a shift-in (X0F) and an apostrophe or quote (whichever the string started with). v A string with a leading GX, Gx, gX, or gx, followed by an apostrophe or quote and a shift-out (x0E). This is followed by n graphic characters, each 2 characters long. The string must end with a shift-in (X0F) and an apostrophe or quote (whichever the string started with). The string has a length of 4n after removing the GX and the delimiters. Each remaining group of 4 characters is the hexadecimal representation of a single graphic character. A number that is in scientic or engineering notation (that is, followed immediately by an 'E' or 'e', an optional plus or minus sign, and a series of digits). It can have a leading plus or minus sign. A number that includes a decimal point, but no exponent, or a number that does not include a decimal point or an exponent and is greater than 2147483647 or smaller than -2147483647. It can have a leading plus or minus sign. m is the total number of digits in the number. n is the number of digits to the left of the decimal point (if any). A number with neither decimal point nor exponent. It can Signed integers have a leading plus or minus sign. 496/497 INTEGER Floating point 480/481 FLOAT Assumed Data Type SQL Type Code SQL Type Description VARGRAPHIC(n)

Varying-length graphic string 464/465

Packed decimal

484/485

DECIMAL(m,n)

The Format of Output Host Variables


It is not necessary to determine the data type of an output host variable (that is, a host variable used in an 'INTO host variable' clause in a FETCH statement). Output values are assigned to host variables as follows: v Character values are assigned without leading and trailing apostrophes. v Graphic values are assigned without a leading G or apostrophe, without a trailing apostrophe, and without shift-out and shift-in characters. v Numeric values are translated into strings. v Integer values do not retain any leading zeros. Negative values have a leading minus sign. v Decimal values retain leading and trailing zeros according to their precision and scale. Negative values have a leading minus sign. Positive values do not have a leading plus sign.

13. The byte immediately following the leading apostrophe is a X'0E' shift-out, and the byte immediately preceding the trailing apostrophe is a X'0F' shift-in. Chapter 17. Coding SQL Statements in REXX Applications

331

v Floating-point values are in scientic notation, with one digit to the left of the decimal place. The 'E' is in uppercase.

Avoiding REXX Conversion


To guarantee that a string is not converted to a number or assumed to be of graphic type, strings should be enclosed in the following: "'". Simply enclosing the string in apostrophes does not work. For example:
stringvar = '100'

causes REXX to set the variable stringvar to the string of characters 100 (without the apostrophes). This is evaluated by the SQL/REXX interface as the number 100, and it is passed to SQL as such. On the other hand,
stringvar = '100'

causes REXX to set the variable stringvar to the string of characters '100' (with the apostrophes). This is evaluated by the SQL/REXX interface as the string 100, and it is passed to SQL as such.

Using Indicator Variables


An indicator variable is an integer. On retrieval, an indicator variable is used to show if its associated host variable was assigned a null value. On assignment to a column, a negative indicator variable is used to indicate that a null value should be assigned. Unlike other languages, a valid value must be specied in the host variable even if its associated indicator variable contains a negative value. For more information on indicator variables see the DB2 UDB for AS/400 SQL Reference book.

332

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 18. Preparing and Running a Program with SQL Statements


This chapter describes some of the tasks for preparing and running an application program. The tasks described are: v Precompiling v Compiling v Binding v Running

Basic Processes of the SQL Precompiler


You must precompile and compile an application program containing embedded SQL statements before you can run it. 14 Precompiling of such programs is done by the SQL precompiler. The SQL precompiler scans each statement of the application program source and does the following: v Looks for SQL statements and for the denition of host variable names. The variable names and denitions are used to verify the SQL statements. You can examine the listing after the SQL precompiler completes processing to see if any errors occurred. v Veries that each SQL statement is valid and free of syntax errors. The validation procedure supplies error messages in the output listing that help you correct any errors that occur. v Validates the SQL statements using the description in the database. During the precompile, the SQL statements are checked for valid table, view, and column names. If a specied table or view does not exist, or you are not authorized to the table or view at the time of the precompile or compile, the validation is done at run time. If the table or view does not exist at run time, an error occurs. Notes: 1. Overrides are processed when retrieving external denitions. For more information, see the DB2 UDB for AS/400 Database Programming book, and the Data Management book. 2. You need some authority (at least *OBJOPR) to any tables or views referred to in the SQL statements in order to validate the SQL statements. The actual authority required to process any SQL statement is checked at run time. For more information on any SQL statement, see the DB2 UDB for AS/400 SQL Reference book. 3. When the RDB parameter is specied on the CRTSQLxxx commands, the precompiler accesses the specied relational database to obtain the table and view descriptions. v Prepares each SQL statement for compilation in the host language. For most SQL statements, the SQL precompiler inserts a comment and a CALL statement to one of the SQL interface modules: QSQROUTE QSQLOPEN QSQLCLSE

14. SQL statements in a REXX procedure are not precompiled and compiled. Copyright IBM Corp. 1997, 1999

333

QSQLCMIT For some SQL statements (for example, DECLARE statements), the SQL precompiler produces no host language statement except a comment. v Produces information about each precompiled SQL statement. The information is stored internally in a temporary source le member, where it is available for use during the bind process. To get complete diagnostic information when you precompile, specify either of the following: v OPTION(*SOURCE *XREF) for CRTSQLxxx (where xxx=CBL, PLI, or RPG) v OPTION(*XREF) OUTPUT(*PRINT) for CRTSQLxxx (where xxx=CI, CPPI, CBLI, or RPGI) or for CVTSQLCPP

Input to the Precompiler


Application programming statements and embedded SQL statements are the primary input to the SQL precompiler. In PL/I, C, and C++ programs, the SQL statements must use the margins that are specied in the MARGINS parameter of the CRTSQLPLI, CRTSQLCI, CRTSQLCPPI, and CVTSQLCPP commands. The SQL precompiler assumes that the host language statements are syntactically correct. If the host language statements are not syntactically correct, the precompiler may not correctly identify SQL statements and host variable declarations. There are limits on the forms of source statements that can be passed through the precompiler. Literals and comments that are not accepted by the application language compiler, can interfere with the precompiler source scanning process and cause errors. You can use the SQL INCLUDE statement to get secondary input from the le that is specied by the INCFILE parameter of the CRTSQLxxx 15 and CVTSQLCPP command. The SQL INCLUDE statement causes input to be read from the specied member until it reaches the end of the member. The included member may not contain other precompiler INCLUDE statements, but can contain both application program and SQL statements. Another preprocessor may process source statements before the SQL precompiler. However, any preprocessor run before the SQL precompile must be able to pass through SQL statements. If mixed DBCS constants are specied in the application program source, the source le must be a mixed CCSID. You can specify many of the precompiler options in the input source member by using the SQL SET OPTION statement. See the DB2 UDB for AS/400 SQL Reference book for the SET OPTION syntax.

Source File CCSIDs


The SQL precompiler will read the source records by using the CCSID of the source le. When processing SQL INCLUDE statements, the include source will be

15. The xxx in this command refers to the host language indicators: CBL for the COBOL for AS/400 language, CBLI for the ILE COBOL for AS/400 language, PLI for the AS/400 PL/I language, CI for the ILE C for AS/400 language, RPG for the RPG for AS/400 language, RPGI for the ILE RPG for AS/400 language, CPPI for the ILE C++/400 language.

334

DB2 UDB for AS/400 SQL Programming V4R4

converted to the CCSID of the original source le if necessary. If the include source cannot be converted to the CCSID of the original source le, an error will occur. The SQL precompiler will process SQL statements using the source CCSID. This affects variant characters the most. For example, the not sign () is located at 'BA'X in CCSID 500. Prior to Version 2 Release 1.1, SQL looked for the not sign () in the location '5F'X in CCSID 37. This means that if the CCSID of your source le is 500, SQL expects the not sign () to be located at 'BA'X. If the source le CCSID is 65535, SQL processes variant characters as if they had a CCSID of 37. This means that SQL looks for the not sign () at '5F'X.

Output from the Precompiler


The following sections describe the various kinds of output supplied by the precompiler.

Listing
The output listing is sent to the printer le that is specied by the PRTFILE parameter of the CRTSQLxxx or CVTSQLCPP command. The following items are written to the printer le: v Precompiler options Options specied in the CRTSQLxxx or CVTSQLCPP command. v Precompiler source This output supplies precompiler source statements with the record numbers that are assigned by the precompiler, if the listing option is in effect. v Precompiler cross-reference If *XREF was specied in the OPTION parameter, this output supplies a cross-reference listing. The listing shows the precompiler record numbers of SQL statements that contain the referred to host names and column names. v Precompiler diagnostics This output supplies diagnostic messages, showing the precompiler record numbers of statements in error. The output to the printer le will use a CCSID value of 65535. The data will not be converted when it is written to the printer le.

Temporary Source File Members


Source statements processed by the precompiler are written to an output source le that is specied on the CRTSQLxx or CVTSQLCPP command in the TOSRCFILE parameter. The default le is QSQLTEMP (QSQLTEMP1 for ILE RPG for AS/400) in the QTEMP library. In your precompiler-changed source code, SQL statements have been converted to comments and calls to the SQL runtime. The name of the output source le member is the same as the name specied in the PGM or OBJ parameter of the CRTSQLxxx or CVTSQLCPP command. This member cannot be changed before being used as input to the compiler. When SQL creates the output source le, it uses the CCSID value of the source le as the CCSID value for the new le. If the precompile uses QSQLTEMP or QSQLTEMP1 in QTEMP, the le can be moved to a permanent library after the precompile if you want to compile at a later time. You cannot change the records of the source member, or the attempted compile fails.
Chapter 18. Preparing and Running a Program with SQL Statements

335

The SQL precompiler uses the CRTSRCPF command to create the output source le. If the defaults for this command have changed, then the results may be unpredictable. If the source le is created by the user, not the SQL precompiler, the les attributes may be different as well. It is recommended that the user allow SQL to create the output source le. Once it has been created by SQL, it can be reused on later precompiles.

Sample Precompiler Output


The precompiler output can provide information about your program source. To generate the listing: v For non-ILE precompilers, specify the *SOURCE (*SRC) and *XREF options on the OPTION parameter of the CRTSQLxxx command. v For ILE precompilers, specify OPTION(*XREF) and OUTPUT(*PRINT) on the CRTSQLxxx or CVTSQLCPP command. The format of the precompiler output is:
5769ST1 V4R4M0 990521 Create SQL COBOL Program Source type...............COBOL Program name..............CORPDATA/CBLTEST1 Source file...............CORPDATA/SRC Member....................CBLTEST1 To source file............QTEMP/QSQLTEMP 1 Options...................*SRC *XREF *SQL Target release............V4R4M0 INCLUDE file..............*LIBL/*SRCFILE Commit....................*CHG Allow copy of data........*YES Close SQL cursor..........*ENDPGM Allow blocking............*READ Delay PREPARE.............*NO Generation level..........10 Printer file..............*LIBL/QSYSPRT Date format...............*JOB Date separator............*JOB Time format...............*HMS Time separator ...........*JOB Replace...................*YES Relational database.......*LOCAL User .....................*CURRENT RDB connect method........*DUW Default Collection........*NONE Package name..............*PGMLIB/*PGM Dynamic User Profile......*USER User Profile..............*NAMING Sort Sequence.............*JOB Language ID...............*JOB IBM SQL flagging..........*NOFLAG ANS flagging..............*NONE Text......................*SRCMBRTXT Source file CCSID.........65535 Job CCSID.................65535 2 Source member changed on 04/01/98 10:16:44 CBLTEST1 04/01/98 11:14:21 Page 1

1 2

A list of the options you specied when the SQL precompiler was called. The date the source member was last changed.

Figure 11. Sample COBOL Precompiler Output Format (Part 1 of 5)

336

DB2 UDB for AS/400 SQL Programming V4R4

5769ST1 V4R4M0 990521 Create SQL COBOL Program CBLTEST1 1 Record *...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 IDENTIFICATION DIVISION. PROGRAM-ID. CBLTEST1. ENVIRONMENT DIVISION. CONFIGURATION SECTION. SOURCE-COMPUTER. IBM-AS400. OBJECT-COMPUTER. IBM-AS400. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT OUTFILE, ASSIGN TO PRINTER-QPRINT, FILE STATUS IS FSTAT. DATA DIVISION. FILE SECTION. FD OUTFILE DATA RECORD IS REC-1, LABEL RECORDS ARE OMITTED. 01 REC-1. 05 CC PIC X. 05 DEPT-NO PIC X(3). 05 FILLER PIC X(5). 05 AVERAGE-EDUCATION-LEVEL PIC ZZZ. 05 FILLER PIC X(5). 05 AVERAGE-SALARY PIC ZZZZ9.99. 01 ERROR-RECORD. 05 CC PIC X. 05 ERROR-CODE PIC S9(5). 05 ERROR-MESSAGE PIC X(70). WORKING-STORAGE SECTION. EXEC SQL INCLUDE SQLCA END-EXEC. 77 FSTAT PIC XX. 01 AVG-RECORD. 05 WORKDEPT PIC X(3). 05 AVG-EDUC PIC S9(4) USAGE COMP-4. 05 AVG-SALARY PIC S9(6)V99 COMP-3. PROCEDURE DIVISION. *************************************************************** * This program will get the average education level and the * * average salary by department. * *************************************************************** A000-MAIN-PROCEDURE. OPEN OUTPUT OUTFILE. *************************************************************** * Set-up WHENEVER statement to handle SQL errors. * *************************************************************** EXEC SQL WHENEVER SQLERROR GO TO B000-SQL-ERROR END-EXEC. *************************************************************** * Declare cursor * *************************************************************** EXEC SQL DECLARE CURS CURSOR FOR SELECT WORKDEPT, AVG(EDLEVEL), AVG(SALARY) FROM CORPDATA.EMPLOYEE GROUP BY WORKDEPT END-EXEC. *************************************************************** * Open cursor * *************************************************************** EXEC SQL OPEN CURS END-EXEC.

2 100 200 300 400 500 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 2400 2500 2600 2700 2800 2900 3000 3100 3200 3300 3400 3500 3600 3700 3800 3900 4000 4100 4200 4300 4400 4500 4600 4700 4800 4900 5000 5100 5200 5300 5400 5500 5600 5700 5800 5900 6000 6100 6200 6300

04/01/98 11:14:21 SEQNBR 3 Last Change

Page

1 2 3

Record number assigned by the precompiler when it reads the source record. Record numbers are used to identify the source record in error messages and SQL run-time processing. Sequence number taken from the source record. The sequence number is the number seen when you use the source entry utility (SEU) to edit the source member. Date when the source record was last changed. If Last is blank, it indicates that the record has not been changed since it was created.

Figure 11. Sample COBOL Precompiler Output Format (Part 2 of 5)

Chapter 18. Preparing and Running a Program with SQL Statements

337

5769ST1 V4R4M0 990521 Create SQL COBOL Program CBLTEST1 Record *...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 64 *************************************************************** 65 * Fetch all result rows * 66 *************************************************************** 67 PERFORM A010-FETCH-PROCEDURE THROUGH A010-FETCH-EXIT 68 UNTIL SQLCODE IS = 100. 69 *************************************************************** 70 * Close cursor * 71 *************************************************************** 72 EXEC SQL 73 CLOSE CURS 74 END-EXEC. 75 CLOSE OUTFILE. 76 STOP RUN. 77 *************************************************************** 78 * Fetch a row and move the information to the output record. * 79 *************************************************************** 80 A010-FETCH-PROCEDURE. 81 MOVE SPACES TO REC-1. 82 EXEC SQL 83 FETCH CURS INTO :AVG-RECORD 84 END-EXEC. 85 IF SQLCODE IS = 0 86 MOVE WORKDEPT TO DEPT-NO 87 MOVE AVG-SALARY TO AVERAGE-SALARY 88 MOVE AVG-EDUC TO AVERAGE-EDUCATION-LEVEL 89 WRITE REC-1 AFTER ADVANCING 1 LINE. 90 A010-FETCH-EXIT. 91 EXIT. 92 *************************************************************** 93 * An SQL error occurred. Move the error number to the error * 94 * record and stop running. * 95 *************************************************************** 96 B000-SQL-ERROR. 97 MOVE SPACES TO ERROR-RECORD. 98 MOVE SQLCODE TO ERROR-CODE. 99 MOVE "AN SQL ERROR HAS OCCURRED" TO ERROR-MESSAGE. 100 WRITE ERROR-RECORD AFTER ADVANCING 1 LINE. 101 CLOSE OUTFILE. 102 STOP RUN. * * * * * E N D O F S O U R C E * * * * *

04/01/98 11:14:21 SEQNBR Last change 6400 6500 6600 6700 6800 6900 7000 7100 7200 7300 7400 7500 7600 7700 7800 7900 8000 8100 8200 8300 8400 8500 8600 8700 8800 8900 9000 9100 9200 9300 9400 9500 9600 9700 9800 9900 10000 10100 10200

Page

Figure 11. Sample COBOL Precompiler Output Format (Part 3 of 5)

338

DB2 UDB for AS/400 SQL Programming V4R4

5769ST1 V4R4M0 990521 CROSS REFERENCE 1 Data Names AVERAGE-EDUCATION-LEVEL AVERAGE-SALARY AVG-EDUC AVG-RECORD AVG-SALARY BIRTHDATE BONUS B000-SQL-ERROR CC CC COMM CORPDATA CURS DEPT-NO EDLEVEL EDLEVEL EMPLOYEE EMPNO ERROR-CODE ERROR-MESSAGE ERROR-RECORD FIRSTNME FSTAT HIREDATE JOB LASTNAME MIDINIT PHONENO REC-1 SALARY SALARY

Create SQL COBOL Program 2 Define 20 22 34 32 35 55 55 **** 17 24 55 **** 53 18 **** 55 **** 55 25 26 23 55 31 55 55 55 55 55 16 **** 55

CBLTEST1

04/01/98 11:14:21

Page

3 Reference IN REC-1 IN REC-1 SMALL INTEGER PRECISION(4,0) IN AVG-RECORD STRUCTURE 83 DECIMAL(8,2) IN AVG-RECORD DATE(10) COLUMN IN CORPDATA.EMPLOYEE DECIMAL(9,2) COLUMN IN CORPDATA.EMPLOYEE LABEL 47 CHARACTER(1) IN REC-1 CHARACTER(1) IN ERROR-RECORD DECIMAL(9,2) COLUMN IN CORPDATA.EMPLOYEE 4 COLLECTION 5 55 CURSOR 62 73 83 CHARACTER(3) IN REC-1 COLUMN 54 6 SMALL INTEGER PRECISION(4,0) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE TABLE IN CORPDATA 7 55 CHARACTER(6) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE NUMERIC(5,0) IN ERROR-RECORD CHARACTER(70) IN ERROR-RECORD STRUCTURE VARCHAR(12) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE CHARACTER(2) DATE(10) COLUMN IN CORPDATA.EMPLOYEE CHARACTER(8) COLUMN IN CORPDATA.EMPLOYEE VARCHAR(15) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE CHARACTER(1) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE CHARACTER(4) COLUMN IN CORPDATA.EMPLOYEE COLUMN 54 DECIMAL(9,2) COLUMN IN CORPDATA.EMPLOYEE

1 2

Data names are the symbolic names used in source statements. The dene column species the line number at which the name is dened. The line number is generated by the SQL precompiler. **** means that the object was not dened or the precompiler did not recognize the declarations. The reference column contains two types of information: v What the symbolic name is dened as 4 v The line numbers where the symbolic name occurs 5 If the symbolic name refers to a valid host variable, the data-type 6 or data-structure 7 is also noted.

Figure 11. Sample COBOL Precompiler Output Format (Part 4 of 5)

5769ST1 V4R4M0 990521 CROSS REFERENCE SEX WORKDEPT WORKDEPT

Create SQL COBOL Program 55 33 ****

CBLTEST1

04/01/98 11:14:21

Page

WORKDEPT 55 No errors found in source 102 Source records processed * * * * * E N D O F L I S T I N G

CHARACTER(1) COLUMN IN CORPDATA.EMPLOYEE CHARACTER(3) IN AVG-RECORD COLUMN 54 56 CHARACTER(3) COLUMN IN CORPDATA.EMPLOYEE * * * * *

Figure 11. Sample COBOL Precompiler Output Format (Part 5 of 5)

Chapter 18. Preparing and Running a Program with SQL Statements

339

Non-ILE Precompiler Commands


DB2 UDB Query Manager and SQL Development Kit includes non-ILE precompiler commands for the following host languages: CRTSQLCBL (for COBOL for AS/400), CRTSQLPLI (for AS/400 PL/I), and CRTSQLRPG (for RPG III, which is part of RPG for AS/400). Some options only apply to certain languages. For example, the options *APOST and *QUOTE are unique to COBOL. They are not included in the commands for the other languages. Refer to Appendix D. DB2 UDB for AS/400 CL Command Descriptions on page 645 for more information.

Compiling a Non-ILE Application Program


The SQL precompiler automatically calls the host language compiler after the successful completion of a precompile, unless *NOGEN is specied. The CRTxxxPGM command is run specifying the program name, source le name, precompiler created source member name, text, and USRPRF. Within these languages, the following parameters are passed: v For COBOL, the *QUOTE or *APOST is passed on the CRTCBLPGM command. v For RPG and COBOL, SAAFLAG (*FLAG) is passed on the CRTxxxPGM command. v For RPG and COBOL, the SRTSEQ and LANGID parameter from the CRTSQLxxx command is specied on the CRTxxxPGM command. v For RPG and COBOL, the CVTOPT (*DATETIME *VARCHAR) is always specied on the CRTxxxPGM command. v For COBOL and RPG, the TGTRLS parameter value from the CRTSQLxxx command is specied on the CRTxxxPGM command. TGTRLS is not specied on the CRTPLIPGM command. The program can be saved or restored to the level specied on the TGTRLS parameter of the CRTSQLPLI command. v For PL/I, the MARGINS are set in the temporary source le. v For all languages, the REPLACE parameter from the CRTSQLxxx command is specied on the CRTxxxPGM command. If a package is created as part of the precompile process, the REPLACE parameter value from the CRTSQLxxx command is specied on the CRTSQLPKG command. v For all languages, if USRPRF(*USER) or system naming (*SYS) with USRPRF(*NAMING) is specied, then USRPRF(*USER) is specied on the CRTxxxPGM command. If USRPRF(*OWNER) or SQL naming (*SQL) with USRPRF(*NAMING) is specied, then USRPRF(*OWNER) is specied on the CRTxxxPGM command. Defaults are used for all other parameters with CRTxxxPGM commands. You can interrupt the call to the host language compiler by specifying *NOGEN on the OPTION parameter of the precompiler command. *NOGEN species that the host language compiler will not be called. Using the object name in the CRTSQLxxx command as the member name, the precompiler created the source member in the output source le (specied as the TOSRCFILE parameter on the CRTSQLxxx command). You now can explicitly call the host language compilers, specify the source member in the output source le, and change the defaults. If the precompile and compile were done as separate steps, the CRTSQLPKG command can be used to create the SQL package for a distributed program.

340

DB2 UDB for AS/400 SQL Programming V4R4

Note: You must not change the source member in QTEMP/QSQLTEMP prior to issuing the CRTxxxPGM command or the compile will fail.

ILE Precompiler Commands


In the DB2 UDB Query Manager and SQL Development Kit, the following ILE precompiler commands exist: CRTSQLCI, CRTSQLCBLI, CRTSQLRPGI, CRTSQLCPPI, and CVTSQLCPP. There is a precompiler command for each of the host languages: ILE C for AS/400, ILE COBOL for AS/400, and ILE RPG for AS/400. Separate commands, by language, let you specify the required parameters and take the default for the remaining parameters. The defaults are applicable only to the language you are using. For example, the options *APOST and *QUOTE are unique to COBOL. They are not included in the commands for the other languages. Refer to Appendix D. DB2 UDB for AS/400 CL Command Descriptions on page 645 for more information.

Compiling an ILE Application Program


The SQL precompiler automatically calls the host language compiler after the successful completion of a precompile for the CRTSQLxxx commands, unless *NOGEN is specied. If the *MODULE option is specied, the SQL precompiler issues the CRTxxxMOD command to create the module. If the *PGM option is specied, the SQL precompiler issues the CRTBNDxxx command to create the program. If the *SRVPGM option is specied, the SQL precompiler issues the CRTxxxMOD command to create the module, followed by the Create Service Program (CRTSRVPGM) command to create the service program. The CRTSQLCPPI command only create *MODULE objects. The CVTSQLCPP never creates an object. Within these languages, the following parameters are passed: v If DBGVIEW(*SOURCE) is specied on the CRTSQLxxx command, then DBGVIEW(*ALL) is specied on both the CRTxxxMOD and CRTBNDxxx commands. v If OUTPUT(*PRINT) is specied on the CRTSQLxxx command, it is passed on both the CRTxxxMOD and CRTBNDxxx commands. If OUTPUT(*NONE) is specied on the CRTSQLxxx command, it is not specied on either the CRTxxxMOD command or the CRTBNDxxx command. v The TGTRLS parameter value from the CRTSQLxxx command is specied on the CRTxxxMOD, CRTBNDxxx, and Create Service Program (CRTSRVPGM) commands. v The REPLACE parameter value from the CRTSQLxxx command is specied on the CRTxxxMOD, CRTBNDxxx, and CRTSRVPGM commands. If a package is created as part of the precompile process, the REPLACE parameter value from the CRTSQLxxx command is specied on the CRTSQLPKG command. v If OBJTYPE is either *PGM or *SRVPGM, and USRPRF(*USER) or system naming (*SYS) with USRPRF(*NAMING) is specied, USRPRF(*USER) is specied on the CRTBNDxxx or the CRTSRVPGM commands. If OBJTYPE is either *PGM or *SRVPGM, and USRPRF(*OWNER) or SQL naming (*SQL) with USRPRF(*NAMING) is specied, USRPRF(*OWNER) is specied on the CRTBNDxxx or the CRTSRVPGM commands. v For C and C++, the MARGINS are set in the temporary source le.
Chapter 18. Preparing and Running a Program with SQL Statements

341

| | |

v For COBOL, the *QUOTE or *APOST is passed on the CRTBNDCBL or the CRTCBLMOD commands. v FOR RPG and COBOL, the SRTSEQ and LANGID parameter from the CRTSQLxxx command is specied on the CRTxxxMOD and CRTBNDxxx commands. v For COBOL, CVTOPT(*VARCHAR *DATETIME *PICGGRAPHIC *FLOAT *DATE *TIME *TIMESTAMP) is always specied on the CRTCBLMOD and CRTBNDCBL commands. v For RPG, if OPTION(*CVTDT) is specied, then CVTOPT(*DATETIME) is specied on the CRTRPGMOD and CRTBNDRPG commands. You can interrupt the call to the host language compiler by specifying *NOGEN on the OPTION parameter of the precompiler command. *NOGEN species that the host language compiler is not called. Using the specied program name in the CRTSQLxxx command as the member name, the precompiler creates the source member in the output source le (TOSRCFILE parameter). You can now explicitly call the host language compilers, specify the source member in the output source le, and change the defaults. If the precompile and compile were done as separate steps, the CRTSQLPKG command can be used to create the SQL package for a distributed program. If the program or service program is created later, the USRPRF parameter may not be set correctly on the CRTBNDxxx, Create Program (CRTPGM), or Create Service Program (CRTSRVPGM) command. The SQL program runs predictably only after the USRPRF parameter is corrected. If system naming is used, then the USRPRF parameter must be set to *USER. If SQL naming is used, then the USRPRF parameter must be set to *OWNER.

Precompiling for the VisualAge C++ for OS/400 Compiler


The SQL precompiler for VisualAge C++ for OS/400 is invoked using the CVTSQLCPP CL command. This precompiler is different than the other language precompilers since it does not have an option to generate the module or program object. Since the precompiler runs on the AS/400 and the compiler runs on the workstation, the two steps must be run independently. The precompile and compile should be done following these steps: 1. Make sure both the base and option one are loaded for the product. 2. Make sure that the environment is set up to run the compiler and precompiler: v Set EBCDIC/ASCII conversion for le extensions .h and .mbr in Client Access. v Map the AS/400 to a workstation drive. In this discussion, it is assumed that the x drive is mapped to the AS/400 system. v Ensure you have a connection established to the AS/400 using the following command:
CTTCONN /h<as400name>

3. If your source is on the workstation, issue the following command:


CTTCRSQX myapp.sqx x mylib/myfile/myapp

This command copies myapp.sqx (your source) to the AS/400 into the qsys.lib/mylib.lib/myle.le/myapp.mbr directory. This is the same as the AS/400 le system MYLIB/MYFILE (MYAPP) member.

342

DB2 UDB for AS/400 SQL Programming V4R4

4. Run the SQL precompiler on the AS/400 for the source member. This is the CVTSQLCPP CL command. You can also do this from the workstation by using the CTTHCMD command. 5. Copy the output source le member containing the converted SQL to the workstation:
CTTCRCPP mylib/mytosrcfile/myapp x myapp.cpp

This creates a le called myapp.cpp on the workstation. Alternately, you can leave the source on the AS/400 and run the compiler against it there. 6. Run the C++ compiler and create the nal module or program. If the output source member is still on the AS/400:
iccas /c x:\qsys.lib\mylib.lib\mytosrcfile.file\myapp.mbr

If the source member is on the workstation:


iccas -c myapp.cpp

Note that the program must be created on the AS/400 where the precompile was run since there is some additional SQL information that was created by the precompiler that is needed for the nal executable object.

Interpreting Application Program Compile Errors


Attention: If you separate precompile and compile steps, and the source program refers to externally described les, the referred to les must not be changed between precompile and compile. Otherwise, results that are not predictable may occur because the changes to the eld denitions are not changed in the temporary source member. Examples of externally described les are: v v v v COPY DDS in COBOL %INCLUDE in PL/I #pragma mapinc and #include in C or C++ Data structures in RPG

When the SQL precompiler does not recognize host variables, try compiling the source. The compiler will not recognize the EXEC SQL statements, ignore these errors. Verify that the compiler interprets the host variable declaration as dened by the SQL precompiler for that language.

Error and Warning Messages during a Compile


The conditions described in the following paragraphs could produce an error or warning message during an attempted compile process.

During a PL/I, C, or C++ Compile


If EXEC SQL starts before the left margin (as specied with the MARGINS parameter, the default), the SQL precompiler will not recognize the statement as an SQL statement. Consequently, it will be passed as is to the compiler.

Chapter 18. Preparing and Running a Program with SQL Statements

343

During a COBOL Compile


If EXEC SQL starts before column 12, the SQL precompiler will not recognize the statement as an SQL statement. Consequently, it will be passed as is to the compiler.

During an RPG Compile


If EXEC SQL is not coded in positions 8 through 16, and preceded with the / character in position 7, the SQL precompiler will not recognize the statement as an SQL statement. Consequently, it will be passed as is to the compiler. For more information, see the specic programming examples in Chapter 12. Coding SQL Statements in C and C++ Applications, through Chapter 17. Coding SQL Statements in REXX Applications.

Binding an Application
Before you can run your application program, a relationship between the program and any specied tables and views must be established. This process is called binding. The result of binding is an access plan. The access plan is a control structure that describes the actions necessary to satisfy each SQL request. An access plan contains information about the program and about the data the program intends to use. For a nondistributed SQL program, the access plan is stored in the program. For a distributed SQL program (where the RDB parameter was specied on the CRTSQLxxx or CVTSQLCPP commands), the access plan is stored in the SQL package at the specied relational database. SQL automatically attempts to bind and create access plans when the program object is created. For non-ILE compiles, this occurs as the result of a successful CRTxxxPGM. For ILE compiles, this occurs as the result of a successful CRTBNDxxx, CRTPGM, or CRTSRVPGM command. If DB2 UDB for AS/400 detects at run time that an access plan is not valid (for example, the referenced tables are in a different library) or detects that changes have occurred to the database that may improve performance (for example, the addition of indexes), a new access plan is automatically created. Binding does three things: 1. It revalidates the SQL statements using the description in the database. During the bind process, the SQL statements are checked for valid table, view, and column names. If a specied table or view does not exist at the time of the precompile or compile, the validation is done at run time. If the table or view does not exist at run time, a negative SQLCODE is returned. 2. It selects the index needed to access the data your program wants to process. In selecting an index, table sizes, and other factors are considered, when it builds an access plan. It considers all indexes available to access the data and decides which ones (if any) to use when selecting a path to the data. 3. It attempts to build access plans. If all the SQL statements are valid, the bind process then builds and stores access plans in the program. If the characteristics of a table or view your program accesses have changed, the access plan may no longer be valid. When you attempt to run a program that contains an access plan that is not valid, the system automatically attempts to rebuild the access plan. If the access plan cannot be rebuilt, a negative SQLCODE

344

DB2 UDB for AS/400 SQL Programming V4R4

is returned. In this case, you might have to change the programs SQL statements and reissue the CRTSQLxxx or CVTSQLCPP command to correct the situation. For example, if a program contains an SQL statement that refers to COLUMNA in TABLEA and the user deletes and recreates TABLEA so that COLUMNA no longer exists, when you call the program, the automatic rebind will be unsuccessful because COLUMNA no longer exists. In this case you must change the program source and reissue the CRTSQLxxx command.

Program References
All collections, tables, views, SQL packages, and indexes referenced in SQL statements in an SQL program are placed in the object information repository (OIR) of the library when the program is created. You can use the CL command Display Program References (DSPPGMREF) to display all object references in the program. If the SQL naming convention is used, the library name is stored in the OIR in one of three ways: 1. If the SQL name is fully qualied, the collection name is stored as the name qualier. 2. If the SQL name is not fully qualied and the DFTRDBCOL parameter is not specied, the authorization ID of the statement is stored as the name qualier. 3. If the SQL name is not fully qualied and the DFTRDBCOL parameter is specied, the collection name specied on the DFTRDBCOL parameter is stored as the name qualier. If the system naming convention is used, the library name is stored in the OIR in one of three ways: 1. If the object name is fully qualied, the library name is stored as the name qualier. 2. If the object is not fully qualied and the DFTRDBCOL parameter is not specied, *LIBL is stored. 3. If the SQL name is not fully qualied and the DFTRDBCOL parameter is specied, the collection name specied on the DFTRDBCOL parameter is stored as the name qualier.

Displaying Precompiler Options


When the SQL application program is successfully compiled, the Display Module (DSPMOD), the Display Program (DSPPGM), or the Display Service Program (DSPSRVPGM) command can be used to determine some of the options that were specied on the SQL precompile. This information may be needed when the source of the program has to be changed. These same SQL precompiler options can then be specied on the CRTSQLxxx or CVTSQLCPP command when the program is compiled again. The Print SQL Information (PRTSQLINF) command can also be used to determine some of the options that were specied on the SQL precompile.

Chapter 18. Preparing and Running a Program with SQL Statements

345

Running a Program with Embedded SQL


Running a host language program with embedded SQL statements, after the precompile and compile have been successfully done, is the same as running any host program. Type:
CALL pgm-name

| | | | | | |

on the system command line. For more information on running programs, see the CL Programming book. Note: After installing a new release, users may encounter message CPF2218 in QHST using any Structured Query Language (SQL) program if the user does not have *CHANGE authority to the program. Once a user with *CHANGE authority calls the program, the access plan is updated and the message will be issued.

OS/400 DDM Considerations


SQL does not support remote le access through DDM (distributed data management) les. SQL does support remote access through DRDA (Distributed Relational Database Architecture.)

Override Considerations
You can use overrides (specied by the OVRDBF command) to direct a reference to a different table or view or to change certain operational characteristics of the program or SQL Package. The following parameters are processed if an override is specied: TOFILE MBR SEQONLY INHWRT WAITRCD All other override parameters are ignored. Overrides of statements in SQL packages are accomplished by doing both of the following: 1. Specifying the OVRSCOPE(*JOB) parameter on the OVRDBF command 2. Sending the command to the application server by using the Submit Remote Command (SBMRMTCMD) command To override tables and views that are created with long names, you can create an override using the system name that is associated with the table or view. When the long name is specied in an SQL statement, the override is found using the corresponding system name. An alias is actually created as a DDM le. You can create an override that refers to an alias name (DDM le). In this case, an SQL statement that refers to the le that has the override actually uses the le to which the alias refers. For more information on overrides, see the DB2 UDB for AS/400 Database Programming book, and the Data Management book.

346

DB2 UDB for AS/400 SQL Programming V4R4

SQL Return Codes


A list of SQL return codes is provided in Appendix B. SQLCODEs and SQLSTATEs.

Chapter 18. Preparing and Running a Program with SQL Statements

347

348

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 19. Using Interactive SQL


This chapter describes how to use interactive SQL to run SQL statements and use the prompt function. Overview information and tips on using interactive SQL are provided. If you want to learn how to use SQL, you should see Chapter 2. Getting Started with SQL. Special considerations for using interactive SQL with a remote connection are covered in Accessing Remote Databases with Interactive SQL on page 359.

Basic Functions of Interactive SQL


Interactive SQL allows the programmer or database administrator to quickly and easily dene, update, delete, or look at data for testing, problem analysis, and database maintenance. A programmer, using interactive SQL, can insert rows into a table and test the SQL statements before running them in an application program. A database administrator can use interactive SQL to grant or revoke privileges, create or drop collections, tables, or views, or select information from system catalog tables. After an interactive SQL statement is run, a completion message or an error message is displayed. In addition, status messages are normally displayed during long-running statements. You can see help on a message by positioning the cursor on the message and pressing F1=Help. The basic functions supplied by interactive SQL are: v The statement entry function allows you to: Type in an interactive SQL statement and run it. Retrieve and edit statements. Prompt for SQL statements. Page through previous statements and messages. Call session services. Invoke list selection function.

Exit interactive SQL. v The prompt function allows you to type either a complete SQL statement or a partial SQL statement, press F4=Prompt, and then be prompted for the syntax of the statement. It also allows you to press F4 to get a menu of all SQL statements. From this menu, you can select a statement and be prompted for the syntax of the statement. v The list selection function allows you to select from lists of your authorized relational databases, collections, tables, views, columns, constraints, or SQL packages. The selections you make from the lists can be inserted into the SQL statement at the cursor position. v The session services function allows you to: Change session attributes. Print the current session. Remove all entries from the current session.
Copyright IBM Corp. 1997, 1999

349

Save the session in a source le.

Starting Interactive SQL


You can start using interactive SQL by typing STRSQL on an AS/400 command line. For a complete description of the command and its parameters, see Appendix D. DB2 UDB for AS/400 CL Command Descriptions. The Enter SQL Statements display appears. This is the main interactive SQL display. From this display, you can enter SQL statements and use: v v v v v F4=prompt F13=Session services F16=Select collections F17=Select tables F18=Select columns
Enter SQL Statements Type SQL statement, press Enter. Current connection is to relational database rdjacque. ===>_____________________________________________________________________ _____________________________________________________________________ _____________________________________________________________________ _____________________________________________________________________ _____________________________________________________________________ _____________________________________________________________________ _____________________________________________________________________ _____________________________________________________________________ _____________________________________________________________________ _____________________________________________________________________ _____________________________________________________________________ _____________________________________________________________________ _____________________________________________________________________ _____________________________________________________________________ _____________________________________________________________________ F3=Exit F4=Prompt F12=Cancel F6=Insert line F13=Services F9=Retrieve F10=Copy line F24=More keys Bottom

Press F24=More keys to view the remaining function keys.


_____________________________________________________________________ _____________________________________________________________________ _____________________________________________________________________ _____________________________________________________________________ Bottom F14=Delete line F15=Split line F17=Select tables (files) F16=Select collections (libraries) F18=Select columns F24=More keys (fields)

Note: If you are using the system naming convention, the names in parentheses appear instead of the names shown above. An interactive session consists of: v Parameter values you specied for the STRSQL command . v SQL statements you entered in the session along with corresponding messages that follow each SQL statement

350

DB2 UDB for AS/400 SQL Programming V4R4

v Values of any parameters you changed using the session services function v List selections you have made Interactive SQL supplies a unique session-ID consisting of your user ID and the current work station ID. This session-ID concept allows multiple users with the same user ID to use interactive SQL from more than one work station at the same time. Also, more than one interactive SQL session can be run from the same work station at the same time from the same user ID. If an SQL session exists and is being re-entered, any parameters specied on the STRSQL command are ignored. The parameters from the existing SQL session are used.

Using Statement Entry Function


The statement entry function is the function you rst enter when selecting interactive SQL. You return to the statement entry function after processing each interactive SQL statement. In the statement entry function, you type or prompt for the entire SQL statement and then submit it for processing by pressing the Enter key.

Typing Statements
The statement you type on the command line can be one or more lines long. You cannot type comments for the SQL statement in interactive SQL. When the statement has been processed, the statement and the resulting message are moved upward on the display. You can then enter another statement. If a statement is recognized by SQL but contains a syntax error, the statement and the resulting text message (syntax error) are moved upward on the display. In the input area, a copy of the statement is shown with the cursor positioned at the syntax error. You can place the cursor on the message and press F1=Help for more information about the error. You can page through previous statements, commands, and messages. Press F9=Retrieve with your cursor on a previous statement to place a copy of that statement in the input area. If you need more room to type an SQL statement, page down on the display.

Prompting
The prompt function helps you supply the necessary information for the syntax of the statement you want to use. The prompt function can be used in any of the three statement processing modes: *RUN, *VLD, and *SYN. You have two options when using the prompter: v Type the verb of the statement before pressing F4=Prompt. The statement is parsed and the clauses that are completed are lled in on the prompt displays. If you type SELECT and press F4=Prompt, the following display appears:

Chapter 19. Using Interactive SQL

351

Specify SELECT Statement Type SELECT statement information. FROM tables . . . . . SELECT columns . . . WHERE conditions . . GROUP BY columns . . HAVING conditions . . ORDER BY columns . . FOR UPDATE OF columns . . . . . . . . . . . . . . . . . . . . . Press F4 for a list.

_____________________________________________ _____________________________________________ _____________________________________________ _____________________________________________ _____________________________________________ _____________________________________________ _____________________________________________ Bottom Y=Yes, N=No Y=Yes, N=No Y=Yes, N=No

Type choices, press Enter. DISTINCT rows in result table . . . . . . . . . N UNION with another SELECT . . . . . . . . . . . N Specify additional options . . . . . . . . . . . N

F3=Exit F10=Copy line

F4=Prompt F5=Refresh F6=Insert line F9=Specify subquery F12=Cancel F14=Delete line F15=Split line F24=More keys

v Press F4=Prompt before typing anything on the Enter SQL Statements display. You are shown a list of statements. The list of statements varies and depends on the current interactive SQL statement processing mode. For syntax check mode with a language other than *NONE, the list includes all SQL statements. For run and validate modes, only statements that can be run in interactive SQL are shown. You can select the number of the statement you want to use. The system prompts you for the statement you selected. If you press F4=Prompt without typing anything, the following display appears:
Select SQL Statement Select one of the following: 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. ALTER TABLE CALL COMMENT ON COMMIT CONNECT CREATE ALIAS CREATE COLLECTION CREATE INDEX CREATE PROCEDURE CREATE TABLE CREATE VIEW DELETE DISCONNECT DROP ALIAS

Selection __ F3=Exit F12=Cancel

More...

If you press F21=Display Statement on a prompt display, the prompter displays the formatted SQL statement as it was lled in to that point. When Enter is pressed within prompting, the statement that was built through the prompt screens is inserted into the session. If the statement processing mode is *RUN, the statement is run. The prompter remains in control if an error is encountered.

352

DB2 UDB for AS/400 SQL Programming V4R4

Syntax Checking
The syntax of the SQL statement is checked when it enters the prompter. The prompter does not accept a syntactically incorrect statement. You must correct the syntax or remove the incorrect part of the statement or prompting will not be allowed.

Statement processing mode


The statement processing mode can be selected on the Change Session Attributes display. In *RUN (run) or *VLD (validate) mode, only statements that are allowed to run in interactive SQL can be prompted. In *SYN (syntax check) mode, all SQL statements are allowed. The statement is not actually run in *SYN or *VLD modes; only the syntax and existence of objects are checked.

Subqueries
Subqueries can be selected on any display that has a WHERE or HAVING clause. To see the subquery display, press F9=Specify subquery when the cursor is on a WHERE or HAVING input line. A display appears that allows you to type in subselect information. If the cursor is within the parentheses of the subquery when F9 is pressed, the subquery information is lled in on the next display. If the cursor is outside the parentheses of the subquery, the next display is blank. For more information on subqueries, see Using Subqueries on page 84.

CREATE TABLE prompting


When prompting for CREATE TABLE, support is available for entering column denitions individually. Place your cursor in the column denition section of the display, and press F4=Prompt. A display that provides room for entering all the information for one column denition is shown. To enter a column name longer than 18 characters, press F20=Display entire name. A window with enough space for a 30 character name will be displayed. The editing keys, F6=Insert line, F10=Copy line, and F14=Delete line, can be used to add and delete entries in the column denition list.

Entering DBCS Data


The rules for processing DBCS data across multiple lines are the same on the Enter SQL Statements display and in the SQL prompter. Each line must contain the same number of shift-in and shift-out characters. When processing a DBCS data string that requires more than one line for entering, the extra shift-in and shift-out characters are removed. If the last column on a line contains a shift-in and the rst column of the next line contains a shift-out, the shift-in and shift-out characters are removed by the prompter when the two lines are assembled. If the last two columns of a line contain a shift-in followed by a single-byte blank and the rst column of the next line contains a shift-out, the shift-in, blank, shift-out sequence is removed when the two lines are assembled. This removal allows DBCS information to be read as one continuous character string. As an example, suppose the following WHERE condition were entered. The shift characters are shown here at the beginning and end of the string sections on each of the two lines.

Chapter 19. Using Interactive SQL

353

Specify SELECT Statement Type SELECT statement information. Press F4 for a list.

FROM tables . . . . . . . . TABLE1_______________________________________ SELECT columns . . . . . . *____________________________________________ WHERE conditions . . . . . COL1 = '<AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQ> <RRSS>'______________________________________ GROUP BY columns . . . . . _____________________________________________ HAVING conditions . . . . . _____________________________________________ ORDER BY columns . . . . . _____________________________________________ FOR UPDATE OF columns . . . _____________________________________________

When Enter is pressed, the character string is put together, removing the extra shift characters. The statement would look like this on the Enter SQL Statements display:
SELECT * FROM TABLE1 WHERE COL1 = '<AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSS>'

Using the List Selection Function


The list selection function is available by pressing F4 on certain prompt displays, or F16, F17, or F18 on the Enter SQL Statements display. After pressing the function key, you are given a list of authorized relational databases, collections, tables, views, aliases, columns, constraints, procedures, parameters, or packages from which to choose. If you request a list of tables, but you have not previously selected a collection, you are asked to select a collection rst. On a list, you can select one or more items, numerically specifying the order in which you want them to appear in the statement. When the list function is exited, the selections you made are inserted at the position of the cursor on the display you came from. Always select the list you are primarily interested in. For example, if you want a list of columns, but you believe that the columns you want are in a table not currently selected, press F18=Select columns. Then, from the column list, press F17 to change the table. If the table list were selected rst, the table name would be inserted into your statement. You would not have a choice for selecting columns. You can request a list at any time while typing an SQL statement on the Enter SQL Statements display. The selections you make from the lists are inserted on the Enter SQL Statements display. They are inserted where the cursor is located in the numeric order that you specied on the list display. Although the selected list information is added for you, you must type the keywords for the statement. The list function tries to provide qualications that are necessary for the selected columns, tables, and SQL packages. However, sometimes the list function cannot determine the intent of the SQL statement. You need to review the SQL statement and verify that the selected columns, tables, and SQL packages are properly qualied.

Example of Using the List Selection Function


The following example shows you how to use the list function to build a SELECT statement. Assume you have: v Just entered interactive SQL by typing STRSQL on an AS/400 command line.

354

DB2 UDB for AS/400 SQL Programming V4R4

v Made no list selections or entries. v Selected *SQL for the naming convention. Note: The example shows lists that are not on your AS/400 system. They are used as an example only. Begin using SQL statements: 1. Type SELECT on the rst statement entry line. 2. Type FROM on the second statement entry line. 3. Leave the cursor positioned after FROM.
Enter SQL Statements Type SQL statement, press Enter. ===> SELECT FROM _

4. Press F17=Select tables to obtain a list of tables, because you want the table name to follow FROM. Instead of a list of tables appearing as you expected, a list of collections appears (the Select and Sequence Collections display). You have just entered the SQL session and have not selected a collection to work with. 5. Type a 1 in the Seq column next to YOURCOLL2 collection.
Select and Sequence Collections Type sequence numbers (1-999) to select collections, press Enter. Seq 1 Collection YOURCOLL1 YOURCOLL2 YOURCOLL3 YOURCOLL4 Type SYS SYS SYS SYS Text Company benefits Employee personal data Job classifications/requirements Company insurances

6. Press Enter. The Select and Sequence Tables display appears, showing the tables existing in the YOURCOLL2 collection. 7. Type a 1 in the Seq column next to PEOPLE table.
Select and Sequence Tables Type sequence numbers (1-999) to select tables, press Enter. Seq 1 Table EMPLCO PEOPLE EMPLEXP EMPLEVL EMPLBEN EMPLMED EMPLINVST Collection YOURCOLL2 YOURCOLL2 YOURCOLL2 YOURCOLL2 YOURCOLL2 YOURCOLL2 YOURCOLL2 Type TAB TAB TAB TAB TAB TAB TAB Text Employee Employee Employee Employee Employee Employee Employee company data personal data experience evaluation reports benefits record medical record investments record

8. Press Enter.

Chapter 19. Using Interactive SQL

355

The Enter SQL Statements display appears again with the table name, YOURCOLL2.PEOPLE, inserted after FROM. The table name is qualied by the collection name in the *SQL naming convention.
Enter SQL Statements Type SQL statement, press Enter. ===> SELECT FROM YOURCOLL2.PEOPLE _

9. Position the cursor after SELECT. 10. Press F18=Select columns to obtain a list of columns, because you want the column name to follow SELECT. The Select and Sequence Columns display appears, showing the columns in the PEOPLE table. 11. Type a 2 in the Seq column next to the NAME column. 12. Type a 1 in the Seq column next to the SOCSEC column.
Select and Sequence Columns Type sequence numbers (1-999) to select columns, press Enter. Seq Column 2 NAME EMPLNO 1 SOCSEC STRADDR CITY ZIP PHONE Table PEOPLE PEOPLE PEOPLE PEOPLE PEOPLE PEOPLE PEOPLE Type CHARACTER CHARACTER CHARACTER CHARACTER CHARACTER CHARACTER CHARACTER Digits Length 6 30 11 30 20 9 20

13. Press Enter. The Enter SQL Statements display appears again with SOCSEC, NAME appearing after SELECT.
Enter SQL Statements Type SQL statement, press Enter. ===> SELECT SOCSEC, NAME FROM YOURCOLL2.PEOPLE

14. Press Enter. The statement you created is now run. Once you have used the list function, the values you selected remain in effect until you change them or until you change the list of collections on the Change Session Attributes display.

Session Services Description


The interactive SQL Session Services display is requested by pressing F13 on the Enter SQL Statements display.

356

DB2 UDB for AS/400 SQL Programming V4R4

From this display you can change session attributes and print, clear, or save the session to a source le. Option 1 (Change session attributes) displays the Change Session Attributes display, which allows you to select the current values that are in effect for your interactive SQL session. The options shown on this display change based on the statement processing option selected. The following session attributes can be changed: v Commitment control attributes. v The statement processing control. v The SELECT output device. v The list of collections. v The list type to select either all your system and SQL objects, or only your SQL objects. v The data refresh option when displaying data. v The allow copy data option. v The naming option. v The programming language. v The date format. v The time format. v The date separator. v The time separator. v The decimal point representation. v The SQL string delimiter. v The sort sequence. v The language identier. Option 2 (Print current session) accesses the Change Printer display, which lets you print the current session immediately and then continue working. You are prompted for printer information. All the SQL statements you entered and all the messages displayed are printed just as they appear on the Enter SQL Statements display. Option 3 (Remove all entries from current session) lets you remove all the SQL statements and messages from the Enter SQL Statements display and the session history. You are prompted to ensure that you really want to delete the information. Option 4 (Save session in source le) accesses the Change Source File display, which lets you save the session in a source le. You are prompted for the source le name. This function lets you embed the source le into a host language program by using the source entry utility (SEU). Note: Option 4 allows you to embed prototyped SQL statements in a high-level language (HLL) program that uses SQL. The source le created by option 4 may be edited and used as the input source le for the Run SQL Statements (RUNSQLSTM) command.

Exiting Interactive SQL


Pressing F3=Exit on the Enter SQL Statements display allows you to exit the interactive SQL environment and do one of the following:
Chapter 19. Using Interactive SQL

357

1. Save and exit session. Leave interactive SQL. Your current session will be saved and used the next time you start interactive SQL. 2. Exit without saving session. Leave interactive SQL without saving your session. 3. Resume session. Remain in interactive SQL and return to the Enter SQL Statements display. The current session parameters remain in effect. 4. Save session in source le. Save the current session in a source le. The Change Source File display is shown to allow you to select where to save the session. You cannot recover and work with this session again in interactive SQL. Notes: 1. Option 4 allows you to embed prototype SQL statements in a high-level language (HLL) program that uses SQL. Use the source entry utility (SEU) to copy the statements into your program. The source le can also be edited and used as the input source le for the Run SQL Statements (RUNSQLSTM) command. 2. If rows have been changed and locks are currently being held for this unit of work and you attempt to exit interactive SQL, a warning message is displayed.

Using an existing SQL Session


If you saved only one interactive SQL session by using option 1 (Save and exit session) on the Exit Interactive SQL display, you may resume that session at any workstation. However, if you use option 1 to save two or more sessions on different workstations, interactive SQL will rst attempt to resume a session that matches your work station. If no matching sessions are available, then interactive SQL will increase the scope of the search to include all sessions that belong to your user ID. If no sessions for your user ID are available, the system will create a new session for your user ID and current workstation. For example, you saved a session on workstation 1 and saved another session on workstation 2 and you are currently working at workstation 1. Interactive SQL will rst attempt to resume the session saved for workstation 1. If that session is currently in use, interactive SQL will then attempt to resume the session that was saved for workstation 2. If that session is also in use, then the system will create a second session for workstation 1. However, suppose you are working at workstation 3 and want to use the ISQL session associated with workstation 2. You then may need to rst delete the session from workstation 1 by using option 2 (Exit without saving session) on the Exit Interactive SQL display.

Recovering an SQL Session


If the previous SQL session ended abnormally, interactive SQL presents the Recover SQL Session display at the start of the next session (when the next STRSQL command is entered). From this display, you can either: v Recover the old session by selecting option 1 (Attempt to resume existing SQL session). v Delete the old session and start a new session by selecting option 2 (Delete existing SQL session and start a new session). If you choose to delete the old session and continue with the new session, the parameters you specied when you entered STRSQL are used. If you choose to

358

DB2 UDB for AS/400 SQL Programming V4R4

recover the old session, or are entering a previously saved session, the parameters you specied when you entered STRSQL are ignored and the parameters from the old session are used. A message is returned to indicate which parameters were changed from the specied value to the old session value.

Accessing Remote Databases with Interactive SQL


In interactive SQL, you can communicate with a remote relational database by using the SQL CONNECT statement. Interactive SQL uses the CONNECT (Type 2) semantics (distributed unit of work) for CONNECT statements. Interactive SQL does an implicit connect to the local RDB when starting an SQL session. When the CONNECT statement is completed, a message shows the relational database connection that was established. If starting a new session and COMMIT(*NONE) was not specied, or if restoring a saved session and the commit level saved with the session was not *NONE, the connection will be registered with commitment control. This implicit connect and possible commitment control registration may inuence subsequent connections to remote databases. For further information, see Determining Connection Type on page 567. It is recommended that prior to connecting to the remote system: v When connecting to an application server that does not support distributed unit of work, a RELEASE ALL followed by a COMMIT be issued to end previous connections, including the implicit connection to local. v When connecting to a non-DB2 UDB for AS/400 application server, a RELEASE ALL followed by a COMMIT be issued to end previous connections, including the implicit connection to local, and change the commitment control level to at least *CHG. When you are connecting to a non-DB2 UDB for AS/400 application server, some session attributes are changed to attributes that are supported by that application server. The following table shows the attributes that change.
Table 35. Values Table
Session Attribute Date Format Original Value *YMD *DMY *MDY *JUL Time Format *HMS with a : separator *HMS with any other separator *CHG, *NONE *ALL *SYS *NO, *YES *ALWAYS *SYSVAL Any value other than *HEX *JIS *EUR *CS Repeatable Read New Value *ISO *EUR *USA *USA

Commitment Control

Naming Convention Allow Copy Data Data Refresh Decimal Point Sort Sequence

*SQL *OPTIMIZE *FORWARD *PERIOD *HEX

Chapter 19. Using Interactive SQL

359

Notes: 1. If connecting to an AS/400 system that is running a release prior to Version 2 Release 3, the sort sequence value changes to *HEX. 2. When connecting to a DB2/2 or DB2/6000 application server, the date and time formats specied must be the same format. After the connection is completed, a message is sent stating that the session attributes have been changed. The changed session attributes can be displayed by using the session services display. While interactive SQL is running, no other connection can be established for the default activation group. When connected to a remote system with interactive SQL, a statement processing mode of syntax-only checks the syntax of the statement against the syntax supported by the local system instead of the remote system. Similarly, the SQL prompter and list support use the statement syntax and naming conventions supported by the local system. The statement is run, however, on the remote system. Because of differences in the level of SQL support between the two systems, syntax errors may be found in the statement on the remote system at run time. Lists of collections and tables are available when you are connected to the local relational database. Lists of columns are available only when you are connected to a relational database manager that supports the DESCRIBE TABLE statement. When you exit interactive SQL with connections that have pending changes or connections that use protected conversations, the connections remain. If you do not perform additional work over the connections, the connections are ended during the next COMMIT or ROLLBACK operation. You can also end the connections by doing a RELEASE ALL and a COMMIT before exiting interactive SQL. Using interactive SQL for remote access to non-DB2 UDB for AS/400 application servers can require some setup. For more information, see the Distributed Database Programming book. Note: In the output of a communications trace, there may be a reference to a CREATE TABLE XXX statement. This is used to determine package existence; it is part of normal processing, and can be ignored.

360

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 20. Using the SQL Statement Processor


This section describes the SQL Statement processor. This processor is available when you use the Run SQL Statements (RUNSQLSTM) command. The SQL statement processor allows SQL statements to be executed from a source member. The statements in the source member can be run repeatedly, or changed, without compiling the source. This makes the setup of a database environment easier. The statements that can be used with the SQL statement processor are: v ALTER TABLE v v v v v v v v v v v v v CALL COMMENT ON COMMIT CREATE ALIAS CREATE COLLECTION CREATE DISTINCT TYPE CREATE FUNCTION CREATE INDEX CREATE SCHEMA CREATE TABLE CREATE VIEW DELETE DROP

| |

v CREATE PROCEDURE

v GRANT (Package Privileges) v GRANT (Procedure Privileges) v GRANT (Table Privileges) v INSERT v LABEL ON v LOCK TABLE v RENAME v REVOKE (Package Privileges) v REVOKE (Procedure Privileges) v v v v v REVOKE (Table Privileges) ROLLBACK SET PATH SET TRANSACTION UPDATE

In the source member, statements end with a semicolon and do not begin with EXEC SQL. If the record length of the source member is longer than 80, only the rst 80 characters will be read. Comments in the source member can be either line comments or block comments. Line comments begin with a double hyphen () and end at the end of the line. Block comments start with /* and can continue across many lines until the next */ is reached. Block comments can be nested. Only SQL statements and comments are allowed in the source le. The output listing and the resulting messages for the SQL statements are sent to a print le. The default print le is QSYSPRT.
Copyright IBM Corp. 1997, 1999

361

To perform syntax checking only on all statements in the source member, specify the PROCESS(*SYN) parameter on the RUNSQLSTM command.

Execution of Statements After Errors Occur


When a statement returns an error with a severity higher than the value specied for the error level (ERRLVL) parameter of the RUNSQLSTM command, the statement has failed. The rest of the statements in the source will be parsed to check for syntax errors, but those statements will not be executed. Most SQL errors have a severity of 30. If you want to continue processing after an SQL statement fails, set the ERRLVL parameter of the RUNSQLSTM command to 30 or higher.

Commitment Control in the SQL Statement Processor


A commitment-control level is specied on the RUNSQLSTM command. If a commitment-control level other than *NONE is specied, the SQL statements are run under commitment control. If all of the statements successfully execute, a COMMIT is done at the completion of the SQL statement processor. Otherwise, a ROLLBACK is done. A statement is considered successful if its return code severity is less than or equal to the value specied on the ERRLVL parameter of the RUNSQLSTM command. The SET TRANSACTION statement can be used within the source member to override the level of commitment control specied on the RUNSQLSTM command. Note: The job must be at a unit of work boundary to use the SQL statement processor with commitment control.

Schemas in the SQL Statement Processor


The SQL statement processor supports the CREATE SCHEMA statement. This is a complex statement that can be thought of as having two distinct sections. The rst section denes the collection for the schema. The second section contains DDL statements that dene the objects in the collection. The rst section can be written in one of two ways: v CREATE SCHEMA collection-name A collection is created using the specied collection name. v CREATE SCHEMA AUTHORIZATION authorization-name A collection is created using the authorization name as the collection name. When the schema is run, the user must have authority to the user prole that is named authorization-name. The privileges held by the authorization-name of the statement must include: Authority to run the CREATE COLLECTION statement Authority to run each SQL statement within the CREATE SCHEMA The second section of the CREATE SCHEMA statement can contain from zero to any number of the following statements: v COMMENT ON v CREATE DISTINCT TYPE v CREATE TABLE

362

DB2 UDB for AS/400 SQL Programming V4R4

v v v v v

CREATE VIEW CREATE INDEX CREATE ALIAS GRANT (User-Dened Type Privileges) GRANT (Table Privileges)

v LABEL ON These statements follow directly after the rst section of the statement. The statements and sections are not separated by semicolons. If other SQL statements follow this schema denition, the last statement in the schema must be ended by a semicolon. All objects created or referenced in the second part of the schema statement must be in the collection that was created for the schema. All unqualied references are implicitly qualied by the collection that was created. All qualied references must be qualied by the created collection.

Source Member Listing for the SQL Statement Processor


5769ST1 V4R4M0 990521 Run SQL Statements Source file...............CORPDATA/SRC Member....................SCHEMA Commit....................*NONE Naming....................*SYS Generation level..........10 Date format...............*JOB Date separator............*JOB Time format...............*HMS Time separator ...........*JOB Default Collection........*NONE IBM SQL flagging..........*NOFLAG ANS flagging..............*NONE Decimal point.............*JOB Sort Sequence.............*JOB Language ID...............*JOB Printer file..............*LIBL/QSYSPRT Source file CCSID.........65535 Job CCSID.................0 Statement processing......*RUN Allow copy of data........*OPTIMIZE Allow blocking............*READ Source member changed on 04/01/98 11:54:10 SCHEMA 04/01/98 15:35:18 Page 1

Figure 12. QSYSPRT listing for SQL statement processor (Part 1 of 3)

Chapter 20. Using the SQL Statement Processor

363

5769ST1 V4R4M0 990521 Run SQL Statements SCHEMA Record *...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 1 2 DROP COLLECTION DEPT; 3 DROP COLLECTION MANAGER; 4 5 CREATE SCHEMA DEPT 6 CREATE TABLE EMP (EMPNAME CHAR(50), EMPNBR INT) 7 -- EMP will be created in collection DEPT 8 CREATE INDEX EMPIND ON EMP(EMPNBR) 9 -- EMPIND will be created in DEPT 10 GRANT SELECT ON EMP TO PUBLIC; -- grant authority 11 12 INSERT INTO DEPT/EMP VALUES('JOHN SMITH', 1234); 13 /* table must be qualified since no 14 longer in the schema */ 15 16 CREATE SCHEMA AUTHORIZATION MANAGER 17 -- this schema will use MANAGER's 18 -- user profile 19 CREATE TABLE EMP_SALARY (EMPNBR INT, SALARY DECIMAL(7,2), 20 LEVEL CHAR(10)) 21 CREATE VIEW LEVEL AS SELECT EMPNBR, LEVEL 22 FROM EMP_SALARY 23 CREATE INDEX SALARYIND ON EMP_SALARY(EMPNBR,SALARY) 24 25 GRANT ALL ON LEVEL TO JONES GRANT SELECT ON EMP_SALARY TO CLERK 26 -- Two statements can be on the same line * * * * * E N D O F S O U R C E * * * * *

SEQNBR

04/01/98 15:35:18 Last change

Page

Figure 12. QSYSPRT listing for SQL statement processor (Part 2 of 3)

5769ST1 V4R4M0 990521 Run SQL Statements SCHEMA Record *...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 MSG ID SEV RECORD TEXT SQL7953 0 1 Position 1 Drop of DEPT in QSYS complete. SQL7953 0 3 Position 3 Drop of MANAGER in QSYS complete. SQL7952 0 5 Position 3 Collection DEPT created. SQL7950 0 6 Position 8 Table EMP created in collection DEPT. SQL7954 0 8 Position 8 Index EMPIND created on table EMP in DEPT. SQL7966 0 10 Position 8 GRANT of authority to EMP in DEPT completed. SQL7956 0 10 Position 40 1 rows inserted in EMP in DEPT. SQL7952 0 13 Position 28 Collection MANAGER created. SQL7950 0 19 Position 9 Table EMP_SALARY created in collection MANAGER. SQL7951 0 21 Position 9 View LEVEL created in collection MANAGER. SQL7954 0 23 Position 9 Index SALARYIND created on table EMP_SALARY in MANAGER. SQL7966 0 25 Position 9 GRANT of authority to LEVEL in MANAGER completed. SQL7966 0 25 Position 37 GRANT of authority to EMP_SALARY in MANAGER completed. Message Summary Total Info Warning Error Severe Terminal 13 13 0 0 0 0 00 level severity errors found in source * * * * * E N D O F L I S T I N G * * * * *

SEQNBR

04/01/98 15:35:18 Last change

Page

Figure 12. QSYSPRT listing for SQL statement processor (Part 3 of 3)

364

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 21. DB2 UDB for AS/400 Data Protection


This chapter describes the security plan for protecting SQL data from unauthorized users and the methods for ensuring data integrity.

Security
All objects on the AS/400 system, including SQL objects, are managed by the system security function. Users may authorize SQL objects through either the SQL GRANT and REVOKE statements or the CL commands Edit Object Authority (EDTOBJAUT), Grant Object Authority (GRTOBJAUT), and Revoke Object Authority (RVKOBJAUT). For more information on system security and the use of the GRTOBJAUT and RVKOBJAUT commands, see the Security - Reference book. The SQL GRANT and REVOKE statements operate on SQL packages, SQL procedures, tables, views, and the individual columns of tables and views. Furthermore, SQL GRANT and REVOKE statements only grant private and public authorities. In some cases, it is necessary to use EDTOBJAUT, GRTOBJAUT, and RVKOBJAUT to authorize users to other objects, such as commands and programs. For more information on the GRANT and REVOKE statements, see the DB2 UDB for AS/400 SQL Reference book. The authority checked for SQL statements depends on whether the statement is static, dynamic, or being run interactively. For static SQL statements: v If the USRPRF value is *USER, the authority to run the SQL statement locally is checked using the user prole of the user running the program. The authority to run the SQL statement remotely is checked using the user prole at the application server. *USER is the default for system (*SYS) naming. v If the USRPRF value is *OWNER, the authority to run the SQL statement locally is checked using the user proles of the user running the program and of the owner of the program. The authority to run the SQL statement remotely is checked using the user proles of the application server job and the owner of the SQL package. The higher authority is the authority that is used. *OWNER is the default for SQL (*SQL) naming. For dynamic SQL statements: v If the USRPRF value is *USER, the authority to run the SQL statement locally is checked using the user prole of the person running the program. The authority to run the SQL statement remotely is checked using the user prole of the application server job. v If the USRPRF value is *OWNER and DYNUSRPRF is *USER, the authority to run the SQL statement locally is checked using the user prole of the person running the program. The authority to run the SQL statement remotely is checked using the user prole of the application server job. v If the USRPRF value is *OWNER and DYNUSRPRF is *OWNER, the authority to run the SQL statement locally is checked using the user proles of the user running the program and the owner of the program. The authority to run the SQL statement remotely is checked using the user proles of the application server job and the owner of the SQL package. The highest authority is the authority that is used. Because of security concerns, you should use the *OWNER parameter
Copyright IBM Corp. 1997, 1999

365

value for DYNUSRPRF carefully. This option gives the access authority of the owner program or package to those who run the program. For interactive SQL statements, authority is checked against the authority of the person processing the statement. Adopted authority is not used for interactive SQL statements.

Authorization ID
The authorization ID identies a unique user and is a user prole object on the AS/400 system. Authorization IDs can be created using the system Create User Prole (CRTUSRPRF) command.

Views
A view can prevent unauthorized users from having access to sensitive data. The application program can access the data it needs in a table, without having access to sensitive or restricted data in the table. A view can restrict access to particular columns by not specifying those columns in the SELECT list (for example, employee salaries). A view can also restrict access to particular rows in a table by specifying a WHERE clause (for example, allowing access only to the rows associated with a particular department number).

Auditing
DB2 UDB for AS/400 is designed to comply with the U.S. government C2 security level. A key feature of that level is the ability to audit actions on the system. DB2 UDB for AS/400 uses the audit facilities managed by the system security function. Auditing can be performed on an object level, user, or system level. The system value QAUDCTL controls whether auditing is performed at the object or user level. The Change User Audit (CHGUSRAUD) command and Change Object Audit (CHGOBJAUD) command specify which users and objects are audited. The system value QAUDLVL controls what types of actions are audited (for example, authorization failures, creates, deletes, grants, revokes, etc.) For more information on auditing see the Security - Reference book. DB2 UDB for AS/400 can also audit row changes by using the DB2 UDB for AS/400 journal support. In some cases, entries in the auditing journal will not be in the same order as they occured. For example, a job that is running under commitment control deletes a table, creates a new table with the same name as the one that was deleted, then does a commit. This will be recorded in the auditing journal as a create followed by a delete. This is because objects that are created are journalled immediately. An object that is deleted under commitment control is hidden and not actually deleted until a commit is done. Once the commit is done, the action is journaled.

Data Integrity
Data integrity protects data from being destroyed or changed by unauthorized persons, system operation or hardware failures (such as physical damage to a disk), programming errors, interruptions before a job is completed (such as a power failure), or interference from running applications at the same time (such as serialization problems). Data integrity is ensured by the following functions:

366

DB2 UDB for AS/400 SQL Programming V4R4

v v v v v

Concurrency Journaling Commitment control Atomic operations Constraints

v Save/restore v Damage tolerance v Index recovery The DB2 UDB for AS/400 Database Programming book and the Backup and Recovery book contain more information about each of these functions.

Concurrency
Concurrency is the ability for multiple users to access and change data in the same table or view at the same time without risk of losing data integrity. This ability is automatically supplied by the DB2 UDB for AS/400 database manager. Locks are implicitly acquired on tables and rows to protect concurrent users from changing the same data at precisely the same time. Typically, DB2 UDB for AS/400 will acquire locks on rows to ensure integrity. However, some situations require DB2 UDB for AS/400 to acquire a more exclusive table level lock instead of row locks. For more information see Commitment Control on page 369. | | | | | | | For example, an update (exclusive) lock on a row currently held by one cursor can be acquired by another cursor in the same program (or in a DELETE or UPDATE statement not associated with the cursor). This will prevent a positioned UPDATE or positioned DELETE statement that references the rst cursor until another FETCH is performed. A read (shared no-update) lock on a row currently held by one cursor will not prevent another cursor in the same program (or DELETE or UPDATE statement) from acquiring a lock on the same row. Default and user-speciable lock-wait time-out values are supported. DB2 UDB for AS/400 creates tables, views, and indexes with the default record wait time (60 seconds) and the default le wait time (*IMMED). This lock wait time is used for DML statements. You can change these values by using the CL commands Change Physical File (CHGPF), Change Logical File (CHGLF), and Override Database File (OVRDBF). The lock wait time used for all DDL statements and the LOCK TABLE statement, is the job default wait time (DFTWAIT). You can change this value by using the CL commands Change Job (CHGJOB) or Change Class (CHGCLS). In the event that a large record wait time is specied, deadlock detection is provided. For example, assume one job has an exclusive lock on row 1 and another job has an exclusive lock on row 2. If the rst job attempts to lock row 2, it will wait because the second job is holding the lock. If the second job then attempts to lock row 1, DB2 UDB for AS/400 will detect that the two jobs are in a deadlock and an error will be returned to the second job.

Chapter 21. DB2 UDB for AS/400 Data Protection

367

You can explicitly prevent other users from using a table at the same time by using the SQL LOCK TABLE statement, which is described in the DB2 UDB for AS/400 SQL Reference book. Using COMMIT(*RR) will also prevent other users from using a table during a unit of work. In order to improve performance, DB2 UDB for AS/400 will frequently leave the open data path (ODP) open (for more information see Chapter 25. Additional SQL performance considerations on page 459). This performance feature also leaves a lock on tables referenced by the ODP, but does not leave any locks on rows. A lock left on a table may prevent another job from performing an operation on that table. In most cases, however, DB2 UDB for AS/400 will detect that other jobs are holding locks and events will be signalled to those jobs. The event causes DB2 UDB for AS/400 to close any ODPs (and release the table locks) that are associated with that table and are currently only open for performance reasons. Note that the lock wait time out must be large enough for the events to be signalled and the other jobs to close the ODPs or an error will be returned. Unless the LOCK TABLE statement is used to acquire table locks, or either COMMIT(*ALL) or COMMIT(*RR) is used, data which has been read by one job can be immediately changed by another job. Usually, the data that is read at the time the SQL statement is executed and therefore it is very current (for example, during FETCH). In the following cases, however, data is read prior to the execution of the SQL statement and therefore the data may not be current (for example, during OPEN). v ALWCPYDTA(*OPTIMIZE) was specied and the optimizer determined that making a copy of the data would perform better than not making a copy. v Some queries require the database manager to create a temporary result table. The data in the temporary result table will not reect changes made after the cursor was opened. A temporary result table is required when: The total length in bytes of storage for the columns specied in an ORDER BY clause exceeds 2000 bytes. ORDER BY and GROUP BY clauses specify different columns or columns in a different order. UNION or DISTINCT clauses are specied. ORDER BY or GROUP BY clauses specify columns which are not all from the same table. Joining a logical le dened by the JOINDFT data denition specications (DDS) keyword with another le. Joining or specifying GROUP BY on a logical le which is based on multiple database le members. The query contains a join in which at least one of the les is a view which contains a GROUP BY clause. The query contains a GROUP BY clause which references a view that contains a GROUP BY clause. v A basic subquery is evaluated when the query is opened.

Journaling
The DB2 UDB for AS/400 journal support supplies an audit trail and forward and backward recovery. Forward recovery can be used to take an older version of a table and apply the changes logged on the journal to the table. Backward recovery can be used to remove changes logged on the journal from the table.

368

DB2 UDB for AS/400 SQL Programming V4R4

When an SQL collection is created, a journal and journal receiver are created in the collection. When SQL creates the journal and journal receiver, they are only created on a user auxiliary storage pool (ASP) if the ASP clause is specied on the CREATE COLLECTION or the CREATE SCHEMA statement. However, because placing journal receivers on their own ASPs can improve performance, the person managing the journal might want to create all future journal receivers on a separate ASP. When a table is created into the collection, it is automatically journaled to the journal DB2 UDB for AS/400 created in the collection (QSQJRN). A table created in a non-collection will also have journaling started if a journal named QSQJRN exists in that library. After this point, it is your responsibility to use the journal functions to manage the journal, the journal receivers, and the journaling of tables to the journal. For example, if a table is moved into a collection, no automatic change to the journaling status occurs. If a table is restored, the normal journal rules apply. That is, if the table was journaled at the time of the save, it is journaled to the same journal at restore time. If the table was not journaled at the time of the save, it is not journaled at restore time. The journal created in the SQL collection is normally the journal used for logging all changes to SQL tables. You can, however, use the system journal functions to journal SQL tables to a different journal. This may be necessary if a table in one collection is a parent to a table in another collection. This is because DB2 UDB for AS/400 requires that the parent and dependent le in a referential constraint be journaled to the same journal when updates or deletes are performed to the parent table. A user can stop journaling on any table using the journal functions, but doing so prevents an application from running under commitment control. If journaling is stopped on a parent table of a referential constraint with a delete rule of NO ACTION, CASCADE, SET NULL, or SET DEFAULT, all update and delete operations will be prevented. Otherwise, an application is still able to function if you have specied COMMIT(*NONE); however, this does not provide the same level of integrity that journaling and commitment control provide.

Commitment Control
The DB2 UDB for AS/400 commitment control support provides a means to process a group of database changes (updates, inserts, DDL operations, or deletes) as a single unit of work (transaction). A commit operation guarantees that the group of operations is completed. A rollback operation guarantees that the group of operations is backed out. A commit operation can be issued through several different interfaces. For example, v An SQL COMMIT statement v A CL COMMIT command v A language commit statement (such as an RPG COMMIT statement) A rollback operation can be issued through several different interfaces. For example, v An SQL ROLLBACK statement v A CL ROLLBACK command v A language rollback statement (such as an RPG ROLBK statement) The only SQL statements that cannot be committed or rolled back are:

Chapter 21. DB2 UDB for AS/400 Data Protection

369

v DROP COLLECTION v GRANT or REVOKE if an authority holder exists for the specied object If commitment control was not already started when either an SQL statement is executed with an isolation level other than COMMIT(*NONE) or a RELEASE statement is executed, then DB2 UDB for AS/400 sets up the commitment control environment by implicitly calling the CL command Start Commitment Control (STRCMTCTL). DB2 UDB for AS/400 species NFYOBJ(*NONE) and CMTSCOPE(*ACTGRP) parameters along with LCKLVL on the STRCMTCTL command. The LCKLVL specied is the lock level on the COMMIT parameter on the CRTSQLxxx, STRSQL, or RUNSQLSTM commands. In REXX, the LCKLVL specied is the lock level on the SET OPTION statement. 16 You may use the STRCMTCTL command to specify a different CMTSCOPE, NFYOBJ, or LCKLVL. If you specify CMTSCOPE(*JOB) to start the job level commitment denition, DB2 UDB for AS/400 uses the job level commitment denition for programs in that activation group. Note: When using commitment control, the tables referred to in the application program by Data Manipulation Language statements must be journaled. For cursors that use column functions, GROUP BY, or HAVING, and are running under commitment control, a ROLLBACK HOLD has no effect on the cursors position. In addition, the following occurs under commitment control: v If COMMIT(*CHG) and (ALWBLK(*NO) or (ALWBLK(*READ)) is specied for one of these cursors, a message (CPI430B) is sent that says COMMIT(*CHG) requested but not allowed. v If COMMIT(*ALL), COMMIT(*RR), or COMMIT(*CS) with the KEEP LOCKS clause is specied for one of the cursors, DB2 UDB for AS/400 will lock all referenced tables in shared mode (*SHRNUP). The lock prevents concurrent application processes from executing any but read-only operations on the named table. A message (either SQL7902 or CPI430A) is sent that says COMMIT(*ALL), COMMIT(*RR), or COMMIT(*CS) with the KEEP LOCKS clause is specied for one of the cursors requested but not allowed. Message SQL0595 may also be sent. For cursors where either COMMIT(*ALL), COMMIT(*RR), or COMMIT(*CS) with the KEEP LOCKS clause is specied and either catalog les are used or a temporary result table is required, DB2 UDB for AS/400 will lock all referenced tables in shared mode (*SHRNUP). This will prevent concurrent processes from executing anything but read-only operations on the table(s). A message (either SQL7902 or CPI430A) is sent that says COMMIT(*ALL) is requested but not allowed. Message SQL0595 may also be sent. If ALWBLK(*ALLREAD) and COMMIT(*CHG) were specied, when the program was precompiled, all read only cursors will allow blocking of rows and a ROLLBACK HOLD will not roll the cursor position back. If COMMIT(*RR) is requested, the tables will be locked until the query is closed. If the cursor is read only, the table will be locked (*SHRNUP). If the cursor is in

16. Note that the LCKLVL specied is only the default lock level. After commitment control is started, the SET TRANSACTION SQL statement and the lock level specied on the COMMIT parameter on the CRTSQLxxx, STRSQL, or RUNSQLSTM commands will override the default lock level.

370

DB2 UDB for AS/400 SQL Programming V4R4

update mode, the table will be locked (*EXCLRD). Since other users will be locked out of the table, running with repeatable read will prevent concurrent access of the table. If an isolation level other then COMMIT(*NONE) was specied and the application issues a ROLLBACK or the activation group ends normally (and the commitment denition is not *JOB), all updates, inserts, deletes, and DDL operations made within the unit of work are backed out. If the application issues a COMMIT or the activation group ends normally, all updates, inserts, deletes, and DDL operations made within the unit of work are committed. DB2 UDB for AS/400 uses locks on rows to keep other jobs from accessing changed data before a unit of work completes. If COMMIT(*ALL) is specied, read locks on rows fetched are also used to prevent other jobs from changing data that was read before a unit of work completes. This will not prevent other jobs from reading the unchanged records. This ensures that, if the same unit of work rereads a record, it gets the same result. Read locks do not prevent other jobs from fetching the same rows. Commitment control handles up to 4 million distinct row changes in a unit of work. If COMMIT(*ALL) or COMMIT(*RR) is specied, all rows read are also included in the limit. (If a row is changed or read more than once in a unit of work, it is only counted once toward the limit.) Holding a large number of locks adversely affects system performance and does not allow concurrent users to access rows locked in the unit of work until the end of the unit of work. It is in your best interest to keep the number of rows processed in a unit of work small. Commitment control will allow up to 512 les for each journal to be open under commitment control or closed with pending changes in a unit of work. COMMIT HOLD and ROLLBACK HOLD allows you to keep the cursor open and start another unit of work without issuing an OPEN again. The HOLD value is not available when you are connected to a remote database that is not on an AS/400 system. However, the WITH HOLD option on DECLARE CURSOR may be used to keep the cursor open after a COMMIT. This type of cursor is supported when you are connected to a remote database that is not on an AS/400 system. Such a cursor is closed on a rollback.
Table 36. Record Lock Duration
SQL Statement SELECT INTO SET variable VALUES INTO FETCH (read-only cursor) COMMIT Parameter (See note 6) *NONE *CHG *CS (See note 8) *ALL (See note 2) *NONE *CHG *CS (See note 8) *ALL (See note 2) Duration of Record Locks No locks No locks Row locked when read and released From read until ROLLBACK or COMMIT No locks No locks From read until the next FETCH From read until ROLLBACK or COMMIT Lock Type

READ READ

READ READ

Chapter 21. DB2 UDB for AS/400 Data Protection

371

Table 36. Record Lock Duration (continued)


SQL Statement FETCH (update or delete capable cursor) (See note 1) COMMIT Parameter (See note 6) *NONE Duration of Record Locks When record not updated or deleted from read until next FETCH When record is updated or deleted from read until UPDATE or DELETE When record not updated or deleted from read until next FETCH When record is updated or deleted from read until COMMIT or ROLLBACK When record not updated or deleted from read until next FETCH When record is updated or deleted from read until COMMIT or ROLLBACK From read until ROLLBACK or COMMIT No locks From insert until ROLLBACK or COMMIT From insert until ROLLBACK or COMMIT From insert until ROLLBACK or COMMIT No locks No locks Each record locked while being read From read until ROLLBACK or COMMIT Each From From From Each From From From Lock From From From Lock From From From From From From From record locked while being updated read until ROLLBACK or COMMIT read until ROLLBACK or COMMIT read until ROLLBACK or COMMIT record locked while being deleted read until ROLLBACK or COMMIT read until ROLLBACK or COMMIT read until ROLLBACK or COMMIT released when record updated read until ROLLBACK or COMMIT read until ROLLBACK or COMMIT read until ROLLBACK or COMMIT released when record deleted read until ROLLBACK or COMMIT read until ROLLBACK or COMMIT read until ROLLBACK or COMMIT read read read read until until until until next FETCH next FETCH next FETCH ROLLBACK or COMMIT Lock Type UPDATE

*CHG

UPDATE

*CS

UPDATE

*ALL INSERT (target table) *NONE *CHG *CS *ALL *NONE *CHG *CS *ALL *NONE *CHG *CS *ALL *NONE *CHG *CS *ALL *NONE *CHG *CS *ALL *NONE *CHG *CS *ALL *NONE *CHG *CS *ALL (see note 2)

UPDATE3 UPDATE UPDATE UPDATE4

INSERT (tables in subselect)

READ READ UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE READ READ READ READ

UPDATE (non-cursor)

DELETE (non-cursor)

UPDATE (with cursor)

DELETE (with cursor)

Subqueries (update or delete capable cursor or UPDATE or DELETE non-cursor)

Subqueries (read-only *NONE cursor or SELECT INTO) *CHG *CS *ALL

No locks No locks Each record locked while being read From read until ROLLBACK or COMMIT

READ READ

372

DB2 UDB for AS/400 SQL Programming V4R4

Table 36. Record Lock Duration (continued)


SQL Statement Notes: 1. A cursor is open with UPDATE or DELETE capabilities if the result table is not read-only (see description of DECLARE CURSOR in DB2 UDB for AS/400 SQL Reference book) and if one of the following is true: v The cursor is dened with a FOR UPDATE clause. v The cursor is dened without a FOR UPDATE, FOR READ ONLY, or ORDER BY clause and the program contains at least one of the following: Cursor UPDATE referring to the same cursor-name Cursor DELETE referring to the same cursor-name An EXECUTE or EXECUTE IMMEDIATE statement and ALWBLK(*READ) or ALWBLK(*NONE) was specied on the CRTSQLxxx command. 2. A table or view can be locked exclusively in order to satisfy COMMIT(*ALL). If a subselect is processed that includes a UNION, or if the processing of the query requires the use of a temporary result, an exclusive lock is acquired to protect you from seeing uncommitted changes. 3. If the row is not updated or deleted, the lock is reduced to *READ. 4. An UPDATE lock on rows of the target table and a READ lock on the rows of the subselect table. 5. A table or view can be locked exclusively in order to satisfy repeatable read. Row locking is still done under repeatable read. The locks acquired and their duration are identical to *ALL. 6. Repeatable read (*RR) record locks will be the same as the locks indicated for *ALL. 7. For a detailed explanation of isolation levels and locking, see the section entitled Isolation Level in Chapter 1 of the DB2 UDB for AS/400 SQL Reference book. 8. If the KEEP LOCKS clause is specied with *CS, any read locks are held until the cursor is closed or until a COMMIT or ROLLBACK is done. If no cursors are associated with the isolation clause, then locks are held until the completion of the SQL statement. COMMIT Parameter (See note 6) Duration of Record Locks Lock Type

Atomic Operations
When running under COMMIT(*CHG), COMMIT(*CS), or COMMIT(*ALL), all operations are guaranteed to be atomic. That is, they will complete or they will appear not to have started. This is true regardless of when or how the function was ended or interrupted (such as power failure, abnormal job end, or job cancel). If COMMIT (*NONE) is specied, however, some underlying database data denition functions are not atomic. The following SQL data denition statements are guaranteed to be atomic: ALTER TABLE (See note 1) COMMENT ON (See note 2) LABEL ON (See note 2) GRANT (See note 3) REVOKE (See note 3) DROP TABLE (See note 4) DROP VIEW (See note 4) DROP INDEX DROP PACKAGE

| | | | | | | | | | |

Chapter 21. DB2 UDB for AS/400 Data Protection

373

Notes: 1. If constraints need to be added or removed, as well as column denitions changed, the operations are processed one at a time, so the entire SQL statement is not atomic. The order of operation is: v remove constraints v drop columns for which the RESTRICT option was specied v all other column denition changes (DROP COLUMN CASCADE, ALTER COLUMN, ADD COLUMN) v add constraints 2. If multiple columns are specied for a COMMENT ON or LABEL ON statement, the columns are processed one at a time, so the entire SQL statement is not atomic, but the COMMENT ON or LABEL ON to each individual column or object will be atomic. 3. If multiple tables, SQL packages, or users are specied for a GRANT or REVOKE statement, the tables are processed one at a time, so the entire SQL statement is not atomic, but the GRANT or REVOKE to each individual table will be atomic. 4. If dependent views need to be dropped during DROP TABLE or DROP VIEW, each dependent view is processed one at a time, so the entire SQL statement is not atomic. The following data denition statements are not atomic because they involve more than one DB2 UDB for AS/400 database operation: CREATE ALIAS CREATE COLLECTION | | | CREATE DISTINCT TYPE CREATE FUNCTION CREATE PROCEDURE CREATE TABLE CREATE VIEW CREATE INDEX CREATE SCHEMA DROP ALIAS DROP COLLECTION DROP DISTINCT TYPE DROP FUNCTION DROP PROCEDURE DROP SCHEMA RENAME (See note 1) Notes: 1. RENAME is atomic only if the name or the system name is changed. When both are changed, the RENAME is not atomic. For example, a CREATE TABLE can be interrupted after the DB2 UDB for AS/400 physical le has been created, but before the member has been added. Therefore, in the case of create statements, if an operation ends abnormally, you may have to drop the object and then create it again. In the case of a DROP COLLECTION statement, you may have to drop the collection again or use the CL command Delete Library (DLTLIB) to remove the remaining parts of the collection.

| | |

374

DB2 UDB for AS/400 SQL Programming V4R4

Constraints
DB2 UDB for AS/400 supports unique, referential, and check constraints. A unique constraint is a rule that guarantees that the values of a key are unique. A referential constraint is a rule that all non-null values of foreign keys in a dependent table have a corresponding parent key in a parent table. A check constraint is a rule that limits the values allowed in a column or group of columns. DB2 UDB for AS/400 will enforce the validity of the constraint during any DML (data manipulation language) statement. Certain operations (such as restore of the dependent table), however, cause the validity of the constraint to be unknown. In this case, DML statements may be prevented until DB2 UDB for AS/400 has veried the validity of the constraint. v Unique constraints are implemented with indexes. If an index that implements a unique constraint is invalid, the Edit Rebuild of Access Paths (EDTRBDAP) command can be used to display any indexes that currently require rebuild. v If DB2 UDB for AS/400 does not currently know whether a referential constraint or check constraint is valid, the constraint is considered to be in a check pending state. The Edit Check Pending Constraints (EDTCPCST) command can be used to display any indexes that currently require rebuild. For more information on constraints see the DB2 UDB for AS/400 Database Programming book.

Save/Restore
| | | | | | | | | | | | | | | | | | | | | | | The AS/400 save/restore functions are used to save tables, views, indexes, journals, journal receivers, SQL packages, SQL procedures, user-dened functions, user-dened types, and collections on disk (save le) or to some external media (tape or diskette). The saved versions can be restored onto any AS/400 system at some later time. The save/restore function allows an entire collection, selected objects, or only objects changed since a given date and time to be saved. All information needed to restore an object to its previous state is saved. This function can be used to recover from damage to individual tables by restoring the data with a previous version of the table or the entire collection. When a program that was created for an SQL procedure or a service program that was created for an SQL function or a sourced function is restored, it is automatically added to the SYSROUTINES and SYSPARMS catalogs, as long as the procedure or function does not already exist with the same signature. SQL programs created in QSYS will not be created as SQL procedures when restored. Additionally, external programs or service programs that were referenced on a CREATE PROCEDURE or CREATE FUNCTION statement may contain the information required to register the routine in SYSROUTINES. If the information exists and the signature is unique, the functions or procedures will also be added to SYSROUTINES and SYSPARMS when restored. When an *SQLUDT object is restored for a user-dened type, the user-dened type is automatically added to the SYSTYPES catalog. The appropriate functions needed to cast between the user-dened type and the source type are also created, as long as the type and functions do not already exist. Either a distributed SQL program or its associated SQL package can be saved and restored to any number of AS/400 systems. This allows any number of copies of the SQL programs on different systems to access the same SQL package on the same
Chapter 21. DB2 UDB for AS/400 Data Protection

375

application server. This also allows a single distributed SQL program to connect to any number of application servers that have the SQL package restored (CRTSQLPKG can also be used). SQL packages cannot be restored to a different library. Attention: Restoring a collection to an existing library or to a collection that has a different name does not restore the journal, journal receivers, or IDDU dictionary (if one exists). If the collection is restored to a collection with a different name, the catalog views in that collection will only reect objects in the old collection. The catalog views in QSYS2, however, will appropriately reect all objects.

Damage Tolerance
The AS/400 system provides several mechanisms to reduce or eliminate damage caused by disk errors. For example, mirroring, checksums, and RAID disks can all reduce the possibility of disk problems. The DB2 UDB for AS/400 functions also have a certain amount of tolerance to damage caused by disk errors or system errors. A DROP operation always succeeds, regardless of the damage. This ensures that should damage occur, at least the table, view, SQL package, or index can be deleted and restored or created again. In the event that a disk error has damaged a small portion of the rows in a table, the DB2 UDB for AS/400 database manager allows you to read rows still accessible.

Index Recovery
DB2 UDB for AS/400 supplies several functions to deal with index recovery. v System managed index protection The EDTRCYAP CL command allows a user to instruct DB2 UDB for AS/400 to guarantee that in the event of a system or power failure, the amount of time required to recover all indexes on the system is kept below a specied time. The system automatically journals enough information in a system journal to limit the recovery time to the specied amount. v Journaling of indexes DB2 UDB for AS/400 supplies an index journaling function that makes it unnecessary to rebuild an entire index due to a power or system failure. If the index is journaled, the system database support automatically makes sure the index is in synchronization with the data in the tables without having to rebuild it from scratch. SQL indexes are not journaled automatically. You can, however, use the CL command Start Journal Access Path (STRJRNAP) to journal any index created by DB2 UDB for AS/400. v Index rebuild All indexes on the system have a maintenance option that species when an index is maintained. SQL indexes are created with an attribute of *IMMED maintenance. In the event of a power failure or abnormal system failure, if indexes were not protected by one of the previously described techniques, those indexes in the process of change may need to be rebuilt by the database manager to make sure they agree with the actual data. All indexes on the system have a recovery option that species when an index should be rebuilt if necessary. All SQL indexes with an attribute of UNIQUE are created with a recovery attribute of *IPL

376

DB2 UDB for AS/400 SQL Programming V4R4

(this means that these indexes are rebuilt before the OS/400 has been started). All other SQL indexes are created with the *AFTIPL recovery option (this means that after the operating system has been started, indexes are asynchronously rebuilt). During an IPL, the operator can see a display showing indexes needing to be rebuilt and their recovery option. The operator can override the recovery options. v Save and restore of indexes The save/restore function allows you to save indexes when a table is saved by using ACCPTH(*YES) on the Save Object (SAVOBJ) or Save Library (SAVLIB) CL commands. In the event of a restore when the indexes have also been saved, there is no need to rebuild the indexes. Any indexes not previously saved and restored are automatically and asynchronously rebuilt by the database manager.

Catalog Integrity
Catalogs contain information about tables, views, SQL packages, indexes, procedures, and parameters in a collection. The database manager ensures that the information in the catalog is accurate at all times. This is accomplished by preventing end users from explicitly changing any information in the catalog and by implicitly maintaining the information in the catalog when changes occur to the tables, views, SQL packages, indexes, procedures, and parameters described in the catalog. The integrity of the catalog is maintained whether objects in the collection are changed by SQL statements, OS/400 CL commands, System/38 Environment CL commands, System/36 Environment functions, or any other product or utility on an AS/400 system. For example, deleting a table can be done by running an SQL DROP statement, issuing an OS/400 DLTF CL command, issuing a System/38 DLTF CL command or entering option 4 on a WRKF or WRKOBJ display. Regardless of the interface used to delete the table, the database manager will remove the description of the table from the catalog at the time the delete is performed. The following is a list of functions and the associated effect on the catalog:
Table 37. Effect of Various Functions on Catalogs
Function Add constraint to table Remove of constraint from table Create object into collection Delete of object from collection Restore of object into collection Change of object long comment Change of object label (text) Change of object owner Move of object from a collection Move of object into collection Rename of object Effect on the Catalog Information added to catalog Related information removed from catalog Information added to catalog Related information removed from catalog Information added to catalog Comment updated in catalog Label updated in catalog Owner updated in catalog Related information removed from catalog Information added to catalog Name of object updated in catalog

Chapter 21. DB2 UDB for AS/400 Data Protection

377

User Auxiliary Storage Pool (ASP)


An SQL collection can be created in a user ASP by using the ASP clause on the CREATE COLLECTION and CREATE SCHEMA statements. The CRTLIB command can also be used to create a library in a user ASP. That library can then be used to receive SQL tables, views, and indexes. See the Backup and Recovery book and the Backup and Recovery book for more information on auxiliary storage pools.

378

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 22. Testing SQL Statements in Application Programs


This chapter describes how to establish a test environment for SQL statements in an application program and how to debug this program.

Establishing a Test Environment


Some things you need to test your program are: v Authorization. You need to be authorized to create tables and views, access SQL data, and create and run programs. v A test data structure. If your program updates, inserts, or deletes data from tables and views, you should use test data to verify the running of the program. If your program only retrieves data from tables and views, you might consider using production-level data when testing your program. It is recommended, however, that you use the CL command Start Debug (STRDBG) with UPDPROD(*NO) to assure that the production level data does not accidentally get changed. See the chapter on testing in the CL Programmingbook for more information on debugging. v Test input data. The input data your program uses during testing should be valid data that represents as many possible input conditions as you can think of. You cannot be sure that your output data is valid unless you use valid input data. If your program veries that input data is valid, include both valid and not valid data to verify that the valid data is processed and the not valid data is detected. You might have to refresh the data for subsequent tests. To test the program thoroughly, test as many of the paths through the program as possible. For example: v Use input data that forces the program to run each of its branches. v Check the results. For example, if the program updates a row, select the row to see if it was updated correctly. v Be sure to test the program error routines. Again, use input data that forces the program to encounter as many of the anticipated error conditions as possible. v Test the editing and validation routines your program uses. Give the program as many different combinations of input data as possible to verify that it correctly edits or validates that data.

Designing a Test Data Structure


To test an application that accesses SQL data, you might have to create test tables and views: v Test views of existing tables. If your application does not change data and the data exists in one or more production-level tables, you might consider using a view of the existing tables. It is also recommended that you use STRDBG command with UPDPROD(*NO) to assure that the production level data does not accidentally get changed. See the chapter on testing in the CL Programming for more information on debugging. v Test tables. When your application creates, changes, or deletes data, you will probably want to test the application by using tables that contain test data. See Chapter 2. Getting Started with SQL for a description of how to create tables and views.

Copyright IBM Corp. 1997, 1999

379

Also, you might want to use the CL command Create Duplicate Object (CRTDUPOBJ) to create a duplicate test table, view, or index.

Authorization
Before you can create a table, you must be authorized to create tables and to use the collection in which the table is to reside. In addition, you must have authority to create and run the programs you want to test. If you intend to use existing tables and views (either directly or as the basis for a view), you must be authorized to access those tables and views. If you want to create a view, you must be authorized to create views and must have authorization to each table and view on which the view is based. For more information on specic authorities required for any specic SQL statement, see the DB2 UDB for AS/400 SQL Reference book.

Testing Your SQL Application Programs


There are two phases for testing DB2 UDB for AS/400 SQL applications: the program debug phase and the performance verication phase.

The Program Debug Phase


This test phase is done to ensure that the SQL queries are specied correctly and that the program is producing the correct results. Debugging your program with SQL statements is much the same as debugging your program without SQL statements. However, when SQL statements are run in a job in the debug mode, the database manager puts messages in the job log about how each SQL statement ran. This message is an indication of the SQLCODE for the SQL statement. If the statement ran successfully, the SQLCODE value is zero, and a completion message is issued. A negative SQLCODE results in a diagnostic message. A positive SQLCODE results in an informational message. The message is either a 4-digit code prexed by SQL or a 5-digit code prexed by SQ. For example, an SQLCODE of 204 results in a message of SQL0204, and an SQLCODE of 30000 results in a message of SQ30000. Associated with a SQLCODE is a SQLSTATE. The SQLSTATE is an additional return code provided in the SQLCA that identies common error conditions among the different IBM relational database products. The same error condition on different relational database products will produce the same SQLSTATE. The same error conditions will not produce the same SQLCODE. This return code is particularly useful when determining the cause of errors returned from the relational database operations performed on non-DB2 UDB for AS/400 system. For non-ILE program debugging, references to high-level language statement numbers in debug mode must be taken from the compile listing. For ILE program debugging, precompile the program specifying DBGVIEW(*SOURCE) and then use the source-level debugger. SQL will always put messages in the job log for negative SQLCODEs and positive codes other than +100 regardless of whether it is in debug mode or not.

380

DB2 UDB for AS/400 SQL Programming V4R4

The Performance Verication Phase


This test phase veries that the appropriate indexes are available and that the queries are coded in a manner that allows the database manager to resolve the queries in the expected response time. The performance of an SQL application is dependent on the attributes of the tables being accessed. If you use small tables, the response time of the query is not affected by the availability of indexes. However, when you run that same query on a database with large tables and appropriate indexes do not exist, the response time for the queries can be very long. The test environment should resemble the production environment as closely as possible. The test collection should have tables with the same names and composition as the production collection. The same indexes need to be available over the tables in both collections. The number of rows and the distribution of values in the tables should be similar.

CL Command Usage for SQL Application Performance Verication


Verication of the performance of an SQL application can be done using the following commands: CHGQRYA The CL command Change Query Attribute (CHGQRYA) can be used to prevent users from running long queries. This command can be used to set the parameter Query Time Limit (QRYTIMLMT) to prevent a query from starting whose estimated number of elapsed seconds is longer than the specied number of seconds. This stops the building of temporary indexes or other resource intensive query operations. Also, a query which is canceled because of the query time limit creates performance information messages in the job log, even if the job in not in debug. For information restricting query runtime using this command, see Chapter 23. Using the DB2 UDB for AS/400 Predictive Query Governor on page 391. DSPJOB The CL command Display Job (DSPJOB) with parameter OPTION(*OPNF) shows the indexes and tables being used by an application that is running in a job. DSPJOB with parameter OPTION(*JOBLCK) can be used to analyze object and row lock contention. It displays the objects and rows that are locked and the name of the job holding the lock. DSPJOB with parameter OPTION(*CMTCTL) shows the isolation level that the program is running, the number of rows being locked during a transaction, and the pending DDL functions. The isolation level displayed is the default isolation level. The actual isolation level, used for any SQL program, is specied on the COMMIT parameter of the CRTSQLxxx command.
Chapter 22. Testing SQL Statements in Application Programs

381

PRTSQLINF

The CL command Print Structured Query Language Information (PRTSQLINF) allows you to print information about the embedded SQL statements in a program, SQL package, or service program. The information includes the SQL statements, the access plans used during the running of the statement, and a list of the command parameters used to precompile the source member for the object. For more information on printing information about SQL Statements, see the PRTSQLINF section in Appendix D. DB2 UDB for AS/400 CL Command Descriptions on page 645. The CL command Trace Job (TRCJOB) can be used to capture a trace of the program modules being run for an SQL application. The trace job output lists the indexes and les being used when the initial database open processing occurs for each SQL statement. Also, the processing unit and page resource usage for running each SQL statement can be determined.

TRCJOB

Performance Information Messages


You can evaluate the structure and performance of the given SQL statements in a program using informational messages put in the job log by the database manager. The messages are issued for an SQL program or interactive SQL when running in the debug mode. The database manager may send any of the following messages when appropriate. The ampersand variables (&1, &X) are replacement variables that contain either an object name or some other substitution value when the message appears in the job log. The messages are: v CPI4321 Access path built for le &1. v CPI4322 Access path built from keyed le &1. v CPI4323 The OS/400 query access plan has been rebuilt. v CPI4324 Temporary le built for le &1. v CPI4325 Temporary result le built for query. v CPI4326 File &1 processed in join position &X. v v v v v v v CPI4327 File &1 processed in join position 1. CPI4328 Access path &4 was used by query. CPI4329 Arrival sequence access was used for le &1. CPI432A Query optimizer timed out. CPI432B Subselects processed as join query. CPI432C All access paths were considered for le &1. CPI432D Additional access path reason codes were used.

v CPI432E Selection elds mapped to different attributes. v CPI432F Access path suggestion for le &1. v CPI4330 &6 tasks used for parallel &10 scan of le &1. v CPI4331 &6 tasks used for parallel index created over le &1. v CPI4332 &1 host variables used in query. v CPI4333 Hashing algorithm used to process join. v CPI4334 Query implemented as reusable ODP.

382

DB2 UDB for AS/400 SQL Programming V4R4

| | |

v v v v v v v v v v v v v v v v v v

CPI4335 CPI4336 CPI4337 CPI4338 CPI4339

Optimizer debug messages for hash join step &1 follow: Group processing generated. Temporary hash table built for hash join step &1. &1 Access path(s) used for bitmap processing of le &2. Query options retrieved from Library &1.

CPI433A Unable to retrieve query options le. CPI433C Library &1 not found. CPI4341 Performing distributed query. CPI4342 Performing distributed join for query. CPI4345 Temporary distributed result le &4 built for query. SQL7910 SQL cursors closed. SQL7911 ODP reused. SQL7912 ODP created. SQL7913 ODP deleted. SQL7914 ODP not deleted. SQL7915 Access plan for SQL statement has been built. SQL7916 Blocking used for query. SQL7917 Access plan not updated.

v SQL7918 Reusable ODP deleted. v SQL7919 Data conversion required on FETCH or embedded SELECT. v SQL7939 Data conversion required on INSERT or UPDATE. These messages provide feedback on how a query was run and, in some cases, indicate the improvements that can be made to help the query run faster. The messages contain message help that provides information about the cause for the message, object name references, and possible user responses. The time at which the message is sent does not necessarily indicate when the associated function was performed. Some messages are sent altogether at the start of a query run. The causes and user responses for the following messages are paraphrased. The actual message help is more complete and should be used when trying to determine the meaning and responses for each message. The possible user action for each message follows: CPI4321 - Access path built for le &1. This message indicates that a temporary access path was created to process the query. The new access path is created by reading all of the records in the specied le. The time required to create an access path on each run of a query can be signicant. Consider creating a logical le (CRTLF) or an SQL index (CREATE INDEX SQL statement): v Over the le named in the message help. v With key elds named in the message help. v With the ascending or descending sequencing specied in the message help.
Chapter 22. Testing SQL Statements in Application Programs

383

v With the sort sequence table specied in the message help. Consider creating the logical le with select or omit criteria that either match or partially match the querys predicates involving constants. The database manager will consider using select or omit logical les even though they are not explicitly specied on the query. For certain queries, the optimizer may decide to create an access path even when an existing one can be used. This might occur when a query has an ordering eld as a key eld for an access path, and the only record selection specied uses a different eld. If the record selection results in roughly 20% of the records or more to be returned, then the optimizer may create a new access path to get faster performance when accessing the data. The new access path minimizes the amount of data that needs to be read. CPI4322 - Access path built from keyed le &1. This message indicates that a temporary access path was created from the access path of a keyed le. Generally, this action should not take a signicant amount of time or resource because only a subset of the data in the le needs to be read. Sometimes even faster performance can be achieved by creating a logical le or SQL index that satises the access path requirement stated in the message help. For more detail, see the previous message, CPI4321. CPI4323 - The OS/400 query access plan has been rebuilt. This message can be sent for a variety of reasons. The specic reason is provided in the message help. Most of the time, this message is sent when the queried le environment has changed, making the current access plan obsolete. An example of the le environment changing is when an access path required by the query no longer exists on the system. An access plan contains the instructions for how a query is to be run and lists the access paths for running the query. If a needed access path is no longer available, the query is again optimized, and a new access plan is created, replacing the old one. The process of again optimizing the query and building a new access plan at runtime is a function of DB2 UDB for AS/400. It allows a query to be run as efficiently as possible, using the most current state of the database without user intervention. The infrequent appearance of this message is not a cause for action. For example, this message will be sent when an SQL package is run the rst time after a restore, or anytime the optimizer detects that a change has occurred (such as a new index was created), that warrants an implicit rebuild. However, excessive rebuilds should be avoided because extra query processing will occur. Excessive rebuilds may indicate a possible application design problem or inefficient database management practices. CPI4324 - Temporary le built for le &1.

384

DB2 UDB for AS/400 SQL Programming V4R4

Before the query processing could begin, the data in the specied le had to be copied into a temporary physical le to simplify running the query. The message help contains the reason why this message was sent. If the specied le selects few rows, usually less than 1000 rows, then the row selection part of the querys implementation should not take a signicant amount of resource and time. However if the query is taking more time and resources than can be allowed, consider changing the query so that a temporary le is not required. One way to do this is by breaking the query into multiple steps. Consider using an INSERT statement with a subselect to select only the records that are required into a physical le, and then use that les records for the rest of the query. CPI4325 - Temporary result le built for query. A temporary result le was created to contain the intermediate results of the query. The message help contains the reason why a temporary result le is required. In some cases, creating a temporary result le provides the fastest way to run a query. Other queries that have many records to be copied into the temporary result le can take a signicant amount of time. However, if the query is taking more time and resources than can be allowed, consider changing the query so that a temporary result le is not required. CPI4326 - File &1 processed in join position &11. This message provides the join position of the specied le when an access path is used to access the les data. Join position pertains to the order in which the les are joined. The order in which les are joined can signicantly inuence the efficiency of a query. The system processes the join of two les with different numbers of selected records more efficiently when the le with the smaller number of selected records is joined to the le with the larger number of selected records. For example, if two les are being joined, the le with the fewest selected records should be in join position 1 and the le with the larger number of selected records should be in join position 2. If the GROUP BY or ORDER BY clause is specied where all the columns in the clause are referenced from one of the les in the query, that le becomes the rst le in the nal join order. If the referenced le is a large le, the query may be slow. To improve performance, consider one of the following: v Add an additional column from a different le to the clause. A temporary result table is used to allow the system to order the les in the most efficient join order. v Specify the ALWCPYDTA(*OPTIMIZE) parameter on the ORDER BY clause. The system orders the les in the most efficient join order. When a query is changed as suggested above, a temporary result table may be used to change the join order. The improved efficiency of the join order will, in most cases, make up for any loss of efficiency caused by the temporary result. If the query uses the JOIN clause or refers to a join logical le within the le specications, the order in which the les are specied will help determine the join

Chapter 22. Testing SQL Statements in Application Programs

385

order the optimizer uses. The optimizer cannot change the le join order if the query contains a join logical le, or if either a left outer or exception join is specied using the JOIN clause. CPI4327 - File &1 processed in join position 1. This message provides the name of the rst or primary le of the join when arrival sequence is used to select records from the le. See the previous message, CPI4326, for information on join position and join performance tips. CPI4328 - Access path of le &4 was used by query. This message names an existing access path that was used by the query. The reason the access path was used is given in the message help. CPI4329 - Arrival sequence access was used for le &1. No access path was used to access the data in the specied le. The records were scanned sequentially in arrival sequence. The use of an access path may improve the performance of the query if record selection is specied. If an access path does not exist, you may want to create one whose key eld matches one of the elds in the record selection. You should only create an access path if the record selection (WHERE clause) selects 20% or fewer records in the le. To force the use of an existing access path, change the ORDER BY clause of the query to specify the rst key eld of the access path. CPI432A - Query optimizer timed out for le &1. The optimizer stops considering access paths when the time spent optimizing the query exceeds an internal value that is associated with the estimated time to run the query and the number of records in the queried les. Generally, the more records in the les, the greater the number of access paths that will be considered. When the estimated time to run the query is exceeded, the optimizer uses the current best method for running the query. Either an access path has been found to get the best performance, or an access path will have to be created, if necessary. Exceeding the estimated time to run the query could mean that the optimizer did not consider the best access path to run the query. The message help contains a list of access paths that were considered before the optimizer exceeded the estimated time. To ensure that an access path is considered for optimization, specify the logical le associated with the access path as the le to be queried. The optimizer will consider the access path of the le specied on the query or SQL statement rst. Remember that SQL indexes cannot be queried. You may want to delete any access paths that are no longer needed.

386

DB2 UDB for AS/400 SQL Programming V4R4

CPI432B - Subselects processed as join query. Two or more SQL subselects were combined by the query optimizer and processed as a join query. Generally, this method of processing is a good performing option. CPI432C - All access paths were considered for le &1. The optimizer considered all access paths built over the specied le. Since the optimizer examined all access paths for the le, it determined the current best access to the le. The message help contains a list of the access paths. With each access path a reason code is added. The reason code explains why the access path was not used. CPI432D - Additional access path reason codes were used. Message CPI432A or CPI432C was issued immediately before this message. Because of message length restrictions, some of the reason codes used by messages CPI432A and CPI432C are explained in the message help of CPI432D. Use the message help from this message to interpret the information returned from message CPI432A or CPI432C. CPI432E - Selection elds mapped to different attributes. This message indicates that the query optimizer was not able to consider the usage of an index to resolve one or more of the selection specications of the query. If there was an index available which otherwise could have been used to limit the processing of the query to just a few rows, then the performance of this query will be affected. The attributes of a comparison value and a comparison column must match otherwise a conversion will occur so that they do match. Generally, this conversion occurs such that the value with the smallest attributes is mapped to the attributes of the other value. When the attributes of the comparison column have to be mapped to be compatible with that of the comparison value, the optimizer can no longer use an index to implement this selection. CPI4338 &1 Access path(s) used for bitmap processing of le &2. The optimizer chooses to use one or more access paths, in conjunction with the query selection (WHERE clause), to build a bitmap. This resulting bitmap indicates which records will actually be selected. Conceptually, the bitmap contains one bit per record in the underlying table. Corresponding bits for selected records are set to 1. All other bits are set to 0. Once the bitmap is built, it is used, as appropriate, to avoid mapping in records from the table not selected by the query. The use of the bitmap depends on whether the bitmap is used in combination with the arrival sequence or with a primary access path. When bitmap processing is used with arrival sequence, either message CPI4327 or CPI4329 will precede this message. In this case, the bitmap will help to selectively map only those records from the table that the query selected.

Chapter 22. Testing SQL Statements in Application Programs

387

When bitmap processing is used with a primary access path, either message CPI4326 or CPI4328 will precede this message. Records selected by the primary access path will be checked against the bitmap before mapping the record from the table.

Performance Information Messages and Open Data Paths


Several of the following SQL run-time messages refer to open data paths. An open data path (ODP) denition is an internal object that is created when a cursor is opened or when other SQL statements are run. It provides a direct link to the data so that I/O operations can occur. ODPs are used on OPEN, INSERT, UPDATE, DELETE, and SELECT INTO statements to perform their respective operations on the data. Even though SQL cursors are closed and SQL statements have already been run, the database manager in many cases will save the associated ODPs of the SQL operations to reuse them the next time the statement is run. So an SQL CLOSE statement may close the SQL cursor but leave the ODP available to be used again the next time the cursor is opened. This can signicantly reduce the processing and response time in running SQL statements. The ability to reuse ODPs when SQL statements are run repeatedly is an important consideration in achieving faster performance. The following informational messages are issued at SQL run time: SQL7910 - All SQL cursors closed. This message is sent when the jobs call stack no longer contains a program that has run an SQL statement. Unless CLOSQLCSR(*ENDJOB) or CLOSQLCSR(*ENDACTGRP) was specied, the SQL environment for reusing ODPs across program calls exists only until the active programs that ran the SQL statements complete. Except for ODPs associated with *ENDJOB or *ENDACTGRP cursors, all ODPs are deleted when all the SQL programs on the call stack complete and the SQL environment is exited. This completion process includes closing of cursors, the deletion of ODPs, the removal of prepared statements, and the release of locks. Putting an SQL statement that can be run in the rst program of an application keeps the SQL environment active for the duration of that application. This allows ODPs in other SQL programs to be reused when the programs are repeatedly called. CLOSQLCSR(*ENDJOB) or CLOSQLCSR(*ENDACTGRP) can also be specied. SQL7911 - ODP reused. This message indicates that the last time the statement was run or when a CLOSE statement was run for this cursor, the ODP was not deleted. It will now be used again. This should be an indication of very efficient use of resources by eliminating unnecessary OPEN and CLOSE operations.

388

DB2 UDB for AS/400 SQL Programming V4R4

SQL7912 - ODP created. No ODP was found that could be used again. The rst time that the statement is run or the cursor is opened for a process, an ODP will always have to be created. However, if this message appears on every run of the statement or open of the cursor, the tips recommended in Improving Performance by Retaining Cursor Positions for Non-ILE Program Calls on page 467 should be applied to this application. SQL7913 - ODP deleted. For a program that is run only once per job, this message could be normal. However, if this message appears on every run of the statement or open of the cursor, then the tips recommended in Improving Performance by Retaining Cursor Positions for Non-ILE Program Calls on page 467 should be applied to this application. SQL7914 - ODP not deleted. If the statement is rerun or the cursor is opened again, the ODP should be available again for use. SQL7915 - Access plan for SQL statement has been built. The DB2 UDB for AS/400 precompilers allow the creation of the program objects even when required tables are missing. In this case the binding of the access plan is done when the program is rst run. This message indicates that an access plan was created and successfully stored in the program object. SQL7916 - Blocking used for query. SQL will request multiple records from the database manager when running this statement instead of requesting one record at a time. SQL7917 - Access plan not updated. The database manager rebuilt the access plan for this statement, but the program could not be updated with the new access plan. Another job is currently running the program that has a shared lock on the access plan of the program. The program cannot be updated with the new access plan until the job can obtain an exclusive lock on the access plan of the program. The exclusive lock cannot be obtained until the shared lock is released. The statement will still run and the new access plan will be used; however, the access plan will continue to be rebuilt when the statement is run until the program is updated. SQL7918 - Reusable ODP deleted. A reusable ODP exists for this statement, but either the jobs library list or override specications have changed the query.

Chapter 22. Testing SQL Statements in Application Programs

389

The statement now refers to different les or uses different override specications than are in the existing ODP. The existing ODP cannot be reused, and a new ODP must be created. To make it possible to reuse the ODP, avoid changing the library list or the override specications. SQL7919 - Data conversion required on FETCH or embedded SELECT. When mapping data to host variables, data conversions were required. When these statements are run in the future, they will be slower than if no data conversions were required. The statement ran successfully, but performance could be improved by eliminating the data conversion. For example, a data conversion that would cause this message to occur would be the mapping of a character string of a certain length to a host variable character string with a different length. You could also cause this error by mapping a numeric value to a host variable that is a different type (decimal to integer). To prevent most conversions, use host variables that are of identical type and length as the columns that are being fetched. SQL7939 - Data conversion required on INSERT or UPDATE. The attributes of the INSERT or UPDATE values are different than the attributes of the columns receiving the values. Since the values must be converted, they cannot be directly moved into the columns. Performance could be improved if the attributes of the INSERT or UPDATE values matched the attributes of the columns receiving the values.

390

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 23. Using the DB2 UDB for AS/400 Predictive Query Governor
The DB2 UDB for AS/400 Predictive Query Governor (governor) can stop the initiation of a query if the querys estimated or predicted runtime (elapsed execution time) is excessive. The governor acts before a query is run instead of while a query is run. The governor can be used in any interactive or batch job on the AS/400. It can be used with all DB2 UDB for AS/400 query interfaces and is not limited to use with SQL queries. | | | | | | | | | | The ability of the governor to predict and stop queries before they are started is important because: v Operating a long-running query and abnormally ending the query before obtaining any results wastes system resources. v Some operations within a query cannot be interrupted by the End Request (ENDRQS) CL command. The creation of a temporary keyed access path or a query using a column function without a GROUP BY clause are two examples of these types of queries. It is important to not start these operations if they will take longer than the user wants to wait. The governor in DB2 UDB for AS/400 is based on the estimated runtime for a query. If the querys estimated runtime exceeds the user dened time limit, the initiation of the query can be stopped. The time limit is user-dened and can be specied in one of three ways: v Using the Query Time Limit (QRYTIMLMT) parameter on the Change Query Attributes (CHGQRYA) CL command. v Setting the QQRYTIMLMT system value and allowing each job to use the value *SYSVAL on the CHGQRYA CL command. v Setting the Query Time Limit option in the Query Options File QAQQINI on page 543. The governor works in conjunction with the query optimizer. When a user requests DB2 UDB for AS/400 to run a query, the following occurs: 1. The query access plan is evaluated by the optimizer. As part of the evaluation, the optimizer predicts or estimates the runtime for the query. This helps determine the best way to access and retrieve the data for the query. 2. The estimated runtime is compared against the user-dened query time limit currently in effect for the job or user session. 3. If the predicted runtime for the query is less than or equal to the query time limit, the query governor lets the query run without interruption and no message is sent to the user. 4. If the query time limit is exceeded, inquiry message CPA4259 is sent to the user. The message states that the estimated query processing time of XX seconds exceeds the time limit of YY seconds. Note: A default reply can be established for this message so that the user does not have the option to reply to the message, and the query request is always ended. 5. If a default message reply is not used, the user chooses to do one of the following:
Copyright IBM Corp. 1997, 1999

| | | | |

391

v End the query request before it is actually run. v Continue and run the query even though the predicted runtime exceeds the governor time limit.

Cancelling a Query
When a query is expected to run longer than the set time limit, the governor issues inquiry message CPA4259. The user enters a C to cancel the query or an I to ignore the time limit and let the query run to completion. If the user enters C, escape message CPF427F is issued to the SQL runtime code. SQL returns SQLCODE -666.

General Implementation Considerations


| | | | | | | | | It is important to remember that the time limit generated by the optimizer is only an estimate. The actual query runtime could be more or less than the estimate, but the value of the two should be about the same. When setting the time limit for the entire system, it is usually best to set the limit to the maximum allowable time that any query should be allowed to run. By setting the limit too low you will run the risk of preventing some queries from completing and thus preventing the application from successfully nishing. There are many functions that use the query component to internally perform query requests. These requests will also be compared to the user-dened time limit.

User Application Implementation Considerations


| | | | | | | | | | | | | The time limit specied for the governor is established on a per-job basis by the query optimizer. The query optimizer determines the time limit using the following process: 1. The query optimizer attempts to extract the time limit from the QRYTIMLMT parameter on the CHGQRYA command. 2. If the time limit is not explicitly specied on the CHGQRYA command, it uses the query options le that is in use for this job. 3. If the time limit parameter in the query options le has been set to *DEFAULT, then the value that is stored in the QQRYTIMLMT system value is used for this job or user session. You can also set the time limit for a job other than the current job. You do this by using the JOB parameter on the CHGQRYA command to specify either a query options le library to search (QRYOPTLIB) or a specic QRYTIMLMT for that job. After the source job runs the CHGQRYA command, effects of the governor on the target job is not dependent upon the source job. The query time limit remains in effect for the duration of the job or user session, or until the time limit is changed by a CHGQRYA command. Under program control, a user could be given different query time limits depending on the application function being performed, the time of day, or the amount of system resources available. This provides a signicant amount of exibility when trying to balance system resources with temporary query requirements.

392

DB2 UDB for AS/400 SQL Programming V4R4

Controlling the Default Reply to the Inquiry Message


The system administrator can control whether the interactive user has the option of ignoring the database query inquiry message by using the CHGJOB CL command as follows: v If a value of *DFT is specied for the INQMSGRPY parameter of the CHGJOB CL command, the interactive user does not see the inquiry messages and the query is canceled immediately. v If a value of *RQD is specied for the INQMSGRPY parameter of the CHGJOB CL command, the interactive user sees the inquiry and must reply to the inquiry. v If a value of *SYSRPYL is specied for the INQMSGRPY parameter of the CHGJOB CL command, a system reply list is used to determine whether the interactive user sees the inquiry and whether a reply is necessary. For more information on the *SYSRPYL parameter, see the CL Reference (Abridged) book. The system reply list entries can be used to customize different default replies based on user prole name, user id, or process names. The fully qualied job name is available in the message data for inquiry message CPA4259. This will allow the keyword CMPDTA to be used to select the system reply list entry that applies to the process or user prole. The user prole name is 10 characters long and starts at position 51. The process name is 10 character long and starts at position 27. The following example will add a reply list element that will cause the default reply of C to cancel any requests for jobs whose user prole is QPGMR.
ADDRPYLE SEQNBR(56) MSGID(CPA4259) CMPDTA(QPGMR 51) RPY(C)

The following example will add a reply list element that will cause the default reply of C to cancel any requests for jobs whose process name is QPADEV0011.
ADDRPYLE SEQNBR(57) MSGID(CPA4259) CMPDTA(QPADEV0011 27) RPY(C)

Using the Governor for Performance Testing


The query governor lets you optimize performance without having to run through several iterations of the query. If the query time limit is set to zero ( QRYTIMLMT(0) ) with the CHGQRYA command, the inquiry message is always sent to the user saying the estimated time exceeds the query time limit. The programmer can prompt for message help on the inquiry message and nd the same information which one can see from the PRTSQLINF (Print SQL Information) command. Additionally, if the query is canceled, the query optimizer evaluates the access plan and sends the optimizer tuning messages to the joblog. This occurs even if the job is not in debug mode. The user or a programmer can then review the optimizer tuning messages in the joblog to see if additional tuning is needed to obtain optimal query performance. Minimal system resources are used because the actual query of the data is never actually done. If the les to be queried contain a large number of records, this represents a signicant savings in system resources. | | | | | | | Be careful when you use this technique for performance testing, because all query requests will be stopped before they are run. This is especially important for a query that cannot be implemented in a single query step. For these types of queries, separate multiple query requests are issued, and then their results are accumulated before returning the nal results. Stopping the query in one of these intermediate steps gives you only the performance information that relates to that intermediate step, and not for the entire query.
Chapter 23. Using the DB2 UDB for AS/400 Predictive Query Governor

393

Examples
| | | | | | To set the query time limit for the current job or user session using query options le QAQQINI, specify QRYOPTLIB parameter on the CHGQRYA command to a user library where the QAQQINI le exists with the parameter set to QUERY_TIME_LIMIT, and the value set to a valid query time limit. For more information on setting the query options le, see Query Options File QAQQINI on page 543. To set the query time limit for 45 seconds you would use the following CHGQRYA command:
CHGQRYA JOB(*) QRYTIMLMT(45)

This sets the query time limit at 45 seconds. If the user runs a query with an estimated runtime equal to or less than 45 seconds, the query runs without interruption. The time limit remains in effect for the duration of the job or user session, or until the time limit is changed by the CHGQRYA command. Assume that the query optimizer estimated the runtime for a query as 135 seconds. A message would be sent to the user that stated that the estimated runtime of 135 seconds exceeds the query time limit of 45 seconds. | | | | | | | | | | | | | | | | | | | To set or change the query time limit for a job other than your current job, the CHGQRYA command is run using the JOB parameter. To set the query time limit to 45 seconds for job 123456/USERNAME/JOBNAME you would use the following CHGQRYA command:
CHGQRYA JOB(123456/USERNAME/JOBNAME) QRYTIMLMT(45)

This sets the query time limit at 45 seconds for job 123456/USERNAME/JOBNAME. If job 123456/USERNAME/JOBNAME tries to run a query with an estimated runtime equal to or less than 45 seconds the query runs without interruption. If the estimated runtime for the query is greater than 45 seconds, for example 50 seconds, a message would be sent to the user stating that the estimated runtime of 50 seconds exceeds the query time limit of 45 seconds. The time limit remains in effect for the duration of job 123456/USERNAME/JOBNAME, or until the time limit for job 123456/USERNAME/JOBNAME is changed by the CHGQRYA command. To set or change the query time limit to the QQRYTIMLMT system value, use the following CHGQRYA command:
CHGQRYA QRYTIMLMT(*SYSVAL)

The QQRYTIMLMT system value is used for duration of the job or user session, or until the time limit is changed by the CHGQRYA command. This is the default behavior for the CHGQRYA command.

394

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips
| | | | | | | | | | | This chapter provides guidelines for designing queries that will perform and will use system resources more efficiently. This chapter covers queries that are optimized by the query optimizer and includes interfaces such as SQL, OPNQRYF, and QUERY/400 queries. SQL and system resources more efficiently in application programs. As a general rule, most of the guidelines can be ignored, and the results will still be correct. However, if you apply the guidelines, your queries will run more efficiently. Note: The information in this chapter is complex. It may be helpful to experiment with an AS/400 system as you read this chapter to verify some of the information. If one understands how DB2 UDB for AS/400 processes queries, it is easier to understand the performance impacts of the guidelines discussed in this chapter. There are two major components of DB2 UDB for AS/400: 1. Data management methods These methods are the algorithms used to retrieve data from the disk. The methods include index usage and row selection techniques. In addition, parallel access methods are available with the DB2 UDB Symmetric Multiprocessing operating system feature. 2. Query optimizer The query optimizer identies the valid techniques which could be used to implement the query and selects the most efficient technique.

General Optimization Tips


| Here are some tips to help your queries run as fast as possible: v Create indexes whose leftmost key elds match your selection predicates to help supply the optimizer with selectivity values (key range estimates). v For join queries, create indexes that match your join elds to help the optimizer determine the average number of matching rows. v Minimize extraneous mapping by specifying only elds of interest on the query. For example, in SQL, avoid SELECT* in favor of FOR FETCH ONLY on read-only cursors. v If your queries often use arrival sequence, use the RGZPFM (Reorganize Physical File Member) command to remove deleted rows from tables or the CHGPF (Change Physical File) REUSEDLT (*YES) command to reuse deleted rows. For embedded SQL, consider using the following precompile options: v Specify ALWCPYDTA(*OPTIMIZE) to allow the query optimizer to create temporary copies of data if better performance can be obtained. v Use CLOSWLCSR(*ENDJOB) or CLOSQLCSR(*ENDACTGRP) to allow open data paths to remain open for future invocations. v Specify DLYPRP(*YES) to delay SQL statement validation until an OPEN, EXECUTE, or DESCRIBE statement is run. This option improves performance by eliminating redundant validation. v Use ALWBLK(*ALLREAD) to allow record blocking for read-only cursors.
Copyright IBM Corp. 1997, 1999

395

For OPNQRYF (Open Query File) queries, consider using the following parameters: v Use ALWCPYDTA(*OPTIMIZE) to let the query optimizer create temporary copies of data if it can obtain better performance by doing so. v Use OPTIMIZE(*FIRSTIO) to bias the optimizer to use an existing index instead of creating a temporary index.

Data Management Methods


This section introduces the fundamental techniques used by DB2 UDB for AS/400 and the AS/400 Licensed Internal Code to access data.

Access Path
An access path is the path used to locate data specied in a query. An access path can be indexed, sequential, or a combination of both.

Sequential Access Path


A sequential access path uses the order of rows as they are stored in the table to locate data specied in a query. Processing tables using the sequential access path is similar to processing sequential or direct les on traditional systems.

Keyed Sequence Access Path


A keyed sequence access path provides access to a table that is arranged according to the contents of key elds (indexes). The keyed sequence is the order in which rows are retrieved. The access path is automatically maintained whenever rows are added to or deleted from the table, or whenever the contents of the index columns are changed. The best example of a keyed sequence access path is an index created using the CREATE INDEX statement or a logical le created using the CRTLF command. Columns that are good candidates for creating keyed sequence access paths are: v Those frequently referenced in row selection predicates. v Those frequently referenced in grouping or ordering. v Those used to join tables (see Join Optimization on page 426).

| |

Encoded Vector Access Paths


An encoded vector access path provides access to a database le by assigning codes to distinct key values and then representing these values in an array. The elements of the array can be 1, 2, or 4 bytes in length, depending on the number of distinct values that must be represented. Because of their compact size and relative simplicity, encoded vector access paths provide for faster scans that can be more easily processed in parallel. You create encoded vector access paths by using the SQL CREATE INDEX statement. For more information about accelerating your queries with encoded , go to the DB2 for AS/400 web pages. vector indexes For a further description of access paths, refer to the Data Management book.

396

DB2 UDB for AS/400 SQL Programming V4R4

Access Method
The Licensed Internal Code and DB2 UDB for AS/400 share the work on access methods. The Licensed Internal Code does the low-level processing which includes selection, join functions, hashing, and access path creation. The query optimization process chooses the most efficient access method for each query and keeps this information in the access plan. The type of access is dependent on the number of rows, the expected number of page faults 17, and other criteria. The possible methods the optimizer can use to retrieve data include: v Dataspace scan method (a dataspace is an internal object that contains the data in a table) (page 399) v Parallel pre-fetch method (page 401) v Key selection method (page 404) v Key positioning method (page 406) v Parallel table or index pre-load (page 413) v Index-from-index method (page 414) v Index only access method (page 412) v Hashing method (page 415) v Bitmap processing method (page 416) The DB2 UDB Symmetric Multiprocessing feature provides the optimizer with additional methods for retrieving data that include parallel processing. Symmetrical multiprocessing (SMP) is a form of parallelism achieved on a single system where multiple processors (CPU and I/O processors) that share memory and disk resource work simultaneously towards achieving a single end result. This parallel processing means that the database manager can have more than one (or all) of the system processors working on a single query simultaneously. The performance of a CPU bound query can be signicantly improved with this feature on multiple-processor systems by distributing the processor load across more than one processor on the system.

17. An interrupt that occurs when a program refers to a 4K-byte page that is not in main storage. Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

397

QUERY CPU CPU CPU CPU SHARED MEMORY

Figure 13. Database Symmetric Multiprocessing

The following methods are available to the optimizer once the DB2 UDB Symmetric Multiprocessing feature has been installed on your system: v Parallel data space scan method (page 402) v Parallel key selection method (page 405) v Parallel key positioning method (page 410) v Parallel index only access method (parallel and non-parallel) (page 412) v Parallel hashing method (parallel and non-parallel) (page Hashing Access Method on page 415) v Parallel bitmap processing method (page 416)

Ordering
An ORDER BY clause (or OPNQRYF KEYFLD parameter) must be specied to guarantee a particular ordering of the results. Before parallel access methods were available, the database manager processed table rows (and keyed sequences) in a sequential manner. This caused the sequencing of the results to be somewhat predictable even though an ordering was not included in the original query request. Because parallel methods cause blocks of table rows and key values to be processed concurrently, the ordering of the retrieved results becomes more random and unpredictable. An ORDER BY clause is the only way to guarantee the specic sequencing of the results. However, an ordering request should only be specied when absolutely required, because the sorting of the results can increase both CPU utilization and response time.

Enabling Parallel Processing


| | | | The application or user must enable parallel processing for queries; the optimizer does not automatically use parallelism as the chosen access method. You can use the system-value QQRYDEGREE, the query options le, and the DEGREE parameter on the Change Query Attributes (CHGQRYA) command to control the

398

DB2 UDB for AS/400 SQL Programming V4R4

| |

degree of parallelism that the query optimizer uses. See Controlling Parallel Processing on page 473 for information on how to control parallel processing. A set of database system tasks are created at system startup for use by the database manager. The database manager uses the tasks to process and retrieve data from different disk devices. Since these tasks can be run on multiple processors simultaneously, the elapsed time of a query can be reduced. Even though much of the I/O and CPU processing of a parallel query is done by the tasks, the accounting of the I/O and CPU resources used are transferred to the application job. The summarized I/O and CPU resources for this type of application continue to be accurately displayed by the Work with Active Jobs (WRKACTJOB) command.

Automatic Data Spreading


DB2 UDB for AS/400 automatically spreads the data across the disk devices available in the auxiliary storage pool (ASP) where the data is allocated. This ensures that the data is spread without user intervention. The spreading allows the database manager to easily process the blocks of records on different disk devices in parallel. Even though DB2 UDB for AS/400 spreads data across disk devices within an ASP, sometimes the allocation of the data extents (contiguous sets of data) might not be spread evenly. This occurs when there is uneven allocation of space on the devices, or when a new device is added to the ASP. The allocation of the data space may be spread again by saving, deleting, and then restoring the table.

Dataspace Scan Access Method


| | | | | The rows in the table are processed in no guaranteed order. If you want the result in a particular sequence, you must specify the ORDER BY clause (or OPNQRYF KEYFLD parameter). All rows in the table are read. The selection criteria is applied to each row, and only the rows that match the criteria are returned to the calling application. Dataspace scan can be very efficient for the following reasons: v It minimizes the number of page I/O operations because all rows in a given page are processed, and once the page is in main storage, the page is not retrieved again. v The database manager can easily predict the sequence of pages from the dataspace for retrieval. For this reason, the database manager can schedule asynchronous I/O of the pages into main storage from auxiliary storage. This is commonly referred to as pre-fetching. This is done so that the page is available in main storage when the database manager needs to access the data. This selection method is very good when a large percentage of the rows are to be selected. A large percentage is generally 20% or more. | | | | | | | Dataspace scan processing can be adversely affected when rows are selected from a table that contains deleted rows. This is because the delete operation only marks rows as deleted. For dataspace scan processing, the database manager reads all of the deleted rows, even though none of the deleted rows are ever selected. You should use the Reorganize Physical File Member (RGZPFM) CL command to eliminate deleted rows. Specifying REUSEDLT(*YES) on the physical le can also reuse the deleted record space. SQL tables are created with REUSEDLT(*YES).
Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

399

Dataspace scan processing is not very efficient when a small percentage of rows in the table will be selected. Because all rows in the table are examined, this leads to unnecessary use of I/O and processing unit resources. The messages created by the PRTSQLINF CL command to describe a query in an SQL program which is using the dataspace selection method would appear as follows:
SQL4010 Arrival sequence access for file 1.

The Licensed Internal Code can use one of two algorithms for selection when a dataspace scan is processed, intermediate buffer selection and dataspace element selection. The following pseudocode illustrates the intermediate buffer selection algorithm:
DO UNTIL END OF FILE 1. Address the next (or first) record 2. Map all column values to an internal buffer, performing all derived operations. 3. Evaluate the selection criteria to a TRUE or FALSE value using the column values as they were copied to internal buffer. 4. IF the selection is TRUE THEN Copy the values from the internal buffer into the user's answer buffer. ELSE No operation END

The dataspace entry algorithm is as follows:


DO UNTIL END OF FILE 1. Calculate a search limit. This limit is usually the number of records which are already in active memory, or have already had an I/O request done to be loaded into memory. 2. DO UNTIL (search limit reached or record selection criteria is TRUE) a. Address the next (or first) record b. Evaluate any selection criteria which does not require a derived value directly for the dataspace record. END 3. IF the selection is true THEN a. Map all column values to an internal buffer, performing all derived operations. b. Copy the values from the internal buffer into the user's answer buffer. ELSE No operation END

400

DB2 UDB for AS/400 SQL Programming V4R4

The dataspace entry selection algorithm provides better performance than intermediate buffer selection for two reasons: v Data movement and computations are only done on records which are selected. v The loop in step 2 of the dataspace entry selection algorithm is generated into an executable code burst. When a small percentage of records are actually selected, DB2 UDB for AS/400 will be running this very small program until a record is found. No action is necessary for queries of this type to make use of the dataspace scan method. Any query interface can utilize this improvement. However, the following guidelines determine whether a selection predicate can be implemented as dataspace selection: v Neither operand of the predicate can be of any kind of a derived value, function, substring, concatenation, or numeric expression. v When both operands of a selection predicate are numeric columns, both columns must have the same type, scale, and precision; otherwise, one operand is mapped into a derived value. For example, a DECIMAL(3,1) must only be compared against another DECIMAL(3,1) column. v When one operand of a selection predicate is a numeric column and the other is a literal or host variable, then the types must be the same and the precision and scale of the literal/host variable must be less than or equal to that of the column. v Selection predicates involving packed decimal or numeric types of columns can only be done if the table was created by the SQL CREATE TABLE statement. v A varying length character column cannot be referenced in the selection predicate. v When one operand of a selection predicate is a character column and the other is a literal or host variable, then the length of the host variable cannot be greater than that of the column. v Comparison of character column data must not require CCSID or key board shift translation. It can be important to avoid intermediate buffer selection because the reduction in CPU and response time for dataspace entry selection can be large, in some cases as high as 70-80%. The queries that will benet the most from dataspace selection are those where less than 60% of the le is actually selected. The lower the percentage of records selected, the more noticeable the performance benet will be.

Parallel Pre-Fetch Access Method


DB2 UDB for AS/400 can also use parallel pre-fetch processing to shorten the processing time required for long-running I/O-bound dataspace scan queries. | | | | | | | | This method has the same characteristics as the dataspace scan method; except that the I/O processing is done in parallel. This is accomplished by starting multiple input streams for the table to pre-fetch the data. This method is most effective when the following are true: v The data is spread across multiple disk devices. v The query is not CPU-processing-intensive. v There is an ample amount of main storage available to hold the data collected from every input stream.

Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

401

| | | | | | |

As mentioned previously, DB2 UDB for AS/400 automatically spreads the data across the disk devices without user intervention, allowing the database manager to pre-fetch table data in parallel. The database manager uses tasks to retrieve data from different disk devices. Usually the request is for an entire extent (contiguous set of data). This improves performance because the disk device can use smooth sequential access to the data. Because of this optimization, parallel prefetch can pre-load data to active memory faster than the SETOBJACC CL command. Even though DB2 UDB for AS/400 spreads data across disk devices within an ASP, sometimes the allocation of the dataspace extents may not be spread evenly. This occurs when there is uneven allocation of space on the devices or a new device is added to the ASP. The allocation of the dataspace can be respread by saving, deleting, and restoring the table. The query optimizer selects the candidate queries which can take advantage of this type of implementation. The optimizer selects the candidates by estimating the CPU time required to process the query and comparing the estimate to the amount of time required for input processing. When the estimated input processing time exceeds the CPU time, the query optimizer indicates that the query may be implemented with parallel I/O.

| | | | | | | | | |

Parallel pre-fetch requires that I/O parallel processing must be enabled either by the system value QQRYDEGREE, the query option le, or by the DEGREE parameter on the Change Query Attributes (CHGQRYA) command. See Controlling Parallel Processing on page 473 for information on how to control parallel processing. Because queries being processed with parallel pre-fetch aggressively utilize main store and disk I/O resources, the number of queries that use parallel pre-fetch should be limited and controlled. Parallel prefetch utilizes multiple disk arms, but it does little utilization of multiple CPUs for any given query. Parallel prefetch I/O will use I/O resources intensely. Allowing a parallel prefetch query on a system with an overcommitted I/O subsystem may intensify the over-commitment problem. You should run the job in a shared storage pool with the *CALC paging option because this will cause more efficient use of active memory. DB2 UDB for AS/400 uses the automated system tuner to determine how much memory this process is allowed to use. At run-time, the Licensed Internal Code will allow parallel pre-fetch to be used only if the memory statistics indicate that it will not over-commit the memory resources. For more information on the paging option see the Automatic System Tuning section of the Work Management book. Parallel pre-fetch requires that enough main storage be available to cache the data being retrieved by the multiple input streams. For large les, the typical extent size is 1 megabyte. This means that 2 megabytes of memory must be available in order to use 2 input streams concurrently. Increasing the amount of available memory in the pool allows more input streams to be used. If there is plenty of available memory, the entire dataspace for the table may be loaded into active memory when the query is opened. The messages created by the PRTSQLINF command to describe a query in an SQL program which is using the parallel pre-fetch access method would appear as follows:
SQL4023 Parallel dataspace pre-fetch used.

402

DB2 UDB for AS/400 SQL Programming V4R4

Parallel Data Space Scan Method (available only when the DB2 UDB Symmetric Multiprocessing feature is installed)
DB2 UDB for AS/400 can use this parallel access method to shorten the processing time required for long-running data space scan queries. The parallel data space scan method reduces the I/O processing time like the parallel pre-fetch access method. In addition, if running on a system that has more than one processor, this method can reduce the elapsed time of a query by splitting the data space scan processing into tasks that can be run on the multiple processors simultaneously. All selection and column processing is performed in the task. The applications job schedules the work requests to the tasks and merges the results into the result buffer that is returned to the application. This method is most effective when the following are true: v The data is spread across multiple disk devices. v The system has multiple processors that are available. v There is an ample amount of main storage available to hold the data buffers and result buffers. | | | As mentioned previously, DB2 UDB for AS/400 automatically spreads the data across the disk devices without user intervention, allowing the database manager to pre-fetch table data in parallel. The query optimizer selects the candidate queries that can take advantage of this type of implementation. The optimizer selects the candidates by estimating the CPU time required to process the query and comparing the estimate to the amount of time required for input processing. The optimizer reduces its estimated elapsed time for data space scan based on the number of tasks it calculates should be used. It calculates the number of tasks based on the number of processors in the system, the amount of memory available in the jobs pool, and the current value of the DEGREE query attribute. If the parallel data space scan is the fastest access method, it is then chosen. Parallel data space scan requires that SMP parallel processing must be enabled either by the system value QQRYDEGREE, the query option le, or by the DEGREE parameter on the Change Query Attributes (CHGQRYA) command. See Controlling Parallel Processing on page 473 for information on how to control parallel processing. Parallel data space scan cannot be used for queries that require any of the following: v Specication of the *ALL commitment control level. v Nested loop join implementation. See Nested Loop Join Implementation on page 426. | | | | | | | | | | v Backward scrolling. For example, parallel data space scan cannot normally be used for queries dened by the Open Query File (OPNQRYF) command, which specify ALWCPYDTA(*YES) or ALWCPYDTA(*NO), because the application might attempt to position to the last record and retrieve previous records. SQL-dened queries that are not dened as scrollable can use this method. Parallel data space scan can be used during the creation of a temporary result, such as a sort or hash operation, no matter what interface was used to dene the query. OPNQRYF can be dened as not scrollable by specifying the *OPTIMIZE parameter value for the ALWCPYDTA parameter, which enbles the usage of most of the parallel access methods.
Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

403

v Restoration of the cursor position. For instance, a query requiring that the cursor position be restored as the result of the SQL ROLLBACK HOLD statement or the ROLLBACK CL command. SQL applications using a commitment control level other than *NONE should specify *ALLREAD as the value for precompiler parameter ALWBLK to allow this method to be used. v Update or delete capability. You should run the job in a shared storage pool with the *CALC paging option, as this will cause more efficient use of active memory. For more information on the paging option see the Automatic System Tuning section of the Work Management book. Parallel data space scan requires active memory to buffer the data being retrieved and to separate result buffers for each task. A typical total amount of memory needed for each task is about 2 megabytes. For example, about 8 megabytes of memory must be available in order to use 4 parallel data space scan tasks concurrently. Increasing the amount of available memory in the pool allows more input streams to be used. Queries that access tables with large varying length character columns, or queries that generate result values that are larger than the actual record length of the table might require more memory for each task. The performance of parallel data space scan can be severely limited if numerous record locking conicts or data mapping errors occur.

Key Selection Access Method


This access method requires keyed sequence access paths. The entire index is read and any selection criteria that references the key columns of the index is applied against the index. The advantage of this method is that the dataspace is only accessed to retrieve rows that satisfy the selection criteria applied against the index. Any additional selection not performed through the key selection method is performed at the dataspace level. The key selection access method can be very expensive if the search condition applies to a large number of rows because: v The whole index is processed. v For every key selected from the index, a random I/O to the dataspace occurs. Normally, the optimizer would choose to use dataspace scan processing when the search condition applies to a large number of rows. The optimizer only chooses the key selection method if less than 20% of the keys are selected or if an operation forces the use of an index. Options that might force the use of an index include: v Ordering v Grouping v Joining | | | | | | | | In these cases, the optimizer may choose to create a temporary index rather than use an existing index. When the optimizer creates a temporary index, it uses a 32K page size. An index created using a CREATE INDEX statement or the CRTLF command normally uses only a 4K page size. The optimizer also processes as much of the selection as possible while building the temporary index. Nearly all temporary indexes built by the optimizer are select/omit or sparse indexes. Finally, the optimizer can use multiple parallel tasks when creating the index. The page size difference, corresponding performance improvement from swapping in fewer pages,

404

DB2 UDB for AS/400 SQL Programming V4R4

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

and the ability to use parallel tasks to create the index may be enough to overcome the overhead of creating an index. Dataspace selection is used for building of temporary keyed access paths. If key selection access method is used because the query specied ordering (an index was required) the query performance might be improved by using the following parameters to allow the ordering to be done with the query sort. v For SQL, the following combinations of precompiler parameters: ALWCPYDTA(*OPTIMIZE), ALWBLK(*ALLREAD), and COMMIT(*CHG or *CS) ALWCPYDTA(*OPTIMIZE) and COMMIT(*NONE) v For OPNQRYF, the following parameters: *ALWCPYDTA(*OPTIMIZE) and COMMIT(*NO) ALWCPYDTA(*OPTIMIZE) and COMMIT(*YES) and the commitment control level is started with a commit level of *NONE, *CHG, or *CS When a query species a select/omit index and the optimizer decides to build a temporary index, all of the selection from the select/omit index is put into the temporary index after any applicable selection from the query.

Parallel Key Selection Access Method (available only when the DB2 UDB Symmetric Multiprocessing feature is installed)
For the parallel key selection access method, the possible key values are logically partitioned. Each partition is processed by a separate task just as in the key selection access method. The number of partitions processed concurrently is determined by the query optimizer. Because the keys are not processed in order, this method cannot be used by the optimizer if the index is being used for ordering. Key partitions that contain a larger portion of the existing keys from the index are further split as processing of other partitions complete. The following example illustrates a query where the optimizer could choose the key selection method:
CREATE INDEX X1 ON EMPLOYEE(LASTNAME,WORKDEPT) DECLARE BROWSE2 CURSOR FOR SELECT * FROM EMPLOYEE WHERE WORKDEPT = 'E01' OPTIMIZE FOR 99999 ROWS

OPNQRYF example:
OPNQRYF FILE((EMPLOYEE)) QRYSLT('WORKDEPT *EQ ''E01''')

If the optimizer chooses to run this query in parallel with a degree of four, the following might be the logical key partitions that get processed concurrently:
LASTNAME values leading character partition start 'A' 'G' 'M' 'T' LASTNAME values leading character partition end 'F' 'L' 'S' 'Z'

Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

405

If there were fewer keys in the rst and second partition, processing of those key values would complete sooner than the third and fourth partitions. After the rst two partitions are nished, the remaining key values in the last two might be further split. The following shows the four partitions that might be processed after the rst and second partition are nished and the splits have occurred:
LASTNAME values leading character partition start 'O' 'Q' 'V' 'X' LASTNAME values leading character partition end 'P' 'S' 'W' 'Z'

Parallel key selection cannot be used for queries that require any of the following: v Specication of the *ALL commitment control level. v Nested loop join implementation. See Nested Loop Join Implementation on page 426. | | | | | | | | | | | | | | | v Backward scrolling. For example, parallel key selection cannot be used for queries dened by the Open Query File (OPNQRYF) command which specify ALWCPYDTA(*YES) or ALWCPYDTA(*NO), because the application might attempt to position to the last record and retrieve previous records. SQL dened queries that are not dened as scrollable can use this method. Parallel key selection can be used during the creation of a temporary result, such as a sort or hash operation, no matter what interface was used to dene the query. v Restoration of the cursor position (for instance, a query requiring that the cursor position be restored as the result of the SQL ROLLBACK HOLD statement or the ROLLBACK CL command). OPNQRYF can be dened as not scrollable by specifying the *OPTIMIZE parameter value for the ALWCPYDTA parameter, which enables the usage of most of the parallel access methods. SQL applications using a commitment control level other than *NONE should specify *ALLREAD as the value for precompiler parameter ALWBLK to allow this method to be used. v Update or delete capabilitiy. You should run the job in a shared pool with *CALC paging option as this will cause more efficient use of active memory. For more information on the paging option see the Automatic System Tuning section of the Work Management book. | | | | | Parallel key selection requires that SMP parallel processing be enabled either by the system value QQRYDEGREE, the query options le, or by the DEGREE parameter on the Change Query Attributes (CHGQRYA) command. See Controlling Parallel Processing on page 473 for information on how to control parallel processing.

Key Positioning Access Method


This access method is very similar to the key selection access method. They both require a keyed sequence access path. In the key selection access method, processing starts at the beginning of the index and continues to the end. In the key positioning access method, selection is against the index directly on a range of keys that match some or all of the selection criteria. All the keys from this range are read and any remaining key selection is performed. This is similar to the selection performed by the key selection method. Any selection not performed through key positioning or key selection is performed at the dataspace level. Because key

406

DB2 UDB for AS/400 SQL Programming V4R4

positioning only processes a subset of the keys in the index, the performance of the key positioning method is better than the performance of the key selection method. The key positioning method is most efficient when a small percentage of rows are to be selected (less than approximately 20%). If more than approximately 20% of the rows are to be selected, the optimizer generally chooses to: v Use dataspace scan processing (if index is not required) v Use key selection (if an index is required) v Use query sort routine (if conditions apply) For queries that do not require an index (no ordering, grouping, or join operations), the optimizer tries to nd an existing index to use for key positioning. If no existing index can be found, the optimizer stops trying to use keyed access to the data because it is faster to use dataspace scan processing than it is to build an index and then perform key positioning. The following example illustrates a query where the optimizer could choose the key positioning method:
CREATE INDEX X1 ON EMPLOYEE(WORKDEPT) DECLARE BROWSE2 CURSOR FOR SELECT * FROM EMPLOYEE WHERE WORKDEPT = 'E01' OPTIMIZE FOR 99999 ROWS

| | | |

OPNQRYF example:
OPNQRYF FILE((EMPLOYEE)) QRYSLT('WORKDEPT *EQ ''E01''')

In this example, the database support uses X1 to position to the rst index entry with the WORKDEPT value equal to E01. For each key equal to E01, it randomly accesses the dataspace 18 and selects the row. The query ends when the key selection moves beyond the key value of E01. Note that for this example all index entries processed and rows retrieved meet the selection criteria. If additional selection is added that cannot be performed through key positioning (such as selection columns which do not match the rst key columns of an index over multiple columns) the optimizer uses key selection to perform as much additional selection as possible. Any remaining selection is performed at the dataspace level. The messages created by the PRTSQLINF CL command to describe this query in an SQL program would appear as follows:
SQL4008 SQL4011 Access path X1 used for file 1. Key row positioning used on file 1.

The key positioning access method has additional processing capabilities. One such capability is to perform range selection across several values. For example:
CREATE INDEX X1 EMPLOYEE(WORKDEPT) DECLARE BROWSE2 CURSOR FOR SELECT * FROM EMPLOYEE WHERE WORKDEPT BETWEEN 'E01' AND 'E11' OPTIMIZE FOR 99999 ROWS

18. random accessing occurs because the keys may not be in the same sequence as the rows in the dataspace Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

407

| | | |

OPNQRYF example:
OPNQRYF FILE((EMPLOYEE)) QRYSLT('WORKDEPT *EQ %RANGE(''E01'' ''E11'')')

In the previous example, the database support positions to the rst index entry equal to value E01 and rows are processed until the last index entry for E11 is processed. The messages created by PRTSQLINF CL command to describe this query in an SQL program would appear as follows:
SQL4008 SQL4011 Access path X1 used for file 1. Key row positioning used on file 1.

A further extension of this access method, called multi-range key positioning, is available. It allows for the selection of rows for multiple ranges of values for the rst key columns of an index over multiple columns.
CREATE INDEX X1 ON EMPLOYEE(WORKDEPT) DECLARE BROWSE2 CURSOR FOR SELECT * FROM EMPLOYEE WHERE WORKDEPT BETWEEN 'E01' AND 'E11' OR WORKDEPT BETWEEN 'A00' AND 'B01' OPTIMIZE FOR 99999 ROWS

| | | | |

OPNQRYF example:
OPNQRYF FILE((EMPLOYEE)) QRYSLT('WORKDEPT *EQ %RANGE(''E01'' ''E11'') *OR WORKDEPT *EQ %RANGE(''A00'' ''B01'')')

In the previous example, the positioning and processing technique is used twice, once for each range of values. The messages created by PRTSQLINF CL command to describe this query in an SQL program would appear as follows:
SQL4008 SQL4011 Access path X1 used for file 1. Key row positioning used on file 1.

All of the key positioning examples have so far only used one key, the left-most key, of the index. Key positioning also handles more than one key (although the keys must be contiguous to the left-most key).
CREATE INDEX X2 ON EMPLOYEE(WORKDEPT,LASTNAME,FIRSTNME) DECLARE BROWSE2 CURSOR FOR SELECT * FROM EMPLOYEE WHERE WORKDEPT = 'D11' AND FIRSTNME = 'DAVID' OPTIMIZE FOR 99999 ROWS

| | | | |

OPNQRYF example:
OPNQRYF FILE((EMPLOYEE)) QRYSLT('WORKDEPT *EQ ''D11'' *AND FIRSTNME *EQ ''DAVID''')

Because the two selection keys (WORKDEPT and FIRSTNME) are not contiguous, there is no multiple key position support for this example. Therefore, only the WORKDEPT = D11 part of the selection can be applied against the index (single key positioning). While this may be acceptable, it means that the processing of rows

408

DB2 UDB for AS/400 SQL Programming V4R4

starts with the rst key of D11 and then uses key selection to process the FIRSTNME = DAVID against all 9 keys with WORKDEPT key value = D11. By creating the following index, X3, the above example query would run using multiple key positioning.
CREATE INDEX X3 ON EMPLOYEE(WORKDEPT, FIRSTNME, LASTNAME)

Multiple key positioning support can apply both pieces of selection as key positioning. This improves performance considerably. A starting value is built by concatenating the two selection values into D11DAVID and selection is positioned to the index entry whose left-most two keys have that value. The messages created by the PRTSQLINF CL command when used to describe this query in an SQL program would look like this:
SQL4008 SQL4011 Access path X3 used for file 1. Key row positioning used on file 1.

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

This next example shows a more interesting use of multiple key positioning.
CREATE INDEX X3 ON EMPLOYEE(WORKDEPT,FIRSTNME) DECLARE BROWSE2 CURSOR FOR SELECT * FROM EMPLOYEE WHERE WORKDEPT = 'D11' AND FIRSTNME IN ('DAVID','BRUCE','WILLIAM') OPTIMIZE FOR 99999 ROWS

OPNQRYF example:
OPNQRYF FILE((EMPLOYEE)) QRYSLT('WORKDEPT *EQ ''D11'' *AND FIRSTNME *EQ %VALUES(''DAVID'' ''BRUCE'' ''WILLIAM'')')

The query optimizer analyzes the WHERE clause and rewrites the clause into an equivalent form:
DECLARE BROWSE2 CURSOR FOR SELECT * FROM EMPLOYEE WHERE (WORKDEPT = 'D11' AND FIRSTNME = 'DAVID') OR (WORKDEPT = 'D11' AND FIRSTNME = 'BRUCE') OR (WORKDEPT = 'D11' AND FIRSTNME = 'WILLIAM') OPTIMIZE FOR 99999 ROWS

| | | | | | |

OPNQRYF example:
OPNQRYF FILE((EMPLOYEE)) QRYSLT('(WORKDEPT *EQ ''D11'' *AND FIRSTNME *EQ ''DAVID'') *OR (WORKDEPT *EQ ''D11'' *AND FIRSTNME *EQ ''BRUCE'') *OR (WORKDEPT *EQ ''D11'' *AND FIRSTNME *EQ ''WILLIAM'')')

In the rewritten form of the query there are actually 3 separate ranges of key values for the concatenated values of WORKDEPT and FIRSTNME:
Index X3 Start value 'D11DAVID' 'D11BRUCE' 'D11WILLIAM' Index X3 Stop value 'D11DAVID' 'D11BRUCE' 'D11WILLIAM'

Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

409

Key positioning is performed over each range, signicantly reducing the number of keys selected to just 3. All of the selection can be accomplished through key positioning. The complexity of this range analysis can be taken to a further degree in the following example:
DECLARE BROWSE2 CURSOR FOR SELECT * FROM EMPLOYEE WHERE (WORKDEPT = 'D11' AND FIRSTNME IN ('DAVID','BRUCE','WILLIAM')) OR (WORKDEPT = 'E11' AND FIRSTNME IN ('PHILIP','MAUDE')) OR (FIRSTNME BETWEEN 'CHRISTINE' AND 'DELORES' AND WORKDEPT IN ('A00','C01'))

| | | | | | | | |

OPNQRYF example:
OPNQRYF FILE((EMPLOYEE)) QRYSLT('(WORKDEPT *EQ ''D11'' *AND FIRSTNME *EQ %VALUES(''DAVID'' ''BRUCE'' ''WILLIAM'')) *OR (WORKDEPT *EQ ''E11'' *AND FIRSTNME *EQ %VALUES(''PHILIP'' ''MAUDE'')) *OR (FIRSTNME *EQ %RANGE(''CHRISTINE'' ''DELORES'') *AND WORKDEPT *EQ %VALUES(''A00'' ''C01''))')

The query optimizer analyzes the WHERE clause and rewrites the clause into an equivalent form:
DECLARE BROWSE2 CURSOR FOR SELECT * FROM EMPLOYEE WHERE (WORKDEPT = 'D11' OR (WORKDEPT = 'D11' OR (WORKDEPT = 'D11' OR (WORKDEPT = 'E11' OR (WORKDEPT = 'E11' OR (WORKDEPT = 'A00' = 'DAVID') = 'BRUCE') = 'WILLIAM') = 'PHILIP') = 'MAUDE') BETWEEN 'CHRISTINE' AND 'DELORES') OR (WORKDEPT = 'C01' AND FIRSTNME BETWEEN 'CHRISTINE' AND 'DELORES') OPTIMIZE FOR 99999 ROWS AND AND AND AND AND AND FIRSTNME FIRSTNME FIRSTNME FIRSTNME FIRSTNME FIRSTNME

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

OPNQRYF example:
OPNQRYF FILE((EMPLOYEE)) QRYSLT('(WORKDEPT *EQ ''D11'' *AND FIRSTNME *EQ ''DAVID'') *OR (WORKDEPT *EQ ''D11'' *AND FIRSTNME *EQ ''BRUCE'') *OR (WORKDEPT *EQ ''D11'' *AND FIRSTNME *EQ ''WILLIAM'') *OR (WORKDEPT *EQ ''E11'' *AND FIRSTNME *EQ ''PHILIP'') *OR (WORKDEPT *EQ ''E11'' *AND FIRSTNME *EQ ''MAUDE'') *OR (WORKDEPT *EQ ''A00'' *AND FIRSTNME *EQ %RANGE(''CHRISTINE'' ''DELORES'')) *OR (WORKDEPT *EQ ''C01'' *AND FIRSTNME *EQ %RANGE(''CHRISTINE'' ''DELORES''))')

In the query there are actually 7 separate ranges of key values for the concatenated values of WORKDEPT and FIRSTNME:
Index X3 Start value 'D11DAVID' 'D11BRUCE' 'D11WILLIAM' 'E11MAUDE' Index X3 Stop value 'D11DAVID' 'D11BRUCE' 'D11WILLIAM' 'E11MAUDE'

410

DB2 UDB for AS/400 SQL Programming V4R4

'E11PHILIP' 'A00CHRISTINE' 'C01CHRISTINE'

'E11PHILIP' 'A00DELORES' 'C01DELORES'

Key positioning is performed over each range. Only those rows whose key values fall within one of the ranges are returned. All of the selection can be accomplished through key positioning. This signicantly improves the performance of this query.

Parallel Key Positioning Access Method (available only when the DB2 UDB Symmetric Multiprocessing feature is installed)
Using the parallel key positioning access method, the existing key ranges are processed by separate tasks concurrently in separate database tasks. The number of concurrent tasks is controlled by the optimizer. The query will start processing the key ranges of the query up to the degree of parallelism being used. As processing of those ranges completes, the next ones on the list are started. As processing for a range completes and there are no more ranges in the list to process, ranges that still have keys left to process are split, just as in the parallel key selection method. The database manager attempts to keep all of the tasks that are being used busy, each processing a separate key range. Whether using the single value, range of values, or multi-range key positioning, the ranges can be further partitioned and processed simultaneously. Because the keys are not processed in order, this method can not be used by the optimizer if the index is being used for ordering. Consider the following example if the SQL statement is run using parallel degree of four.
DECLARE BROWSE2 CURSOR FOR SELECT * FROM EMPLOYEE WHERE (WORKDEPT = 'D11' OR (WORKDEPT = 'D11' OR (WORKDEPT = 'D11' OR (WORKDEPT = 'E11' OR (WORKDEPT = 'E11' OR (WORKDEPT = 'A00' = 'DAVID') = 'BRUCE') = 'WILLIAM') = 'PHILIP') = 'MAUDE') BETWEEN 'CHRISTINE' AND 'DELORES') OR (WORKDEPT = 'C01' AND FIRSTNME BETWEEN 'CHRISTINE' AND 'DELORES') OPTIMIZE FOR 99999 ROWS AND AND AND AND AND AND FIRSTNME FIRSTNME FIRSTNME FIRSTNME FIRSTNME FIRSTNME

OPNQRYF example:
OPNQRYF FILE((EMPLOYEE)) QRYSLT('(WORKDEPT *EQ ''D11'' *AND FIRSTNME *EQ ''DAVID'') *OR (WORKDEPT *EQ ''D11'' *AND FIRSTNME *EQ ''BRUCE'') *OR (WORKDEPT *EQ ''D11'' *AND FIRSTNME *EQ ''WILLIAM'') *OR (WORKDEPT *EQ ''E11'' *AND FIRSTNME *EQ ''PHILIP'') *OR (WORKDEPT *EQ ''E11'' *AND FIRSTNME *EQ ''MAUDE'') *OR (WORKDEPT *EQ ''A00'' *AND FIRSTNME*EQ %RANGE(''CHRISTINE'' ''DELORES'')) *OR (WORKDEPT *EQ ''C01'' *AND FIRSTNME *EQ %RANGE(''CHRISTINE'' ''DELORES''))')

The key ranges the database manager starts with are as follows:
Range Range Range Range Range Range Range Index X3 Start value 1 'D11DAVID' 2 'D11BRUCE' 3 'D11WILLIAM' 4 'E11MAUDE' 5 'E11PHILIP' 6 'A00CHRISTINE' 7 'C01CHRISTINE' Index X3 Stop value 'D11DAVID' 'D11BRUCE' 'D11WILLIAM' 'E11MAUDE' 'E11PHILIP' 'A00DELORES' 'C01DELORES'

Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

411

Ranges 1 to 4 are processed concurrently in separate tasks. As soon as one of those four completes, range 5 is started. When another range completes, range 6 is started, and so on. When one of the four ranges in progress completes and there are no more new ones in the list to start, the remaining work left in one of the other key ranges is split and each half is processed separately. Parallel key positioning cannot be used for queries that require any of the following: v Specication of the *ALL commitment control level. v Nested loop join implementation. See Nested Loop Join Implementation on page 426. | | | | | | | | | | v Backward scrolling. For example, parallel key positioning cannot be used for queries dened by the Open Query File (OPNQRYF) command, which specify ALWCPYDTA(*YES) or ALWCPYDTA(*NO), because the application might attempt to position to the last record and retrieve previous records. SQL-dened queries that are not dened as scrollable can use this method. Parallel key positioning can be used during the creation of a temporary result, such as a sort or hash operation, no matter what interface was used to dene the query. OPNQRYF can be dened as not scrollable by specifying the *OPTIMIZE parameter value for the ALWCPYDTA parameter, which enbles the usage of most of the parallel access methods. v Restoration of the cursor position. For instance, a query requiring that the cursor position be restored as the result of the SQL ROLLBACK HOLD statement or the ROLLBACK CL command. SQL applications using a commitment control level other than *NONE should specify *ALLREAD as the value for precompiler parameter ALWBLK to allow this method to be used. v Update or delete capability. You should run the job in a shared pool with the *CALC paging option as this will cause more efficient use of active memory. For more information on the paging option see the Automatic System Tuning section of Work Management book. Parallel key selection requires that SMP parallel processing be enabled either by the system value QQRYDEGREE, by the query options le PARALLEL_DEGREE option, or by the DEGREE parameter on the Change Query Attributes (CHGQRYA) command. See Controlling Parallel Processing on page 473 for information on how to control parallel processing.

Index Only Access Method


The index only access method can be used in conjunction with any of the key selection or key positioning access methods, including the parallel options for these methods. (The parallel options are available only when the DB2 Symmetric Multiprocessing feature is installed.) The processing for the selection does not change from what has already been described for these methods. However, all of the data is extracted from the index rather than performing a random I/O to the data space. The index entry is then used as the input for any derivation or result mapping that might have been specied on the query. The optimizer chooses this method when: v All of the columns that are referenced within the query can be found within a permanent index or within the key elds of a temporary index that the optimizer has decided to create.

412

DB2 UDB for AS/400 SQL Programming V4R4

v The data values must be able to be extracted from the index and returned to the user in a readable format; in other words, none of the key elds that match the query columns have: Absolute value specied Alternative collating sequence or sort sequence specied Zoned or digit force specied v The query does not use a left outer join or an exception join. v For non-SQL users, no variable length or null capable elds can require key feedback. The following example illustrates a query where the optimizer could choose to perform index only access.
CREATE INDEX X2 ON EMPLOYEE(WORKDEPT,LASTNAME,FIRSTNME) DECLARE BROWSE2 CURSOR FOR SELECT FIRSTNME FROM EMPLOYEE WHERE WORKDEPT = 'D11' OPTIMIZE FOR 99999 ROWS

OPNQRYF example:
OPNQRYF FILE((EMPLOYEE)) QRYSLT('WORKDEPT *EQ ''D11''')

In this example, the database manager uses X2 to position to the index entries for WORKDEPT=D11 and then extracts the value for the column FIRSTNME from those entries. Note that the index key elds do not have to be contiguous to the leftmost key of the index for index only access to be performed. Any key eld in the index can be used to provide data for the index only query. The index is used simply as the source for the data so the database manager can nish processing the query after the selection has been completed. The messages created by the PRTSQLINF command to describe this query in an SQL program are as follows:
SQL4008 SQL4011 SQL4022 Access path X2 used for file 1. Key row positioning used on file 1. Index only access used on file 1.

Note: Index only access is implemented on a particular le, so it is possible to perform index only access on some or all of the les of a join query.

Parallel Table or Index Based Pre-load Access Method


Some queries implemented with key selection can require a lot of random I/O in order to access an index or a table. Because of this, a high percentage of the data in the index or table is referenced. DB2 UDB for AS/400 attempts to avoid this random I/O by initiating index- or table-based pre-load when query processing begins. The data is loaded into active memory in parallel as is done for parallel pre-fetch. After the table or index is loaded into memory, random access to the data is achieved without further I/O. The DB2 UDB for AS/400 cost-based query optimizer recognizes the queries and objects that benet from table or index pre-loads if I/O parallel processing has been enabled. See Controlling Parallel Processing on page 473 for information on how to control parallel processing.

Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

413

The parallel pre-load method can be used with any of the other data access methods. The pre-load is started when the query is opened and control is returned to the application before the pre-load is nished. The application continues fetching rows using the other database access methods without any knowledge of pre-load.

Index-From-Index Access Method


The database manager can build a temporary index from an existing index without having to read all of the rows in the dataspace. Generally speaking, this selection method is one of the most efficient. The temporary index that is created only contains entries for rows that meet the selection predicates. This is similar to the key access path created by a select/omit logical le or sparse index. The optimizer chooses this method when: v The query requires an index because it uses grouping, ordering, or join processing. v A permanent index exists that has selection columns as the left-most keys and the left-most keys are very selective. v The selection columns are not the same as the ordering, grouping, or join-to columns. To use the index-from-index access method, the database manager: 1. Uses key positioning on the permanent index with the query selection criteria 2. Builds index entries in the new temporary index using selected row entries. The result is an index containing entries in the required key sequence for rows that match the selection criteria. A common index-from-index access method example follows:
CREATE INDEX X1 ON EMPLOYEE(WORKDEPT) DECLARE BROWSE2 CURSOR FOR SELECT * FROM EMPLOYEE WHERE WORKDEPT = 'D11' ORDER BY LASTNAME OPTIMIZE FOR 99999 ROWS

| |

| | | | |

OPNQRYF example:
OPNQRYF FILE((EMPLOYEE)) QRYSLT('WORKDEPT *EQ ''D11''') KEYFLD((LASTNAME))

For this example, a temporary select/omit index is created with the primary key eld LASTNAME. It contains index entries for only those rows where WORKDEPT = D11. If WORKDEPT = D11, less than approximately 20% of the rows are selected. The messages created by the PRTSQLINF CL command to describe this query in an SQL program are as follows:
SQL4012 SQL4011 Access path created from keyed file X1 for file 1. Key row positioning used on file 1.

| | | | | |

Rather than using the index-from-index access method, you can use the query sort routine: v For SQL (see Improving Performance by Using the ALWCPYDTA Parameter on page 465) specify either of the following precompile options: ALWCPYDTA(*OPTIMIZE), ALWBLK(*ALLREAD), and COMMIT(*CHG or *CS)

414

DB2 UDB for AS/400 SQL Programming V4R4

| | | | | |

ALWCPYDTA(*OPTIMIZE) and COMMIT(*NONE) v For OPNQRYF, specify either: ALWCPYDTA(*OPTIMIZE) and COMMIT(*NO) ALWCPYDTA(*OPTIMIZE) and COMMIT(*YES) and commitment control is started with a commit level of *NONE, or *CHG, or *CS This decision is based on the number of rows to be retrieved.

Hashing Access Method


The hashing access method provides an alternative method for those queries (groupings and joins) that must process data in a grouped or correlated manner. Keyed sequence access paths (indexes) are used to sort and group the data and are effective in some cases for implementing grouping and join query operations. However, if the optimizer had to create a temporary index for that query, extra processor time and resources are used when creating this index before the requested query can be run. The hashing access method can complement keyed sequence access paths or serve as an alternative. For each selected row, the specied grouping or join value in the row is run through a hashing function. The computed hash value is then used to search a specic partition of the hash table. A hash table is similar to a temporary work table, but has a different structure that is logically partitioned based on the specied query. If the rows source value is not found in the table, then this marks the rst time that this source value has been encountered in the database table. A new hash table entry is initialized with this rst-time value and additional processing is performed based on the query operation. If the rows source value is found in the table, the hash table entry for this value is retrieved and additional query processing is performed based on the requested operation (such as grouping or joining). The hash method can only correlate (or group) identical values; the hash table rows are not guaranteed to be sorted in ascending or descending order. The hashing method can be used only when the ALWCPYDTA(*OPTIMIZE) option has been specied unless a temporary result is required, since the hash table built by the database manager is a temporary copy of the selected rows. The hashing algorithm allows the database manager to build a hash table that is well-balanced, given that the source data is random and distributed. The hash table itself is partitioned based on the requested query operation and the number of source values being processed. The hashing algorithm then ensures that the new hash table entries are distributed evenly across the hash table partitions. This balanced distribution is necessary to guarantee that scans in different partitions of the hash tables are processing the same number of entries. If one hash table partition contains a majority of the hash table entries, then scans of that partition are going to have to examine the majority of the entries in the hash table. This is not very efficient. Since the hash method typically processes the rows in a table sequentially, the database manager can easily predict the sequence of memory pages from the database table needed for query processing. This is similar to the advantages of the dataspace scan access method. The predictability allows the database manager to schedule asynchronous I/O of the table pages into main storage (also known as pre-fetching). Pre-fetching enables very efficient I/O operations for the hash method leading to improved query performance.

Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

415

In contrast, query processing with a keyed sequence access method causes a random I/O to the database table for every key value examined. The I/O operations are random since the keyed-order of the data in the index does not match the physical order of the rows in the database table. Random I/O can reduce query performance because it leads to unnecessary use of I/O and processor unit resources. A keyed sequence access path can also be used by the hash method to process the table rows in keyed order. The keyed access path can signicantly reduce the number of table rows that the hash method has to process. This can offset the random I/O costs associated with keyed sequence access paths. The hash table creation and population takes place before the query is opened. Once the hash table has been completely populated with the specied database records, the hash table is used by the database manager to start returning the results of the queries. Additional processing might be required on the resulting hash table rows, depending on the requested query operations. Since blocks of table rows are automatically spread, the hashing access method can also be performed in parallel so that several groups of records are being hashed at the same time. This shortens the amount of time it takes to hash all the rows in the database table. If the DB2 SMP feature is installed, the hashing methods can be performed in parallel.

Bitmap Processing Method


As the name implies, this method generates bitmaps that are used during access to the data space. The bitmap processing method is used to: v Eliminate the random I/O that occurs on a data space when using a keyed sequence access path in conjunction with the key position and/or key selection method. v Allow multiple keyed sequence access paths to be used to access a particular table. In this method, the optimizer chooses one or more keyed sequence access paths to be used to aid in selecting records from the data space. Temporary bitmaps are allocated (and initialized), one for each index. Each bitmap contains one bit for each record in the underlying data space. For each index, key positioning and key selection methods are used to apply selection criteria. For each index entry selected, the bit associated with that record is set to 1 (i.e. turned on). The data space is not accessed. When the processing of the index is complete, the bitmap contains the information on which records are to be selected from the underlying data space. This process is repeated for each index. If two or more indexes are used, the temporary bitmaps are logically ANDed and ORed together to obtain one resulting bitmap. Once the resulting bitmap is built, it is used to avoid mapping in records from the data space unless they are selected by the query. It is important to note that the indexes used to generate the bitmaps are not actually used to access the selected records. For this reason, they are called tertiary indexes. Conversely, indexes used to access the nal records are called primary indexes. Primary indexes are used for ordering, grouping, joins, and for selection when no bitmap is used.

416

DB2 UDB for AS/400 SQL Programming V4R4

The bitmap processing method is used in conjunction with primary access methods data space scan, key selection, or key positioning. Bitmap processing, like parallel pre-fetch and parallel table/index pre-load, does not actually select the records from the data space; it assists the primary methods. If the bitmap is used in conjunction with the data space scan method, the bitmap initiates a skip-sequential processing. The data space scan (and parallel data space scan) uses the bitmap to skip over non-selected records. This has several advantages: v No CPU processing is used processing non-selected records. v I/O is minimized and the memory is not lled with the contents of the entire data space. The following example illustrates a query where the query optimizer chooses the bitmap processing method in conjunction with the dataspace scan:
CREATE INDEX IX1 ON EMPLOYEE (WORKDEPT) CREATE INDEX IX2 ON EMPLOYEE (SALARY) DECLARE C1 CURSOR FOR SELECT * FROM EMPLOYEE WHERE WORKDEPT = 'E01' OR SALARY>50000 OPTIMIZE FOR 99999 ROWS

OPNQRYF example:
OPNQRYF FILE((EMPLOYEE)) QRYSLT('WORKDEPT *EQ ''E01'' *OR SALARY > 50000')

In this example, both indexes IX1 and IX2 are used. The database manager rst generates a bitmap from the results of applying selection WORKDEPT = E01 against index IX1 (using key positioning). The database manager then generates a bitmap from the results of applying selection SALARY>50000 against index IX2 (again using key positioning). Next, the database manager combines these two bitmaps into one using OR logic. Finally, a data space scan is initiated. The data space scan uses the bitmap to skip through the data space records, retrieving only those selected by the bitmap. This example also shows an additional capability provided with bitmap processing (use of an index for ANDed selection was already possible but bitmap processing now allows more than one index). When using bitmap processing, multiple index usage is possible with selections where OR is the major boolean operator. | | | | | | | | The messages created by the PRTSQLINF command when used to describe this query would look like:
SQL4010 SQL4032 SQL4032 CPI4329 CPI4388 Arrival sequence access for file 1. Access path IX1 used for bitmap processing of file 1. Access path IX2 used for bitmap processing of file 1. Arrival sequence access was used for file EMPLOYEE. 2 Access path(s) used for bitmap processing of file EMPLOYEE.

If the bitmap is used in conjunction with either the key selection or key positioning method, it implies that the bitmap (generated from tertiary indexes) is being used to aid a primary index access. The following example illustrates a query where bitmap processing is used in conjunction with the key positioning for a primary index:

Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

417

CREATE INDEX PIX ON EMPLOYEE (LASTNAME) CREATE INDEX TIX1 ON EMPLOYEE (WORKDEPT) CREATE INDEX TIX2 ON EMPLOYEE (SALARY) DECLARE C1 CURSOR FOR SELECT * FROM EMPLOYEE WHERE WORKDEPT = 'E01' OR SALARY>50000 ORDER BY LASTNAME

OPNQRYF example:
OPNQRYF FILE((EMPLOYEE)) QRYSLT('WORKDEPT *EQ ''E01'' *OR SALARY > 50000') KEYFLD(LASTNAME)

In this example, indexes TIX1 and TIX2 are used in bitmap processing. The database manager rst generates a bitmap from the results of applying selection WORKDEPT = E01 against index TIX1 (using key positioning). It then generates a bitmap from the results of applying selection SALARY>50000 against index TIX2 (again using key positioning). | | | | The database manager then combines these two bitmaps into one using OR logic. A key selection method is initiated using (primary) index PIX. For each entry in index PIX, the bitmap is checked. If the entry is selected by the bitmap, then the data space record is retrieved and processed. The messages created by the PRTSQLINF CL command, when used to describe this query, would look like: | | | | | | | | | | | | | | | | | | | | | | | | | | |
SQL4008 SQL4032 CPI4328 CPI4338 Access path PIX used for file 1. Access path TIX1 used for bitmap processing of file 1. Access path of file PIX was used by query. 2 Access path(s) used for bitmap processing of file EMPLOYEE.

Bitmap processing can be used for join queries, as well. Since bitmap processing is on a per le basis, each le of a join can independently use or not use bitmap processing The following example illustrates a query where bitmap processing is used against the second le of a join query but not on the rst le:
CREATE INDEX EPIX ON EMPLOYEE(EMPNO) CREATE INDEX TIX1 ON EMPLOYEE(WORKDEPT) CREATE INDEX TIX2 ON EMPLOYEE(SALARY) DECLARE C1 CURSOR FOR SELECT * FROM PROJECT, EMPLOYEE WHERE RESEMP=EMPNO AND (WORKDEPT='E01' OR SALARY>50000)

Using the OPNQRYF command:


OPNQRYF FILE((PROJECT) (EMPLOYEE)) FORMAT(RESULTFILE) JFLD((1/RESPEMP 2/EMPNO)) QRYSLT('2/WORKDEPT=''E01'' *OR 2/SALARY>50000')

In this example, the optimizer decides that the join order is le PROJECT to le EMPLOYEE. Data space scan is used on le PROJECT. For le EMPLOYEE, index EPIX is used to process the join (primary index). Indexes TIX1 and TIX2 are used in bitmap processing. The database manager positions to the rst record in le PROJECT. It then performs the join using index EPIX. Next, it generates a bitmap from the results of applying selection WORKDEPT=E01 against index TIX1 (using key positioning). It

418

DB2 UDB for AS/400 SQL Programming V4R4

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

then generates a bitmap from the results of applying selection SALARY>50000 against index TIX2 (again using key positioning). Next, the database manager combines these two bitmaps into one using OR logic. Finally, the entry that EPIX is currently positioned to is checked against the bitmap. The entry is either selected or rejected by the bitmap. If the entry is selected, the records are retrieved from the underlying data space. Next, index EPIX is probed for the next join record. When an entry is found, it is compared against the bitmap and either selected or rejected. Note that the bitmap was generated only once (the rst time it was needed) and is just reused after that. The query optimizer debug messages put into the job log would look like:
CPI4327 File PROJECT processed in join position 1. CPI4326 File EMPLOYEE processed in join position 2. CPI4338 2 Access path(s) used for bitmap processing of file EMPLOYEE.

Bitmap processing alleviates some of the headache associated with having composite key indexes (multiple key elds in one index). For example, given an SQL query:
DECLARE C1 CURSOR FOR SELECT * FROM EMPLOYEE WHERE WORKDEPT='D11' AND FIRSTNAME IN ('DAVID', 'BRUCE', 'WILLIAM')

Or the same query using the OPNQRYF command:


OPNQRYF FILE((EMPLOYEE)) QRYSLT('WORKDEPT=''D11'' *AND FIRSTNME = %VALUES(''DAVID'' ''BRUCE'' ''WILLIAM'')')

An index with keys (WORKDEPT, FIRSTNAME) would be the best index to use to satisfy this query. However, two indexes, one with a key of WORKDEPT and the other with a key of FIRSTNME could be used in bitmap processing, with their resulting bitmaps ANDed together and data space scan used to retrieve the result. With the bitmap processing method, you can create several indexes, each with only one key eld, and have the optimizer use them as general purpose indexes for many queries. You can avoid problems involved with trying to determine the best composite key indexes for all queries being performed against a table. Bitmap processing, in comparison to using a multiple key eld index, allows more ease of use, but at some cost to performance. Keep in mind that you will always achieve the best performance by using composite key indexes. Some additional points regarding bitmap processing: v As long as the DB2 SMP feature is installed, you can use parallel processing whenever you use bitmap processing. in this case, the bitmap is built from the results of performing either parallel key positioning and/or parallel key selection on the tertiary index. v Bitmaps are generated at the rst record fetch (I/O). Therefore, the rst record fetched may take longer to retrieve than subsequent records. v Bitmaps, by their nature, contain static selection. Once the bitmap is generated, it will not select any new or modied records. For example, suppose an OPNQRYF statement specifying (QRYSLT(QUANTITY >5) is opened using bitmap processing and the rst record is read. Through a separate database operation, all records where QUANTITY is equal to 4 are updated so QUANTITY is equal to 10. Since the bitmap was already built (during
Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

419

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

the rst record fetch from the OPNQRYF open identier), these updated records will not be retrieved on subsequent fetches through the OPNQRYF open identier. For this reason, the query optimizer will not consider bitmap processing if the ALWCPYDTA option is *NO. The exception to this is if the query contains grouping or one or more aggregate functions (for example, SUM, COUNT, MIN, MAX), in which case static data is already being made. v Do not use bitmap processing for a query that is insert, update, or delete capable. For OPNQRYF, the OPTION parameter must be set to *INP and the SEQONLY parameter must be set to *YES. There must not be any overrides to SEQONLY(*NO)).

Data Access Methods


The following table provides a summary of the data management methods discussed.
Table 38. Summary of Data Management Methods
Access Method Dataspace Scan Access Method on page 399 Parallel Pre-Fetch Access Method on page 401 Selection Process Good When Reads all rows. Selection criteria applied to data in dataspace. Data retrieved from auxiliary storage in parallel streams. Reads all rows. Selection criteria applied to data in dataspace. > 20% rows selected. Not Good When < 20% rows selected. Selected When Advantages

No ordering, Minimizes page I/O grouping, or joining through and > 20% rows pre-fetching. selected. No ordering, grouping, or joining and > 20% rows selected. Minimizes wait time for page I/O through parallel pre-fetching.

> 20% rows selected. 1. Adequate active memory available. 2. Query would otherwise be I/O bound. 3. Data spread across multiple disk units.

< 20% rows selected. Query is CPU bound.

Parallel Data read and Data Space selected in parallel Scan tasks. Method (available only when the DB2 UDB Symmetric Multiprocessing feature is installed) on page 403

> 10% rows selected, large table. 1. Adequate active memory available. 2. Data spread across multiple disk units. 3. DB2 UDB Symmetric Multiprocessing installed. 4. Multi-processor system.

< 10% rows selected. Query is CPU bound on a uniprocessor system.

1. DB2 UDB Symmetric Multiprocessing installed. 2. I/O bound or running on a multi-processor system.

Signicant performance especially on multiprocessors.

420

DB2 UDB for AS/400 SQL Programming V4R4

Table 38. Summary of Data Management Methods (continued)


Access Method Key Selection Access Method on page 404 Selection Process Good When Selection criteria applied to index. Not Good When Selected When Index is required and cannot use key positioning method. When ordering of results not required. Advantages Dataspace accessed only for rows matching key selection criteria. Better I/O overlap because parallel tasks perform the I/O. Can fully utilize multiprocessor systems.

Ordering, grouping, Large number of and joining. rows selected.

Parallel Key Selection criteria Selection applied to index in Access parallel tasks. Method (available only when the DB2 UDB Symmetric Multiprocessing feature is installed) on page 405 Key Positioning Access Method on page 406 Selection criteria applied to range of index entries. Commonly used option.

Size of index is Large number of much less than the rows selected. dataspace. DB2 UDB Symmetric Multiprocessing must be installed.

< 20% rows selected.

> 20% rows selected.

Selection columns match left-most keys and < 20% rows selected.

Index and dataspace accessed only for rows matching selection criteria. 1. Index and dataspace accessed only for rows matching selection criteria. 2. Better I/O overlap because parallel tasks perform the I/O. 3. Can fully utilize a multiprocessor systems.

Parallel Key Selection criteria Positioning applied to range of Access index entries in Method parallel tasks. (available only when the DB2 UDB Symmetric Multiprocessing feature is installed) on page 411

< 20% rows Large number of selected. DB2 UDB rows selected. Symmetric Multiprocessing must be installed.

1. When ordering of results not required. 2. Selection columns match left-most keys and < 20% rows selected.

Index-FromIndex Access Method on page 414

Key row positioning Ordering, grouping on permanent and joining. index. Builds temporary index over selected index entries. > 20% rows Order data read selected or large using dataspace scan processing or result set of rows. key positioning.

> 20% rows selected.

No existing index to satisfy ordering but existing index does satisfy selection and selecting < 20% rows. Ordering specied; either no index exists to satisfy the ordering or a large result set is expected.

Index and dataspace accessed only for rows matching selection criteria.

Sort routine

< 20% rows selected or small result set of rows.

See dataspace scan and key positioning in this table.

Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

421

Table 38. Summary of Data Management Methods (continued)


Access Method Index Only Access Method on page 412 Selection Process Good When Done in combination with any of the other index access methods Index or table data loaded in parallel to avoid random access. Not Good When Selected When Advantages

All columns used in < 20% rows the query exist as selected or small key elds. DB2 result set of rows. UDB Symmetric Multiprocessing must be installed. Excessive random Active memory is activity would already otherwise occur over-committed. against the object and active memory is available to hold the entire object. Short running queries.

All columns used in Reduced I/O to the the query exist as dataspace. key elds and DB2 UDB Symmetric Multiprocessing is installed. Excessive random activity would result from processing the query and active memory is available which can hold the entire object. Join or grouping specied. Random page I/O is avoided which can improve I/O bound queries.

Parallel Table or Index Based Pre-load Access Method on page 413

Hashing Rows with common Longer running Access values are grouped grouping and/or Method on together. join queries. page 415(Parallel or non-parallel)

Reduce random I/O when compared to index methods. If DB2 UDB Symmetric Multiprocessing is installed, possible exploitation of SMP parallelism. Reduces page I/O to the data space. Allows multiple indexes per table.

Bitmap Processing Method on page 416

Key position/key selection used to build bitmap. Bitmap used to avoid touching rows in table.

Selection can be >25% rows applied to index selected. and either >5% or <25% rows selected or an OR operator is involved in selection that precludes the use of only one index.

Indexes match selection criteria.

The Optimizer
The optimizer is an important part of DB2 UDB for AS/400 because the optimizer: v Makes the key decisions which affect database performance. v Identies the techniques which could be used to implement the query. v Selects the most efficient technique. Data manipulation statements such as SELECT specify only what data the user wants, not how to get to that data. This access path to the data is chosen by the optimizer and stored in the access plan. This section covers the techniques employed by the query optimizer for performing this task including: v Cost estimation v Access plan validation v Join optimization v Grouping optimization

422

DB2 UDB for AS/400 SQL Programming V4R4

Cost Estimation
At run-time, the optimizer chooses an optimal access method for the query by calculating an implementation cost based on the current state of the database. The optimizer models the access cost of each of the following: v Reading rows directly from the table (dataspace scan processing) v Reading rows through an access path (using either key selection or key positioning) v Creating an access path directly from the dataspace v Creating an access path from an existing access path (index-from-index) v Using the query sort routine or hashing method (if conditions are satised) The cost of a particular method is the sum of: v The start-up cost v The cost associated with the given optimization mode. For SQL, the precompile option ALWCPYDTA and the OPTIMIZE FOR n ROWS clause indicate to the query optimizer the optimization goal to be achieved. - The optimizer can optimize SQL queries with one of two goals: 1. Minimize the time required to retrieve the rst buffer of rows from the table. This goal biases the optimization towards not creating an index. Either a data scan or an existing index is preferred. This mode can be specied in two ways: a. The OPTIMIZE FOR n ROWS allows the users to specify the number of rows they expect to retrieve from the query. The optimizer uses this value to determine the percentage of rows that will be returned and optimizes accordingly. A small value instructs the optimizer to minimize the time required to retrieve the rst n rows. b. Specifying ALWCPYDTA(*NONE) or ALWCPYDTA(*YES) a precompiler option, allows the optimizer to minimize the time required to retrieve the rst 3% of the resulting rows. This option is effective only if the OPTIMIZE FOR n ROWS was not specied. 2. Minimize the time to process the whole query assuming that all selected rows are returned to the application. Does not bias the optimizer to any particular access method. This mode can be specied in two ways: a. The OPTIMIZE FOR n ROWS allows the users to specify the number of rows they expect to retrieve from the query. The optimizer uses this value to determine the percentage of rows that will be returned and optimizes accordingly. A value greater than or equal to the expected number of resulting rows instructs the optimizer to minimize the time required to run the entire query. b. ALWCPYDTA(*OPTIMIZE) specied as a precompiler parameter. This option is effective only if the OPTIMIZE FOR n ROWS is not specied. For OPNQRYF, note: - The cost associated with the given optimization parameter (*FIRSTIO, *ALLIO, or *MINWAIT).

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

Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

423

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

v *FIRSTIOMinimize the time required to retrieve the rst buffer of records from the le. Biases the optimization toward not creating an index. Either a data scan or an existing index is preferred. When *FIRSTIO is selected, users may also pass in the number of records they expect to retrieve from the query. The optimizer uses this value to determine the percentage of records that will be returned and optimizes accordingly. A small value would minimize the time required to retrieve the rst n records, similar to *FIRSTIO. A large value would minimize the time to retrieve all n records, similar to *ALLIO. v *ALLIOMinimize the time to process the whole query assuming that all query records are read from the le. Does not bias the optimizer to any particular access method. Note: If you specify ALWCPYDTA(*OPTIMIZE) and use the sort routine, your query resolves according to the *ALLIO optimize parameter. v *MINWAITMinimize delays when reading records from the le. Minimize I/O time at the expense of open time. Biases optimization toward either creating a temporary index or performing a sort. Either an index is created or an existing index is used. v The cost of any access path creations v The cost of the expected number of page faults to read the rows and the cost of processing the expected number of rows. Page faults and number of rows processed may be predicted by statistics the optimizer can obtain from the database objects, including: Table size Row size Index size Key size Page faults can also be greatly affected if index only access can be performed, thus eliminating any random I/O to the data space. A weighted measure of the expected number of rows to process is based on what the relational operators in the row selection predicates, default lter factors, are likely to retrieve: 10% for equal 33% for less-than, greater-than, less-than-equal-to, or greater-than-equal-to 90% for not equal 25% for BETWEEN range (OPNQRYF %RANGE) 10% for each IN list value (OPNQRYF %VALUES) Key range estimate is a method the optimizer uses to gain more accurate estimates of the number of expected rows selected from one or more selection predicates. The optimizer estimates by applying the selection predicates against the left-most keys of an existing index. The default lter factors can then be further rened by the estimate based on the key range. If an index exists whose left-most keys match columns used in row selection predicates, that index can be used to estimate the number of keys that match the selection criteria. The estimate of the number of keys is based on the number of pages and key density of the machine index and is done without actually accessing the keys. Full indexes over columns used in selection predicates can signicantly help optimization.

| |

424

DB2 UDB for AS/400 SQL Programming V4R4

Page faults and the number of rows processed are dependent on the type of access the optimizer chooses. Refer to Data Management Methods on page 396 for more information on access methods.

Access Plan Validation


An access plan is a control structure that describes the actions necessary to satisfy each query request. An access plan contains information about the data and how to extract it. For any query, whenever optimization occurs, an optimized plan of how to access the requested data is developed. The information is kept in what is called a mini plan. The mini plan, along with the query denition template (QDT), is used to interface with the optimizer and make an access plan. v For dynamic SQL, an access plan is created, but the plan is not saved. A new access plan is created each time the PREPARE statement is run. v For a DB2 UDB for AS/400 program, the access plan is saved in the associated space of the program or package that contains embedded SQL statements. v For OPNQRYF, an access plan is created but is not saved. A new access plan is created each time the OPNQRYF command is processed. v For Query/400, an access plan is saved as part of the query denition object.

Optimizer Decision-Making Rules


In performing its function, the optimizer uses a general set of guidelines to choose the best method for accessing data. The optimizer: v Determines the default lter factor for each predicate in the selection clause. v Extracts attributes of the table from internally stored information. v Performs an estimate key range to determine the true lter factor of the predicates when the selection predicates match the left-most keys of an index. v Determines the cost of creating an index over a table if an index is required. v Determines the cost of using a sort routine or hashing method if selection conditions apply and an index is required. v Determines the cost of dataspace scan processing if an index is not required. v For each index available, in the order of most recently created to oldest, the optimizer does the following until its time limit is exceeded: Extracts attributes of the index from internally stored statistics. Determines if the index meets the selection criteria. Determines the cost of using the index using the estimated page faults and the predicate lter factors to help determine the cost. Compares the cost of using this index with the previous cost (current best). Picks the cheaper one. Continues to search for best index until time out or no more indexes. The time limit factor controls how much time is spent choosing an implementation. It is based on how much time was spent so far and the current best implementation cost found. Dynamic SQL queries are subject to the optimizer time restrictions. Static SQL queries optimization time is not limited. For OPNQRYF, if you specify OPTALLAP(*YES), the optimization time is not limited.

Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

425

For small tables, the query optimizer spends little time in query optimization. For large tables, the query optimizer considers more indexes. Generally, the optimizer considers ve or six indexes (for each table of a join) before running out of optimization time.

Join Optimization
| | | | | | | | | | | A join operation is a complex function that requires special attention in order to achieve good performance. This section describes how DB2 UDB for AS/400 implements inner join queries and how optimization choices are made by the query optimizer. It also describes design tips and techniques which help avoid or solve performance problems. The optimization for other types of joins, LEFT OUTER JOIN or EXCEPTION JOIN (OPNQRYF JDFTVAL(*YES) or JDFTVAL(*ONLYDFT) parameter), is similar except that the join order is always the same as the order of the tables specied in the FROM clause (OPNQRYF FILE paramter). Information about these types of joins will not be detailed here, but most of the information and tips in this section also apply to joins of this type.

Nested Loop Join Implementation


DB2 UDB for AS/400 provides a nested loop join method. For this method, the processing of the tables in the join are ordered. This order is called the join order. The rst table in the nal join order is called the primary table. The other tables are called secondary tables. Each join table position is called a dial. During the join, DB2 UDB for AS/400: 1. Accesses the rst primary table row selected by the predicates local to the primary table. 2. Builds a key value from the join columns in the primary table. 3. Uses key positioning to locate the rst row that satises the join condition for the rst secondary table using a keyed access path with keys matching the join condition or local row selection columns of the secondary table. 4. Applies bitmap selection, if applicable. 5. Determines if the row is selected by applying any remaining selection local to the rst secondary dial. If the secondary dial row is not selected then the next row that satises the join condition is located. Steps 1 through 5 are repeated until a row that satises both the join condition and any remaining selection is selected from all secondary tables 6. Returns the result join row. 7. Processes the last secondary table again to nd the next row that satises the join condition in that dial. During this processing, when no more rows that satisfy the join condition can be selected, the processing backs up to the logical previous dial and attempts to read the next row that satises its join condition. 8. Ends processing when all selected rows from the primary table are processed. Note the following characteristics of a nested loop join: v If ordering or grouping of result rows is specied over a single table, then that table becomes the primary table and is processed with a keyed access path over the table.

426

DB2 UDB for AS/400 SQL Programming V4R4

v If ordering or grouping of processing of the join result rows is specied on tables from other than the primary dial or on columns from two or more dials, DB2 UDB for AS/400 breaks the processing of the query into two parts: 1. Process the join query omitting the ordering or grouping processing and write the result rows to a temporary work table. This allows the optimizer to consider any table of the join query as a candidate for the primary table. 2. The ordering or grouping processing is then performed on the data in the temporary work table. | | | | The query optimizer might also decide to break the query into these two parts to improve performance when the SQL ALWCPYDTA(*OPTIMIZE) precompiler parameter or the OPNQRYF KEYFLD, and ALWCPYDTA(*OPTIMIZE) parameters are specied. v All rows that satisfy the join condition from each secondary dial are located using a keyed access path. Rows are retrieved from secondary tables in random sequence. This random disk I/O time often accounts for a large percentage of the processing time of the query. Since a given secondary dial is searched once for each row selected from the primary and the preceding secondary dials that satisfy the join condition for each of the preceding secondary dials, a large number of searches may be performed against the later dials. Any inefficiencies in the processing of the later dials can signicantly inate the query processing time. This is the reason why attention to performance considerations for join queries can reduce the run-time of a join query from hours to minutes. v Again, all selected rows from secondary dials are accessed through a keyed access path. If an efficient keyed access path cannot be found, a temporary keyed access path is created. Some join queries build temporary access paths over secondary dials even when an access path exists for all of the join keys. Because efficiency is very important for secondary dials of longer running queries, the query optimizer may choose to build a temporary keyed access path which contains only keys which pass the local row selection for that dial. This preprocessing of row selection allows the database manager to process row selection in one pass instead of each time rows are matched for a dial.

Hash Join
The hash join method is similar to nested loop join. Instead of using keyed access paths to locate the matching rows in a secondary table, however, a hash temporary result table is created that contains all of the rows selected by local selection against the table. The structure of the hash table is such that rows with the same join value are loaded into the same hash table partition (clustered). The location of the rows for any given join value can be found by applying a hashing function to the join value. Hash join has several advantages over nested loop join: v The structure of a hash temporary result table is simpler than that of an index, so less CPU processing is required to build and probe a hash table. v The rows in the hash result table contain all of the data required by the query so there is no need to access the data space of the table with random I/O when probing the hash table. v Like join values are clustered, so all matching rows for a given join value can usually be accessed with a single I/O request. v The hash temporary result table can be built using SMP parallelism.

Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

427

v Unlike indexes, entries in hash tables are not updated to reect changes of column values in the underlying table. The existence of a hash table does not affect the processing cost of other updating jobs in the system. Hash join cannot be used for queries that: v Perform subqueries unless all subqueries in the query can be transformed to inner joins. v Perform a UNION or UNION ALL. v Perform left outer or exception join. v Use a DDS created join logical le. v Require live access to the data as specied by the *NO or *YES parameter values for the ALWCPYDTA precompiler parameter. Hash join is used only for queries running with ALWCPYDTA(*OPTIMIZE). This parameter can be specied either on precompiler commands, the STRSQL CL command, or the OPNQRYF CL command. The Client Access/400 ODBC driver and Query Management driver always uses this mode. Hash join can be used with OPTIMIZE(*YES) if a temporary result is required to run the query. v Require that the cursor position be restored as the result of the SQL ROLLBACK HOLD statement or the ROLLBACK CL command. For SQL applications using commitment control level other than *NONE, this requires that *ALLREAD be specied as the value for the ALWBLK precompiler parameter. The query attribute DEGREE, which can be changed by using the Change Query attribute CL command (CHGQRYA), does not enable or disable the optimizer from choosing to use hash join. However, hash join queries can use SMP parallelism if the query attribute DEGREE is set to either *OPTIMIZE, *MAX, or *NBRTASKS. Hash join is used in many of the same cases where a temporary index would have been built. Join queries which are most likely to be implemented using hash join are those where either: v All rows in the various tables of the join are involved in producing result rows. v Signicant non-join selection is specied for the tables of the join which reduces the number of rows in the tables that are involved with the join result. The following is an example of a join query that would process all of the rows from the queried tables:
SELECT * FROM EMPLOYEE, EMP_ACT WHERE EMPLOYEE.EMPNO = EMP_ACT.EMPNO OPTIMIZE FOR 99999999 ROWS

| |

| | | | |

OPNQRYF example :
OPNQRYF FILE((EMPLOYEE EMP_ACT)) FORMAT(FORMAT1) JFLD((1/EMPNO 2/EMPNO *EQ)) ALWCPYDTA(*OPTIMIZE)

This query is implemented using the following steps: 1. A temporary hash table is built over table EMP_ACT with a key of EMPNO. This occurs when the query is opened. 2. For each row retrieved from the EMPLOYEE table, the temporary hash table will be probed for any matching join values. 3. For each matching row found, a result row is returned.

428

DB2 UDB for AS/400 SQL Programming V4R4

The messages created by the PRTSQLINF CL command to describe this hash join query in an SQL program would appear as follows:
SQL402A SQL402B SQL402B Hashing algorithm used to process join. File EMPLOYEE used in hash join step 1. File EMP_ACT used in hash join step 2.

The following is an example of a join query that would have the queried tables of the join queried signicantly reduced by local selection:
SELECT FROM WHERE AND AND OPTIMIZE EMPNO, LASTNAME, DEPTNAME EMPLOYEE, DEPARTMENT EMPLOYEE.WORKDEPT = DEPARTMENT.DEPTNO EMPLOYEE.HIREDATE BETWEEN 1996-01-30 AND 1995-01-30 DEPARTMENT.DEPTNO IN ('A00', 'D01', 'D11', 'D21', 'E11') FOR 99999999 ROWS

| | | | | | | | |

OPNQRYF example:
OPNQRYF FILE((EMPLOYEE DEPARTMENT)) FORMAT(FORMAT2) QRYSLT('1/HIREDATE *EQ %RANGE(''1996-01-30'' ''1995-01-30'') *AND 2/DEPTNO *EQ %VALUES(''A00'' ''D01'' ''D11'' ''D21'' ''E11''') JFLD((1/WORKDEPT 2/DEPTNO *EQ)) ALWCPYDTA(*OPTIMIZE)

This query is implemented using the following steps: 1. A temporary hash table is built over table DEPARTMENT with key values of DEPTNO containing rows matching the selection predicate, DEPTNO IN (A00, D01, D11, D21, E11). This occurs when the query is opened. 2. For each row retrieved from the EMPLOYEE table matching the selection predicate, HIREDATE BETWEEN 1996-01-30 and 1995-01-30, the temporary hash table will be probed for the matching join values. 3. For each matching row found, a result row is returned. The messages created by the PRTSQLINF CL command to describe this hash join query in an SQL program would appear as follows:
SQL402A SQL402B SQL402B Hashing algorithm used to process join. File EMPLOYEE used in hash join step 1. File DEPARTMENT used in hash join step 2.

When ordering, grouping, non-equal selection specied with operands derived from columns of different tables, or result columns are derived from columns of different tables, the hash join processing will be done and the result rows of the join will be written to a temporary table. Then, as a second step, the query will be completed using the temporary table. The following is an example of a join query with selection specied with operands derived from columns of different tables:
SELECT EMPNO, LASTNAME, DEPTNAME FROM EMPLOYEE, DEPARTMENT WHERE EMPLOYEE.WORKDEPT = DEPARTMENT.DEPTNO AND EMPLOYEE.EMPNO > DEPARTMENT.MGRNO OPTIMIZE FOR 99999999 ROWS

| | | | |

OPNQRYF example:
OPNQRYF FILE((EMPLOYEE DEPARTMENT) FORMAT(FORMAT2) JFLD((1/WORKDEPT 2/DEPTNO *EQ) (1/EMPNO 2/MGRNO *GT))
Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

429

This query is implemented using the following steps: 1. A temporary hash table is built over table DEPARTMENT with a key of DEPTNO. This occurs when the query is opened. 2. For each row retrieved from the EMPLOYEE table, the temporary hash table will be probed for the matching join values. 3. For each matching row found, a result row is written to a temporary table. 4. After all of the join result rows are written to the temporary table, rows that are selected by EMPNO > MGRNO are read from the temporary le and returned to the application. The messages created by the PRTSQLINF CL command to describe this hash join query in an SQL program would appear as follows:
SQL402A SQL402B SQL402B SQL402C Hashing algorithm used to process join. File EMPLOYEE used in hash join step 1. File DEPARTMENT used in hash join step 2. Temporary result table created for hash join query.

Join Optimization Algorithm


The query optimizer must determine the join columns, join operators, local row selection, keyed access path usage, and dial ordering for a join query. The join columns and join operators depend on the: v v v v Join column specications of the query Join order Interaction of join columns with other row selection Keyed access path used.

Join specications which are not implemented for the dial are either deferred until they can be processed in a later dial or, if an inner join was being performed for this dial, processed as row selection. For a given dial, the only join specications which are usable as join columns for that dial are those being joined to a previous dial. For example, for the second dial the only join specications that can be used to satisfy the join condition are join specications which reference columns in the primary dial. Likewise, the third dial can only use join specications which reference columns in the primary and the second dials and so on. Join specications which reference later dials are deferred until the referenced dial is processed. For any given dial, only one type of join operator is normally implemented. For example, if one inner join join specication has a join operator of = and the other has a join operator of >, the optimizer attempts to implement the join with the = operator. The > join specication is processed as row selection after a matching row for the = specication is found. In addition, multiple join specications that use the same operator are implemented together. Note: For OPNQRYF, only one type of join operator is allowed for either a left outer or an exception join. When looking for an existing keyed access path to access a secondary dial, the query optimizer looks at the left-most key columns of the access path. For a given dial and keyed access path, the join specications which use the left-most key columns can be used. For example:

| | | |

430

DB2 UDB for AS/400 SQL Programming V4R4

DECLARE BROWSE2 CURSOR FOR SELECT * FROM EMPLOYEE, EMP_ACT WHERE EMPLOYEE.EMPNO = EMP_ACT.EMPNO AND EMPLOYEE.HIREDATE = EMP_ACT.EMSTDATE OPTIMIZE FOR 99999 ROWS

| | | | |

OPNQRYF example:
OPNQRYF FILE((EMPLOYEE, EMP_ACT)) FORMAT(FORMAT1) JFLD((1/EMPNO 2/EMP_ACT *EQ)(1/HIREDATE 2/EMSTDATE *EQ))

For the keyed access path over EMP_ACT with key columns EMPNO, PROJNO, and EMSTDATE, the join operation is performed only on column EMPNO. After the join is processed, row selection is done using column EMSTDATE. The query optimizer also uses local row selection when choosing the best use of the keyed access path for the secondary dial. If the previous example had been expressed with a local predicate as:
DECLARE BROWSE2 CURSOR FOR SELECT * FROM EMPLOYEE, EMP_ACT WHERE EMPLOYEE.EMPNO = EMP_ACT.EMPNO AND EMPLOYEE.HIREDATE = EMP_ACT.EMSTDATE AND EMP_ACT.PROJNO = '123456' OPTIMIZE FOR 99999 ROWS

| | | | | |

OPNQRYF example:
OPNQRYF FILE((EMPLOYEE, EMP_ACT)) FORMAT(FORMAT2) QRYSLT('2/PROJNO *EQ ''123456''') JFLD((1/EMPNO 2/EMP_ACT *EQ)(1/HIREDATE 2/EMSTDATE *EQ))

the keyed access path with key columns EMPNO, PROJNO, and EMSTDATE are fully utilized by combining join and selection into one operation against all three key columns. When creating a temporary keyed access path, the left-most key columns are the usable join columns in that dial position. All local row selection for that dial is processed when selecting keys for inclusion into the temporary keyed access path. A temporary keyed access path is similar to the access path created for a select/omit keyed logical le. The temporary index for the previous example would have key elds of EMPNO and EMSTDATE.

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

Since the OS/400 query optimizer attempts a combination of join and local record selection when determining access path usage, it is possible to achieve almost all of the same advantages of a temporary keyed access path by use of an existing access path. In the above example, using either implementation, an existing index may be used or a temporary index may be created. A temporary access path would have been built with the local row selection on PROJNO applied during the access paths creation; the temporary access path would have key elds of EMP_ACT and EMSTDATE (to match the join selection). If, instead, an existing keyed access path was used with key elds of EMP_ACT, PROJNO, EMSTDATE (or PROJNO, EMP_ACT, EMSTDATE or EMSTDATE, PROJNO, EMP_ACT or ...) the local record selection could be applied at the same time as the join selection (rather than prior to the join selection, as happens when the temporary access path is created). The implementation using the existing index is more likely to provide faster performance because join and selection processing are combined without the overhead of building a temporary index. However, the use of the existing keyed
Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

431

| | | |

access path may have just slightly slower I/O processing than the temporary access path because the local selection is run many times rather than once. In general, it is a good idea to have existing indexes available with key columns for the combination of join columns and columns using equal selection as the left-most keys.

Join Order Optimization


| | | | | | | | | | | | | | | | | | | | | | | | | | | | | The join order is xed if any join logical les are referenced or a left outer or an exception join is used to implement any of the dials of the join. The join order is also xed if the OPNQRYF JORDER(*FILE) parameter is specied or the query options le (QAQQINI) FORCE_JOIN_ORDER parameter is *YES. Otherwise, the following join ordering algorithm is used to determine the order of the tables: 1. Determine an access method for each individual table as candidates for the primary dial. 2. Estimate the number of rows returned for each table based on local row selection. If the join query with row ordering or group by processing is being processed in one step, then the table with the ordering or grouping columns is the primary table. 3. Determine an access method, cost, and expected number of rows returned for each join combination of candidate tables as primary and rst secondary tables. The join order combinations estimated for a four table join would be: 1-2 2-1 1-3 3-1 1-4 4-1 2-3 3-2 2-4 4-2 3-4 4-3 4. Choose the combination with the lowest join cost. If the cost is nearly the same, then choose the combination which selects the fewest rows. 5. Determine the cost, access method, and expected number of rows for each remaining table joined to the previous secondary table. 6. Select an access method for each table that has the lowest cost for that table. 7. Choose the secondary table with the lowest join cost. If the cost is nearly the same, choose the combination which selects the fewest rows. 8. Repeat steps 4 through 7 until the lowest cost join order is determined. When a join logical le is referenced, a left outer or an excpetion join, or the join order is forced to the specied le order, the query optimizer loops through all of the dials in the order specied, and determines the lowest cost access methods.

Costing and Selecting Access Paths for Join Secondary dials


In step 3 and in step 5, the query optimizer has to estimate a cost and choose an access method for a given dial combination. The choices made are similar to those for row selection except that a keyed access path must be used. As the query optimizer compares the various possible access choices, it must assign a numeric cost value to each candidate and use that value to determine the implementation which consumes the least amount of processing time. This costing value is a combination of CPU and I/O time and is based on the following assumptions: v Table pages and keyed access path pages must be retrieved from auxiliary storage. For example, the query optimizer is not aware that an entire table may be loaded into active memory as the result of a SETOBJACC CL command.

432

DB2 UDB for AS/400 SQL Programming V4R4

Usage of this command may signicantly improve the performance of a query, but the query optimizer does not change the query implementation to take advantage of the memory resident state of the table. v The query is the only process running on the system. No allowance is given for system CPU utilization or I/O waits which occur because of other processes using the same resources. CPU related costs are scaled to the relative processing speed of the system running the query. v The values in a column are uniformly distributed across the table. For example, if 10% of the rows in a table have the same value, then it is assumed that every tenth row in the table contains that value. v The values in a column are independent from the values in any other columns in a row. For example, if a column named A has a value of 1 in 50% of the rows in a table and a column named B has a value of 2 in 50% of the rows, then it is expected that a query which selects rows where A = 1, and B = 2 selects 25% of the rows in the table. The main factors of the join cost calculations for secondary dials are the number of rows selected in all previous dials and the number of rows which match, on average, each of the rows selected from previous dials. Both of these factors can be derived by estimating the number of matching rows for a given dial. When the join operator is something other than equal, the expected number of matching rows is based on the following default lter factors: v 33% for less-than, greater-than, less-than-equal-to, or greater-than-equal-to v 90% for not equal | | v 25% for BETWEEN range (OPNQRYF %RANGE) v 10% for each IN list value (OPNQRYF %VALUES) For example, when the join operator is less-than, the expected number of matching rows is .33 * (number of rows in the dial). If no join specications are active for the current dial, the cartesian product is assumed to be the operator. For cartesian products, the number of matching rows is every row in the dial, unless local row selection can be applied to the keyed access path. When the join operator is equal, the expected number of rows is the average number of duplicate rows for a given value. The AS/400 performs index maintenance (insertion and deletion of key values in an index) and maintains a running count of the number of unique values for the given key columns in the index. These statistics are bound with the index object and are always maintained. The query optimizer uses these statistics when it is optimizing a query. Maintaining these statistics adds no measurable amount of overhead to index maintenance. This statistical information is only available for indexes which: v Contain no varying length character keys. Note: If you have varying length character columns used as join columns, you can create an index which maps the varying length character column to a xed character key using the CRTLF CL command. An index that contains xed length character keys dened over varying length data supplies average number of duplicate values statistics. v Were created or rebuilt on an AS/400 system on which Version 2 Release 3 or a later version is installed.

Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

433

Note: The query optimizer can use indexes created on earlier versions of OS/400 to estimate if the join key values have a high or low average number of duplicate values. If the index is dened with only the join keys, the estimate is done based on the size of the index. In many cases, additional keys in the index cause matching row estimates through that index to not be valid. The performance of some join queries may be improved by rebuilding these access paths. Average number of duplicate values statistics are maintained only for the rst 4 left-most keys of the index. For queries which specify more than 4 join columns, it might be benecial to create multiple additional indexes so that an index can be found with average number of duplicate values statistics available within the 4 left-most key columns. This is particularly important if some of the join columns are somewhat unique (low average number of duplicate values).
Three Field Key Key 1 Key 2 Key 3 Number of unique keys for Key 1 Number of unique keys for Key1 and Key 2 combination Number of unique keys for Key 1, Key2, and Key 3 combination (the full key)

Figure 14. Average number of duplicate values of a 3 key index

These statistics are maintained as part of index rebuild and creation. Using the average number of duplicate values for equal joins or the default lter value for the other join operators, we now have the number of matching rows. The following formula is used to compute the number of join rows from previous dials.
NPREV = Rp * M2 * FF2 * ..... *Mn * FFn .....

NPREV The number of join rows from all previous dials. Rp M2 FF2 Mn The number of rows selected from the primary dial. The number of matching rows for dial 2. Filtering reduction factor for predicates local to dial 2 that are not already applied using M2 above. The number of matching rows for dial n.

434

DB2 UDB for AS/400 SQL Programming V4R4

FFn

Filtering reduction factor for predicates local to dial n that are not already applied using Mn above. Note: Multiply the pair of matching rows (Mn) and lter reduction lter factors (FFn) for each secondary dial preceding the current dial.

Now that it has calculated the number of join rows from previous dials, the optimizer is ready to generate a cost for the access method.

Temporary Keyed Access Path or Hash Temporary Result Table from Table
The rst access method choice analyzed by the query optimizer is building a temporary keyed access path or hash temporary result table from the table. The basic formula for costing access of a join secondary dial through a temporary keyed access path built from the table or hash table follows:
JSCOST = CRTDSI + NPREV *((MATCH * FF * KeyAccess) + (MATCH * FF * FCost)) * FirstIO

JSCOST Join Secondary cost CRTDSI Cost to build the temporary keyed access path or a hash temporary result table NPREV The number of join rows from all previous dials MATCH The number of matching rows (usually average duplicates) KeyAccess The cost to access a key in a keyed access path or a hash table FF The ltering factor for local predicates of this dial (excluding selection performed on earlier dials because of transitive closure)

FCost The cost to access a row from the table FirstIO A reduction ratio to reduce the non-startup cost because of an optimization goal to optimize for the rst buffer retrieval. For more information, see Cost Estimation on page 423. This secondary dial access method is used if no usable keyed access path is found or if the temporary keyed access path or hash table performs better than any existing keyed access path. This method can be better than using any existing access path because the row selection is completed when the keyed access path or hash table is created if any of the following are true: v The number of matches (MATCH) is high. v The number of join rows from all previous dials (NPREV) is high. v There is some ltering reduction (FF < 100%).

Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

435

Temporary Keyed Access Path or Hash Table from Keyed Access Path
The basic cost formula for this access method choice is the same as that of using a temporary keyed access path or hash table built from a table, with one exception. The cost to build the temporary keyed access path, CRTDSI, is calculated to include the selection of the rows through an existing keyed access path. This access method is used for join secondary dial access for the same reason. However, the creation from a keyed access path might be less costly.

Use an Existing Keyed Access Path


The nal access method is to use an existing keyed access path. The basic formula for costing access of a join secondary dial through an existing keyed access path is:
JSCOST = NPREV *((MATCH * KeyAccess) + (MATCH * FCost)) * FirstIO

JSCOST Join Secondary cost NPREV The number of join rows from all previous dials MATCH The number of matching keys which will be found in this keyed access path (usually average duplicates) KeyAccess The cost to access a key in a keyed access path FCost The cost to access a row from the table FirstIO A reduction ratio to reduce the non-startup cost because of an optimization goal to optimize for the rst buffer retrieval. For more information, see Cost Estimation on page 423. If I/O optimization is used (that is, OPNQRYF OPTIMIZE(*FIRSTIO)), this is a likely access method because the entire cost is reduced. Also, if the number of join rows from all previous dials (NPREV), and the number of matching keys (MATCH) is low, this may be the most efficient method. The query optimizer considers using an index which only has a subset of the join columns as the left-most leading keys when: v It is able to determine from the average number of duplicate values statistics that the average number of rows with duplicate values is quite low. v The number of rows being selected from the previous dials is small.

Predicates Generated Through Transitive Closure


For join queries, the query optimizer may do some special processing to generate additional selection. When the set of predicates that belong to a query logically infer extra predicates, the query optimizer generates additional predicates. The purpose is to provide more information during join optimization.

436

DB2 UDB for AS/400 SQL Programming V4R4

Example of Predicates being Added Because of Transitive Closure


SELECT * FROM EMPLOYEE, EMP_ACT WHERE EMPLOYEE.EMPNO = EMP_ACT.EMPNO AND EMPLOYEE.EMPNO = '000010'

The optimizer will modify the query to be:


SELECT * FROM EMPLOYEE, EMP_ACT WHERE EMPLOYEE.EMPNO = EMP_ACT.EMPNO AND EMPLOYEE.EMPNO = '000010' AND EMP_ACT.EMPNO = '000010'OPNQRYF example:

| | | | | | | | | | |

OPNQRYF example:
OPNQRYF FILE((EMPLOYEE EMP_ACT)) FORMAT(FORMAT1) QRYSLT('1/EMPNO *EQ ''000010''') JFLD((1/EMPNO 2/EMPNO *EQ))

The optimizer will modify the query to be:


OPNQRYF FILE((EMPLOYEE EMP_ACT)) FORMAT(FORMAT1) QRYSLT('1/EMPNO *EQ ''000010'' *AND 2/EMPNO *EQ ''000010''') JFLD((1/EMPNO 2/EMPNO *EQ))

The following rules determine which predicates are added to other join dials: v The dials affected must have join operators of equal. v The predicate is isolatable, which means that a false condition from this predicate would omit the row. v One operand of the predicate is an equal join column and the other is a literal or host variable. v The predicate operator is not LIKE or IN (OPNQRYF %WLDCRD, %VALUES, or *CT). v The predicate is not connected to other predicates by OR. v The join type for the dial is an inner join.

| |

| | | | | | | |

The query optimizer generates a new predicate, whether or not a predicate already exists in the WHERE clause (OPNQRYF QRYSLT parameter). Some predicates are redundant. This occurs when a previous evaluation of other predicates in the query already determines the result that predicate provides. Redundant predicates can be specied by you or generated by the query optimizer during predicate manipulation. Redundant predicates with predicate operators of =, >, >=, <, <=, or BETWEEN (OPNQRYF *EQ, *GT, *GE, *LT, *LE, or %RANGE) are merged into a single predicate to reect the most selective range.

Multiple Join Types for a Query


Even though multiple join types (inner, left outer and exception) can be specied in the query using the JOIN syntax, the AS/400 Licensed Internal Code can only support one join type for the entire query. This requires the optimizer to determine what the overall join type for the query should be. Note: This section does not apply to OPNQRYF.

Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

437

The optimizer will evaluate the join criteria along with any record selection that may be specied in order to determine the join type for each dial and for the entire query. Once this information is known the optimizer will generate additional selection using the relative record number of the tables to simulate the different types of joins that may occur within the query. Since null values are returned for any unmatched rows for either a left outer or an exception join, any isolatable selection specied for that dial, including any additional join criteria that may be specied in the WHERE clause, will cause all of the unmatched records to be eliminated (unless the selection is for an IS NULL predicate). This will cause the join type for that dial to be changed to an inner join (or an exception join) if the IS NULL predicate was specied. In the following example a left outer join is specied between the tables EMPLOYEE and DEPARTMENT. In the WHERE clause there are two selection predicates that also apply to the DEPARTMENT table.
SELECT EMPNO, LASTNAME, DEPTNAME, PROJNO FROM CORPDATA.EMPLOYEE XXX LEFT OUTER JOIN CORPDATA.DEPARTMENT YYY ON XXX.WORKDEPT = YYY.DEPTNO LEFT OUTER JOIN CORPDATA.PROJECT ZZZ ON XXX.EMPNO = ZZZ.RESPEMP WHERE XXX.EMPNO = YYY.MGRNO AND YYY.DEPTNO IN ('A00', 'D01', 'D11', 'D21', 'E11')

The rst selection predicate, XXX.EMPNO = YYY.MGRNO, is an additional join condition that will be added to the join criteria and evaluated as an inner join join condition. The second is an isolatable selection predicate that will eliminate any unmatched records. Either one of these selection predicates will cause the join type for the DEPARTMENT table to be changed from a left outer join to an inner join. Even though the join between the EMPLOYEE and the DEPARTMENT table was changed to an inner join the entire query will still need to remain a left outer join to satisfy the join condition for the PROJECT table. Note: Care must be taken when specifying multiple join types since they are supported by appending selection to the query for any unmatched rows. This means that the number of resulting rows that satisfy the join criteria can become quite large before any selection is applied that will either select or omit the unmatched rows based on that individual dials join type. For more information on how to use the JOIN syntax see either Joining Data from More Than One Table on page 75 or the DB2 UDB for AS/400 SQL Reference book.

Sources of Join Query Performance Problems


The optimization algorithms described above benet most join queries, but the performance of a few queries may be degraded. This occurs when: v An access path is not available which provides average number of duplicate values statistics for the potential join columns. Note: Costing and Selecting Access Paths for Join Secondary dials on page 432 provides suggestions on how to avoid the restrictions about indexes statistics or create additional indexes over the potential join columns if they do not exist.

438

DB2 UDB for AS/400 SQL Programming V4R4

v The query optimizer uses default lter factors to estimate the number of rows being selected when applying local selection to the table because indexes do not exist over the selection columns. Creating indexes over the selection columns allows the query optimizer to make a more accurate ltering estimate by using key range estimates. v The particular values selected for the join columns yield a signicantly greater number of matching rows than the average number of duplicate values for all values of the join columns in the table (i.e. the data is not uniformly distributed). Use DDS to build a logical le with a keyed access path with select/omit specications matching the local row selection. This provides the query optimizer with a more accurate estimate of the number of matching rows for the keys which are selected. Note: The optimizer can better determine from the select/omit access path that the data is not uniformly distributed. v The query optimizer makes the wrong assumption about the number of rows which will be retrieved from the answer set. For SQL programs, specifying the precompile option ALWCPYDTA(*YES) makes it more likely that the queries in that program will use an existing index. Likewise, specifying ALWCPYDTA(*OPTIMIZE) makes it more likely that the queries in that program will create a temporary index. The SQL clause OPTIMIZE FOR n ROWS can also be used to inuence the query optimizer. For the OPNQRYF command, the wrong performance option for the OPTIMIZE keyword may have been specied. Specify *FIRSTIO to make the use of an existing index more likely. Specify *ALLIO to make the creation of a temporary index more likely.

| | | |

Improving Performance of Join Queries


If you are looking at a join query which is performing poorly or you are about to create a new application which uses join queries, the following checklist may be useful.
Table 39. Checklist for Creating an Application that Uses Join Queries
What to Do Check the database design. Make sure that there are indexes available over all of the join columns and/or row selection columns. If using CRTLF, make sure that the index is not shared. Check the query to see whether some complex predicates should be added to other dials to allow the optimizer to get a better idea of the selectivity of each dial. Create a keyed access path which includes Select/Omit specications which match that of the query using CRTLF CL command. How It Helps This gives the query optimizer a better opportunity to select an efficient access method because it can determine the average number of duplicate values. Many queries may be able to use the existing index to implement the query and avoid the cost of creating a temporary index.

Since the query optimizer does not add predicates for predicates connected by OR or non-isolatable predicates, or predicate operators of LIKE or IN, modifying the query by adding these predicates may help.

This step helps if the statistical characteristics are not uniform for the entire table. For example, if there is one value which has a high duplication factor and the rest of the column values are unique, then a select/omit keyed access path allows the optimizer to skew the distribution of values for that key and make the right optimization for the selected values.

Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

439

Table 39. Checklist for Creating an Application that Uses Join Queries (continued)
What to Do Specify ALWCPYDTA(*OPTIMIZE) or ALWCPYDTA(*YES) How It Helps If the query is creating a temporary keyed access path, and you feel that the processing time would be better if the optimizer only used the existing access path, specify ALWCPYDTA(*YES). If the query is not creating a temporary keyed access path, and you feel that the processing time would be better if a temporary keyed access path was created, specify ALWCPYDTA(*OPTIMIZE).

| | | | For OPNQRYF, specify | OPTIMIZE(*FIRSTIO) or | OPTIMIZE(*ALLIO) | |

Alternatively, specify the OPTIMIZE FOR n ROWS to inform the optimizer of the application has intention to read every resulting row. To do this set n to a large number. You could also set n to a small number before ending the query. If the query is creating a temporary keyed access path and you feel that the processing time would be better if it would only use the existing access path, then specify OPTIMIZE(*FIRSTIO). If the query is not creating a temporary keyed access path and you feel that the processing time would be better if a temporary keyed access path was created then specify OPTIMIZE(*ALLIO).

440

DB2 UDB for AS/400 SQL Programming V4R4

Table 39. Checklist for Creating an Application that Uses Join Queries (continued)
What to Do How It Helps A join in which one le is joined with all secondary les consecutively is sometimes called a star join (star join should be in bold). In the case of a star join where all secondary join predicates contain a eld reference to a particular le, there may be performance advantages if that le is placed in join position one. In Example A, all les are joined to le EMPLOYEE. The query optimizer can freely determine the join order. The query should be changed to force EMPLOYEE into join position one by using the query options le (QAQQINI) FORCE_JOIN_ORDER parameter of *YES or OPNQRYF JORDER(*FILE) as shown in example B. Note that in these examples the join type is a join with no default values returned (this is an inner join.). The reason for forcing the le into the rst position is to avoid random I/O processing. If EMPLOYEE is not in join position one, every record in EMPLOYEE could be examined repeatedly during the join process. If EMPLOYEE is fairly large, considerable random I/O processing occurs resulting in poor performance. By forcing EMPLOYEE to the rst position, random I/O processing is minimized. Example A: Start join query DECLARE C1 CURSOR FOR SELECT * FROM DEPARTMENT, EMP_ACT, EMPLOYEE, PROJECT WHERE DEPARTMENT.DEPTNO=EMPLOYEE.WORKDEPT AND EMP_ACT.EMPNO=EMPLOYEE.EMPNO AND EMPLOYEE.WORKDEPT=PROJECT.DEPTNO Example B: Star join query with order forced via FORCE_JOIN_ORDER DECLARE C1 CURSOR FOR SELECT * FROM EMPLOYEE, DEPARTMENT, EMP_ACT, PROJECT WHERE DEPARTMENT.DEPTNO=EMPLOYEE.WORKDEPT AND EMP_ACT.EMPNO=EMPLOYEE.EMPNO AND EMPLOYEE.WORKDEPT=PROJECT.DEPTNO OPNQRYF Example A: Start join query OPNQRYF FILE((DEPARTMENT EMP_ACT EMPLOYEE PROJECT)) FORMAT(FORMAT1) JFLD((1/DEPTNO 3/WORKDEPT *EQ) (2/EMPNO 3/EMPNO *EQ) (3/WORKDEPT 4/DEPTNO *EQ)) Example B: Start join query with JORDER(*FILE) parameter OPNQRYF FILE((EMPLOYEE DEPARTMENT EMP_ACT PROJECT)) FORMAT(FORMAT1) JFLD((2/DEPTNO 1/WORKDEPT *EQ) (3/EMPNO 1/EMPNO *EQ) (1/WORKDEPT 4/DEPTNO *EQ)) JORDER(*FILE) Note: Specifying elds from EMPLOYEE in the ORDER BY clause (OPNQRYF KEYFLD parameter) may also have the effect of placing EMPLOYEE in join position 1. This allows the query optimizer to choose the best order for the remaining les. Specify ALWCPYDTA(*OPTIMIZE) In the cases where ordering is specied and all key columns are from a single to allow the query optimizer to use dial, this allows the query optimizer to consider all possible join orders. a sort routine.

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

Use a join logical le or use the query options le (QAQQINI) FORCE_JOIN_ORDER parameter of *YES. OPNQRYF users can specify JORDER(*FILE).

Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

441

Table 39. Checklist for Creating an Application that Uses Join Queries (continued)
What to Do How It Helps This improves performance by reducing the join fan-out. Every secondary le should have at least one join predicate that references on of its elds as a join-to eld.

| | | |

Specify join predicates to prevent all of the records from one le from being joined to every record in the other le.

Improving Performance When Selecting Data from More than Two Tables
If the select-statement you are considering accesses two or more tables, all the recommendations suggested in Effectively Using SQL Indexes on page 446 apply. The following suggestion is directed specically to select-statements that access several tables. For joins that involve more than two tables, you might want to provide redundant information about the join columns. If you give the optimizer extra information to work with when requesting a join. It can determine the best way to do the join. The additional information might seem redundant, but is helpful to the optimizer. For example, instead of coding:
EXEC SQL DECLARE EMPACTDATA CURSOR FOR SELECT LASTNAME, DEPTNAME, PROJNO, ACTNO FROM CORPDATA.DEPARTMENT, CORPDATA.EMPLOYEE, CORPDATA.EMP_ACT WHERE DEPARTMENT.MGRNO = EMPLOYEE.EMPNO AND EMPLOYEE.EMPNO = EMP_ACT.EMPNO END-EXEC.

| | | | |

When using the OPNQRYF command, specify:


OPNQRYF FILE(CORPDATA/DEPARTMENT CORPDATA/EMPLOYEE CORPDATA/EMP_ACT) FORMAT(FORMAT1) JFLD((1/MGRNO 2/EMPNO *EQ) (2/EMPNO 3/EMP_ACT *EQ))

Provide the optimizer with a little more data and code:


EXEC SQL DECLARE EMPACTDATA CURSOR FOR SELECT LASTNAME, DEPTNAME, PROJNO, ACTNO FROM CORPDATA.DEPARTMENT, CORPDATA.EMPLOYEE, CORPDATA.EMP_ACT WHERE DEPARTMENT.MGRNO = EMPLOYEE.EMPNO AND EMPLOYEE.EMPNO = EMP_ACT.EMPNO AND DEPARTMENT.MGRNO = EMP_ACT.EMPNO END-EXEC.

| | | | | |

When using the OPNQRYF command, specify:


OPNQRYF FILE(CORPDATA/DEPARTMENT CORPDATA/EMPLOYEE CORPDATA/EMP_ACT) FORMAT(FORMAT1) JFLD((1/MGRNO 2/EMPNO *EQ) (2/EMPNO 3/EMP_ACT *EQ) (1/MGRNO 3/EMPNO *EQ))

Grouping Optimization
This section describes how DB2 UDB for AS/400 implements grouping techniques and how optimization choices are made by the query optimizer.

Grouping Hash Implementation


This technique uses the base hash access method to perform grouping or summarization of the selected table rows. For each selected row, the specied

442

DB2 UDB for AS/400 SQL Programming V4R4

grouping value is run through the hash function. The computed hash value and grouping value are used to quickly nd the entry in the hash table corresponding to the grouping value. If the current grouping value already has a row in the hash table, the hash table entry is retrieved and summarized (updated) with the current table row values based on the requested grouping column operations (such as SUM or COUNT). If a hash table entry is not found for the current grouping value, a new entry is inserted into the hash table and initialized with the current grouping value. The time required to receive the rst group result for this implementation will most likely be longer than other grouping implementations because the hash table must be built and populated rst. Once the hash table is completely populated, the database manager uses the table to start returning the grouping results. Before returning any results, the database manager must apply any specied grouping selection criteria or ordering to the summary entries in the hash table. The grouping hash method is most effective when the consolidation ratio is high. The consolidation ratio is the ratio of the selected table rows to the computed grouping results. If every database table row has its own unique grouping value, then the hash table will become too large. This in turn will slow down the hashing access method. The optimizer estimates the consolidation ratio by rst determining the number of unique values in the specied grouping columns (that is, the expected number of groups in the database table). The optimizer then examines the total number of rows in the table and the specied selection criteria and uses the result of this examination to estimate the consolidation ratio. Indexes over the grouping columns can help make the optimizers ratio estimate more accurate. Indexes improve the accuracy because they contain statistics that include the average number of duplicate values for the key columns. The optimizer also uses the expected number of groups estimate to compute the number of partitions in the hash table. As mentioned earlier, the hashing access method is more effective when the hash table is well-balanced. The number of hash table partitions directly affects how entries are distributed across the hash table and the uniformity of this distribution. The hash function performs better when the grouping values consist of columns that have non-numeric data types, with the exception of the integer (binary) data type. In addition, specifying grouping value columns that are not associated with the variable length and null column attributes allows the hash function to perform more effectively.

Grouping with Keyed Sequence Implementation


This implementation utilizes the key selection or key positioning access methods to perform the grouping. An index is required that contains all of the grouping columns as contiguous leftmost key elds. The database manager accesses the individual groups through the keyed access path and performs the requested summary functions. Since the index, by denition, already has all of the key values grouped together, the rst group result can be returned in less time than the hashing method. This is because of the temporary result that is required for the hashing method. This

Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

443

implementation can be benecial if an application does not need to retrieve all of the group results or if an index already exists that matches the grouping columns. When the grouping is implemented with an index and a permanent index does not already exist that satises grouping columns, a temporary index is created. The grouping columns specied within the query are used as the key elds for this index.

Eliminating Grouping Columns


All of the grouping columns are evaluated to determine if they can be removed from the list of grouping columns. Only those grouping columns that have isolatable selection predicates with an equal operator specied can be considered. This guarantees that the column can only match a single value and will not help determine a unique group. This processing is done to allow the optimizer to consider more indexes to implement the query and to reduce the number of columns that will be added as key elds to a temporary index or hash table. The following example illustrates a query where the optimizer could eliminate a grouping column. | | | | | |
DECLARE DEPTEMP CURSOR FOR SELECT EMPNO, LASTNAME, WORKDEPT FROM CORPDATA.EMPLOYEE WHERE EMPNO = '000190' GROUP BY EMPNO, LASTNAME, WORKDEPT

OPNQRYF example:
OPNQRYF FILE(EMPLOYEE) FORMAT(FORMAT1) QRYSLT('EMPNO *EQ ''000190''') GRPFLD(EMPNO LASTNAME WORKDEPT)

In this example, the optimizer can remove EMPNO from the list of grouping elds because of the EMPNO = '000190' selection predicate. An index that only has LASTNAME and WORKDEPT specied as key elds can be considered to implement the query and if a temporary index or hash is required then EMPNO will not be used. Note: Even though EMPNO can be removed from the list of grouping columns, the optimizer might still choose to use that index if a permanent index exists with all three grouping columns.

Adding Additional Grouping Columns


The same logic that is applied to removing grouping columns can also be used to add additional grouping columns to the query. This is only done when you are trying to determine if an index can be used to implement the grouping. The following example illustrates a query where the optimizer could add an additional grouping column. | | | | | | | | | |
CREATE INDEX X1 ON EMPLOYEE (LASTNAME, EMPNO, WORKDEPT) DECLARE DEPTEMP CURSOR FOR SELECT LASTNAME, WORKDEPT FROM CORPDATA.EMPLOYEE WHERE EMPNO = '000190' GROUP BY LASTNAME, WORKDEPT

444

DB2 UDB for AS/400 SQL Programming V4R4

OPNQRYF example:
OPNQRYF FILE ((EMPLOYEE)) FORMAT(FORMAT1) QRYSLT('EMPNO *EQ ''000190''') GRPFLD(LASTNAME WORKDEPT)

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

For this query request, the optimizer can add EMPNO as an additional grouping column when considering X1 for the query.

Grouping using Index Skip Key Processing


Index Skip Key processing can be used when grouping with the keyed sequence implementation algorithm which uses an existing index. The index skip key processing algorithm: 1. Uses the index to position to a group and 2. nds the rst record matching the selection criteria for the group, and if specied the rst non-null MIN or MAX value in the group 3. Returns the group to the user 4. Skip to the next group and repeat processing This will improve performance by potentially not processing all index key values for a group. Index skip key processing can be used: v For single le queries using the keyed sequence grouping implementation when: There are no column functions in the query, or There is only a single MIN or MAX column function in the query and the operand of the MIN or MAX is the next key eld in the index after the grouping elds. There can be no other grouping functions in the query. For the MIN function, the key eld must be an ascending key; for the MAX function, the key eld must be a descending key. If the query is whole le grouping, the operand of the MIN or MAX must be the rst key eld. Example 1, using SQL:
CREATE INDEX IX1 ON EMPLOYEE (SALARY DESC) DECLARE C1 CURSOR FOR SELECT MAX(SALARY) FROM EMPLOYEE;

Example 1, using the OPNQRYF command:


OPNQRYF FILE(EMPLOYEE) FORMAT(FORMAT1) MAPFLD((MAXSAL '%MAX(SALARY)'))

The query optimizer will chose to use the index IX1. The SLIC runtime code will scan the index until it nds the rst non-null value for SALARY. Assuming that SALARY is not null, the runtime code will position to the rst index key and return that key value as the MAX of salary. No more index keys will be processed. Example 2, using SQL:
CREATE INDEX IX2 ON EMPLOYEE (DEPT, JOB,SALARY) DECLARE C1 CURSOR FOR SELECT DEPT, MIN(SALARY) FROM EMPLOYEE WHERE JOB='CLERK' GROUP BY DEPT

Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

445

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

Example 2, using the OPNQRYF command:


OPNQRYF FILE(EMPLOYEE) FORMAT(FORMAT2) QRYSLT('JOB *EQ ''CLERK''') GRPFLD((DEPT)) MAPFLD((MINSAL '%MIN(SALARY)'))

The query optimizer will chose to use Index IX2. The SLIC runtime code will position to the rst group for DEPT where JOB equals CLERK and will return the SALARY. The code will then skip to the next DEPT group where JOB equals CLERK. v For join queries: All grouping columns must be from a single le. For each dial there can be at most one MIN or MAX column function operand that references the dial and no other column functions can exist in the query. If the MIN or MAX function operand is from the same dial as the grouping columns, then it uses the same rules as single le queries. If the MIN or MAX function operand is from a different dial then the join eld for that dial must join to one of the grouping elds and the index for that dial must contain the join elds followed by the MIN or MAX operand. Example 1, using SQL:
CREATE INDEX IX1 ON DEPARTMENT(DEPTNAME) CREATE INDEX IX2 ON EMPLOYEE(WORKDEPT, SALARY) DECLARE C1 CURSOR FOR SELECT DEPTNAME, MIN(SALARY) FROM DEPARTMENT, EMPLOYEE WHERE DEPARTMENT.DEPTNO=EMPLOYEE.WORKDEPT GROUP BY DEPARTMENT.DEPTNO;

Example 1, using the OPNQRYF command:


OPNQRYF FILE(DEPARTMENT EMPLOYEE) FORMAT(FORMAT1) JFLD((1/DEPTNO 2/WORKDEPT *EQ)) GRPFLD((1/DEPTNO)) MAPFLD((MINSAL '%MIN(SALARY)'))

Effectively Using SQL Indexes


DB2 UDB for AS/400 provides two basic means for accessing tables: a table scan (sequential) and an index-based (direct) retrieval. Index-based retrieval is usually more efficient than table scan. However, when a very large percentage of pages are retrieved, table scan is more efficient than index-based retrieval. If DB2 UDB for AS/400 cannot use an index to access the data in a table, it will have to read all the data in the table. Very large tables present a special performance problem: the high cost of retrieving all the data in the table. The following suggestions help you to design code that allows DB2 UDB for AS/400 to take advantage of available indexes. 1. Avoid numeric conversions. When a column value and a host variable (or literal value) are being compared, try to specify the same data types and attributes. DB2 UDB for AS/400 does not use an index for the named column if the host variable or literal value has a greater precision than the precision of the column. If the two items being compared have different data types, DB2 UDB for AS/400 will have to convert

| | | | |

446

DB2 UDB for AS/400 SQL Programming V4R4

| | | | | | | | | | |

one or the other of the values, which can result in inaccuracies (because of limited machine precision). To avoid problems for columns and constants being compared, use the: v same data type v same scale, if applicable v same precision, if applicable For example, EDUCLVL is a halfword integer value (SMALLINT). When using SQL, specify:
... WHERE EDUCLVL < 11 AND EDUCLVL >= 2

instead of
... WHERE EDUCLVL < 1.1E1 AND EDUCLVL > 1.3

| | | | |

When using the OPNQRYF command, specify:


... QRYSLT('EDUCLVL *LT 11 *AND ENUCLVL *GE 2')

instead of
... QRYSLT('EDUCLVL *LT 1.1E1 *AND EDUCLVL *GT 1.3')

| | | | | | | | | | |

If an index was created over the EDUCLVL column, then the optimizer does not use the index in the second example because the precision of the constant is greater than the precision of the column. In the rst example, the optimizer considers using the index, because the precisions are equal. 2. Avoid arithmetic expressions You should never have an arithmetic expression as an operand to be compared to a column in a row selection predicate. The optimizer does not use an index on a eld that is being compared to an arithmetic expression. When using SQL, specify:
... WHERE SALARY > 16500

instead of
... WHERE SALARY > 15000*1.1

3. Avoid character string padding. Try to use the same data length when comparing a xed-length character string column value to a host variable or literal value. DB2 UDB for AS/400 does not use an index if the literal value or host variable is longer than the column length. For example, EMPNO is CHAR(6) and DEPTNO is CHAR(3). Specify:
... WHERE EMPNO > '000300' AND DEPTNO < 'E20'

| | | |

instead of
... WHERE EMPNO > '000300 ' AND DEPTNO < 'E20 '

When using the OPNQRYF command, specify:


... QRYSLT('EMPNO *GT "000300" *AND DEPTNO *LT "E20"')

instead of
... QRYSLT('EMPNO *GT "000300" *AND DEPTNO *LT "E20"')
Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

447

4. Avoid the use of like patterns beginning with % or _. The percent sign (%), and the underline (_), when used in the pattern of a LIKE (OPNQRYF %WLDCRD) predicate, specify a character string that is similar to the column value of rows you want to select. They can take advantage of indexes when used to denote characters in the middle or at the end of a character string, as in the following. When using SQL:
... WHERE LASTNAME LIKE 'J%SON%'

When using the OPNQRYF command, specify:


... QRYSLT('LASTNAME *EQ WLDCRD(''J*SON*'')')

However, when used at the beginning of a character string, they can prevent DB2 UDB for AS/400 from using any indexes that might be dened on the LASTNAME column to limit the number of rows scanned. When using SQL:
... WHERE LASTNAME LIKE '%SON'

When using the OPNQRYF command, specify:


... QRYSLT('LASTNAME *EQ WLDCRD(''*SON'')')

You should therefore avoid using these symbols at the beginning of character strings, especially if you are accessing a particularly large table. 5. Be aware that DB2 UDB for AS/400 does not use an index in the following instances: v For a column that is expected to be updated; for example, your program might include
EXEC SQL DECLARE DEPTEMP CURSOR FOR SELECT EMPNO, LASTNAME, WORKDEPT FROM CORPDATA.EMPLOYEE WHERE (WORKDEPT = 'D11' OR WORKDEPT = 'D21') AND EMPNO = '000190' FOR UPDATE OF EMPNO, WORKDEPT END-EXEC.

OPNQRYF example:
OPNQRYF FILE((CORPDATA/EMPLOYEE)) OPTION(*ALL) QRYSLT('(WORKDEPT *EQ ''D11'' *OR WORKDEPT *EQ ''D21'') *AND EMPNO *EQ ''000190''')

Even if you do not intend to update the employees department, DB2 UDB for AS/400 cannot use an index with a key of WORKDEPT. DB2 UDB for AS/400 can use an index if all of the updateable columns used within the index are also used within the query as an isolatable selection predicate with an equal operator. In the previous example DB2 UDB for AS/400 would use an index with a key of EMPNO. DB2 UDB for AS/400 can operate more efficiently if the FOR UPDATE OF column list only names the column you intend to update: WORKDEPT. Therefore, do not specify a column in the FOR UPDATE OF column list unless you intend to update the column. If you have an updateable cursor because of dynamic SQL or the FOR UPDATE clause was not specied and the program contains an UPDATE statement then all columns can be updated.

448

DB2 UDB for AS/400 SQL Programming V4R4

v For a column being compared with another column from the same row. For example:
EXEC SQL DECLARE DEPTDATA CURSOR FOR SELECT WORKDEPT, DEPTNAME FROM CORPDATA.EMPLOYEE WHERE WORKDEPT = ADMRDEPT END-EXEC.

OPNQRYF example:
OPNQRYF FILE (EMPLOYEE) FORMAT(FORMAT1) QRYSLT('WORKDEPT *EQ ADMRDEPT')

Even though there is an index for WORKDEPT and another index for ADMRDEPT, DB2 UDB for AS/400 will not use either index. The index has no added benet because every row of the table needs to be looked at.

Using Indexes With Sort Sequence


The following sections provide useful information about how indexes work with sort sequence tables. For more information on how Sort Sequence tables work, see the DB2 UDB for AS/400 SQL Reference book.

Using Indexes and Sort Sequence With Selection, Joins, or Grouping


Before using an existing index, DB2 UDB for AS/400 ensures the attributes of the columns (selection, join, or grouping columns) match the attributes of the key elds in the existing index. The sort sequence table is an additional attribute that must be compared. The sort sequence table associated with the query (specied by the SRTSEQ and LANGID parameters) must match the sort sequence table with which the existing index was built. DB2 UDB for AS/400 compares the sort sequence tables. If they do not match, the existing index cannot be used. There is an exception to this, however. If the sort sequence table associated with the query is a unique-weight sequence table (including *HEX), DB2 UDB for AS/400 acts as though no sort sequence table is specied for selection, join, or grouping columns that use the following operators and predicates: v v v v equal (=) operator not equal (|= or <>) operator LIKE predicate (OPNQRYF %WLDCRD and *CT) IN predicate (OPNQRYF %VALUES)

| |

When these conditions are true, DB2 UDB for AS/400 is free to use any existing index where the key elds match the columns and either: v The index does not contain a sort sequence table or v The index contains a unique-weight sort sequence table Note: The table does not have to match the unique-weight sort sequence table associated with the query. Note: Bitmap processing has a special consideration when multiple indexes are used for a table. If two or more indexes have a common key eld between
Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

449

them that is also referenced in the query selection, then those indexes must either use the same sort sequence table or use no sort sequence table.

Ordering
Unless the optimizer chooses to do a sort to satisfy the ordering request, the sort sequence table associated with the index must match the sort sequence table associated with the query. When a sort is used, the translation is done during the sort. Since the sort is handling the sort sequence requirement, this allows DB2 UDB for AS/400 to use any existing index that meets the selection criteria.

Example Indexes
For the purposes of the examples, assume three indexes are created. Assume an index HEXIX was created with *HEX as the sort sequence.
CREATE INDEX HEXIX ON STAFF (JOB)

Assume an index UNQIX was created with a unique-weight sort sequence.


CREATE INDEX UNQIX ON STAFF (JOB)

Assume an index SHRIX was created with a shared-weight sort sequence.


CREATE INDEX SHRIX ON STAFF (JOB)

Example 1
Equals selection with no sort sequence table (SRTSEQ(*HEX)).
SELECT * FROM STAFF WHERE JOB = 'MGR'

When using the OPNQRYF command, specify:


OPNQRYF FILE((STAFF)) QRYSLT('JOB *EQ ''MGR''') SRTSEQ(*HEX)

DB2 UDB for AS/400 could use either index HEXIX or index UNQIX.

Example 2
Equals selection with a unique-weight sort sequence table (SRTSEQ(*LANGIDUNQ) LANGID(ENU)).
SELECT * FROM STAFF WHERE JOB = 'MGR'

| | | | |

When using the OPNQRYF command, specify:


OPNQRYF FILE((STAFF)) QRYSLT('JOB *EQ ''MGR''') SRTSEQ(*LANGIDUNQ) LANGID(ENU)

DB2 UDB for AS/400 could use either index HEXIX or index UNQIX.

450

DB2 UDB for AS/400 SQL Programming V4R4

Example 3
Equal selection with a shared-weight sort sequence table (SRTSEQ(*LANGIDSHR) LANGID(ENU)).
SELECT * FROM STAFF WHERE JOB = 'MGR'

| | | | |

When using the OPNQRYF command, specify:


OPNQRYF FILE((STAFF)) QRYSLT('JOB *EQ ''MGR''') SRTSEQ(*LANGIDSHR) LANGID(ENU)

DB2 UDB for AS/400 could only use index SHRIX.

Example 4
Greater than selection with a unique-weight sort sequence table (SRTSEQ(*LANGIDUNQ) LANGID(ENU)).
SELECT * FROM STAFF WHERE JOB > 'MGR'

| | | | |

When using the OPNQRYF command, specify:


OPNQRYF FILE((STAFF)) QRYSLT('JOB *GT ''MGR''') SRTSEQ(*LANGIDUNQ) LANGID(ENU)

DB2 UDB for AS/400 could only use index UNQIX.

Example 5
Join selection with a unique-weight sort sequence table (SRTSEQ(*LANGIDUNQ) LANGID(ENU)).
SELECT * FROM STAFF S1, STAFF S2 WHERE S1.JOB = S2.JOB

or the same query using the JOIN syntax.


SELECT * FROM STAFF S1 INNER JOIN STAFF S2 ON S1.JOB = S2.JOB

| | | | | |

When using the OPNQRYF command, specify:


OPNQRYF FILE(STAFF STAFF) FORMAT(FORMAT1) JFLD((1/JOB 2/JOB *EQ)) SRTSEQ(*LANGIDUNQ) LANGID(ENU)

DB2 UDB for AS/400 could use either index HEXIX or index UNQIX for either query.

Example 6
Join selection with a shared-weight sort sequence table (SRTSEQ(*LANGIDSHR) LANGID(ENU)).
SELECT * FROM STAFF S1, STAFF S2 WHERE S1.JOB = S2.JOB

or the same query using the JOIN syntax.


Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

451

SELECT * FROM STAFF S1 INNER JOIN STAFF S2 ON S1.JOB = S2.JOB

| | | | |

When using the OPNQRYF command, specify:


OPNQRYF FILE(STAFF STAFF) FORMAT(FORMAT1) JFLD((1/JOB 2/JOB *EQ)) SRTSEQ(*LANGIDSHR) LANGID(ENU)

DB2 UDB for AS/400 could only use index SHRIX for either query.

Example 7
Ordering with no sort sequence table (SRTSEQ(*HEX)).
SELECT * FROM STAFF WHERE JOB = 'MGR' ORDER BY JOB

| | | | | |

When using the OPNQRYF command, specify:


OPNQRYF FILE((STAFF)) QRYSLT('JOB *EQ ''MGR''') KEYFLD(JOB) SRTSEQ(*HEX)

DB2 UDB for AS/400 could only use index HEXIX.

Example 8
Ordering with a unique-weight sort sequence table (SRTSEQ(*LANGIDUNQ) LANGID(ENU)).
SELECT * FROM STAFF WHERE JOB = 'MGR' ORDER BY JOB

| | | | |

When using the OPNQRYF command, specify:


OPNQRYF FILE((STAFF)) QRYSLT('JOB *EQ ''MGR''') KEYFLD(JOB) SRTSEQ(*LANGIDUNQ) LANGID(ENU)

DB2 UDB for AS/400 could only use index UNQIX.

Example 9
Ordering with a shared-weight sort sequence table (SRTSEQ(*LANGIDSHR) LANGID(ENU)).
SELECT * FROM STAFF WHERE JOB = 'MGR' ORDER BY JOB

| | | | |

When using the OPNQRYF command, specify:


OPNQRYF FILE((STAFF)) QRYSLT('JOB *EQ ''MGR''') KEYFLD(JOB) SRTSEQ(*LANGIDSHR) LANGID(ENU)

DB2 UDB for AS/400 could only use index SHRIX.

452

DB2 UDB for AS/400 SQL Programming V4R4

Example 10
Ordering with ALWCPYDTA(*OPTIMIZE) and a unique-weight sort sequence table (SRTSEQ(*LANGIDUNQ) LANGID(ENU)).
SELECT * FROM STAFF WHERE JOB = 'MGR' ORDER BY JOB

| | | | | | |

When using the OPNQRYF command, specify:


OPNQRYF FILE((STAFF)) QRYSLT('JOB *EQ ''MGR''') KEYFLD(JOB) SRTSEQ(*LANGIDUNQ) LANGID(ENU) ALWCPYDTA(*OPTIMIZE)

DB2 UDB for AS/400 could use either index HEXIX or index UNQIX for selection. Ordering would be done during the sort using the *LANGIDUNQ sort sequence table.

Example 11
Grouping with no sort sequence table (SRTSEQ(*HEX)).
SELECT JOB FROM STAFF GROUP BY JOB

| | | | |

When using the OPNQRYF command, specify:


OPNQRYF FILE((STAFF)) FORMAT(FORMAT2) GRPFLD((JOB)) SRTSEQ(*HEX)

DB2 UDB for AS/400 could use either index HEXIX or index UNQIX.

Example 12
Grouping with a unique-weight sort sequence table (SRTSEQ(*LANGIDUNQ) LANGID(ENU)).
SELECT JOB FROM STAFF GROUP BY JOB

| | | | |

When using the OPNQRYF command, specify:


OPNQRYF FILE((STAFF)) FORMAT(FORMAT2) GRPFLD((JOB)) SRTSEQ(*LANGIDUNQ) LANGID(ENU)

DB2 UDB for AS/400 could use either index HEXIX or index UNQIX.

Example 13
Grouping with a shared-weight sort sequence table (SRTSEQ(*LANGIDSHR) LANGID(ENU)).
SELECT JOB FROM STAFF GROUP BY JOB

| | | |

When using the OPNQRYF command, specify:


OPNQRYF FILE((STAFF)) FORMAT(FORMAT2) GRPFLD((JOB)) SRTSEQ(*LANGIDSHR) LANGID(ENU)

Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

453

DB2 UDB for AS/400 could only use index SHRIX. The following examples assume 3 more indexes are created over columns JOB and SALARY. The CREATE INDEX statements precede the examples. Assume an index HEXIX2 was created with *HEX as the sort sequence.
CREATE INDEX HEXIX2 ON STAFF (JOB, SALARY)

Assume an index UNQIX2 was created and the sort sequence is a unique-weight sort sequence.
CREATE INDEX UNQIX2 ON STAFF (JOB, SALARY)

Assume an index SHRIX2 was created with a shared-weight sort sequence.


CREATE INDEX SHRIX2 ON STAFF (JOB, SALARY)

Example 14
Ordering and grouping on the same columns with a unique-weight sort sequence table (SRTSEQ(*LANGIDUNQ) LANGID(ENU)).
SELECT JOB, SALARY FROM STAFF GROUP BY JOB, SALARY ORDER BY JOB, SALARY

| | | | | |

When using the OPNQRYF command, specify:


OPNQRYF FILE((STAFF)) FORMAT(FORMAT3) GRPFLD(JOB SALARY) KEYFLD(JOB SALARY) SRTSEQ(*LANGIDUNQ) LANGID(ENU)

DB2 UDB for AS/400 could use UNQIX2 to satisfy both the grouping and ordering requirements. If index UNQIX2 did not exist, DB2 UDB for AS/400 would create an index using a sort sequence table of *LANGIDUNQ.

Example 15
Ordering and grouping on the same columns with ALWCPYDTA(*OPTIMIZE) and a unique-weight sort sequence table (SRTSEQ(*LANGIDUNQ) LANGID(ENU)).
SELECT JOB, SALARY FROM STAFF GROUP BY JOB, SALARY ORDER BY JOB, SALARY

| | | | | | |

When using the OPNQRYF command, specify:


OPNQRYF FILE((STAFF)) FORMAT(FORMAT3) GRPFLD(JOB SALARY) KEYFLD(JOB SALARY) SRTSEQ(*LANGIDUNQ) LANGID(ENU) ALWCPYDTA(*OPTIMIZE)

DB2 UDB for AS/400 could use UNQIX2 to satisfy both the grouping and ordering requirements. If index UNQIX2 did not exist, DB2 UDB for AS/400 would either: v Create an index using a sort sequence table of *LANGIDUNQ or v Use index HEXIX2 to satisfy the grouping and to perform a sort to satisfy the ordering

454

DB2 UDB for AS/400 SQL Programming V4R4

Example 16
Ordering and grouping on the same columns with a shared-weight sort sequence table (SRTSEQ(*LANGIDSHR) LANGID(ENU)).
SELECT JOB, SALARY FROM STAFF GROUP BY JOB, SALARY ORDER BY JOB, SALARY

| | | | | |

When using the OPNQRYF command, specify:


OPNQRYF FILE((STAFF)) FORMAT(FORMAT3) GRPFLD(JOB SALARY) KEYFLD(JOB SALARY) SRTSEQ(*LANGIDSHR) LANGID(ENU)

DB2 UDB for AS/400 could use SHRIX2 to satisfy both the grouping and ordering requirements. If index SHRIX2 did not exist, DB2 UDB for AS/400 would create an index using a sort sequence table of *LANGIDSHR.

Example 17
Ordering and grouping on the same columns with ALWCPYDTA(*OPTIMIZE) and a shared-weight sort sequence table (SRTSEQ(*LANGIDSHR) LANGID(ENU).
SELECT JOB, SALARY FROM STAFF GROUP BY JOB, SALARY ORDER BY JOB, SALARY

| | | | | | |

When using the OPNQRYF command, specify:


OPNQRYF FILE((STAFF)) FORMAT(FORMAT3) GRPFLD(JOB SALARY) KEYFLD(JOB SALARY) SRTSEQ(*LANGIDSHR) LANGID(ENU) ALWCPYDTA(*OPTIMIZE)

DB2 UDB for AS/400 could use SHRIX2 to satisfy both the grouping and ordering requirements. If index SHRIX2 did not exist, DB2 UDB for AS/400 would create an index using a sort sequence table of *LANGIDSHR.

Example 18
Ordering and grouping on different columns with a unique-weight sort sequence table (SRTSEQ(LANGIDUNQ) LANGID(ENU)).
SELECT JOB, SALARY FROM STAFF GROUP BY JOB, SALARY ORDER BY SALARY, JOB

| | | | | |

When using the OPNQRYF command, specify:


OPNQRYF FILE((STAFF)) FORMAT(FORMAT3) GRPFLD(JOB SALARY) KEYFLD(SALARY JOB) SRTSEQ(*LANGIDSHR) LANGID(ENU)

DB2 UDB for AS/400 could use index HEXIX2 or index UNQIX2 to satisfy the grouping requirements. A temporary result would be created containing the grouping results. A temporary index would then be built over the temporary result using a *LANGIDUNQ sort sequence table to satisfy the ordering requirements.

Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

455

Example 19
Ordering and grouping on different columns with ALWCPYDTA(*OPTIMIZE) and a unique-weight sort sequence table (SRTSEQ(*LANGIDUNQ) LANGID(ENU)).
SELECT JOB, SALARY FROM STAFF GROUP BY JOB, SALARY ORDER BY SALARY, JOB

| | | | | | |

When using the OPNQRYF command, specify:


OPNQRYF FILE((STAFF)) FORMAT(FORMAT3) GRPFLD(JOB SALARY) KEYFLD(SALARY JOB) SRTSEQ(*LANGIDUNQ) LANGID(ENU) ALWCPYDTA(*OPTIMIZE)

DB2 UDB for AS/400 could use index HEXIX2 or index UNQIX2 to satisfy the grouping requirements. A sort would be performed to satisfy the ordering requirements.

Example 20
Ordering and grouping on different columns with ALWCPYDTA(*OPTIMIZE) and a shared-weight sort sequence table (SRTSEQ(*LANGIDSHR) LANGID(ENU)).
SELECT JOB, SALARY FROM STAFF GROUP BY JOB, SALARY ORDER BY SALARY, JOB

| | | | | | |

When using the OPNQRYF command, specify:


OPNQRYF FILE((STAFF)) FORMAT(FORMAT3) GRPFLD(JOB SALARY) KEYFLD(SALARY JOB) SRTSEQ(*LANGIDSHR) LANGID(ENU) ALWCPYDTA(*OPTIMIZE)

DB2 UDB for AS/400 could use index SHRIX2 to satisfy the grouping requirements. A sort would be performed to satisfy the ordering requirements.

Tips for using VARCHAR and VARGRAPHIC data types


Variable-length column (VARCHAR or VARGRAPHIC) support allows you to dene any number of columns in a table as variable length. If you use VARCHAR or VARGRAPHIC support, the size of a table can usually be reduced. Data in a variable-length column is stored internally in two areas: a xed-length or ALLOCATE area and an overow area. If a default value is specied, the allocated length is at least as large as the value. The following points help you determine the best way to use your storage area. When you dene a table with variable-length data, you must decide the width of the ALLOCATE area. If the primary goal is: v Space saving: use ALLOCATE(0). v Performance: the ALLOCATE area should be wide enough to incorporate at least 90% to 95% of the values for the column. It is possible to balance space savings and performance. In the following example of an electronic phone book, the following data is used:

456

DB2 UDB for AS/400 SQL Programming V4R4

v 8600 names identied by: last, rst, and middle name v The Last, First, and Middle columns are variable length. v The shortest last name is 2 characters; the longest is 22 characters. This example shows how space can be saved by using variable-length columns. The xed-length column table uses the most space. The table with the carefully calculated allocate sizes uses less disk space. The table that was dened with no allocate size (with all of the data stored in the overow area) uses the least disk space.
Number of Total Records in Middle Name Physical File Overow Max/Alloc Size Space 22 40/7 40/0 567 K 408 K 373 K 0 73 8600

Variety of Support Fixed Length Variable Length VariableLength Default

Last Name Max/Alloc 22 40/10 40/0

First Name Max/Alloc 22 40/10 40/0

In many applications performance must be considered. If you use the default ALLOCATE(0), it will double the disk unit traffic. ALLOCATE(0) requires two reads; one to read the xed-length portion of the row and one to read the overow space. The variable-length implementation, with the carefully chosen ALLOCATE, minimizes overow and space and maximizes performance. The size of the physical le is 28% smaller than the xed-length implementation. Because 1% of rows are in the overow area, the access requiring two reads is minimized. The variable-length implementation performs about the same as the xed-length implementation. To create the table using the ALLOCATE keyword:
CREATE TABLE PHONEDIR (LAST VARCHAR(40) ALLOCATE(10), FIRST VARCHAR(40) ALLOCATE(10), MIDDLE VARCHAR(40) ALLOCATE(7))

If you are using host variables to insert or update variable-length columns, the host variables should be variable length. Because blanks are not truncated from xed-length host variables, using xed-length host variables would cause more rows to spill into the overow space. This would increase the size of the table. In this example, xed-length host variables are used to insert a row into a table:
01 LAST-NAME PIC X(40). ... MOVE "SMITH" TO LAST-NAME. EXEC SQL INSERT INTO PHONEDIR VALUES(:LAST-NAME, :FIRST-NAME, :MIDDLE-NAME, :PHONE) END-EXEC.

The host-variable LAST-NAME is not variable length. The string SMITH, followed by 35 blanks, is inserted into the VARCHAR column LAST. The value is longer than the allocate size of 10. Thirty of thirty-ve trailing blanks are in the overow area. In this example, variable-length host variables are used to insert a row into a table:

Chapter 24. DB2 UDB for AS/400 Data Management and Query Optimizer Tips

457

01

VLAST-NAME. 49 LAST-NAME-LEN PIC S9(4) BINARY. 49 LAST-NAME-DATA PIC X(40). ... MOVE "SMITH" TO LAST-NAME-DATA. MOVE 5 TO LAST-NAME-LEN. EXEC SQL INSERT INTO PHONEDIR VALUES(:VLAST-NAME, :VFIRST-NAME, :VMIDDLE-NAME, :PHONE) END-EXEC.

The host variable VLAST-NAME is variable length. The actual length of the data is set to 5. The value is shorter than the allocated length. It can be placed in the xed portion of the column. For more information about using variable-length host variables, see Chapter 12. Coding SQL Statements in C and C++ Applications, through Chapter 17. Coding SQL Statements in REXX Applications. Running the RGZPFM command against tables that contain variable-length columns can improve performance. The fragments in the overow area that are not in use are compacted by the RGZPFM command. This reduces the read time for rows that overow, increases the locality of reference, and produces optimal order for serial batch processing. Choose the appropriate maximum length for variable-length columns. Selecting lengths that are too long increases the process access group (PAG). A large PAG slows performance. A large maximum length makes SEQONLY(*YES) less effective. Variable-length columns longer than 2000 bytes are not eligible as key columns.

458

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 25. Additional SQL performance considerations


The SQL data manipulation language statements must do database open operations in order to create an open data path (ODP) to the data. An open data path is the path through which all input/output operations for the le are performed. In a sense, it connects the SQL application to a le. The number of open operations in a program can signicantly affect performance. A database open operation occurs on: v An OPEN statement v SELECT INTO statement v An INSERT statement with a VALUES clause v An UPDATE statement with a WHERE condition v An UPDATE statement with a WHERE CURRENT OF cursor and SET clauses that refer to operators or functions v A DELETE statement with a WHERE condition An INSERT statement with a select-statement requires two open operations. Certain forms of subqueries may also require one open per subselect. To minimize the number of opens, DB2 UDB for AS/400 leaves the open data path (ODP) open and reuses the ODP if the statement is run again, unless: v GROUP BY contains columns from more than one table. v The ODP used a host variable to build a subset temporary index. The OS/400 database support may choose to build a temporary index with entries for only the rows that match the row selection specied in the SQL statement. If a host variable was used in the row selection, the temporary index will not have the entries required for a different value contained in the host variable. v Ordering was specied on a host variable value. v A host variable is used to specify the pattern of a LIKE predicate. The host variable value has either underscores (_) or involves more than one search pattern: for %ABC%DEF, two patterns are involved, ABC and DEF. v An Override Database File (OVRDBF) or Delete Override (DLTOVR) CL command has been issued since the ODP was opened, which would affect the SQL statement execution. Note: Only overrides that affect the name of the table being referred to will cause the ODP to be closed within a given program invocation. A change to the library list since the last open has occurred, which would change the le selected by an unqualied referral in system naming mode. The le being queried is a join logical le and its join type (JDFTVAL) does not match the join type specied in the query. The format specied for a logical le references more than one physical le. The le is a complex SQL view that requires a temporary le to contain the results of the SQL view.

v v v v

DB2 UDB for AS/400 only reuses ODPs opened by the same statement. An identical statement coded later in the program does not reuse an ODP from any other statement. If the identical statement must be run in the program many times, code it once in a subroutine and call the subroutine to run the statement.

Copyright IBM Corp. 1997, 1999

459

The ODPs opened by DB2 UDB for AS/400 are closed when any of the following occurs: v A CLOSE, INSERT, UPDATE, DELETE, or SELECT INTO statement completes and the ODP required a temporary result or a subset temporary index. v The Reclaim Resources (RCLRSC) command is issued. A RCLRSC is issued when the rst COBOL program on the call stack ends or when a COBOL program issues the STOP RUN COBOL statement. RCLRSC will not close ODPs created for programs precompiled using CLOSQLCSR(*ENDJOB). For interaction of RCLRSC with non-default activation groups, see the following books: ILE C for AS/400 Programmers Guide ILE COBOL for AS/400 Programmers Guide ILE RPG for AS/400 Programmers Guide v When the last program that contains SQL statements on the call stack exits, except for ODPs created for programs precompiled using CLOSQLCSR(*ENDJOB) or modules precompiled using CLOSQLCSR(*ENDACTGRP). v When a CONNECT (Type 1) statement changes the application server for an activation group, all ODPs created for the activation group are closed. v When a DISCONNECT statement ends a connection to the application server, all ODPs for that application server are closed. v When a released connection is ended by a successful COMMIT, all ODPs for that application server are closed. You can control whether DB2 UDB for AS/400 keeps the ODPs open by: v Designing the application so a program that issues an SQL statement is always on the call stack v Using the CLOSQLCSR(*ENDJOB) or CLOSQLCSR(*ENDACTGRP) parameter DB2 UDB for AS/400 does an open operation for the rst execution of each UPDATE WHERE CURRENT OF when any expression in the SET clause contains an operator or function. The open can be avoided by coding the function or operation in the host language code. For example, the following UPDATE causes DB2 UDB for AS/400 to do an open operation:
EXEC SQL FETCH EMPT INTO :SALARY END-EXEC. EXEC SQL UPDATE CORPDATA.EMPLOYEE SET SALARY = :SALARY + 1000 WHERE CURRENT OF EMPT END-EXEC.

Instead, use the following coding technique to avoid opens:


EXEC SQL FETCH EMPT INTO :SALARY END EXEC. ADD 1000 TO SALARY. EXEC SQL

460

DB2 UDB for AS/400 SQL Programming V4R4

UPDATE CORPDATA.EMPLOYEE SET SALARY = :SALARY WHERE CURRENT OF EMPT END-EXEC.

The CL commands Trace Job (TRCJOB) or Display Journal (DSPJRN) can be used to determine the number of opens being performed by an SQL statement.

Improving Performance by Using Database Manager Blocking Considerations


To improve performance, the SQL run-time attempts to retrieve and insert records from the database manager a block at a time whenever possible. You can control blocking, if desired, by using the SEQONLY parameter on the CL command Override Database File (OVRDBF) prior to calling the application program that contains the SQL statements or by specifying the ALWBLK parameter on the CRTSQLxxx commands. The database manager does not allow blocking in the following situations: v The cursor is update or delete capable. v The length of the row plus the feedback information is greater than 32767. The minimum size for the feedback information is 11 bytes. The feedback size is increased by the number of bytes in the key elds for the index used by the cursor and by the number of key elds, if any, that are null capable. v COMMIT(*CS) is specied and ALWBLK(*ALLREAD) is not specied. v COMMIT(*ALL) is specied and the following are true: A SELECT INTO statement or a blocked FETCH statement is not used The query does not use column functions or specify group by columns. A temporary result table does not have to be created. v COMMIT(*CHG) is specied and ALWBLK(*ALLREAD) is not specied. v The cursor contains at least one subquery and the outermost subselect provided a correlated reference for a subquery or the outermost subselect processed a subquery with an IN, = ANY, or < > ALL subquery predicate operator, which is treated as a correlated reference. The SQL run-time automatically blocks records with the database manager in the following cases: v INSERT If an INSERT statement contains a select-statement, inserted records are blocked and not actually inserted into the target table until the block is full. The SQL run-time automatically does blocking for blocked inserts. Note: If an INSERT with a VALUES clause is specied, the SQL run-time might not actually close the internal cursor used to perform the inserts until the program ends. If the same INSERT statement is run again, a full open is not necessary and the application runs much faster. v OPEN Blocking is done under the OPEN statement when the records are retrieved if all of the following conditions are true: The cursor is only used for FETCH statements. No EXECUTE or EXECUTE IMMEDIATE statements are in the program, or ALWBLK(*ALLREAD) was specied, or the cursor is declared with the FOR FETCH ONLY clause.
Chapter 25. Additional SQL performance considerations

461

COMMIT(*CHG) and ALWBLK(*ALLREAD) are specied, COMMIT(*CS) and ALWBLK(*ALLREAD) are specied, or COMMIT(*NONE) is specied.

Improving Performance Using FETCH FOR n ROWS


Applications that perform many FETCH statements in succession may be improved by using FETCH FOR n ROWS. With this clause, you can retrieve multiple rows of data from a table and put them into a host structure array or row storage area with a single FETCH. For more information on declaring arrays of host structures or row storage areas, see the DB2 UDB for AS/400 SQL Reference book or the individual programming chapters. An SQL application that uses a FETCH statement, without the FOR n ROWS clause, can be improved by using the multiple-row FETCH statement to retrieve multiple rows. After the host structure array or row storage area has been lled by the FETCH, the application can loop through the data in the array or storage area to process each of the individual records. The statement runs faster because the SQL run-time was called only once and all the data was simultaneously returned to the application program. You can change the application program to allow the database manager to block the records that the SQL run-time retrieves from the tables. For more information, see Improving Performance by Using Database Manager Blocking Considerations on page 461. In the following table, the program attempted to FETCH 100 rows into the application. Note the differences in the table for the number of calls to SQL run-time and the database manager when blocking can be performed.
Table 40. Number of Calls Using a FETCH Statement
Database Manager Not Using Database Manager Using Blocking Blocking Single-Row FETCH Statement Multiple-Row FETCH Statement 100 SQL calls 100 database calls 1 SQL run-time call 100 database calls 100 SQL calls 1 database call 1 SQL run-time call 1 database call

Improving Performance with SQL Blocking


Special performance considerations should be made for the following points when using FETCH FOR n ROWS. You can improve SQL blocking performance with the following: v The attribute information in the host structure array or the descriptor associated with the row storage area matches the attributes of the columns retrieved. v The application should retrieve as many rows as possible with a single multiple-row FETCH call. The blocking factor for a multiple-row FETCH request is not controlled by the system page sizes or the SEQONLY parameter on the OVRDBF command. It is controlled by the number of rows requested on the multiple-row FETCH request. v Do not mix single- and multiple-row FETCH requests against the same cursor within a program. If one FETCH against a cursor is treated as a multiple-row

462

DB2 UDB for AS/400 SQL Programming V4R4

FETCH, all fetches against that cursor are treated as multiple-row fetches. In that case, each of the single-row FETCH requests would be treated as a multiple-row FETCH of one row. v The PRIOR, CURRENT, and RELATIVE scroll options should not be used with multiple-row FETCH statements. To allow random movement of the cursor by the application, the database manager must maintain the same cursor position as the application. Therefore, the SQL run-time treats all FETCH requests against a scrollable cursor with these options specied as multiple-row FETCH requests.

Improving Performance Using INSERT n ROWS


Applications that perform many INSERT statements in succession may be improved by using INSERT n ROWS. With this clause, you can insert one or more rows of data from a host structure array into a target table. This array must be an array of structures where the elements of the structure correspond to columns in the target table. An SQL application that loops over an INSERT...VALUES statement (without the n ROWS clause) can be improved by using the INSERT n ROWS statement to insert multiple rows into the table. After the application has looped to ll the host array with records, a single INSERT n ROWS statement can be run to insert the entire array into the table. The statement runs faster because the SQL run-time was only called once and all the data was simultaneously inserted into the target table. In the following table, the program attempted to INSERT 100 rows into a table. Note the differences in the number of calls to SQL run-time and to the database manager when blocking can be performed.
Table 41. Number of Calls Using an INSERT Statement
Database Manager Not Using Database Manager Using Blocking Blocking Single-Row INSERT Statement Multiple-Row INSERT Statement 100 SQL run-time calls 100 database calls 1 SQL run-time call 100 database calls 100 SQL run-time calls 1 database call 1 SQL run-time call 1 database call

Improving Performance When Paging Interactively Displayed Data


In large tables, paging performance is usually degraded because of the REFRESH(*ALWAYS) parameter on the STRSQL command which dynamically retrieves the latest data directly from the table. Paging performance can be improved by specifying REFRESH(*FORWARD). When interactively displaying data using REFRESH(*FORWARD), the results of a select-statement are copied to a temporary le as you page forward through the display. Other users sharing the table can make changes to the rows while you are displaying the select-statement results. If you page backward or forward to rows that have already been displayed, the rows shown are those in the temporary le instead of those in the updated table. The refresh option can be changed on the Session Services display.

Chapter 25. Additional SQL performance considerations

463

Improving Performance by Using SELECT Statements Effectively


The number of columns specied in the select list of a SELECT statement causes the database manager to retrieve the data from the underlying tables and map the data into host variables in the application programs. By minimizing the number of columns specied, processing unit resource usage can be conserved. Even though it is convenient to code SELECT *, it is far better to explicitly code the columns actually required for the application. This is especially important if index-only access is desired or if all of the columns will participate in a sort operation (as happens for SELECT DISTINCT and for SELECT UNION).

Improving Performance by Using Live Data


The term live data refers to the type of access that the database manager uses when it retrieves data without making a copy of the data. Using this type of access, the data, which is returned to the program, always reects the current values of the data in the database. The programmer can control whether the database manager uses a copy of the data or retrieves the data directly. This is done by specifying the allow copy data (ALWCPYDTA) parameter on the precompiler commands or on the Start SQL (STRSQL) command. Specifying ALWCPYDTA(*NO) instructs the database manager to always use live data. Live data access can be used as a performance advantage because the cursor does not have to be closed and opened again to refresh the data being retrieved. An example application demonstrating this advantage is one that produces a list on a display. If the display screen can only show 20 elements of the list at a time, then, after the initial 20 elements are displayed, the application programmer can request that the next 20 rows be displayed. A typical SQL application designed for an operating system other than the OS/400 operating system, might be structured as follows:
EXEC SQL DECLARE C1 CURSOR FOR SELECT EMPNO, LASTNAME, WORKDEPT FROM CORPDATA.EMPLOYEE ORDER BY EMPNO END-EXEC. EXEC SQL OPEN C1 END-EXEC. * PERFORM FETCH-C1-PARA 20 TIMES.

MOVE EMPNO to LAST-EMPNO. EXEC SQL CLOSE C1 END-EXEC. * * Show the display and wait for the user to indicate that the next 20 rows should be displayed.

EXEC SQL DECLARE C2 CURSOR FOR SELECT EMPNO, LASTNAME, WORKDEPT FROM CORPDATA.EMPLOYEE WHERE EMPNO > :LAST-EMPNO ORDER BY EMPNO END-EXEC.

464

DB2 UDB for AS/400 SQL Programming V4R4

EXEC SQL OPEN C2 END-EXEC. * * PERFORM FETCH-C21-PARA 20 TIMES.

Show the display with these 20 rows of data.

EXEC SQL CLOSE C2 END-EXEC.

In the above example, notice that an additional cursor had to be opened to continue the list and to get current data. This could result in creating an additional ODP that would increase the processing time on the AS/400 system. In place of the above example, the programmer could design the application specifying ALWCPYDTA(*NO) with the following SQL statements:
EXEC SQL DECLARE C1 CURSOR FOR SELECT EMPNO, LASTNAME, WORKDEPT FROM CORPDATA.EMPLOYEE ORDER BY EMPNO END-EXEC. EXEC SQL OPEN C1 END-EXEC. * * * * * Display the screen with these 20 rows of data. PERFORM FETCH-C1-PARA 20 TIMES.

Show the display and wait for the user to indicate that the next 20 rows should be displayed. PERFORM FETCH-C1-PARA 20 TIMES.

EXEC SQL CLOSE C1 END-EXEC.

In the above example, the query could perform better if the FOR 20 ROWS clause was used on the multiple-row FETCH statement. Then, the 20 rows would be retrieved in one operation.

Improving Performance by Using the ALWCPYDTA Parameter


Some complex queries can perform better by using a sort or hashing method to evaluate the query instead of using or creating an index. By using the sort or hash, the database manager is able to separate the row selection from the ordering and grouping process. This separation allows the use of the most efficient index for the selection. For example, consider the following SQL statement:
EXEC SQL DECLARE C1 CURSOR FOR SELECT EMPNO, LASTNAME, WORKDEPT FROM CORPDATA.EMPLOYEE WHERE WORKDEPT = 'A00' ORDER BY LASTNAME END-EXEC.

Chapter 25. Additional SQL performance considerations

465

In the above example when ALWCPYDTA(*NO) or ALWCPYDTA(*YES) is specied, the database manager may try to create an index from the rst index with a column named LASTNAME, if such an index exists. The rows in the table are scanned, using the index, to select only the rows matching the WHERE condition. If ALWCPYDTA(*OPTIMIZE) is specied, the database manager uses an index with the rst index column of WORKDEPT. It then makes a copy of all of the rows that match the WHERE condition. Finally, it may sort the copied rows by the values in LASTNAME. This row selection processing is signicantly more efficient, because the index used immediately locates the rows to be selected. ALWCPYDTA(*OPTIMIZE) optimizes the total time required to process the query. However, the time required to receive the rst row may be increased because a copy of the data must be made prior to returning the rst row of the result table. This initial change in response time may be important for applications presenting interactive displays or that retrieve only the rst few rows of the query. The DB2 UDB for AS/400 query optimizer can be inuenced to avoid sorting by using the OPTIMIZE clause. Refer to Improving Performance by Using the Optimize Clause for more information. Queries that involve a join operation may also benet from ALWCPYDTA(*OPTIMIZE) because the join order can be optimized regardless of the ORDER BY specication. Note: The hashing method cannot be used to implement the grouping on queries that involve a nested loop join implementation and do not require a temporary result to be created.

Improving Performance by Using the Optimize Clause


If an application is not going to retrieve the entire result table for a cursor, using the OPTIMIZE clause can improve performance. The query optimizer modies the cost estimates to retrieve the subset of rows using the value specied on the OPTIMIZE clause. Assume the following query returns 1000 rows:
EXEC SQL DECLARE C1 CURSOR FOR SELECT EMPNO, LASTNAME, WORKDEPT FROM CORPDATA.EMPLOYEE WHERE WORKDEPT = 'A00' ORDER BY LASTNAME OPTIMIZE FOR 100 ROWS END EXEC.

The optimizer calculates the following costs. The optimize ratio = optimize for n rows value / estimated number of rows in answer set.
Cost using a temporarily created index: + + Cost to Cost to Cost to with retrieve answer set rows create the index retrieve the rows again a temporary index * optimize ratio

466

DB2 UDB for AS/400 SQL Programming V4R4

Cost using a SORT: + + Cost to retrieve answer set rows Cost for SORT input processing Cost for SORT output processing * optimize ratio

Cost using an existing index: Cost to retrieve answer set rows using an existing index * optimize ratio

In the previous examples, the estimated cost to sort or to create an index is not adjusted by the optimize ratio. This enables the optimizer to balance the optimization and preprocessing requirements. If the optimize number is larger than the number of rows in the result table, no adjustments are made to the cost estimates. If the OPTIMIZE clause is not specied for a query, a default value is used based on the statement type, value of ALWCPYDTA specied, or output device.
Statement Type DECLARE CURSOR Embedded Select INTERACTIVE Select output to display INTERACTIVE Select output to printer or database le ALWCPYDTA(*OPTIMIZE) The number or rows in the result table. 2 3% or the number of rows in the result table. The number of rows in the result table. ALWCPYDTA(*YES or *NO) 3% or the number of rows in the result table. 2 3% or the number of rows in the result table. The number of rows in the result table.

The OPTIMIZE clause inuences the optimization of a query: v To use an existing index (by specifying a small number). v To enable the creation of an index or to run a sort or a hash by specifying a large number of possible rows in the answer set.

Improving Performance by Retaining Cursor Positions


You can improve performance by retaining cursor positions. The next two sections provide information on retaining cursors for non-ILE and ILE program calls.

Improving Performance by Retaining Cursor Positions for Non-ILE Program Calls


For non-ILE program calls, the close SQL cursor (CLOSQLCSR) parameter allows you to specify the scope of the following: v The cursors v The prepared statements v The locks When used properly, the CLOSQLCSR parameter can reduce the number of SQL OPEN, PREPARE, and LOCK statements needed. It can also simplify applications by allowing you to retain cursor positions across program calls.

Chapter 25. Additional SQL performance considerations

467

*ENDPGM This is the default for all non-ILE precompilers. With this option, a cursor remains open and accessible only while the program that opened it is on the call stack. When the program ends, the SQL cursor can no longer be used. Prepared statements are also lost when the program ends. Locks, however, remain until the last SQL program on the call stack has completed. *ENDSQL With this option, SQL cursors and prepared statements created by a program remain open until the last SQL program on the call stack has completed. They cannot be used by other programs, only by a different call to the same program. Locks remain until the last SQL program in the call stack completes. *ENDJOB This option allows you to keep SQL cursors, prepared statements, and locks active for the duration of the job. When the last SQL program on the stack has completed, any SQL resources created by *ENDJOB programs are still active. The locks remain in effect. The SQL cursors that were not explicitly closed by the CLOSE, COMMIT, or ROLLBACK statements remain open. The prepared statements are still usable on subsequent calls to the same program.

Improving Performance by Retaining Cursor Positions across ILE Program Calls


For ILE program calls, the close SQL cursor (CLOSQLCSR) parameter allows you to specify the scope of the following: v The cursors v The prepared statements v The locks When used properly, the CLOSQLCSR parameter can reduce the number of SQL OPEN, PREPARE, and LOCK statements needed. It can also simplify applications by allowing you to retain cursor positions across program calls. *ENDACTGRP This is the default for the ILE precompilers. With this option, SQL cursors and prepared statements remain open until the activation group that the program is running under ends. They cannot be used by other programs, only by a different call to the same program. Locks remain until the activation group ends. *ENDMOD With this option, a cursor remains open and accessible only while the module that opened it is active. When the module ends, the SQL cursor can no longer be used. Prepared statements will also be lost when the module ends. Locks, however, remain until the last SQL program in the call stack completes.

468

DB2 UDB for AS/400 SQL Programming V4R4

General Rules for Retaining Cursor Positions For All Program Calls
When using programs compiled with either CLOSQLCSR(*ENDPGM) or CLOSQLCSR(*ENDMOD), a cursor must be opened every time the program or module is called, in order to access the data. If the SQL program or module is going to be called several times, and you want to take advantage of a reusable ODP, then the cursor must be explicitly closed before the program or module exits. Using the CLOSQLCSR parameter and specifying *ENDSQL, *ENDJOB, or *ENDACTGRP, you may not need to run an OPEN and a CLOSE statement on every call. In addition to having fewer statements to run, you can maintain the cursor position between calls to the program or module. The following examples of SQL statements help demonstrate the advantage of using the CLOSQLCSR parameter:
EXEC SQL DECLARE DEPTDATA CURSOR FOR SELECT EMPNO, LASTNAME FROM CORPDATA.EMPLOYEE WHERE WORKDEPT = :DEPTNUM END-EXEC. EXEC SQL OPEN DEPTDATA END-EXEC. EXEC SQL FETCH DEPTDATA INTO :EMPNUM, :LNAME END-EXEC. EXEC SQL CLOSE DEPTDATA END-EXEC.

If this program is called several times from another SQL program, it will be able to use a reusable ODP. This means that, as long as SQL remains active between the calls to this program, the OPEN statement will not require a database open operation. However, the cursor is still positioned to the rst result row after each OPEN statement, and the FETCH statement will always return the rst row. In the following example, the CLOSE statement has been removed:
EXEC SQL DECLARE DEPTDATA CURSOR FOR SELECT EMPNO, LASTNAME FROM CORPDATA.EMPLOYEE WHERE WORKDEPT = :DEPTNUM END-EXEC. IF CURSOR-CLOSED IS = TRUE THEN EXEC SQL OPEN DEPTDATA END-EXEC. EXEC SQL FETCH DEPTDATA INTO :EMPNUM, :LNAME END-EXEC.

If this program is precompiled with the *ENDJOB option or the *ENDACTGRP option and the activation group remains active, the cursor position is maintained. The cursor position is also maintained when the following occurs:
Chapter 25. Additional SQL performance considerations

469

v The program is precompiled with the *ENDSQL option. v SQL remains active between program calls. The result of this strategy is that each call to the program retrieves the next record in the cursor. On subsequent data requests, the OPEN statement is unnecessary and, in fact, fails with a -502 SQLCODE. You can ignore the error, or add code to skip the OPEN. This can be done by using a FETCH statement rst, and only running the OPEN statement if the FETCH operation failed. This technique also applies to prepared statements. A program could rst try the EXECUTE, and if it fails, perform the PREPARE. The result is that the PREPARE would only be needed on the rst call to the program, assuming the correct CLOSQLCSR option was chosen. Of course, if the statement can change between calls to the program, it should perform the PREPARE in all cases. The main program could also control this by sending a special parameter on the rst call only. This special parameter value would indicate that because it is the rst call, the subprogram should perform the OPENs, PREPAREs, and LOCKs. Note: If you are using COBOL programs, do not use the STOP RUN statement. When the rst COBOL program on the call stack ends or a STOP RUN statement runs, a reclaim resource (RCLRSC) operation is done. This operation closes the SQL cursor. The *ENDSQL option does not work as desired.

Improving Performance of SQL PREPARE Statements


The processing which occurs when an SQL PREPARE statement is run is similar to the processing which occurs during precompile processing. The statement being prepared is: v Syntax checked v Validated to ensure that the usage of objects are valid. v Has an access plan built Again when the statement is executed or opened, the database manager will revalidate that the access plan is still valid. Much of this open processing validation is redundant with the validation which occurred during the PREPARE processing. The DLYPRP(*YES) parameter species whether PREPARE statements in this program will completely validate the dynamic statement. The validation will be completed when the dynamic statement is opened or executed. This parameter can provide a signicant performance enhancement for programs which use the PREPARE SQL statement because it eliminates redundant validation. Programs specifying this precompile option should check the SQLCODE and SQLSTATE after running the OPEN or EXECUTE statement to ensure the statement is valid. DLYPRP(*YES) will not provide any performance improvement if the INTO clause is used on the PREPARE statement or if a DESCRIBE statement uses the dynamic statement before an OPEN is issued for the statement.

Effects on Performance When Using Long Object Names


Long object names are converted internally to system object names when used in SQL statements. This conversion can have some performance impacts. If the long object name is qualied with a library name, then the conversion to the short name happens at precompile time. In this case, there is no performance impact when the

470

DB2 UDB for AS/400 SQL Programming V4R4

statement is executed. However, if the long object name is unqualied, the conversion is done at execution time, and has a small performance impact.

Improving Performance Using the Precompile Options


Several precompile options are available for creating programs with improved performance. They are only options because using them may impact the function of the application. For this reason, the default values for these parameters is the value that will ensure successful migration of applications from prior releases. However, performance may be improved by specifying other options. The following table shows these precompile options and their performance impacts:
Precompile Option ALWCPYDTA Optimal Value *OPTIMIZE Improvements Queries where the ordering or grouping criteria conicts with the selection criteria. Additional read-only cursors use blocking. Considerations A copy of the data may be made when the query is opened. Related Topics See Improving Performance by Using the ALWCPYDTA Parameter on page 465. See Improving Performance by Using Database Manager Blocking Considerations on page 461. See Improving Performance by Retaining Cursor Positions for Non-ILE Program Calls on page 467. See Improving Performance of SQL PREPARE Statements on page 470. See Improving Performance by Using Structure Parameter Passing Techniques on page 472.

ALWBLK

*ALLREAD

ROLLBACK HOLD may not change the position of a read-only cursor.Dynamic processing of positioned updates or deletes might fail. Implicit closing of SQL cursor is not done when the program invocation ends.

CLOSQLCSR

*ENDJOB *ENDSQL or *ENDACTGRP

Cursor position can be retained across program invocations.

DLYPRP

*YES

Programs using SQL Complete validation of PREPARE statements the prepared may run faster. statement is delayed until the statement is run or opened. The precompiler can generate code that will take advantage of performance enhancements available in the current release. The program object cannot be used on a system from a previous release.

TGTRLS

*CURRENT (the default)

Some of these options may be suitable for most of your applications. Use the command CRTDUPOBJ to create a copy of the SQL CRTSQLxxx command and the CHGCMDDFT command to customize the optimal values for the precompile parameters. The DSPPGM, DSPSRVPGM, DSPMOD, or PRTSQLINF commands can be used to show the precompile options used for an existing program object.

Chapter 25. Additional SQL performance considerations

471

Improving Performance by Using Structure Parameter Passing Techniques


The SQL precompiler uses two methods of passing host variables to the SQL run time. The original method was to pass each host variable as a separate parameter. For example:
CALL QSQROUTE (SQLCA, hostvariable1, hostvariable2, hostvariable3)

The second method is to create a data structure with an element for each host variable referenced in the statement. Then that data structure could be passed as a parameter. For example:
CALL QSQROUTE (SQLCA, hostvariable structure)

The second method will provide better performance. Note: The structure parameter passing technique is not used for SQL statements for special cases in PL/I and RPG for AS/400 programs (see Differences in PL/I Because of Structure Parameter Passing Techniques on page 294 and Differences in RPG for AS/400 Because of Structure Parameter Passing Techniques on page 307.

Background Information on Parameter Passing


Additional code is created in the program to move the input host variable data to the structure before the call to the SQL program. After the call to the SQL program, code is added that moves the data from the structure to the output host variables. The precompiler creates the structure so that the SQL header is rst, followed by the input host variables, the output host variables, the indicators for the input host variables, and the indicators for the output host variables. Because the output host variables are created in a contiguous storage space, the SQL run-time support can check for a match with the I/O buffer (each result column attribute is checked for a matching host variable attribute) and move the data with one instruction if they all match. The SQL header on the structure contains information unique to the statement so that SQL does not have to reconstruct the information on each call. Some of this information is added and processed by the SQL run-time support. SQL run-time support creates an SQLDA internally for each statement that uses host variables. With the original parameter list, the host variable address could be different for each call of the statement and, therefore, SQL run-time support rebuilds the SQLDA for each call of the statement. With structure parameter passing, the structure is created as a static variable, and the address of the elements will not change. SQL run-time support builds the SQLDA the rst time the statement is called, and saves the SQLDA so it can be used on future calls of the statement. With the original type of parameter passing, the number of host variables that could be referred to in a program was approximately 4000 because of an architecture limit of 4100 pointers in a program. Each parameter required a pointer. With the

472

DB2 UDB for AS/400 SQL Programming V4R4

structure parameter passing, only two parameters are passed for each SQL statement, therefore, the limit of 4000 pointers does not apply.

Some Differences Because of Structure Parameter Passing Techniques


You need to be aware of the following differences in the parameter passing techniques when embedding SQL statements into application programs: v SQLCODE +326 is returned when the structure parameter passing technique is used and the number of host variables specied is greater than the number of columns in the select list. The extra output host variables are ignored by the original parameter passing technique, but with the structure parameter passing technique, the host variable is set to the value in the SQL created structure (blanks are used for character host variables and zeros are used for numeric host variables).Attention: This could cause incorrect results when the extra output host variables overlap with other host variables. An example of this problem, using RPG for AS/400, follows:
ISTRUC I I I DS 1 2 1 1 A 2 B 2 C

SELECT * INTO :STRUC FROM ATABLE

In the above example, if ATABLE has only one or two columns, the SQLCODE will be set to +326. When the assignment to C from the SQL structure is done, the contents of A and B will be blank instead of the value of the column corresponding to A and B. v With the original parameter passing technique, SQLCODE -302 or -304 is returned when a conversion error occurs (because of numeric data that is not valid) while processing the data for a host variable. However, with the structure parameter passing technique, SQL does not detect this error. The conversion error occurs in the host language statements that reference the host variable. For example, if a DECIMAL(5,2) input host variable contains the invalid data FFFFFFX, an error will occur in the host language when the data is moved into the data structure. v The structure created by SQL uses names that start with the letters SQL. If existing programs use variable names starting with SQL, those names may conict with the SQL-created names. v The contents of the SQL-created data structure must not be changed by the application programs.

Controlling Parallel Processing


This section describes how parallel processing can be turned on and off. If the DB2 UDB Symmetric Multiprocessing feature is installed, then symmetric multiprocessing (SMP) can also be turned on and off. This control is available for system wide control through the system value QQRYDEGREE. At a job level, this control is available using the DEGREE parameter on the CHGQRYA command. Even though parallelism has been enabled for a system or given job, the individual queries that run in a job might not actually use a parallel method. This might be because of functional restrictions, or the optimizer might choose a non-parallel
Chapter 25. Additional SQL performance considerations

473

method because it runs faster. See the previous sections that describe the performance characteristics and restrictions of each of the parallel access methods. Because queries being processed with parallel access methods aggressively use main storage, CPU, and disk resources, the number of queries that use parallel processing should be limited and controlled.

Controlling Parallel Processing System Wide


The QQRYDEGREE system value can be used to control parallel processing for a system. The current value of the system value can be displayed or modied using the following CL commands: v v v v WRKSYSVAL - Work with System Value CHGSYSVAL - Change System Value DSPSYSVAL - Display System Value RTVSYSVAL - Retrieve System Value

The special values for QQRYDEGREE control whether parallel processing is allowed by default for all jobs on the system. The possible values are: *NONE No parallel processing is allowed for database query processing. *IO I/O parallel processing is allowed for queries. *OPTIMIZE The query optimizer can choose to use any number of tasks for either I/O or SMP parallel processing to process the queries. SMP parallel processing is used only if the DB2 UDB Symmetric Multiprocessing feature is installed. The query optimizer chooses to use parallel processing to minimize elapsed time based on the jobs share of the memory in the pool. *MAX The query optimizer can choose to use either I/O or SMP parallel processing to process the query. SMP parallel processing can be used only if the DB2 UDB Symmetric Multiprocessing feature is installed. The choices made by the query optimizer are similar to those made for parameter value *OPTIMIZE, except the optimizer assumes that all active memory in the pool can be used to process the query. The default value of the QQRYDEGREE system value is *NONE, so the value must be changed if parallel query processing is desired as the default for jobs run on the system. Changing this system value affects all jobs that will be run or are currently running on the system whose DEGREE query attribute is *SYSVAL. However, queries that have already been started or queries using reusable ODPs are not affected.

Controlling Parallel Processing for a Job


Query parallel processing can also be controlled at the job level using the DEGREE parameter of the Change Query Attributes (CHGQRYA) command. The parallel processing option allowed and, optionally, the number of tasks that can be used

474

DB2 UDB for AS/400 SQL Programming V4R4

when running database queries in the job can be specied. You can prompt on the CHGQRYA command in an interactive job to display the current values of the DEGREE query attribute. Changing the DEGREE query attribute does not affect queries that have already been started or queries using reusable ODPs. Job: B,I
(1) CHGQRYA * JOB( job-number/ *SAME *NOMAX *SYSVAL seconds *SAME *NONE *IO *OPTIMIZE *MAX *SYSVAL *ANY *NBRTASKS number-of-tasks user-name/ job-name )

Pgm: B,I
(2)

REXX: B,I

Exec

QRYTIMLMT(

DEGREE (

ASYNCJ (

*SAME *LOCAL *DIST *NONE *ANY

APYRMT (

*SAME *YES *NO

Notes: 1. Value *ANY is equivalent to value *IO. 2. All parameters preceding this point can be specied in positional form. The parameter values for the DEGREE keyword are: *SAME The parallel degree query attribute does not change. *NONE No parallel processing is allowed for database query processing. *IO Any number of tasks can be used when the database query optimizer chooses to use I/O parallel processing for queries. SMP parallel processing is not allowed. *OPTIMIZE The query optimizer can choose to use any number of tasks for either I/O or SMP parallel processing to process the query. SMP parallel processing can be used only if the DB2 UDB Symmetric Multiprocessing feature is installed. Use of parallel processing and the number of tasks used is determined with respect to the number of processors available in the system, the jobs share of the amount of active memory available in the pool in which the job is run, and whether the expected elapsed time for the query is limited by CPU processing or I/O resources. The query optimizer chooses an implementation that minimizes elapsed time based on the jobs share of the memory in the pool.
Chapter 25. Additional SQL performance considerations

475

*MAX The query optimizer can choose to use either I/O or SMP parallel processing to process the query. SMP parallel processing can be used only if the DB2 UDB Symmetric Multiprocessing feature is installed. The choices made by the query optimizer are similar to those made for parameter value *OPTIMIZE except the optimizer assumes that all active memory in the pool can be used to process the query. *NBRTASKS number-of-tasks Species the number of tasks to be used when the query optimizer chooses to use SMP parallel processing to process a query. I/O parallelism is also allowed. SMP parallel processing can be used only if the DB2 UDB Symmetric Multiprocessing feature is installed. | | | | | | Using a number of tasks less than the number of processors available on the system restricts the number of processors used simultaneously for running a given query. A larger number of tasks ensures that the query is allowed to use all of the processors available on the system to run the query. Too many tasks can degrade performance because of the over commitment of active memory and the overhead cost of managing all of the tasks. *SYSVAL Species that the processing option used should be set to the current value of the QQRYDEGREE system value. *ANY Parameter value *ANY has the same meaning as *IO. The *ANY value is maintained for compatibility with prior releases. The initial value of the DEGREE attribute for a job is *SYSVAL. See the CL Reference (Abridged) book for more information about the CHGQRYA command.

476

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 26. Monitoring and Optimizing Query Performance Tools


Optimizing Query Performance Using Query Optimization Tools
| | | | | You can use query optimization tools to improve data retrieval time. Use the results of the tools to: v Change the Data Access Methods on page 420 chosen by the system v Create the correct indexes The query optimization tools to use in this iterative process include: v Query optimizer debug messages v Print SQL information on page 478 v Database monitor statistics on page 478 v Change query attributes on page 543 v Query Options File QAQQINI on page 543 v Memory Resident Database Monitor APIs on page 524 v You can use the Operations Navigator SQL Performance monitor to work with Memory Resident Database Monitor APIs on page 524. You may want to quickly check out the Comparison table of query optimization tools on page 542 to learn: v What information each tool can yield about your query v When in the process a specic tool can analyze your query v The tasks each tool can perform to improve your query If you are experienced with query optimization, you may want to refer to a list of General Optimization Tips on page 395.

Query optimizer debug messages


| | | | | | | | | | | | | | | Query optimizer debug messages issue informational messages to the joblog about the implementation of a query. These messages explain what happened during the query optimization process. For example, you can learn: v v v v v v v Why an index was or was not used Why a temporary result was required Whether joins and blocking are used What type of index was advised by the optimizer Status of the jobs queries Access paths used Status of the cursor

The optimizer automatically logs messages for OPNQRYF, SQL Query Manager, interactive SQL, embedded SQL, and all AS/400 HLLs. To view the messages, put your job into debug mode using one of the following methods: v Use the following command:
STRDBG PGM(Library/program) UPDPROD(*YES)
Copyright IBM Corp. 1997, 1999

477

| | | | | |

v Set the QRYOPTLIB parameter on the Change Query Attributes (CHGQRYA) command to a user library where the QAQQINI le exists. Set the parameter on the QAQQINI le to MESSAGES_DEBUG, and set the value to *YES. Pressing F10 from the command Entry panel displays the message text. To see the second-level text, press F1 (Help). The second-level text sometimes offers hints for improving query performance. See Performance Information Messages on page 382 for the specic meanings of the debug messages.

Print SQL information


| | | | | | | | | | | | | | | | | | | | | The PRTSQLINF command gathers information about the embedded SQL statements in a program, SQL package (the object normally used to store the access plan for a remote query), or service program. It then puts the information in a spooled le. PRTSQLINF provides information about: v The SQL statements being executed v The type of access plan used during execution. This includes information about how the query will be implemented, the indexes used, the join order, whether a sort is done, whether a database scan is sued, and whether an index is created. v A list of the command parameters used to precompile the source member for the object. To gather this information, run PRTSQLINF against a saved access plan. This means you must execute or at least prepare the query (using SQLs PREPARE statement) before you use the command. It is best to execute the query because the access paln created as a result of PREPARE is relatively sparse and may well change after the rst run. PRTSQLINFs requirement of a saved access plan means the command cannot be used with OPNQRYF. PRTSQLINF gives output that is similar to the information you can get from debug messages, but PRTSQLINF must be run against a saved access plan. The query optimizer automatically logs information messages about the current query processing when your job is in debug mode. So, query debug messages work at runtime while PRTSQLINF works retroactively.

Database monitor statistics


| | | | | | | | | | | | Database monitor statistics provide the most complete information about a query. You can log all information and statistics for queries that you run on a particular job or at a system level. The STRDBMON and ENDDBMON CL commands start and end the collection of database performance statistics. You can monitor a specic job or all jobs on the system. The statistics gathered are placed in the output database le specied on the command. Each job in the system can be monitored concurrently by two monitors: v One started specically on that job v One started for all jobs in the system When a job is monitored by two monitors, each monitor is logging records to a different output le. You can identify records in the output database le by each records unique identication number.

478

DB2 UDB for AS/400 SQL Programming V4R4

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

STRDBMON provides the same information as the two earlier tools (Query optimizer debug messages (STRDBG) and Print SQL information (PRTSQLINF)) along with the following information: v System and job name v SQL statement and sub-select number v Start and end timestamp v v v v v v v Estimated processing time Total rows in le queried Number of rows selected Estimated number of rows selected Estimated number of joined rows Key elds for advised index Total optimization time

v Join type and method v ODP implementation This chapter discusses monitoring database query performance. Database monitor statistics provide the most complete information about a query. You can gather performance statistics for a specic query or for every query on the system. There are a variety of ways of gathering the statistics: v Start Database Monitor (STRDBMON) Command and End Database Monitor (ENDDBMON) Command on page 480 v Start Performance Monitor (STRPFRMON) command with the STRDBMON parameter v Memory Resident Database Monitor APIs on page 524 v You can use Optimizing Query Performance Using Query Optimization Tools on page 477 to improve data retrieval time. You can use these performance statistics to generate various reports. For instance, you can include reports that show queries that: v v v v Use an abundance of the system resources. Take an extremely long time to execute. Did not run because of the query governor time limit. Create a temporary keyed access path during execution

v Use the query sort during execution v Could perform faster with the creation of a keyed logical le containing keys suggested by the query optimizer. Note: A query that is cancelled by an end request generally does not generate performance statistics.

Start Database Monitor (STRDBMON) Command


The STRDBMON command starts the collection of database performance statistics for a specic job or all jobs on the system. The statistics are placed in an output database le and member specied on the command. If the output le and/or member does not exist, one is created based upon the le and format denition of model le QSYS/QAQQDBMN. If the output le and/or member exist, the record format of the output le must be named QQQDBMN.
Chapter 26. Monitoring and Optimizing Query Performance Tools

479

You can specify a replace/append option that allows you to clear the member of information before writing records or to just append new information to the end of the existing le. You can also specify a force record write option that allows you to control how many records are kept in the record buffer of each job being monitored before forcing the records to be written to the output le. By specifying a force record write value of 1, FRCRCD(1), monitor records will appear in the log as soon as they are created. FRCRCD(1) also ensures that the physical sequence of the records are most likely, but not guaranteed, to be in time sequence. However, FRCRCD(1) will cause the most negative performance impact on the jobs being monitored. By specifying a larger number for the FRCRCD parameter, the performance impact of monitoring can be lessened. Specifying *DETAIL on the TYPE parameter of the STRDBMON command indicates that detail records, as well as summary records, are to be collected. This is only useful for non-SQL queries, those queries which do not generate a QQQ1000 record. For non-SQL queries the only way to determine the number of records returned and the total time to return those records is to collect detail records. Currently the only detail record is QQQ3019. The DDS for this record is shown in Figure 32 on page 523. While the detail record contains valuable information it creates a slight performance degradation for each block of records returned. Therefore its use should be closely monitored. If the monitor is started on all jobs, any jobs waiting on job queues or any jobs started during the monitoring period will have statistics gathered from them once they begin. If the monitor is started on a specic job, that job must be active in the system when the command is issued. Each job in the system can be monitored concurrently by only two monitors: v One started specically on that job. v One started on all jobs in the system. When a job is monitored by two monitors and each monitor is logging to a different output le, monitor records will be written to both logs for this job. If both monitors have selected the same output le then the monitor records are not duplicated in the output le.

End Database Monitor (ENDDBMON) Command


The ENDDBMON command ends the Database Monitor for a specic job or all jobs on the system. If an attempt to end the monitor on all jobs is issued, there must have been a previous STRDBMON issued for all jobs. If a particular job is specied on this command, the job must have the monitor started explicitly and specically on that job. In the following sequence: 1. Start monitoring all jobs in the system. 2. Start monitoring a specic job. 3. End monitoring on all jobs. The specic job monitor continues to run because an explicit start of the monitor was done on it. It continues to run until an ENDDBMON on the specic job is issued. In the following sequence:

480

DB2 UDB for AS/400 SQL Programming V4R4

1. Start monitoring all jobs in the system. 2. Start monitoring a specic job. 3. End monitoring on the specic job. The all job monitor continues to run, even over the specic job, until an ENDDBMON for all jobs is issued. In 1. 2. 3. the following sequence: Start monitoring a specic job. Start monitoring all jobs in the system. End monitoring on all jobs.

The specic job monitor continues to run until an ENDDBMON for the specic job is issued. In the following sequence: 1. Start monitoring a specic job. 2. Start monitoring all jobs in the system. 3. End monitoring on the specic job. The all job monitor continues to run for all jobs, including the specic job. When an all job monitor is ended, all of the jobs on the system will be triggered to close the output le, however, the ENDDBMON command can complete before all of the monitored jobs have written their nal performance records to the log. Use the work with object locks, WRKOBJLCK, CL command to see that all of the monitored jobs no longer hold locks on the output le before assuming the monitoring is complete.

Database Monitor Performance Records


The records in the database le are uniquely identied by their record identication number. These records are dened in several different logical les which are not shipped with the system and must be created by the user, if desired. The logical les can be created with the DDS shown in Database Monitor Logical File DDS on page 493. The eld descriptions are explained in the tables following each gure. Note: The database monitor logical les are keyed logical les that contain some select/omit criteria. Therefore, there will be some maintenance overhead associated with these les while the database monitor is active. The user may wish to minimize this overhead while the database monitor is active, especially if monitoring all jobs. When monitoring all jobs the number of records generated could be quite large. Possible ways to minimize maintenance overhead associated with database monitor logical les: v Do not create the database monitor logical les until the database monitor has completed. v Create the database monitor logical les using dynamic select/omit criteria (DYNSLT keyword on logical les DDS). v Create the database monitor logical les with rebuild access path maintenance specied on the CRTLF command (*REBLD option on MAINT parameter). By minimizing the maintenance overhead at run time, you are merely delaying the maintenance cost until the database monitor logical le is either created or opened.
Chapter 26. Monitoring and Optimizing Query Performance Tools

481

The choice is to either spend the time while the database monitor is active or spend the time after the database monitor has completed.

Query Optimizer Index Advisor


The query optimizer analyzes the record selection in the query and determines, based on default values, if creation of a permanent index would improve performance. If the optimizer determines that a permanent index would be benecial, it returns the key elds necessary to create the suggested index. The index advisor information can be found in the Database Monitor logical les QQQ3000, QQQ3001 and QQQ3002. The advisor information is stored in elds QQIDXA, QQIDXK and QQIDXD. When the QQIDXA eld contains a value of Y the optimizer is advising you to create an index using the key elds shown in eld QQIDXD. The intention of creating this index is to improve the performance of the query. In the list of key elds contained in eld QQIDXD the optimizer has listed what it considers the suggested primary and secondary key elds. Primary key elds are elds that should signicantly reduce the number of keys selected based on the corresponding query selection. Secondary key elds are elds that may or may not signicantly reduce the number of keys selected. The optimizer is able to perform key positioning over any combination of the primary key elds, plus one additional secondary key eld. Therefore it is important that the rst secondary key eld be the most selective secondary key eld. The optimizer will use key selection with any of the remaining secondary key elds. While key selection is not as fast as key positioning it can still reduce the number of keys selected. Hence, secondary key elds that are fairly selective should be included. Field QQIDXK contains the number of suggested primary key elds that are listed in eld QQIDXD. These are the left-most suggested key elds. The remaining key elds are considered secondary key elds and are listed in order of expected selectivity based on the query. For example, assuming QQIDXK contains the value of 4 and QQIDXD species 7 key elds, then the rst 4 key elds specied in QQIDXK would be the primary key elds. The remaining 3 key elds would be the suggested secondary key elds. It is up to the user to determine the true selectivity of any secondary key elds and to determine whether those key elds should be included when creating the index. When building the index the primary key elds should be the left-most key elds followed by any of the secondary key elds the user chooses and they should be prioritized by selectivity. Note: After creating the suggested index and executing the query again, it is possible that the query optimizer will choose not to use the suggested index.

Database Monitor Examples


Suppose you have an application program with SQL statements and you want to analyze and performance tune these queries. The rst step in analyzing the performance is collection of data. The following examples show how you might collect and analyze data using STRDBMON and ENDDBMON.

482

DB2 UDB for AS/400 SQL Programming V4R4

Performance data is collected in LIB/PERFDATA for an application running in your current job. The following sequence collects performance data and prepares to analyze it. 1. STRDBMON FILE(LIB/PERFDATA). If this le does not already exist, the command will create one from the skeleton le in QSYS/QAQQDBMN. 2. Run your application 3. ENDDBMON 4. Create logical les over LIB/PERFDATA using the DDS shown in Database Monitor Logical File DDS on page 493. You are now ready to analyze the data. The following examples give you a few ideas on how to use this data. You should closely study the physical and logical le DDS to understand all the data being collected so you can create queries that give the best information for your applications.

Performance Analysis Example 1


Determine which queries in your SQL application are implemented with table scans. The complete information can be obtained by joining two logical les: QQQ1000, which contains information about the SQL statements, and QQQ3000, which contains data about queries performing table scans. The following SQL query could be used:
SELECT A.QQTLN, A.QQTFN, A.QQTOTR, A.QQIDXA, B.QQROWR, (B.QQETIM - B.QQSTIM) AS TOT_TIME, B.QQSTTX FROM LIB/QQQ3000 A, LIB/QQQ1000 B WHERE A.QQJFLD = B.QQJFLD AND A.QQUCNT = B.QQUCNT

Sample output of this query is shown in Table 42. The critical thing to understand is the join criteria
WHERE A.QQJFLD = B.QQJFLD AND A.QQUCNT = B.QQUCNT

A lot of data about many queries is contained in multiple records in le LIB/PERFDATA. It is not uncommon for data about a single query to be contained in 10 or more records within the le. The combination of dening the logical les and then joining the les together allows you to piece together all the data for a query or set of queries. Field QQJFLD uniquely identies all data common to a job; eld QQUCNT is unique at the query level. The combination of the two, when referenced in the context of the logical les, connects the query implementation to the query statement information. scale=table-scale-factor
Table 42. Output for SQL Queries that Performed Table Total Index Lib Name Name Rows Advised LIB1 TBL1 20000 Y
LIB1 LIB1 TBL2 TBL1 100 20000 N Y

Table Scans Rows Returned TOT_TIME Statement Text 10 6.2 SELECT * FROM LIB1/TBL1 WHERE FLD1 = 'A' 100 0.9 SELECT * FROM LIB1/TBL2
32 7.1 SELECT * FROM LIB1/TBL1 WHERE FLD1 = 'B' AND FLD2 > 9000

If the query does not use SQL, the SQL information record (QQQ1000) is not created. This makes it more difficult to determine which records in LIB/PERFDATA pertain to which query. When using SQL, record QQQ1000 contains the actual SQL statement text that matches the performance records to the corresponding query.
Chapter 26. Monitoring and Optimizing Query Performance Tools

483

Only through SQL is the statement text captured. For queries executed using the OPNQRYF command, the OPNID parameter is captured and can be used to tie the records to the query. The OPNID is contained in eld QQOPID of record QQQ3014.

Performance Analysis Example 2


Similar to the preceding example that showed which SQL applications were implemented with table scans, the following example shows all queries that are implemented with table scans.
SELECT A.QQTLN, A.QQTFN, A.QQTOTR, A.QQIDXA, B.QQOPID, B.QQTTIM, C.QQCLKT, C.QQRCDR, D.QQROWR, (D.QQETIM - D.QQSTIM) AS TOT_TIME, D.QQSTTX FROM LIB/QQQ3000 A INNER JOIN LIB/QQQ3014 B ON (A.QQJFLD = B.QQJFLD AND A.QQUCNT = B.QQUCNT) LEFT OUTER JOIN LIB/QQQ3019 C ON (A.QQJFLD = C.QQJFLD AND A.QQUCNT = C.QQUCNT) LEFT OUTER JOIN LIB/QQQ1000 D ON (A.QQJFLD = D.QQJFLD AND A.QQUCNT = D.QQUCNT)

In this example, the output for all queries that performed table scans are shown in Table 43. Note: The elds selected from le QQQ1000 do return NULL default values if the query was not executed using SQL. For this example assume the default value for character data is blanks and the default value for numeric data is an asterisk (*).
Table 43. Output for All Queries that Performed Table Scans ODP Lib Table Total Index Query Open Clock Name Name Rows Advised OPNID Time Time LIB1 TBL1 20000 Y 1.1 4.7

Recs Rtned 10

Rows Rtned 10

TOT_ TIME 6.2

Statement Text SELECT * FROM LIB1/TBL1 WHERE FLD1 = 'A' SELECT * FROM LIB1/TBL2 SELECT * FROM LIB1/TBL1 WHERE FLD1 = 'A' AND FLD2 > 9000

LIB1 LIB1

TBL2 TBL1

100 20000

N Y

0.1 2.6

0.7 4.4

100 32

100 32

0.9 7.1

LIB1

TBL4

4000

QRY04

1.2

4.2

724

If the SQL statement text is not needed, joining to le QQQ1000 is not necessary. You can determine the total time and rows selected from data in the QQQ3014 and QQQ3019 records.

Performance Analysis Example 3


Your next step may include further analysis of the table scan data. The previous examples contained a eld titled Index Advised. A Y (yes) in this eld is a hint from the query optimizer that the query may perform better with an index to access the data. For the queries where an index is advised, notice that the records selected by the query are low in comparison to the total number of records in the table. This is another indication that a table scan may not be optimal. Finally, a long execution time may highlight queries that may be improved by performance tuning.

484

DB2 UDB for AS/400 SQL Programming V4R4

The next logical step is to look into the index advised optimizer hint. The following query could be used for this:
SELECT A.QQTLN, A.QQTFN, A.QQIDXA, A.QQIDXD, A.QQIDXK, B.QQOPID, C.QQSTTX FROM LIB/QQQ3000 A INNER JOIN LIB/QQQ3014 B ON (A.QQJFLD = B.QQJFLD AND A.QQUCNT = B.QQUCNT) LEFT OUTER JOIN LIB/QQQ1000 C ON (A.QQJFLD = C.QQJFLD AND A.QQUCNT = C.QQUCNT) WHERE A.QQIDXA = 'Y'

There are two slight modications from the rst example. First, the selected elds have been changed. Most important is the selection of eld QQIDXD that contains a list of possible key elds to use when creating the index suggested by the query optimizer. Second, the query selection limits the output to those table scan queries where the optimizer advises that an index be created (A.QQIDXA = Y). Table 44 shows what the results might look like.
Table 44. Output with Recommended Key Fields Advised Table Index Key Lib Name Name Advised Fields LIB1 TBL1 Y FLD1
LIB1 TBL1 Y FLD1, FLD2 FLD1, FLD4 Advised Primary Key 1 1

Query OPNID

Statement Text SELECT * FROM LIB1/TBL1 WHERE FLD1 = 'A' SELECT * FROM LIB1/TBL1 WHERE FLD1 = 'B' AND FLD2 > 9000

LIB1

TBL4

QRY04

At this point you should determine whether it makes sense to create a permanent index as advised by the optimizer. In this example, creating one index over LIB1/TBL1 would satisfy all three queries since each use a primary or left-most key eld of FLD1. By creating one index over LIB1/TBL1 with key elds FLD1, FLD2, there is potential to improve the performance of the second query even more. The frequency these queries are run and the overhead of maintaining an additional index over the le should be considered when deciding whether or not to create the suggested index. If you create a permanent index over FLD1, FLD2 the next sequence of steps would be to: 1. 2. 3. 4. Start the performance monitor again Re-run the application End the performance monitor Re-evaluate the data.

It is likely that the three index-advised queries are no longer performing table scans.

Additional Database Monitor Examples


The following are additional ideas or examples on how to extract information from the performance monitor statistics. All of the examples assume data has been collected in LIB/PERFDATA and the documented logical les have been created. 1. How many queries are performing dynamic replans?

Chapter 26. Monitoring and Optimizing Query Performance Tools

485

SELECT COUNT(*) FROM LIB/QQQ1000 WHERE QQDYNR <> 'NA'

2. What is the statement text and the reason for the dynamic replans?
SELECT QQDYNR, QQSTTX FROM LIB/QQQ1000 WHERE QQDYNR <> 'NA'

Note: You have to refer to the description of eld QQDYNR for denitions of the dynamic replan reason codes. 3. How many indexes have been created over LIB1/TBL1?
SELECT FROM WHERE AND COUNT(*) LIB/QQQ3002 QQTLN = 'LIB1' QQTFN = 'TBL1'

4. What key elds are used for all indexes created over LIB1/TBL1 and what is the associated SQL statement text?
SELECT FROM WHERE AND AND AND A.QQTLN, A.QQTFN, A.QQIDXD, B.QQSTTX LIB/QQQ3002 A, LIB/QQQ1000 B A.QQJFLD = B.QQJFLD A.QQUCNT = B.QQUCNT A.QQTLN = 'LIB1' A.QQTFN = 'TBL1'

Note: This query shows key elds only from queries executed using SQL. 5. What key elds are used for all indexes created over LIB1/TBL1 and what was the associated SQL statement text or query open ID?
SELECT A.QQTLN, A.QQTFN, A.QQIDXD, B.QQOPID,C.QQSTTX FROM LIB/QQQ3002 A INNER JOIN LIB/QQQ3014 B ON (A.QQJFLD = B.QQJFLD AND A.QQUCNT = B.QQUCNT) LEFT OUTER JOIN LIB/QQQ1000 C ON (A.QQJFLD = C.QQJFLD AND A.QQUCNT = C.QQUCNT) WHERE A.QQTLN = 'LIB1' AND A.QQTFN = 'TBL1'

Note: This query shows key elds from all queries on the system. 6. What types of SQL statements are being performed? Which are performed most frequently?
SELECT QQSTOP, COUNT(*) FROM LIB/QQQ1000 GROUP BY QQSTOP ORDER BY 2 DESC

7. Which SQL queries are the most time consuming? Which user is running these queries?
SELECT (QQETIM - QQSTIM), QQUSER, QQSTTX FROM LIB/QQQ1000 ORDER BY 1 DESC

8. Which queries are the most time consuming?


SELECT (A.QQTTIM + B.QQCLKT), A.QQOPID, C.QQSTTX FROM LIB/QQQ3014 A LEFT OUTER JOIN LIB/QQQ3019 B ON (A.QQJFLD = B.QQJFLD AND A.QQUCNT = B.QQUCNT) LEFT OUTER JOIN LIB/QQQ1000 C ON (A.QQJFLD = C.QQJFLD AND A.QQUCNT = C.QQUCNT) ORDER BY 1 DESC

486

DB2 UDB for AS/400 SQL Programming V4R4

Note: This example assumes detail data has been collected into record QQQ3019. 9. Show the data for all SQL queries with the data for each SQL query logically grouped together.
SELECT FROM WHERE AND A.* LIB/PERFDATA A, LIB/QQQ1000 B A.QQJFLD = B.QQJFLD A.QQUCNT = B.QQUCNT

Note: This might be used within a report that will format the the interesting data into a more readable format. For example, all reason code elds could be expanded by the report to print the denition of the reason code (i.e., physical eld QQRCOD = T1 means a table scan was performed because no indexes exist over the queried le). 10. How many queries are being implemented with temporary les because a key length of greater than 2000 bytes or more than 120 key elds was specied for ordering?
SELECT COUNT(*) FROM LIB/QQQ3004 WHERE QQRCOD = 'F6'

11. Which SQL queries were implemented with nonreusable ODPs?


SELECT FROM WHERE AND AND B.QQSTTX LIB/QQQ3010 A, LIB/QQQ1000 B A.QQJFLD = B.QQJFLD A.QQUCNT = B.QQUCNT A.QQODPI = 'N'

12. What is the estimated time for all queries stopped by the query governor?
SELECT QQEPT, QQOPID FROM LIB/QQQ3014 WHERE QQGVNS = 'Y'

Note: This example assumes detail data has been collected into record QQQ3019. 13. Which queries estimated time exceeds actual time?
SELECT A.QQEPT, (A.QQTTIM + B.QQCLKT), A.QQOPID, C.QQTTIM, C.QQSTTX FROM LIB/QQQ3014 A LEFT OUTER JOIN LIB/QQQ3019 B ON (A.QQJFLD = B.QQJFLD AND A.QQUCNT = B.QQUCNT) LEFT OUTER JOIN LIB/QQQ1000 C ON (A.QQJFLD = C.QQJFLD AND A.QQUCNT = C.QQUCNT) WHERE A.QQEPT/1000 > (A.QQTTIM + B.QQCLKT)

Note: This example assumes detail data has been collected into record QQQ3019. 14. Should a PTF for queries that perform UNION exists be applied. It should be applied if any queries are performing UNION. Do any of the queries perform this function?
SELECT COUNT(*) FROM QQQ3014 WHERE QQUNIN = 'Y'

Note: If result is greater than 0, the PTF should be applied. 15. You are a system administrator and an upgrade to the next release is planned. A comparison between the two releases would be interesting.

Chapter 26. Monitoring and Optimizing Query Performance Tools

487

v Collect data from your application on the current release and save this data in LIB/CUR_DATA v Move to the next release v Collect data from your application on the new release and save this data in a different le: LIB/NEW_DATA v Write a program to compare the results. You will need to compare the statement text between the records in the two les to correlate the data.

488

DB2 UDB for AS/400 SQL Programming V4R4

Database Monitor Physical File DDS


|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 A* A* Database Monitor physical file record format A* A R QQQDBMN TEXT('Database + Monitor') A QQRID 15P TEXT('Record + ID') + EDTCDE(4) + COLHDG('Record' 'ID') A QQTIME Z TEXT('Time record was + created') + COLHDG('Created' 'Time') A QQJFLD 46H TEXT('Join Field') + COLHDG('Join' 'Field') A QQRDBN 18A TEXT('Relational + Database Name') + COLHDG('Relational' + 'Database' 'Name') A QQSYS 8A TEXT('System Name') + COLHDG('System' 'Name') A QQJOB 10A TEXT('Job Name') + COLHDG('Job' 'Name') A QQUSER 10A TEXT('Job User') + COLHDG('Job' 'User') A QQJNUM 6A TEXT('Job Number') + COLHDG('Job' 'Number') A QQUCNT 15P TEXT('Unique Counter') + ALWNULL + COLHDG('Unique' 'Counter') A QQUDEF 100A VARLEN TEXT('User Defined + Field') + ALWNULL + COLHDG('User' 'Defined' + 'Field') A QQSTN 15P TEXT('Statement Number') + ALWNULL + COLHDG('Statement' + 'Number') A QQQDTN 15P TEXT('Subselect Number') + ALWNULL + COLHDG('Subselect' 'Number') A QQQDTL 15P TEXT('Nested level of + subselect') + ALWNULL + COLHDG('Nested' + 'Level of' + 'Subselect') A QQMATN 15P TEXT('Subselect of + materialized view') + ALWNULL + COLHDG('Subselect of' + 'Materialized' 'View') A QQMATL 15P TEXT('Nested level of + Views subselect') + ALWNULL + COLHDG('Nested Level' + 'of View's' + 'Subselect')

Figure 15. QSYS/QAQQDBMN Performance Statistics Physical File DDS (1 of 4)

Chapter 26. Monitoring and Optimizing Query Performance Tools

489

|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 A QQTLN 10A TEXT('Library') + ALWNULL + COLHDG('Library' 'Name') A QQTFN 10A TEXT('File') + ALWNULL + COLHDG('File' 'Name') A QQTMN 10A TEXT('Member') + ALWNULL + COLHDG('Member' 'Name') A QQPTLN 10A TEXT('Physical Library') + ALWNULL + COLHDG('Library of' + 'Physical File') A QQPTFN 10A TEXT('Physical File') + ALWNULL + COLHDG('Name of' + 'Physical File') A QQPTMN 10A TEXT('Physical Member') + ALWNULL + COLHDG('Member of' + 'Physical' 'File') A QQILNM 10A TEXT('Index Library') + ALWNULL + COLHDG('Index' 'Library') A QQIFNM 10A TEXT('Index File') + ALWNULL + COLHDG('Index' 'Name') A QQIMNM 10A TEXT('Index Member') + ALWNULL + COLHDG('Index' 'Member') A QQNTNM 10A TEXT('NLSS Table') + ALWNULL + COLHDG('NLSS' 'Table') A QQNLNM 10A TEXT('NLSS Library') + ALWNULL + COLHDG('NLSS' 'Library') A QQSTIM Z TEXT('Start timestamp') + ALWNULL + COLHDG('Start' 'Time') A QQETIM Z TEXT('End timestamp') + ALWNULL + COLHDG('End' 'Time') A QQKP 1A TEXT('Key positioning') + ALWNULL + COLHDG('Key' 'Positioning') A QQKS 1A TEXT('Key selection') + ALWNULL + COLHDG('Key' 'Selection') A QQTOTR 15P TEXT('Total row in table') + ALWNULL + COLHDG('Total' 'Rows') A QQTMPR 15P TEXT('Number of rows in + temporary') + ALWNULL + COLHDG('Number' 'of Rows' + 'in Temporary') A QQJNP 15P TEXT('Join Position') + ALWNULL + COLHDG('Join' 'Position')

Figure 16. QSYS/QAQQDBMN Performance Statistics Physical File DDS (2 of 4)

490

DB2 UDB for AS/400 SQL Programming V4R4

|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 A QQEPT 15P TEXT('Estimated processing + time') + ALWNULL + COLHDG('Estimated' + 'Processing' 'Time') A QQDSS 1A TEXT('Data space + selection') ALWNULL COLHDG('Data' 'Space' + 'Selection') A QQIDXA 1A TEXT('Index advised') + ALWNULL + COLHDG('Index' 'Advised') A QQORDG 1A TEXT('Ordering') ALWNULL COLHDG('Ordering') A QQGRPG 1A TEXT('Grouping') + ALWNULL + COLHDG('Grouping') A QQJNG 1A TEXT('Join') ALWNULL COLHDG('Join') A QQUNIN 1A TEXT('Union') + ALWNULL + COLHDG('Union') A QQSUBQ 1A TEXT('Subquery') + ALWNULL + COLHDG('Subquery') A QQHSTV 1A TEXT('Host Variables') + ALWNULL + COLHDG('Host' 'Variables') A QQRCDS 1A TEXT('Record Selection') + ALWNULL + COLHDG('Record' 'Selection') A QQRCOD 2A TEXT('Reason Code') + ALWNULL + COLHDG('Reason' 'Code') A QQRSS 15P TEXT('Number of rows + selected or sorted') + ALWNULL + COLHDG('Number' + 'of Rows' 'Selected') A QQREST 15P TEXT('Estimated number + of rows selected') + ALWNULL + COLHDG('Estimated' + 'Number of' + 'Rows Selected') A QQRIDX 15P TEXT('Number of entries + in index created') + ALWNULL + COLHDG('Number of' + 'Entries in' + 'Index Created') A QQFKEY 15P TEXT('Estimated keys for + key positioning') + ALWNULL + COLHDG('Estimated' + 'Entries for' + 'Key Positioning')

Figure 17. QSYS/QAQQDBMN Performance Statistics Physical File DDS (3 of 4)

Chapter 26. Monitoring and Optimizing Query Performance Tools

491

|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 A QQKSEL 15P TEXT('Estimated keys for + key selection') + ALWNULL + COLHDG('Estimated' + 'Entries for' + 'Key Selection') A QQAJN 15P TEXT('Estimated number + of joined rows') + ALWNULL + COLHDG('Estimated' + 'Number of' + 'Joined Rows') A QQIDXD 1000A VARLEN TEXT('Key fields + for the index advised') + ALWNULL + COLHDG('Advised' 'Key' + 'Fields') A QQC11 1A ALWNULL A QQC12 1A ALWNULL A QQC13 1A ALWNULL A QQC14 1A ALWNULL A QQC15 1A ALWNULL A QQC16 1A ALWNULL A QQC18 1A ALWNULL A QQC21 2A ALWNULL A QQC22 2A ALWNULL A QQC23 2A ALWNULL A QQI1 15P ALWNULL A QQI2 15P ALWNULL A QQI3 15P ALWNULL A QQI4 15P ALWNULL A QQI5 15P ALWNULL A QQI6 15P ALWNULL A QQI7 15P ALWNULL A QQI8 15P ALWNULL A QQI9 15P ALWNULL TEXT('Thread + Identifier') + COLHDG('Thread' + 'Identifier') A QQIA 15P ALWNULL A QQF1 15P ALWNULL A QQF2 15P ALWNULL A QQF3 15P ALWNULL A QQC61 6A ALWNULL A QQC81 8A ALWNULL A QQC82 8A ALWNULL A QQC83 8A ALWNULL A QQC84 8A ALWNULL A QQC101 10A ALWNULL A QQC102 10A ALWNULL A QQC103 10A ALWNULL A QQC104 10A ALWNULL A QQC105 10A ALWNULL A QQC106 10A ALWNULL A QQC181 18A ALWNULL A QQC182 18A ALWNULL A QQC183 18A ALWNULL A QQC301 30A VARLEN ALWNULL A QQC302 30A VARLEN ALWNULL A QQC303 30A VARLEN ALWNULL A QQ1000 1000A VARLEN ALWNULL A QQTIM1 Z ALWNULL A QQTIM2 Z ALWNULL

Figure 18. QSYS/QAQQDBMN Performance Statistics Physical File DDS (4 of 4)

492

DB2 UDB for AS/400 SQL Programming V4R4

Database Monitor Logical File DDS


|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 A* A* Database Monitor logical file 1000 A* A R QQQ1000 PFILE(*CURLIB/QAQQDBMN) A QQRID A QQTIME A QQJFLD A QQRDBN A QQSYS A QQJOB A QQUSER A QQJNUM A QQUCNT A QQRCNT RENAME(QQI5) + COLHDG('Refresh' + 'Counter') A QQUDEF A QQSTN A QQSTF RENAME(QQC11) + COLHDG('Statement' + 'Function') A QQSTOP RENAME(QQC21) + COLHDG('Statement' + 'Operation') A QQSTTY RENAME(QQC12) + COLHDG('Statement' 'Type') A QQPARS RENAME(QQC13) + COLHDG('Parse' 'Required') A QQPNAM RENAME(QQC103) + COLHDG('Package' 'Name') A QQPLIB RENAME(QQC104) + COLHDG('Package' 'Library') A QQCNAM RENAME(QQC181) + COLHDG('Cursor' 'Name') A QQSNAM RENAME(QQC182) + COLHDG('Statement' 'Name')

Figure 19. Summary record for SQL Information (Part 1 of 2)

Chapter 26. Monitoring and Optimizing Query Performance Tools

493

A A A A A A A A A A A A A

QQSTIM QQSTTX QQSTOC QQROWR QQDYNR QQDACV QQTTIM QQTTMM QQTSLM QQROWF QQETIM K QQJFLD S QQRID

RENAME(QQ1000) + COLHDG('Statement' 'Text') RENAME(QQC14) + COLHDG('Statement' + 'Outcome') RENAME(QQI2) + COLHDG('Rows' 'Returned') RENAME(QQC22) + COLHDG('Dynamic' 'Replan') RENAME(QQC16) + COLHDG('Data' 'Conversion') RENAME(QQI4) + COLHDG('Total' 'Time') RENAME(QQI6) + COLHDG('Total' 'Time' + 'Microseconds') RENAME(QQI7) + COLHDG('Total' 'Statement' 'Length') RENAME(QQI3) + COLHDG('Rows' 'Fetched') CMP(EQ 1000)

Figure 19. Summary record for SQL Information (Part 2 of 2) Table 45. QQQ1000 - Summary record for SQL Information
Logical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB QQUSER QQJNUM QQTHRD QQUCNT QQRCNT QQUDEF QQSTN QQSTF Physical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB QQUSER QQJNUM QQI9 QQUCNT QQI5 QQUDEF QQSTN QQC11 Description Record identication Time record was created Join eld (unique per job) Relational database name System name Job name Job user Job number Thread identier Unique count (unique per query) Unique refresh counter User dened eld Statement number (unique per statement) Statement function S - Select U - Update I - Insert D - Delete L - Data denition language O - Other

494

DB2 UDB for AS/400 SQL Programming V4R4

Table 45. QQQ1000 - Summary record for SQL Information (continued)


Logical Field Name QQSTOP Physical Field Name QQC21 Description Statement operation AL - Alter table CA - Call CC - Create collection or Create schema CF - Create function CI - Create index CL - Close CO - Comment on CM - Commit CN - Connect CP - Create procedure CS - Create alias CT - Create table CV - Create view CY - Create type DP - Declare procedure DL - Delete DE - Describe DT - Describe table DI - Disconnect DR - Drop EX - Execute EI - Execute immediate FE - Fetch FL - Free locator GR - Grant IN - Insert LO - Label on LK - Lock MT - More text OP - Open PR - Prepare RE - Release RT - Rename table RV - Revoke RO - Rollback SI - Select into SC - Set connection SE - Set variable SP - Set path SR - Set result sets ST - Set transaction UP - Update VI - Value information Statement type D - Dynamic statement S - Static statement Parse required, Y - Yes N - No Name of the package or name of the program that contains the current SQL statement Name of the library containing the package Name of the cursor corresponding to this SQL statement, if applicable

QQSTTY

QQC12

QQPARS

QQC13

QQPNAM QQPLIB QQCNAM

QQC103 QQC104 QQC181

Chapter 26. Monitoring and Optimizing Query Performance Tools

495

Table 45. QQQ1000 - Summary record for SQL Information (continued)


Logical Field Name QQSNAM QQSTIM QQSTTX QQSTOC Physical Field Name QQC182 QQSTIM QQ1000 QQC14 Description Name of statement for SQL statement, if applicable Time this statement entered Statement text Statement outcome S - Successful U - Unsuccessful Number of result rows returned Dynamic replan (access plan rebuilt) NA - No replan. NR - SQL QDT rebuilt for new release. A1 - A le or member is not the same object as the one referenced when the access plan was last built. Some reasons they could be different are: - Object was deleted and recreated. - Object was saved and restored. - Library list was changed. - Object was renamed. - Object was moved. - Object was overridden to a different object. - This is the rst run of this query after the object containing the query has been restored. A2 - Access plan was built to use a reusable Open Data Path (ODP) and the optimizer chose to use a non-reusable ODP for this call. A3 - Access plan was built to use a non-reusable Open Data Path (ODP) and the optimizer chose to use a reusable ODP for this call. A4 - The number of records in the le member has changed by more than 10% since the access plan was last built. A5 - A new access path exists over one of the les in the query. A6 - An access path that was used for this access plan no longer exists or is no longer valid. A7 - OS/400 Query requires the access plan to be rebuilt because of system programming changes. A8 - The CCSID of the current job is different than the CCSID of the job that last created the access plan. A9 - The value of one or more of the following is different for the current job than it was for the job that last created this access plan: - date format. - date separator. - time format. - time separator.

QQROWR QQDYNR

QQI2 QQC22

496

DB2 UDB for AS/400 SQL Programming V4R4

Table 45. QQQ1000 - Summary record for SQL Information (continued)


Logical Field Name Physical Field Name Description AA - The sort sequence table specied is different than the sort sequence table that was used when this access plan was created. AB - Storage pool changed or DEGREE parameter of CHGQRYA command changed. AC - The system feature DB2 multisystem has been installed or removed.. AD - The value of the degree query attribute has changed. AE - A view is either being opened by a high level language or a view is being materialized. AF - A user-dened type or user-dened function is not the same object as the one referred to in the access plan. B0 - The options specied have changed as a result of the query options le QAQQINI. QQDACV QQC16 Data conversion N - No. 0 - Not applicable. 1 - Lengths do not match. 2 - Numeric types do not match. 3 - C host variable is NUL-terminated 4 - Host variable or column is variable length and the other is not variable length. 5 - CCSID conversion. 6 - DRDA and NULL capable, variable length, contained in a partial row, derived expression, or blocked fetch with not enough host variables. 7 - Data, time, or timestamp column. 8 - Too many host variables. 9 - Target table of an insert is not an SQL table. Total time (Universal Time Coordinated) for this statement, in milliseconds. For fetches, this includes all fetches for this OPEN of the cursor. Total time (Universal Time Coordinated) for this statement, in microseconds. For fetches, this includes all fetches for this OPEN of the cursor. Total text length includes the length of the text, in this record and any other records, which are related because of the MT operation type. Total rows fetched for cursor Time SQL request completed

QQTTIM

QQI4

QQTTMM

QQI6

QQTSLM

QQI7

QQROWF QQETIM

QQI3 QQETIM

Chapter 26. Monitoring and Optimizing Query Performance Tools

497

|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 A* A* Database Monitor logical file 3000 A* A R QQQ3000 PFILE(*CURLIB/QAQQDBMN) A QQRID A QQTIME A QQJFLD A QQRDBN A QQSYS A QQJOB A QQUSER A QQJNUM A QQTHRD RENAME(QQI9) + COLHDG('Thread' + 'Identifier') A QQUCNT A QQUDEF A QQQDTN A QQQDTL A QQMATN A QQMATL A QQTLN A QQTFN A QQTMN A QQPTLN A QQPTFN A QQPTMN A QQTOTR A QQREST A QQAJN A QQEPT A QQJNP A QQJNDS RENAME(QQI1) + COLHDG('Data Space' 'Number') A QQJNMT RENAME(QQC21) + COLHDG('Join' 'Method') A QQJNTY RENAME(QQC22) + COLHDG('Join' 'Type') A QQJNOP RENAME(QQC23) + COLHDG('Join' 'Operator') A QQIDXK RENAME(QQI2) + COLHDG('Advised' 'Primary' 'Keys') A QQDSS A QQIDXA A QQRCOD A QQIDXD A K QQJFLD A S QQRID CMP(EQ 3000)

Figure 20. Summary record for Arrival Sequence Table 46. QQQ3000 - Summary record for Arrival Sequence
Logical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB Physical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB Description Record identication Time record was created Join eld (unique per job) Relational database name System name Job name

498

DB2 UDB for AS/400 SQL Programming V4R4

Table 46. QQQ3000 - Summary record for Arrival Sequence (continued)


Logical Field Name QQUSER QQJNUM QQTHRD QQUCNT QQUDEF QQQDTN QQQDTL QQMATN QQMATL QQTLN QQTFN QQTMN QQPTLN QQPTFN QQPTMN QQTOTR QQREST QQAJN QQEPT QQJNP QQJNDS QQJNMT Physical Field Name QQUSER QQJNUM QQI9 QQUCNT QQUDEF QQQDTN QQQDTL QQMATN QQMATL QQTLN QQTFN QQTMN QQPTLN QQPTFN QQPTMN QQTOTR QQREST QQAJN QQEPT QQJNP QQI1 QQC21 Description Job user Job number Thread identier Unique count (unique per query) User dened eld QDT number (unique per QDT) QDT subquery nested level Materialized view QDT number Materialized view nested level Library File Member Physical library Physical le Physical member Total rows in table Estimated number of rows selected Estimated number of joined rows Estimated processing time, in seconds Join position - when available Data space number Join method - when available NL - Nested loop MF - Nested loop with selection HJ - Hash join Join type - when available IN - Inner join PO - Left partial outer join EX - Exception join Join operator - when available EQ - Equal NE - Not equal GT - Greater than GE - Greater than or equal LT - Less than LE - Less than or equal CP - Cartesian product Number of advised key elds that use key positioning Data space selection Y - Yes N - No Index advised Y - Yes N - No

QQJNTY

QQC22

QQJNOP

QQC23

QQIDXK QQDSS

QQI2 QQDSS

QQIDXA

QQIDXA

Chapter 26. Monitoring and Optimizing Query Performance Tools

499

Table 46. QQQ3000 - Summary record for Arrival Sequence (continued)


Logical Field Name QQRCOD Physical Field Name QQRCOD Description Reason code T1 - No indexes exist. T2 - Indexes exist, but none could be used. T3 - Optimizer chose table scan over available indexes. Key elds for the index advised

QQIDXD

QQIDXD

500

DB2 UDB for AS/400 SQL Programming V4R4

|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 A* A* Database Monitor logical file 3001 A* A R QQQ3001 PFILE(*CURLIB/QAQQDBMN) A QQRID A QQTIME A QQJFLD A QQRDBN A QQSYS A QQJOB A QQUSER A QQJNUM A QQUCNT A QQUDEF A QQQDTN A QQQDTL A QQMATN A QQMATL A QQMATL A QQTLN A QQTFN A QQTMN A QQPTLN A QQPTFN A QQPTMN A QQILNM A QQIFNM A QQIMNM A QQTOTR A QQREST A QQFKEY A QQKSEL A QQAJN A QQEPT A QQJNP A QQJNDS RENAME(QQI1) + COLHDG('Data Space' + 'Number') A QQJNMT RENAME(QQC21) + COLHDG('Join' 'Method') A QQJNTY RENAME(QQC22) + COLHDG('Join' 'Type') A QQJNOP RENAME(QQC23) + COLHDG('Join' 'Operator') A QQIDXK RENAME(QQI2) + COLHDG('Advised' + 'Primary' + 'Keys')

Figure 21. Summary record for Using Existing Index (Part 1 of 2)

Chapter 26. Monitoring and Optimizing Query Performance Tools

501

A A

QQKP QQKPN

A A A A A A A A A

QQKS QQDSS QQIDXA QQRCOD QQCST QQIDXD QQCSTN K QQJFLD S QQRID

RENAME(QQI3) + COLHDG('Number of Key' + 'Positioning' + 'Fields')

RENAME(QQC11) + COLHDG('Constraint' + 'Indicator') RENAME(QQ1000) + COLHDG('Constraint' + 'Name') CMP(EQ 3001)

Figure 21. Summary record for Using Existing Index (Part 2 of 2) Table 47. QQQ3001 - Summary record for Using Existing Index
Logical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB QQUSER QQJNUM QQTHRD QQUCNT QQUDEF QQQDTN QQQDTL QQMATN QQMATL QQTLN QQTFN QQTMN QQPTLN QQPTFN QQPTMN QQILNM QQIFNM QQIMNM QQTOTR QQREST Physical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB QQUSER QQJNUM QQI9 QQUCNT QQUDEF QQQDTN QQQDTL QQMATN QQMATL QQTLN QQTFN QQTMN QQPTLN QQPTFN QQPTMN QQILNM QQIFNM QQIMNM QQTOTR QQREST Description Record identication Time record was created Join eld (unique per job) Relational database name System name Job name Job user Job number Thread identier Unique count (unique per query) User dened eld QDT number (unique per QDT) QDT subquery nested level Materialized view QDT number Materialized view nested level Library File Member Physical library Physical le Physical member Index library Index le Index member Total rows in table Estimated number of rows selected

502

DB2 UDB for AS/400 SQL Programming V4R4

Table 47. QQQ3001 - Summary record for Using Existing Index (continued)
Logical Field Name QQFKEY QQKSEL QQAJN QQEPT QQJNP QQJNDS QQJNMT Physical Field Name QQFKEY QQKSEL QQAJN QQEPT QQJNP QQI1 QQC21 Description Keys selected thru key positioning Keys selected thru key selection Estimated number of joined rows Estimated processing time, in seconds Join position - when available Data space number Join method - when available NL - Nested loop MF - Nested loop with selection HJ - Hash join Join type - when available IN - Inner join PO - Left partial outer join EX - Exception join Join operator - when available EQ - Equal NE - Not equal GT - Greater than GE - Greater than or equal LT - Less than LE - Less than or equal CP - Cartesian product Number of advised key elds that use key positioning Key positioning Y - Yes N - No Key selection Y - Yes N - No Data space selection Y - Yes N - No Index advised Y - Yes N - No Reason code I1 - Record selection I2 - Ordering/Grouping I3 - Record selection and Ordering/Grouping I4 - Nested loop join I5 - Record selection using bitmap processing Constraint indicator Y - Yes N - No Key elds for index advised Constraint name

QQJNTY

QQC22

QQJNOP

QQC23

QQIDXK QQKP

QQI2 QQKP

QQKS

QQKS

QQDSS

QQDSS

QQIDXA

QQIDXA

QQRCOD

QQRCOD

QQCST

QQC11

QQIDXD QQCSTN

QQIDXD QQC1000

Chapter 26. Monitoring and Optimizing Query Performance Tools

503

|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 A* Database Monitor logical file 3002 A R QQQ3002 PFILE(*CURLIB/QAQQDBMN) A QQRID A QQTIME A QQJFLD A QQRDBN A QQSYS A QQJOB A QQUSER A QQJNUM A QQTHRD RENAME(QQI9) + COLHDG('Thread' + 'Identifier') A QQUCNT A QQUDEF A QQQDTN A QQQDTL A QQMATN A QQMATL A QQTLN A QQTFN A QQTMN A QQPTLN A QQPTFN A QQPTMN A QQILNM A QQIFNM A QQIMNM A QQNTNM A QQNLNM A QQSTIM A QQETIM A QQTOTR A QQRIDX A QQREST A QQFKEY A QQKSEL A QQAJN A QQJNP

Figure 22. Summary record for Index Created (Part 1 of 2)

504

DB2 UDB for AS/400 SQL Programming V4R4

A A A A A A A A A A A A A A A A

QQJNDS QQJNMT QQJNTY QQJNOP QQIDXK QQEPT QQKP QQKPN QQKS QQDSS QQIDXA QQRCOD QQIDXD QQCRTK K QQJFLD S QQRID

RENAME(QQI1) + COLHDG('Data Space' 'Number') RENAME(QQC21) + COLHDG('Join' 'Method') RENAME(QQC22) + COLHDG('Join' 'Type') RENAME(QQC23) + COLHDG('Join' 'Operator') RENAME(QQI2) + COLHDG('Advised' 'Primary' 'Keys') RENAME(QQI3) + COLHDG('Number of Key' + 'Positioning' + 'Fields')

RENAME(QQ1000) + COLHDG('Key Fields' + 'of Index' 'Created') CMP(EQ 3002)

Figure 22. Summary record for Index Created (Part 2 of 2) Table 48. QQQ3002 - Summary record for Index Created
Logical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB QQUSER QQJNUM QQTHRD QQUCNT QQUDEF QQQDTN QQQDTL QQMATN QQMATL QQTLN QQTFN QQTMN QQPTLN QQPTFN QQPTMN Physical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB QQUSER QQJNUM QQI9 QQUCNT QQUDEF QQQDTN QQQDTL QQMATN QQMATL QQTLN QQTFN QQTMN QQPTLN QQPTFN QQPTMN Description Record identication Time record was created Join eld (unique per job) Relational database name System name Job name Job user Job number Thread identier Unique count (unique per query) User dened eld QDT number (unique per QDT) QDT subquery nested level Materialized view QDT number Materialized view nested level Library File Member Physical library Physical le Physical member

Chapter 26. Monitoring and Optimizing Query Performance Tools

505

Table 48. QQQ3002 - Summary record for Index Created (continued)


Logical Field Name QQILNM QQIFNM QQIMNM QQNTNM QQNLNM QQSTIM QQETIM QQTOTR QQRIDX QQREST QQFKEY QQKSEL QQAJN QQEPT QQJNP QQJNDS QQJNMT Physical Field Name QQILNM QQIFNM QQIMNM QQNTNM QQNLNM QQSTIM QQETIM QQTOTR QQRIDX QQREST QQFKEY QQKSEL QQAJN QQEPT QQJNP QQI1 QQC21 Description Index library Index le Index member NLSS library NLSS table Start timestamp End timestamp Total rows in table Number of entries in index created Estimated number of rows selected Keys selected thru key positioning Keys selected thru key selection Estimated number of joined rows Estimated processing time, in seconds Join position - when available Data space number Join method - when available NL - Nested loop MF - Nested loop with selection HJ - Hash join Join type - when available IN - Inner join PO - Left partial outer join EX - Exception join Join operator - when available EQ - Equal NE - Not equal GT - Greater than GE - Greater than or equal LT - Less than LE - Less than or equal CP - Cartesian product Number of advised key elds that use key positioning Key positioning Y - Yes N - No Key selection Y - Yes N - No Data space selection Y - Yes N - No Index advised Y - Yes N - No

QQJNTY

QQC22

QQJNOP

QQC23

QQIDXK QQKP

QQI2 QQKP

QQKS

QQKS

QQDSS

QQDSS

QQIDXA

QQIDXA

506

DB2 UDB for AS/400 SQL Programming V4R4

Table 48. QQQ3002 - Summary record for Index Created (continued)


Logical Field Name QQRCOD Physical Field Name QQRCOD Description Reason code I1 - Record selection I2 - Ordering/Grouping I3 - Record selection and Ordering/Grouping I4 - Nested loop join Key elds for index advised Key elds for index created

QQIDXD QQCRTK

QQIDXD QQ1000

|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 A* A* Database Monitor logical file 3003 A* A R QQQ3003 PFILE(*CURLIB/QAQQDBMN) A QQRID A QQTIME A QQJFLD A QQRDBN A QQSYS A QQJOB A QQUSER A QQJNUM A QQTHRD RENAME(QQI9) + COLHDG('Thread' + 'Identifier') A QQUCNT A QQUDEF A QQQDTN A QQQDTL A QQMATN A QQMATL A QQSTIM A QQETIM A QQRSS A QQSSIZ RENAME(QQI1) + COLHDG('Size of' + 'Sort' + 'Space') A QQPSIZ RENAME(QQI2) + COLHDG('Pool' + 'Size') A QQPID RENAME(QQI3) + COLHDG('Pool' + 'ID') A QQIBUF RENAME(QQI4) + COLHDG('Internal' + 'Buffer' + 'Length') A QQEBUF RENAME(QQI5) + COLHDG('External' + 'Buffer' + 'Length') A QQRCOD A K QQJFLD A S QQRID CMP(EQ 3003)

Figure 23. Summary record for Query Sort

Chapter 26. Monitoring and Optimizing Query Performance Tools

507

Table 49. QQQ3003 - Summary record for Query Sort


Logical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB QQUSER QQJNUM QQTHRD QQUCNT QQUDEF QQQDTN QQQDTL QQMATN QQMATL QQSTIM QQETIM QQRSS QQSSIZ QQPSIZ QQPID QQIBUF QQEBUF QQRCOD Physical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB QQUSER QQJNUM QQI9 QQUCNT QQUDEF QQQDTN QQQDTL QQMATN QQMATL QQSTIM QQETIM QQRSS QQI1 QQI2 QQI3 QQI4 QQI5 QQRCOD Description Record identication Time record was created Join eld (unique per job) Relational database name System name Job name Job user Job number Thread identier Unique count (unique per query) User dened eld QDT number (unique per QDT) QDT subquery nested level Materialized view QDT number Materialized view nested level Start timestamp End timestamp Number of rows selected or sorted Size of sort space Pool size Pool id Internal sort buffer length External sort buffer length Reason code F1 Query contains grouping elds (GROUP BY) from more that one le, or contains grouping elds from a secondary le of a join query that cannot be reordered. Query contains ordering elds (ORDER BY) from more that one le, or contains ordering elds from a secondary le of a join query that cannot be reordered. The grouping and ordering elds are not compatible. DISTINCT was specied for the query. UNION was specied for the query. Query had to be implemented using a sort. Key length of more than 2000 bytes or more than 120 key elds specied for ordering. Query optimizer chose to use a sort rather than an access path to order the results of the query. Perform specied record selection to minimize I/O wait time.

F2

F3 F4 F5 F6

F7 F8

508

DB2 UDB for AS/400 SQL Programming V4R4

|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 A* A* Database Monitor logical file 3004 A* A R QQQ3004 PFILE(*CURLIB/QAQQDBMN) A QQRID A QQTIME A QQJFLD A QQRDBN A QQSYS A QQJOB A QQUSER A QQJNUM A QQTHRD RENAME(QQI9) + COLHDG('Thread' + 'Identifier') A QQUCNT A QQUDEF A QQQDTN A QQQDTL A QQMATN A QQMATL A QQTLN A QQTFN A QQTMN A QQSTIM A QQETIM A QQDFVL RENAME(QQC11) + COLHDG('Default' + 'Values') A QQTMPR A QQRCOD A K QQJFLD A S QQRID CMP(EQ 3004)

Figure 24. Summary record for Temporary File Table 50. QQQ3004 - Summary record for Temporary File
Logical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB QQUSER QQJNUM QQTHRD QQUCNT QQUDEF QQQDTN QQQDTL QQMATN QQMATL QQTLN Physical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB QQUSER QQJNUM QQI9 QQUCNT QQUDEF QQQDTN QQQDTL QQMATN QQMATL QQTLN Description Record identication Time record was created Join eld (unique per job) Relational database name System name Job name Job user Job number Thread identier Unique count (unique per query) User dened eld QDT number (unique per QDT) QDT subquery nested level Materialized view QDT number Materialized view nested level Library

Chapter 26. Monitoring and Optimizing Query Performance Tools

509

Table 50. QQQ3004 - Summary record for Temporary File (continued)


Logical Field Name QQTFN QQTMN QQSTIM QQETIM QQDFVL Physical Field Name QQTFN QQTMN QQSTIM QQETIM QQC11 Description File Member Start timestamp End timestamp Default values may be present in temporary Y - Yes N - No Number of rows in the temporary Reason code F1 Query contains grouping elds (GROUP BY) from more that one le, or contains grouping elds from a secondary le of a join query that cannot be reordered. Query contains ordering elds (ORDER BY) from more that one le, or contains ordering elds from a secondary le of a join query that cannot be reordered. The grouping and ordering elds are not compatible. DISTINCT was specied for the query. UNION was specied for the query Query had to be implemented using a sort. Key length of more than 2000 bytes or more than 120 key elds specied for ordering. Query optimizer chose to use a sort rather than an access path to order the results of the query. Perform specied record selection to minimize I/O wait time. File is a JLF and its join type does not match the join type specied in the query. Format specied for the logical le references more than 1 physical le. File is a complex SQL view or derived table requiring a temporary le to contain the result of the SQL view or derived table.

QQTMPR QQRCOD

QQTMPR QQRCOD

F2

F3 F4 F5 F6

F7 F8 F9 FA FB

510

DB2 UDB for AS/400 SQL Programming V4R4

|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 A* A* Database Monitor logical file 3005 A* A R QQQ3005 PFILE(*CURLIB/QAQQDBMN) A QQRID A QQTIME A QQJFLD A QQRDBN A QQSYS A QQJOB A QQUSER A QQJNUM A QQTHRD RENAME(QQI9) + COLHDG('Thread' + 'Identifier') A QQUCNT A QQUDEF A QQQDTN A QQQDTL A QQMATN A QQMATL A QQTLN A QQTFN A QQTMN A QQLCKF RENAME(QQC11) + COLHDG('Lock' + 'Indicator') A QQULCK RENAME(QQC12) + COLHDG('Unlock' + 'Request') A QQRCOD A K QQJFLD A S QQRID CMP(EQ 3005)

Figure 25. Summary record for Table Locked Table 51. QQQ3005 - Summary record for Table Locked
Logical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB QQUSER QQJNUM QQTHRD QQUCNT QQUDEF QQQDTN QQQDTL QQMATN QQMATL QQTLN Physical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB QQUSER QQJNUM QQI9 QQUCNT QQUDEF QQQDTN QQQDTL QQMATN QQMATL QQTLN Description Record identication Time record was created Join eld (unique per job) Relational database name System name Job name Job user Job number Thread identier Unique count (unique per query) User dened eld QDT number (unique per QDT) QDT subquery nested level Materialized view QDT number Materialized view nested level Library

Chapter 26. Monitoring and Optimizing Query Performance Tools

511

Table 51. QQQ3005 - Summary record for Table Locked (continued)


Logical Field Name QQTFN QQTMN QQLCKF Physical Field Name QQTFN QQTMN QQC11 Description File Member Successful lock indicator Y - Yes N - No Unlock request Y - Yes N - No Reason code L1 - UNION with *ALL or *CS with Keep Locks L2 - DISTINCT with *ALL or *CS with Keep Locks L3 - No duplicate keys with *ALL or *CS with Keep Locks L4 - Temporary needed with *ALL or *CS with Keep Locks L5 - System File with *ALL or *CS with Keep Locks L6 - Orderby > 2000 bytes with *ALL or *CS with Keep Locks L9 - Unknown

QQULCK

QQC12

QQRCOD

QQRCOD

|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 A* A* Database Monitor logical file 3006 A* A R QQQ3006 PFILE(*CURLIB/QAQQDBMN) A QQRID A QQTIME A QQJFLD A QQRDBN A QQSYS A QQJOB A QQUSER A QQJNUM A QQTHRD RENAME(QQI9) + COLHDG('Thread' + 'Identifier') A QQUCNT A QQUDEF A QQQDTN A QQQDTL A QQMATN A QQMATL A QQTLN A QQTFN A QQTMN A QQPTLN A QQPTFN A QQPTMN A QQRCOD A K QQJFLD A S QQRID CMP(EQ 3006)

Figure 26. Summary record for Access Plan Rebuilt

512

DB2 UDB for AS/400 SQL Programming V4R4

Table 52. QQQ3006 - Summary record for Access Plan Rebuilt


Logical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB QQUSER QQJNUM QQTHRD QQUCNT QQUDEF QQQDTN QQQDTL QQMATN QQMATL QQTLN QQTFN QQTMN QQPTLN QQPTFN QQPTMN Physical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB QQUSER QQJNUM QQI9 QQUCNT QQUDEF QQQDTN QQQDTL QQMATN QQMATL QQTLN QQTFN QQTMN QQPTLN QQPTFN QQPTMN Description Record identication Time record was created Join eld (unique per job) Relational database name System name Job name Job user Job number Thread identier Unique count (unique per query) User dened eld QDT number (unique per QDT) QDT subquery nested level Materialized view QDT number Materialized view nested level Library File Member Physical library Physical le Physical member

Chapter 26. Monitoring and Optimizing Query Performance Tools

513

Table 52. QQQ3006 - Summary record for Access Plan Rebuilt (continued)
Logical Field Name QQRCOD Physical Field Name QQRCOD Description Reason code why access plan was rebuilt A1 A le or member is not the same object as the one referenced when the access plan was last built. Some reasons they could be different are: v Object was deleted and recreated. v Object was saved and restored. v Library list was changed. v Object was renamed. v Object was moved. v Object was overridden to a different object. v This is the rst run of this query after the object containing the query has been restored. A2 A3 A4 A5 A6 A7 A8 A9 Access plan was built to use a reusable Open Data Path (ODP) and the optimizer chose to use a non-reusable ODP for this call. Access plan was built to use a non-reusable Open Data Path (ODP) and the optimizer chose to use a reusable ODP for this call. The number of records in the le member has changed by more than 10% since the access plan was last built. A new access path exists over one of the les in the query. An access path that was used for this access plan no longer exists or is no longer valid. OS/400 Query requires the access plan to be rebuilt because of system programming changes. The CCSID of the current job is different than the CCSID of the job that last created the access plan. The value of one or more of the following is different for the current job than it was for the job that last created this access plan: v date format v date separator v time format v time separator

AA AB AC AD AE AF B0

The sort sequence table specied is different than the sort sequence table that was used when this access plan was created. Storage pool changed or DEGREE parameter of CHGQRYA command changed. The system feature DB2 multisystem has been installed or removed. The value of the degree query attribute has changed. A view is either being opened by a high level language or a view is being materialized. A user-dened type or user-dened function is not the same object as the one referred to in the access plan. The options specied have changed as a result of the query options le QAQQINI.

514

DB2 UDB for AS/400 SQL Programming V4R4

Table 52. QQQ3006 - Summary record for Access Plan Rebuilt (continued)
Logical Field Name QQINLN QQINFN Physical Field Name QQC101 QQC102 Description Query Options Library Name Query Options File Name

|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 A* A* Database Monitor logical file 3007 A* A R QQQ3007 PFILE(*CURLIB/QAQQDBMN) A QQRID A QQTIME A QQJFLD A QQRDBN A QQSYS A QQJOB A QQUSER A QQJNUM A QQTHRD RENAME(QQI9) + COLHDG('Thread' + 'Identifier') A QQUCNT A QQUDEF A QQQDTN A QQQDTL A QQMATN A QQMATL A QQTLN A QQTFN A QQTMN A QQPTLN A QQPTFN A QQPTMN A QQIDXN RENAME(QQ1000) + COLHDG('Index' + 'Names') A QQTOUT RENAME(QQC11) + COLHDG('Optimizer' + 'Timed Out') A K QQJFLD A S QQRID CMP(EQ 3007)

Figure 27. Summary record for Optimizer Timed Out Table 53. QQQ3007 - Summary record for Optimizer Timed Out
Logical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB QQUSER QQJNUM QQTHRD Physical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB QQUSER QQJNUM QQI9 Description Record identication Time record was created Join eld (unique per job) Relational database name System name Job name Job user Job number Thread identier
Chapter 26. Monitoring and Optimizing Query Performance Tools

515

Table 53. QQQ3007 - Summary record for Optimizer Timed Out (continued)
Logical Field Name QQUCNT QQUDEF QQQDTN QQQDTL QQMATN QQMATL QQTLN QQTFN QQTMN QQPTLN QQPTFN QQPTMN QQIDXN QQTOUT Physical Field Name QQUCNT QQUDEF QQQDTN QQQDTL QQMATN QQMATL QQTLN QQTFN QQTMN QQPTLN QQPTFN QQPTMN QQ1000 QQC11 Description Unique count (unique per query) User dened eld QDT number (unique per QDT) QDT subquery nested level Materialized view QDT number Materialized view nested level Library File Member Physical library Physical le Physical member Index names Optimizer timed out Y - Yes N - No

|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 A* A* Database Monitor logical file 3008 A* A R QQQ3008 PFILE(*CURLIB/QAQQDBMN) A QQRID A QQTIME A QQJFLD A QQRDBN A QQSYS A QQJOB A QQUSER A QQJNUM A QQTHRD RENAME(QQI9) + COLHDG('Thread' + 'Identifier') A QQUCNT A QQUDEF A QQQDTN A QQQDTL A QQMATN A QQMATL A QQORGQ RENAME(QQI1) + COLHDG('Original' + 'Number' + 'of QDTs') A QQMRGQ RENAME(QQI2) + COLHDG('Number' + 'of QDTs' + 'Merged') A K QQJFLD A S QQRID CMP(EQ 3008)

Figure 28. Summary record for Subquery Processing

516

DB2 UDB for AS/400 SQL Programming V4R4

Table 54. QQQ3008 - Summary record for Subquery Processing


Logical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB QQUSER QQJNUM QQTHRD QQUCNT QQUDEF QQQDTN QQQDTL QQMATN QQMATL QQORGQ QQMRGQ Physical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB QQUSER QQJNUM QQI9 QQUCNT QQUDEF QQQDTN QQQDTL QQMATN QQMATL QQI1 QQI2 Description Record identication Time record was created Join eld (unique per job) Relational database name System name Job name Job user Job number Thread identier Unique count (unique per query) User dened eld QDT number (unique per QDT) QDT subquery nested level Materialized view QDT number Materialized view nested level Original number of QDTs Number of QDTs merged

Chapter 26. Monitoring and Optimizing Query Performance Tools

517

|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 A* A* Database Monitor logical file 3010 A* A R QQQ3010 PFILE(*CURLIB/QAQQDBMN) A QQRID A QQTIME A QQJFLD A QQRDBN A QQSYS A QQJOB A QQUSER A QQJNUM A QQTHRD RENAME(QQI9) + COLHDG('Thread' + 'Identifier') A QQUCNT A QQRCNT RENAME(QQI5) + COLHDG('Refresh' + 'Counter') A QQUDEF A QQODPI RENAME(QQC11) + COLHDG('ODP' + 'Implementation') A QQHVI RENAME(QQC12) + COLHDG('Host Variable' + 'Implementation') A QQHVAR RENAME(QQ1000) + COLHDG('Host Variable' + 'Values') A K QQJFLD A S QQRID CMP(EQ 3010)

Figure 29. Summary record for Host Variable and ODP Implementation Table 55. QQQ3010 - Summary record for Host Variable and ODP Implementation
Logical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB QQUSER QQJNUM QQTHRD QQUCNT QQRCNT QQUDEF QQODPI Physical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB QQUSER QQJNUM QQI9 QQUCNT QQRCNT QQUDEF QQC11 Description Record identication Time record was created Join eld (unique per job) Relational database name System name Job name Job user Job number Thread identier Unique count (unique per query) Unique refresh counter User dened eld ODP implementation R - Reusable ODP (ISV) N - Nonreusable ODP (V2) - Field not used

518

DB2 UDB for AS/400 SQL Programming V4R4

Table 55. QQQ3010 - Summary record for Host Variable and ODP Implementation (continued)
Logical Field Name QQHVI Physical Field Name QQC12 Description Host variable implementation I - Interface supplied values (ISV) V - Host variables treated as literals (V2) U - File management row positioning (UP) Host variable values

QQHVAR

QQ1000

|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 A* A* Database Monitor logical file 3014 A* A R QQQ3014 PFILE(*CURLIB/QAQQDBMN) A QQRID A QQTIME A QQJFLD A QQRDBN A QQSYS A QQJOB A QQUSER A QQJNUM A QQTHRD RENAME(QQI9) + COLHDG('Thread' + 'Identifier') A QQUCNT A QQUDEF A QQQDTN A QQQDTL A QQMATN A QQMATL A QQREST A QQEPT A QQTTIM RENAME(QQI1) + COLHDG('ODP' + 'Open' 'Time') A QQORDG A QQGRPG A QQJNG A QQJNTY RENAME(QQC22) + COLHDG('Join' + 'Type')

Figure 30. Summary record for Generic Query Information (Part 1 of 2)

Chapter 26. Monitoring and Optimizing Query Performance Tools

519

A A A A A

QQUNIN QQSUBQ QQHSTV QQRCDS QQGVNE

QQGVNS

A A

QQOPID QQINFN

QQINLN

QQIDXSK

A A

K QQJFLD S QQRID

RENAME(QQC11) + COLHDG('Query' + 'Governor' + 'Enabled') RENAME(QQC12) + COLHDG('Stopped' + 'by Query' + 'Governor') RENAME(QQC101) + COLHDG('Query' + 'Open ID') RENAME(QQC102) + COLHDG('Query' + 'Options' + 'File Name') RENAME(QQC103) + COLHDG('Query' + 'Options' + 'Library') RENAME(QQC13) + COLHDG('Index' + 'Skip Key') + "Processing') CMP(EQ 3014)

Figure 30. Summary record for Generic Query Information (Part 2 of 2) Table 56. QQQ3014 - Summary record for Generic Query Information
Logical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB QQUSER QQJNUM QQTHRD QQUCNT QQUDEF QQQDTN QQQDTL QQMATN QQMATL QQREST QQEPT QQTTIM Physical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB QQUSER QQJNUM QQI9 QQUCNT QQUDEF QQQDTN QQQDTL QQMATN QQMATL QQREST QQEPT QQI1 Description Record identication Time record was created Join eld (unique per job) Relational database name System name Job name Job user Job number Thread identier Unique count (unique per query) User dened eld QDT number (unique per query) QDT subquery nested level Materialized view QDT number Materialized view nested level Estimated number of rows selected Estimated processing time, in seconds Time spent to open cursor, in milliseconds

520

DB2 UDB for AS/400 SQL Programming V4R4

Table 56. QQQ3014 - Summary record for Generic Query Information (continued)
Logical Field Name QQORDG Physical Field Name QQORDG Description Ordering Y - Yes N - No Grouping Y - Yes N - No Joining Y - Yes N - No Join type - when available IN - Inner join PO - Left partial outer join EX - Exception join Union Y - Yes N - No Subquery Y - Yes N - No Host variables Y - Yes N - No Record selection Y - Yes N - No Query governor enabled Y - Yes N - No Query governor stopped the query Y - Yes N - No Query open ID Query Options Library Name Query Options File Name Index skip key processing indicator Y - Yes N - No

QQGRPG

QQGRPG

QQJNG

QQJNG

QQJNTY

QQC22

QQUNIN

QQUNIN

QQSUBQ

QQSUBQ

QQHSTV

QQHSTV

QQRCDS

QQRCDS

QQGVNE

QQC11

QQGVNS

QQC12

QQOPID QQINLN QQINFN QQIDXSK

QQC101 QQC102 QQC103 QQC13

Chapter 26. Monitoring and Optimizing Query Performance Tools

521

|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 A* A* Database Monitor logical file 3018 A* A R QQQ3018 PFILE(*CURLIB/QAQQDBMN) A QQRID A QQTIME A QQJFLD A QQRDBN A QQSYS A QQJOB A QQUSER A QQJNUM A QQTHRD RENAME(QQI9) + COLHDG('Thread' + 'Identifier') A QQUDEF A QQJOBT RENAME(QQC11)+ COLHDG('Job' + 'Type') A QQCMDT RENAME(QQC12) + COLHDG('Command' + 'Type') A QQJOBI RENAME(QQC301) + COLHDG('Job' + 'Info') A K QQJFLD A S QQRID CMP(EQ 3018)

Figure 31. Summary record for STRDBMON/ENDDBMON Table 57. QQQ3018 - Summary record for STRDBMON/ENDDBMON
Logical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB QQUSER QQJNUM QQTHRD QQUDEF QQJOBT Physical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB QQUSER QQJNUM QQI9 QQUDEF QQC11 Description Record identication Time record was created Join eld (unique per job) Relational database name System name Job name Job user Job number Thread identier User dened eld Type of job monitored C - Current J - Job name A - All Command type S - STRDBMON E - ENDDBMON Monitored job information * - Current job Job number/User/Job name *ALL - All jobs

QQCMDT

QQC12

QQJOBI

QQC301

522

DB2 UDB for AS/400 SQL Programming V4R4

|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 A* A* Database Monitor logical file 3019 A* A R QQQ3019 PFILE(*CURLIB/QAQQDBMN) A QQRID A QQTIME A QQJFLD A QQRDBN A QQSYS A QQJOB A QQUSER A QQJNUM A QQTHRD RENAME(QQI9) + COLHDG('Thread' + 'Identifier') A QQUCNT A QQUDEF A QQQDTN A QQQDTL A QQMATN A QQCPUT RENAME(QQI1) + COLHDG('Record' + 'Retrieval' + 'CPU Time') A QQCLKT RENAME(QQI2) + COLHDG('Record' + 'Retrieval' + 'Clock Time') A QQSYNR RENAME(QQI3) + COLHDG('Synch' + 'Reads') A QQSYNW RENAME(QQI4) + COLHDG('Synch' + 'Writes') A QQASYR RENAME(QQI5) + COLHDG('Asynch' + 'Reads') A QQASYW RENAME(QQI6) + COLHDG('Asynch' + 'Writes') A QQRCDR RENAME(QQI7) + COLHDG('Records' + 'Returned') A QQGETC RENAME(QQI8) + COLHDG('Number' + 'of GETs') A K QQJFLD A S QQRID CMP(EQ 3019)

Figure 32. Detail record for Records Retrieved Table 58. QQQ3019 - Detail record for Records Retrieved
Logical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB Physical Field Name QQRID QQTIME QQJFLD QQRDBN QQSYS QQJOB Description Record identication Time record was created Join eld (unique per job) Relational database name System name Job name

Chapter 26. Monitoring and Optimizing Query Performance Tools

523

Table 58. QQQ3019 - Detail record for Records Retrieved (continued)


Logical Field Name QQUSER QQJNUM QQTHRD QQUCNT QQUDEF QQQDTN QQQDTL QQMATN QQMATL QQCPUT QQCLKT QQSYNR QQSYNW QQASYR QQASYW QQRCDR QQGETC Physical Field Name QQUSER QQJNUM QQI9 QQUCNT QQUDEF QQQDTN QQQDTL QQMATN QQMATL QQI1 QQI2 QQI3 QQI4 QQI5 QQI6 QQI7 QQI8 Description Job user Job number Thread identier Unique count (unique per query) User dened eld QDT number (unique per query) QDT subquery nested level Materialized view QDT number Materialized view nested level CPU time to return all records, in milliseconds Clock time to return all records, in milliseconds Number of synchronous database reads Number of synchronous database writes Number of asynchronous database reads Number of asynchronous database writes Number of records returned Number of calls to retrieve records returned

Memory Resident Database Monitor APIs


The Memory Resident Database Monitor (DBMon) is a tool that provides another method for monitoring database performance. This tool is only intended for SQL performance monitoring and is useful for programmers and performance analysts. The DBMon monitor, with the help of a new set of APIs, takes database monitoring statistics and manages them for the user in memory. This memory-based monitor reduces CPU overhead as well as resulting le sizes. The Start Database Monitor (STRDBMON) can constrain system resources when collecting performance information. This overhead is mainly attributed to the fact that performance information is written directly to a database le as the information is collected. The memory-based collection mode reduces the system resources consumed by collecting and managing performance results in memory. This allows the monitor to gather database performance statistics with a minimal impact to the performance of the system as whole (or to the performance of individual SQL statements). The DBMon monitor collects much of the same information as the STRDBMON monitor, but the performance statistics are kept in memory. At the expense of some detail, information is summarized for identical SQL statements to reduce the amount of information collected. The objective is to get the statistics to memory as fast as possible while deferring any manipulation or conversion of the data until the performance data is dumped to a result le for analysis.

524

DB2 UDB for AS/400 SQL Programming V4R4

The DBMon monitor is not meant to replace the STRDBMON monitor. There are circumstances where the loss of detail in the DBMon monitor will not be sufficient to fully analyze an SQL statement. In these cases, the STRDBMON monitor should still be used. The DBMon monitor manages the data in memory combining and accumulating the information into a series of record formats. This means that for each unique SQL statement, information is accumulated from each run of the statement and the detail information is only collected for the most expensive statement execution. Each SQL statement is identied by the monitor according to the: v statement name v package (or program) v library that contains the prepared statement v cursor name that is used For pure dynamic statements, the statement text is kept in a separate space and the statement identication will be handled internally via a pointer. | | | | | | | | | | | | A new set of APIs enable support for the DBMon monitor. An API supports each of the following activities: v Start the new monitor v Dump statistics to les v Clear the monitor data from memory v Query the monitor status v End the new monitor When you start the new monitor, information is stored in the local address space of each job that the system monitors. As each statement completes, the system moves information from the local job space to a common system space. If more statements are executed than can t in this amount of common system space, the system drops the statements that have not been executed recently.

External API Description


The memory resident database monitor is controlled by a set of APIs. For additional information, see the System API Reference manual.
Table 59. External API Description
QQQSSDBM QQQCSDBM QQQDSDBM QQQESDBM QQQQSDBM API to start the SQL monitor API to clear SQL monitor memory API to dump the contents of the SQL monitor to le API to end the SQL monitor API to query status of the database monitor

External File Description


The memory resident database monitor uses its own set of physical les instead of using the single physical with logical les that the STRDBMON monitor uses. The memory resident database monitor les closely match the suggested logical les of the STRDBMON monitor.

Chapter 26. Monitoring and Optimizing Query Performance Tools

525

Table 60. External File Description


QAQQQRYI QAQQTEXT QAQQ3000 QAQQ3001 QAQQ3002 QAQQ3003 QAQQ3004 QAQQ3007 QAQQ3008 QAQQ3010 Query (SQL) information SQL statement text Table scan Index used Index created Sort Temporary le Optimizer time out/ all access paths considered Subquery Host variable values

The information relating to the locked tables (QQQ3005) was omitted and the replan information was combined with the QAQQQRYI, and QQQ3010 (ODP and host variable information) is found in both QAQQ3010 and QAQQQRYI les.

External File Description (QAQQQRYI)


Table 61. QAQQQRYI - Summary Record for SQL Information
Column Name QQKEY QQTIME QQJOB QQUSER QQJNUM QQTHID QQUDEF QQPLIB QQPNAM QQSNAM QQCNT QQAVGT QQMINT QQMAXT QQOPNT QQFETT QQCLST QQOTHT QQLTU QQMETU QQAPRT QQFULO QQPSUO Description Join eld (unique per query) used to link records for a single query together Time record was created Job name Job user Job number Thread Id User dened eld Name of the library containing the program or package Name of the package or name of the program that contains the current SQL statement Name of the sttement for SQL statement, if applicable Statement usage count Average runtime (ms) Minimum runtime (ms) Maximum runtime (ms) Open time for most expensive execution (ms) Fetch time for most expensive execution (ms) Close time for most expensive execution (ms) Other time for most expensive execution (ms) Time statement last used Most expensive time used Access plan rebuild time Number of full opens Number of pseudo-opens

526

DB2 UDB for AS/400 SQL Programming V4R4

Table 61. QAQQQRYI - Summary Record for SQL Information (continued)


Column Name QQTOTR QQRROW QQRROW Description Total rows in le if non-join Number of result rows returned Statement function S - SelectU - Update I - Insert D - Delete L - Data denition language O - Other Statement operation AL - Alter table CA - Call CC - Create collection or Create schema CD - Create distinct type CF - Create function CI - Create index CL - Close CO - Comment on CM - Commit CN - Connect CP - Create procedure CS - Create alias CT - Create table CV - Create view DC- Declare cursor DP - Declare procedure DL - Delete DE - Describe DT - Describe table DI - Disconnect DR - Drop EX - Execute EI - Execute immediate FE - Fetch FC - Fetch/Close FL - Free locator GR - Grant IN - Insert LO - Label on LK - Lock OP - Open OC - Open/Fetch/Close OD - Open/Fetch/Close/Delete OF - Open/Fetch OU - Open/Fetch/Close/Update PR - Prepare RE - Release RT - Rename table RV - Revoke RO - Rollback SI - Select into SC - Set connection SV - Set variable SP - Set path SR - Set results ST - Set transaction UP - Update

QQSTOP

Chapter 26. Monitoring and Optimizing Query Performance Tools

527

Table 61. QAQQQRYI - Summary Record for SQL Information (continued)


Column Name QQODPI Description ODP implementation R - Reusable ODP (ISV) N - Non-reusable ODP (V2) Host variable implementation I - Interface supplied values (ISV) V - Host variables treated as literals (V2) U - File management row positioning (UP) Access plan rebuilt A1 A le or member is not the same object as the one referenced when the access plan was last built. Some reasons they could be different are: v Object was deleted and recreated. v Object was saved and restored. v Library list was changed. v Object was renamed. v Object was moved. v Object was overridden to a different object. v This is the rst run of this query after the object containing the query has been restored. A2 A3 A4 A5 A6 A7 A8 A9 Access plan was built to use a reusable Open Data Path (ODP) and the optimizer chose to use a non-reusable ODP for this call. Access plan was built to use a non-reusable Open Data Path (ODP) and the optimizer chose to use a reusable ODP for this call. The number of records in the le member has changed by more than 10% since the access plan was last built. A new access path exists over one of the les in the query. An access path that was used for this access plan no longer exists or is no longer valid. OS/400 Query requires the access plan to be rebuilt because of system programming changes. The CCSID of the current job is different than the CCSID of the job that last created the access plan. The value of one or more of the following is different for the current job than it was for the job that last created this access plan: v date format v date separator v time format v time separator

QQHVI

QQAPR

528

DB2 UDB for AS/400 SQL Programming V4R4

Table 61. QAQQQRYI - Summary Record for SQL Information (continued)


Column Name Description AA AB AC AD AE AF B0 The sort sequence table specied is different than the sort sequence table that was used when this access plan was created. Storage pool changed or DEGREE parameter of CHGQRYA command changed. The system feature DB2 multisystem has been installed or removed. The value of the degree query attribute has changed. A view is either being opened by a high level language or a view is being materialized. A user-dened type or user-dened function is not the same object as the one referred to in the access plan. The options specied have changed as a result of the query options le QAQQINI.

QQDACV

Data conversion N 0 1 2 3 4 5 6 7 8 9 No. Not applicable. Lengths do not match. Numeric types do not match. C host variable is NUL-terminated. Host variable or column is variable length and the other s not variable length. CCSID conversion. DRDA and NULL capable, variable ength, contained in a partial row, derived expression, or blocked fetch with not enough host variables. Data, time, or timestamp column. Too many host variables. Target table of an insert is not an SQL table.

QQCTS QQCIU QQCIC QQCSO QQCTF QQCIA QQCAPR QQARSS QQC11 QQCTS QQC12 QQC21 QQC22 QQI1

Statement table scan usage count Statement index usage count Statement index creation count Statement sort usage countr Statement temporary le count Statement index advised count Statement access plan rebuild count Average result set size Statement temporary le count Reserved Reserved Reserved Reserved Reserved
Chapter 26. Monitoring and Optimizing Query Performance Tools

529

Table 61. QAQQQRYI - Summary Record for SQL Information (continued)


Column Name QQI2 QQC301 QQC302 QQC1000 Description Reserved Reserved Reserved Reserved

External File Description (QAQQTEXT)


Table 62. QAQQTEXT - Summary Record for SQL Statement
Column Name QQKEY QQTIME QQSTTX QQC11 QQC12 QQC21 QQC22 QQQI1 QQI2 QQC301 QQC302 QQ1000 Description Join eld (unique per query) used to link records for a single query togetherecord identication Time record was created Statement text Reserved Reserved Reserved Reserved Reserved Reserved Reserved Reserved Reserved

External File Description (QAQQ3000)


Table 63. QAQQ3000 - Summary Record for Arrival Sequence
Column Name QQKEY QQTIME QQQDTN QQQDTL QQMATN QQMATL QQTLN QQPTFN QQTOTR QQREST QQAJN QQEPT QQJNP QQJNDS Description Join eld (unique per query) used to link records for a single query togetherecord identication Time record was created QDT number (unique per ODT) QDT subquery nested level Materialized view QDT number Materialized view nested level Physical library Physical le Total rows in table Estimated number of rows selected Estimated number of joined rows Estimated procesing time, in seconds Join position - when available Data space number

530

DB2 UDB for AS/400 SQL Programming V4R4

Table 63. QAQQ3000 - Summary Record for Arrival Sequence (continued)


Column Name QQJNMT Description Join method - when available NL - Nested loop MF - Nested loop with selection HJ - Hash join Join type - when available IN - Inner join PO - Left partial outer join EX - Exception join Join operator - when available EQ - Equal NE - Not equal GT - Greater than GE - Greater than or equal LT - Less than LE - Less than or equal CP - Cartesian product Data space selection Y - Yes N - No Index advised Y - Yes N - No Reason code T1 - No indexes exist. T2 - Indexes exist, but none could be used. T3 - Optimizer chose table scan over available indexes. Library-long File-long Physical library-long Physical le-long Key elds for the index advised Reserved Reserved Reserved Reserved Reserved Reserved Reserved Reserved Reserved

QQJNTY

QQJNOP

QQDSS

QQIDXA

QQRCOD

QQLTLN QQLTFN QQLPTL QQLPTF QQIDXD QQC11 QQC12 QQC21 QQC22 QQI1 QQI2 QQC301 QQC302 QQ1000

External File Description (QAQQ3001)


Table 64. QQQ3001 - Summary Record for Using Existing Index
Column Name QQKEY QQTIME Description Join eld (unique per query) used to link records for a single query together Time record was created

Chapter 26. Monitoring and Optimizing Query Performance Tools

531

Table 64. QQQ3001 - Summary Record for Using Existing Index (continued)
Column Name QQQDTN QQQDTL QQMATN QQMATL QQTLN QQTFN QQILNM QQIFNM QQTOTR QQREST QQAJN QQEPT QQJNMT Description QDT number (unique per QDT) RQDT subquery nested levelelational database name Materialized view QDT number Materialized view nested level Library File Index library Index le Total rows in table Estimated number of rows selected Join position - when available Estimated procesing time, in seconds Join method - when available NL - Nested loop MF - Nested loop with selection HJ - Hash join Join type - when available IN - Inner join PO - Left partial outer join EX - Exception join Join operator - when available EQ - Equal NE - Not equal GT - Greater than GE - Greater than or equal LT - Less than LE - Less than or equal CP - Cartesian product Number of advised key elds that use key positioning Key positioning Y - Yes N - No Key selection Y - Yes N - No Data space selection Y - Yes N - No Index advised Y - Yes N - No

QQJNTY

QQJNOP

QQIDXK QQKP

QQKS

QQDSS

QQIDXA

532

DB2 UDB for AS/400 SQL Programming V4R4

Table 64. QQQ3001 - Summary Record for Using Existing Index (continued)
Column Name QQRCOD Description Reason code I1 - Record selection I2 - Ordering/Grouping I3 - Record selection and Ordering/Grouping I4 - Nested loop join I5 - Record selection using bitmap processing Constraint indicator Y - Yes N - No Constraint name Library-long File-long Physical library-long Physical le-long Key elds for the index advised Reserved Reserved Reserved Reserved Reserved Reserved Reserved Reserved Reserved

QQCST

QQCSTN QQLTLN QQLTFN QQLPTL QQLPTF QQIDXD QQC11 QQC12 QQC21 QQC22 QQI1 QQI2 QQC301 QQC302 QQ1000

External File Description (QAQQ3002)


Table 65. QQQ3002 - Summary Rrecord for Index Created
Column Name QQKEY QQTIME QQQDTN QQQDTL QQMATN QQMATL QQTLN QQTFN QQILNM QQIFNM QQNTNM QQNLNM QQTOTR Description Join eld (unique per query) used to link records for a single query together Time record was created QDT number (unique per QDT) RQDT subquery nested levelelational database name Materialized view QDT number Materialized view nested level Library File Index library Index le NLSS table NLSS library Total rows in table
Chapter 26. Monitoring and Optimizing Query Performance Tools

533

Table 65. QQQ3002 - Summary Rrecord for Index Created (continued)


Column Name QQRIDX QQREST QQFKEY QQKSEL QQAJN QQJNP QQJNDS QQJNMT Description Number of entries in index created Estimated number of rows selected Number of key positioning keys Number of key selection keys Estimated number of joined rows Join position - when available Data space number Join method - when available NL - Nested loop MF - Nested loop with selection HJ - Hash join Join type - when available IN - Inner join PO - Left partial outer join EX - Exception join Join operator - when available EQ - Equal NE - Not equal GT - Greater than GE - Greater than or equal LT - Less than LE - Less than or equal CP - Cartesian product Number of advised key elds that use key positioning Estimated procesing time, in seconds Key positioning Y - Yes N - No Number of key positioning elds Key selection Y - Yes N - No Data space selection Y - Yes N - No Index advised Y - Yes N - No Reason code I1 - Record selection I2 - Ordering/Grouping I3 - Record selection and Ordering/Grouping I4 - Nested loop join I5 - Record selection using bitmap processing Constraint indicator Y - Yes N - No

QQJNTY

QQJNOP

QQIDXK QQEPT QQKP

QQKPN QQKS

QQDSS

QQIDXA

QQRCOD

QQCST

534

DB2 UDB for AS/400 SQL Programming V4R4

Table 65. QQQ3002 - Summary Rrecord for Index Created (continued)


Column Name QQCSTN QQTTIM QQLTLN QQLTFN QQLPTL QQLPTF QQLILN QQLIFN QQLNTN QQLNLN QQIDXD QQCRTK QQC11 QQC12 QQC21 QQC22 QQI1 QQI2 QQC301 QQC302 QQ1000 Description Constraint name Index create time Library-long File-long Physical library-long Physical le-long Index library-long Index le-long NLSS table-long NLSS library-long Key elds for the index advised Key elds for index created Reserved Reserved Reserved Reserved Reserved Reserved Reserved Reserved Reserved

External File Description (QAQQ3003)


Table 66. QQQ3003 - Summary Record for Query Sort
Column Name QQKEY QQTIME QQQDTN QQQDTL QQMATN QQMATL QQTTIM QQRSS QQSIZ QQPSIZ QQPID QQIBUF QQEBUF Description Join eld (unique per query) used to link records for a single query together Time record was created QDT number (unique per QDT) RQDT subquery nested levelelational database name Materialized view QDT number Materialized view nested level Sort time Number of rows selected or sorted Size of sort space Pool size Pool id Internal sort buffer length External sort buffer length

Chapter 26. Monitoring and Optimizing Query Performance Tools

535

Table 66. QQQ3003 - Summary Record for Query Sort (continued)


Column Name QQRCOD Description Reason code F1 F2 F3 F4 F5 F6 F7 F8 QQC11 QQC12 QQC21 QQC22 QQI1 QQI2 QQC301 QQC302 QQ1000 Query contains grouping elds (Group By) from more than one le, or contains grouping elds from a secondary le of a join query that cannot be reordered. Query contains ordering elds (Order By) from more than one le, or contains ordering elds from a secondary le of a join query that cannot be reordered. The grouping and ordering elds are not compatible. DISTINCT was specied for the query. UNION was specied for the query. Query had to be implemented using a sort. Key length of more than 2000 bytes or more than 120 elds specied for ordering. Query optimizer chose to use a sort rather than an access path to order the results of the query. Perform specied record selection to minimize I/O wait time.

Reserved Reserved Reserved Reserved Reserved Reserved Reserved Reserved Reserved

External File Description (QAQQ3004)


Table 67. QQQ3004 - Summary Record for Temporary File
Column Name QQKEY QQTIME QQQDTN QQQDTL QQMATN QQMATL QQTLN QQTFN QQTTIM QQTMPR Description Join eld (unique per query) used to link records for a single query together Time record was created QDT number (unique per QDT) RQDT subquery nested levelelational database name Materialized view QDT number Materialized view nested level Library File Temporary le create time Number of rows in temporary

536

DB2 UDB for AS/400 SQL Programming V4R4

Table 67. QQQ3004 - Summary Record for Temporary File (continued)


Column Name QQRCOD Description Reason code F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB Query contains grouping elds (Group By) from more than one le, or contains grouping elds from a secondary le of a join query that cannot be reordered. Query contains ordering elds (Order By) from more than one le, or contains ordering elds from a secondary le of a join query that cannot be reordered. The grouping and ordering elds are not compatible. DISTINCT was specied for the query. UNION was specied for the query. Query had to be implemented using a sort. Key length of more than 2000 bytes or more than 120 elds specied for ordering. Query optimizer chose to use a sort rather than an access path to order the results of the query. Perform specied record selection to minimize I/O wait time. File is a JLF and its join type does not match the join type specied in the query. Format specied for the logical le references more than one physical le. File is a complex SQL view requiring a temporary le to contain the results of the SQL view.

QQDFVL

Default values may be present in temporary Y - Yes N - No Library-long File-long Reserved Reserved Reserved Reserved Reserved Reserved Reserved Reserved Reserved

QQLTLN QQLTFN QQC11 QQC12 QQC21 QQC22 QQI1 QQI2 QQC301 QQC302 QQ1000

External File Description (QAQQ3007)


Table 68. QQQ3007 - Summary Record for Optimizer Information
Column Name QQKEY QQTIME QQQDTN QQQDTL QQMATN Description Join eld (unique per query) used to link records for a single query together Time record was created QDT number (unique per QDT) RQDT subquery nested levelelational database name Materialized view QDT number

Chapter 26. Monitoring and Optimizing Query Performance Tools

537

Table 68. QQQ3007 - Summary Record for Optimizer Information (continued)


Column Name QQMATL QQTLN QQTFN QQPTLN QQPTFN QQTOUT Description Materialized view nested level Library File Physical library Physical le Optimizer timed out Y - Yes N - No. Reason code Library-long File-long Physical library-long Physical le-long Index names Reserved Reserved Reserved Reserved Reserved Reserved Reserved Reserved Reserved

QQIRSN QQLTLN QQLTFN QQPTL QQPTF QQIDXN QQC11 QQC12 QQC21 QQC22 QQI1 QQI2 QQC301 QQC302 QQ1000

External File Description (QAQQ3008)


Table 69. QQQ3008 - Summary Record for Subquery Processing
Column Name QQKEY QQTIME QQQDTN QQQDTL QQMATN QQMATL QQORGQ QQMRGQ QQC11 QQC12 QQC21 QQC22 QQI1 QQI2 Description Join eld (unique per query) used to link records for a single query together Time record was created QDT number (unique per QDT) RQDT subquery nested levelelational database name Materialized view QDT number Materialized view nested level Materialized view QDT number Materialized view nested level Reserved Reserved Reserved Reserved Reserved Reserved
DB2 UDB for AS/400 SQL Programming V4R4

538

Table 69. QQQ3008 - Summary Record for Subquery Processing (continued)


Column Name QQC301 QQC302 QQ1000 Description Reserved Reserved Reserved

External File Description (QAQQ3010)


Table 70. QQQ3010 - Summary Record for Host Variable and ODP Implementation
Column Name QQKEY QQTIME QQHVAR QQC11 QQC12 QQC21 QQC22 QQI1 QQI2 QQC301 QQC302 Description Join eld (unique per query) used to link records for a single query together Time record was created Host variable values Reserved Reserved Reserved Reserved Reserved Reserved Reserved Reserved

Sample SQL Queries


| | | | | | | | | | | | | | | | | | | | | | | | | | | | As with the STRDBMON monitor, it is up to the user to extract the information from the les in which all of the monitored data is stored. This can be done through any query interface that the user wishes. If you are using Operation Navigator with the support for the SQL Monitor, you have the ability to analyze the results direct through the GUI interface. There are a number of shipped queries that can be used or modied to extract the information from any of the les. The sample query listed below will give the user the Basic Statement Information about all of the statements that were monitored.
SELECT /* Database Performance Monitor Basic Statement Information */ /* Time */ a.QQTIME as "Time", /* Costs */ DECIMAL(QQMAXT/1000,18,3) DECIMAL(QQAVGT/1000,18,3) DECIMAL(QQMINT/1000,18,3) DECIMAL(QQOPNT/1000,18,3) DECIMAL(QQFETT/1000,18,3) DECIMAL(QQCLST/1000,18,3) DECIMAL(QQOTHT/1000,18,3) QQMETU as "Most Expensive QQLTU as "Last Use", as "Maximum as "Average as "Minimum as "Maximum as "Maximum as "Maximum as "Maximum Use", Runtime", Runtime", Runtime", Open Time", Fetch Time ", Close Time", Other Time ",

/* Statement Identification */ CASE QQSTOP


Chapter 26. Monitoring and Optimizing Query Performance Tools

539

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

WHEN 'AL' THEN 'ALTER TABLE' WHEN 'CA' THEN 'CALL' WHEN 'CD' THEN 'CREATE DISTINCT TYPE' WHEN 'CF' THEN 'CREATE FUNCTION' WHEN 'CL' THEN 'CLOSE' WHEN 'CO' THEN 'COMMENT ON' WHEN 'CM' THEN 'COMMIT' WHEN 'CN' THEN 'CONNECT' WHEN 'CC' THEN 'CREATE COLLECTION' WHEN 'CI' THEN 'CREATE INDEX' WHEN 'CP' THEN 'CREATE PROCEDURE' WHEN 'CS' THEN 'CREATE ALIAS' WHEN 'CT' THEN 'CREATE TABLE' WHEN 'CV' THEN 'CREATE VIEW' WHEN 'DC' THEN 'DECLARE CURSOR' WHEN 'DD' THEN 'DELETE...DELETE' WHEN 'DE' THEN 'DESCRIBE' WHEN 'DF' THEN 'DELETE...FETCH' WHEN 'DI' THEN 'DISCONNECT' WHEN 'DK' THEN 'DELETE...CLOSE' WHEN 'DL' THEN 'DELETE' WHEN 'DP' THEN 'DECLARE PROCEDURE' WHEN 'DR' THEN 'DROP' WHEN 'DT' THEN 'DESCRIBE TABLE' WHEN 'DU' THEN 'DELETE...UPDATE' WHEN 'EX' THEN 'EXECUTE' WHEN 'EI' THEN 'EXECUTE IMMEDIATE' WHEN 'FC' THEN 'FETCH...CLOSE' WHEN 'FD' THEN 'FETCH...DELETE' WHEN 'FE' THEN 'FETCH' WHEN 'FF' THEN 'FETCH...FETCH' WHEN 'FL' THEN 'FREE LOCATOR' WHEN 'FU' THEN 'FETCH...UPDATE' WHEN 'GR' THEN 'GRANT' WHEN 'IC' THEN 'INSERT' WHEN 'IN' THEN 'INSERT' WHEN 'LO' THEN 'LABEL ON' WHEN 'LK' THEN 'LOCK' WHEN 'OC' THEN 'OPEN...CLOSE' WHEN 'OD' THEN 'OPEN...DELETE' WHEN 'OF' THEN 'OPEN...FETCH' WHEN 'OP' THEN 'OPEN' WHEN 'OU' THEN 'OPEN...UPDATE' WHEN 'PR' THEN 'PREPARE' WHEN 'RE' THEN 'RELEASE' WHEN 'RO' THEN 'ROLLBACK' WHEN 'RT' THEN 'RENAME' WHEN 'RV' THEN 'REVOKE' WHEN 'SC' THEN 'SET CONNECTION' WHEN 'SI' THEN 'SELECT INTO' WHEN 'SK' THEN 'SELECT INTO' WHEN 'SP' THEN 'SET PATH' WHEN 'SR' THEN 'SET RESULTS' WHEN 'ST' THEN 'SET TRANSACTION' WHEN 'SV' THEN 'SET VARIABLE' WHEN 'UC' THEN 'UPDATE...CLOSE' WHEN 'UD' THEN 'UPDATE...DELETE' WHEN 'UF' THEN 'UPDATE...FETCH' WHEN 'UP' THEN 'UPDATE' WHEN 'UU' THEN 'UPDATE...UPDATE' ELSE QQSTOP END as "Operation", QQCNT as "Statement Usage Count ", varchar(b.QQSTTX,20000) as "Statement Text", varchar(qqhvar,500) as "Host Variable Values", /* Opens */

540

DB2 UDB for AS/400 SQL Programming V4R4

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

QQFULO as "Full Opens", QQPSUO as "Pseudo Opens", /* Row QQTOTR QQRROW QQARSS Sizes */ as "Table Rows", as "Result Rows", as "Average Result Size",

/* Implementation */ CASE QQODPI WHEN 'R' THEN 'Reusable' WHEN 'N' THEN 'Non-Reusable' ELSE QQODPI END as "ODP Implementation", CASE QQHVI WHEN 'I' THEN 'ISV' WHEN 'V' THEN 'V2' WHEN 'U' THEN 'UP' ELSE QQHVI END as "Host Variable Implementation", CASE QQDACV WHEN 'N' THEN NULL WHEN '0' THEN NULL WHEN '1' THEN 'Different Lengths' WHEN '2' THEN 'Different Numeric Types' WHEN '3' THEN 'C NUL-terminated Variable' WHEN '4' THEN 'Varying Length Fixed Length' WHEN '5' THEN 'CCSID Conversion' WHEN '6' THEN 'DRDA Mapping Required' WHEN '7' THEN 'Datetime Column' WHEN '8' THEN 'Too Many Host Variables' WHEN '9' THEN 'Target Table Is Not A SQL Table' ELSE QQDACV END as "Data Conversion", QQCTS as "Table Scan Count", /* Index Information */ QQCIU as "Index Use Count", QQCIC as "Index Create Count", QQCIA as "Index Advised Count", /* Copy of data */ QQCTF as "Temporary Table Count", QQCSO as "Sort Count", /* Access Plan Rebuild */ QQAPRT as "Last Access Plan Rebuilt", QQCAPR as "Access Plan Rebuild Count", CASE QQAPR WHEN 'A1' THEN WHEN 'A2' THEN WHEN 'A3' THEN WHEN 'A4' THEN WHEN 'A5' THEN WHEN 'A6' THEN WHEN 'A7' THEN WHEN 'A8' THEN WHEN 'A9' THEN WHEN 'AA' THEN ELSE QQAPR END as "Access 'Different File Or Member' 'Reusable Plan to Non-Reusable Plan Change' 'Non-Reusable To Reusable Plan Change' 'More Than Ten Percent Change In Number Of Rows' 'New Access Path Found' 'Access Path No Longer Found Or Valid' 'System Programming Change' 'Different CCSID' 'Different Date Or Time Format' 'Different Sort Sequence Table' Plan Rebuild Reason",

/* Job-user-program identification */ QQJOB as "Job",


Chapter 26. Monitoring and Optimizing Query Performance Tools

541

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

QQUSER QQJNUM QQTHID QQPLIB QQPNAM

as as as as as

"Job User", "Job Number", "Thread ID", "Program Library", "Program",

/* Statement attributes */ QQUDEF as "User Defined Field", QQCNAM as "Cursor", QQSNAM as "Statement Name" FROM <> a left join <> b on a.qqkey=b.qqkey left join <> c on a.qqkey=c.qqkey ORDER BY "Maximum Runtime" DESC

Record Identication
A new join key eld has been generated (QQKEY) to ease joining multiple physical les together. This eld replaces the job (QQJOB) and unique query counters (QQCNT) that the existing database monitor used. The join key eld contains a unique identier that allows all of the information for this query to be received from each of the physical les. This join key eld does not replace all of the detail elds that are still required to identify the specic information about the individual steps of a query. The Query Denition templte (QDT) Number or the Subselect Number identies information about each detailed step. Use these elds to identify which records belong to each step of the query process: v QQQDTN - Query Denition Template Number v QQQDTL - Query Denition Template Subselect Number (Subquery) v QQMATN - Materialized Query Denition Tempalte Number (View) v QQMATL - Materialized Query Denition Template Subselect Number (View w/ Subquery) Use these elds when the monitored query contains a subquery, union, or a view operation. All query types can generate multiple QDTs to satisfy the original query request. The system uses these elds to separate the information for each QDT while still allowing each QDT to be identied as belonging to this original query (QQKEY).

Comparison table of query optimization tools


PRTSQLINF STRDBG/CHGQRYA STRDBMON Only available when the query is run Memory-Based Monitor Onlly available when the query is run

Available without Only available when running query (after the query is run access plan has been created) Displayed for all queries in SQL program, whether executed or not Information on host variable implementation Displayed only for those queries which are executed Limited information on the implementation of host variables

Displayed only for those queries which are executed All information on host variables, implementation, and values

Displayed only for those queries which are executed All information on host variables, implementation, and values

542

DB2 UDB for AS/400 SQL Programming V4R4

PRTSQLINF

STRDBG/CHGQRYA

STRDBMON Available to all query users (OPNQRYF, SQL, QUERY/400) Performance records written to database le

Memory-Based Monitor Available only to SQL interfaces

Available only to SQL Available to all query users with programs, users (OPNQRYF, packages, or service SQL, QUERY/400) programs Messages printed to spool le Messages displayed in job log

Performance information collected in memory and then written to database le Repeated query requests are summarized

Easier to tie messages to query with subqueries or unions

Difficult to tie messages to query with subqueries or unions

Uniquely identies every query

Change query attributes


| | | | | | | | | | | | | | | | | | | You can modify different types of attributes of queries that you will execute during a certain job with the CHGQRYA command. The types of attributes that you can modify include: v Predictive Query Governor v Query Parallelism v Asynchronous Job v Apply CHGQRYA to remote Before the system intitiates a query, the system checks the query time limit against the estimated elapsed query time. The system also uses a time limit of zero to optimize performance on queries without having to run through several iterations. You can check the inquiry message CPA4259 for the predicted runtime and for what operations the query will perform. If the query is cancelled, debug messages will be written to the joblog. The Chapter 23. Using the DB2 UDB for AS/400 Predictive Query Governor on page 391 can stop the initiation of a query if the querys estimated or predicted runtime (elapsed execution time) is excessive. The governor acts before a query is run instead of while a query is run. The governor can be used in any interactive or batch job on the AS/400. It can be used with all DB2 UDB for AS/400 query interfaces and is not limited to use with SQL queries.

Query Options File QAQQINI


The query options le QAQQINI support provides the ability to dynamically modify or override the environment in which queries are executed through the CHGQRYA command and the QAQQINI le. The query options le QAQQINI is used to set the attributes used by the Query Optimizer. For each query that is run the query option values are retrieved from the QAQQINI le in the library specied on the QRYOPTLIB parameter of the CHGQRYA CL command and used to optimize or implement the query.

Chapter 26. Monitoring and Optimizing Query Performance Tools

543

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

Environmental attributes that you can modify through the QAQQINI le include: v APPLY_REMOTE v ASYNC_JOB_USAGE v FORCE_ORDER_JOIN v MESSAGES_DEBUG v v v v v OPTIMIZE_STATISTIC_LIMITATION PARALLEL_DEGREE PARAMETER_MARKER_CONVERSION QUERY_TIME_LIMIT UDF_TIME_OUT

Specifying the QAQQINI le


CHGQRYA (Change Query Attributes) CL command has a parameter QRYOPTLIB (query options library) which allows the user to specify which library currently contains or will contain the query options le QAQQINI. The query options le will be retrieved from the library specied on the QRYOPTLIB parameter for each query and remains in effect for the duration of the job or user session, or until the QRYOPTLIB parameter is changed by the CHGQRYA command. If no library is specied for this parameter, then the library QUSRSYS is searched for the existence of the QAQQINI le. If a query options le is not found for a query, no attributes will be modied. The initial value of the QRYOPTLIB parameter for a job is QUSRSYS.

Creating the QAQQINI Query Options File


| | | | | | | | | | | | | | ach system is shipped with a QAQQINI template le in library QSYS. The QAQQINI le in QSYS is to be used as a template when creating all user specied QAQQINI les. To create your own QAQQINI le use the CRTDUPOBJ CL command to create a copy of the QAQQINI le into the library which will be specied on the CHGQRYA QRYOPTLIB parameter. The lename must remain QAQQINI, for example:
CRTDUPOBJ OBJ(QAQQINI) FROMLIB(QSYS) OBJTYPE(*FILE) TOLIB(MYLIB) DATA(*YES)

Because system-supplied triggers are attached to the QAQQINI le in QSYS it is imperative that the only means of copying the QAQQINI le is through the CRTDUPOBJ CL command. Note: It is recommended that the le QAQQINI, in QSYS, not be modied. This is the original template that is to be duplicated into QUSRSYS or a user specied library for use.

QAQQINI Query Options File Format


Query Options File:
R QAQQINI QQPARM 256A UNIQUE TEXT('Query options + file') VARLEN(10) +

544

DB2 UDB for AS/400 SQL Programming V4R4

QQVAL

256A

QQTEXT

1000G

K QQPARM

TEXT('Query + option parameter') + COLHDG('Parameter') VARLEN(10) + TEXT('Query option + parameter value') + COLHDG('Parameter Value') VARLEN(100) + TEXT('Query + option text') + ALWNULL + COLHDG('Query Option' + 'Text') + CCSID(13488) + DFT(*NULL)

| |

The QAQQINI le shipped in the library QSYS has been pre-populated with the following records:
Table 71. QAQQINI File Records. Description
QQPARM APPLY_REMOTE ASYNC_JOB_USAGE FORCE_JOIN_ORDER MESSAGES_DEBUG OPTIMIZE_STATISTIC_LIMITATION PARALLEL_DEGREE PARAMETER_MARKER_CONVERSION QUERY_TIME_LIMIT UDF_TIME_OUT QQVAL *DEFAULT *DEFAULT *DEFAULT *DEFAULT *DEFAULT *DEFAULT *DEFAULT *DEFAULT *DEFAULT

Setting the Options within the Query Options File


The QAQQINI le query options can be modied with the INSERT, UPDATE, or DELETE SQL statements. For the following examples, a QAQQINI le has already been created in library MyLib. To update an existing record in MyLib/QAQQINI use the UPDATE SQL statment. This example sets MESSAGES_DEBUG = *YES so that the query optimizer will print out the optimizer debug messages:
UPDATE MyLib/QAQQINI SET QQVAL='*YES' WHERE QQPARM='MESSAGES_DEBUG'

To delete an existing record in MyLib/QAQQINI use the DELETE SQL statement. This example removes the QUERY_TIME_LIMIT record from the QAQQINI le:
DELETE FROM MyLib/QAQQINI WHERE QQPARM='QUERY_TIME_LIMIT'

To insert a new record into MyLib/QAQQINI use the INSERT SQL statement. This example adds the QUERY_TIME_LIMIT record with a value of *NOMAX to the QAQQINI le:
INSERT INTO MyLib/QAQQINI VALUES('QUERY_TIME_LIMIT','*NOMAX','New time limit set by DBAdmin')

Chapter 26. Monitoring and Optimizing Query Performance Tools

545

QAQQINI Query Options


| | The tables below summarize the query options that can be specied on the QAQQINI command:
Parameter value APPLY_REMOTE Description Species, for database queries involving distributed les, whether or not the CHGQRYA attributes are applied to the jobs on the remote system associated with this job. Species the circumstances in which asynchronous (temp writer) jobs can be used to help process database queries in the job. Only applies to queries involving distributed les. Species whether the Query Optimizer is not allowed to reorder les during implementation of a join query. This option issues all the Query Optimizer debug messages that would normally be issued if the job was in debug mode. Species the circumstances in which statistics gathering is allowed for query optimization. Species the parallel processing option that can be used when running database queries and database le keyed access path builds, rebuilds, and maintenance in the job. This option will disallow database queries with literals to be implemented as parameter markers. Species a limit for database queries allowed to be started, based on the estimated number of elapsed seconds that the query requires to process. Species, for database queries involving UDFs, the number of seconds that the database should wait for a UDF to nish.

ASYNC_JOB_USAGE

FORCE_JOIN_ORDER

MESSAGES_DEBUG

OPTIMIZE_STATISTIC_LIMITATION

PARALLEL_DEGREE

PARAMETER_MARKER_CONVERSION

QUERY_TIME_LIMIT

UDF_TIME_OUT

Table 72. Query Options Specied on QAQQINI Command


Parameter Value *DEFAULT *NO Description The default value is set to *NO. The CHGQRYA attributes for the job are not applied to the remote jobs. The remote jobs will use the attributes associated to them on their systems. The query attributes for the job are applied to the remote jobs used in processing database queries involving distributed les. For attributes where *SYSVAL is specied, the system value on the remote system is used for the remote job. This option requires that, if CHGQRYA was used for this job, the remote jobs must have authority to use the CHGQRYA command.

APPLY_REMOTE

*YES

546

DB2 UDB for AS/400 SQL Programming V4R4

Table 72. Query Options Specied on QAQQINI Command (continued)


Parameter Value *DEFAULT *LOCAL Description The default value is set to *LOCAL. Asynchronous jobs may be used for database queries that involve only les local to the system where the database queries are being run. In addition, for queries involving distributed les, this option allows the communications required to be asynchronous. This allows each system involved in the query of the distributed les to run its portion of the query at the same time (in parallel) as the other systems. Asynchronous jobs may be used for database queries that involve distributed les. Asynchronous jobs may be used for any database query. No asynchronous jobs are allowed to be used for database query processing. In addition, all processing for queries involving distributed les occurs synchronously. Therefore, no inter-system parallel processing will occur. The default is set to *NO. Allow the optimizer to re-order join les. Do not allow the query optimizer to re-order join les as part of its optimization process. The join will occur in the order in which the les were specied in the query. The default is set to *NO. No debug messages are to be displayed. Issue all Query Optimizer debug messages The amount of time spent in statistics gathering is determined by the query optimizer. No index statistics will be gathered by the query optimizer. Default statistics will be used for optimization. (Use this option sparingly.) Species the maximum percentage of the index that will be searched while gathering statistics. Valid values for integer value are 1 to 99. Species the largest table size, in number of records, for which gathering statistics is allowed. For tables with more records than the specied value, the optimizer will not gather statistics and will use default values.

ASYNC_JOB_USAGE *DIST *ANY *NONE

*DEFAULT *NO FORCE_JOIN_ORDER *YES

*DEFAULT MESSAGES_DEBUG *NO *YES *DEFAULT *NO

OPTIMIZE_STATISTIC_ LIMITATION

*PERCENTAGE integer value *MAX_NUMBER_ OF_RECORDS_ ALLOWED integer value

Chapter 26. Monitoring and Optimizing Query Performance Tools

547

Table 72. Query Options Specied on QAQQINI Command (continued)


Parameter Value *DEFAULT *SYSVAL *IO Description The default value is set to *SYSVAL. The processing option used is set to the current value of the system value, QQRYDEGREE. Any number of tasks can be used when the database query optimizer chooses to use I/O parallel processing for queries. SMP parallel processing is not allowed. The query optimizer can choose to use any number of tasks for either I/O or SMP parallel processing to process the query or database le keyed access path build, rebuild, or maintenance. SMP parallel processing is used only if the system feature, DB2 Symmetric Multiprocessing for OS/400, is installed. Use of parallel processing and the number of tasks used is determined with respect to the number of processors available in the system, this job has a share of the amount of active memory available in the pool in which the job is run, and whether the expected elapsed time for the query or database le keyed access path build or rebuild is limited by CPU processing or I/O resources. The query optimizer chooses an implementation that minimizes elapsed time based on the job has a share of the memory in the pool. The query optimizer chooses to use either I/O or SMP parallel processing to process the query. SMP parallel processing will only be used if the system feature, DB2 Symmetric Multiprocessing for OS/400, is installed. The choices made by the query optimizer are similar to those made for parameter value *OPTIMIZE except the optimizer assumes that all active memory in the pool can be used to process the query or database le keyed access path build, rebuild, or maintenance. No parallel processing is allowed for database query processing or database le keyed access path build, rebuild, or maintenance. The default value is set to *NO. Constants cannot be implemented as parameter markers. Constants can be implemented as parameter markers. The default value is set to *SYSVAL. The query time limit for this job will be obtained from the system value, QQRYTIMLMT. There is no maximum number of estimated elapsed seconds. Species the maximum value that is checked against the estimated number of elapsed seconds required to run a query. If the estimated elapsed seconds is greater than this value, the query is not started. Valid values range from 0 through 2147352578.

*OPTIMIZE

PARALLEL_DEGREE

*MAX

*NONE

*DEFAULT PARAMETER_MARKER_ CONVERSION *NO *YES *DEFAULT *SYSVAL *NOMAX QUERY_TIME_LIMIT integer value

548

DB2 UDB for AS/400 SQL Programming V4R4

Table 72. Query Options Specied on QAQQINI Command (continued)


Parameter Value *DEFAULT *MAX UDF_TIME_OUT integer value Description The amount of time to wait is determined by the database. The default is 30 seconds. The maximum amount of time that the database will wait for the UDF to nish. Specify the number of seconds that the database should wait for a UDF to nish. If the value given exceeds the database maximum wait time, the maximum wait time will be used by the database. Minimum value is 1 and maximum value is system dened.

QAQQINI Query Options File Authority Requirements


QAQQINI is shippped with a *PUBLIC *USE authority. This allows users to view the query options le, but not change it. It is recommended that only the system or database administrator have *CHANGE authority to the QAQQINI query options le. The query options le, which resides in the library specied on the CHGQRYA CL command QRYOPTLIB parameter, is always used by the query optimizer. This is true even if the user has no authority to the query options library and le. This provides the system administrator with an additional security mechanism. When the QAQQINI le resides in the library QUSRSYS the query options will effect all of the query users on the system. To prevent anyone from inserting, deleting, or updating the query options, the system administrator should remove update authority from *PUBLIC to the le. This will prevent users from changing the data in the le. When the QAQQINI le resides in a user library, specied on the CHGQRYA CL command option QRYOPTLIB, the query options will effect all of the querys run for that users job. To prevent the query options from being retrieved from a particular library the system administrator can revoke authority to the CHGQRYA CL command.

QAQQINI File System Supplied Triggers


The query options le QAQQINI le uses a system-supplied trigger program in order to process any changes made to the le. A trigger cannot be removed from or added to the le QAQQINI. If an error occurs on the update of the QAQQINI le (an INSERT, DELETE, or UPDATE operation), the following SQL0443 diagnostic message will be issued:
Trigger program or external routine detected an error.

Chapter 26. Monitoring and Optimizing Query Performance Tools

549

550

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 27. Solving Common Database Problems


This chapter describes techniques for solving some common database problems. Techniques are provided to help you do the following tasks: v Page through retrieved data v Retrieve data in reverse order v Establish position at the end of a table v Add data to the end of a table v Update data as it is retrieved from a table v Update data previously retrieved v Change the table denition

Paging through Retrieved Data


When a program retrieves data from the database, the FETCH statement allows the program to page forward through the data. If you are using a scrollable cursor, then the program can page anywhere in the le, based on the scroll option specied on the FETCH statement. This allows the program to retrieve the data more than once. Several options that can be used to page through the data are listed in 56.

Retrieving in Reverse Order


If there is only one row for each value of DEPTNO, then the following statement species a unique ordering of rows:
SELECT * FROM DEPARTMENT WHERE LOCATION = 'MINNESOTA' ORDER BY DEPTNO

To retrieve the same rows in reverse order, simply specify that the order is descending, as in this statement:
SELECT * FROM DEPARTMENT WHERE LOCATION = 'MINNESOTA' ORDER BY DEPTNO DESC

A cursor on the second statement would retrieve rows in exactly the opposite order from a cursor on the rst statement. But that is guaranteed only if the rst statement species a unique ordering. If both statements are required in the same program, it might be useful to have two indexes on the DEPTNO column, one in ascending order and one in descending order.

Establishing Position at the End of a Table


For a scrollable cursor, the end of the table can be determined by the following:
FETCH AFTER FROM C1

Once the cursor is positioned at the end of the table, the program can use the PRIOR or RELATIVE scroll options to position and fetch data starting from the end of the table.
Copyright IBM Corp. 1997, 1999

551

Adding Data to the End of a Table


The order in which rows are returned to your program depends on the ORDER BY clause in the SQL statement. To get the effect of adding data to the end of a table, include a sequence number column in the table denition. Then, when you retrieve data from the table, use an ORDER BY clause naming that column.

Updating Data as It Is Retrieved from a Table


You can update rows of data as you retrieve them. On the select-statement, use FOR UPDATE OF followed by a list of columns that may be updated. Then use the cursor-controlled UPDATE statement. The WHERE CURRENT OF clause names the cursor that points to the row you want to update. If a FOR UPDATE OF, an ORDER BY, a FOR READ ONLY, or a SCROLL clause without the DYNAMIC clause is not specied, all columns can be updated. If a multiple-row FETCH statement has been specied and run, the cursor is positioned on the last row of the block. Therefore, if the WHERE CURRENT OF clause is specied on the UPDATE statement, the last row in the block is updated. If a row within the block must be updated, the program must rst position the cursor on that row. Then the UPDATE WHERE CURRENT OF can be specied. Consider the following example:
Table 73. Updating a Table
Scrollable Cursor SQL Statement EXEC SQL DECLARE THISEMP DYNAMIC SCROLL CURSOR FOR SELECT EMPNO, WORKDEPT, BONUS FROM CORPDATA.EMPLOYEE WHERE WORKDEPT = D11 FOR UPDATE OF BONUS END-EXEC. EXEC SQL OPEN THISEMP END-EXEC. EXEC SQL WHENEVER NOT FOUND GO TO CLOSE-THISEMP END-EXEC. EXEC SQL FETCH NEXT FROM THISEMP FOR 5 ROWS INTO :DEPTINFO :IND-ARRAY END-EXEC. ... determine if any employees in department D11 receive a bonus less than $500.00. If so, update that record to the new minimum of $500.00. EXEC SQL FETCH RELATIVE :NUMBACK FROM THISEMP END-EXEC. ... positions to the record in the block to update by fetching in the reverse order. DEPTINFO and IND-ARRAY are declared in the program as a host structure array and an indicator array. Comments

552

DB2 UDB for AS/400 SQL Programming V4R4

Table 73. Updating a Table (continued)


Scrollable Cursor SQL Statement EXEC SQL UPDATE CORPDATA.EMPLOYEE SET BONUS = 500 WHERE CURRENT OF THISEMP END-EXEC. EXEC SQL FETCH RELATIVE :NUMBACK FROM THISEMP FOR 5 ROWS INTO :DEPTINFO :IND-ARRAY END-EXEC. ... branch back to determine if any more employees in the block have a bonus under $500.00. ... branch back to fetch and process the next block of rows. CLOSE-THISEMP. EXEC SQL CLOSE THISEMP END-EXEC. Comments ... updates the bonus for the employee in department D11 that is under the new $500.00 minimum. ... positions to the beginning of the same block that was already fetched and fetches the block again. (NUMBACK -(5 - NUMBACK - 1))

Restrictions
You cannot use FOR UPDATE OF with a select-statement that includes any of these elements: v The rst FROM clause identies more than one table or view. v The rst FROM clause identies a read-only view. v The rst SELECT clause species the keyword DISTINCT. v v v v The outer subselect contains a GROUP BY clause. The outer subselect contains a HAVING clause. The rst SELECT clause contains a column function. The select-statement contains a subquery such that the base object of the outer subselect and of the subquery is the same table. v The select-statement contains a UNION or UNION ALL operator. v The select-statement includes a FOR READ ONLY clause. v The SCROLL keyword is specied without DYNAMIC. If a FOR UPDATE OF clause is specied, you cannot update columns that were not named in the FOR UPDATE OF clause. But you can name columns in the FOR UPDATE OF clause that are not in the SELECT list, as in this example:
SELECT A, B, C FROM TABLE FOR UPDATE OF A,E

Do not name more columns than you need in the FOR UPDATE OF clause; indexes on those columns are not used when you access the table.

Updating Data Previously Retrieved


You can page through and update data that had previously been retrieved by doing one of three things:

Chapter 27. Solving Common Database Problems

553

v Use the UPDATE statement with a WHERE clause that names all of the values in the row or species a unique key of the table. You can code one statement, using host variables in the WHERE clause, and run the same statement many times with different values of the variables to update different rows. v For a scrollable cursor, the program can use the appropriate scroll options to retrieve the row that had previously been fetched. Then, using the WHERE CURRENT OF clause on the UPDATE statement, the row can be changed to the appropriate value.

Changing the Table Denition


You can add, drop, and alter columns in a table using the SQL ALTER TABLE statement or the Change Physical File (CHGPF) CL command. See the DB2 UDB for AS/400 SQL Reference book for information on how to use the SQL ALTER TABLE statement. See the CL Reference (Abridged) book for information on how to use the Change Physical File (CHGPF) CL command. You can also dynamically create a view of the table, which includes only the columns you want, in the order you want.

554

DB2 UDB for AS/400 SQL Programming V4R4

Chapter 28. Distributed Relational Database Function


A distributed relational database consists of a set of SQL objects that are spread across interconnected computer systems. These relational databases can be of the same type (for example, DB2 UDB for AS/400) or of different types (DB2 for OS/390, DB2 for VM, DB2 Universal Database (UDB), or non-IBM database management systems which support DRDA). Each relational database has a relational database manager to manage the tables in its environment. The database managers communicate and cooperate with each other in a way that allows a given database manager access to run SQL statements on a relational database on another system. The application requester supports the application side of a connection. The application server is the local or remote database to which an application requester is connected. DB2 UDB for AS/400 provides support for Distributed Relational Database Architecture (DRDA) to allow an application requester to communicate with application servers. In addition, DB2 UDB for AS/400 can invoke exit programs to allow access to data on other database management systems which do not support DRDA. These exit programs are called application requester driver (ARD) programs. DB2 UDB for AS/400 supports two levels of distributed relational database: v Remote unit of work (RUW) Remote unit of work is where the preparation and running of SQL statements occurs at only one application server during a unit of work. DB2 UDB for AS/400 supports RUW over either APPC or TCP/IP. v Distributed unit of work (DUW) Distributed unit of work is where the preparation and running of SQL statements can occur at multiple applications servers during a unit of work. However, a single SQL statement can only refer to objects located at a single application server. DB2 UDB for AS/400 supports DUW over APPC only. For comprehensive information about distributed relational databases, see the Distributed Database Programming book.

DB2 UDB for AS/400 Distributed Relational Database Support


The DB2 UDB Query Manager and SQL Development Kit licensed program supports interactive access to distributed databases with the following SQL statements: v CONNECT v SET CONNECTION v DISCONNECT v RELEASE v DROP PACKAGE v GRANT PACKAGE v REVOKE PACKAGE For detailed descriptions of these statements, see the DB2 UDB for AS/400 SQL Reference book.

Copyright IBM Corp. 1997, 1999

555

Additional support is provided by the development kit through parameters on the SQL precompiler commands: Create SQL ILE C Object (CRTSQLCI) command Create SQL COBOL Program (CRTSQLCBL) command Create SQL ILE COBOL Object (CRTSQLCBLI) command Create SQL PL/I Program (CRTSQLPLI) command Create SQL RPG Program (CRTSQLRPG) command Create SQL ILE RPG Object (CRTSQLRPGI) command For more information on the SQL precompiler commands, see the topic Chapter 18. Preparing and Running a Program with SQL Statements on page 333. The create SQL Package (CRTSQLPKG) command lets you create an SQL package from an SQL program that was created as a distributed program. Syntax and parameter denitions for the CRTSQLPKG and CRTSQLxxx commands are provided in Appendix D. DB2 UDB for AS/400 CL Command Descriptions.

DB2 UDB for AS/400 Distributed Relational Database Example Program


A remote unit of work relational database sample program has been shipped with the SQL product. There are several les and members within the QSQL library to help you set up an environment that will run a distributed DB2 UDB for AS/400 sample program. To use these les and members, you need to run the SETUP batch job located in the le QSQL/QSQSAMP. The SETUP batch job allows you to customize the example to do the following: v Create the QSQSAMP library at the local and remote locations. v Set up relational database directory entries at the local and remote locations. v Create application panels at the local location. v Precompile, compile, and run programs to create distributed sample application collections, tables, indexes, and views. v Load data into the tables at the local and remote locations. v Precompile and compile programs. v Create SQL packages at the remote location for the application programs. v Precompile, compile, and run the program to update the location column in the department table. Before running the SETUP, you may need to edit the SETUP member of the QSQL/QSQSAMP le. Instructions are included in the member as comments. To run the SETUP, specify the following command on the AS/400 command line:
========> SBMDBJOB QSQL/QSQSAMP SETUP

Wait for the batch job to complete. To use the sample program, specify the following command on the command line:
========> ADDLIBLE QSQSAMP

556

DB2 UDB for AS/400 SQL Programming V4R4

To call the rst display that allows you to customize the sample program, specify the following command on the command line.
========> CALL QSQ8HC3

The following display appears. From this display, you can customize your database sample program.
DB2 for OS/400 ORGANIZATION APPLICATION ACTION...........: D (DISPLAY) OBJECT...........: DS (DEPT STRUCTURE) _ __ A (ADD) U (UPDATE) DE (DEPARTMENT) E (ERASE) EM (EMPLOYEE) MN (MANAGER NAME)

SEARCH CRITERIA..: __ DI (DEPARTMENT ID) DN (DEPARTMENT NAME) EI (EMPLOYEE ID) MI (MANAGER ID) EN (EMPLOYEE NAME) LOCATION.........: DATA.............: ________________

(BLANK IMPLIES LOCAL LOCATION)

_______________________________

Bottom F3=Exit (C) COPYRIGHT IBM CORP. 1982, 1991

SQL Package Support


The OS/400 program supports an object called an SQL package. (OS/400 object type is *SQLPKG.) The SQL package contains the control structures and access plans necessary to process SQL statements on the application server when running a distributed program. An SQL package can be created when: v The RDB parameter is specied on the CRTSQLxxx command and the program object is successfully created. The SQL package will be created on the system specied by the RDB parameter. If the compile is unsuccessful or the compile only creates the module object, the SQL package will not be created. v Using the CRTSQLPKG command. The CRTSQLPKG can be used to create a package when the package was not created at precompile time or if the package is needed at an RDB other than the one specied on the precompile command. The Delete SQL Package (DLTSQLPKG) command allows you to delete an SQL package on the local system. An SQL package is not created unless the privileges held by the authorization ID associated with the creation of the SQL package includes appropriate authority for creating a package on the remote system (the application server). To run the program, the authorization ID must include EXECUTE privileges on the SQL package. On AS/400 systems, the EXECUTE privilege includes system authority of *OBJOPR and *EXECUTE. The syntax for the Create SQL Package (CRTSQLPKG) command is shown in Appendix D. DB2 UDB for AS/400 CL Command Descriptions.
Chapter 28. Distributed Relational Database Function

557

Valid SQL Statements in an SQL Package


Programs that connect to another AS/400 can use any of the SQL statements as described in the DB2 UDB for AS/400 SQL Reference book, except the SET TRANSACTION statement. Programs compiled using DB2 UDB for AS/400 that refer to a system that is not DB2 UDB for AS/400 can use executable SQL statements supported by that remote system. The precompiler will continue to issue diagnostic messages for statements it does not understand. These statements are sent to the remote system during the creation of the SQL package. The run-time support will return a SQLCODE of -84 or -525 when the statement cannot be run on the current application server. For example, multiple-row FETCH, blocked INSERT, and scrollable cursor support are allowed only in distributed programs where both the application requester and application server are OS/400 at Version 2 Release 2 or later. For more information, see the appendix that contains the section Considerations for Using Distributed Relational Database in the DB2 UDB for AS/400 SQL Reference, SC41-5612-02 book.

Considerations for Creating an SQL Package


There are many considerations to think about when you are creating an SQL package. Some of these considerations are listed below.

CRTSQLPKG Authorization
When creating an SQL package on an AS/400 system the authorization ID used must have *USE authority to the CRTSQLPKG command.

Creating a Package on a non-DB2 UDB for AS/400


When you create a program and SQL package for a non-DB2 UDB for AS/400, and try to use SQL statements that are unique to that relational database, the CRTSQLxxx GENLVL parameter should be set to 30. The program will be created unless a message with a severity level of greater than 30 is issued. If a message is issued with a severity level of greater than 30, the statement is probably not valid for any relational database. For example, undened or unusable host variables or constants that are not valid would generate a message severity greater than 30. The precompiler listing should be checked for unexpected messages when running with a GENLVL greater than 10. When you are creating a package for a DB2 Universal Database, you must set the GENLVL parameter to a value less than 20. If the RDB parameter species a system that is not a DB2 UDB for AS/400 system, then the following options should not be used on the CRTSQLxxx command: v COMMIT(*NONE) v OPTION(*SYS) v DATFMT(*MDY) v DATFMT(*DMY) v DATFMT(*JUL) v DATFMT(*YMD) v DATFMT(*JOB) v DYNUSRPRF(*OWNER) v TIMFMT(*HMS) if TIMSEP(*BLANK) or TIMSEP(,) is specied v SRTSEQ(*JOBRUN)

558

DB2 UDB for AS/400 SQL Programming V4R4

v SRTSEQ(*LANGIDUNQ) v SRTSEQ(*LANGIDSHR) v SRTSEQ(library-name/table-name) Note: When connecting to a DB2 Universal Database application server, the following additional rules apply: v v v v The specied date and time formats must be the same format A value of *BLANK must be used for the TEXT parameter Default collections (DFTRDBCOL) are not supported The CCSID of the source program from which the package is being created must not be 65535; if 65535 is used, an empty package is created.

Target Release (TGTRLS)


While creating the package, the SQL statements are checked to determine which release can support the function. This release is set as the restore level of the package. For example, if the package contains a CREATE TABLE statement which adds a FOREIGN KEY constraint to the table, then the restore level of the package will be Version 3 Release 1, because FOREIGN KEY constraints were not supported prior to this release. TGTRLS message are suppressed when the TGTRLS parameter is *CURRENT.

SQL Statement Size


The create SQL package function may not be able to handle the same size SQL statement that the precompiler can process. During the precompile of the SQL program, the SQL statement is placed into the associated space of the program. When this occurs, each token is separated by a blank. In addition, when the RDB parameter is specied, the host variables of the source statement are replaced with an H. The create SQL package function passes this statement to the application server, along with a list of the host variables for that statement. The addition of the blanks between the tokens and the replacement of host variables may cause the statement to exceed the maximum SQL statement size (SQL0101 reason 5).

Statements that do not require a Package


In some cases, you might try to create an SQL package but the SQL package will not be created and the program will still run. This situation occurs when the program contains only SQL statements that do not require an SQL package to run. For example, a program that contains only the SQL statement DESCRIBE TABLE will generate message SQL5041 during SQL package creation. The SQL statements that do not require an SQL package are: v v v v v v v DESCRIBE TABLE COMMIT ROLLBACK CONNECT SET CONNECTION DISCONNECT RELEASE

Package Object Type


SQL packages are always created as non-ILE objects and always run in the default activation group.
Chapter 28. Distributed Relational Database Function

559

ILE programs and service programs


ILE programs and service programs that bind several modules containing SQL statements must have a separate SQL package for each module.

Package Creation Connection


The type of connection done for the package creation is based on the type of connect requested using the RDBCNNMTH parameter. If RDBCNNMTH(*DUW) was specied, commitment control is used and the connection may be a read-only connection. If the connection is read-only, then the package creation will fail.

Unit of Work
Because package creation implicitly performs a commit or rollback, the commit denition must be at a unit of work boundary before the package creation is attempted. The following conditions must all be true for a commit denition to be at a unit of work boundary: v SQL is at a unit of work boundary. v There are no local or DDM les open using commitment control and no closed local or DDM les with pending changes. v There are no API resources registered. v There are no LU 6.2 resources registered that are not associated with DRDA or DDM.

Creating Packages Locally


The name specied on the RDB parameter can be the name of the local system. If it is the name of the local system, the SQL package will be created on the local system. The SQL package can be saved (SAVOBJ command) and then restored (RSTOBJ command) to another AS/400 system. When you run the program with a connection to the local system, the SQL package is not used. If you specify *LOCAL for the RDB parameter, an *SQLPKG object is not created, but the package information is saved in the *PGM object.

Labels
You can use the LABEL ON statement to create a description for the SQL package.

Consistency Token
The program and its associated SQL package contain a consistency token that is checked when a call is made to the SQL package. The consistency tokens must match or the package cannot be used. It is possible for the program and SQL package to appear to be uncoordinated. Assume the program is on the AS/400 system and the application server is another AS/400 system. The program is running in session A and it is recreated in session B (where the SQL package is also recreated). The next call to the program in session A could result in a consistency token error. To avoid locating the SQL package on each call, SQL maintains a list of addresses for SQL packages that are used by each session. When session B re-creates the SQL package, the old SQL package is moved to the QRPLOBJ library. The address to the SQL package in session A is still valid. (This situation can be avoided by creating the program and SQL package from the session that is running the program, or by submitting a remote command to delete the old SQL package before creating the program.)

560

DB2 UDB for AS/400 SQL Programming V4R4

To use the new SQL package, you should end the connection with the remote system. You can either sign off the session and then sign on again, or you can use the interactive SQL (STRSQL) command to issue a DISCONNECT for unprotected network connections or a RELEASE followed by a COMMIT for protected connections. RCLDDMCNV should then be used to end the network connections. Call the program again.

SQL and Recursion


If you invoke SQL from an attention key program while you are already precompiling, you will receive unpredictable results. The CRTSQLxxx, CRTSQLPKG, STRSQL commands and the SQL run-time environment are not recursive. They will produce unpredictable results if recursion is attempted. Recursion would occur if while one of the commands is running, (or running a program with embedded SQL statements) the job is interrupted before the command has completed, and another SQL function is started.

CCSID Considerations for SQL


If you are running a distributed application and one of your systems is not an AS/400 system, the job CCSID value on the AS/400 cannot be set to 65535. Before requesting that the remote system create an SQL package, the application requester always converts the name specied on the RDB parameter, SQL package name, library name, and the text of the SQL package from the CCSID of the job to CCSID 500. This is required by DRDA. When the remote relational database is an AS/400 system, the names are not converted from CCSID 500 to the job CCSID. It is recommended that delimited identiers not be used for table, view, index, collection, library, or SQL package names. Conversion of names does not occur between systems with different CCSIDs. Consider the following example with system A running with a CCSID of 37 and system B running with a CCSID of 500. v Create a program that creates a table with the name ab|c on system A. v Save program ab|c on system A, then restore it to system B. v The code point for in CCSID 37 is x5F while in CCSID 500 it is xBA. v On system B the name would display a[b]c. If you created a program that referenced the table whose name was ab|c., the program would not nd the table. The at sign (@), pound sign (#), and dollar sign ($) characters should not be used in SQL object names. Their code points depend on the CCSID used. If you use delimited names or the three national extenders, the name resolution functions may possibly fail in a future release.

Connection Management and Activation Groups Connections and conversations


Prior to the use of TCP/IP by DRDA, the term connection was not ambiguous. It referred to a connection from the SQL point of view. That is, a connection started at the time one did a CONNECT TO some RDB, and ended when a DISCONNECT was done or a RELEASE ALL followed by a successful COMMIT occurred. The
Chapter 28. Distributed Relational Database Function

561

APPC conversation may or may not have been kept up, depending on the jobs DDMCNV attribute value, and whether the conversation was with an AS/400 or other type of system. TCP/IP terminology does not include the term conversation. A similar concept exists, however. With the advent of TCP/IP support by DRDA, use of the term conversation will be replaced, in this book, by the more general term connection, unless the discussion is specically about an APPC conversation. Therefore, there are now two different types of connections about which the reader must be aware: SQL connections of the type described above, and network connections which replace the term conversation. Where there would be the possibility of confusion between the two types of connections, the word will be qualied by SQL or network to allow the reader to understand the intended meaning. SQL connections are managed at the activation group level. Each activation group within a job manages its own connections and these connections are not shared across activation groups. For programs that run in the default activation group, connections are still managed as they were prior to Version 2 Release 3. The following is an example of an application that runs in multiple activation groups. This example is used to illustrate the interaction between activation groups, connection management, and commitment control. It is not a recommended coding style.

Source Code for PGM1:


.... EXEC SQL CONNECT TO SYSB END-EXEC. EXEC SQL SELECT .... END-EXEC. CALL PGM2. ....

Figure 33. Source Code for PGM1

Command to create program and SQL package for PGM1:


CRTSQLCBL PGM(PGM1) COMMIT(*NONE) RDB(SYSB)

562

DB2 UDB for AS/400 SQL Programming V4R4

Source Code for PGM2:


... EXEC SQL CONNECT TO SYSC; EXEC SQL DECLARE C1 CURSOR FOR SELECT ....; EXEC SQL OPEN C1; do { EXEC SQL FETCH C1 INTO :st1; EXEC SQL UPDATE ... SET COL1 = COL1+10 WHERE CURRENT OF C1; PGM3(st1); } while SQLCODE == 0; EXEC SQL CLOSE C1; EXEC SQL COMMIT;

....

Figure 34. Source Code for PGM2

Command to create program and SQL package for PGM2:


CRTSQLCI OBJ(PGM2) COMMIT(*CHG) RDB(SYSC) OBJTYPE(*PGM)

Source Code for PGM3:


... EXEC SQL INSERT INTO TAB VALUES(:st1); EXEC SQL COMMIT; ....

Figure 35. Source Code for PGM3

Commands to create program and SQL package for PGM3:


CRTSQLCI OBJ(PGM3) COMMIT(*CHG) RDB(SYSD) OBJTYPE(*MODULE) CRTPGM PGM(PGM3) ACTGRP(APPGRP) CRTSQLPKG PGM(PGM3) RDB(SYSD)

Chapter 28. Distributed Relational Database Function

563

SYSA Job: SYSB (Remote)


Call

Job:
Default Activation Group: SQL Package for PGM1

Default Activation Group:

PGM1 Call

Connect

SYSC (Remote)
System-Named Activation Group:

Job:
Default Activation Group:
Connect

PGM2

SQL Package for PGM2

Call

Return Call

Activation Group APPGRP:

SYSD (Remote) Job:


Connect
Default Activation Group: SQLPackage for PGM3

PGM3

RV2W577-3

In this example, PGM1 is a non-ILE program created using the CRTSQLCBL command. This program runs in the default activation group. PGM2 is created using the CRTSQLCI command, and it runs in a system-named activation group. PGM3 is also created using the CRTSQLCI command, but it runs in the activation group named APPGRP. Because APPGRP is not the default value for the ACTGRP parameter, the CRTPGM command is issued separately. The CRTPGM command is followed by a CRTSQLPKG command that creates the SQL package object on the SYSD relational database. In this example, the user has not explicitly started the job level commitment denition. SQL implicitly starts commitment control. 1. 2. 3. 4. PGM1 is called and runs in the default activation group. PGM1 connects to relational database SYSB and runs a SELECT statement. PGM1 then calls PGM2, which runs in a system-named activation group. PGM2 does a connect to relational database SYSC. Because PGM1 and PGM2 are in different activation groups, the connection started by PGM2 in the system-named activation group does not disconnect the connection started by PGM1 in the default activation group. Both connections are active. PGM2 opens the cursor and fetches and updates a row. PGM2 is running under commitment control, is in the middle of a unit of work, and is not at a connectable state. 5. PGM2 calls PGM3, which runs in activation group APPGRP. 6. The INSERT statement is the rst statement run in activation group APPGRP. The rst SQL statement causes an implicit connect to relational database SYSD. A row is inserted into table TAB located at relational database SYSD. The insert is then committed. The pending changes in the system-named

564

DB2 UDB for AS/400 SQL Programming V4R4

activation group are not committed, because commitment control was started by SQL with a commit scope of activation group. 7. PGM3 is then exited and control returns to PGM2. PGM2 fetches and updates another row. 8. PGM3 is called again to insert the row. An implicit connect was done on the rst call to PGM3. It is not done on subsequent calls because the activation group did not end between calls to PGM3. Finally, all the rows are processed by PGM2 and the unit of work associated with the system-named activation group is committed.

Multiple Connections to the Same Relational Database


If different activation groups connect to the same relational database, each SQL connection has its own network connection and its own application server job. If activation groups are run with commitment control, changes committed in one activation group do not commit changes in other activation groups unless the job-level commitment denition is used.

SYSA Job:

SYSB Job:

Default ActivationGroup:
Connect

Job:
System-Named Activation Group:

Connect

RV2W578-2

Implicit Connection Management for the Default Activation Group


The application requester can implicitly connect to an application server. Implicit SQL connection occurs when the application requester detects the rst SQL statement is being issued by the rst active SQL program for the default activation group and the following items are true: v The SQL statement being issued is not a CONNECT statement with parameters. v SQL is not active in the default activation group.

Chapter 28. Distributed Relational Database Function

565

For a distributed program, the implicit SQL connection is to the relational database specied on the RDB parameter. For a nondistributed program, the implicit SQL connection is to the local relational database. SQL will end any active connections in the default activation group when SQL becomes not active. SQL becomes not active when: v The application requester detects the rst active SQL program for the process has ended and the following are all true: There are no pending SQL changes There are no connections using protected connections A SET TRANSACTION statement is not active No programs that were precompiled with CLOSQLCSR(*ENDJOB) were run. If there are pending changes, protected connections, or an active SET TRANSACTION statement, SQL is placed in the exited state. If programs precompiled with CLOSQLCSR(*ENDJOB) were run, SQL will remain active for the default activation group until the job ends. v At the end of a unit of work if SQL is in the exited state. This occurs when you issue a COMMIT or ROLLBACK command outside of an SQL program. v At the end of a job.

Implicit Connection Management for Nondefault Activation Groups


The application requester can implicitly connect to an application server. Implicit SQL connection occurs when the application requester detects that the rst SQL statement issued for the activation group is not a CONNECT statement with parameters. For a distributed program, the implicit SQL connection is made to the relational database specied on the RDB parameter. For a nondistributed program, the implicit SQL connection is made to the local relational database. Implicit disconnect can occur at the following times in a process: v When the activation group ends, if commitment control is not active, activation group level commitment control is active, or the job level commitment denition is at a unit of work boundary. If the job level commitment denition is active and not at a unit of work boundary, SQL is placed in the exited state. v If SQL is in the exited state, when the job level commitment denition is committed or rolled back. v At the end of a job.

Distributed Support
DB2 UDB for AS/400 supports two levels of distributed relational database: v Remote unit of work (RUW) Remote unit of work is where the preparation and running of SQL statements occurs at only one application server during a unit of work. An activation group with an application process at an application requester can connect to an application server and, within one or more units of work, run any number of static or dynamic SQL statements that refer to objects on the application server. Remote unit of work is also referred to as DRDA level 1.

566

DB2 UDB for AS/400 SQL Programming V4R4

v Distributed unit of work (DUW) Distributed unit of work is where the preparation and running of SQL statements can occur at multiple applications servers during a unit of work. However, a single SQL statement can only refer to objects located at a single application server. Distributed unit of work is also referred to as DRDA level 2. Distributed unit of work allows: Update access to multiple application servers in one logical unit of work or Update access to a single application server with read access to multiple application servers, in one logical unit of work. Whether multiple application servers can be updated in a unit of work is dependent on the existence of a sync point manager at the application requester, sync point managers at the application servers, and two-phase commit protocol support between the application requester and the application servers. The sync point manager is a system component that coordinates commit and rollback operations among the participants in the two-phase commit protocol. When running distributed updates, the sync point managers on the different systems cooperate to ensure that resources reach a consistent state. The protocols and ows used by sync point managers are also referred to as two-phase commit protocols. If two-phase commit protocols will be used, the connection is a protected resource; otherwise the connection is an unprotected resource. The type of data transport protocols used between systems affects whether the network connection is protected or unprotected. In OS/400 V4R2, TCP/IP connections are always unprotected; thus they can participate in a distributed unit of work in only a limited way. For example, if the rst connection made from the program is to an AS/400 over TCP/IP, updates can be performed over it, but any subsequent connections, even over APPC, will be read only. Note that when using Interactive SQL, the rst SQL connection is to the local system. Therefore in order to make updates to a remote system using TCP/IP, you must do a RELEASE ALL followed by a COMMIT to end all SQL connections before doing the CONNECT TO remote-tcp-system.

Determining Connection Type


When a remote connection is established it will use either an unprotected or protected network connection. With regards to committable updates, this SQL connection may be read-only, updateable, or unknown whether it is updateable when the connection is established. A committable update is any insert, delete, update, or DDL statement that is run under commitment control. If the connection is read-only, changes using COMMIT(*NONE) can still be run. After a CONNECT or SET CONNECTION, SQLERRD(4) of the SQLCA indicates the type of connection. SQLERRD(4) will also indicate if the connection uses a unprotected or protected network connection. Specic values are: 1. Committable updates can be performed on the connection. The connection is unprotected. This will occur when:

Chapter 28. Distributed Relational Database Function

567

v The connection is established using remote unit of work (RDBCNNMTH(*RUW)). This also includes local connections and application requester driver (ARD) connections using remote unit of work. v If the connection is established using distributed unit of work (RDBCNNMTH(*DUW)) then all the following are true: The connection is not local. The application server does not support distributed unit of work. For example, a DB2 UDB for AS/400 application server with a release of OS/400 prior to Version 3 Release 1. The commitment control level of the program issuing the connect is not *NONE. Either no connections to other application servers (including local) exist that can perform committable updates or all connections are read-only connections to application servers that do not support distributed unit of work. There are no open updateable local les under commitment control for the commitment denition. There are no open updateable DDM les that use a different connection under commitment control for the commitment denition. There are no API commitment control resources for the commitment denition. There are no protected connections registered for the commitment denition. If running with commitment control, SQL will register a one-phase updateable DRDA resource for remote connections or a two-phase updateable DRDA resource for local and ARD connections. 2. No committable updates can be performed on the connection. The connection is read-only. The network connection is unprotected. This will never occur for applications compiled with remote unit of work connection management (*RUW). For distributed unit of work applications, this will occur only when the following are true when the connection is established: v The connection is not local. v The application server does not support distributed unit of work v At least one of the following is true: The commitment control level of the program issuing the connect is *NONE. Another connection exists to an application server that does not support distributed unit-of-work and that application server can perform committable updates Another connection exists to an application server that supports distributed unit-of-work (including local). There are open updateable local les under commitment control for the commitment denition. There are open updateable DDM les that use a different connection under commitment control for the commitment denition. There are no one-phase API commitment control resources for the commitment denition. There are protected connections registered for the commitment denition.

568

DB2 UDB for AS/400 SQL Programming V4R4

If running with commitment control, SQL will register a one-phase read-only resource. 3. It is unknown if committable updates can be performed. The connection is protected. This will never occur for applications compiled with remote unit of work connection management (*RUW). For distributed unit of work applications, this will occur when all of the following are true when the connection is established: v The connection is not local. v The commitment control level of the program issuing the connect is not *NONE. v The application server supports both distributed unit of work and two-phase commit protocol (protected connections). If running with commitment control, SQL will register a two-phase undetermined resource. 4. It is unknown if committable updates can be performed. The connection is not protected. This will never occur for applications compiled with remote unit of work connection management (*RUW). For distributed unit of work, this will occur only when all of the following are true when the connection is established: v The connection is not local. v The application server supports distributed unit of work v Either the application server does not support two-phase commit protocols (protected connections) or the commitment control level of the program issuing the connect is *NONE. If running with commitment control, SQL will register a one-phase DRDA undetermined resource. 5. It is unknown if committable updates can be performed and the connection is a local connection using distributed unit of work or an ARD connection using distributed unit of work. If running with commitment control, SQL will register a two-phase DRDA undetermined resource. For more information on two-phase and one-phase resources, see the Backup and Recovery book. The following table summarizes the type of connection that will result for remote distributed unit of work connections. SQLERRD(4) is set on successful CONNECT and SET CONNECTION statements.
Table 74. Summary of Connection Type
Application Server Supports Two-phase Commit No No Application Server Supports Distributed Unit of Work No No Other Updateable One-phase Resource Registered No Yes

Connect under Commitment Control No No

SQLERRD(4) 2 2

Chapter 28. Distributed Relational Database Function

569

Table 74. Summary of Connection Type (continued)


Application Server Supports Two-phase Commit No No Yes Yes Yes Yes No No No No Yes Yes Yes Yes Application Server Supports Distributed Unit of Work Yes Yes No No Yes Yes No No Yes Yes No No Yes Yes Other Updateable One-phase Resource Registered No Yes No Yes No Yes No Yes No Yes No Yes No Yes

Connect under Commitment Control No No No No No No Yes Yes Yes Yes Yes Yes Yes Yes

SQLERRD(4) 4 4 2 2 4 4 1 2 4 4 N/A * N/A * 3 3

*DRDA does not allow protected connections to be used to application servers which only support remote unit of work (DRDA1). This includes all DB2 for AS/400 TCP/IP connections.

Connect and Commitment Control Restrictions


There are some restrictions on when you can connect using commitment control. These restrictions also apply to attempting to run statements using commitment control but the connection was established using COMMIT(*NONE). If a two-phase undetermined or updateable resource is registered or a one-phase updateable resource is registered, another one-phase updateable resource cannot not be registered. Furthermore, when protected connections are inactive and the DDMCNV job attribute is *KEEP, these unused DDM connections will also cause the CONNECT statements in programs compiled with RUW connection management to fail. If running with RUW connection management and using the job-level commitment denition, then there are some restrictions. v If the job-level commitment denition is used by more than one activation group, all RUW connections must be to the local relational database. v If the connection is remote, only one activation group may use the job-level commitment denition for RUW connections.

Determining Connection Status


The CONNECT statement without parameters can be used to determine if the current connection is updateable or read-only for the current unit of work. A value of 1 or 2 will be returned in SQLERRD(3). The value in SQLERRD(3) is determined as follows:

570

DB2 UDB for AS/400 SQL Programming V4R4

1. Committable updates can be performed on the connection for the unit of work. This will occur when one of the following is true: v SQLERRD(4) has a value of 1. v All of the following are true: SQLERRD(4) has a value of 3 or 5. No connection exists to an application server that does not support distributed unit of work which can perform committable updates. One of the following is true: - The rst committable update is performed on a connection that uses a protected connection, is performed on the local database, or is performed on a connection to an ARD program. - There there are open updateable local les under commitment control. - There are open updateable DDM les that use protected connections. - There are two-phase API commitment control resources. - No committable updates have been made. v All of the following are true: SQLERRD(4) has a value of 4 No other connections exist to an application server that does not support distributed unit of work which can perform committable updates. The rst committable update is performed on this connection or no committable updates have been made. There are no open updateable DDM les that use protected connections. There are no open updateable local les under commitment control. There are no two-phase API commitment control resources. 2. No committable updates can be performed on the connection for this unit of work. This will occur when one of the following is true: v SQLERRD(4) has a value of 2. v SQLERRD(4) has a value of 3 or 5 and one of the following is true: A connection exists to an updateable application server that only supports remote unit of work. The rst committable update is performed on a connection that uses an unprotected connection. v SQLERRD(4) has a value of 4 and one of the following is true: A connection exists to an updateable application server that only supports remote unit of work. The rst committable update was not performed on this connection. There are open updateable DDM les that use protected connections. There are open updateable local les under commitment control. There are two-phase API commitment control resources. This following table summarizes how SQLERRD(3) is determined based on the SQLERRD(4) value, if there is an updateable connection to an application server that only supports remote unit of work, and where the rst committable update occurred.

Chapter 28. Distributed Relational Database Function

571

Table 75. Summary of Determining SQLERRD(3) Values


Connection Exists to Updateable Remote Unit of Work Application Server --Yes No No No No Yes No No No No Yes No No No No

SQLERRD(4) 1 2 3 3 3 3 3 4 4 4 4 4 5 5 5 5 5

Where First Committable Update Occurred * SQLERRD(3) ---no updates one-phase this connection two-phase -no updates one-phase this connection two-phase -no updates one-phase this connection two-phase 1 2 2 1 2 1 1 2 1 2 1 2 2 1 2 1 1

* The terms in this column are dened as: v No updates indicates no committable updates have been performed, no DDM les open for update using a protected connection, no local les are open for update, and no commitment control APIs are registered. v One-phase indicates the rst committable update was performed using an unprotected connection or DDM les are open for update using unprotected connections. v Two-phase indicates a committable update was performed on a two-phase distributed-unit-of-work application server, DDM les are open for update using a protected connection, commitment control APIs are registered, or local les are open for update under commitment control.

When the value of SQLERRD(4) is 3, 4, or 5 (due to an ARD program) and the value of SQLERRD(3) is 2, if an attempt is made to perform a committable update over the connection, the unit of work will be placed in a rollback required state. If an unit of work is in a rollback required state, the only statement allowed is a ROLLBACK statement; all other statements will result in SQLCODE -918.

Distributed Unit of Work Connection Considerations


When connecting in a distributed unit of work application, there are many considerations. This section lists some design considerations. v If the unit of work will perform updates at more than one application server and commitment control will be used, all connections over which updates will be done should be made using commitment control. If the connections are done not using commitment control and later committable updates are performed, read-only connections for the unit of work are likely to result.

572

DB2 UDB for AS/400 SQL Programming V4R4

v Other non-SQL commit resources, such as local les, DDM les, and commitment control API resources, will affect the updateable and read-only status of a connection. v If connecting using commitment control to an application server that does not support distributed unit of work (for example, a V4R2 AS/400 using TCP/IP), that connection will be either updateable or read-only. If the connection is updateable it is the only updateable connection.

Ending Connections
Because remote connections use resources, connections that are no longer going to be used should be ended as soon as possible. Connections can be ended implicitly or explicitly. For a description of when connections are implicitly ended see Implicit Connection Management for the Default Activation Group on page 565 and Implicit Connection Management for Nondefault Activation Groups on page 566. Connections can be explicitly ended by either the DISCONNECT statement or the RELEASE statement followed by a successful COMMIT. The DISCONNECT statement can only be used with connections that use unprotected connections or with local connections. The DISCONNECT statement will end the connection when the statement is run. The RELEASE statement can be used with either protected or unprotected connections. When the RELEASE statement is run, the connection is not ended but instead placed into the released state. A connection that is in the release stated can still be used. The connection is not ended until a successful COMMIT is run. A ROLLBACK or an unsuccessful COMMIT will not end a connection in the released state. When a remote SQL connection is established, a DDM network connection (APPC conversation or TCP/IP connection) is used. When the SQL connection is ended, the network connection may either be placed in the unused state or dropped. Whether a network connection is dropped or placed in the unused state depends on the DDMCNV job attribute. If the job attribute value is *KEEP and the connection is to another AS/400, the connection becomes unused. If the job attribute value is *DROP and the connection is to another AS/400, the connection is dropped. If the connection is to a non-AS/400, the connection is always dropped. *DROP is desirable in the following situations: v When the cost of maintaining the unused connection is high and the connection will not be used relatively soon. v When running with a mixture of programs, some compiled with RUW connection management and some programs compiled with DUW connection management. Attempts to run programs compiled with RUW connection management to remote locations will fail when protected connections exist. v When running with protected connections using either DDM or DRDA. Additional overhead is incurred on commits and rollbacks for unused protected connections. The Reclaim DDM connections (RCLDDMCNV) command may be used to end all unused connections.

Distributed Unit of Work


Distributed unit of work (DUW) allows access to multiple application servers within the same unit of work. Each SQL statement can access only one application server. Using distributed unit of work allows changes at multiple applications servers to be committed or rolled back within a single unit of work.

Chapter 28. Distributed Relational Database Function

573

Managing Distributed Unit of Work Connections


The CONNECT, SET CONNECTION, DISCONNECT, and RELEASE statements are used to manage connections in the DUW environment. A distributed unit of work CONNECT is run when the program is precompiled using RDBCNNMTH(*DUW), which is the default. This form of the CONNECT statement does not disconnect existing connections but instead places the previous connection in the dormant state. The relational database specied on the CONNECT statement becomes the current connection. The CONNECT statement can only be used to start new connections; if you want to switch between existing connections, the SET CONNECTION statement must be used. Because connections use system resources, connections should be ended when they are no longer needed. The RELEASE or DISCONNECT statement can be used to end connections. The RELEASE statement must be followed by a successful commit in order for the connections to end. The following is an example of a C program running in a DUW environment that uses commitment control.
.... EXEC SQL WHENEVER SQLERROR GO TO done; EXEC SQL WHENEVER NOT FOUND GO TO done; .... EXEC SQL DECLARE C1 CURSOR WITH HOLD FOR SELECT PARTNO, PRICE FROM PARTS WHERE SITES_UPDATED = 'N' FOR UPDATE OF SITES_UPDATED; /* Connect to the systems */ EXEC SQL CONNECT TO LOCALSYS; EXEC SQL CONNECT TO SYSB; EXEC SQL CONNECT TO SYSC; /* Make the local system the current connection */ EXEC SQL SET CONNECTION LOCALSYS; /* Open the cursor */ EXEC SQL OPEN C1;

Figure 36. Example of Distributed Unit of Work Program (Part 1 of 4)

574

DB2 UDB for AS/400 SQL Programming V4R4

while (SQLCODE==0) { /* Fetch the first row */ EXEC SQL FETCH C1 INTO :partnumber,:price; /* Update the row which indicates that the updates have been propagated to the other sites */ EXEC SQL UPDATE PARTS SET SITES_UPDATED='Y' WHERE CURRENT OF C1; /* Check if the part data is on SYSB */ if ((partnumber > 10) && (partnumber < 100)) { /* Make SYSB the current connection and update the price */ EXEC SQL SET CONNECTION SYSB; EXEC SQL UPDATE PARTS SET PRICE=:price WHERE PARTNO=:partnumber; }

Figure 36. Example of Distributed Unit of Work Program (Part 2 of 4)

/* Check if the part data is on SYSC */ if ((partnumber > 50) && (partnumber < 200)) { /* Make SYSC the current connection and update the price */ EXEC SQL SET CONNECTION SYSC; EXEC SQL UPDATE PARTS SET PRICE=:price WHERE PARTNO=:partnumber; } /* Commit the changes made at all 3 sites */ EXEC SQL COMMIT; /* Set the current connection to local so the next row can be fetched */ EXEC SQL SET CONNECTION LOCALSYS; } done:

Figure 36. Example of Distributed Unit of Work Program (Part 3 of 4)


EXEC SQL WHENEVER SQLERROR /* Release the connections EXEC SQL RELEASE SYSB; EXEC SQL RELEASE SYSC; /* Close the cursor */ EXEC SQL CLOSE C1; /* Do another commit which The local connection is released. */ EXEC SQL COMMIT; ... CONTINUE; that are no longer being used */

will end the released connections. still active because it was not

Figure 36. Example of Distributed Unit of Work Program (Part 4 of 4)

In this program, there are 3 application servers active: LOCALSYS which the local system, and 2 remote systems, SYSB and SYSC. SYSB and SYSC also support distributed unit of work and two-phase commit. Initially all connections are made active by using the CONNECT statement for each of the application servers involved in the transaction. When using DUW, a CONNECT statement does not disconnect the previous connection, but instead places the previous connection in
Chapter 28. Distributed Relational Database Function

575

the dormant state. After all the application servers, have been connected, the local connection is made the current connection using the SET CONNECTION statement. The cursor is then opened and the rst row of data fetched. It is then determined at which application servers the data needs to be updated. If SYSB needs to be updated, then SYSB is made the current connection using the SET CONNECTION statement and the update is run. The same is done for SYSC. The changes are then committed. Because two-phase commit is being used, it is guaranteed that the changes are committed at the local system and the two remote systems. Because the cursor was declared WITH HOLD, it remains open after the commit. The current connection is then changed to the local system so that the next row of data can be fetched. This set of fetches, updates, and commits is repeated until all the data has been processed. After all the data has been fetched, the connections for both remote systems are released. They can not be disconnected because they use protected connections. After the connections are released, a commit is issued to end the connections. The local system is still connected and continues processing.

Checking Connection Status


If running in an environment where it is possible to have read-only connections, the status of the connection should be checked before doing committable updates. This will prevent the unit of work from entering the rollback required state. The following COBOL example shows how to check the connection status.
... EXEC SQL SET CONNECTION SYS5 END-EXEC. ... * Check if the connection is updateable. EXEC SQL CONNECT END-EXEC. * If connection is updateable, update sales information otherwise * inform the user. IF SQLERRD(3) = 1 THEN EXEC SQL INSERT INTO SALES_TABLE VALUES(:SALES-DATA) END-EXEC ELSE DISPLAY 'Unable to update sales information at this time'. ...

Figure 37. Example of Checking Connection Status

Cursors and Prepared Statements


Cursors and prepared statements are scoped to the compilation unit and also to the connection. Scoping to the compilation unit means that a program called from another separately compiled program cannot use a cursor or prepared statement that was opened or prepared by the calling program. Scoping to the connection means that each connection within a program can have its own separate instance of a cursor or prepared statement. The following distributed unit of work example shows how the same cursor name is opened in two different connections, resulting in two instances of cursor C1.

576

DB2 UDB for AS/400 SQL Programming V4R4

..... EXEC SQL DECLARE C1 CURSOR FOR SELECT * FROM CORPDATA.EMPLOYEE; /* Connect to local and open C1 */ EXEC SQL CONNECT TO LOCALSYS; EXEC SQL OPEN C1; /* Connect to the remote system and open C1 */ EXEC SQL CONNECT TO SYSA; EXEC SQL OPEN C1; /* Keep processing until done */ while (NOT_DONE) { /* Fetch a row of data from the local system */ EXEC SQL SET CONNECTION LOCALSYS; EXEC SQL FETCH C1 INTO :local_emp_struct; /* Fetch a row of data from the remote system */ EXEC SQL SET CONNECTION SYSA; EXEC SQL FETCH C1 INTO :rmt_emp_struct; /* Process the data */ ..... } /* Close the cursor on the remote system */ EXEC SQL CLOSE C1; /* Close the cursor on the local system */ EXEC SQL SET CONNECTION LOCALSYS; EXEC SQL CLOSE C1; .....

Figure 38. Example of Cursors in a DUW program

Application Requester Driver Programs


To complement database access provided by products that implement DRDA, DB2 UDB for AS/400 provides an interface for writing exit programs on a DB2 UDB for AS/400 application requester to process SQL requests. Such an exit program is called an application requester driver. The AS/400 calls the ARD program during the following operations: v During package creation performed using the CRTSQLPKG or CRTSQLxxx commands, when the relational database (RDB) parameter matches the RDB name corresponding to the ARD program. v Processing of SQL statements when the current connection is to an RDB name corresponding to the ARD program. These calls allow the ARD program to pass the SQL statements and information about the statements to a remote relational database and return results back to the system. The system then returns the results to the application or the user. Access to relational databases accessed by ARD programs appears like access to DRDA application servers in the unlike environment. For more information about application requester driver programs, see the System API Reference.

Chapter 28. Distributed Relational Database Function

577

Problem Handling
The primary strategy for capturing and reporting error information for the AS/400 distributed database function is called rst failure data capture (FFDC). The purpose of FFDC support is to provide accurate information on errors detected in the DDM components of the OS/400 system from which an APAR 19 can be created. By means of this function, key structures and the DDM data stream are automatically dumped to a spool le. The rst 1024 bytes of the error information are also logged in the system error log. This automatic dumping of error information on the rst occurrence of an error means that the failure should not have to be recreated to be reported by the customer. FFDC is active in both the application requester and application server functions of the OS/400 DDM component. However, for the FFDC data to be logged, the system value QSFWERRLOG must be set to *LOG. Note: Not all negative SQLCODEs are dumped; only those that can be used to produce an APAR are dumped. For more information on handling problems on distributed relational database operations, see the Distributed Database Problem Determination Guide When an SQL error is detected, an SQLCODE with a corresponding SQLSTATE is returned in the SQLCA. For more information on these codes, see Appendix B. SQLCODEs and SQLSTATEs.

19. Authorized Program Analysis Report (APAR).

578

DB2 UDB for AS/400 SQL Programming V4R4

Appendix A. DB2 UDB for AS/400 Sample Tables


This appendix contains the sample tables referred to and used in this guide and the DB2 UDB for AS/400 SQL Reference book. Along with the tables are the SQL statements for creating the tables. For detailed information on creating tables, see Creating and Using a Table on page 14. As a group, the EMPLOYEE, DEPARTMENT, PROJECT, and EMP_ACT tables include information that describes employees, departments, projects, and activities. This information makes up a sample application demonstrating some of the features of the DB2 UDB Query Manager and SQL Development Kit licensed program. The tables are in a collection named CORPDATA (for corporate data). The tables are: v v v v v v Department table (CORPDATA.DEPARTMENT) Employee table (CORPDATA.EMPLOYEE) Employee to project activity table (CORPDATA.EMP_ACT) Project table (CORPDATA.PROJECT) Class Schedule table (CL_SCHED) In Tray table (IN_TRAY)

Notes: 1. In these sample tables, a question mark (?) indicates a null value. 2. The IN_TRAY and CL_SCHED tables are used to illustrate examples that include dates and times given in the DB2 UDB for AS/400 SQL Reference book. They are not related to the examples in the CORPDATA collection.

Department Table (CORPDATA.DEPARTMENT)


The department table describes each department in the enterprise and identies its manager and the department it reports to. The department table is created with the following CREATE TABLE statement:
CREATE TABLE CORPDATA.DEPARTMENT (DEPTNO CHAR(3) DEPTNAME VARCHAR(29) MGRNO CHAR(6) ADMRDEPT CHAR(3) NOT NULL, NOT NULL, , NOT NULL )

The following table shows the content of the columns:


Table 76. Columns of the Department Table
Column Name DEPTNO DEPTNAME MGRNO ADMRDEPT Description Department number or ID. A name describing the general activities of the department. Employee number (EMPNO) of the department manager. The department (DEPTNO) to which this department reports; the department at the highest level reports to itself.

Copyright IBM Corp. 1997, 1999

579

DEPARTMENT
DEPTNO A00 B01 C01 D01 D11 D21 E01 E11 E21 DEPTNAME SPIFFY COMPUTER SERVICE DIV. PLANNING INFORMATION CENTER DEVELOPMENT CENTER MANUFACTURING SYSTEMS ADMINISTRATION SYSTEMS SUPPORT SERVICES OPERATIONS SOFTWARE SUPPORT MGRNO 000010 000020 000030 ? 000060 000070 000050 000090 000100 ADMRDEPT A00 A00 A00 A00 D01 D01 A00 E01 E01

Employee Table (CORPDATA.EMPLOYEE)


The employee table identies all employees by an employee number and lists basic personnel information. The employee table is created with the following CREATE TABLE statement:
CREATE TABLE CORPDATA.EMPLOYEE (EMPNO CHAR(6) FIRSTNME VARCHAR(12) MIDINIT CHAR(1) LASTNAME VARCHAR(15) WORKDEPT CHAR(3) PHONENO CHAR(4) HIREDATE DATE JOB CHAR(8) EDLEVEL SMALLINT SEX CHAR(1) BIRTHDATE DATE SALARY DECIMAL(9,2) BONUS DECIMAL(9,2) COMM DECIMAL(9,2) NOT NULL, NOT NULL, NOT NULL, NOT NULL, , , , , NOT NULL, , , , , )

The table below shows the content of the columns.


Column Name EMPNO FIRSTNME MIDINIT LASTNAME WORKDEPT PHONENO HIREDATE JOB EDLEVEL SEX BIRTHDATE SALARY Description Employee number First name of employee Middle initial of employee Last name of employee ID of department in which the employee works Employee telephone number Date of hire Job held by the employee Number of years of formal education Sex of the employee (M or F) Date of birth Yearly salary in dollars

580

DB2 UDB for AS/400 SQL Programming V4R4

Column Name BONUS COMM

Description Yearly bonus in dollars Yearly commission in dollars

EMP NO 000010 000020 000030 000050 000060 000070 000090 000100 000110 000120 000130 000140 000150 000160 000170 000180 000190 000200 000210 000220 000230 000240 000250 000260 000270 000280 000290 000300 000310 000320 000330 000340

FIRST NAME CHRISTINE MICHAEL SALLY JOHN IRVING EVA EILEEN THEODORE VINCENZO SEAN DOLORES HEATHER BRUCE ELIZABETH MASATOSHI MARILYN JAMES DAVID WILLIAM JENNIFER JAMES SALVATORE DANIEL SYBIL MARIA ETHEL JOHN PHILIP MAUDE RAMLAL WING JASON

MID INIT I L A B F D W Q G M A R J S H T K J M S P L R R X F V R

LASTNAME HAAS THOMPSON KWAN GEYER STERN PULASKI HENDERSON SPENSER LUCCHESSI O'CONNELL QUINTANA NICHOLLS ADAMSON PIANKA YOSHIMURA SCOUTTEN WALKER BROWN JONES LUTZ JEFFERSON MARINO SMITH JOHNSON PEREZ SCHNEIDER PARKER SMITH SETRIGHT MEHTA LEE GOUNOT

WORK DEPT A00 B01 C01 E01 D11 D21 E11 E21 A00 A00 C01 C01 D11 D11 D11 D11 D11 D11 D11 D11 D21 D21 D21 D21 D21 E11 E11 E11 E11 E21 E21 E21

PHONE NO 3978 3476 4738 6789 6423 7831 5498 0972 3490 2167 4578 1793 4510 3782 2890 1682 2986 4501 0942 0672 2094 3780 0961 8953 9001 8997 4502 2095 3332 9990 2103 5698

HIRE DATE 1965-01-01 1973-10-10 1975-04-05 1949-08-17 1973-09-14 1980-09-30 1970-08-15 1980-06-19 1958-05-16 1963-12-05 1971-07-28 1976-12-15 1972-02-12 1977-10-11 1978-09-15 1973-07-07 1974-07-26 1966-03-03 1979-04-11 1968-08-29 1966-11-21 1979-12-05 1969-10-30 1975-09-11 1980-09-30 1967-03-24 1980-05-30 1972-06-19 1964-09-12 1965-07-07 1976-02-23 1947-05-05

JOB PRES MANAGER MANAGER MANAGER MANAGER MANAGER MANAGER MANAGER SALESREP CLERK ANALYST ANALYST DESIGNER DESIGNER DESIGNER DESIGNER DESIGNER DESIGNER DESIGNER DESIGNER CLERK CLERK CLERK CLERK CLERK OPERATOR OPERATOR OPERATOR OPERATOR FILEREP FILEREP FILEREP

ED LEVEL 18 18 20 16 16 16 16 14 19 14 16 18 16 17 16 17 16 16 17 18 14 17 15 16 15 17 12 14 12 16 14 16

SEX F M F M M F F M M M F F M F M F M M M F M M M F F F M M F M M M

BIRTH DATE 1933-08-24 1948-02-02 1941-05-11 1925-09-15 1945-07-07 1953-05-26 1941-05-15 1956-12-18 1929-11-05 1942-10-18 1925-09-15 1946-01-19 1947-05-17 1955-04-12 1951-01-05 1949-02-21 1952-06-25 1941-05-29 1953-02-23 1948-03-19 1935-05-30 1954-03-31 1939-11-12 1936-10-05 1953-05-26 1936-03-28 1946-07-09 1936-10-27 1931-04-21 1932-08-11 1941-07-18 1926-05-17

SALARY 52750 41250 38250 40175 32250 36170 29750 26150 46500 29250 23800 28420 25280 22250 24680 21340 20450 27740 18270 29840 22180 28760 19180 17250 27380 26250 15340 17750 15900 19950 25370 23840

BONUS 1000 800 800 800 500 700 600 500 900 600 500 600 500 400 500 500 400 600 400 600 400 600 400 300 500 500 300 400 300 400 500 500

COMM 4220 3300 3060 3214 2580 2893 2380 2092 3720 2340 1904 2274 2022 1780 1974 1707 1636 2217 1462 2387 1774 2301 1534 1380 2190 2100 1227 1420 1272 1596 2030 1907

Employee to Project Activity Table (CORPDATA.EMP_ACT)


The employee to project activity table identies the employee who performs each activity listed for each project. The employees level of involvement (full-time or part-time) and schedule for activity are also in the table. The employee to project activity table is created with the following CREATE TABLE statement:
CREATE TABLE CORPDATA.EMP_ACT (EMPNO CHAR(6) PROJNO CHAR(6) ACTNO SMALLINT EMPTIME DECIMAL(5,2) EMSTDATE DATE EMENDATE DATE NOT NULL, NOT NULL, NOT NULL, , , )

The table below shows the content of the columns.


Table 77. Columns of the Employee to Project Activity Table
Column Name EMPNO PROJNO ACTNO EMPTIME EMSTDATE Description Employee ID number PROJNO of the project to which the employee is assigned ID of an activity within a project to which an employee is assigned A proportion of the employees full time (between 0.00 and 1.00) to be spent on the project from EMSTDATE to EMENDATE Start date of the activity

Appendix A. DB2 UDB for AS/400 Sample Tables

581

Table 77. Columns of the Employee to Project Activity Table (continued)


Column Name EMENDATE Description Completion date of the activity

EMP_ACT
EMPNO 000010 000070 000230 000230 000230 000230 000230 000240 000240 000250 000250 000250 000250 000250 000250 000250 000250 000250 000250 000260 000260 000260 000260 000260 000260 000260 000270 000270 000270 000270 000270 000270 000270 000030 000130 000130 PROJNO AD3100 AD3110 AD3111 AD3111 AD3111 AD3111 AD3111 AD3111 AD3111 AD3112 AD3112 AD3112 AD3112 AD3112 AD3112 AD3112 AD3112 AD3112 AD3112 AD3113 AD3113 AD3113 AD3113 AD3113 AD3113 AD3113 AD3113 AD3113 AD3113 AD3113 AD3113 AD3113 AD3113 IF1000 IF1000 IF1000 ACTNO 10 10 60 60 70 80 180 70 80 60 60 60 60 70 70 70 80 80 180 70 70 80 80 180 180 180 60 60 60 70 70 80 80 10 90 100 EMPTIME .50 1.00 1.00 .50 .50 .50 1.00 1.00 1.00 1.00 .50 .50 1.00 .50 1.00 .25 .25 .50 .50 .50 1.00 1.00 .50 .50 1.00 .50 .50 1.00 .25 .75 1.00 1.00 .50 .50 1.00 .50 EMSTDATE 1982-01-01 1982-01-01 1982-01-01 1982-03-15 1982-03-15 1982-04-15 1982-10-15 1982-02-15 1982-09-15 1982-01-01 1982-02-01 1982-12-01 1983-01-01 1982-02-01 1982-03-15 1982-08-15 1982-08-15 1982-10-15 1982-08-15 1982-06-15 1982-07-01 1982-01-01 1982-03-01 1982-03-01 1982-04-15 1982-06-01 1982-03-01 1982-04-01 1982-09-01 1982-09-01 1982-10-15 1982-01-01 1982-03-01 1982-06-01 1982-01-01 1982-10-01 EMENDATE 1982-07-01 1983-02-01 1982-03-15 1982-04-15 1982-10-15 1982-10-15 1983-01-01 1982-09-15 1983-01-01 1982-02-01 1982-03-15 1983-01-01 1983-02-01 1982-03-15 1982-08-15 1982-10-15 1982-10-15 1982-12-01 1983-01-01 1982-07-01 1983-02-01 1982-03-01 1982-04-15 1982-04-15 1982-06-01 1982-07-01 1982-04-01 1982-09-01 1982-10-15 1982-10-15 1983-02-01 1982-03-01 1982-04-01 1983-01-01 1982-10-01 1983-01-01

582

DB2 UDB for AS/400 SQL Programming V4R4

EMPNO 000140 000030 000140 000140 000140 000140 000010 000110 000010 000200 000200 000220 000150 000150 000170 000170 000190 000190 000160 000170 000180 000210 000210 000050 000090 000280 000290 000300 000310 000050 000100 000320 000320 000330 000330 000340 000340 000020

PROJNO IF1000 IF2000 IF2000 IF2000 IF2000 IF2000 MA2100 MA2100 MA2110 MA2111 MA2111 MA2111 MA2112 MA2112 MA2112 MA2112 MA2112 MA2112 MA2113 MA2113 MA2113 MA2113 MA2113 OP1000 OP1010 OP1010 OP1010 OP1010 OP1010 OP2010 OP2010 OP2011 OP2011 OP2012 OP2012 OP2013 OP2013 PL2100

ACTNO 90 10 100 100 110 110 10 20 10 50 60 40 60 180 60 70 70 80 60 80 70 80 180 10 10 130 130 130 130 10 10 140 150 140 160 140 170 30

EMPTIME .50 .50 1.00 .50 .50 .50 .50 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 .50 .50 .25 1.00 1.00 1.00 1.00 1.00 .75 1.00 .75 .25 .25 .75 .50 .50 1.00

EMSTDATE 1982-10-01 1982-01-01 1982-01-01 1982-03-01 1982-03-01 1982-10-01 1982-01-01 1982-01-01 1982-01-01 1982-01-01 1982-06-15 1982-01-01 1982-01-01 1982-07-15 1982-01-01 1982-06-01 1982-02-01 1982-10-01 1982-07-15 1982-01-01 1982-04-01 1982-10-01 1982-10-01 1982-01-01 1982-01-01 1982-01-01 1982-01-01 1982-01-01 1982-01-01 1982-01-01 1982-01-01 1982-01-01 1982-01-01 1982-01-01 1982-01-01 1982-01-01 1982-01-01 1982-01-01

EMENDATE 1983-01-01 1983-01-01 1982-03-01 1982-07-01 1982-07-01 1983-01-01 1982-11-01 1982-03-01 1983-02-01 1982-06-15 1983-02-01 1983-02-01 1982-07-15 1983-02-01 1983-06-01 1983-02-01 1982-10-01 1983-10-01 1983-02-01 1983-02-01 1982-06-15 1983-02-01 1983-02-01 1983-02-01 1983-02-01 1983-02-01 1983-02-01 1983-02-01 1983-02-01 1983-02-01 1983-02-01 1983-02-01 1983-02-01 1983-02-01 1983-02-01 1983-02-01 1983-02-01 1982-09-15

Appendix A. DB2 UDB for AS/400 Sample Tables

583

Project Table (CORPDATA.PROJECT)


The project table describes each project that the business is currently undertaking. Data contained in each row include the project number, name, person responsible, and schedule dates. The project table is created with the following CREATE TABLE statement:
CREATE TABLE CORPDATA.PROJECT (PROJNO CHAR(6) PROJNAME VARCHAR(24) DEPTNO CHAR(3) RESPEMP CHAR(6) PRSTAFF DECIMAL(5,2) PRSTDATE DATE PRENDATE DATE MAJPROJ CHAR(6) NOT NOT NOT NOT NULL, NULL, NULL, NULL, , , , )

The table below shows the contents of the columns:


Column Name PROJNO PROJNAME DEPTNO RESPEMP PRSTAFF PRSTDATE PRENDATE MAJPROJ Description Project number Project name Department number of the department responsible for the project Employee number of the person responsible for the project Estimated mean staffing Estimated start date of the project Estimated end date of the project Controlling project number for sub projects

PROJECT
PROJNO AD3100 AD3110 AD3111 AD3112 AD3113 IF1000 IF2000 MA2100 MA2110 MA2111 PROJNAME DEPTNO RESPEMP 000010 000070 000230 000250 000270 000030 000030 000010 000060 000220 PRSTAFF 6.5 6 2 1 2 2 1 12 9 2 PRSTDATE 1982-01-01 1982-01-01 1982-01-01 1982-01-01 1982-01-01 1982-01-01 1982-01-01 1982-01-01 1982-01-01 1982-01-01 PRENDATE 1983-02-01 1983-02-01 1983-02-01 1983-02-01 1983-02-01 1983-02-01 1983-02-01 1983-02-01 1983-02-01 1982-12-01 MAJPROJ ? AD3100 AD3110 AD3110 AD3110 ? ? ? MA2100 MA2110 ADMIN SERVICES D01 GENERAL ADMIN SYSTEMS PAYROLL PROGRAMMING PERSONNEL PROGRAMMING ACCOUNT PROGRAMMING QUERY SERVICES USER EDUCATION WELD LINE AUTOMATION WL PROGRAMMING W L PROGRAM DESIGN D21 D21 D21 D21 C01 C01 D01 D11 D11

584

DB2 UDB for AS/400 SQL Programming V4R4

PROJNO MA2112 MA2113 OP1000 OP1010 OP2000 OP2010 OP2011 OP2012 OP2013 PL2100

PROJNAME W L ROBOT DESIGN W L PROD CONT PROGS OPERATION SUPPORT OPERATION GEN SYSTEMS SERVICES SYSTEMS SUPPORT SCP SYSTEMS SUPPORT APPLICATIONS SUPPORT DB/DC SUPPORT WELD LINE PLANNING

DEPTNO D11 D11 E01 E11 E01 E21 E21 E21 E21 B01

RESPEMP 000150 000160 000050 000090 000050 000100 000320 000330 000340 000020

PRSTAFF 3 3 6 5 5 4 1 1 1 1

PRSTDATE 1982-01-01 1982-02-15 1982-01-01 1982-01-01 1982-01-01 1982-01-01 1982-01-01 1982-01-01 1982-01-01 1982-01-01

PRENDATE 1982-12-01 1982-12-01 1983-02-01 1983-02-01 1983-02-01 1983-02-01 1983-02-01 1983-02-01 1983-02-01 1982-09-15

MAJPROJ MA2110 MA2110 ? OP1000 ? OP2000 OP2010 OP2010 OP2010 MA2100

Class Schedule Table (CL_SCHED)


The class schedule table describes: each class, the start time for the class, the end time for the class, and the class code. The class schedule table is created with the following CREATE TABLE statement:
CREATE TABLE CL_SCHED (CLASS_CODE DAY STARTING ENDING CHAR(7), SMALLINT, TIME, TIME)

The table below gives the contents of the columns.


Column Name CLASS_CODE DAY STARTING ENDING Description Class code (room:teacher) Day number of 4 day schedule Class start time Class end time

Note: This table has no data.

In Tray Table (IN_TRAY)


The in tray table describes an electronic in-basket containing: a timestamp from when the message was received, the user ID of the person sending the message, and the message itself. The in tray table is created with the following CREATE TABLE statement:

Appendix A. DB2 UDB for AS/400 Sample Tables

585

CREATE TABLE IN_TRAY (RECEIVED SOURCE SUBJECT NOTE_TEXT

TIMESTAMP, CHAR(8), CHAR(64), VARCHAR(3000))

The table below gives the contents of the columns.


Column Name RECEIVED SOURCE SUBJECT NOTE_TEXT Description Date and time received User ID of person sending the note Brief description of the note The note

Note: This table has no data.

586

DB2 UDB for AS/400 SQL Programming V4R4

Appendix B. SQLCODEs and SQLSTATEs


SQL does not communicate directly with the end user but rather returns error codes to the application program when an error occurs. This appendix lists SQLCODEs and their associated SQLSTATEs. There are many other SQL messages, but they are not listed here. Detailed descriptions of all DB2 UDB for AS/400 messages, including SQLCODEs, are available on-line and can be displayed and printed from the Display Message Description display. You can access this display by using the CL command Display Message Description (DSPMSGD). | | If you wish, you can quickly reference Positive SQLCODEs on page 589 or Negative SQLCODEs on page 591. SQLCODEs are returned in the SQLCA structure. SQLSTATE is an additional return code that provides application programs with common return codes for common error conditions found among the IBM relational database systems. SQLSTATEs are particularly useful when handling errors in distributed SQL applications. Every SQLCODE has a corresponding message in message le QSQLMSG in library QSYS. The message ID for any SQLCODE is constructed by appending the absolute value (5 digits) of the SQLCODE to SQ and changing the third character to 'L' if the third character is a 0. For example, if the SQLCODE is 30070, the message ID is SQ30070. If SQL encounters an error while processing the statement, the rst characters of the SQLSTATE are not '00', '01' or '02', and the SQLCODE is a negative number. If SQL encounters a warning but valid condition while processing your statement, the SQLCODE is a positive number and bytes one and two of the SQLSTATE are '01'. If your SQL statement is processed without encountering an error or warning condition, the SQLCODE returned is 0 and SQLSTATE is '00000'. When running in debug mode, SQL places a message corresponding to the SQLCODE in the job log for each SQL statement run. If you are not running in debug mode and get a negative SQLCODE, you will get a message in the job log also. An application can also send the SQL message corresponding to any SQLCODE to the job log by specifying the message ID and the replacement text on the CL commands Retrieve Message (RTVMSG), Send Program Message (SNDPGMMSG), and Send User Message (SNDUSRMSG). SQLSTATE values consist of a two-character class code, followed by a three-character code. The class codes conform to ISO/ANSI standards. The class codes are: v 00 Unqualied Successful Completion v v v v v 01 02 03 07 08 Warning No Data SQL Statement Not Yet Complete Dynamic SQL Error Connection Exception

v 09 Triggered Action Exception


Copyright IBM Corp. 1997, 1999

587

v v v v v v v v v v v v v v v v v v

0A Feature Not Supported 09 Invalid Token 20 Case Not Found for CASE Statement 21 Cardinality Violation 22 Data Exception 23 Constraint Violation 24 Invalid Cursor State 25 Invalid Transaction State 26 Invalid SQL Statement Identier 27 Triggered Data Change Violation 28 Invalid Authorization Specication 2B Dependent Privilege Descriptors Still Exist 2C Invalid Character Set Name 2D Invalid Transaction Termination 2E Invalid Connection Name 2F SQL Function Exception 33 Invalid SQL Descriptor Name 34 Invalid Cursor Name

v 35 Invalid Condition Number v 38 External Function Exception v 39 External Function Call Exception v v v v v v v v v v v v 3C Ambiguous Cursor Name 3D Invalid Catalog Name 3F Invalid Collection (Schema) Name 40 Transaction Rollback 42 44 51 53 54 55 56 57 Syntax Error and Access Rule Violation WITH CHECK OPTION Violation Invalid Application State Invalid Operand or Inconsistent Specication SQL or Product Limit Exceeded Object Not in Prerequisite State Miscellaneous SQL or Product Error Resource Not Available or Operator Intervention

v 58 System Error For a list of SQLSTATEs that are used by the DB2 family of products, see IBM SQL Reference, Version 2, SC26-8416. Also available on CD-ROM as a part of the Transaction Processing Collection Kit CD-ROM, SK2T-0730-11. When an SQLSTATE other than '00000' is returned from a non-DB2 UDB for AS/400 application server, DB2 UDB for AS/400 attempts to map the SQLSTATE to a DB2 UDB for AS/400 SQLCODE and message: v If the SQLSTATE is not recognized by DB2 UDB for AS/400, the common message for the class is issued.

588

DB2 UDB for AS/400 SQL Programming V4R4

v If the SQLSTATE and SQLCODE correspond to a single DB2 UDB for AS/400 SQLCODE, DB2 UDB for AS/400 attempts to convert the tokens returned in SQLERRM to the replacement data expected by the SQL message. If an error occurs while converting the tokens: The SQLCA is not changed. A common message for the class code of the SQLSTATE is issued.

SQLCODE and SQLSTATE Descriptions


In the following brief descriptions of the SQLCODEs (and their associated SQLSTATEs) message data elds are identied by an ampersand (&); and a number (for example, &1); The replacement text for these elds is stored in SQLERRM in the SQLCA. More detailed cause and recovery information for any SQLCODE can be found by using the Display Message Description (DSPMSGD) CL command.

Positive SQLCODEs
N/A SQLCODE 0 SQL0088 SQLCODE +88 SQLSTATE 01504

Explanation: The SQL statement has run successfully. If SQLWARN0 is blank, and SQLSTATE is '00000', the statement was run successfully. Otherwise, a warning condition exists. Check the other warning indicators or SQLSTATE to determine the particular warning condition. For example, if SQLWARN1 is not blank, a string has been truncated. The following warnings have an SQLCODE of zero: v SQLWARN1 SQLSTATE 01004 Explanation: The value of a string column was truncated when assigned to a host variable. v SQLWARN2 SQLSTATE 01003 Explanation: Null values were eliminated from the argument of a column function. v SQLWARN3 SQLSTATE 01503 Explanation: The number of result columns is larger than the number of host variables provided. v SQLWARN4 SQLSTATE 01504 Explanation: The UPDATE or DELETE statement does not include a WHERE clause. v SQLWARN6 SQLSTATE 01506 Explanation: An adjustment was made to a DATE or TIMESTAMP value to correct a date the was not valid. The date resulted from an arithmetic operation. SQL0012 SQLCODE +12 SQLSTATE 01545

Explanation: No WHERE on UPDATE or DELETE. SQL0100 SQLCODE +100 SQLSTATE 02000

Explanation: Row not found for &1. SQL0114 SQLCODE +114 SQLSTATE 01536

Explanation: Relational database &1 not the same as current server &2. SQL0138 SQLCODE +138 SQLSTATE 01544

Explanation: Argument &1 of SUBSTR function not valid. SQL0177 SQLCODE +177 SQLSTATE 01009

Explanation: CHECK condition text too long. SQL0178 SQLCODE +178 SQLSTATE 0100A

Explanation: Query expression text for view &1 in &2 too long. SQL0180 SQLCODE +180 SQLSTATE 01534

Explanation: Syntax of date, time, or timestamp value not valid. SQL0181 SQLCODE +181 SQLSTATE 01534

Explanation: Correlation without qualication occurred for column &1 to table &2. SQL0030 SQLCODE +30 SQLSTATE 01503

Explanation: Value in date, time, or timestamp string not valid.

Explanation: Number of INTO host-variable incorrect.

Appendix B. SQLCODEs and SQLSTATEs

589

SQL0183

SQLCODE +183

SQLSTATE 01535

SQL0445

SQLCODE +445

SQLSTATE 01004

Explanation: The result of a date or timestamp expression not valid. SQL0191 SQLCODE +191 SQLSTATE 01547

Explanation: Value of parameter &4 in procedure &1 in &2 too long. SQL0460 SQLCODE +460 SQLSTATE 01593

Explanation: MIXED data not properly formed. SQL0204 SQLCODE +204 SQLSTATE 01532

Explanation: Truncation of data may have occurred for ALTER TABLE in &1 of &2. SQL0551 SQLCODE +551 SQLSTATE 01548

Explanation: Object &1 in &2 type *&3 not found.

| SQL0237

SQLCODE +237

SQLSTATE 01005

Explanation: Not authorized to object &1 in &2 type *&3. SQL0552 SQLCODE +552 SQLSTATE 01542

| Explanation: Not enough SQLVAR entries were | provided in the SQLDA. | SQL0239
SQLCODE +239 SQLSTATE 01005

Explanation: Not authorized to &1. SQL0569 SQLCODE +569 SQLSTATE 01006

| Explanation: Not enough SQLVAR entries were | provided in the SQLDA.


SQL0304 SQLCODE +304 01547, 01565 SQLSTATE 01515,

Explanation: Not all requested privileges revoked from object &1 in &2 type &3. SQL0570 SQLCODE +570 SQLSTATE 01007

Explanation: Conversion error in assignment to host variable &2. SQL0326 SQLCODE +326 SQLSTATE 01557

Explanation: Not all requested privileges to object &1 in &2 type &3 granted. SQL0595 SQLCODE +595 SQLSTATE 01526

Explanation: Too many host variables specied. SQL0331 SQLCODE +331 SQLSTATE 01520

Explanation: Commit level &1 escalated to &2 lock. SQL0596 SQLCODE +596 SQLSTATE 01002

Explanation: Characters conversion cannot be performed. SQL0335 SQLCODE +335 SQLSTATE 01517

Explanation: Error occurred during disconnect. SQL0645 SQLCODE +645 SQLSTATE 01528

Explanation: Characters conversion has resulted in substitution characters.

Explanation: WHERE NOT NULL clause ignored for index &1 in &2. SQL0802 SQLCODE +802 SQLSTATE 01519, 01547, 01564, 01565

| SQL0360

SQLCODE +360

SQLSTATE 01627

| Explanation: Datalink in table &1 in &2 may not be | valid due to pending links.
SQL0403 SQLCODE +403 SQLSTATE 01522

Explanation: Data conversion or data mapping error. SQL0863 SQLCODE +863 SQLSTATE 01539

Explanation: Alias &1 in &2 created but table or view not found. SQL0420 SQLCODE +420 SQLSTATE 01565

Explanation: Mixed or DBCS CCSID not supported by relational database &1. SQL0990 SQLCODE +990 SQLSTATE 01587

Explanation: Outcome unknown for the unit of work.

Explanation: Character in CAST argument not valid.

590

DB2 UDB for AS/400 SQL Programming V4R4

SQL7905

SQLCODE +7905

SQLSTATE 01567

Explanation: Table &1 in &2 created but could not be journaled.

Negative SQLCODEs
SQL0007 SQLCODE -07 SQLSTATE 42601 SQL0102 SQLCODE -102 SQLSTATE 54002 Explanation: Character &1 (HEX &2) not valid in SQL statement. SQL0010 SQLCODE -10 SQLSTATE 42603 Explanation: String constant beginning with &1 too long. SQL0103 SQLCODE -103 SQLSTATE 42604

Explanation: String constant beginning &1 not delimited. SQL0029 SQLCODE -29 SQLSTATE 42601

Explanation: Numeric constant &1 not valid. SQL0104 SQLCODE -104 SQLSTATE 42601

Explanation: INTO clause missing from embedded SELECT statement. SQL0051 SQLCODE -51 SQLSTATE 3C000

Explanation: Token &1 was not valid. Valid tokens: &2. SQL0105 SQLCODE -105 SQLSTATE 42604

Explanation: Cursor or procedure &1 previously declared. SQL0060 SQLCODE -60 SQLSTATE 42815

Explanation: Mixed or graphic string constant not valid. SQL0106 SQLCODE -106 SQLSTATE 42611

Explanation: Value &3 for argument &1 of &2 function not valid. SQL0080 SQLCODE -80 SQLSTATE 42978

Explanation: Precision specied for FLOAT column not valid. SQL0107 SQLCODE -107 SQLSTATE 42622

Explanation: &1 too long. Maximum &2 characters. SQL0109 SQLCODE -109 SQLSTATE 42601

Explanation: Indicator variable &1 not SMALLINT type. SQL0084 SQLCODE -84 SQLSTATE 42612

Explanation: &1 clause not allowed. SQL0110 SQLCODE -110 SQLSTATE 42606

Explanation: SQL statement not allowed. SQL0090 SQLCODE -90 SQLSTATE 42618

Explanation: Hexadecimal constant beginning with &1 not valid. SQL0112 SQLCODE -112 SQLSTATE 42607

Explanation: Host variable not permitted here.

| |

SQL0097

SQLCODE -97

SQLSTATE 42601

Explanation: Use of data type not valid. SQL0099 SQLCODE -99 SQLSTATE 42992

Explanation: Argument of function &1 is another function. SQL0113 SQLCODE -113 2E000, 42602 SQLSTATE 28000,

Explanation: Operator in join condition not valid. SQL0101 SQLCODE -101 54010, 54011 SQLSTATE 54001, SQL0114

Explanation: Name &1 not allowed. SQLCODE -114 SQLSTATE 42961

Explanation: SQL statement too long or complex.

Explanation: Relational database &1 not the same as current server &2.

Appendix B. SQLCODEs and SQLSTATEs

591

SQL0115

SQLCODE -115

SQLSTATE 42601

SQL0132

SQLCODE -132

SQLSTATE 42824

Explanation: Comparison operator &1 not valid. SQL0117 SQLCODE -117 SQLSTATE 42802

Explanation: LIKE predicate not valid. SQL0133 SQLCODE -133 SQLSTATE 42906

Explanation: Statement inserts wrong number of values. SQL0118 SQLCODE -118 SQLSTATE 42902

Explanation: Operator on correlated column in SQL function not valid. SQL0134 SQLCODE -134 SQLSTATE 42907

Explanation: Table &1 in &2 also specied in a FROM clause. SQL0119 SQLCODE -119 SQLSTATE 42803

Explanation: Argument of function too long. SQL0136 SQLCODE -136 SQLSTATE 54005

Explanation: Column &1 in HAVING clause not in GROUP BY. SQL0120 SQLCODE -120 SQLSTATE 42903

Explanation: ORDER BY or GROUP BY columns too long. SQL0137 SQLCODE -137 SQLSTATE 54006

Explanation: Result too long. SQL0138 SQLCODE -138 SQLSTATE 22011

Explanation: Use of column function &2 not valid. SQL0121 SQLCODE -121 SQLSTATE 42701

Explanation: Duplicate column name &1 in INSERT or UPDATE. SQL0122 SQLCODE -122 SQLSTATE 42803

Explanation: Argument &1 of SUBSTR function not valid. SQL0144 SQLCODE -144 SQLSTATE 58003

Explanation: Section number not valid. SQL0145 SQLCODE -145 SQLSTATE 55005

Explanation: Column specied in SELECT list not valid. SQL0125 SQLCODE -125 SQLSTATE 42805

Explanation: Recursion not supported for an application server other than the AS/400 system. SQL0150 SQLCODE -150 SQLSTATE 42807

Explanation: ORDER BY column number &1 not valid. SQL0128 SQLCODE -128 SQLSTATE 42601

Explanation: View or logical le &1 in &2 read-only. SQL0151 SQLCODE -151 SQLSTATE 42808

Explanation: Use of NULL is not valid. SQL0129 SQLCODE -129 SQLSTATE 54004

Explanation: Column &1 in table &2 in &3 read-only. SQL0152 SQLCODE -152 SQLSTATE 42809

Explanation: Too many tables in SQL statement. SQL0130 SQLCODE -130 22025 SQLSTATE 22019,

Explanation: Constraint type not valid for constraint &1 in &2. SQL0153 SQLCODE -153 SQLSTATE 42908

Explanation: Escape character &1 or LIKE pattern not valid. SQL0131 SQLCODE -131 SQLSTATE 42818

Explanation: Column list required for CREATE VIEW. SQL0154 SQLCODE -154 SQLSTATE 42909

Explanation: Operands of LIKE not compatible or not valid.

Explanation: UNION and UNION ALL for CREATE VIEW not valid.

592

DB2 UDB for AS/400 SQL Programming V4R4

SQL0156

SQLCODE -156

SQLSTATE 42809

SQL0183

SQLCODE -183

SQLSTATE 22008

Explanation: &1 in &2 not a table. SQL0157 SQLCODE -157 SQLSTATE 42810

Explanation: The result of a date or timestamp expression not valid. SQL0184 SQLCODE -184 SQLSTATE 42610

Explanation: View &1 in &2 not valid in FOREIGN KEY clause. SQL0158 SQLCODE -158 SQLSTATE 42811

Explanation: Parameter marker not valid in expression. SQL0187 SQLCODE -187 SQLSTATE 42816

Explanation: Number of columns specied not consistent. SQL0159 SQLCODE -159 SQLSTATE 42809

Explanation: Use of labeled duration is not valid. SQL0188 SQLCODE -188 28000, 2E000 SQLSTATE 22503,

Explanation: &1 in &2 not correct type. SQL0160 SQLCODE -160 SQLSTATE 42813

Explanation: &1 is not a valid string representation of an authorization name or a relational database name. SQL0189 SQLCODE -189 SQLSTATE 22522

Explanation: WITH CHECK OPTION not allowed for view &1 in &2. SQL0161 SQLCODE -161 SQLSTATE 44000

Explanation: Coded Character Set Identier &1 is not valid. SQL0190 SQLCODE -190 SQLSTATE 42837

Explanation: INSERT/UPDATE not allowed due to WITH CHECK OPTION. SQL0170 SQLCODE -170 SQLSTATE 42605

Explanation: Attributes of column &3 in &1 in &2 not compatible. SQL0191 SQLCODE -191 SQLSTATE 22504

Explanation: Number of arguments for function &1 not valid. SQL0171 SQLCODE -171 SQLSTATE 42815

Explanation: MIXED data not properly formed. SQL0192 SQLCODE -192 SQLSTATE 42937

Explanation: Argument &1 of function &2 not valid. SQL0175 SQLCODE -175 SQLSTATE 58028

Explanation: Argument of TRANSLATE function not valid. SQL0194 SQLCODE -194 SQLSTATE 42848

Explanation: COMMIT failed. SQL0180 SQLCODE -180 SQLSTATE 22007

Explanation: KEEP LOCKS not allowed. SQL0195 SQLCODE -195 SQLSTATE 42814

Explanation: Syntax of date, time, or timestamp value not valid. SQL0181 SQLCODE -181 SQLSTATE 22007

Explanation: Last column of &1 in &2 cannot be dropped. SQL0196 SQLCODE -196 SQLSTATE 42817

Explanation: Value in date, time, or timestamp string not valid. SQL0182 SQLCODE -182 SQLSTATE 42816

Explanation: Column &3 in &1 in &2 cannot be dropped with RESTRICT. SQL0197 SQLCODE -197 SQLSTATE 42877

Explanation: A date, time, or timestamp expression not valid.

Explanation: Column &1 cannot be qualied.

Appendix B. SQLCODEs and SQLSTATEs

593

SQL0198

SQLCODE -198

SQLSTATE 42617

SQL0228

SQLCODE -228

SQLSTATE 42620

Explanation: SQL statement empty or blank. SQL0199 SQLCODE -199 SQLSTATE 42601

Explanation: FOR UPDATE OF clause not valid with SCROLL for cursor &1. SQL0231 SQLCODE -231 SQLSTATE 22006

Explanation: Keyword &1 not expected. Valid tokens: &2. SQL0203 SQLCODE -203 SQLSTATE 42702

Explanation: Position of cursor &1 not valid for FETCH of current row. SQL0250 SQLCODE -250 SQLSTATE 42718

Explanation: Column &1 is ambiguous. SQL0204 SQLCODE -204 SQLSTATE 42704

Explanation: Local relational database not dened in the directory. SQL0251 SQLCODE -251 42602 SQLSTATE 2E000,

Explanation: &1 in &2 type *&3 not found. SQL0205 SQLCODE -205 SQLSTATE 42703

Explanation: Column &1 not in table &2. SQL0206 SQLCODE -206 SQLSTATE 42703

Explanation: Character in relational database name &1 is not valid. SQL0255 SQLCODE -255 SQLSTATE 42999

Explanation: Column &1 not in specied tables. SQL0208 SQLCODE -208 SQLSTATE 42707

Explanation: DB2 Multisystem query error. SQL0256 SQLCODE -256 SQLSTATE 42998

Explanation: ORDER BY column &1 not in results table. SQL0212 SQLCODE -212 SQLSTATE 42712

Explanation: Constraint &1 in &2 not allowed on distributed le. SQL0270 SQLCODE -270 SQLSTATE 42997

Explanation: Duplicate table designator &1 not valid. SQL0214 SQLCODE -214 SQLSTATE 42822

Explanation: Unique index not allowed. SQL0301 SQLCODE -301 07006,42895 SQLSTATE

Explanation: ORDER BY expression is not valid. SQL0221 SQLCODE -221 SQLSTATE 42873

Explanation: Input host variable &2 or argument &1 not valid. SQL0302 SQLCODE -302 SQLSTATE 22001, 22003, 22023, 22024

Explanation: Number of rows &2 not valid. SQL0225 SQLCODE -225 SQLSTATE 42872

Explanation: FETCH not valid; cursor &1 not declared with SCROLL. SQL0226 SQLCODE -226 SQLSTATE 24507

Explanation: Conversion error on input host variable &2. SQL0303 SQLCODE -303 42806 SQLSTATE 22001,

Explanation: Current row deleted or moved for cursor &1. SQL0227 SQLCODE -227 SQLSTATE 24513

Explanation: Host variable &1 not compatible with SELECT item. SQL0304 SQLCODE -304 22023, 22504 SQLSTATE 22003,

Explanation: FETCH not valid, cursor &1 in unknown position.

Explanation: Conversion error in assignment to host variable &2.

594

DB2 UDB for AS/400 SQL Programming V4R4

SQL0305

SQLCODE -305

SQLSTATE 22002

| SQL0340

SQLCODE -340

SQLSTATE 42726

Explanation: Indicator variable required. SQL0306 SQLCODE -306 SQLSTATE 42863

| Explanation: Duplicate name &1 for common table | expression. | SQL0341


SQLCODE -341 SQLSTATE 42835

Explanation: Undened host variable in REXX. SQL0311 SQLCODE -311 SQLSTATE 22501

| Explanation: Cyclic references between common | table expressions. | SQL0346


SQLCODE -346 SQLSTATE 42836

Explanation: Length in a varying-length host variable not valid. SQL0312 SQLCODE -312 SQLSTATE 42618

| Explanation: Recursion not allowed for common table | expressions. | SQL0350


SQLCODE -350 SQLSTATE 42962

Explanation: Host variable &1 not dened or not usable. SQL0313 SQLCODE -313 07004 SQLSTATE 07001,

| Explanation: Column &1 is not valid as key eld for | index or constraint.
SQL0351 SQLCODE -351 SQLSTATE 56084

Explanation: Number of host variables not valid. SQL0328 SQLCODE -328 SQLSTATE 42996

| Explanation: The AR is not at the same level and | DB2/400 cannot transform the data type to a compatible | type. | SQL0352
SQLCODE -352 SQLSTATE 56084

Explanation: Column &1 not allowed in partitioning key.

| |

SQL0329

SQLCODE -329

SQLSTATE 0E000

Explanation: The SET PATH name list is not valid. SQL0330 SQLCODE -330 SQLSTATE 22021

| Explanation: The AS is not at the same level and | DB2/400 cannot transform the data type to a compatible | type. | SQL0357
SQLCODE -357 SQLSTATE 57050

Explanation: Character conversion cannot be performed. SQL0331 SQLCODE -331 SQLSTATE 22021

| Explanation: File server &1 used in DataLink not | currently available. | SQL0358
SQLCODE -358 SQLSTATE 428D1

Explanation: Character conversion cannot be performed. SQL0332 SQLCODE -332 SQLSTATE 57017

| Explanation: Error &1 occurred using DataLink data | type. | SQL0392


SQLCODE -392 SQLSTATE 42855

Explanation: Character conversion between CCSID &1 and CCSID &2 not valid. SQL0334 SQLCODE -334 SQLSTATE 22524

| Explanation: Assignment of LOB to specied host | variable not allowed. | SQL0398


SQLCODE -398 SQLSTATE 428D2

Explanation: Character conversion has resulted in truncation. SQL0338 SQLCODE -338 SQLSTATE 42972

| Explanation: AS LOCATOR cannot be specied for a | non-LOB parameter.


SQL0401 SQLCODE -401 SQLSTATE 42818

Explanation: JOIN expression not valid.

Explanation: Comparison operator &1 operands not compatible.

Appendix B. SQLCODEs and SQLSTATEs

595

SQL0402

SQLCODE -402

SQLSTATE 42819

SQL0420

SQLCODE -420

SQLSTATE 22018

Explanation: &1 use not valid. SQL0404 SQLCODE -404 SQLSTATE 22001

Explanation: Character in CAST argument not valid. SQL0421 SQLCODE -421 SQLSTATE 42826

Explanation: Value for column &1 too long. SQL0405 SQLCODE -405 SQLSTATE 42820

Explanation: Number of UNION operands not equal.

| |

SQL0423

SQLCODE -423

SQLSTATE 0F001

Explanation: Numeric constant &1 out of range. SQL0406 SQLCODE -406 22023, 22504 SQLSTATE 22003,

Explanation: LOB locator &1 not valid. SQL0428 SQLCODE -428 SQLSTATE 25501

Explanation: SQL statement cannot be run.

Explanation: Conversion error on assignment to column &2. SQL0407 SQLCODE -407 SQLSTATE 23502

| | | | | |

SQL0429

SQLCODE -429

SQLSTATE 54028

Explanation: The maximum number of concurrent LOB lcoators has been reached. SQL0432 SQLCODE -432 SQLSTATE 42841

Explanation: Null values are not allowed in column &1. SQL0408 SQLCODE -408 SQLSTATE 42821

Explanation: A parameter marker cannot have the user-dened type name &1. SQL0433 SQLCODE -433 SQLSTATE 22001

Explanation: INSERT or UPDATE value for column &1 not compatible. SQL0410 SQLCODE -410 SQLSTATE 42820

Explanation: Signicant digits truncated during CAST from numeric to character. SQL0440 SQLCODE -440 SQLSTATE 42884

Explanation: Floating point literal &1 not valid. SQL0412 SQLCODE -412 SQLSTATE 42823

Explanation: Subquery with more than one result column not valid.

Explanation: Number of arguments on CALL must match procedure.

|
SQL0414 SQLCODE -414 SQLSTATE 42824 Explanation: Column &1 not valid in LIKE predicate. SQL0415 SQLCODE -415 SQLSTATE 42825

SQL0441

SQLCODE -441

SQLSTATE 42601

| |

Explanation: Clause or keyword &1 not valid where specied. SQL0442 SQLCODE -442 SQLSTATE 54023

Explanation: UNION operands not compatible. SQL0417 SQLCODE -417 SQLSTATE 42609

Explanation: Maximum # of parameters on CALL exceeded. SQL0443 SQLCODE -443 38501 SQLSTATE 2Fxxx,

Explanation: Combination of parameter markers not valid. SQL0418 SQLCODE -418 SQLSTATE 42610

Explanation: Trigger program or external procedure detected on error. SQL0444 SQLCODE -444 SQLSTATE 42724

Explanation: Use of parameter marker is not valid. SQL0419 SQLCODE -419 SQLSTATE 42911

Explanation: External program &4 in &1 not found.

Explanation: Negative scale not valid.

596

DB2 UDB for AS/400 SQL Programming V4R4

SQL0446

SQLCODE -446

SQLSTATE 22003

| SQL0463

SQLCODE -463

SQLSTATE 39001

Explanation: Conversion error in assignment of argument &2. SQL0448 SQLCODE -448 SQLSTATE 54023

| Explanation: SQLSTATE &4 returned from routine &1 | in &2 not valid..
SQL0469 SQLCODE -469 SQLSTATE 42886

Explanation: Maximum parameters on DECLARE PROCEDURE exceeded. SQL0449 SQLCODE -449 SQLSTATE 42878

Explanation: IN, OUT, INOUT not valid for parameter &4 in procedure &1 in &2. SQL0470 SQLCODE -470 SQLSTATE 39002

Explanation: External program name for procedure &1 in &2 not valid. SQL0451 SQLCODE -451 SQLSTATE 42815

Explanation: NULL values not allowed for parameter &4 in procedure.

| SQL0473

SQLCODE -473

SQLSTATE 42918

Explanation: Attributes of parameter &1 not valid for procedure.

| Explanation: User-dened type &1 cannot be created. | SQL0475


SQLCODE -475 SQLSTATE 42866

| | | | | | | | |

SQL0452

SQLCODE -452

SQLSTATE 428A1

Explanation: Unable to access a le that is referred to by a le reference variable. SQL0453 SQLCODE -453 SQLSTATE 42880

| Explanation: RETURNS data type for function &3 in | &4 not valid. | SQL0476
SQLCODE -476 SQLSTATE 42725

| Explanation: Function &1 in &2 not unique. | SQL0478


SQLCODE -478 SQLSTATE 42893

Explanation: Return type for function &1 in &2 not compatible with CAST TO type. SQL0454 SQLCODE -454 SQLSTATE 42723

| Explanation: Object &1 in &2 of type &3 cannot be | dropped. | SQL0483


SQLCODE -483 SQLSTATE 42885

Explanation: Function &1 in &2 with the same signature already exists. SQL0455 SQLCODE -455 SQLSTATE 42882

| Explanation: Parameters for function &1 in &2 not | same as sourced function. | SQL0484
SQLCODE -484 SQLSTATE 42733

Explanation: Specic name not same as procedure name.

| | | | | | |

SQL0456

SQLCODE -456

SQLSTATE 42710

| Explanation: Routine &1 in &2 already exists.


SQL0487 SQLCODE -487 SQLSTATE 38001

Explanation: Specic name &3 in &2 already exists. SQL0457 SQLCODE -457 SQLSTATE 42939

Explanation: SQL statements not allowed. SQL0490 SQLCODE -490 SQLSTATE 428B7

Explanation: Name &1 in &2 not allowed for function. SQL0458 SQLCODE -458 SQLSTATE 42883

Explanation: Numeric value &1 not valid.

Explanation: Function &1 in &2 not found with matching signature. SQL0461 SQLCODE -461 SQLSTATE 42846

| SQL0491

SQLCODE -491

SQLSTATE 42601

| Explanation: RETURNS clause required on CREATE | FUNCTION statement.

Explanation: Cast from &1 to &2 not supported.

Appendix B. SQLCODEs and SQLSTATEs

597

| SQL0492

SQLCODE -492

SQLSTATE 42879

SQL0517

SQLCODE -517

SQLSTATE 07005

| Explanation: Data type for function &1 in &2 not valid | for source type.
SQL0501 SQLCODE -501 SQLSTATE 24501

Explanation: Prepared statement &2 not SELECT statement. SQL0518 SQLCODE -518 SQLSTATE 07003

Explanation: Cursor &1 not open. SQL0502 SQLCODE -502 SQLSTATE 24502

Explanation: Prepared statement &1 not found. SQL0519 SQLCODE -519 SQLSTATE 24506

Explanation: Cursor &1 already open. SQL0503 SQLCODE -503 SQLSTATE 42912

Explanation: Prepared statement &2 in use. SQL0520 SQLCODE -520 SQLSTATE 42828

Explanation: Column &3 cannot be updated. SQL0504 SQLCODE -504 SQLSTATE 34000

Explanation: Cannot UPDATE or DELETE on cursor &1. SQL0525 SQLCODE -525 SQLSTATE 51015

Explanation: Cursor &1 not declared. SQL0507 SQLCODE -507 SQLSTATE 24501

Explanation: Statement not valid on application server. SQL0527 SQLCODE -527 SQLSTATE 42874

Explanation: Cursor &1 not open. SQL0508 SQLCODE -508 SQLSTATE 24504

Explanation: ALWCPYDTA(*NO) specied but temporary result required for &1. SQL0530 SQLCODE -530 SQLSTATE 23503

Explanation: Cursor &1 not positioned on locked row. SQL0509 SQLCODE -509 SQLSTATE 42827

Explanation: Table &2 in &3 not same as table in cursor &1. SQL0510 SQLCODE -510 SQLSTATE 42828

Explanation: Insert or UPDATE value not allowed by referential constraint. SQL0531 SQLCODE -531 23504 SQLSTATE 23001,

Explanation: Cursor &1 for le &2 is read-only. SQL0511 SQLCODE -511 SQLSTATE 42829

Explanation: Update prevented by referential constraint. SQL0532 SQLCODE -532 23504 SQLSTATE 23001,

Explanation: FOR UPDATE OF clause not valid. SQL0513 SQLCODE -513 SQLSTATE 42924

Explanation: Delete prevented by referential constraint. SQL0536 SQLCODE -536 SQLSTATE 42914

Explanation: Alias &1 in &2 cannot reference another alias. SQL0514 SQLCODE -514 SQLSTATE 26501

Explanation: Delete not allowed because table referenced in subquery can be affected. SQL0537 SQLCODE -537 SQLSTATE 42709

Explanation: Prepared statement &2 not found. SQL0516 SQLCODE -516 SQLSTATE 26501

Explanation: Prepared statement &2 not found.

Explanation: Duplicate column name in denition of key.

598

DB2 UDB for AS/400 SQL Programming V4R4

SQL0538

SQLCODE -538

SQLSTATE 42830

SQL0577

Explanation: Foreign key attributes do not match parent key. SQL0539 SQLCODE -539 SQLSTATE 42888

SQLCODE -577 2F002

SQLSTATE 38002,

Explanation: Modifying SQL data not permitted. SQL0579 SQLCODE -579 2F004 SQLSTATE 38004,

Explanation: Table does not have primary key. SQL0541 SQLCODE -541 SQLSTATE 42891 SQL0580

Explanation: Reading SQL data not permitted. SQLCODE -580 SQLSTATE 42625

Explanation: Duplicate UNIQUE constraint already exists. SQL0543 SQLCODE -543 SQLSTATE 23511

Explanation: At least one result in CASE expression must be not NULL. SQL0581 SQLCODE -581 SQLSTATE 42804

Explanation: Constraint &1 conicts with SET NULL or SET DEFAULT rule. SQL0544 SQLCODE -544 SQLSTATE 23512

Explanation: The results in a CASE expression are not compatible.

Explanation: CHECK constraint &1 cannot be added. SQL0545 SQLCODE -545 SQLSTATE 23513

| SQL0583

SQLCODE -583

SQLSTATE 42845

| Explanation: Use of function &1 in &2 not valid. | SQL0585


SQLCODE -585 SQLSTATE 42732

Explanation: INSERT or UPDATE not allowed by CHECK constraint. SQL0546 SQLCODE -546 SQLSTATE 42621

| Explanation: Library &1 is used incorrectly on the | SET PATH statement


SQL0590 SQLCODE -590 SQLSTATE 42734

Explanation: CHECK condition of constraint &1 not valid. SQL0551 SQLCODE -551 SQLSTATE 42501

Explanation: Name &1 specied in &2 not unique. SQL0601 SQLCODE -601 SQLSTATE 42710

Explanation: Not authorized to object &1 in &2 type *&3. SQL0552 SQLCODE -552 SQLSTATE 42502

Explanation: Object &1 in &2 type *&3 already exists. SQL0602 SQLCODE -602 SQLSTATE 54008

Explanation: Not authorized to &1. SQL0557 SQLCODE -557 SQLSTATE 42852

Explanation: More than 120 columns specied for CREATE INDEX. SQL0603 SQLCODE -603 SQLSTATE 23515

Explanation: Privilege not valid for table or view &1 in &2. SQL0573 SQLCODE -573 SQLSTATE 42890

Explanation: Unique index cannot be created because of duplicate keys. SQL0604 SQLCODE -604 SQLSTATE 42611

Explanation: Table does not have matching parent key. SQL0574 SQLCODE -574 SQLSTATE 42894

Explanation: Attributes of column not valid. SQL0607 SQLCODE -607 SQLSTATE 42832

Explanation: Default value not valid.

Explanation: Operation not allowed on system table &1 in &2.

Appendix B. SQLCODEs and SQLSTATEs

599

SQL0612

SQLCODE -612

SQLSTATE 42711

SQL0666

SQLCODE -666

SQLSTATE 57005

Explanation: &1 is a duplicate column name. SQL0613 SQLCODE -613 SQLSTATE 54008

Explanation: Estimated query processing time exceeds limit. SQL0667 SQLCODE -667 SQLSTATE 23520

Explanation: Primary or unique key constraint too long. SQL0614 SQLCODE -614 SQLSTATE 54008

Explanation: Foreign key does not match a value in the parent key. SQL0675 SQLCODE -675 SQLSTATE 42892

Explanation: Length of columns for CREATE INDEX too long. SQL0615 SQLCODE -615 SQLSTATE 55006

Explanation: Specied delete rule not allowed with existing trigger. SQL0679 SQLCODE -679 SQLSTATE 57006

Explanation: Object &1 in &2 type *&3 not dropped. It is in use. SQL0616 SQLCODE -616 SQLSTATE 42893

Explanation: Object &1 in &2 type *&3 not created due to pending operation. SQL0683 SQLCODE -683 SQLSTATE 42842

Explanation: &1 in &2 type &3 cannot be dropped with RESTRICT. SQL0624 SQLCODE -624 SQLSTATE 42889

Explanation: FOR DATA or CCSID clause not valid for specied type.

Explanation: Table already has primary key. SQL0628 SQLCODE -628 SQLSTATE 42613

| SQL0707

SQLCODE -707

SQLSTATE 42939

| Explanation: Name &1 in &2 not allowed for distinct | type. | SQL0713
SQLCODE -713 SQLSTATE 42815

Explanation: Clauses are mutually exclusive. SQL0629 SQLCODE -629 SQLSTATE 42834

| Explanation: Host variable for &2 is NULL.


SQL0724 SQLCODE -724 SQLSTATE 54038

Explanation: SET NULL not allowed for referential constraint. SQL0631 SQLCODE -631 SQLSTATE 54008

Explanation: Too many cascaded trigger programs. SQL0751 SQLCODE -751 SQLSTATE 42987

Explanation: Foreign key for referential constraint too long. SQL0637 SQLCODE -637 SQLSTATE 42614

Explanation: SQL statement &1 not allowed in stored procedure or trigger. SQL0752 SQLCODE -752 SQLSTATE 0A001

Explanation: Duplicate &1 keyword. SQL0642 SQLCODE -642 SQLSTATE 54021

Explanation: Connection cannot be changed. Reason code is &1. SQL0773 SQLCODE -773 SQLSTATE 20000

Explanation: Maximum number of constraints exceeded.

Explanation: Case not found for CASE statement.

| SQL0658

SQLCODE -658

SQLSTATE 42917 SQL0774 SQLCODE -774 SQLSTATE 2D522 Explanation: Statement cannot be executed within a compound SQL statement.

| Explanation: Function cannot be dropped.

600

DB2 UDB for AS/400 SQL Programming V4R4

SQL0775

SQLCODE -775

SQLSTATE 42910

SQL0803

SQLCODE -803

SQLSTATE 23505

Explanation: Statement not allowed in a compound SQL statement. SQL0776 SQLCODE -776 SQLSTATE 428D4

Explanation: Duplicate key value specied. SQL0804 SQLCODE -804 SQLSTATE 07002

Explanation: SQLDA not valid. SQL0805 SQLCODE -805 SQLSTATE 51002

Explanation: Cursor &1 specied in FOR statement not allowed. SQL0777 SQLCODE -777 SQLSTATE 42919

Explanation: SQL package &1 in &2 not found. SQL0811 SQLCODE -811 SQLSTATE 21000

Explanation: Nested compound statements not allowed. SQL0778 SQLCODE -778 SQLSTATE 428D5

Explanation: Result of SELECT INTO or subquery more than one row. SQL0818 SQLCODE -818 SQLSTATE 51003

Explanation: End label &1 not same as begin label. SQL0779 SQLCODE -779 SQLSTATE 42736

Explanation: Consistency tokens do not match. SQL0822 SQLCODE -822 SQLSTATE 51004

Explanation: Label &1 specied on LEAVE statement not valid. SQL0780 SQLCODE -780 SQLSTATE 428D6

Explanation: Address in SQLDA not valid. SQL0827 SQLCODE -827 SQLSTATE 42862

Explanation: UNDO specied for a handler and ATOMIC not specied. SQL0781 SQLCODE -781 SQLSTATE 42737

Explanation: &1 in &2 type *SQLPKG cannot be accessed. SQL0840 SQLCODE -840 SQLSTATE 54004

Explanation: Condition &1 specied in handler not dened. SQL0782 SQLCODE -782 SQLSTATE 428D7

Explanation: Number of selected items exceeds 8000. SQL0842 SQLCODE -842 SQLSTATE 08002

Explanation: Condition value &1 specied in handler not valid. SQL0783 SQLCODE -783 SQLSTATE 42738

Explanation: Connection already exists. SQL0843 SQLCODE -843 SQLSTATE 08003

Explanation: Connection does not exist. SQL0858 SQLCODE -858 SQLSTATE 08501

Explanation: Select list for cursor &1 in FOR statement not valid. SQL0784 SQLCODE -784 SQLSTATE 42860

Explanation: Cannot disconnect relational database due to LU 6.2 protected conversation. SQL0862 SQLCODE -862 SQLSTATE 55029

Explanation: Check constraint &1 cannot be dropped. SQL0785 SQLCODE -785 SQLSTATE 428D8

Explanation: Use of SQLCODE or SQLSTATE not valid. SQL0802 SQLCODE -802 SQLSTATE 22003, 22012, 22023, 22504

Explanation: Local program attempted to connect to a remote relational database. SQL0871 SQLCODE -871 SQLSTATE 54019

Explanation: Too many CCSID values specied.

Explanation: Data conversion or data mapping error.

Appendix B. SQLCODEs and SQLSTATEs

601

SQL0900

SQLCODE -900

SQLSTATE 08003

SQL0971

SQLCODE -971

SQLSTATE 57011

Explanation: Application process not in a connected state. SQL0901 SQLCODE -901 SQLSTATE 58004

Explanation: Referential constraint &4 in check pending state. SQL5001 SQLCODE -5001 SQLSTATE 42703

Explanation: SQL system error. SQL0904 SQLCODE -904 SQLSTATE 57011

Explanation: Column qualier &2 undened. SQL5002 SQLCODE -5002 SQLSTATE 42812

Explanation: Resource limit exceeded. SQL0906 SQLCODE -906 SQLSTATE 24514

Explanation: Collection must be specied for table &1. SQL5003 SQLCODE -5003 SQLSTATE 42922

Explanation: Operation not performed because of previous error. SQL0907 SQLCODE -907 SQLSTATE 27000

Explanation: Cannot perform operation under commitment control. SQL5005 SQLCODE -5005 SQLSTATE 42815

Explanation: Attempt to change same row twice. SQL0910 SQLCODE -910 SQLSTATE 57007

Explanation: Operator &4 not consistent with operands. SQL5012 SQLCODE -5012 SQLSTATE 42618

Explanation: Object &1 in &2 type *&3 has a pending change. SQL0913 SQLCODE -913 SQLSTATE 57033

Explanation: Host variable not a numeric with zero scale. SQL5016 SQLCODE -5016 SQLSTATE 42833

Explanation: Row or object &1 in &2 type *&3 in use. SQL0917 SQLCODE -917 SQLSTATE 42969

Explanation: Object name &1 not valid for naming option. SQL5021 SQLCODE -5021 SQLSTATE 42930

Explanation: Package not created. SQL0918 SQLCODE -918 SQLSTATE 51021

Explanation: FOR UPDATE OF column &1 also in ORDER BY. SQL5023 SQLCODE -5023 SQLSTATE 26510

Explanation: Rollback required. SQL0950 SQLCODE -950 SQLSTATE 42705

Explanation: Relational database &1 not in relational database directory. SQL0951 SQLCODE -951 SQLSTATE 55007

Explanation: Duplicate statement name in DECLARE CURSOR. SQL5024 SQLCODE -5024 SQLSTATE 42618

Explanation: Host variable &1 not character. SQL5047 SQLCODE -5047 SQLSTATE 42616

Explanation: Object &1 in &2 not altered. It is in use. SQL0952 SQLCODE -952 SQLSTATE 57014

Explanation: Processing of the SQL statement ended by ENDRDBRQS command. SQL0969 SQLCODE -969 SQLSTATE 58033

Explanation: Error processing SRTSEQ or LANGID parameter. SQL5051 SQLCODE -5051 SQLSTATE 42875

Explanation: Incorrect qualier.

Explanation: Unexpected client driver error.

602

DB2 UDB for AS/400 SQL Programming V4R4

SQL7001

SQLCODE -7001

SQLSTATE 42858

SQL7026

SQLCODE -7026

SQLSTATE 42896

Explanation: File &1 in &2 not database le. SQL7002 SQLCODE -7002 SQLSTATE 42847

Explanation: Auxiliary storage pool not found. SQL7027 SQLCODE -7027 SQLSTATE 42984

Explanation: Override parameter not valid. SQL7003 SQLCODE -7003 SQLSTATE 42857

Explanation: Unable to grant to a view. SQL7028 SQLCODE -7028 SQLSTATE 42944

Explanation: File &1 in &2 has more than one format. SQL7006 SQLCODE -7006 SQLSTATE 55018

Explanation: Unable to CHGOBJOWN for primary group. SQL7029 SQLCODE -7029 SQLSTATE 428B8

Explanation: Cannot drop collection &1. SQL7007 SQLCODE -7007 SQLSTATE 51009

Explanation: New name &3 is not valid. SQL7031 SQLCODE -7031 SQLSTATE 54044

Explanation: COMMIT or ROLLBACK not valid. SQL7008 SQLCODE -7008 SQLSTATE 55019

Explanation: Sort sequence table &1 too long. SQL7032 SQLCODE -7032 SQLSTATE 42904

Explanation: &1 in &2 not valid for operation. SQL7010 SQLCODE -7010 SQLSTATE 42850

Explanation: SQL procedure &1 in &2 not created. SQL7033 SQLCODE -7033 SQLSTATE 42923

Explanation: Logical le &1 in &2 not valid for CREATE VIEW. SQL7011 SQLCODE -7011 SQLSTATE 42851

Explanation: Alias name &1 in &2 not allowed.

| SQL7034

SQLCODE -7034

SQLSTATE 42926

Explanation: &1 in &2 not table, view, or physical le. SQL7017 SQLCODE -7017 SQLSTATE 42971

| Explanation: LOB locators are not allowed with | COMMIT(*NONE). | SQL7037


SQLCODE -7037 SQLSTATE 42835

Explanation: Commitment control is already active to a DDM target. SQL7018 SQLCODE -7018 SQLSTATE 42970

| Explanation: Data in a distributed le &1 in &2 cannot | be redistributed.


SQL7941 SQLCODE -7941 SQLSTATE 42981

Explanation: COMMIT HOLD or ROLLBACK HOLD not allowed. SQL7021 SQLCODE -7021 SQLSTATE 57043

Explanation: Application process not at commit boundary. SQL9012 SQLCODE -9012 SQLSTATE 42968

Explanation: Local program attempting to run on application server. SQL7022 SQLCODE -7022 SQLSTATE 42977

Explanation: DB2 UDB Query Manager and SQL Development Kit not available. SQ30000 SQLCODE -30000 SQLSTATE 58008

Explanation: User &1 not the same as current user &2 for connect to local relational database. SQL7024 SQLCODE -7024 SQLSTATE 42876

Explanation: Distributed Relational Database Architecture (DRDA) protocol error. SQ30001 SQLCODE -30001 SQLSTATE 57042

Explanation: Index cannot be created because of CCSID incompatibility.

Explanation: Call to distributed SQL program not allowed.

Appendix B. SQLCODEs and SQLSTATEs

603

SQ30020

SQLCODE -30020

SQLSTATE 58009

SQ30072

SQLCODE -30072

SQLSTATE 58016

Explanation: Distributed Relational Database Architecture (DRDA) protocol error. SQ30021 SQLCODE -30021 SQLSTATE 58010

Explanation: Distributed Data Management (DDM) parameter &1 not supported. SQ30073 SQLCODE -30073 SQLSTATE 58017

Explanation: Distributed relational database not supported by the remote system. SQ30040 SQLCODE -30040 SQLSTATE 57012

Explanation: Distributed Data Management (DDM) parameter value &1 not supported. SQ30074 SQLCODE -30074 SQLSTATE 58018

Explanation: DDM resource &2 at relational database &1 not available. SQ30041 SQLCODE -30041 SQLSTATE 57013

Explanation: Distributed Data Management (DDM) reply message &1 not supported. SQ30080 SQLCODE -30080 SQLSTATE 08001

Explanation: DDM resources at relational database &1 not available. SQ30050 SQLCODE -30050 SQLSTATE 58011

Explanation: Communication error occurred during distributed database processing. SQ30089 SQLCODE -30089 SQLSTATE 08001

Explanation: DDM command &1 is not valid while bind process is in progress. SQ30051 SQLCODE -30051 SQLSTATE 58012

Explanation: Communication error occurred during DB2 Multisystem processing. SQ30090 SQLCODE -30090 2D528, 2D529 SQLSTATE 25000,

Explanation: Bind process for specied package name and consistency token not active. SQ30052 SQLCODE -30052 SQLSTATE 42932

Explanation: Change request not valid for read-only application server.

Explanation: Program preparation assumptions not correct. SQ30053 SQLCODE -30053 SQLSTATE 42506

Explanation: Not authorized to create package for owner &1. SQ30060 SQLCODE -30060 SQLSTATE 08004

Explanation: User not authorized to relational database &1. SQ30061 SQLCODE -30061 SQLSTATE 08004

Explanation: Relational database &1 not found. SQ30070 SQLCODE -30070 SQLSTATE 58014

Explanation: Distributed Data Management (DDM) command &1 not supported. SQ30071 SQLCODE -30071 SQLSTATE 58015

Explanation: Distributed Data Management (DDM) object &1 not supported.

604

DB2 UDB for AS/400 SQL Programming V4R4

Appendix C. Sample Programs Using DB2 UDB for AS/400 Statements


This appendix contains a sample application showing how to code SQL statements in each of the languages supported by the DB2 UDB for AS/400 system: ILE C, COBOL, ILE COBOL, PL/I, RPG for AS/400, ILE RPG for AS/400, and REXX.

Examples of programs that use SQL statements


The sample application gives raises based on commission. Each sample program produces the same report, which is shown at the end of this appendix. The rst part of the report shows, by project, all employees working on the project who received a raise. The second part of the report shows the new salary expense for each project. The following notes apply to all the sample programs: SQL statements can be entered in upper or lowercase. 1 This host language statement retrieves the external denitions for the SQL table PROJECT. These denitions can be used as host variables or as a host structure. Notes: 1. In RPG for AS/400, eld names in an externally described structure that are longer than 6 characters must be renamed. 2. REXX does not support the retrieval of external denitions. 2 The SQL INCLUDE SQLCA statement is used to include the SQLCA for PL/I, C, and COBOL programs. For RPG programs, the SQL precompiler automatically places the SQLCA data structure into the source at the end of the Input specication section. For REXX, the SQLCA elds are maintained in separate variables rather than in a contiguous data area mapped by the SQLCA. This SQL WHENEVER statement denes the host language label to which control is passed if an SQLERROR (SQLCODE < 0) occurs in an SQL statement. This WHENEVER SQLERROR statement applies to all the following SQL statements until the next WHENEVER SQLERROR statement is encountered. REXX does not support the WHENEVER statement. Instead, REXX uses the SIGNAL ON ERROR facility. This SQL UPDATE statement updates the SALARY column, which contains the employee salary by the percentage in the host variable PERCENTAGE (PERCNT for RPG). The updated rows are those that have employee commissions greater than 2000. For REXX, this is PREPARE and EXECUTE since UPDATE cannot be executed directly if there is a host variable. This SQL COMMIT statement commits the changes made by the SQL UPDATE statement. Record locks on all changed rows are released. Note: The program was precompiled using COMMIT(*CHG). (For REXX, *CHG. is the default.) 6
Copyright IBM Corp. 1997, 1999

This SQL DECLARE CURSOR statement denes cursor C1, which joins

605

two tables, EMPLOYEE and EMP_ACT, and returns rows for employees who received a raise (commission > 2000). Rows are returned in ascending order by project number and employee number (PROJNO and EMPNO columns). For REXX, this is a PREPARE and DECLARE CURSOR since the DECLARE CURSOR statement cannot be specied directly with a statement string if it has host variables. 7 8 This SQL OPEN statement opens cursor C1 so that the rows can be fetched. This SQL WHENEVER statement denes the host language label to which control is passed when all rows are fetched (SQLCODE = 100). For REXX, the SQLCODE must be explicitly checked. This SQL FETCH statement returns all columns for cursor C1 and places the returned values into the corresponding elements of the host structure. After all rows are fetched, control is passed to this label. The SQL CLOSE statement closes cursor C1. This SQL DECLARE CURSOR statement denes cursor C2, which joins the three tables, EMP_ACT, PROJECT, and EMPLOYEE. The results are grouped by columns PROJNO and PROJNAME. The COUNT function returns the number of rows in each group. The SUM function calculates the new salary cost for each project. The ORDER BY 1 clause species that rows are retrieved based on the contents of the nal results column (EMP_ACT.PROJNO). For REXX, this is a PREPARE and DECLARE CURSOR since the DECLARE CURSOR statement cannot be specied directly with a statement string if it has host variables. This SQL FETCH statement returns the results columns for cursor C2 and places the returned values into the corresponding elements of the host structure described by the program. This SQL WHENEVER statement with the CONTINUE option causes processing to continue to the next statement regardless if an error occurs on the SQL ROLLBACK statement. Errors are not expected on the SQL ROLLBACK statement; however, this prevents the program from going into a loop if an error does occur. SQL statements until the next WHENEVER SQLERROR statement is encountered. REXX does not support the WHENEVER statement. Instead, REXX uses the SIGNAL OFF ERROR facility. This SQL ROLLBACK statement restores the table to its original condition if an error occurred during the update.

9 10 11

12

13

14

SQL Statements in ILE C and C++ Programs


This sample program is written in the C programming language. The same program would work in C++ if the following conditions are true: v An SQL BEGIN DECLARE SECTION statement was added before line 18 v An SQL END DECLARE SECTION statement was added after line 42

606

DB2 UDB for AS/400 SQL Programming V4R4

5769ST1 V4R4M0 990521 Create SQL ILE C Object Source type...............C Object name...............CORPDATA/CEX Source file...............CORPDATA/SRC Member....................CEX To source file............QTEMP/QSQLTEMP Options...................*XREF Listing option............*PRINT Target release............V4R4M0 INCLUDE file..............*LIBL/*SRCFILE Commit....................*CHG Allow copy of data........*YES Close SQL cursor..........*ENDACTGRP Allow blocking............*READ Delay PREPARE.............*NO Generation level..........10 Margins...................*SRCFILE Printer file..............*LIBL/QSYSPRT Date format...............*JOB Date separator............*JOB Time format...............*HMS Time separator ...........*JOB Replace...................*YES Relational database.......*LOCAL User .....................*CURRENT RDB connect method........*DUW Default Collection........*NONE Package name..............*OBJLIB/*OBJ Created object type.......*PGM Debugging view............*NONE Dynamic User Profile......*USER User Profile..............*NAMING Sort Sequence.............*JOB Language ID...............*JOB IBM SQL flagging..........*NOFLAG ANS flagging..............*NONE Text......................*SRCMBRTXT Source file CCSID.........65535 Job CCSID.................65535 Source member changed on 04/01/98 17:15:17

CEX

04/01/98 15:52:26

Page

Figure 39. Sample C Program Using SQL Statements (Part 1 of 7)

Appendix C. Sample Programs Using DB2 UDB for AS/400 Statements

607

5769ST1 Record 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65

V4R4M0 990521 Create SQL ILE C Object CEX *...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 #include "string.h" #include "stdlib.h" #include "stdio.h" main() { /* A sample program which updates the salaries for those employees */ /* whose current commission total is greater than or equal to the */ /* value of 'commission'. The salaries of those who qualify are */ /* increased by the value of 'percentage' retroactive to 'raise_date'*/ /* A report is generated showing the projects which these employees */ /* have contributed to ordered by project number and employee ID. */ /* A second report shows each project having an end date occurring */ /* after 'raise_date' (is potentially affected by the retroactive */ /* raises) with its total salary expenses and a count of employees */ /* who contributed to the project. */ short work_days = 253; /* work days during in one year float commission = 2000.00; /* cutoff to qualify for raise float percentage = 1.04; /* raised salary as percentage char raise_date??(12??) = "1982-06-01"; /* effective raise date /* File declaration for qprint */ FILE *qprint; /* Structure for report 1 */ 1 #pragma mapinc ("project","CORPDATA/PROJECT(PROJECT)","both","p z") #include "project" struct { CORPDATA_PROJECT_PROJECT_both_t Proj_struct; char empno??(7??); char name??(30??); float salary; } rpt1; /* Structure for report 2 */ struct { char projno??(7??); char project_name??(37??); short employee_count; double total_proj_cost; } rpt2; 2 exec sql include SQLCA; qprint=fopen("QPRINT","w"); /* /* 3 4 Update the selected projects by the new percentage. If an error */ occurs during the update, ROLLBACK the changes. */ EXEC SQL WHENEVER SQLERROR GO TO update_error; EXEC SQL UPDATE CORPDATA/EMPLOYEE SET SALARY = SALARY * :percentage WHERE COMM >= :commission ; */ */ */ */

/* Commit changes */ 5 EXEC SQL COMMIT; EXEC SQL WHENEVER SQLERROR GO TO report_error; /* Report the updated statistics for each employee assigned to the */ /* selected projects. */ /* Write out the header for Report 1 */ fprintf(qprint," REPORT OF PROJECTS AFFECTED \

04/01/98 15:52:26 SEQNBR Last change 100 200 300 400 500 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 2400 2500 2600 2700 2800 2900 3000 3100 3200 3300 3400 3500 3600 3700 3800 3900 4000 4100 4200 4300 4400 4500 4600 4700 4800 4900 5000 5100 5200 5300 5400 5500 5600 5700 5800 5900 6000 6100 6200 6300 6400 6500

Page

Figure 39. Sample C Program Using SQL Statements (Part 2 of 7)

608

DB2 UDB for AS/400 SQL Programming V4R4

5769ST1 Record 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130

V4R4M0 990521 Create SQL ILE C Object CEX *...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 BY RAISES"); fprintf(qprint,"\n\nPROJECT EMPID EMPLOYEE NAME "); fprintf(qprint, " SALARY\n"); 6 exec sql declare c1 cursor for select distinct projno, emp_act.empno, lastname||', '||firstnme, salary from corpdata/emp_act, corpdata/employee where emp_act.empno = employee.empno and comm >= :commission order by projno, empno; 7 EXEC SQL OPEN C1; /* Fetch and write the rows to QPRINT */ 8 EXEC SQL WHENEVER NOT FOUND GO TO done1; do { 10 EXEC SQL FETCH C1 INTO :Proj_struct.PROJNO, :rpt1.empno, :rpt1.name,:rpt1.salary; fprintf(qprint,"\n%6s %6s %-30s %8.2f", rpt1.Proj_struct.PROJNO,rpt1.empno, rpt1.name,rpt1.salary); } while (SQLCODE==0); done1: EXEC SQL CLOSE C1; /* /* /* /* /* For all projects ending at a date later than the 'raise_date' (i.e. those projects potentially affected by the salary raises) generate a report containing the project number, project name the count of employees participating in the project and the total salary cost of the project. * / */ */ */ */

/* Write out the header for Report 2 */ fprintf(qprint,"\n\n\n ACCUMULATED STATISTICS\ BY PROJECT"); fprintf(qprint, "\n\nPROJECT \ NUMBER OF TOTAL"); fprintf(qprint, "\nNUMBER PROJECT NAME \ EMPLOYEES COST\n"); 11 EXEC SQL DECLARE C2 CURSOR FOR SELECT EMP_ACT.PROJNO, PROJNAME, COUNT(*), SUM ( ( DAYS(EMENDATE) - DAYS(EMSTDATE) ) * EMPTIME * (DECIMAL( SALARY / :work_days ,8,2))) FROM CORPDATA/EMP_ACT, CORPDATA/PROJECT, CORPDATA/EMPLOYEE WHERE EMP_ACT.PROJNO=PROJECT.PROJNO and EMP_ACT.EMPNO =EMPLOYEE.EMPNO and PRENDATE > :raise_date GROUP BY EMP_ACT.PROJNO, PROJNAME ORDER BY 1; EXEC SQL OPEN C2; /* Fetch and write the rows to QPRINT */ EXEC SQL WHENEVER NOT FOUND GO TO done2; do { 12 EXEC SQL FETCH C2 INTO :rpt2;

04/01/98 15:52:26 SEQNBR Last change 6600 6700 6800 6900 7000 7100 7200 7300 7400 7500 7600 7700 7800 7900 8000 8100 8200 8300 8400 8500 8600 8700 8800 8900 9000 9100 9200 9300 9400 9500 9600 9700 9800 9900 10000 10100 10200 10300 10400 10500 10600 10700 10800 10900 11000 11100 11200 11300 11400 11500 11600 11700 11800 11900 12000 12100 12200 12300 12400 12500 12600 12700 12800 12900 13000

Page

Figure 39. Sample C Program Using SQL Statements (Part 3 of 7)

Appendix C. Sample Programs Using DB2 UDB for AS/400 Statements

609

5769ST1 Record 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 * * * *

V4R4M0 990521 Create SQL ILE C Object CEX *...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 fprintf(qprint,"\n%6s %-36s %6d %9.2f", rpt2.projno,rpt2.project_name,rpt2.employee_count, rpt2.total_proj_cost); } while (SQLCODE==0); done2: EXEC SQL CLOSE C2; goto finished; /* Error occured while updating table. Inform user and rollback */ /* changes. */ update_error: 13 EXEC SQL WHENEVER SQLERROR CONTINUE; fprintf(qprint,"*** ERROR Occurred while updating table. SQLCODE=" "%5d\n",SQLCODE); 14 EXEC SQL ROLLBACK; goto finished; /* Error occured while generating reports. Inform user and exit. report_error: fprintf(qprint,"*** ERROR Occurred while generating reports. " "SQLCODE=%5d\n",SQLCODE); goto finished; /* All done */ finished: fclose(qprint); exit(0); } * E N D O F S O U R C E * * * * * */

04/01/98 15:52:26 SEQNBR Last change 13100 13200 13300 13400 13500 13600 13700 13800 13900 14000 14100 14200 14300 14400 14500 14600 14700 14800 14900 15000 15100 15200 15300 15400 15500 15600 15700 15800 15900 16000 16100 16200 16300

Page

Figure 39. Sample C Program Using SQL Statements (Part 4 of 7)

610

DB2 UDB for AS/400 SQL Programming V4R4

5769ST1 V4R4M0 990521 CROSS REFERENCE Data Names commission done1 done2 employee_count empno name percentage project_name projno raise_date report_error rpt1 rpt2 salary total_proj_cost update_error work_days ACTNO BIRTHDATE BONUS COMM COMM CORPDATA C1 C2 DEPTNO DEPTNO EDLEVEL EMENDATE EMENDATE EMP_ACT EMP_ACT

Create SQL ILE C Object Define 19 **** **** 40 31 32 20 39 38 21 **** 34 42 33 41 **** 18 74 74 74 **** 74 **** 71 112 27 116 74 74 **** **** ****

CEX

04/01/98 15:52:26

Page

Reference FLOAT(24) 54 75 LABEL 81 LABEL 126 SMALL INTEGER PRECISION(4,0) IN rpt2 VARCHAR(7) IN rpt1 85 VARCHAR(30) IN rpt1 86 FLOAT(24) 53 VARCHAR(37) IN rpt2 VARCHAR(7) IN rpt2 VARCHAR(12) 119 LABEL 59 STRUCTURE 130 FLOAT(24) IN rpt1 86 FLOAT(53) IN rpt2 LABEL 50 SMALL INTEGER PRECISION(4,0) 115 SMALL INTEGER PRECISION(4,0) COLUMN (NOT NULL) IN CORPDATA.EMP_ACT DATE(10) COLUMN IN CORPDATA.EMPLOYEE DECIMAL(9,2) COLUMN IN CORPDATA.EMPLOYEE COLUMN 54 75 DECIMAL(9,2) COLUMN IN CORPDATA.EMPLOYEE COLLECTION 52 74 74 116 116 116 CURSOR 78 85 95 CURSOR 123 130 139 VARCHAR(3) IN Proj_struct CHARACTER(3) COLUMN (NOT NULL) IN CORPDATA.PROJECT SMALL INTEGER PRECISION(4,0) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE DATE(10) COLUMN IN CORPDATA.EMP_ACT COLUMN 114 TABLE 72 75 113 117 118 120 TABLE IN CORPDATA 74 116

Figure 39. Sample C Program Using SQL Statements (Part 5 of 7)

Appendix C. Sample Programs Using DB2 UDB for AS/400 Statements

611

5769ST1 V4R4M0 990521 CROSS REFERENCE EMPLOYEE EMPLOYEE EMPNO EMPNO EMPNO EMPNO EMPTIME EMPTIME EMSTDATE EMSTDATE FIRSTNME FIRSTNME HIREDATE JOB LASTNAME LASTNAME MAJPROJ MAJPROJ MIDINIT Proj_struct PHONENO PRENDATE PRENDATE PRENDATE PROJECT PROJECT PROJNAME PROJNAME PROJNAME PROJNO PROJNO PROJNO PROJNO

Create SQL ILE C Object **** **** **** **** 74 74 74 **** 74 **** **** 74 74 74 **** 74 27 116 74 30 74 27 **** 116 **** **** 27 **** 116 27 **** 74 ****

CEX

04/01/98 15:52:26

Page

TABLE IN CORPDATA 52 74 116 TABLE 75 118 COLUMN IN EMP_ACT 72 75 76 118 COLUMN IN EMPLOYEE 75 118 CHARACTER(6) COLUMN (NOT NULL) IN CORPDATA.EMP_ACT CHARACTER(6) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE DECIMAL(5,2) COLUMN IN CORPDATA.EMP_ACT COLUMN 114 DATE(10) COLUMN IN CORPDATA.EMP_ACT COLUMN 114 COLUMN 73 VARCHAR(12) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE DATE(10) COLUMN IN CORPDATA.EMPLOYEE CHARACTER(8) COLUMN IN CORPDATA.EMPLOYEE COLUMN 73 VARCHAR(15) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE VARCHAR(6) IN Proj_struct CHARACTER(6) COLUMN IN CORPDATA.PROJECT CHARACTER(1) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE STRUCTURE IN rpt1 CHARACTER(4) COLUMN IN CORPDATA.EMPLOYEE DATE(10) IN Proj_struct COLUMN 119 DATE(10) COLUMN IN CORPDATA.PROJECT TABLE IN CORPDATA 116 TABLE 117 VARCHAR(24) IN Proj_struct COLUMN 113 120 VARCHAR(24) COLUMN (NOT NULL) IN CORPDATA.PROJECT VARCHAR(6) IN Proj_struct 85 COLUMN 72 76 CHARACTER(6) COLUMN (NOT NULL) IN CORPDATA.EMP_ACT COLUMN IN EMP_ACT

Figure 39. Sample C Program Using SQL Statements (Part 6 of 7)

5769ST1 V4R4M0 990521 CROSS REFERENCE PROJNO PROJNO PRSTAFF PRSTAFF PRSTDATE PRSTDATE RESPEMP RESPEMP SALARY SALARY SEX WORKDEPT No errors found in source 163 Source records processed * * * * * E N D O F L I S T I

Create SQL ILE C Object **** 116 27 116 27 116 27 116 **** 74 74 74 N G

CEX

04/01/98 15:52:26

Page

113 117 120 COLUMN IN PROJECT 117 CHARACTER(6) COLUMN (NOT NULL) IN CORPDATA.PROJECT DECIMAL(5,2) IN Proj_struct DECIMAL(5,2) COLUMN IN CORPDATA.PROJECT DATE(10) IN Proj_struct DATE(10) COLUMN IN CORPDATA.PROJECT VARCHAR(6) IN Proj_struct CHARACTER(6) COLUMN (NOT NULL) IN CORPDATA.PROJECT COLUMN 53 53 73 115 DECIMAL(9,2) COLUMN IN CORPDATA.EMPLOYEE CHARACTER(1) COLUMN IN CORPDATA.EMPLOYEE CHARACTER(3) COLUMN IN CORPDATA.EMPLOYEE * * * * *

Figure 39. Sample C Program Using SQL Statements (Part 7 of 7)

612

DB2 UDB for AS/400 SQL Programming V4R4

SQL Statements in COBOL and ILE COBOL Programs


5769ST1 V4R4M0 990521 Create SQL COBOL Program Source type...............COBOL Program name..............CORPDATA/CBLEX Source file...............CORPDATA/SRC Member....................CBLEX To source file............QTEMP/QSQLTEMP Options...................*SRC *XREF Target release............V4R4M0 INCLUDE file..............*LIBL/*SRCFILE Commit....................*CHG Allow copy of data........*YES Close SQL cursor..........*ENDPGM Allow blocking............*READ Delay PREPARE.............*NO Generation level..........10 Printer file..............*LIBL/QSYSPRT Date format...............*JOB Date separator............*JOB Time format...............*HMS Time separator ...........*JOB Replace...................*YES Relational database.......*LOCAL User .....................*CURRENT RDB connect method........*DUW Default Collection........*NONE Package name..............*PGMLIB/*PGM Dynamic User Profile......*USER User Profile..............*NAMING Sort Sequence.............*JOB Language ID...............*JOB IBM SQL flagging..........*NOFLAG ANS flagging..............*NONE Text......................*SRCMBRTXT Source file CCSID.........65535 Job CCSID.................65535 Source member changed on 07/01/96 09:44:58 CBLEX 04/01/98 11:09:13 Page 1

Figure 40. Sample COBOL Program Using SQL Statements (Part 1 of 9)

Appendix C. Sample Programs Using DB2 UDB for AS/400 Statements

613

5769ST1 V4R4M0 990521 Create SQL COBOL Program CBLEX Record *...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 1 2 **************************************************************** 3 * A sample program which updates the salaries for those * 4 * employees whose current commission total is greater than or * 5 * equal to the value of COMMISSION. The salaries of those who * 6 * qualify are increased by the value of PERCENTAGE retroactive * 7 * to RAISE-DATE. A report is generated showing the projects * 8 * which these employees have contributed to ordered by the * 9 * project number and employee ID. A second report shows each * 10 * project having an end date occurring after RAISE-DATE * 11 * (i.e. potentially affected by the retroactive raises ) with * 12 * its total salary expenses and a count of employees who * 13 * contributed to the project. * 14 **************************************************************** 15 16 17 IDENTIFICATION DIVISION. 18 19 PROGRAM-ID. CBLEX. 20 ENVIRONMENT DIVISION. 21 CONFIGURATION SECTION. 22 SOURCE-COMPUTER. IBM-AS400. 23 OBJECT-COMPUTER. IBM-AS400. 24 INPUT-OUTPUT SECTION. 25 26 FILE-CONTROL. 27 SELECT PRINTFILE ASSIGN TO PRINTER-QPRINT 28 ORGANIZATION IS SEQUENTIAL. 29 30 DATA DIVISION. 31 32 FILE SECTION. 33 34 FD PRINTFILE 35 BLOCK CONTAINS 1 RECORDS 36 LABEL RECORDS ARE OMITTED. 37 01 PRINT-RECORD PIC X(132). 38 39 WORKING-STORAGE SECTION. 40 77 WORK-DAYS PIC S9(4) BINARY VALUE 253. 41 77 RAISE-DATE PIC X(11) VALUE "1982-06-01". 42 77 PERCENTAGE PIC S999V99 PACKED-DECIMAL. 43 77 COMMISSION PIC S99999V99 PACKED-DECIMAL VALUE 2000.00. 44 45 *************************************************************** 46 * Structure for report 1. * 47 *************************************************************** 48 49 1 01 RPT1. 50 COPY DDS-PROJECT OF CORPDATA-PROJECT. 51 05 EMPNO PIC X(6). 52 05 NAME PIC X(30). 53 05 SALARY PIC S9(6)V99 PACKED-DECIMAL. 54 55 56 *************************************************************** 57 * Structure for report 2. * 58 *************************************************************** 59 60 01 RPT2. 61 15 PROJNO PIC X(6). 62 15 PROJECT-NAME PIC X(36). 63 15 EMPLOYEE-COUNT PIC S9(4) BINARY. 64 15 TOTAL-PROJ-COST PIC S9(10)V99 PACKED-DECIMAL. 65

SEQNBR

04/01/98 11:09:13 Last change

Page

Figure 40. Sample COBOL Program Using SQL Statements (Part 2 of 9)

614

DB2 UDB for AS/400 SQL Programming V4R4

5769ST1 V4R4M0 990521 Create SQL COBOL Program CBLEX Record *...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 66 2 EXEC SQL 67 INCLUDE SQLCA 68 END-EXEC. 69 77 CODE-EDIT PIC ---99. 70 71 *************************************************************** 72 * Headers for reports. * 73 *************************************************************** 74 75 01 RPT1-HEADERS. 76 05 RPT1-HEADER1. 77 10 FILLER PIC X(21) VALUE SPACES. 78 10 FILLER PIC X(111) 79 VALUE "REPORT OF PROJECTS AFFECTED BY RAISES". 80 05 RPT1-HEADER2. 81 10 FILLER PIC X(9) VALUE "PROJECT". 82 10 FILLER PIC X(10) VALUE "EMPID". 83 10 FILLER PIC X(35) VALUE "EMPLOYEE NAME". 84 10 FILLER PIC X(40) VALUE "SALARY". 85 01 RPT2-HEADERS. 86 05 RPT2-HEADER1. 87 10 FILLER PIC X(21) VALUE SPACES. 88 10 FILLER PIC X(111) 89 VALUE "ACCUMULATED STATISTICS BY PROJECT". 90 05 RPT2-HEADER2. 91 10 FILLER PIC X(9) VALUE "PROJECT". 92 10 FILLER PIC X(38) VALUE SPACES. 93 10 FILLER PIC X(16) VALUE "NUMBER OF". 94 10 FILLER PIC X(10) VALUE "TOTAL". 95 05 RPT2-HEADER3. 96 10 FILLER PIC X(9) VALUE "NUMBER". 97 10 FILLER PIC X(38) VALUE "PROJECT NAME". 98 10 FILLER PIC X(16) VALUE "EMPLOYEES". 99 10 FILLER PIC X(65) VALUE "COST". 100 01 RPT1-DATA. 101 05 PROJNO PIC X(6). 102 05 FILLER PIC XXX VALUE SPACES. 103 05 EMPNO PIC X(6). 104 05 FILLER PIC X(4) VALUE SPACES. 105 05 NAME PIC X(30). 106 05 FILLER PIC X(3) VALUE SPACES. 107 05 SALARY PIC ZZZZZ9.99. 108 05 FILLER PIC X(96) VALUE SPACES. 109 01 RPT2-DATA. 110 05 PROJNO PIC X(6). 111 05 FILLER PIC XXX VALUE SPACES. 112 05 PROJECT-NAME PIC X(36). 113 05 FILLER PIC X(4) VALUE SPACES. 114 05 EMPLOYEE-COUNT PIC ZZZ9. 115 05 FILLER PIC X(5) VALUE SPACES. 116 05 TOTAL-PROJ-COST PIC ZZZZZZZZ9.99. 117 05 FILLER PIC X(56) VALUE SPACES. 118 119 PROCEDURE DIVISION. 120 121 A000-MAIN. 122 MOVE 1.04 TO PERCENTAGE. 123 OPEN OUTPUT PRINTFILE. 124 125 *************************************************************** 126 * Update the selected employees by the new percentage. If an * 127 * error occurs during the update, ROLLBACK the changes, * 128 *************************************************************** 129 130 3 EXEC SQL

SEQNBR

04/01/98 11:09:13 Last change

Page

Figure 40. Sample COBOL Program Using SQL Statements (Part 3 of 9)

Appendix C. Sample Programs Using DB2 UDB for AS/400 Statements

615

5769ST1 V4R4M0 990521 Create SQL COBOL Program CBLEX Record *...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 131 WHENEVER SQLERROR GO TO E010-UPDATE-ERROR 132 END-EXEC. 133 4 EXEC SQL 134 UPDATE CORPDATA/EMPLOYEE 135 SET SALARY = SALARY * :PERCENTAGE 136 WHERE COMM >= :COMMISSION 137 END-EXEC. 138 139 *************************************************************** 140 * Commit changes. * 141 *************************************************************** 142 143 5 EXEC SQL 144 COMMIT 145 END-EXEC. 146 147 EXEC SQL 148 WHENEVER SQLERROR GO TO E020-REPORT-ERROR 149 END-EXEC. 150 151 *************************************************************** 152 * Report the updated statistics for each employee receiving * 153 * a raise and the projects that s/he participates in * 154 *************************************************************** 155 156 *************************************************************** 157 * Write out the header for Report 1. * 158 *************************************************************** 159 160 write print-record from rpt1-header1 161 before advancing 2 lines. 162 write print-record from rpt1-header2 163 before advancing 1 line. 164 6 exec sql 165 declare c1 cursor for 166 SELECT DISTINCT projno, emp_act.empno, 167 lastname||", "||firstnme ,salary 168 from corpdata/emp_act, corpdata/employee 169 where emp_act.empno =employee.empno and 170 comm >= :commission 171 order by projno, empno 172 end-exec. 173 7 EXEC SQL 174 OPEN C1 175 END-EXEC. 176 177 PERFORM B000-GENERATE-REPORT1 THRU B010-GENERATE-REPORT1-EXIT 178 UNTIL SQLCODE NOT EQUAL TO ZERO. 179 180 10 A100-DONE1. 181 EXEC SQL 182 CLOSE C1 183 END-EXEC. 184 185 ************************************************************* 186 * For all projects ending at a date later than the RAISE- * 187 * DATE ( i.e. those projects potentially affected by the * 188 * salary raises generate a report containing the project * 189 * project number, project name, the count of employees * 190 * participating in the project and the total salary cost * 191 * for the project * 192 ************************************************************* 193 194 195 ***************************************************************

SEQNBR

04/01/98 11:09:13 Last change

Page

Note:

8 and 9 are located on Part 5 of this gure.

Figure 40. Sample COBOL Program Using SQL Statements (Part 4 of 9)

616

DB2 UDB for AS/400 SQL Programming V4R4

5769ST1 V4R4M0 990521 Create SQL COBOL Program CBLEX Record *...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 196 * Write out the header for Report 2. * 197 *************************************************************** 198 199 MOVE SPACES TO PRINT-RECORD. 200 WRITE PRINT-RECORD BEFORE ADVANCING 2 LINES. 201 WRITE PRINT-RECORD FROM RPT2-HEADER1 202 BEFORE ADVANCING 2 LINES. 203 WRITE PRINT-RECORD FROM RPT2-HEADER2 204 BEFORE ADVANCING 1 LINE. 205 WRITE PRINT-RECORD FROM RPT2-HEADER3 206 BEFORE ADVANCING 2 LINES. 207 208 EXEC SQL 209 11 DECLARE C2 CURSOR FOR 210 SELECT EMP_ACT.PROJNO, PROJNAME, COUNT(*), 211 SUM ( (DAYS(EMENDATE)-DAYS(EMSTDATE)) * 212 EMPTIME * DECIMAL((SALARY / :WORK-DAYS),8,2)) 213 FROM CORPDATA/EMP_ACT, CORPDATA/PROJECT, 214 CORPDATA/EMPLOYEE 215 WHERE EMP_ACT.PROJNO=PROJECT.PROJNO AND 216 EMP_ACT.EMPNO =EMPLOYEE.EMPNO AND 217 PRENDATE > :RAISE-DATE 218 GROUP BY EMP_ACT.PROJNO, PROJNAME 219 ORDER BY 1 220 END-EXEC. 221 EXEC SQL 222 OPEN C2 223 END-EXEC. 224 225 PERFORM C000-GENERATE-REPORT2 THRU C010-GENERATE-REPORT2-EXIT 226 UNTIL SQLCODE NOT EQUAL TO ZERO. 227 228 A200-DONE2. 229 EXEC SQL 230 CLOSE C2 231 END-EXEC 232 233 *************************************************************** 234 * All done. * 235 *************************************************************** 236 237 A900-MAIN-EXIT. 238 CLOSE PRINTFILE. 239 STOP RUN. 240 241 *************************************************************** 242 * Fetch and write the rows to PRINTFILE. * 243 *************************************************************** 244 245 B000-GENERATE-REPORT1. 246 8 EXEC SQL 247 WHENEVER NOT FOUND GO TO A100-DONE1 248 END-EXEC. 249 9 EXEC SQL 250 FETCH C1 INTO :PROJECT.PROJNO, :RPT1.EMPNO, 251 :RPT1.NAME, :RPT1.SALARY 252 END-EXEC. 253 MOVE CORRESPONDING RPT1 TO RPT1-DATA. 254 MOVE PROJNO OF RPT1 TO PROJNO OF RPT1-DATA. 255 WRITE PRINT-RECORD FROM RPT1-DATA 256 BEFORE ADVANCING 1 LINE. 257 258 B010-GENERATE-REPORT1-EXIT. 259 EXIT. 260

SEQNBR

04/01/98 11:09:13 Last change

Page

Figure 40. Sample COBOL Program Using SQL Statements (Part 5 of 9)

Appendix C. Sample Programs Using DB2 UDB for AS/400 Statements

617

5769ST1 V4R4M0 990521 Create SQL COBOL Program CBLEX Record *...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 261 *************************************************************** 262 * Fetch and write the rows to PRINTFILE. * 263 *************************************************************** 264 265 C000-GENERATE-REPORT2. 266 EXEC SQL 267 WHENEVER NOT FOUND GO TO A200-DONE2 268 END-EXEC. 269 12 EXEC SQL 270 FETCH C2 INTO :RPT2 271 END-EXEC. 272 MOVE CORRESPONDING RPT2 TO RPT2-DATA. 273 WRITE PRINT-RECORD FROM RPT2-DATA 274 BEFORE ADVANCING 1 LINE. 275 276 C010-GENERATE-REPORT2-EXIT. 277 EXIT. 278 279 *************************************************************** 280 * Error occured while updating table. Inform user and * 281 * rollback changes. * 282 *************************************************************** 283 284 E010-UPDATE-ERROR. 285 13 EXEC SQL 286 WHENEVER SQLERROR CONTINUE 287 END-EXEC. 288 MOVE SQLCODE TO CODE-EDIT. 289 STRING "*** ERROR Occurred while updating table. SQLCODE=" 290 CODE-EDIT DELIMITED BY SIZE INTO PRINT-RECORD. 291 WRITE PRINT-RECORD. 292 14 EXEC SQL 293 ROLLBACK 294 END-EXEC. 295 STOP RUN. 296 297 *************************************************************** 298 * Error occured while generating reports. Inform user and * 299 * exit. * 300 *************************************************************** 301 302 E020-REPORT-ERROR. 303 MOVE SQLCODE TO CODE-EDIT. 304 STRING "*** ERROR Occurred while generating reports. SQLCODE 305 "=" CODE-EDIT DELIMITED BY SIZE INTO PRINT-RECORD. 306 WRITE PRINT-RECORD. 307 STOP RUN. * * * * * E N D O F S O U R C E * * * * *

SEQNBR

04/01/98 11:09:13 Last change

Page

Figure 40. Sample COBOL Program Using SQL Statements (Part 6 of 9)

618

DB2 UDB for AS/400 SQL Programming V4R4

5769ST1 V4R4M0 990521 CROSS REFERENCE Data Names ACTNO A100-DONE1 A200-DONE2 BIRTHDATE BONUS CODE-EDIT COMM COMM COMMISSION CORPDATA C1 C2 DEPTNO DEPTNO EDLEVEL EMENDATE EMENDATE EMP_ACT EMP_ACT EMPLOYEE EMPLOYEE EMPLOYEE-COUNT EMPLOYEE-COUNT EMPNO EMPNO EMPNO EMPNO EMPNO EMPNO EMPTIME EMPTIME EMSTDATE

Create SQL COBOL Program Define 168 **** **** 134 134 69 **** 134 43 **** 165 209 50 213 134 168 **** **** **** **** **** 63 114 51 103 134 **** **** 168 168 **** 168

CBLEX

04/01/98 11:09:13

Page

Reference SMALL INTEGER PRECISION(4,0) COLUMN (NOT NULL) IN CORPDATA.EMP_ACT LABEL 247 LABEL 267 DATE(10) COLUMN IN CORPDATA.EMPLOYEE DECIMAL(9,2) COLUMN IN CORPDATA.EMPLOYEE COLUMN 136 170 DECIMAL(9,2) COLUMN IN CORPDATA.EMPLOYEE DECIMAL(7,2) 136 170 COLLECTION 134 168 168 213 213 214 CURSOR 174 182 250 CURSOR 222 230 270 CHARACTER(3) IN PROJECT CHARACTER(3) COLUMN (NOT NULL) IN CORPDATA.PROJECT SMALL INTEGER PRECISION(4,0) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE DATE(10) COLUMN IN CORPDATA.EMP_ACT COLUMN 211 TABLE 166 169 210 215 216 218 TABLE IN CORPDATA 168 213 TABLE IN CORPDATA 134 168 214 TABLE 169 216 SMALL INTEGER PRECISION(4,0) IN RPT2 IN RPT2-DATA CHARACTER(6) IN RPT1 250 CHARACTER(6) IN RPT1-DATA CHARACTER(6) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE COLUMN IN EMP_ACT 166 169 171 216 COLUMN IN EMPLOYEE 169 216 CHARACTER(6) COLUMN (NOT NULL) IN CORPDATA.EMP_ACT DECIMAL(5,2) COLUMN IN CORPDATA.EMP_ACT COLUMN 212 DATE(10) COLUMN IN CORPDATA.EMP_ACT

Figure 40. Sample COBOL Program Using SQL Statements (Part 7 of 9)

Appendix C. Sample Programs Using DB2 UDB for AS/400 Statements

619

5769ST1 V4R4M0 990521 CROSS REFERENCE EMSTDATE E010-UPDATE-ERROR E020-REPORT-ERROR FIRSTNME FIRSTNME HIREDATE JOB LASTNAME LASTNAME MAJPROJ MAJPROJ MIDINIT NAME NAME PERCENTAGE PHONENO PRENDATE PRENDATE PRENDATE PRINT-RECORD PROJECT PROJECT PROJECT PROJECT-NAME PROJECT-NAME PROJNAME PROJNAME PROJNAME PROJNO PROJNO PROJNO PROJNO PROJNO

Create SQL COBOL Program **** **** **** 134 **** 134 134 134 **** 50 213 134 52 105 42 134 50 **** 213 37 50 **** **** 62 112 50 **** 213 50 61 101 110 ****

CBLEX

04/01/98 11:09:13

Page

COLUMN 211 LABEL 131 LABEL 148 VARCHAR(12) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE COLUMN 167 DATE(10) COLUMN IN CORPDATA.EMPLOYEE CHARACTER(8) COLUMN IN CORPDATA.EMPLOYEE VARCHAR(15) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE COLUMN 167 CHARACTER(6) IN PROJECT CHARACTER(6) COLUMN IN CORPDATA.PROJECT CHARACTER(1) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE CHARACTER(30) IN RPT1 251 CHARACTER(30) IN RPT1-DATA DECIMAL(5,2) 135 CHARACTER(4) COLUMN IN CORPDATA.EMPLOYEE DATE(10) IN PROJECT COLUMN 217 DATE(10) COLUMN IN CORPDATA.PROJECT CHARACTER(132) STRUCTURE IN RPT1 TABLE IN CORPDATA 213 TABLE 215 CHARACTER(36) IN RPT2 CHARACTER(36) IN RPT2-DATA VARCHAR(24) IN PROJECT COLUMN 210 218 VARCHAR(24) COLUMN (NOT NULL) IN CORPDATA.PROJECT CHARACTER(6) IN PROJECT 250 CHARACTER(6) IN RPT2 CHARACTER(6) IN RPT1-DATA CHARACTER(6) IN RPT2-DATA COLUMN

Figure 40. Sample COBOL Program Using SQL Statements (Part 8 of 9)

620

DB2 UDB for AS/400 SQL Programming V4R4

5769ST1 V4R4M0 990521 CROSS REFERENCE PROJNO PROJNO PROJNO PROJNO PRSTAFF PRSTAFF PRSTDATE PRSTDATE RAISE-DATE RESPEMP RESPEMP RPT1 RPT1-DATA RPT1-HEADERS RPT1-HEADER1 RPT1-HEADER2 RPT2 RPT2-DATA RPT2-HEADERS RPT2-HEADER1 RPT2-HEADER2 RPT2-HEADER3 SALARY SALARY SALARY SALARY SEX TOTAL-PROJ-COST TOTAL-PROJ-COST WORK-DAYS WORKDEPT No errors found in source 307 Source records processed

Create SQL COBOL Program 168 **** **** 213 50 213 50 213 41 50 213 49 100 75 76 80 60 109 85 86 90 95 53 107 **** 134 134 64 116 40 134 * * * * *

CBLEX

04/01/98 11:09:13

Page

166 171 CHARACTER(6) COLUMN (NOT NULL) IN CORPDATA.EMP_ACT COLUMN IN EMP_ACT 210 215 218 COLUMN IN PROJECT 215 CHARACTER(6) COLUMN (NOT NULL) IN CORPDATA.PROJECT DECIMAL(5,2) IN PROJECT DECIMAL(5,2) COLUMN IN CORPDATA.PROJECT DATE(10) IN PROJECT DATE(10) COLUMN IN CORPDATA.PROJECT CHARACTER(11) 217 CHARACTER(6) IN PROJECT CHARACTER(6) COLUMN (NOT NULL) IN CORPDATA.PROJECT

IN RPT1-HEADERS IN RPT1-HEADERS STRUCTURE 270 IN RPT2-HEADERS IN RPT2-HEADERS IN RPT2-HEADERS DECIMAL(8,2) IN RPT1 251 IN RPT1-DATA COLUMN 135 135 167 212 DECIMAL(9,2) COLUMN IN CORPDATA.EMPLOYEE CHARACTER(1) COLUMN IN CORPDATA.EMPLOYEE DECIMAL(12,2) IN RPT2 IN RPT2-DATA SMALL INTEGER PRECISION(4,0) 212 CHARACTER(3) COLUMN IN CORPDATA.EMPLOYEE E N D O F L I S T I N G * * * * *

Figure 40. Sample COBOL Program Using SQL Statements (Part 9 of 9)

SQL Statements in PL/I

Appendix C. Sample Programs Using DB2 UDB for AS/400 Statements

621

5769ST1 V4R4M0 990521 Create SQL PL/I Program Source type...............PLI Program name..............CORPDATA/PLIEX Source file...............CORPDATA/SRC Member....................PLIEX To source file............QTEMP/QSQLTEMP Options...................*SRC *XREF Target release............V4R4M0 INCLUDE file..............*LIBL/*SRCFILE Commit....................*CHG Allow copy of data........*YES Close SQL cursor..........*ENDPGM Allow blocking............*READ Delay PREPARE.............*NO Generation level..........10 Margins...................*SRCFILE Printer file..............*LIBL/QSYSPRT Date format...............*JOB Date separator............*JOB Time format...............*HMS Time separator ...........*JOB Replace...................*YES Relational database.......*LOCAL User .....................*CURRENT RDB connect method........*DUW Default Collection........*NONE Package name..............*PGMLIB/*PGM Dynamic User Profile......*USER User Profile..............*NAMING Sort Sequence.............*JOB Language ID...............*JOB IBM SQL flagging..........*NOFLAG ANS flagging..............*NONE Text......................*SRCMBRTXT Source file CCSID.........65535 Job CCSID.................65535 Source member changed on 07/01/96 12:53:08

PLIEX

04/01/98 12:53:36

Page

Figure 41. Sample PL/I Program Using SQL Statements (Part 1 of 7)

622

DB2 UDB for AS/400 SQL Programming V4R4

5769ST1 Record 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65

V4R4M0 990521 Create SQL PL/I Program PLIEX *...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 /* A sample program which updates the salaries for those employees */ /* whose current commission total is greater than or equal to the */ /* value of COMMISSION. The salaries of those who qualify are */ /* increased by the value of PERCENTAGE, retroactive to RAISE_DATE. */ /* A report is generated showing the projects which these employees */ /* have contributed to, ordered by project number and employee ID. */ /* A second report shows each project having an end date occurring */ /* after RAISE_DATE (i.e. is potentially affected by the retroactive */ /* raises) with its total salary expenses and a count of employees */ /* who contributed to the project. */ /*********************************************************************/ PLIEX: PROC; DCL DCL DCL DCL RAISE_DATE WORK_DAYS COMMISSION PERCENTAGE CHAR(10); FIXED BIN(15); FIXED DECIMAL(8,2); FIXED DECIMAL(5,2);

/* File declaration for sysprint */ DCL SYSPRINT FILE EXTERNAL OUTPUT STREAM PRINT; /* Structure for report 1 */ DCL 1 RPT1, 1 %INCLUDE PROJECT (PROJECT, RECORD,,COMMA); 15 EMPNO CHAR(6), 15 NAME CHAR(30), 15 SALARY FIXED DECIMAL(8,2); /* Structure for report 2 */ DCL 1 RPT2, 15 PROJNO CHAR(6), 15 PROJECT_NAME CHAR(36), 15 EMPLOYEE_COUNT FIXED BIN(15), 15 TOTL_PROJ_COST FIXED DECIMAL(10,2); 2 EXEC SQL INCLUDE SQLCA; COMMISSION = 2000.00; PERCENTAGE = 1.04; RAISE_DATE = '1982-06-01'; WORK_DAYS = 253; OPEN FILE(SYSPRINT); /* Update the selected employee's salaries by the new percentage. */ /* If an error occurs during the update, ROLLBACK the changes. */ 3 EXEC SQL WHENEVER SQLERROR GO TO UPDATE_ERROR; 4 EXEC SQL UPDATE CORPDATA/EMPLOYEE SET SALARY = SALARY * :PERCENTAGE WHERE COMM >= :COMMISSION ; /* Commit changes */ 5 EXEC SQL COMMIT; EXEC SQL WHENEVER SQLERROR GO TO REPORT_ERROR; /* Report the updated statistics for each project supported by one */ /* of the selected employees. */ /* Write out the header for Report 1 */ put file(sysprint) edit('REPORT OF PROJECTS AFFECTED BY EMPLOYEE RAISES') (col(22),a);

04/01/98 12:53:36 SEQNBR Last change 100 200 300 400 500 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 2400 2500 2600 2700 2800 2900 3000 3100 3200 3300 3400 3500 3600 3700 3800 3900 4000 4100 4200 4300 4400 4500 4600 4700 4800 4900 5000 5100 5200 5300 5400 5500 5600 5700 5800 5900 6000 6100 6200 6300 6400 6500

Page

Figure 41. Sample PL/I Program Using SQL Statements (Part 2 of 7)

Appendix C. Sample Programs Using DB2 UDB for AS/400 Statements

623

5769ST1 Record 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130

V4R4M0 990521 Create SQL PL/I Program PLIEX *...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 put file(sysprint) edit('PROJECT','EMPID','EMPLOYEE NAME','SALARY') (skip(2),col(1),a,col(10),a,col(20),a,col(55),a); 6 exec sql declare c1 cursor for select DISTINCT projno, EMP_ACT.empno, lastname||', '||firstnme, salary from CORPDATA/EMP_ACT, CORPDATA/EMPLOYEE where EMP_ACT.empno = EMPLOYEE.empno and comm >= :COMMISSION order by projno, empno; 7 EXEC SQL OPEN C1; /* Fetch and write the rows to SYSPRINT */ 8 EXEC SQL WHENEVER NOT FOUND GO TO DONE1; DO UNTIL (SQLCODE |= 0); 9 EXEC SQL FETCH C1 INTO :RPT1.PROJNO, :rpt1.EMPNO, :RPT1.NAME, :RPT1.SALARY; PUT FILE(SYSPRINT) EDIT(RPT1.PROJNO,RPT1.EMPNO,RPT1.NAME,RPT1.SALARY) (SKIP,COL(1),A,COL(10),A,COL(20),A,COL(54),F(8,2)); END; DONE1: 10 EXEC SQL CLOSE C1; /* /* /* /* /* For all projects ending at a date later than 'raise_date' (i.e. those projects potentially affected by the salary raises) generate a report containing the project number, project name the count of employees participating in the project and the total salary cost of the project. */ */ */ */ */

/* Write out the header for Report 2 */ PUT FILE(SYSPRINT) EDIT('ACCUMULATED STATISTICS BY PROJECT') (SKIP(3),COL(22),A); PUT FILE(SYSPRINT) EDIT('PROJECT','NUMBER OF','TOTAL') (SKIP(2),COL(1),A,COL(48),A,COL(63),A); PUT FILE(SYSPRINT) EDIT('NUMBER','PROJECT NAME','EMPLOYEES','COST') (SKIP,COL(1),A,COL(10),A,COL(48),A,COL(63),A,SKIP); 11 EXEC SQL DECLARE C2 CURSOR FOR SELECT EMP_ACT.PROJNO, PROJNAME, COUNT(*), SUM( (DAYS(EMENDATE) - DAYS(EMSTDATE)) * EMPTIME * DECIMAL(( SALARY / :WORK_DAYS ),8,2) ) FROM CORPDATA/EMP_ACT, CORPDATA/PROJECT, CORPDATA/EMPLOYEE WHERE EMP_ACT.PROJNO=PROJECT.PROJNO AND EMP_ACT.EMPNO =EMPLOYEE.EMPNO AND PRENDATE > :RAISE_DATE GROUP BY EMP_ACT.PROJNO, PROJNAME ORDER BY 1; EXEC SQL OPEN C2; /* Fetch and write the rows to SYSPRINT */ EXEC SQL WHENEVER NOT FOUND GO TO DONE2; DO UNTIL (SQLCODE |= 0);

04/01/98 12:53:36 SEQNBR Last change 6600 6700 6800 6900 7000 7100 7200 7300 7400 7500 7600 7700 7800 7900 8000 8100 8200 8300 8400 8500 8600 8700 8800 8900 9000 9100 9200 9300 9400 9500 9600 9700 9800 9900 10000 10100 10200 10300 10400 10500 10600 10700 10800 10900 11000 11100 11200 11300 11400 11500 11600 11700 11800 11900 12000 12100 12200 12300 12400 12500 12600 12700 12800 12900 13000

Page

Figure 41. Sample PL/I Program Using SQL Statements (Part 3 of 7)

624

DB2 UDB for AS/400 SQL Programming V4R4

5769ST1 Record 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165

V4R4M0 990521 Create SQL PL/I Program PLIEX *...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 12 EXEC SQL FETCH C2 INTO :RPT2; PUT FILE(SYSPRINT) EDIT(RPT2.PROJNO,RPT2.PROJECT_NAME,EMPLOYEE_COUNT, TOTL_PROJ_COST) (SKIP,COL(1),A,COL(10),A,COL(50),F(4),COL(62),F(8,2)); END; DONE2: EXEC SQL CLOSE C2; GO TO FINISHED; /* Error occured while updating table. Inform user and rollback */ /* changes. */ UPDATE_ERROR: 13 EXEC SQL WHENEVER SQLERROR CONTINUE; PUT FILE(SYSPRINT) EDIT('*** ERROR Occurred while updating table.'|| ' SQLCODE=',SQLCODE)(A,F(5)); 14 EXEC SQL ROLLBACK; GO TO FINISHED; /* Error occured while generating reports. Inform user and exit. REPORT_ERROR: PUT FILE(SYSPRINT) EDIT('*** ERROR Occurred while generating '|| 'reports. SQLCODE=',SQLCODE)(A,F(5)); GO TO FINISHED; /* All done */ FINISHED: CLOSE FILE(SYSPRINT); RETURN; END PLIEX; * * * * * E N D O F S O U R C E * * * * * */

04/01/98 12:53:36 SEQNBR Last change 13100 13200 13300 13400 13500 13600 13700 13800 13900 14000 14100 14200 14300 14400 14500 14600 14700 14800 14900 15000 15100 15200 15300 15400 15500 15600 15700 15800 15900 16000 16100 16200 16300 16400 16500

Page

Figure 41. Sample PL/I Program Using SQL Statements (Part 4 of 7)

Appendix C. Sample Programs Using DB2 UDB for AS/400 Statements

625

5769ST1 V4R4M0 990521 CROSS REFERENCE Data Names ACTNO BIRTHDATE BONUS COMM COMM COMMISSION CORPDATA C1 C2 DEPTNO DEPTNO DONE1 DONE2 EDLEVEL EMENDATE EMENDATE EMP_ACT EMP_ACT EMPLOYEE EMPLOYEE EMPLOYEE_COUNT EMPNO EMPNO EMPNO EMPNO EMPNO EMPTIME EMPTIME EMSTDATE EMSTDATE FIRSTNME FIRSTNME

Create SQL PL/I Program Define 74 74 74 **** 74 18 **** 71 114 26 118 **** **** 74 74 **** **** **** **** **** 35 27 **** **** 74 74 74 **** 74 **** **** 74

PLIEX

04/01/98 12:53:36

Page

Reference SMALL INTEGER PRECISION(4,0) COLUMN (NOT NULL) IN CORPDATA.EMP_ACT DATE(10) COLUMN IN CORPDATA.EMPLOYEE DECIMAL(9,2) COLUMN IN CORPDATA.EMPLOYEE COLUMN 52 76 DECIMAL(9,2) COLUMN IN CORPDATA.EMPLOYEE DECIMAL(8,2) 52 76 COLLECTION 50 74 74 118 118 118 CURSOR 79 86 95 CURSOR 125 132 141 CHARACTER(3) IN RPT1 CHARACTER(3) COLUMN (NOT NULL) IN CORPDATA.PROJECT LABEL 82 LABEL 128 SMALL INTEGER PRECISION(4,0) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE DATE(10) COLUMN IN CORPDATA.EMP_ACT COLUMN 116 TABLE 72 75 115 119 120 122 TABLE IN CORPDATA 74 118 TABLE IN CORPDATA 50 74 118 TABLE 75 120 SMALL INTEGER PRECISION(4,0) IN RPT2 CHARACTER(6) IN RPT1 86 COLUMN IN EMP_ACT 72 75 77 120 COLUMN IN EMPLOYEE 75 120 CHARACTER(6) COLUMN (NOT NULL) IN CORPDATA.EMP_ACT CHARACTER(6) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE DECIMAL(5,2) COLUMN IN CORPDATA.EMP_ACT COLUMN 116 DATE(10) COLUMN IN CORPDATA.EMP_ACT COLUMN 116 COLUMN 73 VARCHAR(12) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE

Figure 41. Sample PL/I Program Using SQL Statements (Part 5 of 7)

626

DB2 UDB for AS/400 SQL Programming V4R4

5769ST1 V4R4M0 990521 CROSS REFERENCE HIREDATE JOB LASTNAME LASTNAME MAJPROJ MAJPROJ MIDINIT NAME PERCENTAGE PHONENO PRENDATE PRENDATE PRENDATE PROJECT PROJECT PROJECT_NAME PROJNAME PROJNAME PROJNAME PROJNO PROJNO PROJNO PROJNO PROJNO PROJNO PROJNO PRSTAFF PRSTAFF PRSTDATE PRSTDATE RAISE_DATE REPORT_ERROR

Create SQL PL/I Program 74 74 **** 74 26 118 74 28 19 74 26 **** 118 **** **** 34 26 **** 118 26 33 **** 74 **** **** 118 26 118 26 118 16 ****

PLIEX

04/01/98 12:53:36

Page

DATE(10) COLUMN IN CORPDATA.EMPLOYEE CHARACTER(8) COLUMN IN CORPDATA.EMPLOYEE COLUMN 73 VARCHAR(15) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE CHARACTER(6) IN RPT1 CHARACTER(6) COLUMN IN CORPDATA.PROJECT CHARACTER(1) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE CHARACTER(30) IN RPT1 86 DECIMAL(5,2) 51 CHARACTER(4) COLUMN IN CORPDATA.EMPLOYEE DATE(10) IN RPT1 COLUMN 121 DATE(10) COLUMN IN CORPDATA.PROJECT TABLE IN CORPDATA 118 TABLE 119 CHARACTER(36) IN RPT2 VARCHAR(24) IN RPT1 COLUMN 115 122 VARCHAR(24) COLUMN (NOT NULL) IN CORPDATA.PROJECT CHARACTER(6) IN RPT1 86 CHARACTER(6) IN RPT2 COLUMN 72 77 CHARACTER(6) COLUMN (NOT NULL) IN CORPDATA.EMP_ACT COLUMN IN EMP_ACT 115 119 122 COLUMN IN PROJECT 119 CHARACTER(6) COLUMN (NOT NULL) IN CORPDATA.PROJECT DECIMAL(5,2) IN RPT1 DECIMAL(5,2) COLUMN IN CORPDATA.PROJECT DATE(10) IN RPT1 DATE(10) COLUMN IN CORPDATA.PROJECT CHARACTER(10) 121 LABEL 57

Figure 41. Sample PL/I Program Using SQL Statements (Part 6 of 7)

5769ST1 V4R4M0 990521 CROSS REFERENCE RESPEMP RESPEMP RPT1 RPT2 SALARY SALARY SALARY SEX SYSPRINT TOTL_PROJ_COST UPDATE_ERROR WORK_DAYS WORKDEPT No errors found in source 165 Source records processed

Create SQL PL/I Program 26 118 25 32 29 **** 74 74 22 36 **** 17 74 * * * * * CHARACTER(6) CHARACTER(6) STRUCTURE STRUCTURE 132 DECIMAL(8,2) 87 COLUMN 51 51 73 117 DECIMAL(9,2) CHARACTER(1)

PLIEX

04/01/98 12:53:36

Page

IN RPT1 COLUMN (NOT NULL) IN CORPDATA.PROJECT

IN RPT1

COLUMN IN CORPDATA.EMPLOYEE COLUMN IN CORPDATA.EMPLOYEE

DECIMAL(10,2) IN RPT2 LABEL 48 SMALL INTEGER PRECISION(4,0) 117 CHARACTER(3) COLUMN IN CORPDATA.EMPLOYEE E N D O F L I S T I N G * * * * *

Figure 41. Sample PL/I Program Using SQL Statements (Part 7 of 7)

Appendix C. Sample Programs Using DB2 UDB for AS/400 Statements

627

SQL Statements in RPG for AS/400 Programs


5769ST1 V4R4M0 990521 Create SQL RPG Program Source type...............RPG Program name..............CORPDATA/RPGEX Source file...............CORPDATA/SRC Member....................RPGEX To source file............QTEMP/QSQLTEMP Options...................*SRC *XREF Target release............V4R4M0 INCLUDE file..............*LIBL/*SRCFILE Commit....................*CHG Allow copy of data........*YES Close SQL cursor..........*ENDPGM Allow blocking............*READ Delay PREPARE.............*NO Generation level..........10 Printer file..............*LIBL/QSYSPRT Date format...............*JOB Date separator............*JOB Time format...............*HMS Time separator ...........*JOB Replace...................*YES Relational database.......*LOCAL User .....................*CURRENT RDB connect method........*DUW Default Collection........*NONE Package name..............*PGMLIB/*PGM Dynamic User Profile......*USER User Profile...............*NAMING Sort Sequence.............*JOB Language ID...............*JOB IBM SQL flagging..........*NOFLAG ANS flagging..............*NONE Text......................*SRCMBRTXT Source file CCSID.........65535 Job CCSID.................65535 Source member changed on 07/01/96 17:06:17 RPGEX 04/01/98 12:55:22 Page 1

Figure 42. Sample RPG for AS/400 Program Using SQL Statements (Part 1 of 8)

628

DB2 UDB for AS/400 SQL Programming V4R4

5769ST1 V4R4M0 990521 Create SQL RPG Program RPGEX Record *...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 1 H 2 F* File declaration for QPRINT 3 F* 4 FQPRINT O F 132 PRINTER 5 I* 6 I* Structure for report 1. 7 I* 8 1 IRPT1 E DSPROJECT 9 I PROJNAME PROJNM 10 I RESPEMP RESEM 11 I PRSTAFF STAFF 12 I PRSTDATE PRSTD 13 I PRENDATE PREND 14 I MAJPROJ MAJPRJ 15 I* 16 I DS 17 I 1 6 EMPNO 18 I 7 36 NAME 19 I P 37 412SALARY 20 I* 21 I* Structure for report 2. 22 I* 23 IRPT2 DS 24 I 1 6 PRJNUM 25 I 7 42 PNAME 26 I B 43 440EMPCNT 27 I P 45 492PRCOST 28 I* 29 I DS 30 I B 1 20WRKDAY 31 I P 3 62COMMI 32 I 7 16 RDATE 33 I P 17 202PERCNT 34 2 C* 35 C Z-ADD253 WRKDAY 36 C Z-ADD2000.00 COMMI 37 C Z-ADD1.04 PERCNT 38 C MOVEL'1982-06-'RDATE 39 C MOVE '01' RDATE 40 C SETON LR 41 C* 42 C* Update the selected projects by the new percentage. If an 43 C* error occurs during the update, ROLLBACK the changes. 44 C* 45 3 C/EXEC SQL WHENEVER SQLERROR GOTO UPDERR 46 C/END-EXEC 47 C* 48 4 C/EXEC SQL 49 C+ UPDATE CORPDATA/EMPLOYEE 50 C+ SET SALARY = SALARY * :PERCNT 51 C+ WHERE COMM >= :COMMI 52 C/END-EXEC 53 C* 54 C* Commit changes. 55 C* 56 5 C/EXEC SQL COMMIT 57 C/END-EXEC 58 C* 59 C/EXEC SQL WHENEVER SQLERROR GO TO RPTERR 60 C/END-EXEC 61 C* 62 C* Report the updated statistics for each employee assigned to 63 C* selected projects. 64 C* 65 C* Write out the header for report 1.

04/01/98 12:55:22 SEQNBR Last change 100 200 300 400 500 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 2400 2500 2600 2700 2800 2900 3000 3100 3200 3300 3400 3500 3600 3700 3800 3900 3901 02/03/93 4000 4100 4200 4300 4400 4500 4600 4700 4800 4900 5000 5100 5200 5300 5400 5500 5600 5700 5800 5900 6000 6100 6200 6300 6400

Page

Figure 42. Sample RPG for AS/400 Program Using SQL Statements (Part 2 of 8)

Appendix C. Sample Programs Using DB2 UDB for AS/400 Statements

629

5769ST1 V4R4M0 990521 Create SQL RPG Program RPGEX Record *...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 66 C* 67 C EXCPTRECA 68 6 C/EXEC SQL DECLARE C1 CURSOR FOR 69 C+ SELECT DISTINCT PROJNO, EMP_ACT.EMPNO, 70 C+ LASTNAME||', '||FIRSTNME, SALARY 71 C+ FROM CORPDATA/EMP_ACT, CORPDATA/EMPLOYEE 72 C+ WHERE EMP_ACT.EMPNO = EMPLOYEE.EMPNO AND 73 C+ COMM >= :COMMI 74 C+ ORDER BY PROJNO, EMPNO 75 C/END-EXEC 76 C* 77 7 C/EXEC SQL 78 C+ OPEN C1 79 C/END-EXEC 80 C* 81 C* Fetch and write the rows to QPRINT. 82 C* 83 8 C/EXEC SQL WHENEVER NOT FOUND GO TO DONE1 84 C/END-EXEC 85 C SQLCOD DOUNE0 86 C/EXEC SQL 87 9 C+ FETCH C1 INTO :PROJNO, :EMPNO, :NAME, :SALARY 88 C/END-EXEC 89 C EXCPTRECB 90 C END 91 C DONE1 TAG 92 C/EXEC SQL 93 10 C+ CLOSE C1 94 C/END-EXEC 95 C* 96 C* For all project ending at a date later than the raise date 97 C* (i.e. those projects potentially affected by the salary raises) 98 C* generate a report containing the project number, project name, 99 C* the count of employees participating in the project and the 100 C* total salary cost of the project. 101 C* 102 C* Write out the header for report 2. 103 C* 104 C EXCPTRECC 105 11 C/EXEC SQL 106 C+ DECLARE C2 CURSOR FOR 107 C+ SELECT EMP_ACT.PROJNO, PROJNAME, COUNT(*), 108 C+ SUM((DAYS(EMENDATE) - DAYS(EMSTDATE)) * EMPTIME * 109 C+ DECIMAL((SALARY/:WRKDAY),8,2)) 110 C+ FROM CORPDATA/EMP_ACT, CORPDATA/PROJECT, CORPDATA/EMPLOYEE 111 C+ WHERE EMP_ACT.PROJNO = PROJECT.PROJNO AND 112 C+ EMP_ACT.EMPNO = EMPLOYEE.EMPNO AND 113 C+ PRENDATE > :RDATE 114 C+ GROUP BY EMP_ACT.PROJNO, PROJNAME 115 C+ ORDER BY 1 116 C/END-EXEC 117 C* 118 C/EXEC SQL OPEN C2 119 C/END-EXEC 120 C* 121 C* Fetch and write the rows to QPRINT. 122 C* 123 C/EXEC SQL WHENEVER NOT FOUND GO TO DONE2 124 C/END-EXEC 125 C SQLCOD DOUNE0 126 C/EXEC SQL 127 12 C+ FETCH C2 INTO :RPT2 128 C/END-EXEC 129 C EXCPTRECD 130 C END

04/01/98 12:55:22 SEQNBR Last change 6500 6600 6700 02/03/93 6800 02/03/93 6900 02/03/93 7000 02/03/93 7100 02/03/93 7200 02/03/93 7300 02/03/93 7400 7500 7600 7700 7800 7900 8000 8100 8200 8300 8400 8500 8600 8700 8800 8900 9000 9100 9200 9300 9400 9500 9600 9700 9800 9900 10000 10100 10200 10300 10400 10500 10600 10700 10800 10900 11000 11100 11200 11300 11400 11500 11600 11700 11800 11900 12000 12100 12200 12300 12400 12500 12600 12700 12800 12900

Page

Figure 42. Sample RPG for AS/400 Program Using SQL Statements (Part 3 of 8)

630

DB2 UDB for AS/400 SQL Programming V4R4

5769ST1 V4R4M0 990521 Create SQL RPG Program RPGEX Record *...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 131 C DONE2 TAG 132 C/EXEC SQL CLOSE C2 133 C/END-EXEC 134 C RETRN 135 C* 136 C* Error occured while updating table. Inform user and rollback 137 C* changes. 138 C* 139 C UPDERR TAG 140 C EXCPTRECE 141 13 C/EXEC SQL WHENEVER SQLERROR CONTINUE 142 C/END-EXEC 143 C* 144 14 C/EXEC SQL 145 C+ ROLLBACK 146 C/END-EXEC 147 C RETRN 148 C* 149 C* Error occured while generating reports. Inform user and exit. 150 C* 151 C RPTERR TAG 152 C EXCPTRECF 153 C* 154 C* All done. 155 C* 156 C FINISH TAG 157 OQPRINT E 0201 RECA 158 O 45 'REPORT OF PROJECTS AFFEC' 159 O 64 'TED BY EMPLOYEE RAISES' 160 O E 01 RECA 161 O 7 'PROJECT' 162 O 17 'EMPLOYEE' 163 O 32 'EMPLOYEE NAME' 164 O 60 'SALARY' 165 O E 01 RECB 166 O PROJNO 6 167 O EMPNO 15 168 O NAME 50 169 O SALARYL 61 170 O E 22 RECC 171 O 42 'ACCUMULATED STATISTIC' 172 O 54 'S BY PROJECT' 173 O E 01 RECC 174 O 7 'PROJECT' 175 O 56 'NUMBER OF' 176 O 67 'TOTAL' 177 O E 02 RECC 178 O 6 'NUMBER' 179 O 21 'PROJECT NAME' 180 O 56 'EMPLOYEES' 181 O 66 'COST' 182 O E 01 RECD 195 O 57 'CODE=' 183 O PRJNUM 6 184 O PNAME 45 185 O EMPCNTL 54 186 O PRCOSTL 70 187 O E 01 RECE 188 O 28 '*** ERROR Occurred while' 189 O 52 ' updating table. SQLCODE' 190 O 53 '=' 191 O SQLCODL 62 192 O E 01 RECF 193 O 28 '*** ERROR Occurred while' 194 O 52 ' generating reports. SQL'

04/01/98 12:55:22 SEQNBR Last change 13000 13100 13200 13300 02/03/93 13400 13500 13600 13700 13800 13900 14000 14100 14200 14300 14400 14500 14600 02/03/93 14700 14800 14900 15000 15100 15200 15300 15400 15500 15700 15800 15900 16000 16100 16200 16300 16400 16500 16600 16700 16800 16900 17000 17100 17200 17300 17400 17500 17600 17700 17800 17900 18000 18100 18200 19500 18300 18400 18500 18600 18700 18800 18900 19000 19100 19200 19300 19400

Page

Figure 42. Sample RPG for AS/400 Program Using SQL Statements (Part 4 of 8)

5769ST1 V4R4M0 990521 Create SQL RPG Record *...+... 1 ...+... 2 ...+... 3 ...+... 4 196 O SQLCODL * * * * * E N D

Program RPGEX ...+... 5 ...+... 6 ...+... 7 ...+... 8 67 O F S O U R C E * * * * *

04/01/98 12:55:22 SEQNBR Last change 19600

Page

Figure 42. Sample RPG for AS/400 Program Using SQL Statements (Part 5 of 8)

Appendix C. Sample Programs Using DB2 UDB for AS/400 Statements

631

5769ST1 V4R4M0 990521 CROSS REFERENCE Data Names ACTNO BIRTHDATE BONUS COMM COMM COMMI CORPDATA C1 C2 DEPTNO DEPTNO DONE1 DONE2 EDLEVEL EMENDATE EMENDATE EMP_ACT EMP_ACT EMPCNT EMPLOYEE EMPLOYEE EMPNO EMPNO EMPNO EMPNO EMPNO EMPTIME EMPTIME EMSTDATE EMSTDATE FINISH FIRSTNME

Create SQL RPG Program Define 68 48 48 **** 48 31 **** 68 105 8 105 91 131 48 68 **** **** **** 26 **** **** 17 48 **** **** 68 68 **** 68 **** 156 48

RPGEX

04/01/98 12:55:22

Page

Reference SMALL INTEGER PRECISION(4,0) COLUMN (NOT NULL) IN CORPDATA.EMP_ACT DATE(10) COLUMN IN CORPDATA.EMPLOYEE DECIMAL(9,2) COLUMN IN CORPDATA.EMPLOYEE COLUMN 48 68 DECIMAL(9,2) COLUMN IN CORPDATA.EMPLOYEE DECIMAL(7,2) 48 68 COLLECTION 48 68 68 105 105 105 CURSOR 77 86 92 CURSOR 118 126 132 CHARACTER(3) IN RPT1 CHARACTER(3) COLUMN (NOT NULL) IN CORPDATA.PROJECT LABEL 83 LABEL 123 SMALL INTEGER PRECISION(4,0) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE DATE(10) COLUMN IN CORPDATA.EMP_ACT COLUMN 105 TABLE 68 68 105 105 105 105 TABLE IN CORPDATA 68 105 SMALL INTEGER PRECISION(4,0) IN RPT2 TABLE IN CORPDATA 48 68 105 TABLE 68 105 CHARACTER(6) 86 CHARACTER(6) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE COLUMN IN EMP_ACT 68 68 68 105 COLUMN IN EMPLOYEE 68 105 CHARACTER(6) COLUMN (NOT NULL) IN CORPDATA.EMP_ACT DECIMAL(5,2) COLUMN IN CORPDATA.EMP_ACT COLUMN 105 DATE(10) COLUMN IN CORPDATA.EMP_ACT COLUMN 105 LABEL VARCHAR(12) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE

Figure 42. Sample RPG for AS/400 Program Using SQL Statements (Part 6 of 8)

632

DB2 UDB for AS/400 SQL Programming V4R4

5769ST1 V4R4M0 990521 CROSS REFERENCE FIRSTNME HIREDATE JOB LASTNAME LASTNAME MAJPRJ MAJPROJ MIDINIT NAME PERCNT PHONENO PNAME PRCOST PREND PRENDATE PRENDATE PRJNUM PROJECT PROJECT PROJNAME PROJNAME PROJNM PROJNO PROJNO PROJNO PROJNO PROJNO PROJNO PRSTAFF PRSTD PRSTDATE RDATE

Create SQL RPG Program **** 48 48 48 **** 8 105 48 18 33 48 25 27 8 **** 105 24 **** **** **** 105 8 8 **** 68 **** **** 105 105 8 105 32

RPGEX

04/01/98 12:55:22

Page

COLUMN 68 DATE(10) COLUMN IN CORPDATA.EMPLOYEE CHARACTER(8) COLUMN IN CORPDATA.EMPLOYEE VARCHAR(15) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE COLUMN 68 CHARACTER(6) IN RPT1 CHARACTER(6) COLUMN IN CORPDATA.PROJECT CHARACTER(1) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE CHARACTER(30) 86 DECIMAL(7,2) 48 CHARACTER(4) COLUMN IN CORPDATA.EMPLOYEE CHARACTER(36) IN RPT2 DECIMAL(9,2) IN RPT2 DATE(10) IN RPT1 COLUMN 105 DATE(10) COLUMN IN CORPDATA.PROJECT CHARACTER(6) IN RPT2 TABLE IN CORPDATA 105 TABLE 105 COLUMN 105 105 VARCHAR(24) COLUMN (NOT NULL) IN CORPDATA.PROJECT VARCHAR(24) IN RPT1 CHARACTER(6) IN RPT1 86 COLUMN 68 68 CHARACTER(6) COLUMN (NOT NULL) IN CORPDATA.EMP_ACT COLUMN IN EMP_ACT 105 105 105 COLUMN IN PROJECT 105 CHARACTER(6) COLUMN (NOT NULL) IN CORPDATA.PROJECT DECIMAL(5,2) COLUMN IN CORPDATA.PROJECT DATE(10) IN RPT1 DATE(10) COLUMN IN CORPDATA.PROJECT CHARACTER(10) 105

Figure 42. Sample RPG for AS/400 Program Using SQL Statements (Part 7 of 8)

5769ST1 V4R4M0 990521 CROSS REFERENCE RESEM RESPEMP RPTERR RPT1 RPT2 SALARY SALARY SALARY SEX STAFF UPDERR WORKDEPT WRKDAY No errors found in source 196 Source records processed

Create SQL RPG Program 8 105 151 8 23 19 **** 48 48 8 139 48 30

RPGEX

04/01/98 12:55:22

Page

CHARACTER(6) IN RPT1 CHARACTER(6) COLUMN (NOT NULL) IN CORPDATA.PROJECT LABEL 59 STRUCTURE STRUCTURE 126 DECIMAL(9,2) 86 COLUMN 48 48 68 105 DECIMAL(9,2) COLUMN IN CORPDATA.EMPLOYEE CHARACTER(1) COLUMN IN CORPDATA.EMPLOYEE DECIMAL(5,2) IN RPT1 LABEL 45 CHARACTER(3) COLUMN IN CORPDATA.EMPLOYEE SMALL INTEGER PRECISION(4,0) 105 E N D O F L I S T I N G * * * * *

* * * * *

Figure 42. Sample RPG for AS/400 Program Using SQL Statements (Part 8 of 8)

Appendix C. Sample Programs Using DB2 UDB for AS/400 Statements

633

SQL Statements in ILE RPG for AS/400 Programs


5769ST1 V4R4M0 990521 Create SQL ILE RPG Object Source type...............RPG Object name...............CORPDATA/RPGLEEX Source file...............CORPDATA/SRC Member....................*OBJ To source file............QTEMP/QSQLTEMP1 Options...................*XREF Listing option............*PRINT Target release............V4R4M0 INCLUDE file..............*LIBL/*SRCFILE Commit....................*CHG Allow copy of data........*YES Close SQL cursor..........*ENDMOD Allow blocking............*READ Delay PREPARE.............*NO Generation level..........10 Printer file..............*LIBL/QSYSPRT Date format...............*JOB Date separator............*JOB Time format...............*HMS Time separator ...........*JOB Replace...................*YES Relational database.......*LOCAL User .....................*CURRENT RDB connect method........*DUW Default Collection........*NONE Package name..............*OBJLIB/*OBJ Created object type.......*PGM Debugging view............*NONE Dynamic User Profile......*USER User Profile..............*NAMING Sort Sequence.............*JOB Language ID...............*JOB IBM SQL flagging..........*NOFLAG ANS flagging..............*NONE Text......................*SRCMBRTXT Source file CCSID.........65535 Job CCSID.................65535 Source member changed on 07/01/96 15:55:32 RPGLEEX 04/01/98 16:03:02 Page 1

Figure 43. Sample ILE RPG for AS/400 Program Using SQL Statements (Part 1 of 7)

634

DB2 UDB for AS/400 SQL Programming V4R4

5769ST1 V4R4M0 990521 Create SQL ILE RPG Object RPGLEEX Record *...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 1 H 2 F* File declaration for QPRINT 3 F* 4 FQPRINT O F 132 PRINTER 5 D* 6 D* Structure for report 1. 7 D* 8 1 DRPT1 E DS EXTNAME(PROJECT) 9 D* 10 D DS 11 D EMPNO 1 6 12 D NAME 7 36 13 D SALARY 37 41P 2 14 D* 15 D* Structure for report 2. 16 D* 17 DRPT2 DS 18 D PRJNUM 1 6 19 D PNAME 7 42 20 D EMPCNT 43 44B 0 21 D PRCOST 45 49P 2 22 D* 23 D DS 24 D WRKDAY 1 2B 0 25 D COMMI 3 6P 2 26 D RDATE 7 16 27 D PERCNT 17 20P 2 28 * 29 2 C Z-ADD 253 WRKDAY 30 C Z-ADD 2000.00 COMMI 31 C Z-ADD 1.04 PERCNT 32 C MOVEL '1982-06-' RDATE 33 C MOVE '01' RDATE 34 C SETON LR 35 C* 36 C* Update the selected projects by the new percentage. If an 37 C* error occurs during the update, ROLLBACK the changes. 38 C* 39 3 C/EXEC SQL WHENEVER SQLERROR GOTO UPDERR 40 C/END-EXEC 41 C* 42 C/EXEC SQL 43 4 C+ UPDATE CORPDATA/EMPLOYEE 44 C+ SET SALARY = SALARY * :PERCNT 45 C+ WHERE COMM >= :COMMI 46 C/END-EXEC 47 C* 48 C* Commit changes. 49 C* 50 5 C/EXEC SQL COMMIT 51 C/END-EXEC 52 C* 53 C/EXEC SQL WHENEVER SQLERROR GO TO RPTERR 54 C/END-EXEC 55 C* 56 C* Report the updated statistics for each employee assigned to 57 C* selected projects. 58 C* 59 C* Write out the header for report 1. 60 C* 61 C EXCEPT RECA 62 6 C/EXEC SQL DECLARE C1 CURSOR FOR 63 C+ SELECT DISTINCT PROJNO, EMP_ACT.EMPNO, 64 C+ LASTNAME||', '||FIRSTNME, SALARY 65 C+ FROM CORPDATA/EMP_ACT, CORPDATA/EMPLOYEE

04/01/98 16:03:02 Page SEQNBR Last change Comments 100 200 300 400 500 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 2400 2500 2600 2700 2800 2900 3000 3100 3200 3300 3400 3500 3600 3700 3800 3900 4000 4100 4200 4300 4400 4500 4600 4700 4800 4900 5000 5100 5200 5300 5400 5500 5600 5700 5800 5900 6000 6100 6200 6300 6400 6500

Figure 43. Sample ILE RPG for AS/400 Program Using SQL Statements (Part 2 of 7)

Appendix C. Sample Programs Using DB2 UDB for AS/400 Statements

635

5769ST1 V4R4M0 990521 Create SQL ILE RPG Object RPGLEEX Record *...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 66 C+ WHERE EMP_ACT.EMPNO = EMPLOYEE.EMPNO AND 67 C+ COMM >= :COMMI 68 C+ ORDER BY PROJNO, EMPNO 69 C/END-EXEC 70 C* 71 7 C/EXEC SQL 72 C+ OPEN C1 73 C/END-EXEC 74 C* 75 C* Fetch and write the rows to QPRINT. 76 C* 77 8 C/EXEC SQL WHENEVER NOT FOUND GO TO DONE1 78 C/END-EXEC 79 C SQLCOD DOUNE 0 80 C/EXEC SQL 81 9 C+ FETCH C1 INTO :PROJNO, :EMPNO, :NAME, :SALARY 82 C/END-EXEC 83 C EXCEPT RECB 84 C END 85 C DONE1 TAG 86 C/EXEC SQL 87 10 C+ CLOSE C1 88 C/END-EXEC 89 C* 90 C* For all project ending at a date later than the raise date 91 C* (i.e. those projects potentially affected by the salary raises) 92 C* generate a report containing the project number, project name, 93 C* the count of employees participating in the project and the 94 C* total salary cost of the project. 95 C* 96 C* Write out the header for report 2. 97 C* 98 C EXCEPT RECC 99 C/EXEC SQL 100 11 C+ DECLARE C2 CURSOR FOR 101 C+ SELECT EMP_ACT.PROJNO, PROJNAME, COUNT(*), 102 C+ SUM((DAYS(EMENDATE) - DAYS(EMSTDATE)) * EMPTIME * 103 C+ DECIMAL((SALARY/:WRKDAY),8,2)) 104 C+ FROM CORPDATA/EMP_ACT, CORPDATA/PROJECT, CORPDATA/EMPLOYEE 105 C+ WHERE EMP_ACT.PROJNO = PROJECT.PROJNO AND 106 C+ EMP_ACT.EMPNO = EMPLOYEE.EMPNO AND 107 C+ PRENDATE > :RDATE 108 C+ GROUP BY EMP_ACT.PROJNO, PROJNAME 109 C+ ORDER BY 1 110 C/END-EXEC 111 C* 112 C/EXEC SQL OPEN C2 113 C/END-EXEC 114 C* 115 C* Fetch and write the rows to QPRINT. 116 C* 117 C/EXEC SQL WHENEVER NOT FOUND GO TO DONE2 118 C/END-EXEC 119 C SQLCOD DOUNE 0 120 C/EXEC SQL 121 12 C+ FETCH C2 INTO :RPT2 122 C/END-EXEC 123 C EXCEPT RECD 124 C END 125 C DONE2 TAG 126 C/EXEC SQL CLOSE C2 127 C/END-EXEC 128 C RETURN 129 C* 130 C* Error occured while updating table. Inform user and rollback

04/01/98 16:03:02 Page SEQNBR Last change Comments 6600 6700 6800 6900 7000 7100 7200 7300 7400 7500 7600 7700 7800 7900 8000 8100 8200 8300 8400 8500 8600 8700 8800 8900 9000 9100 9200 9300 9400 9500 9600 9700 9800 9900 10000 10100 10200 10300 10400 10500 10600 10700 10800 10900 11000 11100 11200 11300 11400 11500 11600 11700 11800 11900 12000 12100 12200 12300 12400 12500 12600 12700 12800 12900 13000

Figure 43. Sample ILE RPG for AS/400 Program Using SQL Statements (Part 3 of 7)

636

DB2 UDB for AS/400 SQL Programming V4R4

5769ST1 V4R4M0 990521 Create SQL ILE RPG Object RPGLEEX Record *...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 131 C* changes. 132 C* 133 C UPDERR TAG 134 C EXCEPT RECE 135 13 C/EXEC SQL WHENEVER SQLERROR CONTINUE 136 C/END-EXEC 137 C* 138 14 C/EXEC SQL 139 C+ ROLLBACK 140 C/END-EXEC 141 C RETURN 142 C* 143 C* Error occured while generating reports. Inform user and exit. 144 C* 145 C RPTERR TAG 146 C EXCEPT RECF 147 C* 148 C* All done. 149 C* 150 C FINISH TAG 151 OQPRINT E RECA 0 2 01 152 O 42 'REPORT OF PROJECTS AFFEC' 153 O 64 'TED BY EMPLOYEE RAISES' 154 O E RECA 0 1 155 O 7 'PROJECT' 156 O 17 'EMPLOYEE' 157 O 32 'EMPLOYEE NAME' 158 O 60 'SALARY' 159 O E RECB 0 1 160 O PROJNO 6 161 O EMPNO 15 162 O NAME 50 163 O SALARY L 61 164 O E RECC 2 2 165 O 42 'ACCUMULATED STATISTIC' 166 O 54 'S BY PROJECT' 167 O E RECC 0 1 168 O 7 'PROJECT' 169 O 56 'NUMBER OF' 170 O 67 'TOTAL' 171 O E RECC 0 2 172 O 6 'NUMBER' 173 O 21 'PROJECT NAME' 174 O 56 'EMPLOYEES' 175 O 66 'COST' 176 O E RECD 0 1 177 O PRJNUM 6 178 O PNAME 45 179 O EMPCNT L 54 180 O PRCOST L 70 181 O E RECE 0 1 182 O 28 '*** ERROR Occurred while' 183 O 52 ' updating table. SQLCODE' 184 O 53 '=' 185 O SQLCOD L 62 186 O E RECF 0 1 187 O 28 '*** ERROR Occurred while' 188 O 52 ' generating reports. SQL' 189 O 57 'CODE=' 190 O SQLCOD L 67 * * * * * E N D O F S O U R C E * * * * *

04/01/98 16:03:02 Page SEQNBR Last change Comments 13100 13200 13300 13400 13500 13600 13700 13800 13900 14000 14100 14200 14300 14400 14500 14600 14700 14800 14900 15000 15100 15200 15300 15400 15500 15600 15700 15800 15900 16000 16100 16200 16300 16400 16500 16600 16700 16800 16900 17000 17100 17200 17300 17400 17500 17600 17700 17800 17900 18000 18100 18200 18300 18400 18500 18600 18700 18800 18900 19000

Figure 43. Sample ILE RPG for AS/400 Program Using SQL Statements (Part 4 of 7)

Appendix C. Sample Programs Using DB2 UDB for AS/400 Statements

637

5769ST1 V4R4M0 990521 CROSS REFERENCE Data Names ACTNO BIRTHDATE BONUS COMM COMM COMMI CORPDATA C1 C2 DEPTNO DEPTNO DONE1 DONE1 DONE2 DONE2 EDLEVEL EMENDATE EMENDATE EMP_ACT EMP_ACT EMPCNT EMPLOYEE EMPLOYEE EMPNO EMPNO EMPNO EMPNO EMPNO EMPTIME EMPTIME EMSTDATE EMSTDATE FINISH

Create SQL ILE RPG Object Define 62 42 42 **** 42 25 **** 62 99 8 99 85 **** 125 **** 42 62 **** **** **** 20 **** **** 11 42 **** **** 62 62 **** 62 **** 150

RPGLEEX

04/01/98 16:03:02

Page

Reference SMALL INTEGER PRECISION(4,0) COLUMN (NOT NULL) IN CORPDATA.EMP_ACT DATE(10) COLUMN IN CORPDATA.EMPLOYEE DECIMAL(9,2) COLUMN IN CORPDATA.EMPLOYEE COLUMN 42 62 DECIMAL(9,2) COLUMN IN CORPDATA.EMPLOYEE DECIMAL(7,2) 42 62 COLLECTION 42 62 62 99 99 99 CURSOR 71 80 86 CURSOR 112 120 126 CHARACTER(3) IN RPT1 CHARACTER(3) COLUMN (NOT NULL) IN CORPDATA.PROJECT LABEL 77 LABEL 117 SMALL INTEGER PRECISION(4,0) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE DATE(10) COLUMN IN CORPDATA.EMP_ACT COLUMN 99 TABLE 62 62 99 99 99 99 TABLE IN CORPDATA 62 99 SMALL INTEGER PRECISION(4,0) IN RPT2 TABLE IN CORPDATA 42 62 99 TABLE 62 99 CHARACTER(6) DBCS-open 80 CHARACTER(6) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE COLUMN IN EMP_ACT 62 62 62 99 COLUMN IN EMPLOYEE 62 99 CHARACTER(6) COLUMN (NOT NULL) IN CORPDATA.EMP_ACT DECIMAL(5,2) COLUMN IN CORPDATA.EMP_ACT COLUMN 99 DATE(10) COLUMN IN CORPDATA.EMP_ACT COLUMN 99

Figure 43. Sample ILE RPG for AS/400 Program Using SQL Statements (Part 5 of 7)

638

DB2 UDB for AS/400 SQL Programming V4R4

5769ST1 V4R4M0 990521 CROSS REFERENCE FIRSTNME FIRSTNME HIREDATE JOB LASTNAME LASTNAME MAJPROJ MAJPROJ MIDINIT NAME PERCNT PHONENO PNAME PRCOST PRENDATE PRENDATE PRENDATE PRJNUM PROJECT PROJECT PROJNAME PROJNAME PROJNAME PROJNO PROJNO PROJNO PROJNO PROJNO PROJNO PRSTAFF PRSTAFF PRSTDATE PRSTDATE

Create SQL ILE RPG Object 42 **** 42 42 42 **** 8 99 42 12 27 42 19 21 8 **** 99 18 **** **** 8 **** 99 8 **** 62 **** **** 99 8 99 8 99

RPGLEEX

04/01/98 16:03:02

Page

VARCHAR(12) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE COLUMN 62 DATE(10) COLUMN IN CORPDATA.EMPLOYEE CHARACTER(8) COLUMN IN CORPDATA.EMPLOYEE VARCHAR(15) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE COLUMN 62 CHARACTER(6) IN RPT1 CHARACTER(6) COLUMN IN CORPDATA.PROJECT CHARACTER(1) COLUMN (NOT NULL) IN CORPDATA.EMPLOYEE CHARACTER(30) DBCS-open 80 DECIMAL(7,2) 42 CHARACTER(4) COLUMN IN CORPDATA.EMPLOYEE CHARACTER(36) DBCS-open IN RPT2 DECIMAL(9,2) IN RPT2 DATE(8) IN RPT1 COLUMN 99 DATE(10) COLUMN IN CORPDATA.PROJECT CHARACTER(6) DBCS-open IN RPT2 TABLE IN CORPDATA 99 TABLE 99 VARCHAR(24) IN RPT1 COLUMN 99 99 VARCHAR(24) COLUMN (NOT NULL) IN CORPDATA.PROJECT CHARACTER(6) IN RPT1 80 COLUMN 62 62 CHARACTER(6) COLUMN (NOT NULL) IN CORPDATA.EMP_ACT COLUMN IN EMP_ACT 99 99 99 COLUMN IN PROJECT 99 CHARACTER(6) COLUMN (NOT NULL) IN CORPDATA.PROJECT DECIMAL(5,2) IN RPT1 DECIMAL(5,2) COLUMN IN CORPDATA.PROJECT DATE(8) IN RPT1 DATE(10) COLUMN IN CORPDATA.PROJECT

Figure 43. Sample ILE RPG for AS/400 Program Using SQL Statements (Part 6 of 7)

5769ST1 V4R4M0 990521 CROSS REFERENCE RDATE RESPEMP RESPEMP RPTERR RPTERR RPT1 RPT2 SALARY SALARY SALARY SEX UPDERR UPDERR WORKDEPT WRKDAY

Create SQL ILE RPG Object 26 8 99 145 **** 8 17 13 **** 42 42 133 **** 42 24

RPGLEEX

04/01/98 16:03:02

Page

CHARACTER(10) DBCS-open 99 CHARACTER(6) IN RPT1 CHARACTER(6) COLUMN (NOT NULL) IN CORPDATA.PROJECT LABEL 53 STRUCTURE STRUCTURE 120 DECIMAL(9,2) 80 COLUMN 42 42 62 99 DECIMAL(9,2) COLUMN IN CORPDATA.EMPLOYEE CHARACTER(1) COLUMN IN CORPDATA.EMPLOYEE LABEL 39 CHARACTER(3) COLUMN IN CORPDATA.EMPLOYEE SMALL INTEGER PRECISION(4,0) 99 E N D O F L I S T I N G * * * * *

No errors found in source 190 Source records processed * * * * *

Figure 43. Sample ILE RPG for AS/400 Program Using SQL Statements (Part 7 of 7)

Appendix C. Sample Programs Using DB2 UDB for AS/400 Statements

639

SQL Statements in REXX Programs


Record 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 *...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 /*********************************************************************/ /* A sample program which updates the salaries for those employees */ /* whose current commission total is greater than or equal to the */ /* value of COMMISSION. The salaries of those who qualify are */ /* increased by the value of PERCENTAGE, retroactive to RAISE_DATE. */ /* A report is generated and dumped to the display which shows the */ /* projects which these employees have contributed to, ordered by */ /* project number and employee ID. A second report shows each */ /* project having an end date occurring after RAISE DATE (i.e. is */ /* potentially affected by the retroactive raises) with its total */ /* salary expenses and a count of employees who contributed to the */ /* project. */ /*********************************************************************/ /* Initialize RC variable */ RC = 0 /* Initialize HV for program usage */ COMMISSION = 2000.00; PERCENTAGE = 1.04; RAISE_DATE = '1982-06-01'; WORK_DAYS = 253; /* Create the output file to dump the 2 reports. Perform an OVRDBF */ /* to allow us to use the SAY REXX command to write to the output */ /* file. */ ADDRESS '*COMMAND', 'DLTF FILE(CORPDATA/REPORTFILE)' ADDRESS '*COMMAND', 'CRTPF FILE(CORPDATA/REPORTFILE) RCDLEN(80)' ADDRESS '*COMMAND', 'OVRDBF FILE(STDOUT) TOFILE(CORPDATA/REPORTFILE) MBR(REPORTFILE)' /* Update the selected employee's salaries by the new percentage. */ /* If an error occurs during the update, ROLLBACK the changes. */ 3 SIGNAL ON ERROR ERRLOC = 'UPDATE_ERROR' UPDATE_STMT = 'UPDATE CORPDATA/EMPLOYEE ', 'SET SALARY = SALARY * ? ', 'WHERE COMM >= ? ' EXECSQL, 'PREPARE S1 FROM :UPDATE_STMT' 4 EXECSQL, 'EXECUTE S1 USING :PERCENTAGE,', ' :COMMISSION ' /* Commit changes */ 5 EXECSQL, 'COMMIT'

Figure 44. Sample REXX Procedure Using SQL Statements (Part 1 of 4)

640

DB2 UDB for AS/400 SQL Programming V4R4

Record 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120

*...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ERRLOC = 'REPORT_ERROR' /* Report the updated statistics for each project supported by one */ /* of the selected employees. */ /* Write out the header SAY ' ' SAY ' ' SAY ' ' SAY ' REPORT OF SAY ' ' SAY 'PROJECT EMPID SAY '------- ----SAY ' ' SELECT_STMT = for Report 1 */

PROJECTS AFFECTED BY EMPLOYEE RAISES' EMPLOYEE NAME ------------SALARY' ------' ', ', ', ', ', '

EXECSQL, 'PREPARE S2 FROM :SELECT_STMT' 6 EXECSQL, 'DECLARE C1 CURSOR FOR S2' 7 EXECSQL, 'OPEN C1 USING :COMMISSION'

'SELECT DISTINCT PROJNO, EMP_ACT.EMPNO, ' LASTNAME||'', ''||FIRSTNME, SALARY 'FROM CORPDATA/EMP_ACT, CORPDATA/EMPLOYEE 'WHERE EMP_ACT.EMPNO = EMPLOYEE.EMPNO AND ' COMM >= ? 'ORDER BY PROJNO, EMPNO

/* Handle the FETCH errors and warnings inline */ SIGNAL OFF ERROR /* Fetch all of the rows */ DO UNTIL (SQLCODE <> 0) 9 EXECSQL, 'FETCH C1 INTO :RPT1.PROJNO, :RPT1.EMPNO,', ' :RPT1.NAME, :RPT1.SALARY ' /* Process any errors that may have occurred. Continue so that /* we close the cursor for any warnings. IF SQLCODE < 0 THEN SIGNAL ERROR */ */

/* Stop the loop when we hit the EOF. Don't try to print out the */ /* fetched values. */ 8 IF SQLCODE = 100 THEN LEAVE /* Print out the fetched row */ SAY RPT1.PROJNO ' ' RPT1.EMPNO ' END; 10 EXECSQL, 'CLOSE C1' /* /* /* /* /* For all projects ending at a date later than 'raise_date' (i.e. those projects potentially affected by the salary raises) generate a report containing the project number, project name the count of employees participating in the project and the total salary cost of the project. */ */ */ */ */ ' RPT1.NAME ' ' RPT1.SALARY

/* Write out the header for Report 2 */ SAY ' ' SAY ' ' SAY ' ' SAY ' ACCUMULATED STATISTICS BY PROJECT' SAY ' ' SAY 'PROJECT PROJECT NAME SAY 'NUMBER SAY '------- -----------SAY ' '

NUMBER OF EMPLOYEES ---------

TOTAL' COST' -----'

Figure 44. Sample REXX Procedure Using SQL Statements (Part 2 of 4)

Appendix C. Sample Programs Using DB2 UDB for AS/400 Statements

641

Record 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 190 191 192 193 194 195

*...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 /* Go to the common error handler */ SIGNAL ON ERROR SELECT_STMT = 'SELECT EMP_ACT.PROJNO, PROJNAME, COUNT(*), ', ' SUM( (DAYS(EMENDATE) - DAYS(EMSTDATE)) * EMPTIME * ', ' DECIMAL(( SALARY / ? ),8,2) ) ', 'FROM CORPDATA/EMP_ACT, CORPDATA/PROJECT, CORPDATA/EMPLOYEE', 'WHERE EMP_ACT.PROJNO = PROJECT.PROJNO AND ', ' EMP_ACT.EMPNO = EMPLOYEE.EMPNO AND ', ' PRENDATE > ? ', 'GROUP BY EMP_ACT.PROJNO, PROJNAME ', 'ORDER BY 1 ' EXECSQL, 'PREPARE S3 FROM :SELECT_STMT' 11 EXECSQL, 'DECLARE C2 CURSOR FOR S3' EXECSQL, 'OPEN C2 USING :WORK_DAYS, :RAISE_DATE' /* Handle the FETCH errors and warnings inline */ SIGNAL OFF ERROR /* Fetch all of the rows */ DO UNTIL (SQLCODE <> 0) 12 EXECSQL, 'FETCH C2 INTO :RPT2.PROJNO, :RPT2.PROJNAME, ', ' :RPT2.EMPCOUNT, :RPT2.TOTAL_COST ' /* Process any errors that may have occurred. Continue so that /* we close the cursor for any warnings. IF SQLCODE < 0 THEN SIGNAL ERROR */ */

/* Stop the loop when we hit the EOF. Don't try to print out the */ /* fetched values. */ IF SQLCODE = 100 THEN LEAVE /* Print out the fetched row */ SAY RPT2.PROJNO ' ' RPT2.PROJNAME ' ' , RPT2.EMPCOUNT ' ' RPT2.TOTAL_COST END; EXECSQL, 'CLOSE C2' /* Delete the OVRDBF so that we will continue writing to the output /* display. ADDRESS '*COMMAND', 'DLTOVR FILE(STDOUT)' /* Leave procedure with a successful or warning RC */ EXIT RC /* Error occurred while updating the table or generating the */ /* reports. If the error occurred on the UPDATE, rollback all of */ /* the changes. If it occurred on the report generation, display the */ /* REXX RC variable and the SQLCODE and exit the procedure. */ ERROR: 13 SIGNAL OFF ERROR /* Determine the error location */ SELECT /* When the error occurred on the UPDATE statement */ WHEN ERRLOC = 'UPDATE_ERROR' THEN DO SAY '*** ERROR Occurred while updating table.', 'SQLCODE = ' SQLCODE 14 EXECSQL, 'ROLLBACK' END */ */

Figure 44. Sample REXX Procedure Using SQL Statements (Part 3 of 4)

642

DB2 UDB for AS/400 SQL Programming V4R4

196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211

/* When the error occurred during the report generation */ WHEN ERRLOC = 'REPORT_ERROR' THEN SAY '*** ERROR Occurred while generating reports. ', 'SQLCODE = ' SQLCODE OTHERWISE SAY '*** Application procedure logic error occurred ' END /* Delete the OVRDBF so that we will continue writing to the /* output display. ADDRESS '*COMMAND', 'DLTOVR FILE(STDOUT)' /* Return the error RC received from SQL. */ EXIT RC * * * * * E N D O F S O U R C E */ */

* * * * *

Figure 44. Sample REXX Procedure Using SQL Statements (Part 4 of 4)

Report Produced by Sample Programs


The following report is produced by each of the preceding sample programs.
REPORT OF PROJECTS AFFECTED BY RAISES PROJECT AD3100 AD3110 AD3111 AD3113 IF1000 IF1000 IF2000 IF2000 MA2100 MA2100 MA2110 MA2111 MA2111 MA2112 OP1000 OP1010 OP1010 OP2010 OP2010 OP2012 PL2100 EMPID 000010 000070 000240 000270 000030 000140 000030 000140 000010 000110 000010 000200 000220 000150 000050 000090 000280 000050 000100 000330 000020 EMPLOYEE NAME HAAS, CHRISTINE PULASKI, EVA MARINO, SALVATORE PEREZ, MARIA KWAN, SALLY NICHOLLS, HEATHER KWAN, SALLY NICHOLLS, HEATHER HAAS, CHRISTINE LUCCHESSI, VICENZO HAAS, CHRISTINE BROWN, DAVID LUTZ, JENNIFER ADAMSON, BRUCE GEYER, JOHN HENDERSON, EILEEN SCHNEIDER, ETHEL GEYER, JOHN SPENSER, THEODORE LEE, WING THOMPSON, MICHAEL SALARY 54860.00 37616.80 29910.40 28475.20 39780.00 29556.80 39780.00 29556.80 54860.00 48360.00 54860.00 28849.60 31033.60 26291.20 41782.00 30940.00 27300.00 41782.00 27196.00 26384.80 42900.00

ACCUMULATED STATISTICS BY PROJECT PROJECT NUMBER AD3100 AD3110 AD3111 AD3112 AD3113 IF1000 IF2000 MA2100 MA2110 MA2111 MA2112 PROJECT NAME ADMIN SERVICES GENERAL ADMIN SYSTEMS PAYROLL PROGRAMMING PERSONNEL PROGRAMMING ACCOUNT PROGRAMMING QUERY SERVICES USER EDUCATION WELD LINE AUTOMATION W L PROGRAMMING W L PROGRAM DESIGN W L ROBOT DESIGN NUMBER OF EMPLOYEES 1 1 8 9 14 4 5 2 1 3 6 TOTAL COST 19623.11 58877.28 72806.74 28845.70 72114.52 52205.66 55212.61 114001.52 85864.68 93729.24 166945.84

Appendix C. Sample Programs Using DB2 UDB for AS/400 Statements

643

MA2113 OP1000 OP1010 OP2010 OP2011 OP2012 OP2013 PL2100

W L PROD CONT PROGS OPERATION SUPPORT OPERATION SYSTEMS SUPPORT SCP SYSTEMS SUPPORT APPLICATIONS SUPPORT DB/DC SUPPORT WELD LINE PLANNING

5 1 5 2 2 2 2 1

71509.11 16348.86 167828.76 91612.62 31224.60 41294.88 37311.12 43576.92

644

DB2 UDB for AS/400 SQL Programming V4R4

Appendix D. DB2 UDB for AS/400 CL Command Descriptions


This appendix contains the syntax diagrams referred to and used in this guide and the DB2 UDB for AS/400 SQL Reference book.

CRTSQLCBL (Create Structured Query Language COBOL) Command


Job: B,I Pgm: B,I
PGM( library-name/

REXX: B,I
*CURLIB/

Exec
program-name )

CRTSQLCBL

*LIBL/ SRCFILE( *CURLIB/ library-name/

QLBLSRC source-file-name

(1) *PGM source-file-member-name

SRCMBR(

OPTION(

OPTION Details

) TGTRLS(

*CURRENT *PRV VxRxMx

*LIBL/ INCFILE( *CURLIB/ library-name/

*SRCFILE source-file-name

COMMIT(

*UR *CHG *ALL *RS *CS *NONE *NC *RR

CLOSQLCSR( )

*ENDPGM *ENDSQL *ENDJOB

ALWCPYDTA(

*OPTIMIZE *YES *NO

ALWBLK(

*ALLREAD *NONE *READ

Copyright IBM Corp. 1997, 1999

645

CRTSQLCBL
*NO *YES 10 severity-level

DLYPRP(

GENLVL(

DATFMT(

*JOB *USA *ISO *EUR *JIS *MDY *DMY *YMD *JUL

DATSEP(

*JOB '/' '.' ',' '-' ' ' *BLANK

TIMFMT(

*HMS *USA *ISO *EUR *JIS

TIMSEP(

*JOB ':' '.' ',' ' ' *BLANK

REPLACE(

*YES *NO

RDB(

*LOCAL relational-database-name *NONE

USER(

*CURRENT user-name

PASSWORD(

*NONE password

RDBCNNMTH(

*DUW *RUW

DFTRDBCOL(

*NONE collection-name

DYNDFTCOL(

*NO *YES

*PGMLIB/ SQLPKG( library-name/

*PGM package-name

646

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCBL
*NAMING *LIBL

SQLPATH(

collection-name

SAAFLAG(

*NOFLAG *FLAG

FLAGSTD(

*NONE *ANS

*LIBL/ PRTFILE( *CURLIB/ library-name/

QSYSPRT printer-file-name

SRTSEQ(

*JOB *JOBRUN *LANGIDUNQ *LANGIDSHR *HEX *LIBL/ table-name *CURLIB/ library-name/

LANGID(

*JOB *JOBRUN language-ID

USRPRF(

*NAMING *OWNER *USER

DYNUSRPRF(

*USER *OWNER

QTEMP/ TOSRCFILE( *LIBL/ *CURLIB/ library-name/

QSQLTEMP source-file-name

TEXT(

*SRCMBRTXT *BLANK 'description'

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

647

CRTSQLCBL
OPTION Details:
*NOSRC *NOSOURCE *SOURCE *SRC *NOXREF *XREF *GEN *NOGEN *JOB *PERIOD *SYSVAL *COMMA *NOLSTDBG *LSTDBG *QUOTESQL *APOSTSQL

*QUOTE *APOST

*SYS *SQL

*NOSECLVL *SECLVL

Notes: 1. All parameters preceding this point can be specied in positional form.

Purpose
The Create Structured Query Language COBOL (CRTSQLCBL) command calls the Structured Query Language (SQL) precompiler, which precompiles COBOL source containing SQL statements, produces a temporary source member, and then optionally calls the COBOL compiler to compile the program.

Parameters
PGM Species the qualied name of the compiled program. The name of the compiled COBOL program can be qualied by one of the following library values: *CURLIB The compiled COBOL program is created in the current library for the job. If no library is specied as the current library for the job, the QGPL library is used. library name: Specify the name of the library where the compiled COBOL program is created.

program-name: Specify the name of the compiled COBOL program.


SRCFILE Species the qualied name of the source le that contains the COBOL source with SQL statements. The name of the source le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used.

library-name: Specify the name of the library to be searched.


QLBLSRC: If a COBOL source le name is not specied, the IBM-supplied source le QLBLSRC contains the COBOL source.

648

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCBL
source-le-name: Specify the name of the source le that contains the COBOL source. This source le should have a record length of 92 bytes. The source le can be a database le, device le, or an inline data le.
SRCMBR Species the name of the source le member that contains the COBOL source. This parameter is specied only if the source le name in the SRCFILE parameter is a database le. If this parameter is not specied, the PGM name specied on the PGM parameter is used. *PGM: Species that the COBOL source is in the member of the source le that has the same name as that specied on the PGM parameter.

source-le-member-name: Specify the name of the member that contains the COBOL source.
OPTION Species whether one or more of the following options are used when the COBOL source is precompiled. If an option is specied more than once, or if two options conict, the last option specied is used. Element 1: Source Listing Options *NOSOURCE or *NOSRC: A source printout is not produced by the precompiler unless errors are detected during precompile or create package. *SOURCE or *SRC: The precompiler produces a source printout consisting of COBOL source input. Element 2: Cross-Reference Options *NOXREF: The precompiler does not cross-reference names. *XREF: The precompiler cross-references items in the program to the statement numbers in the program that refer to those items. Element 3: Program Creation Options *GEN: The compiler creates a program that can run after the program is compiled. An SQL package object is created if a relational database name is specied on the RDB parameter. *NOGEN: The precompiler does not call the COBOL compiler, and a program and SQL package are not created. Element 4: Decimal Point Options *JOB: The value used as the decimal point for numeric constants in SQL is the representation of decimal point specied for the job at precompile time. *SYSVAL: The value used as the decimal point for numeric constants in SQL statements is the QDECFMT system value. Note: If QDECFMT species that the value used as the decimal point is a comma, any numeric constants in lists (such as in the SELECT clause or the VALUES clause) must be separated by a comma followed by a

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

649

CRTSQLCBL
blank. For example, VALUES(1,1, 2,23, 4,1) is equivalent to VALUES(1.1,2.23,4.1) in which the decimal point is a period. *PERIOD: The value used as the decimal point for numeric constants in SQL statements is a period. *COMMA: The value used as the decimal point for numeric constants in SQL statements is a comma. Note: Any numeric constants in lists (such as in the SELECT clause or the VALUES clause) must be separated by a comma followed by a blank. For example, VALUES(1,1, 2,23, 4,1) is equivalent to VALUES(1.1,2.23,4.1) where the decimal point is a period. Element 5: String Delimiter Options *QUOTESQL: A double quote (") is the string delimiter in the SQL statements. *APOSTSQL: An apostrophe (') is the string delimiter in the SQL statements. Element 6: Literal Options *QUOTE: A double quote (") is used for non-numeric literals and Boolean literals in the COBOL statements. *APOST: An apostrophe (') is used for non-numeric literals and Boolean literals in the COBOL statements. Element 7: Naming Convention Option *SYS: The system naming convention (library-name/le-name) is used. *SQL: The SQL naming convention (collection-name.table-name) is used. When creating a program on a remote database other than an AS/400 system, *SQL must be specied as the naming convention. Element 8: Second-Level Message Text Option *NOSECLVL: Second-level text descriptions are not added to the listing. *SECLVL: Second-level text with replacement data is added for all messages on the listing. Element 9: Debug Listing View *NOLSTDBG: Error and debug information is not generated. *LSTDBG: The SQL precompiler generates a listing view, and error and debug information required for this view. You can use *LSTDBG only if you are using the CODE/400 product to compile your program. TGTRLS Species the release of the operating system on which the user intends to use the object being created.

650

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCBL
In the examples given for the *CURRENT and *PRV values, and when specifying the release-level value, the format VxRxMx is used to specify the release, where Vx is the version, Rx is the release, and Mx is the modication level. For example, V2R3M0 is version 2, release 3, modication level 0. *CURRENT: The object is to be used on the release of the operating system currently running on the users system. For example, if V2R3M5 is running on the system, *CURRENT means the user intends to use the object on a system with V2R3M5 installed. The user can also use the object on a system with any subsequent release of the operating system installed. Note: If V2R3M5 is running on the system, and the object is to be used on a system with V2R3M0 installed, specify TGTRLS(V2R3M0) not TGTRLS(*CURRENT). *PRV: The object is to be used on the previous release with modication level 0 of the operating system. For example, if V2R3M5 is running on the users system, *PRV means the user intends to use the object on a system with V2R2M0 installed. The user can also use the object on a system with any subsequent release of the operating system installed.

release-level: Specify the release in the format VxRxMx. The object can be used on a system with the specied release or with any subsequent release of the operating system installed.
Valid values depend on the current version, release, and modication level, and they change with each new release. If you specify a release-level which is earlier than the earliest release level supported by this command, an error message is sent indicating the earliest supported release. INCFILE Species the qualied name of the source le that contains members included in the program with any SQL INCLUDE statement. The name of the source le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library to be searched. *SRCFILE: The qualied source le specied in the SRCFILE parameter contains the source le member(s) specied on any SQL INCLUDE statement.

source-le-name: Specify the name of the source le that contains the source le member(s) specied on any SQL INCLUDE statement. The record length of the source le specied here must be no less than the record length of the source le specied for the SRCFILE parameter.
COMMIT Species whether SQL statements in the compiled program are run under commitment control. Files referred to in the host language source are not affected by this option. Only SQL tables, SQL views, and SQL packages referred to in SQL statements are affected. Note: Files referenced in the COBOL source are not affected by this option.
Appendix D. DB2 UDB for AS/400 CL Command Descriptions

651

CRTSQLCBL
*CHG or *UR: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs can be seen. *ALL or *RS: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows selected, updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs cannot be seen. *CS: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows updated, deleted, and inserted are locked until the end of the unit of work (transaction). A row that is selected, but not updated, is locked until the next row is selected. Uncommitted changes in other jobs cannot be seen. *NONE or *NC: Species that commitment control is not used. Uncommitted changes in other jobs can be seen. If the SQL DROP COLLECTION statement is included in the program, *NONE or *NC must be used. If a relational database is specied on the RDB parameter and the relational database is on a system that is not on an AS/400, *NONE or *NC cannot be specied. *RR: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows selected, updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs cannot be seen. All tables referred to in SELECT, UPDATE, DELETE, and INSERT statements are locked exclusively until the end of the unit of work (transaction). CLOSQLCSR Species when SQL cursors are implicitly closed, SQL prepared statements are implicitly discarded, and LOCK TABLE locks are released. SQL cursors are explicitly closed when you issue the CLOSE, COMMIT, or ROLLBACK (without HOLD) SQL statements. *ENDPGM: SQL cursors are closed and SQL prepared statements are discarded when the program ends. LOCK TABLE locks are released when the rst SQL program on the call stack ends. *ENDSQL: SQL cursors remain open between calls and can be fetched without running another SQL OPEN. One of the programs higher on the call stack must have run at least one SQL statement. SQL cursors are closed, SQL prepared statements are discarded, and LOCK TABLE locks are released when the rst SQL program on the call stack ends. If *ENDSQL is specied for a program that is the rst SQL program called (the rst SQL program on the call stack), the program is treated as if *ENDPGM was specied. *ENDJOB: SQL cursors remain open between calls and can be fetched without running another SQL OPEN. The programs higher on the call stack do not need to have run SQL statements. SQL cursors are left open, SQL prepared statements are preserved, and LOCK TABLE locks are held when the rst SQL program on the call stack ends. SQL cursors are closed, SQL prepared statements are discarded, and LOCK TABLE locks are released when the job ends.

652

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCBL
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ALWCPYDTA Species whether a copy of the data can be used in a SELECT statement. *OPTIMIZE: The system determines whether to use the data retrieved directly from the database or to use a copy of the data. The decision is based on which method provides the best performance. If COMMIT is *CHG or *CS and ALWBLK is not *ALLREAD, or if COMMIT is *ALL or *RR, then a copy of the data is used only when it is necessary to run a query. *YES: A copy of the data is used only when necessary. *NO: A copy of the data is not allowed. If a temporary copy of the data is required to perform the query, an error message is returned. ALWBLK Species whether the database manager can use record blocking, and the extent to which blocking can be used for read-only cursors. *ALLREAD: Rows are blocked for read-only cursors if *NONE or *CHG is specied on the COMMIT parameter. All cursors in a program that are not explicitly able to be updated are opened for read-only processing even though EXECUTE or EXECUTE IMMEDIATE statements may be in the program. Specifying *ALLREAD: v Allows record blocking under commitment control level *CHG in addition to the blocking allowed for *READ. v Can improve the performance of almost all read-only cursors in programs, but limits queries in the following ways: The Rollback (ROLLBACK) command, a ROLLBACK statement in host languages, or the ROLLBACK HOLD SQL statement does not reposition a read-only cursor when *ALLREAD is specied. Dynamic running of a positioned UPDATE or DELETE statement (for example, using EXECUTE IMMEDIATE), cannot be used to update a row in a cursor unless the DECLARE statement for the cursor includes the FOR UPDATE clause. *NONE: Rows are not blocked for retrieval of data for cursors. Specifying *NONE: v Guarantees that the data retrieved is current. v May reduce the amount of time required to retrieve the rst row of data for a query. v Stops the database manager from retrieving a block of data rows that is not used by the program when only the rst few rows of a query are retrieved before the query is closed. v Can degrade the overall performance of a query that retrieves a large number of rows. *READ: Records are blocked for read-only retrieval of data for cursors when: v *NONE is specied on the COMMIT parameter, which indicates that commitment control is not used. v The cursor is declared with a FOR READ ONLY clause or there are no dynamic statements that could run a positioned UPDATE or DELETE statement for the cursor.
Appendix D. DB2 UDB for AS/400 CL Command Descriptions

653

CRTSQLCBL
| | Specifying *READ can improve the overall performance of queries that meet the above conditions and retrieve a large number of records. DLYPRP Species whether the dynamic statement validation for a PREPARE statement is delayed until an OPEN, EXECUTE, or DESCRIBE statement is run. Delaying validation improves performance by eliminating redundant validation. *NO: Dynamic statement validation is not delayed. When the dynamic statement is prepared, the access plan is validated. When the dynamic statement is used in an OPEN or EXECUTE statement, the access plan is revalidated. Because the authority or the existence of objects referred to by the dynamic statement may change, you must still check the SQLCODE or SQLSTATE after issuing the OPEN or EXECUTE statement to ensure that the dynamic statement is still valid. *YES: Dynamic statement validation is delayed until the dynamic statement is used in an OPEN, EXECUTE, or DESCRIBE SQL statement. When the dynamic statement is used, the validation is completed and an access plan is built. If you specify *YES on this parameter, you should check the SQLCODE and SQLSTATE after running an OPEN, EXECUTE, or DESCRIBE statement to ensure that the dynamic statement is valid. Note: If you specify *YES, performance is not improved if the INTO clause is used on the PREPARE statement or if a DESCRIBE statement uses the dynamic statement before an OPEN is issued for the statement. GENLVL Species the severity level at which the create operation fails. If errors occur that have a severity level greater than or equal to this value, the operation ends. 10: The default severity level is 10.

severity-level: Specify a value ranging from 0 through 40.


DATFMT Species the format used when accessing date result columns. All output date elds are returned in the specied format. For input date strings, the specied value is used to determine whether the date is specied in a valid format. Note: An input date string that uses the format *USA, *ISO, *EUR, or *JIS is always valid. If a relational database is specied on the RDB parameter and the database is on a system that is not an AS/400 system, then *USA, *ISO, *EUR, or *JIS must be specied. *JOB: The format specied for the job is used. Use the Display Job (DSPJOB) command to determine the current date format for the job. *USA: The United States date format (mm/dd/yyyy) is used. *ISO: The International Organization for Standardization (ISO) date format (yyyy-mm-dd) is used. *EUR: The European date format (dd.mm.yyyy) is used.

654

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCBL
*JIS: The Japanese Industrial Standard date format (yyyy-mm-dd) is used. *MDY: The date format (mm/dd/yy) is used. *DMY: The date format (dd/mm/yy) is used. *YMD: The date format (yy/mm/dd) is used. *JUL: The Julian date format (yy/ddd) is used. DATSEP Species the separator used when accessing date result columns. Note: This parameter applies only when *JOB, *MDY, *DMY, *YMD, or *JUL is specied on the DATFMT parameter. *JOB: The date separator specied for the job at precompile time is used. Use the Display Job (DSPJOB) command to determine the current value for the job. /: A slash (/) is used. .: A period (.) is used. ,: A comma (,) is used. -: A dash (-) is used. : A blank ( ) is used. *BLANK: A blank ( ) is used. TIMFMT Species the format used when accessing time result columns. For input time strings, the specied value is used to determine whether the time is specied in a valid format. Note: An input date string that uses the format *USA, *ISO, *EUR, or *JIS is always valid. If a relational database is specied on the RDB parameter and the database is on a system that is not another AS/400 system, the time format must be *USA, *ISO, *EUR, *JIS, or *HMS with a time separator of colon or period. *HMS: The (hh:mm:ss) format is used. *USA: The United States time format (hh:mm xx) is used, where xx is AM or PM. *ISO: The International Organization for Standardization (ISO) time format (hh.mm.ss) is used. *EUR: The European time format (hh.mm.ss) is used. *JIS: The Japanese Industrial Standard time format (hh:mm:ss) is used.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

655

CRTSQLCBL
TIMSEP Species the separator used when accessing time result columns. Note: This parameter applies only when *HMS is specied on the TIMFMT parameter. *JOB: The time separator specied for the job at precompile time is used. Use the Display Job (DSPJOB) command to determine the current value for the job. :: A colon (:) is used. .: A period (.) is used. ,: A comma (,) is used. : A blank ( ) is used. *BLANK: A blank ( ) is used. REPLACE Species whether a new program or SQL package is created when a program or SQL package of the same name exists in the same library. The value of this parameter is passed to the CRTCBLPGM command. More information on this parameter is in Appendix A, Expanded Parameter Descriptions in the CL Reference (Abridged) book. *YES: A new program or SQL package is created, and any existing program or SQL package of the same name and type in the specied library is moved to QRPLOBJ. *NO: A new program or SQL package is not created if an object of the same name and type already exists in the specied library. RDB Species the name of the relational database where the SQL package object is created. *LOCAL: The program is created as a distributed SQL program. The SQL statements will access the local database. An SQL package object is not created as part of the precompile process. The Create Structured Query Language Package (CRTSQLPKG) command can be used.

relational-database-name: Specify the name of the relational database where the new SQL package object is to be created. When the name of the local relational database is specied, the program created is still a distributed SQL program. The SQL statements will access the local database.
*NONE: An SQL package object is not created. The program object is not a distributed program and the Create Structured Query Language Package (CRTSQLPKG) command cannot be used. USER Species the user name sent to the remote system when starting the conversation. This parameter is valid only when RDB is specied. *CURRENT: The user prole under which the current job is running is used.

656

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCBL
user-name: Specify the user name to be used for the application server job.
PASSWORD Species the password to be used on the remote system. This parameter is valid only if RDB is specied. *NONE: No password is sent. If this value is specied, USER(*CURRENT) must also be specied.

password: Specify the password of the user name specied on the USER parameter.
RDBCNNMTH Species the semantics used for CONNECT statements. Refer to the SQL Reference book for more information. *DUW: CONNECT (Type 2) semantics are used to support distributed unit of work. Consecutive CONNECT statements to additional relational databases do not result in disconnection of previous connections. *RUW: CONNECT (Type 1) semantics are used to support remote unit of work. Consecutive CONNECT statements result in the previous connection being disconnected before a new connection is established. DFTRDBCOL Species the collection name used for the unqualied names of tables, views, indexes, and SQL packages. This parameter applies only to static SQL statements. *NONE: The naming convention dened on the OPTION parameter is used.

collection-name: Specify the name of the collection identier. This value is used instead of the naming convention specied on the OPTION parameter.
| | | | | | | | | | DYNDFTCOL Species whether the default collection name specied for the DFTRDBCOL parameter is also used for dynamic statements. *NO: Do not use the value specied on the DFTRDBCOL parameter for unqualied names of tables, views, indexes, and SQL packages for dynamic SQL statements. The naming convention specied on the OPTION parameter is used. *YES: The collection name specied on the DFTRDBCOL parameter will be used for the unqualied names of the tables, views, indexes, and SQL packages in dynamic SQL statements. SQLPKG Species the qualied name of the SQL package created on the relational database specied on the RDB parameter of this command. The library values are: *PGMLIB: The package is created in the library with the same name as the library containing the program. library-name: Specify the name of the library where the package is created. *PGM: The package name is the same as the program name.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

657

CRTSQLCBL
package-name: Specify the name of the package created on the remote database specied on the RDB parameter.
| | | | | | | | | | | | SQLPATH Species the path to be used to nd procedures, functions, and user dened types in static SQL statements. *NAMING: The path used depends on the naming convention specied on the OPTION parameter. For *SYS naming, the path used is *LIBL, the current library list at runtime. For *SQL naming, the path used is QSYS, QSYS2, userid, where userid is the value of the USER special register. If a collection-name is specied on the DFTRDBCOL parameter, the collection-name takes the place of userid. *LIBL: The path used is the library list at runtime.

collection-name: Specify a list of one or more collection names. A maximum of 43 individual collections may be specied.
SAAFLAG Species the IBM SQL agging function. This parameter ags SQL statements to verify whether they conform to IBM SQL syntax More information about which IBM database products IBM SQL syntax is in the DRDA IBM SQL Reference, SC26-3255-00. *NOFLAG: The precompiler does not check to see whether SQL statements conform to IBM SQL syntax. *FLAG: The precompiler checks to see whether SQL statements conform to IBM SQL syntax. FLAGSTD Species the American National Standards Institute (ANSI) agging function. This parameter ags SQL statements to verify whether they conform to the following standards.
ANSI X3.135-1992 entry ISO 9075-1992 entry FIPS 127.2 entry

*NONE: The precompiler does not check to see whether SQL statements conform to ANSI standards. *ANS: The precompiler checks to see whether SQL statements conform to ANSI standards. PRTFILE Species the qualied name of the printer device le to which the listing is directed. The le must have a minimum record length of 132 bytes or information is lost. The name of the printer le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used.

658

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCBL
QSYSPRT: If a le name is not specied, the precompiler printout is directed to the IBM-supplied printer le QSYSPRT.

printer-le-name: Specify the name of the printer device le to which the precompiler printout is directed.
SRTSEQ Species the sort sequence table to be used for string comparisons in SQL statements. Note: *HEX must be specied for this parameter on distributed applications where the application server is not on an AS/400 system or the release level is prior to V2R3M0. *JOB: The SRTSEQ value for the job is retrieved during the precompile. *JOBRUN: The SRTSEQ value for the job is retrieved when the program is run. For distributed applications, SRTSEQ(*JOBRUN) is valid only when LANGID(*JOBRUN) is also specied. *LANGIDUNQ: The unique-weight sort table for the language specied on the LANGID parameter is used. *LANGIDSHR: The shared-weight sort table for the language specied on the LANGID parameter is used. *HEX: A sort sequence table is not used. The hexadecimal values of the characters are used to determine the sort sequence. The name of the sort sequence table can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library to be searched.

table-name: Specify the name of the sort sequence table to be used.


LANGID Species the language identier to be used when SRTSEQ(*LANGIDUNQ) or SRTSEQ(*LANGIDSHR) is specied. *JOB: The LANGID value for the job is retrieved during the precompile. *JOBRUN: The LANGID value for the job is retrieved when the program is run. For distributed applications, LANGID(*JOBRUN) is valid only when SRTSEQ(*JOBRUN) is also specied.

language-id: Specify a language identier to be used by the program.


USRPRF Species the user prole that is used when the compiled program object is run, including the authority that the program object has for each object in static SQL statements. The prole of either the program owner or the program user is used to control which objects can be used by the program object.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

659

CRTSQLCBL
*NAMING: The user prole is determined by the naming convention. If the naming convention is *SQL, USRPRF(*OWNER) is used. If the naming convention is *SYS, USRPRF(*USER) is used. *USER: The prole of the user running the program object is used. *OWNER: The user proles of both the program owner and the program user are used when the program is run. DYNUSRPRF Species the user prole used for dynamic SQL statements. *USER: Local dynamic SQL statements are run under the user prole of the job. Distributed dynamic SQL statements are run under the user prole of the application server job. *OWNER: Local dynamic SQL statements are run under the user prole of the programs owner. Distributed dynamic SQL statements are run under the user prole of the SQL packages owner. | | | | | | | | | | | | | | | | | TOSRCFILE Species the qualied name of the source le that is to contain the output source member that has been processed by the SQL precompiler. If the specied source le is not found, it will be created. The output member will have the same name as the name that is specied for the SRCMBR parameter. The possible library values are: QTEMP: The library QTEMP will be used. *LIBL: The jobs library list is searched for the specied le. If the le is not found in any library in the library list, the le will be created in the current library. *CURLIB: The current library for the job will be used. If no library is specied as the current library for the job, the QGPL library will be used. library-name: Specify the name of the library that is to contain the output source le. QSQLTEMP: The source le QSQLTEMP will be used.

source-le-name: Specify the name of the source le to contain the output source member.
TEXT Species the text that briey describes the program and its function. More information on this parameter is in Appendix A, Expanded Parameter Descriptions in the CL Reference (Abridged) book. *SRCMBRTXT: The text is taken from the source le member being used to create the COBOL program. Text for a database source member can be added or changed by using the Start Source Entry Utility (STRSEU) command, or by using either the Add Physical File Member (ADDPFM) or Change Physical File Member (CHGPFM) command. If the source le is an inline le or a device le, the text is blank. *BLANK: Text is not specied.

660

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCBL
description: Specify no more than 50 characters of text, enclosed in apostrophes.

Example
CRTSQLCBL PGM(ACCTS/STATS) SRCFILE(ACCTS/ACTIVE) TEXT('Statistical analysis program for active accounts')

This command runs the SQL precompiler which precompiles the source and stores the changed source in the member STATS in le QSQLTEMP in library QTEMP. The COBOL compiler is called to create program STATS in library ACCTS using the source member created by the SQL precompiler.

CRTSQLCBLI (Create SQL ILE COBOL Object) Command


Job: B,I Pgm: B,I
OBJ( library-name/

REXX: B,I
*CURLIB/

Exec
object-name )

CRTSQLCBLI

*LIBL/ SRCFILE( *CURLIB/ library-name/

QCBLLESRC source-file-name

(1) *OBJ source-file-member-name

SRCMBR(

OPTION(

OPTION Details

) TGTRLS(

*CURRENT *PRV VxRxMx

OBJTYPE(

*PGM *MODULE *SRVPGM

*LIBL/ INCFILE( *CURLIB/ library-name/

*SRCFILE source-file-name

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

661

CRTSQLCBLI
*UR *CHG *ALL *RS *CS *NONE *NC *RR *ENDACTGRP *ENDMOD

CLOSQLCSR( )

COMMIT(

ALWCPYDTA(

*OPTIMIZE *YES *NO

ALWBLK(

*ALLREAD *NONE *READ

DLYPRP(

*NO *YES

GENLVL(

10 severity-level

DATFMT(

*JOB *USA *ISO *EUR *JIS *MDY *DMY *YMD *JUL

DATSEP(

*JOB '/' '.' ',' '-' ' ' *BLANK

TIMFMT(

*HMS *USA *ISO *EUR *JIS

TIMSEP(

*JOB ':' '.' ',' ' ' *BLANK

REPLACE(

*YES *NO

RDB(

*LOCAL relational-database-name *NONE

USER(

*CURRENT user-name

PASSWORD(

*NONE password

RDBCNNMTH(

*DUW *RUW

DFTRDBCOL(

*NONE collection-name

662

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCBLI
*NO *YES

DYNDFTCOL(

*OBJLIB/ SQLPKG( library-name/

*OBJ package-name

SQLPATH(

*NAMING *LIBL

collection-name

SAAFLAG(

*NOFLAG *FLAG

FLAGSTD(

*NONE *ANS

DBGVIEW(

*NONE *SOURCE

USRPRF(

*NAMING *OWNER *USER

DYNUSRPRF(

*USER *OWNER

SRTSEQ(

*JOB *JOBRUN *LANGIDUNQ *LANGIDSHR *HEX *LIBL/ table-name *CURLIB/ library-name/

LANGID(

*JOB *JOBRUN language-identifier

OUTPUT(

*NONE *PRINT

*LIBL/ PRTFILE( *CURLIB/ library-name/

QSYSPRT printer-file-name

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

663

CRTSQLCBLI
QTEMP/ TOSRCFILE( *LIBL/ *CURLIB/ library-name/ QSQLTEMP source-file-name

TEXT(

*SRCMBRTXT *BLANK 'description'

OPTION Details:
*XREF *NOXREF *GEN *NOGEN *JOB *SYSVAL *PERIOD *COMMA *SYS *SQL *NOSECLVL *SECLVL

*QUOTESQL *APOSTSQL

*QUOTE *APOST

*NOEVENTF *EVENTF

*OPTLOB *NOOPTLOB

Notes: 1. All parameters preceding this point can be specied in positional form.

Purpose
The Create Structured Query Language ILE COBOL Object (CRTSQLCBLI) command calls the Structured Query Language (SQL) precompiler which precompiles COBOL source containing SQL statements, produces a temporary source member, and then optionally calls the ILE COBOL compiler to create a module, a program, or a service program.

Parameters
OBJ Species the qualied name of the object being created. *CURLIB: The new object is created in the current library for the job. If no library is specied as the current library for the job, the QGPL library is used.

library-name: Specify the name of the library where the object is created. object-name: Specify the name of the object that is being created.
SRCFILE Species the qualied name of the source le that contains the COBOL source with SQL statements. The name of the source le can be qualied by one of the following library values:

664

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCBLI
*LIBL All libraries in the jobs library list are searched until the rst match is found. *CURLIB The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library to be searched. QCBLLESRC: If the source le name is not specied, the source le QCBLLESRC contains the COBOL source.

source-le-name: Specify the name of the source le that contains the COBOL source.
SRCMBR Species the name of the source le member that contains the COBOL source. This parameter is specied only if the source le name in the SRCFILE parameter is a database le. If this parameter is not specied, the OBJ name specied on the OBJ parameter is used. *OBJ: Species that the COBOL source is in the member of the source le that has the same name as that specied on the OBJ parameter.

source-le-member-name: Specify the name of the member that contains the COBOL source.
OPTION Species whether one or more of the following options are used when the COBOL source is precompiled. If an option is specied more than once, or if two options conict, the last option specied is used. Element 1: Cross-Reference Options *XREF: The precompiler cross-references items in the program to the statement numbers in the program that refer to those items. *NOXREF: The precompiler does not cross-reference names. Element 2: Program Creation Options *GEN: The precompiler creates the object that is specied by the OBJTYPE parameter. *NOGEN: The precompiler does not call the ILE COBOL compiler, and a module, program, service program, or SQL package are not created. Element 3: Decimal Point Options *JOB: The value used as the decimal point for numeric constants in SQL is the representation of decimal point specied for the job at precompile time. *SYSVAL: The value used as the decimal point for numeric constants in SQL statements is the QDECFMT system value. *PERIOD: The value used as the decimal point for numeric constants in SQL statements is a period (.).

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

665

CRTSQLCBLI
Note: If QDECFMT species that the value used as the decimal point is a comma (,), any numeric constants in lists (such as in the SELECT clause or the VALUES clause) must be separated by a comma (,) followed by a blank ( ). For example, VALUES(1,1, 2,23, 4,1) is equivalent to VALUES(1.1,2.23,4.1) in which the decimal point is a period (.). *COMMA: The value used as the decimal point for numeric constants in SQL statements is a comma (,). Note: Any numeric constants in lists (such as in the SELECT clause or the VALUES clause) must be separated by a comma (,) followed by a blank( ). For example, VALUES(1,1, 2,23, 4,1) is equivalent to VALUES(1.1,2.23,4.1) where the decimal point is a period(.). Element 4: Naming Convention Options *SYS: The system naming convention (library-name/le-name) is used. *SQL: The SQL naming convention is used (collection-name.table-name). When creating a program on a remote database other than an AS/400 system, *SQL must be specied as the naming convention. Element 5: Second-Level Message Text Option *NOSECLVL: Second-level text descriptions are not added to the listing. *SECLVL: Second-level text with replacement data is added for all messages on the listing. Element 6: String Delimiter Options *QUOTESQL: A double quote (") is the string delimiter in the SQL statements. *APOSTSQL: An apostrophe (') is the string delimiter in the SQL statements. Element 7: Literal Options *QUOTE: A double quote (") is used for literals which are not numeric and Boolean literals in the COBOL statements. *APOST: An apostrophe (') is used for literals which are not numeric and Boolean literals in the COBOL statements. Element 8: Event File Creation *NOEVENTF: The compiler will not produce an event le for use by CoOperative Development Environment/400 (CODE/400). *EVENTF: The compiler produces an event le for use by CoOperative Development Environment/400 (CODE/400). The event le will be created as a member in the le EVFEVENT in your source library. CODE/400 uses this le to offer error feedback integrated with the CODE/400 editor. This option is normally specied by CODE/400 on your behalf. | Element 9: Large Object Optimization for DRDA

666

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCBLI
*OPTLOB: The rst FETCH for a cursor derermines how the cursor will be used for LOBs (Large Objects) on all subsequent FETCHes. This option remains in effect until the cursor is closed. If the rst FETCH uses a LOB locator to access a LOB column, no subsequent FETCH for that cursor can fetch that LOB column into a LOB host variable. If the rst FETCH places the LOB column into a LOB host variable, no subsequent FETCH for that cursor can use a LOB locator for that column. *NOOPTLOB:There is no restriction on whether a column is retrieved into a LOB locator or into a LOB host variable. This option can cause performance to degrade. TGTRLS Species the release of the operating system on which the user intends to use the object being created. In the examples given for the *CURRENT and *PRV values, and when specifying the release-level value, the format VxRxMx is used to specify the release, where Vx is the version, Rx is the release, and Mx is the modication level. For example, V2R3M0 is version 2, release 3, modication level 0. *CURRENT: The object is to be used on the release of the operating system currently running on the users system. For example, if V2R3M5 is running on the system, *CURRENT means the user intends to use the object on a system with V2R3M5 installed. The user can also use the object on a system with any subsequent release of the operating system installed. Note: If V2R3M5 is running on the system, and the object is to be used on a system with V2R3M0 installed, specify TGTRLS(V2R3M0) not TGTRLS(*CURRENT). *PRV: The object is to be used on the previous release with modication level 0 of the operating system. For example, if V2R3M5 is running on the users system, *PRV means the user intends to use the object on a system with V2R2M0 installed. The user can also use the object on a system with any subsequent release of the operating system installed.

release-level: Specify the release in the format VxRxMx. The object can be used on a system with the specied release or with any subsequent release of the operating system installed.
Valid values depend on the current version, release, and modication level, and they change with each new release. If you specify a release-level which is earlier than the earliest release level supported by this command, an error message is sent indicating the earliest supported release. OBJTYPE Species the type of object being created. *PGM: The SQL precompiler issues the CRTBNDCBL command to create the bound program. *MODULE: The SQL precompiler issues the CRTCBLMOD command to create the module.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

667

CRTSQLCBLI
*SRVPGM: The SQL precompiler issues the CRTCBLMOD and CRTSRVPGM commands to create the service program. Notes: 1. When OBJTYPE(*PGM) or OBJTYPE(*SRVPGM) is specied and the RDB parameter is also specied, the CRTSQLPKG command is issued by the SQL precompiler after the program has been created. When OBJTYPE(*MODULE) is specied, an SQL package is not created and you must issue the CRTSQLPKG command after the CRTPGM or CRTSRVPGM command has created the program. 2. If *NOGEN is specied, only the SQL temporary source member is generated and a module, program, service program, or SQL package are not created. INCFILE Species the qualied name of the source le that contains members included in the program with any SQL INCLUDE statement. The name of the source le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used.

library-name: Specify the name of the library to be searched.


*SRCFILE: The qualied source le specied in the SRCFILE parameter contains the source le members specied on any SQL INCLUDE statement.

source-le-name: Specify the name of the source le that contains the source le members specied on any SQL INCLUDE statement. The record length of the source le specied here must be no less than the record length of the source le specied on the SRCFILE parameter.
COMMIT Species whether SQL statements in the compiled unit are run under commitment control. Files referred to in the host language source are not affected by this option. Only SQL tables, SQL views, and SQL packages referred to in SQL statements are affected. *CHG or *UR: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs can be seen. *ALL or *RS: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows selected, updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs cannot be seen. *CS: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows updated, deleted, and inserted are locked until the end of the unit of

668

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCBLI
work (transaction). A row that is selected, but not updated, is locked until the next row is selected. Uncommitted changes in other jobs cannot be seen. *NONE or *NC: Species that commitment control is not used. Uncommitted changes in other jobs can be seen. If the SQL DROP COLLECTION statement is included in the program, *NONE or *NC must be used. If a relational database is specied on the RDB parameter and the relational database is on a system that is not on an AS/400, *NONE or *NC cannot be specied. *RR: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows selected, updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs cannot be seen. All tables referred to in SELECT, UPDATE, DELETE, and INSERT statements are locked exclusively until the end of the unit of work (transaction). CLOSQLCSR Species when SQL cursors are implicitly closed, SQL prepared statements are implicitly discarded, and LOCK TABLE locks are released. SQL cursors are explicitly closed when you issue the CLOSE, COMMIT, or ROLLBACK (without HOLD) SQL statements. *ENDACTGRP: SQL cursors are closed, SQL prepared statements are implicitly discarded, and LOCK TABLE locks are released when the activation group ends. *ENDMOD: SQL cursors are closed and SQL prepared statements are implicitly discarded when the module is exited. LOCK TABLE locks are released when the activation group ends. | | | | | | | | | | | | | | | | | | | | ALWCPYDTA Species whether a copy of the data can be used in a SELECT statement. *OPTIMIZE: The system determines whether to use the data retrieved directly from the database or to use a copy of the data. The decision is based on which method provides the best performance. If COMMIT is *CHG or *CS and ALWBLK is not *ALLREAD, or if COMMIT is *ALL or *RR, then a copy of the data is used only when it is necessary to run a query. *YES: A copy of the data is used only when necessary. *NO: A copy of the data is not allowed. If a temporary copy of the data is required to perform the query, an error message is returned. ALWBLK Species whether the database manager can use record blocking, and the extent to which blocking can be used for read-only cursors. *ALLREAD: Rows are blocked for read-only cursors if *NONE or *CHG is specied on the COMMIT parameter. All cursors in a program that are not explicitly able to be updated are opened for read-only processing even though EXECUTE or EXECUTE IMMEDIATE statements may be in the program. Specifying *ALLREAD: v Allows record blocking under commitment control level *CHG in addition to the blocking allowed for *READ.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

669

CRTSQLCBLI
| | | | | | | | | | | | | | | | | | | | | | | | | | | v Can improve the performance of almost all read-only cursors in programs, but limits queries in the following ways: The Rollback (ROLLBACK) command, a ROLLBACK statement in host languages, or the ROLLBACK HOLD SQL statement does not reposition a read-only cursor when *ALLREAD is specied. Dynamic running of a positioned UPDATE or DELETE statement (for example, using EXECUTE IMMEDIATE), cannot be used to update a row in a cursor unless the DECLARE statement for the cursor includes the FOR UPDATE clause. *NONE: Rows are not blocked for retrieval of data for cursors. Specifying *NONE: v Guarantees that the data retrieved is current. v May reduce the amount of time required to retrieve the rst row of data for a query. v Stops the database manager from retrieving a block of data rows that is not used by the program when only the rst few rows of a query are retrieved before the query is closed. v Can degrade the overall performance of a query that retrieves a large number of rows. *READ: Records are blocked for read-only retrieval of data for cursors when: v *NONE is specied on the COMMIT parameter, which indicates that commitment control is not used. v The cursor is declared with a FOR READ ONLY clause or there are no dynamic statements that could run a positioned UPDATE or DELETE statement for the cursor. Specifying *READ can improve the overall performance of queries that meet the above conditions and retrieve a large number of records. DLYPRP Species whether the dynamic statement validation for a PREPARE statement is delayed until an OPEN, EXECUTE, or DESCRIBE statement is run. Delaying validation improves performance by eliminating redundant validation. *NO: Dynamic statement validation is not delayed. When the dynamic statement is prepared, the access plan is validated. When the dynamic statement is used in an OPEN or EXECUTE statement, the access plan is revalidated. Because the authority or the existence of objects referred to by the dynamic statement may change, you must still check the SQLCODE or SQLSTATE after issuing the OPEN or EXECUTE statement to ensure that the dynamic statement is still valid. *YES: Dynamic statement validation is delayed until the dynamic statement is used in an OPEN, EXECUTE, or DESCRIBE SQL statement. When the dynamic statement is used, the validation is completed and an access plan is built. If you specify *YES on this parameter, you should check the SQLCODE and SQLSTATE after running an OPEN, EXECUTE, or DESCRIBE statement to ensure that the dynamic statement is valid.

670

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCBLI
Note: If you specify *YES, performance is not improved if the INTO clause is used on the PREPARE statement or if a DESCRIBE statement uses the dynamic statement before an OPEN is issued for the statement. GENLVL Species the severity level at which the create operation fails. If errors occur that have a severity level greater than this value, the operation ends. 10: The default severity level is 10.

severity-level: Specify a value ranging from 0 through 40.


DATFMT Species the format used when accessing date result columns. All output date elds are returned in the specied format. For input date strings, the specied value is used to determine whether the date is specied in a valid format. Note: An input date string that uses the format *USA, *ISO, *EUR, or *JIS is always valid. If a relational database is specied on the RDB parameter and the database is on a system that is not an AS/400 system, then *USA, *ISO, *EUR, or *JIS must be specied. *JOB: The format specied for the job is used. Use the Display Job (DSPJOB) command to determine the current date format for the job. *USA: The United States date format (mm/dd/yyyy) is used. *ISO: The International Organization for Standardization (ISO) date format (yyyy-mm-dd) is used. *EUR: The European date format (dd.mm.yyyy) is used. *JIS: The Japanese Industrial Standard date format (yyyy-mm-dd) is used. *MDY: The date format (mm/dd/yy) is used. *DMY: The date format (dd/mm/yy) is used. *YMD: The date format (yy/mm/dd) is used. *JUL: The Julian date format (yy/ddd) is used. DATSEP Species the separator used when accessing date result columns. Note: This parameter applies only when *JOB, *MDY, *DMY, *YMD, or *JUL is specied on the DATFMT parameter. *JOB: The date separator specied for the job at precompile time is used. Use the Display Job (DSPJOB) command to determine the current value for the job. /: A slash (/) is used. .: A period (.) is used.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

671

CRTSQLCBLI
,: A comma (,) is used. -: A dash (-) is used. : A blank ( ) is used. *BLANK: A blank ( ) is used. TIMFMT Species the format used when accessing time result columns. For input time strings, the specied value is used to determine whether the time is specied in a valid format. Note: An input date string that uses the format *USA, *ISO, *EUR, or *JIS is always valid. If a relational database is specied on the RDB parameter and the database is on a system that is not another AS/400 system, the time format must be *USA, *ISO, *EUR, *JIS, or *HMS with a time separator of a colon or period. *HMS: The hh:mm:ss format is used. *USA: The United States time format hh:mm xx is used, where xx is AM or PM. *ISO: The International Organization for Standardization (ISO) time format hh.mm.ss is used. *EUR: The European time format hh.mm.ss is used. *JIS: The Japanese Industrial Standard time format hh:mm:ss is used. TIMSEP Species the separator used when accessing time result columns. Note: This parameter applies only when *HMS is specied on the TIMFMT parameter. *JOB: The time separator specied for the job at precompile time is used. Use the Display Job (DSPJOB) command to determine the current value for the job. :: A colon (:) is used. .: A period (.) is used. ,: A comma (,) is used. : A blank ( ) is used. *BLANK: A blank ( ) is used. REPLACE Species if a SQL module, program, service program or package is created when there is an existing SQL module, program, service program, or package

672

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCBLI
of the same name and type in the same library. The value of this parameter is passed to the CRTCBLMOD, CRTBNDCBL, CRTSRVPGM, and CRTSQLPKG commands. *YES: A new SQL module, program, service program, or package is created, any existing SQL object of the same name and type in the specied library is moved to QRPLOBJ. *NO: A new SQL module, program, service program, or package is not created if an SQL object of the same name and type already exists in the specied library. RDB Species the name of the relational database where the SQL package object is created. *LOCAL: The program is created as a distributed SQL program. The SQL statements will access the local database. An SQL package object is not created as part of the precompile process. The Create Structured Query Language Package (CRTSQLPKG) command can be used.

relational-database-name: Specify the name of the relational database where the new SQL package object is to be created. When the name of the local relational database is specied, the program created is still a distributed SQL program. The SQL statements will access the local database.
*NONE: An SQL package object is not created. The program object is not a distributed program and the Create Structured Query Language Package (CRTSQLPKG) command cannot be used. USER Species the user name sent to the remote system when starting the conversation. This parameter is valid only when RDB is specied. *CURRENT: The user prole under which the current job is running is used.

user-name: Specify the user name being used for the application server job.
PASSWORD Species the password to be used on the remote system. This parameter is valid only if RDB is specied. *NONE: No password is sent. If this value is specied, USER(*CURRENT) must also be specied.

password: Specify the password of the user name specied on the USER parameter.
RDBCNNMTH Species the semantics used for CONNECT statements. Refer to the SQL Reference book for more information. *DUW: CONNECT (Type 2) semantics are used to support distributed unit of work. Consecutive CONNECT statements to additional relational databases do not result in disconnection of previous connections.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

673

CRTSQLCBLI
*RUW: CONNECT (Type 1) semantics are used to support remote unit of work. Consecutive CONNECT statements result in the previous connection being disconnected before a new connection is established. DFTRDBCOL Species the collection name used for the unqualied names of tables, views, indexes, and SQL packages. This parameter applies only to static SQL statements. *NONE: The naming convention dened on the OPTION parameter is used.

collection-name: Specify the name of the collection identier. This value is used instead of the naming convention specied on the OPTION parameter.
| | | | | | | | | | DYNDFTCOL Species whether the default collection name specied for the DFTRDBCOL parameter is also used for dynamic statements. *NO: Do not use the value specied on the DFTRDBCOL parameter for unqualied names of tables, views, indexes, and SQL packages for dynamic SQL statements. The naming convention specied on the OPTION parameter is used. *YES: The collection name specied on the DFTRDBCOL parameter will be used for the unqualied names of the tables, views, indexes, and SQL packages in dynamic SQL statements. SQLPKG Species the qualied name of the SQL package created on the relational database specied on the RDB parameter of this command. The possible library values are: *OBJLIB: The package is created in the library with the same name as the library specied on the OBJ parameter.

library-name: Specify the name of the library where the package is created.
*OBJ: The name of the SQL package is the same as the object name specied on the OBJ parameter.

package-name: Specify the name of the SQL package. If the remote system is not an AS/400 system, no more than 8 characters can be specied.
| | | | | | | | | | SQLPATH Species the path to be used to nd procedures, functions, and user dened types in static SQL statements. *NAMING: The path used depends on the naming convention specied on the OPTION parameter. For *SYS naming, the path used is *LIBL, the current library list at runtime. For *SQL naming, the path used is QSYS, QSYS2, userid, where userid is the value of the USER special register. If a collection-name is specied on the DFTRDBCOL parameter, the collection-name takes the place of userid. *LIBL: The path used is the library list at runtime.

674

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCBLI
| |

collection-name: Specify a list of one or more collection names. A maximum of 43 individual collections may be specied.
SAAFLAG Species the IBM SQL agging function. This parameter ags SQL statements to verify whether they conform to IBM SQL syntax More information about which IBM database products IBM SQL syntax is in the DRDA IBM SQL Reference, SC26-3255-00. *NOFLAG: The precompiler does not check to see whether SQL statements conform to IBM SQL syntax. *FLAG: The precompiler checks to see whether SQL statements conform to IBM SQL syntax. FLAGSTD Species the American National Standards Institute (ANSI) agging function. This parameter ags SQL statements to verify whether they conform to the following standards.
ANSI X3.135-1992 entry ISO 9075-1992 entry FIPS 127.2 entry

*NONE: The precompiler does not check to see whether SQL statements conform to ANSI standards. *ANS: The precompiler checks to see whether SQL statements conform to ANSI standards. DBGVIEW Species the type of source debug information to be provided by the SQL precompiler. *NONE: The source view is not generated. *SOURCE: The SQL precompiler provides the source views for the root and if necessary, SQL INCLUDE statements. A view is provided which contains the statements generated by the precompiler. USRPRF Species the user prole that is used when the compiled program object is run, including the authority that the program object has for each object in static SQL statements. The prole of either the program owner or the program user is used to control which objects can be used by the program object. *NAMING: The user prole is determined by the naming convention. If the naming convention is *SQL, USRPRF(*OWNER) is used. If the naming convention is *SYS, USRPRF(*USER) is used. *USER: The prole of the user running the program object is used. *OWNER: The user proles of both the program owner and the program user are used when the program is run. DYNUSRPRF Species the user prole to be used for dynamic SQL statements.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

675

CRTSQLCBLI
*USER: For local programs, dynamic SQL statements run under the prole of the programs user. For distributed programs, dynamic SQL statements run under the prole of the SQL packages user. *OWNER: For local programs, dynamic SQL statements run under the prole of the programs owner. For distributed programs, dynamic SQL statements run under the prole of the SQL packages owner. SRTSEQ Species the sort sequence table to be used for string comparisons in SQL statements. Note: *HEX must be specied for this parameter on distributed applications where the application server is not on an AS/400 system or the release level is prior to V2R3M0. *JOB: The SRTSEQ value for the job is retrieved during the precompile. *JOBRUN: The SRTSEQ value for the job is retrieved when the program is run. For distributed applications, SRTSEQ(*JOBRUN) is valid only when LANGID(*JOBRUN) is also specied. *LANGIDUNQ: The unique-weight sort table for the language specied on the LANGID parameter is used. The name of the table name can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used.

library-name: Specify the name of the library to be searched.


*LANGIDSHR: The sort sequence table uses the same weight for multiple characters, and is the shared-weight sort sequence table associated with the language specied on the LANGID parameter. *HEX: A sort sequence is not used. The hexadecimal values of the characters are used to determine the sort sequence.

table-name: Specify the name of the sort sequence table to be used.


LANGID Species the language identier to be used when SRTSEQ(*LANGIDUNQ) or SRTSEQ(*LANGIDSHR) is specied. *JOB: The LANGID value for the job is retrieved during the precompile. *JOBRUN: The LANGID value for the job is retrieved when the program is run. For distributed applications, LANGID(*JOBRUN) is valid only when SRTSEQ(*JOBRUN) is also specied.

language-identier: Specify a language identier.


OUTPUT Species whether the precompiler listing is generated.

676

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCBLI
*NONE: The precompiler listing is not generated. *PRINT: The precompiler listing is generated. PRTFILE Species the qualied name of the printer device le to which the precompiler printout is directed. The le must have a minimum length of 132 bytes. If a le with a record length of less than 132 bytes is specied, information is lost. The name of the printer le can be qualied by one of the following library values: *LIBL All libraries in the jobs library list are searched until the rst match is found. *CURLIB The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library to be searched. QSYSPRT: If a le name is not specied, the precompiler printout is directed to the IBM-supplied printer le QSYSPRT.

printer-le-name: Specify the name of the printer device le to which the precompiler printout is directed.
| | | | | | | | | | | | | | | | | TOSRCFILE Species the qualied name of the source le that is to contain the output source member that has been processed by the SQL precompiler. If the specied source le is not found, it will be created. The output member will have the same name as the name that is specied for the SRCMBR parameter. The possible library values are: QTEMP: The library QTEMP will be used. *LIBL: The jobs library list is searched for the specied le. If the le is not found in any library in the library list, the le will be created in the current library. *CURLIB: The current library for the job will be used. If no library is specied as the current library for the job, the QGPL library will be used. library-name: Specify the name of the library that is to contain the output source le. QSQLTEMP: The source le QSQLTEMP will be used.

source-le-name: Specify the name of the source le to contain the output source member.
TEXT Species the text that briey describes the printer le. More information on this parameter is in Appendix A, Expanded Parameter Descriptions in the CL Reference (Abridged) book. *SRCMBRTXT: The text is taken from the source le member being used to create the COBOL program. Text can be added or changed for a database source member by using the Start Source Entry Utility (STRSEU) command, or by using either the Add Physical File Member (ADDPFM) or Change Physical File Member (CHGPFM) command. If the source le is an inline le or a device le, the text is blank.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

677

CRTSQLCBLI
*BLANK: Text is not specied.

description: Specify no more than 50 characters of text, enclosed in apostrophes.

Example
CRTSQLCBLI PAYROLL OBJTYPE(*MODULE) TEXT('Payroll Program')

This command runs the SQL precompiler which precompiles the source and stores the changed source in member PAYROLL in le QSQLTEMP in library QTEMP. The ILE COBOL compiler is called to create module PAYROLL in the current library by using the source member created by the SQL precompiler.

CRTSQLCI (Create Structured Query Language ILE C Object) Command


Job: B,I Pgm: B,I
OBJ( library-name/

REXX: B,I
*CURLIB/

Exec
object-name )

CRTSQLCI

*LIBL/ SRCFILE( *CURLIB/ library-name/

QCSRC source-file-name

(1) *OBJ source-file-member-name

SRCMBR(

OPTION(

OPTION Details

) TGTRLS(

*CURRENT *PRV VxRxMx

OBJTYPE(

*MODULE *PGM *SRVPGM

*LIBL/ INCFILE( *CURLIB/ library-name/

*SRCFILE source-file-name

678

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCI
*UR *CHG *ALL *RS *CS *NONE *NC *RR *ENDACTGRP *ENDMOD

CLOSQLCSR( )

COMMIT(

ALWCPYDTA(

*OPTIMIZE *YES *NO

ALWBLK(

*ALLREAD *NONE *READ

DLYPRP(

*NO *YES

GENLVL(

10 severity-level

MARGINS(

*SRCFILE left-right

DATFMT(

*JOB *USA *ISO *EUR *JIS *MDY *DMY *YMD *JUL

DATSEP(

*JOB '/' '.' ',' '-' ' ' *BLANK

TIMFMT(

*HMS *USA *ISO *EUR *JIS

TIMSEP(

*JOB ':' '.' ',' ' ' *BLANK

REPLACE(

*YES *NO

RDB(

*LOCAL relational-database-name *NONE

USER(

*CURRENT user-name

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

679

CRTSQLCI
*NONE password *DUW *RUW

PASSWORD(

RDBCNNMTH(

DFTRDBCOL(

*NONE collection-name

DYNDFTCOL(

*NO *YES

SQLPKG(

*OBJ package-name

SQLPATH(

*NAMING *LIBL

collection-name

SAAFLAG(

*NOFLAG *FLAG

FLAGSTD(

*NONE *ANS

DBGVIEW(

*NONE *SOURCE

USRPRF(

*NAMING *OWNER *USER

DYNUSRPRF(

*USER *OWNER

SRTSEQ(

*JOB *JOBRUN *LANGIDUNQ *LANGIDSHR *HEX *LIBL/ table-name *CURLIB/ library-name/

LANGID(

*JOB *JOBRUN language-identifier

OUTPUT(

*NONE *PRINT

680

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCI
*LIBL/ PRTFILE( *CURLIB/ library-name/ QSYSPRT printer-file-name

QTEMP/ TOSRCFILE( *LIBL/ *CURLIB/ library-name/

QSQLTEMP source-file-name

TEXT(

*SRCMBRTXT *BLANK 'description'

OPTION Details:
*XREF *NOXREF *GEN *NOGEN *PERIOD *JOB *SYSVAL *COMMA *SYS *SQL *NOSECLVL *SECLVL

*NOCNULRQD *CNULRQD

*NOEVENTF *EVENTF

*OPTLOB *NOOPTLOB

Notes: 1. All parameters preceding this point can be specied in positional form.

Purpose
The Create Structured Query Language ILE C Object (CRTSQLCI) command calls the Structured Query Language (SQL) precompiler that precompiles C source containing SQL statements, produces a temporary source member, and then optionally calls the ILE C compiler to create a module, create a program, or create a service program.

Parameters
OBJ Species the qualied name of the object being created. The name of the object can be qualied by one of the following library values: *CURLIB: The object is created in the current library for the job. If no library is specied as the current library for the job, the QGPL library is used.

library-name: Specify the name of the library where the object is created.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

681

CRTSQLCI
object-name: Specify the name of the object that is being created.
SRCFILE Species the qualied name of the source le that contains the C source with SQL statements. The name of the source le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library to be searched. QCSRC: If the source le name is not specied, the IBM-supplied source le QCSRC contains the C source.

source-le-name: Specify the name of the source le that contains the C source.
SRCMBR Species the name of the source le member that contains the C source. This parameter is only specied if the source le name in the SRCFILE parameter is a database le. If this parameter is not specied, the OBJ name specied on the OBJ parameter is used. *OBJ: Species that the C source is in the member of the source le that has the same name as that specied on the OBJ parameter.

source-le-member-name: Specify the name of the member that contains the C source.
OPTION Species whether one or more of the following options are used when the C source is precompiled. If an option is specied more than once, or if two options conict, the last option specied is used. Element 1: Cross-Reference Options *XREF: The precompiler cross-references items in the program to the statement numbers in the program that refer to those items. *NOXREF: The precompiler does not cross-reference names. Element 2: Program Creation Options *GEN: The precompiler creates the object that is specied by the OBJTYPE parameter. *NOGEN: The precompiler does not call the C compiler, and a module, program, service program, or SQL package is not created. Element 3: Decimal Point Options *PERIOD: The value used as the decimal point for numeric constants in SQL statements is a period.

682

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCI
*JOB: The value used as the decimal point for numeric constants in SQL is the representation of decimal point specied for the job at precompile time. *SYSVAL: The value used as the decimal point for numeric constants in SQL statements is the QDECFMT system value. Note: If QDECFMT species that the value used as the decimal point is a comma, any numeric constants in lists (such as in the SELECT clause or the VALUES clause) must be separated by a comma followed by a blank. For example, VALUES(1,1, 2,23, 4,1) is equivalent to VALUES(1.1,2.23,4.1) in which the decimal point is a period. *COMMA: The value used as the decimal point for numeric constants in SQL statements is a comma. Note: Any numeric constants in lists (such as in the SELECT clause or the VALUES clause) must be separated by a comma followed by a blank. For example, VALUES(1,1, 2,23, 4,1) is equivalent to VALUES(1.1,2.23,4.1) where the decimal point is a period. Element 4: Naming Convention Options *SYS: The system naming convention (library-name/le-name) is used. *SQL: The SQL naming convention is used (collection-name.table-name). When creating a package on a remote database other than an AS/400 system, *SQL must be specied as the naming convention. Element 5: Second-Level Message Text Option *NOSECLVL: Second-level text descriptions are not added to the listing. *SECLVL: Second-level text with replacement data is added for all messages on the listing. Element 6: NUL Required Options *NOCNULRQD: For output character and graphic host variables, the NUL-terminator is not returned when the host variable is exactly the same length as the data. Input character and graphic host variables do not require a NUL-terminator. *CNULRQD: Output character and graphic host variables always contain the NUL-terminator. If there is not enough space for the NUL-terminator, the data is truncated and the NUL-terminator is added. Input character and graphic host variables require a NUL-terminator. Element 7: Event File Creation *NOEVENTF: The compiler will not produce an event le for use by CoOperative Development Environment/400 (CODE/400). *EVENTF: The compiler produces an event le for use by CoOperative Development Environment/400 (CODE/400). The event le will be created as a member in the le EVFEVENT in your source library. CODE/400 uses this le to

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

683

CRTSQLCI
offer error feedback integrated with the CODE/400 editor. This option is normally specied by CODE/400 on your behalf. | | | | Element 8: Large Object Optimization for DRDA *OPTLOB: The rst FETCH for a cursor derermines how the cursor will be used for LOBs (Large Objects) on all subsequent FETCHes. This option remains in effect until the cursor is closed. If the rst FETCH uses a LOB locator to access a LOB column, no subsequent FETCH for that cursor can fetch that LOB column into a LOB host variable. If the rst FETCH places the LOB column into a LOB host variable, no subsequent FETCH for that cursor can use a LOB locator for that column. | | | *NOOPTLOB: There is no restriction on whether a column is retrieved into a LOB locator or into a LOB host variable. This option can cause performance to degrade. TGTRLS Species the release of the operating system on which the user intends to use the object being created. In the examples given for the *CURRENT and *PRV values, and when specifying the release-level value, the format VxRxMx is used to specify the release, where Vx is the version, Rx is the release, and Mx is the modication level. For example, V2R3M0 is version 2, release 3, modication level 0. *CURRENT: The object is to be used on the release of the operating system currently running on the users system. For example, if V2R3M5 is running on the system, *CURRENT means the user intends to use the object on a system with V2R3M5 installed. The user can also use the object on a system with any subsequent release of the operating system installed. Note: If V2R3M5 is running on the system, and the object is to be used on a system with V2R3M0 installed, specify TGTRLS(V2R3M0) not TGTRLS(*CURRENT). *PRV: The object is to be used on the previous release with modication level 0 of the operating system. For example, if V2R3M5 is running on the users system, *PRV means the user intends to use the object on a system with V2R2M0 installed. The user can also use the object on a system with any subsequent release of the operating system installed.

release-level: Specify the release in the format VxRxMx. The object can be used on a system with the specied release or with any subsequent release of the operating system installed.
Valid values depend on the current version, release, and modication level, and they change with each new release. If you specify a release-level which is earlier than the earliest release level supported by this command, an error message is sent indicating the earliest supported release. OBJTYPE Species the type of object being created. *MODULE: The SQL precompiler issues the CRTCMOD command to create the module.

684

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCI
*PGM: The SQL precompiler issues the CRTBNDC command to create the bound program. *SRVPGM: The SQL precompiler issues the CRTCMOD and CRTSRVPGM commands to create the service program. The user must create a source member in QSRVSRC that has the same name as the name specied on the OBJ parameter. The source member must contain the export information for the module. More information on the export le is in the Integrated Language Environment*C/400 Programmers Guide. Notes: 1. When OBJTYPE(*PGM) or OBJTYPE(*SRVPGM) is specied and the RDB parameter is also specied, the CRTSQLPKG command is issued by the SQL precompiler after the program has been created. When OBJTYPE(*MODULE) is specied, an SQL package is not created and the user must issue the CRTSQLPKG command after the CRTPGM or CRTSRVPGM command has created the program. 2. If *NOGEN is specied, only the SQL temporary source member is generated and a module, program, service program, or SQL package is not created. INCFILE Species the qualied name of the source le that contains members included in the program with any SQL INCLUDE statement. The name of the source le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library to be searched. *SRCFILE: The qualied source le specied in the SRCFILE parameter contains the source le members specied on any SQL INCLUDE statement.

source-le-name: Specify the name of the source le that contains the source le members specied on any SQL INCLUDE statement. The record length of the source le specied here must be no less than the record length of the source le specied on the SRCFILE parameter.
COMMIT Species whether SQL statements in the compiled unit are run under commitment control. Files referred to in the host language source are not affected by this option. Only SQL tables, SQL views, and SQL packages referred to in SQL statements are affected. *CHG or *UR: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs can be seen. *ALL or *RS: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and
Appendix D. DB2 UDB for AS/400 CL Command Descriptions

685

CRTSQLCI
REVOKE statements and the rows selected, updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs cannot be seen. *CS: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows updated, deleted, and inserted are locked until the end of the unit of work (transaction). A row that is selected, but not updated, is locked until the next row is selected. Uncommitted changes in other jobs cannot be seen. *NONE or *NC: Species that commitment control is not used. Uncommitted changes in other jobs can be seen. If the SQL DROP COLLECTION statement is included in the program, *NONE or *NC must be used. If a relational database is specied on the RDB parameter and the relational database is on a system that is not on an AS/400, *NONE or *NC cannot be specied. *RR: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows selected, updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs cannot be seen. All tables referred to in SELECT, UPDATE, DELETE, and INSERT statements are locked exclusively until the end of the unit of work (transaction). CLOSQLCSR Species when SQL cursors are implicitly closed, SQL prepared statements are implicitly discarded, and LOCK TABLE locks are released. SQL cursors are explicitly closed when you issue the CLOSE, COMMIT, or ROLLBACK (without HOLD) SQL statements. *ENDACTGRP: SQL cursors are closed, SQL prepared statements are implicitly discarded, and LOCK TABLE locks are released when the activation group ends. *ENDMOD: SQL cursors are closed and SQL prepared statements are implicitly discarded when the module is exited. LOCK TABLE locks are released when the rst SQL program on the call stack ends. | | | | | | | | | | | | | | | ALWCPYDTA Species whether a copy of the data can be used in a SELECT statement. *OPTIMIZE: The system determines whether to use the data retrieved directly from the database or to use a copy of the data. The decision is based on which method provides the best performance. If COMMIT is *CHG or *CS and ALWBLK is not *ALLREAD, or if COMMIT is *ALL or *RR, then a copy of the data is used only when it is necessary to run a query. *YES: A copy of the data is used only when necessary. *NO: A copy of the data is not allowed. If a temporary copy of the data is required to perform the query, an error message is returned. ALWBLK Species whether the database manager can use record blocking, and the extent to which blocking can be used for read-only cursors. *ALLREAD: Rows are blocked for read-only cursors if *NONE or *CHG is specied on the COMMIT parameter. All cursors in a program that are not

686

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCI
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | explicitly able to be updated are opened for read-only processing even though EXECUTE or EXECUTE IMMEDIATE statements may be in the program. Specifying *ALLREAD: v Allows record blocking under commitment control level *CHG in addition to the blocking allowed for *READ. v Can improve the performance of almost all read-only cursors in programs, but limits queries in the following ways: The Rollback (ROLLBACK) command, a ROLLBACK statement in host languages, or the ROLLBACK HOLD SQL statement does not reposition a read-only cursor when *ALLREAD is specied. Dynamic running of a positioned UPDATE or DELETE statement (for example, using EXECUTE IMMEDIATE), cannot be used to update a row in a cursor unless the DECLARE statement for the cursor includes the FOR UPDATE clause. *NONE: Rows are not blocked for retrieval of data for cursors. Specifying *NONE: v Guarantees that the data retrieved is current. v May reduce the amount of time required to retrieve the rst row of data for a query. v Stops the database manager from retrieving a block of data rows that is not used by the program when only the rst few rows of a query are retrieved before the query is closed. v Can degrade the overall performance of a query that retrieves a large number of rows. *READ: Records are blocked for read-only retrieval of data for cursors when: v *NONE is specied on the COMMIT parameter, which indicates that commitment control is not used. v The cursor is declared with a FOR READ ONLY clause or there are no dynamic statements that could run a positioned UPDATE or DELETE statement for the cursor. Specifying *READ can improve the overall performance of queries that meet the above conditions and retrieve a large number of records. DLYPRP Species whether the dynamic statement validation for a PREPARE statement is delayed until an OPEN, EXECUTE, or DESCRIBE statement is run. Delaying validation improves performance by eliminating redundant validation. *NO: Dynamic statement validation is not delayed. When the dynamic statement is prepared, the access plan is validated. When the dynamic statement is used in an OPEN or EXECUTE statement, the access plan is revalidated. Because the authority or the existence of objects referred to by the dynamic statement may change, you must still check the SQLCODE or SQLSTATE after issuing the OPEN or EXECUTE statement to ensure that the dynamic statement is still valid. *YES: Dynamic statement validation is delayed until the dynamic statement is used in an OPEN, EXECUTE, or DESCRIBE SQL statement. When the dynamic statement is used, the validation is completed and an access plan is
Appendix D. DB2 UDB for AS/400 CL Command Descriptions

687

CRTSQLCI
built. If you specify *YES on this parameter, you should check the SQLCODE and SQLSTATE after running an OPEN, EXECUTE, or DESCRIBE statement to ensure that the dynamic statement is valid. Note: If you specify *YES, performance is not improved if the INTO clause is used on the PREPARE statement or if a DESCRIBE statement uses the dynamic statement before an OPEN is issued for the statement. GENLVL Species the severity level at which the create operation fails. If errors occur that have a severity level greater than this value, the operation ends. 10: The default severity level is 10.

severity-level: Specify a value ranging from 0 through 40.


MARGINS Species the part of the precompiler input record that contains source text. | | *SRCFILE: The precompiler uses le member margin values that are specied by the user on the SRCMBR parameter. The margin values default to 1 and 80. Element 1: Left Margin

left: Specify the beginning position for the statements. Valid values range from 1 through 80.
Element 2: Right Margin

right: Specify the ending position for the statements. Valid values range from 1 through 80.
DATFMT Species the format used when accessing date result columns. All output date elds are returned in the specied format. For input date strings, the specied value is used to determine whether the date is specied in a valid format. Note: An input date string that uses the format *USA, *ISO, *EUR, or *JIS is always valid. If a relational database is specied on the RDB parameter and the database is on a system that is not an AS/400 system, then *USA, *ISO, *EUR, or *JIS must be specied. *JOB: The format specied for the job is used. Use the Display Job (DSPJOB) command to determine the current date format for the job. *USA: The United States date format (mm/dd/yyyy) is used. *ISO: The International Organization for Standardization (ISO) date format (yyyy-mm-dd) is used. *EUR: The European date format (dd.mm.yyyy) is used. *JIS: The Japanese Industrial Standard date format (yyyy-mm-dd) is used. *MDY: The date format (mm/dd/yy) is used.

688

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCI
*DMY: The date format (dd/mm/yy) is used. *YMD: The date format (yy/mm/dd) is used. *JUL: The Julian date format (yy/ddd) is used. DATSEP Species the separator used when accessing date result columns. Note: This parameter applies only when *JOB, *MDY, *DMY, *YMD, or *JUL is specied on the DATFMT parameter. *JOB:The date separator specied for the job at precompile time is used. Use the Display Job (DSPJOB) command to determine the current value for the job. /: A slash (/) is used. .: A period (.) is used. ,: A comma (,) is used. -: A dash (-) is used. : A blank ( ) is used. *BLANK: A blank ( ) is used. TIMFMT Species the format used when accessing time result columns. For input time strings, the specied value is used to determine whether the time is specied in a valid format. Note: An input time string that uses the format *USA, *ISO, *EUR, or *JIS is always valid. If a relational database is specied on the RDB parameter and the database is on a system that is not another AS/400 system, the time format must be *USA, *ISO, *EUR, *JIS, or *HMS with a time separator of colon or period. *HMS: The hh:mm:ss format is used. *USA: The United States time format hh:mm xx is used, where xx is AM or PM. *ISO: The International Organization for Standardization (ISO) time format hh.mm.ss is used. *EUR: The European time format hh.mm.ss is used. *JIS: The Japanese Industrial Standard time format hh:mm:ss is used. TIMSEP Species the separator used when accessing time result columns. Note: This parameter applies only when *HMS is specied on the TIMFMT parameter.
Appendix D. DB2 UDB for AS/400 CL Command Descriptions

689

CRTSQLCI
*JOB: The time separator specied for the job at precompile time is used. Use the Display Job (DSPJOB) command to determine the current value for the job. :: A colon (:) is used. .: A period (.) is used. ,: A comma (,) is used. : A blank ( ) is used. *BLANK: A blank ( ) is used. REPLACE Species if a SQL module, program, service program or package is created when there is an existing SQL module, program, service program, or package of the same name and type in the same library. The value of this parameter is passed to the CRTCMOD, CRTBNDC, CRTSRVPGM, and CRTSQLPKG commands. *YES: A new SQL module, program, service program, or package is created, and any existing object of the same name and type in the specied library is moved to QRPLOBJ. *NO: A new SQL module, program, service program, or package is not created if an object of the same name and type already exists in the specied library. RDB Species the name of the relational database where the SQL package object is created. *LOCAL: The program is created as a distributed SQL program. The SQL statements will access the local database. An SQL package object is not created as part of the precompile process. The Create Structured Query Language Package (CRTSQLPKG) command can be used.

relational-database-name: Specify the name of the relational database where the new SQL package object is to be created. When the name of the local relational database is specied, the program created is still a distributed SQL program. The SQL statements will access the local database.
*NONE: An SQL package object is not created. The program object is not a distributed program and the Create Structured Query Language Package (CRTSQLPKG) command cannot be used. USER Species the user name sent to the remote system when starting the conversation. This parameter is valid only when RDB is specied. *CURRENT: The user prole under which the current job is running is used.

user-name: Specify the user name being used for the application server job.
PASSWORD Species the password to be used on the remote system. This parameter is valid only if RDB is specied.

690

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCI
*NONE: No password is sent. If this value is specied, USER(*CURRENT) must also be specied.

password: Specify the password of the user name specied on the USER parameter.
RDBCNNMTH Species the semantics used for CONNECT statements. Refer to the SQL Reference, SC41-3612 book for more information. *DUW: CONNECT (Type 2) semantics are used to support distributed unit of work. Consecutive CONNECT statements to additional relational databases do not result in disconnection of previous connections. *RUW: CONNECT (Type 1) semantics are used to support remote unit of work. Consecutive CONNECT statements result in the previous connection being disconnected before a new connection is established. DFTRDBCOL Species the collection name used for the unqualied names of tables, views, indexes, and SQL packages. This parameter applies only to static SQL statements. *NONE: The naming convention dened on the OPTION parameter is used.

collection-name: Specify the name of the collection identier. This value is used instead of the naming convention specied on the OPTION parameter.
| | | | | | | | | | DYNDFTCOL Species whether the default collection name specied for the DFTRDBCOL parameter is also used for dynamic statements. *NO: Do not use the value specied on the DFTRDBCOL parameter for unqualied names of tables, views, indexes, and SQL packages for dynamic SQL statements. The naming convention specied on the OPTION parameter is used. *YES: The collection name specied on the DFTRDBCOL parameter will be used for the unqualied names of the tables, views, indexes, and SQL packages in dynamic SQL statements. SQLPKG Species the qualied name of the SQL package created on the relational database specied on the RDB parameter of this command. The possible library values are: *OBJLIB: The package is created in the library with the same name as the library specied on the OBJ parameter. library-name: Specify the name of the library where the package is created. *OBJ: The name of the SQL package is the same as the object name specied on the OBJ parameter.

package-name: Specify the name of the SQL package. If the remote system is not an AS/400 system, no more than 8 characters can be specied.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

691

CRTSQLCI
| | | | | | | | | | | | SQLPATH Species the path to be used to nd procedures, functions, and user dened types in static SQL statements. *NAMING: The path used depends on the naming convention specied on the OPTION parameter. For *SYS naming, the path used is *LIBL, the current library list at runtime. For *SQL naming, the path used is QSYS, QSYS2, userid, where userid is the value of the USER special register. If a collection-name is specied on the DFTRDBCOL parameter, the collection-name takes the place of userid. *LIBL: The path used is the library list at runtime.

collection-name: Specify a list of one or more collection names. A maximum of 43 individual collections may be specied.
SAAFLAG Species the IBM SQL agging function. This parameter ags SQL statements to verify whether they conform to IBM SQL syntax More information about which IBM database products IBM SQL syntax is in the DRDA IBM SQL Reference, SC26-3255-00. *NOFLAG: The precompiler does not check to see whether SQL statements conform to IBM SQL syntax. *FLAG: The precompiler checks to see whether SQL statements conform to IBM SQL syntax FLAGSTD Species the American National Standards Institute (ANSI) agging function. This parameter ags SQL statements to verify whether they conform to the following standards.
ANSI X3.135-1992 entry ISO 9075-1992 entry FIPS 127.2 entry

*NONE: The precompiler does not check to see whether SQL statements conform to ANSI standards. *ANS: The precompiler checks to see whether SQL statements conform to ANSI standards. DBGVIEW This parameter species the type of source debug information to be provided by the SQL precompiler. *NONE: The source view will not be generated. *SOURCE: The SQL precompiler provides the source views for the root and if necessary, SQL INCLUDE statements. A view is provided that contains the statements generated by the precompiler. USRPRF Species the user prole that is used when the compiled program object is run, including the authority that the program object has for each object in static SQL

692

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCI
statements. The prole of either the program owner or the program user is used to control which objects can be used by the program object. *NAMING: The user prole is determined by the naming convention. If the naming convention is *SQL, USRPRF(*OWNER) is used. If the naming convention is *SYS, USRPRF(*USER) is used. *USER: The prole of the user running the program object is used. *OWNER: The user proles of both the program owner and the program user are used when the program is run. DYNUSRPRF Species the user prole to be used for dynamic SQL statements. *USER: Local dynamic SQL statements are run under the prole of the programs user. Distributed dynamic SQL statements are run under the prole of the SQL packages user. *OWNER: Local dynamic SQL statements are run under the prole of the programs owner. Distributed dynamic SQL statements are run under the prole of the SQL packages owner. SRTSEQ Species the sort sequence table to be used for string comparisons in SQL statements. Note: *HEX must be specied for this parameter on distributed applications where the application server is not on an AS/400 system or the release level is prior to V2R3M0. *JOB: The SRTSEQ value for the job is retrieved during the precompile. *JOBRUN: The SRTSEQ value for the job is retrieved when the program is run. For distributed applications, SRTSEQ(*JOBRUN) is valid only when LANGID(*JOBRUN) is also specied. *HEX: A sort sequence table is not used. The hexadecimal values of the characters are used to determine the sort sequence. *LANGIDSHR: The sort sequence table uses the same weight for multiple characters, and is the shared-weight sort sequence table associated with the language specied on the LANGID parameter. *LANGIDUNQ: The unique-weight sort table for the language specied on the LANGID parameter is used. The name of the table name can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used.

library-name: Specify the name of hte library to be searched. table-name: Specify the name of the sort sequence table to be used.
Appendix D. DB2 UDB for AS/400 CL Command Descriptions

693

CRTSQLCI
LANGID Species the language identier to be used when SRTSEQ(*LANGIDUNQ) or SRTSEQ(*LANGIDSHR) is specied. *JOB: The LANGID value for the job is retrieved during the precompile. *JOBRUN: The LANGID value for the job is retrieved when the program is run. For distributed applications, LANGID(*JOBRUN) is valid only when SRTSEQ(*JOBRUN) is also specied.

language-identier: Specify a language identier.


OUTPUT Species whether the precompiler listing is generated. *NONE: The precompiler listing is not generated. *PRINT: The precompiler listing is generated. PRTFILE Species the qualied name of the printer device le to which the precompiler printout is directed. The le must have a minimum length of 132 bytes. If a le with a record length of less than 132 bytes is specied, information is lost. The name of the printer le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library to be searched. QSYSPRT: If a le name is not specied, the precompiler printout is directed to the IBM-supplied printer le QSYSPRT.

printer-le-name: Specify the name of the printer device le to which the precompiler printout is directed.
| | | | | | | | | | | | | | | TOSRCFILE Species the qualied name of the source le that is to contain the output source member that the SQL precompiler has processed. If the precompiler cannot nd the specied source le, it creates the le. The output member will have the same name as the name that is specied for the SRCMBR parameter. The possible library values are: QTEMP: The library QTEMP will be used. *LIBL: The jobs library list is searched for the specied le. If the le is not found in any library in the library list, the le will be created in the current library. *CURLIB: The current library for the job will be used. If no library is specied as the current library for the job, the QGPL library will be used. library-name: Specify the name of the library that is to contain the output source le. QSQLTEMP: The source le QSQLTEMP will be used.

694

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCI
| |

source-le-name: Specify the name of the source le to contain the output source member.
TEXT Species the text that briey describes the program and the function. More information on this parameter is in Appendix A, Expanded Parameter Descriptions in the CL Reference book. *SRCMBRTXT: The text is taken from the source le member being used to create the C program. Text can be added or changed for a database source member by using the Start Source Entry Utility (STRSEU) command, or by using either the Add Physical File Member (ADDPFM) command or the Change Physical File Member (CHGPFM) command. If the source le is an inline le or a device le, the text is blank. *BLANK: Text is not specied.

description: Specify no more than 50 characters of text, enclosed in apostrophes.

Example
CRTSQLCI PAYROLL OBJTYPE(*MODULE) TEXT('Payroll Program')

| | | | | | |

This command runs the SQL precompiler which precompiles the source and stores the changed source in member PAYROLL in le QSQLTEMP in library QTEMP. The ILE C for AS/400 compiler is called to create module PAYROLL in the current library by using the source member created by the SQL precompiler.

CRTSQLCPPI (Create Structured Query Language C++ Object) Command


Job: B,I Pgm: B,I
OBJ( library-name/

REXX: B,I
*CURLIB/

Exec
object-name )

CRTSQLCPPI

| |
SRCFILE(

*LIBL/ *CURLIB/ library-name/

QCSRC source-file-name

| |
SRCMBR( *OBJ source-file-member-name )

(1)

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

695

CRTSQLCPPI
| |
OPTION( OPTION Details ) TGTRLS( *CURRENT VxRxMx

| |
INCFILE(

*LIBL/ *CURLIB/ library-name/

*SRCFILE source-file-name

| |
COMMIT(

*UR *CHG *ALL *RS *CS *NONE *NC *RR

CLOSQLCSR( )

*ENDACTGRP *ENDMOD

| |
ALWCPYDTA(

*OPTIMIZE *YES *NO

ALWBLK(

*ALLREAD *NONE *READ

| |
DLYPRP(

*NO *YES

GENLVL(

10 severity-level

| |
MARGINS(

*SRCFILE left-right

DATFMT(

*JOB *USA *ISO *EUR *JIS *MDY *DMY *YMD *JUL

| |
DATSEP(

*JOB '/' '.' ',' '-' ' ' *BLANK

TIMFMT(

*HMS *USA *ISO *EUR *JIS

696

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCPPI
|
TIMSEP( *JOB ':' '.' ',' ' ' *BLANK )

| | |
REPLACE(

*YES *NO

RDB(

*LOCAL relational-database-name *NONE

| |
USER(

*CURRENT user-name

PASSWORD(

*NONE password

| |
RDBCNNMTH(

*DUW *RUW

DFTRDBCOL(

*NONE collection-name

| |
DYNDFTCOL(

*NO *YES

| |
SQLPKG(

*OBJLIB/ library-name/

*OBJ package-name

| |
SQLPATH(

*NAMING *LIBL

collection-name

| |
SAAFLAG(

*NOFLAG *FLAG

FLAGSTD(

*NONE *ANS

| |
DBGVIEW(

*NONE *SOURCE

USRPRF(

*NAMING *OWNER *USER

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

697

CRTSQLCPPI
| |
DYNUSRPRF( *USER *OWNER

| |
SRTSEQ(

*JOB *JOBRUN *LANGIDUNQ *LANGIDSHR *HEX *LIBL/ table-name *CURLIB/ library-name/

| |
LANGID(

*JOB *JOBRUN language-identifier

OUTPUT(

*NONE *PRINT

| |
PRTFILE(

*LIBL/ *CURLIB/ library-name/

QSYSPRT printer-file-name

| | |
TOSRCFILE( *LIBL/ *CURLIB/ library-name/ QTEMP/ QSQLTEMP source-file-name

| |
TEXT(

*SRCMBRTXT *BLANK 'description'

| | | | OPTION Details:
*XREF *NOXREF *GEN *NOGEN *JOB *PERIOD *SYSVAL *COMMA *SYS *SQL *NOSECLVL *SECLVL

| |

*NOCNULRQD *CNULRQD

*NOEVENTF *EVENTF

*OPTLOB *NOOPTLOB

698

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCPPI
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Notes: 1. All parameters preceding this point can be specied in positional form.

Purpose
The Create Structured Query Language C++ Object (CRTSQLCPPI) command calls the Structured Query Language (SQL) precompiler. The SQL precompiler precompiles C++ source containing SQL statements, produces a temporary source member, and then optionally calls the C++ compiler to create a module. To precompile for the VisualAge C++ for OS/400 compiler, use the CVTSQLCPP command.

Parameters
OBJ Species the qualied name of the object that the precompiler creates. One of the following library values can qualify the name of the object: *CURLIB The object is created in the current library for the job. If you do not specify a library as the current library for the job, the precompiler uses QGPL library. library-name: Specify the name of the library where the object is created.

object-name: Specify the name of the object that the precompiler creates.
SRCFILE Species the qualied name of the source le that contains the C++ source with SQL statements. One of the following library values can qualify the name of the source le: *LIBL: The precompiler searches all libraries in the jobs library list until it nds the rst match. *CURLIB: The precompiler searches the current library for the job. If you do not specify a library as the current library for the job, it uses the QGPL library. library-name: Specify the name of the library that the precompiler searches. QCSRC: If you do not specify the source le name, the IBM-supplied source le QCSRC contains the C++ source.

source-le-name: Specify the name of the source le that contains the C++ source.
SRCMBR Species the name of the source le member that contains the C++ source. Specify this parameter only if the source le name in the SRCFILE parameter is a database le. If you do not specify this parameter, the precompiler uses the OBJ name that is specied on the OBJ parameter. *OBJ: Species that the C++ source is in the member of the source le that has the same name as the le specied on the OBJ parameter.

source-le-member-name: Specify the name of the member that contains the C++ source.
Appendix D. DB2 UDB for AS/400 CL Command Descriptions

699

CRTSQLCPPI
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | OPTION Species whether one or more of the following options are used when the C++ source is precompiled. If an option is specied more than once, or if two options conict, the last option specied is used. Element 1: Cross-Reference Options *XREF: The precompiler cross-references items in the program to the statement numbers in the program that refer to those items. *NOXREF: The precompiler does not cross-reference names. Element 2: Program Creation Options *GEN: The precompiler creates the module object. *NOGEN: The precompiler does not call the C++ compiler, and does not create a module. Element 3: Decimal Point Options *JOB: The value used as the decimal point for numeric constants in SQL is the representation of decimal point that is specied for the job at precompile time. Note: If the job species that the value used as the decimal point is a comma, any numeric constants in lists (such as in the SELECT clause or the VALUES clause) must be separated by a comma followed by a blank. For example, VALUES(1,1, 2,23, 4,1) is equivalent to VALUES(1.1,2.23,4.1) in which the decimal point is a period. *PERIOD:The value used as the decimal point for numeric constants in SQL statements is a period. *COMMA: The value used as the decimal point for numeric constants in SQL statements is a comma. Note: Any numeric constants in lists (such as in the SELECT clause or the VALUES clause) must be separated by a comma followed by a blank. For example, VALUES(1,1, 2,23, 4,1) is equivalent to VALUES(1.1,2.23,4.1) where the decimal point is a period. Element 4: Naming Convention Options *SYS: The system naming convention (library-name/le-name) is used. *SQL: The SQL naming convention is used (collection-name.table-name). When creating a package on a remote database other than an AS/400 system, you must specify *SQL as the naming convention. Element 5: Second-Level Message Text Option *NOSECLVL: Second-level text descriptions are not added to the listing. *SECLVL: Second-level text with replacement data is added for all messages on the listing.

700

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCPPI
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Element 6: NUL Required Options *NOCNULRQD: For output character and graphic host variables, the NUL-terminator is not returned when the host variable is exactly the same length as the data. Input character and graphic host variables do not require a NUL-terminator. *CNULRQD: Output character and graphic host variables always contain the NUL-terminator. If there is not enough space for the NUL-terminator, the data is truncated, and the NUL-terminator is added. Input character and graphic host variables require a NUL-terminator. Element 7: Event File Creation *NOEVENTF: The compiler will not produce an event le for use by CoOperative Development Environment/400 (CODE/400). *EVENTF: The compiler produces an event le for use by CoOperative Development Environment/400 (CODE/400). It creates the event le as a member in the le EVFEVENT in your source library. CODE/400 uses this le to offer error feedback that is integrated with the CODE/400 editor. CODE/400 normally species this option on your behalf. Element 8: Large Object Optimization for DRDA *OPTLOB: The rst FETCH for a cursor derermines how the cursor will be used for LOBs (Large Objects) on all subsequent FETCHes. This option remains in effect until the cursor is closed. If the rst FETCH uses a LOB locator to access a LOB column, no subsequent FETCH for that cursor can fetch that LOB column into a LOB host variable. If the rst FETCH places the LOB column into a LOB host variable, no subsequent FETCH for that cursor can use a LOB locator for that column. *NOOPTLOB: There is no restriction on whether a column is retrieved into a LOB locator or into a LOB host variable. This option can cause performance to degrade. TGTRLS Species the release of the operating system on which the user intends to use the object that is being created. The examples given for the *CURRENT value, as well as the release-level value, use the format VxRxMx to specify the release. In this format, Vx is the version, Rx is the release, and Mx is the modication level. For example, V2R3M0 is version 2, release 3, modication level 0. *CURRENT: The object is to be used on the release of the operating system that is currently running on the users system. For example, if V2R3M5 is running on the system, *CURRENT means that the user intends to use the object on a system with V2R3M5 installed. The user can also use the object on a system with any subsequent release of the operating system installed.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

701

CRTSQLCPPI
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Note: If V2R3M5 is running on the system, and the object is to be used on a system with V2R3M0 installed, specify TGTRLS(V2R3M0) not TGTRLS(*CURRENT).

release-level: Specify the release in the format VxRxMx. The object can be used on a system with the specied release or with any subsequent release of the operating system installed.
Valid values depend on the current version, release, and modication level, and they change with each new release. If you specify a release-level which is earlier than the earliest release level that is supported by this command, an error message is sent indicating the earliest supported release. INCFILE Species the qualied name of the source le that contains members that are included in the program with any SQL INCLUDE statement. One of the following library values can qualify the name of the source le: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used.

library-name: Specify the name of the library to be searched.


*SRCFILE: The qualied source le specied in the SRCFILE parameter contains the source le members that are specied on any SQL INCLUDE statement.

source-le-name: Specify the name of the source le that contains the source le members that are specied on any SQL INCLUDE statement. The record length of the source le that is specied here must be no less than the record length of the source le specied on the SRCFILE parameter.
COMMIT Species whether SQL statements in the compiled unit are run under commitment control. Files referred to in the host language source are not affected by this option. Only SQL tables, SQL views, and SQL packages referred to in SQL statements are affected. *CHG or *UR: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs can be seen. *ALL or *RS: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows selected, updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs cannot be seen. *CS: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows updated, deleted, and inserted are locked until the end of the unit of work (transaction). A row that is selected, but not updated, is locked until the next row is selected. Uncommitted changes in other jobs cannot be seen.

702

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCPPI
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | *NONE or *NC: Species that commitment control is not used. Uncommitted changes in other jobs can be seen. If the SQL DROP COLLECTION statement is included in the program, *NONE or *NC must be used. If a relational database is specied on the RDB parameter and the relational database is on a system that is not on an AS/400, *NONE or *NC cannot be specied. *RR: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows selected, updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs cannot be seen. All tables referred to in SELECT, UPDATE, DELETE, and INSERT statements are locked exclusively until the end of the unit of work (transaction). CLOSQLCSR Species when SQL cursors are implicitly closed, SQL prepared statements are implicitly discarded, and LOCK TABLE locks are released. SQL cursors are explicitly closed when you issue the CLOSE, COMMIT, or ROLLBACK (without HOLD) SQL statements. *ENDACTGRP: SQL cursors are closed, SQL prepared statements are implicitly discarded, and LOCK TABLE locks are released when the activation group ends. *ENDMOD: SQL cursors are closed, and SQL prepared statements are implicitly discarded when the module is exited. LOCK TABLE locks are released when the rst SQL program on the call stack ends. ALWCPYDTA Species whether a copy of the data can be used in a SELECT statement. *OPTIMIZE: The system determines whether to use the data retrieved directly from the database or to use a copy of the data. The decision is based on which method provides the best performance. If COMMIT is *CHG or *CS and ALWBLK is not *ALLREAD, or if COMMIT is *ALL or *RR, then a copy of the data is used only when it is necessary to run a query. *YES: A copy of the data is used only when necessary. *NO: A copy of the data is not allowed. If a temporary copy of the data is required to perform the query, an error message is returned. ALWBLK Species whether the database manager can use record blocking, and the extent to which blocking can be used for read-only cursors. *ALLREAD: Rows are blocked for read-only cursors if *NONE or *CHG is specied on the COMMIT parameter. All cursors in a program that are not explicitly able to be updated are opened for read-only processing even though EXECUTE or EXECUTE IMMEDIATE statements may be in the program. Specifying *ALLREAD: v Allows record blocking under commitment control level *CHG in addition to the blocking allowed for *READ. v Can improve the performance of almost all read-only cursors in programs, but limits queries in the following ways:

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

703

CRTSQLCPPI
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The Rollback (ROLLBACK) command, a ROLLBACK statement in host languages, or the ROLLBACK HOLD SQL statement does not reposition a read-only cursor when *ALLREAD is specied. Dynamic running of a positioned UPDATE or DELETE statement (for example, using EXECUTE IMMEDIATE), cannot be used to update a row in a cursor unless the DECLARE statement for the cursor includes the FOR UPDATE clause. *NONE: Rows are not blocked for retrieval of data for cursors. Specifying *NONE: v Guarantees that the data retrieved is current. v May reduce the amount of time required to retrieve the rst row of data for a query. v Stops the database manager from retrieving a block of data rows that is not used by the program when only the rst few rows of a query are retrieved before the query is closed. v Can degrade the overall performance of a query that retrieves a large number of rows. *READ: Records are blocked for read-only retrieval of data for cursors when: v *NONE is specied on the COMMIT parameter, which indicates that commitment control is not used. v The cursor is declared with a FOR READ ONLY clause or there are no dynamic statements that could run a positioned UPDATE or DELETE statement for the cursor. Specifying *READ can improve the overall performance of queries that meet the above conditions and retrieve a large number of records. DLYPRP Species whether the dynamic statement validation for a PREPARE statement is delayed until an OPEN, EXECUTE, or DESCRIBE statement is run. Delaying validation improves performance by eliminating redundant validation. *NO: Dynamic statement validation is not delayed. When the dynamic statement is prepared, the access plan is validated. When the dynamic statement is used in an OPEN or EXECUTE statement, the access plan is revalidated. Because the authority or the existence of objects referred to by the dynamic statement may change, you must still check the SQLCODE or SQLSTATE after issuing the OPEN or EXECUTE statement to ensure that the dynamic statement is still valid. *YES: Dynamic statement validation is delayed until the dynamic statement is used in an OPEN, EXECUTE, or DESCRIBE SQL statement. When the dynamic statement is used, the validation is completed, and an access plan is built. If you specify *YES on this parameter, you should check the SQLCODE and SQLSTATE after running an OPEN, EXECUTE, or DESCRIBE statement to ensure that the dynamic statement is valid. Note: If you specify *YES, performance is not improved if the INTO clause is used on the PREPARE statement or if a DESCRIBE statement uses the dynamic statement before an OPEN is issued for the statement.

704

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCPPI
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | GENLVL Species the severity level at which the create operation fails. If errors occur that have a severity level greater than this value, the operation ends. 10: The default severity level is 10.

severity-level: Specify a value ranging from 0 through 40.


MARGINS Species the part of the precompiler input record that contains source text. *SRCFILE: The le member margin values specied by the user on the SRCMBR parameter are used. If the member is of SQLCLE, SQLC, C, or CLE source type, the margin values are the values that are specied on the SEU services display. If the member is a different source type, the margin values are the default values of 1 and 80. Element 1: Left Margin

left: Specify the beginning position for the statements. Valid values range from 1 through 80.
Element 2: Right Margin

right: Specify the ending position for the statements. Valid values range from 1 through 80.
DATFMT Species the format used when accessing date result columns. All output date elds are returned in the specied format. For input date strings, the specied value is used to determine whether the date is specied in a valid format. Note: An input date string that uses the format *USA, *ISO, *EUR, or *JIS is always valid. If a relational database is specied on the RDB parameter and the database is on a system that is not an AS/400 system, then *USA, *ISO, *EUR, or *JIS must be specied. *JOB: The format specied for the job is used. Use the Display Job (DSPJOB) command to determine the current date format for the job. *USA: The United States date format (mm/dd/yyyy) is used. *ISO: The International Organization for Standardization (ISO) date format (yyyy-mm-dd) is used. *EUR: The European date format (dd.mm.yyyy) is used. *JIS: The Japanese Industrial Standard date format (yyyy-mm-dd) is used. *MDY: The date format (mm/dd/yy) is used. *DMY: The date format (dd/mm/yy) is used. *YMD: The date format (yy/mm/dd) is used.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

705

CRTSQLCPPI
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | *JUL: The Julian date format (yy/ddd) is used. DATSEP Species the separator used when accessing date result columns. Note: This parameter applies only when *JOB, *MDY, *DMY, *YMD, or *JUL is specied on the DATFMT parameter. *JOB:The date separator specied for the job at precompile time is used. Use the Display Job (DSPJOB) command to determine the current value for the job. /: A slash (/) is used. .: A period (.) is used. ,: A comma (,) is used. -: A dash (-) is used. : A blank ( ) is used. *BLANK: A blank ( ) is used. TIMFMT Species the format used when accessing time result columns. For input time strings, the specied value is used to determine whether the time is specied in a valid format. Note: An input time string that uses the format *USA, *ISO, *EUR, or *JIS is always valid. If a relational database is specied on the RDB parameter and the database is on a system that is not another AS/400 system, the time format must be *USA, *ISO, *EUR, *JIS, or *HMS with a time separator of colon or period. *HMS: The hh:mm:ss format is used. *USA: The United States time format hh:mm xx is used, where xx is AM or PM. *ISO: The International Organization for Standardization (ISO) time format hh.mm.ss is used. *EUR: The European time format hh.mm.ss is used. *JIS: The Japanese Industrial Standard time format hh:mm:ss is used. TIMSEP Species the separator used when accessing time result columns. Note: This parameter applies only when *HMS is specied on the TIMFMT parameter. *JOB: The time separator specied for the job at precompile time is used. Use the Display Job (DSPJOB) command to determine the current value for the job.

706

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCPPI
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | :: A colon (:) is used. .: A period (.) is used. ,: A comma (,) is used. : A blank ( ) is used. *BLANK: A blank ( ) is used. REPLACE Species if an SQL module is created when there is an existing SQL module of the same name in the same library. The value of this parameter is passed to the CRTCPPMOD command. *YES: A new SQL module is created, and any existing object of the same name in the specied library is moved to QRPLOBJ. *NO: A new SQL module is not created if an object of the same name already exists in the specied library. RDB Species the name of the relational database where the SQL package object is created. *LOCAL: The program is created as a distributed SQL program. The SQL statements will access the local database. An SQL package object is not created as part of the precompile process. The Create Structured Query Language Package (CRTSQLPKG) command can be used.

relational-database-name: Specify the name of the relational database where the new SQL package object is to be created. When the name of the local relational database is specied, the program created is still a distributed SQL program. The SQL statements will access the local database.
*NONE: An SQL package object is not created. The program object is not a distributed program and the Create Structured Query Language Package (CRTSQLPKG) command cannot be used. USER Species the user name sent to the remote system when starting the conversation. This parameter is valid only when RDB is specied. *CURRENT: The user prole under which the current job is running is used.

user-name: Specify the user name being used for the application server job.
PASSWORD Species the password to be used on the remote system. This parameter is valid only if RDB is specied. *NONE: No password is sent. If this value is specied, USER(*CURRENT) must also be specied.

password: Specify the password of the user name that is specied on the USER parameter.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

707

CRTSQLCPPI
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | RDBCNNMTH Species the semantics used for CONNECT statements. Refer to the SQL Reference, SC41-3612 book for more information. *DUW: CONNECT (Type 2) semantics are used to support distributed unit of work. Consecutive CONNECT statements to additional relational databases do not result in disconnection of previous connections. *RUW: CONNECT (Type 1) semantics are used to support remote unit of work. Consecutive CONNECT statements result in the previous connection being disconnected before a new connection is established. DFTRDBCOL Species the collection name used for the unqualied names of tables, views, indexes, and SQL packages. This parameter applies only to static SQL statements. *NONE: The naming convention dened on the OPTION parameter is used.

collection-name: Specify the name of the collection identier. This value is used instead of the naming convention that is specied on the OPTION parameter.
DYNDFTCOL Species whether the default collection name specied for the DFTRDBCOL parameter is also used for dynamic statements. *NO: Do not use the value specied on the DFTRDBCOL parameter for unqualied names of tables, views, indexes, and SQL packages for dynamic SQL statements. The naming convention specied on the OPTION parameter is used. *YES: The collection name specied on the DFTRDBCOL parameter will be used for the unqualied names of the tables, views, indexes, and SQL packages in dynamic SQL statements. SQLPKG Species the qualied name of the SQL package created on the relational database specied on the RDB parameter of this command. The possible library values are: *OBJLIB: The package is created in the library with the same name as the library specied on the OBJ parameter. library-name: Specify the name of the library where the package is created. *OBJ: The name of the SQL package is the same as the object name specied on the OBJ parameter.

package-name: Specify the name of the SQL package. If the remote system is not an AS/400 system, no more than 8 characters can be specied.
SQLPATH Species the path to be used to nd procedures, functions, and user dened types in static SQL statements. *NAMING: The path used depends on the naming convention specied on the OPTION parameter.

708

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCPPI
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | For *SYS naming, the path used is *LIBL, the current library list at runtime. For *SQL naming, the path used is QSYS, QSYS2, userid, where userid is the value of the USER special register. If a collection-name is specied on the DFTRDBCOL parameter, the collection-name takes the place of userid. *LIBL: The path used is the library list at runtime.

collection-name: Specify a list of one or more collection names. A maximum of 43 individual collections may be specied.
SAAFLAG Species the IBM SQL agging function. This parameter ags SQL statements to verify whether they conform to IBM SQL syntax More information about which IBM database products IBM SQL syntax is in the DRDA IBM SQL Reference, SC26-3255-00. *NOFLAG: The precompiler does not check to see whether SQL statements conform to IBM SQL syntax. *FLAG: The precompiler checks to see whether SQL statements conform to IBM SQL syntax. FLAGSTD Species the American National Standards Institute (ANSI) agging function. This parameter ags SQL statements to verify whether they conform to the following standards.
ANSI X3.135-1992 entry ISO 9075-1992 entry FIPS 127.2 entry

*NONE: The precompiler does not check to see whether SQL statements conform to ANSI standards. *ANS: The precompiler checks to see whether SQL statements conform to ANSI standards. DBGVIEW This parameter species the type of source debug information to be provided by the SQL precompiler. *NONE: The source view will not be generated. *SOURCE: The SQL precompiler provides the source views for the root and if necessary, SQL INCLUDE statements. A view is provided that contains the statements generated by the precompiler. USRPRF Species the user prole that is used when the compiled program object is run, including the authority that the program object has for each object in static SQL statements. The prole of either the program owner or the program user is used to control which objects can be used by the program object. *NAMING: The user prole is determined by the naming convention. If the naming convention is *SQL, USRPRF(*OWNER) is used. If the naming convention is *SYS, USRPRF(*USER) is used. *USER: The prole of the user running the program object is used.
Appendix D. DB2 UDB for AS/400 CL Command Descriptions

709

CRTSQLCPPI
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | *OWNER: The user proles of both the program owner and the program user are used when the program is run. DYNUSRPRF Species the user prole to be used for dynamic SQL statements. *USER: Local dynamic SQL statements are run under the prole of the programs user. Distributed dynamic SQL statements are run under the prole of the SQL packages user. *OWNER: Local dynamic SQL statements are run under the prole of the programs owner. Distributed dynamic SQL statements are run under the prole of the SQL packages owner. SRTSEQ Species the sort sequence table to be used for string comparisons in SQL statements. Note: *HEX must be specied for this parameter on distributed applications where the application server is not on an AS/400 system or the release level is prior to V2R3M0. *JOB: The SRTSEQ value for the job is retrieved during the precompile. *JOBRUN: The SRTSEQ value for the job is retrieved when the program is run. For distributed applications, SRTSEQ(*JOBRUN) is valid only when LANGID(*JOBRUN) is also specied. *HEX: A sort sequence table is not used. The hexadecimal values of the characters are used to determine the sort sequence. *LANGIDSHR: The sort sequence table uses the same weight for multiple characters, and is the shared-weight sort sequence table associated with the language specied on the LANGID parameter. *LANGIDUNQ: The unique-weight sort table for the language that is specied on the LANGID parameter is used. The name of the table name can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of hte library to be searched.

table-name: Specify the name of the sort sequence table to be used.


LANGID Species the language identier to be used when SRTSEQ(*LANGIDUNQ) or SRTSEQ(*LANGIDSHR) is specied. *JOB: The LANGID value for the job is retrieved during the precompile. *JOBRUN: The LANGID value for the job is retrieved when the program is run. For distributed applications, LANGID(*JOBRUN) is valid only when SRTSEQ(*JOBRUN) is also specied.

710

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLCPPI
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |

language-identier: Specify a language identier.


OUTPUT Species whether the precompiler listing is generated. *NONE: The precompiler listing is not generated. *PRINT: The precompiler listing is generated. PRTFILE Species the qualied name of the printer device le to which the precompiler printout is directed. The le must have a minimum length of 132 bytes. If a le with a record length of less than 132 bytes is specied, information is lost. The name of the printer le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used.

library-name: Specify the name of the library to be searched.


QSYSPRT: If a le name is not specied, the precompiler printout is directed to the IBM-supplied printer le QSYSPRT.

printer-le-name: Specify the name of the printer device le to which the precompiler printout is directed.
TOSRCFILE Species the qualied name of the source le that is to contain the output source member that has been processed by the SQL precompiler. If the specied source le is not found, it will be created. The output member will have the same name as the name that is specied for the SRCMBR parameter. The possible library values are: QTEMP: The library QTEMP will be used. *LIBL: The jobs library list is searched for the specied le. If the le is not found in any library in the library list, the le will be created in the current library. *CURLIB: The current library for the job will be used. If no library is specied as the current library for the job, the QGPL library will be used. library-name: Specify the name of the library that is to contain the output source le. QSQLTEMP: The source le QSQLTEMP will be used.

source-le-name: Specify the name of the source le to contain the output source member.
TEXT Species the text that briey describes the program and the function. More information on this parameter is in Appendix A, Expanded Parameter Descriptions in the CL Reference book. *SRCMBRTXT: The text is taken from the source le member being used to create the C++ program. You can add or change text for a database source
Appendix D. DB2 UDB for AS/400 CL Command Descriptions

711

CRTSQLCPPI
| | | | | | | | | | | | | | member by using the Start Source Entry Utility (STRSEU) command. You can also use either the Add Physical File Member (ADDPFM) command or the Change Physical File Member (CHGPFM) command. If the source le is an inline le or a device le, the text is blank. *BLANK: Text is not specied.

description: Specify no more than 50 characters of text, enclosed in apostrophes.

Example
CRTSQLCPPI PAYROLL OBJTYPE(*MODULE) TEXT('Payroll Program')

This command runs the SQL precompiler which precompiles the source and stores the changed source in member PAYROLL in le QSQLTEMP in library QTEMP. The command calls the ILE C++ compiler to create module PAYROLL in the current library by using the source member that is created by the SQL precompiler.

CRTSQLPLI (Create Structured Query Language PL/I) Command


Job: B,I Pgm: B,I
PGM( library-name/

REXX: B,I
*CURLIB/

Exec
program-name )

CRTSQLPLI

*LIBL/ SRCFILE( *CURLIB/ library-name/

QPLISRC source-file-name

(1) *PGM source-file-member-name

SRCMBR(

OPTION(

Option Details TGTRLS(

*CURRENT *PRV VxRxMx

*LIBL/ INCFILE( *CURLIB/ library-name/

*SRCFILE source-file-name

712

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLPLI
*UR *CHG *ALL *RS *CS *NONE *NC *RR *ENDPGM *ENDSQL *ENDJOB

CLOSQLCSR( )

COMMIT(

ALWCPYDTA(

*OPTIMIZE *YES *NO

ALWBLK(

*ALLREAD *NONE *READ

DLYPRP(

*NO *YES

GENLVL(

10 severity-level

MARGINS(

*SRCFILE left-right

DATFMT(

*JOB *USA *ISO *EUR *JIS *MDY *DMY *YMD *JUL

DATSEP(

*JOB '/' '.' ',' '-' ' ' *BLANK

TIMFMT(

*HMS *USA *ISO *EUR *JIS

TIMSEP(

*JOB ':' '.' ',' ' ' *BLANK

REPLACE(

*YES *NO

RDB(

*LOCAL relational-database-name *NONE

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

713

CRTSQLPLI
*CURRENT user-name *NONE password

USER(

PASSWORD(

RDBCNNMTH(

*DUW *RUW

DFTRDBCOL(

*NONE collection-name

DYNDFTCOL(

*NO *YES

*PGMLIB/ SQLPKG( library-name/

*PGM package-name

SQLPATH(

*NAMING *LIBL

collection-name

SAAFLAG(

*NOFLAG *FLAG

FLAGSTD(

*NONE *ANS

*LIBL/ PRTFILE( *CURLIB/ library-name/

QSYSPRT printer-file-name

SRTSEQ(

*JOB *JOBRUN *LANGIDUNQ *LANGIDSHR *HEX *LIBL/ table-name *CURLIB/ library-name/

LANGID(

*JOB *JOBRUN language-ID

USRPRF(

*NAMING *OWNER *USER

714

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLPLI
*USER *OWNER

DYNUSRPRF(

QTEMP/ TOSRCFILE( *LIBL/ *CURLIB/ library-name/

QSQLTEMP source-file-name

TEXT(

*SCRMBRTXT *BLANK 'description'

Option Details:
*NOSRC *NOSOURCE *SRC *SOURCE *NOXREF *XREF *GEN *NOGEN *JOB *PERIOD *SYSVAL *COMMA *SYS *SQL

*NOSECLVL *SECLVL

*OPTLOB ) *NOOPTLOB

Notes: 1. All parameters preceding this point can be specied in positional form.

Purpose
The Create Structured Query Language PL/I (CRTSQLPLI) command calls a Structured Query Language (SQL) precompiler, which precompiles PL/I source containing SQL statements, produces a temporary source member, and optionally calls the PL/I compiler to compile the program.

Parameters
PGM Species the qualied name of the compiled program. The name of the compiled PL/I program can be qualied by one of the following library values: *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library where the compiled PL/I program is created.

program-name: Specify the name of the compiled program.


Appendix D. DB2 UDB for AS/400 CL Command Descriptions

715

CRTSQLPLI
SRCFILE Species the qualied name of the source le that contains the PL/I source with SQL statements. The name of the source le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library to be searched. QPLISRC: If the source le name is not specied, the IBM-supplied source le QPLISRC contains the PL/I source.

source-le-name: Specify the name of the source le that contains the PL/I source.
SRCMBR Species the name of the source le member that contains the PL/I source. This parameter is specied only if the source le name in the SRCFILE parameter is a database le. If this parameter is not specied, the PGM name specied on the PGM parameter is used. *PGM: Species that the PL/I source is in the member of the source le that has the same name as that specied on the PGM parameter.

source-le-member-name: Specify the name of the member that contains the PL/I source.
OPTION Species whether one or more of the following options are used when the PL/I source is precompiled. If an option is specied more than once, or if two options conict, the last option specied is used. Element 1: Source Listing Options *NOSOURCE: or *NOSRC: A source printout is not produced by the precompiler unless errors are detected during precompile or create package. *SOURCE or *SRC: The precompiler produces a source printout consisting of PL/I source input. Element 2: Cross-Reference Options *NOXREF: The precompiler does not cross-reference names. *XREF: The precompiler cross-references items in the program to the statement numbers in the program that refer to those items. Element 3: Program Creation Options *GEN: The compiler creates a program that can run after the program is compiled. An SQL package object is created if a relational database name is specied on the RDB parameter.

716

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLPLI
*NOGEN: The precompiler does not call the C compiler, and a program and SQL package are not created. Element 4: Decimal Point Options *JOB: The value used as the decimal point for numeric constants in SQL is the representation of decimal point specied for the job at precompile time. *PERIOD: The value used as the decimal point for numeric constants used in SQL statements is a period. *SYSVAL: The value used as the decimal point for numeric constants in SQL statements is the QDECFMT system value. Note: If QDECFMT species that the value used as the decimal point is a comma, any numeric constants in lists (such as in the SELECT clause or the VALUES clause) must be separated by a comma followed by a blank. For example, VALUES(1,1, 2,23, 4,1) is equivalent to VALUES(1.1,2.23,4.1) in which the decimal point is a period. *COMMA: The value used as the decimal point for numeric constants in SQL statements is a comma. Note: Any numeric constants in lists (such as in the SELECT clause or the VALUES clause) must be separated by a comma followed by a blank. For example, VALUES(1,1, 2,23, 4,1) is equivalent to VALUES(1.1,2.23,4.1) where the decimal point is a period. Element 5: Naming Convention Options *SYS: The system naming convention (library-name/le-name) is used. *SQL: The SQL naming convention is used (collection-name.table-name). When creating a program on a remote database other than an AS/400 system, *SQL must be specied as the naming convention. Element 6: Second-Level Message Text Option *NOSECLVL: Second-level text descriptions are not added to the listing. *SECLVL: Second-level text with replacement data is added to the printout for all messages on the listing. Element 7: Large Object Optimization for DRDA Option *OPTLOB: The rst FETCH for a cursor determines how the cursor will be used for LOBs (Large Objects) on all subsequent FETCHes. This option remains in effect until the cursor is closed. If the rst FETCH uses a LOB locator to access a LOB column, no subsequent FETCH for that cursor can fetch that LOB column into a LOB host variable. If the rst FETCH places the LOB column into a LOB host variable, no subsequent FETCH for that cursor can use a LOB locator for that column.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

717

CRTSQLPLI
*NOOPTLOB: There is no restriction on whether a column is retrieved into a LOB locator or into a LOB host variable. This option can cause performance to degrade. TGTRLS Species the release of the operating system on which the user intends to use the object being created. In the examples given for the *CURRENT and *PRV values, and when specifying the release-level value, the format VxRxMx is used to specify the release, where Vx is the version, Rx is the release, and Mx is the modication level. For example, V2R3M0 is version 2, release 3, modication level 0. *CURRENT: The object is to be used on the release of the operating system currently running on the users system. For example, if V2R3M5 is running on the system, *CURRENT means the user intends to use the object on a system with V2R3M5 installed. The user can also use the object on a system with any subsequent release of the operating system installed. Note: If V2R3M5 is running on the system, and the object is to be used on a system with V2R3M0 installed, specify TGTRLS(V2R3M0) not TGTRLS(*CURRENT). *PRV: The object is to be used on the previous release with modication level 0 of the operating system. For example, if V2R3M5 is running on the users system, *PRV means the user intends to use the object on a system with V2R2M0 installed. The user can also use the object on a system with any subsequent release of the operating system installed.

release-level: Specify the release in the format VxRxMx. The object can be used on a system with the specied release or with any subsequent release of the operating system installed.
Valid values depend on the current version, release, and modication level, and they change with each new release. If you specify a release-level which is earlier than the earliest release level supported by this command, an error message is sent indicating the earliest supported release. INCFILE Species the qualied name of the source le that contains members included in the program with any SQL INCLUDE statement. The name of the source le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used.

library-name: Specify the name of the library to be searched.


*SRCFILE: The qualied source le specied in the SRCFILE parameter contains the source le members specied on any SQL INCLUDE statement.

source-le-name: Specify the name of the source le that contains the source le members specied on any SQL INCLUDE statement. The record length of the source le specied must be no less than the record length of the source le specied for the SRCFILE parameter.

718

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLPLI
COMMIT Species whether SQL statements in the compiled program are run under commitment control. Files referred to in the host language source are not affected by this option. Only SQL tables, SQL views, and SQL packages referred to in SQL statements are affected. *CHG or *UR: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs can be seen. *ALL or *RS: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows selected, updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs cannot be seen. *CS: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows updated, deleted, and inserted are locked until the end of the unit of work (transaction). A row that is selected, but not updated, is locked until the next row is selected. Uncommitted changes in other jobs cannot be seen. *NONE or *NC: Species that commitment control is not used. Uncommitted changes in other jobs can be seen. If the SQL DROP COLLECTION statement is included in the program, *NONE or *NC must be used. If a relational database is specied on the RDB parameter and the relational database is on a system that is not on an AS/400, *NONE or *NC cannot be specied. *RR: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows selected, updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs cannot be seen. All tables referred to in SELECT, UPDATE, DELETE, and INSERT statements are locked exclusively until the end of the unit of work (transaction). CLOSQLCSR Species when SQL cursors are implicitly closed, SQL prepared statements are implicitly discarded, and LOCK TABLE locks are released. SQL cursors are explicitly closed when you issue the CLOSE, COMMIT, or ROLLBACK (without HOLD) SQL statements. *ENDPGM: SQL cursors are closed and SQL prepared statements are discarded when the program ends. LOCK TABLE locks are released when the rst SQL program on the call stack ends. *ENDSQL: SQL cursors remain open between calls and can be fetched without running another SQL OPEN. One of the programs higher on the call stack must have run at least one SQL statement. SQL cursors are closed, SQL prepared statements are discarded, and LOCK TABLE locks are released when the rst SQL program on the call stack ends. If *ENDSQL is specied for a program that is the rst SQL program called (the rst SQL program on the call stack), the program is treated as if *ENDPGM was specied.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

719

CRTSQLPLI
*ENDJOB: SQL cursors remain open between calls and can be fetched without running another SQL OPEN. The programs higher on the call stack do not need to have run SQL statements. SQL cursors are left open, SQL prepared statements are preserved, and LOCK TABLE locks are held when the rst SQL program on the call stack ends. SQL cursors are closed, SQL prepared statements are discarded, and LOCK TABLE locks are released when the job ends. | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ALWCPYDTA Species whether a copy of the data can be used in a SELECT statement. *OPTIMIZE: The system determines whether to use the data retrieved directly from the database or to use a copy of the data. The decision is based on which method provides the best performance. If COMMIT is *CHG or *CS and ALWBLK is not *ALLREAD, or if COMMIT is *ALL or *RR, then a copy of the data is used only when it is necessary to run a query. *YES: A copy of the data is used only when necessary. *NO: A copy of the data is not allowed. If a temporary copy of the data is required to perform the query, an error message is returned. ALWBLK Species whether the database manager can use record blocking, and the extent to which blocking can be used for read-only cursors. *ALLREAD: Rows are blocked for read-only cursors if *NONE or *CHG is specied on the COMMIT parameter. All cursors in a program that are not explicitly able to be updated are opened for read-only processing even though EXECUTE or EXECUTE IMMEDIATE statements may be in the program. Specifying *ALLREAD: v Allows record blocking under commitment control level *CHG in addition to the blocking allowed for *READ. v Can improve the performance of almost all read-only cursors in programs, but limits queries in the following ways: The Rollback (ROLLBACK) command, a ROLLBACK statement in host languages, or the ROLLBACK HOLD SQL statement does not reposition a read-only cursor when *ALLREAD is specied. Dynamic running of a positioned UPDATE or DELETE statement (for example, using EXECUTE IMMEDIATE), cannot be used to update a row in a cursor unless the DECLARE statement for the cursor includes the FOR UPDATE clause. *NONE: Rows are not blocked for retrieval of data for cursors. Specifying *NONE: v Guarantees that the data retrieved is current. v May reduce the amount of time required to retrieve the rst row of data for a query. v Stops the database manager from retrieving a block of data rows that is not used by the program when only the rst few rows of a query are retrieved before the query is closed. v Can degrade the overall performance of a query that retrieves a large number of rows.

720

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLPLI
| | | | | | | | *READ: Records are blocked for read-only retrieval of data for cursors when: v *NONE is specied on the COMMIT parameter, which indicates that commitment control is not used. v The cursor is declared with a FOR READ ONLY clause or there are no dynamic statements that could run a positioned UPDATE or DELETE statement for the cursor. Specifying *READ can improve the overall performance of queries that meet the above conditions and retrieve a large number of records. DLYPRP Species whether the dynamic statement validation for a PREPARE statement is delayed until an OPEN, EXECUTE, or DESCRIBE statement is run. Delaying validation improves performance by eliminating redundant validation. *NO: Dynamic statement validation is not delayed. When the dynamic statement is prepared, the access plan is validated. When the dynamic statement is used in an OPEN or EXECUTE statement, the access plan is revalidated. Because the authority or the existence of objects referred to by the dynamic statement may change, you must still check the SQLCODE or SQLSTATE after issuing the OPEN or EXECUTE statement to ensure that the dynamic statement is still valid. *YES: Dynamic statement validation is delayed until the dynamic statement is used in an OPEN, EXECUTE, or DESCRIBE SQL statement. When the dynamic statement is used, the validation is completed and an access plan is built. If you specify *YES on this parameter, you should check the SQLCODE and SQLSTATE after running an OPEN, EXECUTE, or DESCRIBE statement to ensure that the dynamic statement is valid. Note: If you specify *YES, performance is not improved if the INTO clause is used on the PREPARE statement or if a DESCRIBE statement uses the dynamic statement before an OPEN is issued for the statement. GENLVL Species the severity level at which the create operation fails. If errors occur that have a severity level greater than or equal to this value, the operation ends. 10: The default severity level is 10.

severity-level: Specify a value ranging from 0 through 40.


MARGINS Species the part of the precompiler input record that contains source text. *SRCFILE: The le member margin values specied by the user on the SRCMBR parameter are used. If the member is a SQLPLI source type, the margin values are the values specied on the SEU services display. If the member is a different source type, the margin values are the default values of 2 and 72. Element 1: Left Margin

left: Specify the beginning position for the statements. Valid values range from 1 through 80.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

721

CRTSQLPLI
Element 2: Right Margin

right: Specify the ending position for the statements. Valid values range from 1 through 80.
DATFMT Species the format used when accessing date result columns. All output date elds are returned in the specied format. For input date strings, the specied value is used to determine whether the date is specied in a valid format. Note: An input date string that uses the format *USA, *ISO, *EUR, or *JIS is always valid. If a relational database is specied on the RDB parameter and the database is on a system that is not an AS/400 system, then *USA, *ISO, *EUR, or *JIS must be specied. *JOB: The format specied for the job is used. Use the Display Job (DSPJOB) command to determine the current date format for the job. *USA: The United States date format (mm/dd/yyyy) is used. *ISO: The International Organization for Standardization (ISO) date format (yyyy-mm-dd) is used. *EUR: The European date format (dd.mm.yyyy) is used. *JIS: The Japanese Industrial Standard date format (yyyy-mm-dd) is used. *MDY: The date format (mm/dd/yy) is used. *DMY: The date format (dd/mm/yy) is used. *YMD: The date format (yy/mm/dd) is used. *JUL: The Julian date format (yy/ddd) is used. DATSEP Species the separator used when accessing date result columns. Note: This parameter applies only when *JOB, *MDY, *DMY, *YMD, or *JUL is specied on the DATFMT parameter. *JOB: The date separator specied for the job at precompile time is used. Use the Display Job (DSPJOB) command to determine the current value for the job. /: A slash (/) is used. .: A period (.) is used. ,: A comma (,) is used. -: A dash (-) is used. : A blank ( ) is used. *BLANK: A blank ( ) is used.

722

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLPLI
TIMFMT Species the format used when accessing time result columns. For input time strings, the specied value is used to determine whether the time is specied in a valid format. Note: An input date string that uses the format *USA, *ISO, *EUR, or *JIS is always valid. If a relational database is specied on the RDB parameter and the database is on a system that is not another AS/400 system, the time format must be *USA, *ISO, *EUR, *JIS, or *HMS with a time separator of colon or period. *HMS: The (hh:mm:ss) format is used. *USA: The United States time format (hh:mm xx) is used, where xx is AM or PM. *ISO: The International Organization for Standardization (ISO) time format (hh.mm.ss) is used. *EUR: The European time format (hh.mm.ss) is used. *JIS: The Japanese Industrial Standard time format (hh:mm:ss) is used. TIMSEP Species the separator used when accessing time result columns. Note: This parameter applies only when *HMS is specied on the TIMFMT parameter. *JOB: The time separator specied for the job at precompile time is used. Use the Display Job (DSPJOB) command to determine the current value for the job. :: A colon (:) is used. .: A period (.) is used. ,: A comma (,) is used. : A blank ( ) is used. *BLANK: A blank ( ) is used. REPLACE Species whether a new program or SQL package is created when a program or SQL package of the same name exists in the same library. The value of this parameter is passed to the CRTPLIPGM command. More information on this parameter is in Appendix A, Expanded Parameter Descriptions in the CL Reference (Abridged) book. *YES: A new program or SQL package is created, and any existing program or SQL package of the same name and type in the specied library is moved to QRPLOBJ. *NO: A new program or SQL package is not created if an object of the same name and type already exists in the specied library.
Appendix D. DB2 UDB for AS/400 CL Command Descriptions

723

CRTSQLPLI
RDB Species the name of the relational database where the SQL package object is created. *LOCAL: The program is created as a distributed SQL program. The SQL statements will access the local database. An SQL package object is not created as part of the precompile process. The Create Structured Query Language Package (CRTSQLPKG) command can be used.

relational-database-name: Specify the name of the relational database where the new SQL package object is to be created. When the name of the local relational database is specied, the program created is still a distributed SQL program. The SQL statements will access the local database.
*NONE: An SQL package object is not created. The program object is not a distributed program and the Create Structured Query Language Package (CRTSQLPKG) command cannot be used. USER Species the user name sent to the remote system when starting the conversation. This parameter is valid only when RDB is specied. *CURRENT: The user prole under which the current job is running is used.

user-name: Specify the user name being used for the application server job.
PASSWORD Species the password to be used on the remote system. This parameter is valid only if RDB is specied. *NONE: No password is sent. If this value is specied, USER(*CURRENT) must also be specied.

password: Specify the password of the user name specied on the USER parameter.
RDBCNNMTH Species the semantics used for CONNECT statements. Refer to the SQL Reference book for more information. *DUW: CONNECT (Type 2) semantics are used to support distributed unit of work. Consecutive CONNECT statements to additional relational databases do not result in disconnection of previous connections. *RUW: CONNECT (Type 1) semantics are used to support remote unit of work. Consecutive CONNECT statements result in the previous connection being disconnected before a new connection is established. DFTRDBCOL Species the collection name used for the unqualied names of tables, views, indexes, and SQL packages. This parameter applies only to static SQL statements. *NONE: The naming convention dened on the OPTION parameter is used.

collection-name: Specify the name of the collection identier. This value is used instead of the naming convention specied on the OPTION parameter.

724

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLPLI
| | | | | | | | | | DYNDFTCOL Species whether the default collection name specied for the DFTRDBCOL parameter is also used for dynamic statements. *NO: Do not use the value specied on the DFTRDBCOL parameter for unqualied names of tables, views, indexes, and SQL packages for dynamic SQL statements. The naming convention specied on the OPTION parameter is used. *YES: The collection name specied on the DFTRDBCOL parameter will be used for the unqualied names of the tables, views, indexes, and SQL packages in dynamic SQL statements. SQLPKG Species the qualied name of the SQL package created on the relational database specied on the RDB parameter of this command. The possible library values are: *PGMLIB: The package is created in the library with the same name as the library containing the program. library-name: Specify the name of the library where the package is created. *PGM: The package name is the same as the program name.

package-name: Specify the name of the package created on the remote database specied on the RDBNAME parameter.
| | | | | | | | | | | | SQLPATH Species the path to be used to nd procedures, functions, and user dened types in static SQL statements. *NAMING: The path used depends on the naming convention specied on the OPTION parameter. For *SYS naming, the path used is *LIBL, the current library list at runtime. For *SQL naming, the path used is QSYS, QSYS2, userid, where userid is the value of the USER special register. If a collection-name is specied on the DFTRDBCOL parameter, the collection-name takes the place of userid. *LIBL: The path used is the library list at runtime.

collection-name: Specify a list of one or more collection names. A maximum of 43 individual collections may be specied.
SAAFLAG Species the IBM SQL agging function. This parameter ags SQL statements to verify whether they conform to IBM SQL syntax More information about which IBM database products IBM SQL syntax is in the DRDA IBM SQL Reference, SC26-3255-00. *NOFLAG: The precompiler does not check to see whether SQL statements conform to IBM SQL syntax. *FLAG: The precompiler checks to see whether SQL statements conform to IBM SQL syntax.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

725

CRTSQLPLI
FLAGSTD Species the American National Standards Institute (ANSI) agging function. This parameter ags SQL statements to verify whether they conform to the following standards.
ANSI X3.135-1992 entry ISO 9075-1992 entry FIPS 127.2 entry

Species the American National Standards Institute (ANSI) agging function. This parameter ags SQL statements to verify whether they conform to the following standards.
ANSI X3.135-1992 entry ISO 9075-1992 entry FIPS 127.2 entry

*NONE: The precompiler does not check to see whether SQL statements conform to ANSI standards. *ANS: The precompiler checks to see whether SQL statements conform to ANSI standards. PRTFILE Species the qualied name of the printer device le to which the listing is directed. The le must have a minimum record length of 132 bytes or information is lost. The name of the printer le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library to be searched. QSYSPRT: If a le name is not specied, the precompiler printout is directed to the IBM-supplied printer le QSYSPRT.

printer-le-name: Specify the name of the printer device le to which the precompiler printout is directed.
SRTSEQ Species the sort sequence table to be used for string comparisons in SQL statements. Note: *HEX must be specied for this parameter on distributed applications where the application server is not on an AS/400 system or the release level is prior to V2R3M0. *JOB: The SRTSEQ value for the job is retrieved during the precompile. *JOBRUN: The SRTSEQ value for the job is retrieved when the program is run. For distributed applications, SRTSEQ(*JOBRUN) is valid only when LANGID(*JOBRUN) is also specied. *LANGIDUNQ: The unique-weight sort table for the language specied on the LANGID parameter is used.

726

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLPLI
*LANGIDSHR: The shared-weight sort table for the language specied on the LANGID parameter is used. *HEX: A sort sequence table is not used. The hexadecimal values of the characters are used to determine the sort sequence. The name of the sort sequence table can be qualied by one of hte following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library to be searched.

table-name: Specify the name of the sort sequence table to be used.


LANGID Species the language identier to be used when SRTSEQ(*LANGIDUNQ) or SRTSEQ(*LANGIDSHR) is specied. *JOB: The LANGID value for the job is retrieved during the precompile. *JOBRUN: The LANGID value for the job is retrieved when the program is run. For distributed applications, LANGID(*JOBRUN) is valid only when SRTSEQ(*JOBRUN) is also specied.

language-id: Specify a language identier to be used by the program.


USRPRF Species the user prole that is used when the compiled program object is run, including the authority that the program object has for each object in static SQL statements. The prole of either the program owner or the program user is used to control which objects can be used by the program object. *NAMING: The user prole is determined by the naming convention. If the naming convention is *SQL, USRPRF(*OWNER) is used. If the naming convention is *SYS, USRPRF(*USER) is used. *USER: The prole of the user running the program object is used. *OWNER: The user proles of both the program owner and the program user are used when the program is run. DYNUSRPRF Species the user prole used for dynamic SQL statements. *USER: Local dynamic SQL statements are run under the user prole of the job. Distributed dynamic SQL statements are run under the user prole of the application server job. *OWNER: Local dynamic SQL statements are run under the user prole of the programs owner. Distributed dynamic SQL statements are run under the user prole of the SQL packages owner. | | | TOSRCFILE Species the qualied name of the source le that is to contain the output source member that has been processed by the SQL precompiler. If the
Appendix D. DB2 UDB for AS/400 CL Command Descriptions

727

CRTSQLPLI
| | | | | | | | | | | | | | specied source le is not found, it will be created. The output member will have the same name as the name that is specied for the SRCMBR parameter. The possible library values are: QTEMP: The library QTEMP will be used. *LIBL: The jobs library list is searched for the specied le. If the le is not found in any library in the library list, the le will be created in the current library. *CURLIB: The current library for the job will be used. If no library is specied as the current library for the job, the QGPL library will be used. library-name: Specify the name of the library that is to contain the output source le. QSQLTEMP: The source le QSQLTEMP will be used.

source-le-name: Specify the name of the source le to contain the output source member.
TEXT Species the text that briey describes the program and its function. More information on this parameter is in Appendix A, Expanded Parameter Descriptions in the CL Reference (Abridged) book. *SCRMBRTXT: The text is taken from the source le member being used to create the PL/I program. The user can add or change text for a database source member by using the Start Source Entry Utility (STRSEU) command, or by using either the Add Physical File Member (ADDPFM) or Change Physical File Member (CHGPFM) command. If the source le is an inline le or a device le, the text is blank. *BLANK: Text is not specied.

description: Specify no more than 50 characters of text, enclosed in apostrophes.

Example
CRTSQLPLI PAYROLL TEXT('Payroll Program')

This command runs the SQL precompiler, which precompiles the source and stores the changed source in member PAYROLL in le QSQLTEMP in library QTEMP. The PL/I compiler is called to create program PAYROLL in the current library using the source member created by the SQL precompiler.

CRTSQLRPG (Create Structured Query Language RPG) Command


Job: B,I Pgm: B,I
PGM( library-name/

REXX: B,I
*CURLIB/

Exec
program-name )

CRTSQLRPG

728

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLRPG
*LIBL/ SRCFILE( *CURLIB/ library-name/ QRPGSRC source-file-name

(1) *PGM source-file-member-name

SRCMBR(

OPTION(

OPTION DETAILS

) TGTRLS(

*CURRENT *PRV VxRxMx

*LIBL/ INCFILE( *CURLIB/ library-name/

*SRCFILE source-file-name

COMMIT(

*UR *CHG *ALL *RS *CS *NONE *NC *RR

CLOSQLCSR( )

*ENDPGM *ENDSQL *ENDJOB

ALWCPYDTA(

*OPTIMIZE *YES *NO

ALWBLK(

*ALLREAD *NONE *READ

DLYPRP(

*NO *YES

GENLVL(

10 severity-level

DATFMT(

*JOB *USA *ISO *EUR *JIS *MDY *DMY *YMD *JUL

DATSEP(

*JOB '/' '.' ',' '-' ' ' *BLANK

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

729

CRTSQLRPG
*HMS *USA *ISO *EUR *JIS *JOB ':' '.' ',' ' ' *BLANK

TIMFMT(

TIMSEP(

REPLACE(

*YES *NO

RDB(

*LOCAL relational-database-name *NONE

USER(

*CURRENT user-name

PASSWORD(

*NONE password

RDBCNNMTH(

*DUW *RUW

DFTRDBCOL(

*NONE collection-name

DYNDFTCOL(

*NO *YES

*PGMLIB/ SQLPKG( library-name/

*PGM package-name

SQLPATH(

*NAMING *LIBL

collection-name

SAAFLAG(

*NOFLAG *FLAG

FLAGSTD(

*NONE *ANS

*LIBL/ PRTFILE( *CURLIB/ library-name/

QSYSPRT printer-file-name

730

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLRPG
*JOB *JOBRUN *LANGIDUNQ *LANGIDSHR *HEX *LIBL/ table-name *CURLIB/ library-name/

SRTSEQ(

LANGID(

*JOB *JOBRUN language-ID

USRPRF(

*NAMING *OWNER *USER

DYNUSRPRF(

*USER *OWNER

QTEMP/ TOSRCFILE( *LIBL/ *CURLIB/ library-name/

QSQLTEMP source-file-name

TEXT(

*SRCMBRTXT *BLANK 'description'

OPTION Details:
*NOSRC *NOSOURCE *SOURCE *SRC *NOXREF *XREF *GEN *NOGEN *JOB *SYSVAL *PERIOD *COMMA *SYS *SQL

*NOSECLVL *SECLVL

*NOSEQSRC *SEQSRC

*NOLSTDBG *LSTDBG

Notes: 1. All parameters preceding this point can be specied in positional form.

Purpose
The Create Structured Query Language RPG (CRTSQLRPG) command calls the Structured Query Language (SQL) precompiler which precompiles the RPG source
Appendix D. DB2 UDB for AS/400 CL Command Descriptions

731

CRTSQLRPG
containing the SQL statements, produces a temporary source member, and then optionally calls the RPG compiler to compile the program.

Parameters
PGM Species the qualied name of the compiled program. The name of the compiled RPG can be qualied by one of the following library values: *CURLIB: The compiled RPG program is created in the current library for the job. If no library is specied as the current library for the job, the QGPL library is used.

library-name: Specify the name of hte library where the compiled RPG program is created. program-name: Specify the name of the compiled program.
SRCFILE Species the qualied name of the source le that contains the RPG source with SQL statements. The name of the source le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library to be searched. QRPGSRC: If the source le name is not specied, the IBM-supplied source le QRPGSRC contains the RPG source.

source-le-name: Specify the name of the source le that contains the RPG source.
SRCMBR Species the name of hte source le member that contains the RPG source. This parameter is specied only if the source le name in the SRCFILE parameter is a database le. If this parameter is not specied, the PGM name specied on the PGM parameter is used. *PGM: Species that the RPG source is in the member of the source le that has the same name as that specied on the PGM parameter.

source-le-member-name: Specify the name of the member that contains the RPG source.
OPTION Species whether one or more of the following options are used when the RPG source is precompiled. If an option is specied more than once, or if two options conict, the last option specied is used. Element 1: Source Listing Options

732

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLRPG
*NOSOURCE or *NOSRC: A source printout is not produced by the precompiler unless errors are detected during precompile or create package. *SOURCE or *SRC: The precompiler produces a source printout, consisting of RPG source input. Element 2: Cross-Reference Options *NOXREF: The precompiler does not cross-reference names. *XREF: The precompiler cross-references items in the program to the statement numbers in the program that refer to those items. Element 3: Program Creation Options *GEN: The compiler creates a program that can run after the program is compiled. An SQL package object is created if a relational database name is specied on the RDB parameter. *NOGEN: The precompiler does not call the RPG compiler, and a program and SQL package are not created. Element 4: Decimal Point Options *JOB: The value used as the decimal point for numeric constants in SQL is the representation of decimal point specied for the job at precompile time. *SYSVAL: The value used as the decimal point for numeric constants in SQL statements is the QDECFMT system value. Note: If QDECFMT species that the value used as the decimal point is a comma, any numeric constants in lists (such as in the SELECT clause, VALUES clause, and so on.) must be separated by a comma followed by a blank. For example, VALUES(1,1, 2,23, 4,1) is equivalent to VALUES(1.1,2.23,4.1) where the decimal point is a period. *PERIOD: The value used as the decimal point for numeric constants used in SQL statements is a period. *COMMA: The value used as the decimal point for numeric constants in SQL statements is a comma. Note: Any numeric constants in lists (such as in the SELECT clause, VALUES clause, and so on.) must be separated by a comma followed by a blank. For example, VALUES(1,1, 2,23, 4,1) is equivalent to VALUES(1.1,2.23,4.1) where the decimal point is a period. Element 5: Naming Convention Options *SYS: The system naming convention (library-name/le-name) is used. *SQL: The SQL naming convention is used (collection-name.table-name). When creating a program on a remote database other than an AS/400 system, *SQL must be specied as the naming convention. Element 6: Second-Level Message Text Option
Appendix D. DB2 UDB for AS/400 CL Command Descriptions

733

CRTSQLRPG
*NOSECLVL: Second-level text descriptions are not added to the listing. *SECLVL: Second-level text with replacement data is added for all messages on the listing. Element 7: Source Sequence Number Option *NOSEQSRC: Source sequence numbers from the input source les are used when creating the new source member in QSQLTEMP. *SEQSRC: Source records written to the new source member in QSQLTEMP are numbered starting at 000001. Element 8: Debug Listing View Option *NOLSTDBG: Error and debug information is not generated. *LSTDBG: The SQL precompiler generates a listing view and error and debug information required for this view. You can use *LSTDBG only if you are using the CODE/400 product to compile your program. TGTRLS Species the release of the operating system on which the user intends to use the object being created. In the examples given for the *CURRENT and *PRV values, and when specifying the release-level value, the format VxRxMx is used to specify the release, where Vx is the version, Rx is the release, and Mx is the modication level. For example, V2R3M0 is version 2, release 3, modication level 0. *CURRENT: The object is to be used on the release of the operating system currently running on the users system. For example, if V2R3M5 is running on the system, *CURRENT means the user intends to use the object on a system with V2R3M5 installed. The user can also use the object on a system with any subsequent release of the operating system installed. Note: If V2R3M5 is running on the system, and the object is to be used on a system with V2R3M0 installed, specify TGTRLS(V2R3M0) not TGTRLS(*CURRENT). *PRV: The object is to be used on the previous release with modication level 0 of the operating system. For example, if V2R3M5 is running on the users system, *PRV means the user intends to use the object on a system with V2R2M0 installed. The user can also use the object on a system with any subsequent release of the operating system installed.

release-level: Specify the release in the format VxRxMx. The object can be used on a system with the specied release or with any subsequent release of the operating system installed.
Valid values depend on the current version, release, and modication level, and they change with each new release. If you specify a release-level which is earlier than the earliest release level supported by this command, an error message is sent indicating the earliest supported release. INCFILE Species the qualied name of the source le that contains members included in the program with any SQL INCLUDE statement.

734

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLRPG
The name of the source le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used.

library-name: Specify the name of the library to be searched.


*SRCFILE: The qualied source le specied in the SRCFILE parameter contains the source le members specied on any SQL INCLUDE statement.

source-le-name: Specify the name of the source le that contains the source le members specied on any SQL INCLUDE statement. The record length of the source le specied here must be no less than the record length of the source le specied for the SRCFILE parameter.
COMMIT Species whether SQL statements in the compiled program are run under commitment control. Files referred to in the host language source are not affected by this option. Only SQL tables, SQL views, and SQL packages referred to in SQL statements are affected. Note: Files referenced in the RPG source are not affected by this option. *CHG or *UR: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs can be seen. *ALL or *RS: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows selected, updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs cannot be seen. *CS: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows updated, deleted, and inserted are locked until the end of the unit of work (transaction). A row that is selected, but not updated, is locked until the next row is selected. Uncommitted changes in other jobs cannot be seen. *NONE or *NC: Species that commitment control is not used. Uncommitted changes in other jobs can be seen. If the SQL DROP COLLECTION statement is included in the program, *NONE or *NC must be used. If a relational database is specied on the RDB parameter and the relational database is on a system that is not on an AS/400, *NONE or *NC cannot be specied. *RR: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows selected, updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs cannot be seen. All tables referred to in SELECT, UPDATE, DELETE, and INSERT statements are locked exclusively until the end of the unit of work (transaction).

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

735

CRTSQLRPG
CLOSQLCSR Species when SQL cursors are implicitly closed, SQL prepared statements are implicitly discarded, and LOCK TABLE locks are released. SQL cursors are explicitly closed when you issue the CLOSE, COMMIT, or ROLLBACK (without HOLD) SQL statements. *ENDPGM: SQL cursors are closed and SQL prepared statements are discarded when the program ends. LOCK TABLE locks are released when the rst SQL program on the call stack ends. *ENDSQL: SQL cursors remain open between calls and can be fetched without running another SQL OPEN. One of the programs higher on the call stack must have run at least one SQL statement. SQL cursors are closed, SQL prepared statements are discarded, and LOCK TABLE locks are released when the rst SQL program on the call stack ends. If *ENDSQL is specied for a program that is the rst SQL program called (the rst SQL program on the call stack), the program is treated as if *ENDPGM was specied. *ENDJOB: SQL cursors remain open between calls and can be fetched without running another SQL OPEN. The programs higher on the call stack do not need to have run SQL statements. SQL cursors are left open, SQL prepared statements are preserved, and LOCK TABLE locks are held when the rst SQL program on the call stack ends. SQL cursors are closed, SQL prepared statements are discarded, and LOCK TABLE locks are released when the job ends. | | | | | | | | | | | | | | | | | | | | | | ALWCPYDTA Species whether a copy of the data can be used in a SELECT statement. *OPTIMIZE: The system determines whether to use the data retrieved directly from the database or to use a copy of the data. The decision is based on which method provides the best performance. If COMMIT is *CHG or *CS and ALWBLK is not *ALLREAD, or if COMMIT is *ALL or *RR, then a copy of the data is used only when it is necessary to run a query. *YES: A copy of the data is used only when necessary. *NO: A copy of the data is not allowed. If a temporary copy of the data is required to perform the query, an error message is returned. ALWBLK Species whether the database manager can use record blocking, and the extent to which blocking can be used for read-only cursors. *ALLREAD: Rows are blocked for read-only cursors if *NONE or *CHG is specied on the COMMIT parameter. All cursors in a program that are not explicitly able to be updated are opened for read-only processing even though EXECUTE or EXECUTE IMMEDIATE statements may be in the program. Specifying *ALLREAD: v Allows record blocking under commitment control level *CHG in addition to the blocking allowed for *READ. v Can improve the performance of almost all read-only cursors in programs, but limits queries in the following ways:

736

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLRPG
| | | | | | | | | | | | | | | | | | | | | | | | | The Rollback (ROLLBACK) command, a ROLLBACK statement in host languages, or the ROLLBACK HOLD SQL statement does not reposition a read-only cursor when *ALLREAD is specied. Dynamic running of a positioned UPDATE or DELETE statement (for example, using EXECUTE IMMEDIATE), cannot be used to update a row in a cursor unless the DECLARE statement for the cursor includes the FOR UPDATE clause. *NONE: Rows are not blocked for retrieval of data for cursors. Specifying *NONE: v Guarantees that the data retrieved is current. v May reduce the amount of time required to retrieve the rst row of data for a query. v Stops the database manager from retrieving a block of data rows that is not used by the program when only the rst few rows of a query are retrieved before the query is closed. v Can degrade the overall performance of a query that retrieves a large number of rows. *READ: Records are blocked for read-only retrieval of data for cursors when: v *NONE is specied on the COMMIT parameter, which indicates that commitment control is not used. v The cursor is declared with a FOR READ ONLY clause or there are no dynamic statements that could run a positioned UPDATE or DELETE statement for the cursor. Specifying *READ can improve the overall performance of queries that meet the above conditions and retrieve a large number of records. DLYPRP Species whether the dynamic statement validation for a PREPARE statement is delayed until an OPEN, EXECUTE, or DESCRIBE statement is run. Delaying validation improves performance by eliminating redundant validation. *NO: Dynamic statement validation is not delayed. When the dynamic statement is prepared, the access plan is validated. When the dynamic statement is used in an OPEN or EXECUTE statement, the access plan is revalidated. Because the authority or the existence of objects referred to by the dynamic statement may change, you must still check the SQLCODE or SQLSTATE after issuing the OPEN or EXECUTE statement to ensure that the dynamic statement is still valid. *YES: Dynamic statement validation is delayed until the dynamic statement is used in an OPEN, EXECUTE, or DESCRIBE SQL statement. When the dynamic statement is used, the validation is completed and an access plan is built. If you specify *YES on this parameter, you should check the SQLCODE and SQLSTATE after running an OPEN, EXECUTE, or DESCRIBE statement to ensure that the dynamic statement is valid. Note: If you specify *YES, performance is not improved if the INTO clause is used on the PREPARE statement or if a DESCRIBE statement uses the dynamic statement before an OPEN is issued for the statement.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

737

CRTSQLRPG
GENLVL Species the severity level at which the create operation fails. If errors occur that have a severity level greater than or equal to this value, the operation ends. 10: The default severity level is 10.

severity-level: Specify a value ranging from 0 through 40.


DATFMT Species the format used when accessing date result columns. All output date elds are returned in the specied format. For input date strings, the specied value is used to determine whether the date is specied in a valid format. Note: An input date string that uses the format *USA, *ISO, *EUR, or *JIS is always valid. If a relational database is specied on the RDB parameter and the database is on a system that is not an AS/400 system, then *USA, *ISO, *EUR, or *JIS must be specied. *JOB: The format specied for the job is used. Use the Display Job (DSPJOB) command to determine the current date format for the job. *USA: The United States date format (mm/dd/yyyy) is used. *ISO: The International Organization for Standardization (ISO) date format (yyyy-mm-dd) is used. *EUR: The European date format (dd.mm.yyyy) is used. *JIS: The Japanese Industrial Standard date format (yyyy-mm-dd) is used. *MDY: The date format (mm/dd/yy) is used. *DMY: The date format (dd/mm/yy) is used. *YMD: The date format (yy/mm/dd) is used. *JUL: The Julian date format (yy/ddd) is used. DATSEP Species the separator used when accessing date result columns. Note: This parameter applies only when *JOB, *MDY, *DMY, *YMD, or *JUL is specied on the DATFMT parameter. *JOB: The date separator specied for the job at precompile time is used. Use the Display Job (DSPJOB) command to determine the current value for the job. /: A slash (/) is used. .: A period (.) is used. ,: A comma (,) is used. -: A dash (-) is used.

738

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLRPG
: A blank ( ) is used. *BLANK: A blank ( ) is used. TIMFMT Species the format used when accessing time result columns. For input time strings, the specied value is used to determine whether the time is specied in a valid format. Note: An input date string that uses the format *USA, *ISO, *EUR, or *JIS is always valid. If a relational database is specied on the RDB parameter and the database is on a system that is not another AS/400 system, the time format must be *USA, *ISO, *EUR, *JIS, or *HMS with a time separator of colon or period. *HMS: The (hh:mm:ss) format is used. *USA: The United States time format (hh:mm xx) is used, where xx is AM or PM. *ISO: The International Organization for Standardization (ISO) time format (hh.mm.ss) is used. *EUR: The European time format (hh.mm.ss) is used. *JIS: The Japanese Industrial Standard time format (hh:mm:ss) is used. TIMSEP Species the separator used when accessing time result columns. Note: This parameter applies only when *HMS is specied on the TIMFMT parameter. *JOB: The time separator specied for the job at precompile time is used. Use the Display Job (DSPJOB) command to determine the current value for the job. :: A colon (:) is used. .: A period (.) is used. ,: A comma (,) is used. : A blank ( ) is used. *BLANK: A blank ( ) is used. REPLACE Species whether a new program or SQL package is created when a program or SQL package of the same name exists in the same library. The value of this parameter is passed to the C command.More information on this parameter is in Appendix A, Expanded Parameter Descriptions in the CL Reference (Abridged) book.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

739

CRTSQLRPG
*YES: A new program or SQL package is created, and any existing program or SQL package of the same name and type in the specied library is moved to QRPLOBJ. *NO: A new program or SQL package is not created if an object of the same name and type already exists in the specied library. RDB Species the name of the relational database where the SQL package object is created. *LOCAL: The program is created as a distributed SQL program. The SQL statements will access the local database. An SQL package object is not created as part of the precompile process. The Create Structured Query Language Package (CRTSQLPKG) command can be used.

relational-database-name: Specify the name of the relational database where the new SQL package object is to be created. When the name of the local relational database is specied, the program created is still a distributed SQL program. The SQL statements will access the local database.
*NONE: An SQL package object is not created. The program object is not a distributed program and the Create Structured Query Language Package (CRTSQLPKG) command cannot be used. USER Species the user name sent to the remote system when starting the conversation. This parameter is valid only when RDB is specied. *CURRENT: The user prole under which the current job is running is used.

user-name: Specify the user name being used for the application requester job.
PASSWORD Species the password to be used on the remote system. This parameter is valid only if RDB is specied. *NONE: No password is sent. If this value is specied, USER(*CURRENT) must also be specied.

password: Specify the password of the user name specied on the USER parameter.
RDBCNNMTH Species the semantics used for CONNECT statements. Refer to the SQL Reference, SC41-3612 book for more information. *DUW: CONNECT (Type 2) semantics are used to support distributed unit of work. Consecutive CONNECT statements to additional relational databases do not result in disconnection of previous connections. *RUW: CONNECT (Type 1) semantics are used to support remote unit of work. Consecutive CONNECT statements result in the previous connection being disconnected before a new connection is established.

740

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLRPG
DFTRDBCOL Species the collection name used for the unqualied names of tables, views, indexes, and SQL packages. This parameter applies only to static SQL statements. *NONE: The naming convention dened on the OPTION parameter is used.

collection-name: Specify the name of the collection identier. This value is used instead of the naming convention specied on the OPTION parameter.
| | | | | | | | | | DYNDFTCOL Species whether the default collection name specied for the DFTRDBCOL parameter is also used for dynamic statements. *NO: Do not use the value specied on the DFTRDBCOL parameter for unqualied names of tables, views, indexes, and SQL packages for dynamic SQL statements. The naming convention specied on the OPTION parameter is used. *YES: The collection name specied on the DFTRDBCOL parameter will be used for the unqualied names of the tables, views, indexes, and SQL packages in dynamic SQL statements. SQLPKG Species the qualied name of the SQL package created on the relational database specied on the RDB parameter of this command. The possible library values are: *PGMLIB: The package is created in the library with the same name as the library containing the program. library-name: Specify the name of the library where the package is created. *PGM: The package name is the same as the program name.

package-name: Specify the name of the package created on the remote database specied on the RDBNAME parameter.
| | | | | | | | | | | | SQLPATH Species the path to be used to nd procedures, functions, and user dened types in static SQL statements. *NAMING: The path used depends on the naming convention specied on the OPTION parameter. For *SYS naming, the path used is *LIBL, the current library list at runtime. For *SQL naming, the path used is QSYS, QSYS2, userid, where userid is the value of the USER special register. If a collection-name is specied on the DFTRDBCOL parameter, the collection-name takes the place of userid. *LIBL: The path used is the library list at runtime.

collection-name: Specify a list of one or more collection names. A maximum of 43 individual collections may be specied.
SAAFLAG Species the IBM SQL agging function. This parameter ags SQL statements
Appendix D. DB2 UDB for AS/400 CL Command Descriptions

741

CRTSQLRPG
to verify whether they conform to IBM SQL syntax More information about which IBM database products IBM SQL syntax is in the DRDA IBM SQL Reference, SC26-3255-00. *NOFLAG: The precompiler does not check to see whether SQL statements conform to IBM SQL syntax. *FLAG: The precompiler checks to see whether SQL statements conform to IBM SQL syntax. FLAGSTD Species the American National Standards Institute (ANSI) agging function. This parameter ags SQL statements to verify whether they conform to the following standards.
ANSI X3.135-1992 entry ISO 9075-1992 entry FIPS 127.2 entry

*NONE: The precompiler does not check to see whether SQL statements conform to ANSI standards. *ANS: The precompiler checks to see whether SQL statements conform to ANSI standards. PRTFILE Species the qualied name of the printer device le to which the listing is directed. The le must have a minimum record length of 132 bytes or information is lost. The name of the printer le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the printer device le to which the compiler printout is directed. QSYSPRT: If a le name is not specied, the precompiler printout is directed to the IBM-supplied printer le QSYSPRT.

printer-le-name: Specify the name of the printer device le to which the compiler printout is directed.
SRTSEQ Species the sort sequence table to be used for string comparisons in SQL statements. Note: *HEX must be specied for this parameter on distributed applications where the application server is not on an AS/400 system or the release level is prior to V2R3M0. *JOB: The SRTSEQ value for the job is retrieved during the precompile. *JOBRUN: The SRTSEQ value for the job is retrieved when the program is run. For distributed applications, SRTSEQ(*JOBRUN) is valid only when LANGID(*JOBRUN) is also specied.

742

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLRPG
*LANGIDUNQ: The unique-weight sort table for the language specied on the LANGID parameter is used. *LANGIDSHR: The shared-weight sort table for the language specied on the LANGID parameter is used. *HEX: A sort sequence table is not used. The hexadecimal values of the characters are used to determine the sort sequence. The name of the sort sequence table can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used.

library-name: Specify the name of the library to be searched. table-name: Specify the name of the sort sequence table to be used.
LANGID Species the language identier to be used when SRTSEQ(*LANGIDUNQ) or SRTSEQ(*LANGIDSHR) is specied. *JOB: The LANGID value for hte job is retrieved during the precompile. *JOBRUN: The LANGID value for the job is retrieved when the program is run. For distributed applications, LANGID(*JOBRUN) is valid only when SRTSEQ(*JOBRUN) is also specied.

language-id: Specify a language identier to be used by the program.


USRPRF Species the user prole that is used when the compiled program object is run, including the authority that the program object has for each object in static SQL statements. The prole of either the program owner or the program user is used to control which objects can be used by the program object. *NAMING: The user prole is determined by the naming convention. If the naming convention is *SQL, USRPRF(*OWNER) is used. If the naming convention is *SYS, USRPRF(*USER) is used. *USER: The prole of the user running the program object is used. *OWNER: The user proles of both the program owner and the program user are used when the program is run. DYNUSRPRF Species the user prole used for dynamic SQL statements. *USER: Local dynamic SQL statements are run under the user prole of the job. Distributed dynamic SQL statements are run under the user prole of the application server job. *OWNER: Local dynamic SQL statements are run under the user prole of the programs owner. Distributed dynamic SQL statements are run under the user prole of the SQL packages owner.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

743

CRTSQLRPG
| | | | | | | | | | | | | | | | | TOSRCFILE Species the qualied name of the source le that is to contain the output source member that has been processed by the SQL precompiler. If the specied source le is not found, it will be created. The output member will have the same name as the name that is specied for the SRCMBR parameter. The possible library values are: QTEMP: The library QTEMP will be used. *LIBL: The jobs library list is searched for the specied le. If the le is not found in any library in the library list, the le will be created in the current library. *CURLIB: The current library for the job will be used. If no library is specied as the current library for the job, the QGPL library will be used. library-name: Specify the name of the library that is to contain the output source le. QSQLTEMP: The source le QSQLTEMP will be used.

source-le-name: Specify the name of the source le to contain the output source member.
TEXT Species text that briey describes the program and its function. More information on this parameter is in Appendix A, Expanded Parameter Descriptions in the CL Reference book. *SRCMBRTXT: The text is taken from the source le member being used to create the RPG program. Text for a database source member can be added or changed by using the Start Source Entry Utility (STRSEU) command, or by using either the Add Physical File Member (ADDPFM) command or the Change Physical File Member (CHGPFM) command. If the source le is an inline le or a device le, the text is blank. *BLANK: Text is not specied.

description: Specify no more than 50 characters of text, enclosed in apostrophes.

Example
CRTSQLRPG PGM(JONES/ARBR5) TEXT('Accounts Receivable Branch 5')

This command runs the SQL precompiler which precompiles the source and stores the changed source in member ARBR5 in le QSQLTEMP in library QTEMP. The RPG compiler is called to create program ARBR5 in library JONES by using the source member created by the SQL precompiler.

CRTSQLRPGI (Create SQL ILE RPG Object) Command


Job: B,I Pgm: B,I
OBJ( library-name/

REXX: B,I
*CURLIB/

Exec
object-name )

CRTSQLRPGI

744

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLRPGI
*LIBL/ SRCFILE( *CURLIB/ library-name/ QRPGLESRC source-file-name

(1) *OBJ source-file-member-name

SRCMBR(

OPTION(

OPTION Details

) TGTRLS(

*CURRENT *PRV VxRxMx

OBJTYPE(

*PGM *MODULE *SRVPGM

*LIBL/ INCFILE( *CURLIB/ library-name/

*SRCFILE source-file-name

COMMIT(

*UR *CHG *ALL *RS *CS *NONE *NC *RR

CLOSQLCSR( )

*ENDACTGRP *ENDMOD

ALWCPYDTA(

*OPTIMIZE *YES *NO

ALWBLK(

*ALLREAD *NONE *READ

DLYPRP(

*NO *YES

GENLVL(

10 severity-level

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

745

CRTSQLRPGI
*JOB *USA *ISO *EUR *JIS *MDY *DMY *YMD *JUL *JOB '/' '.' ',' '-' ' ' *BLANK

DATFMT(

DATSEP(

TIMFMT(

*HMS *USA *ISO *EUR *JIS

TIMSEP(

*JOB ':' '.' ',' ' ' *BLANK

REPLACE(

*YES *NO

RDB(

*LOCAL relational-database-name *NONE

USER(

*CURRENT user-name

PASSWORD(

*NONE password

RDBCNNMTH(

*DUW *RUW

DFTRDBCOL(

*NONE collection-name

DYNDFTCOL(

*NO *YES

*OBJLIB/ SQLPKG( library-name/

*OBJ package-name

SQLPATH(

*NAMING *LIBL

collection-name

746

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLRPGI
*NOFLAG *FLAG *NONE *ANS

SAAFLAG(

FLAGSTD(

DBGVIEW(

*NONE *SOURCE

USRPRF(

*NAMING *OWNER *USER

DYNUSRPRF(

*USER *OWNER

SRTSEQ(

*JOB *JOBRUN *LANGIDUNQ *LANGIDSHR *HEX *LIBL/ table-name *CURLIB/ library-name/

LANGID(

*JOB *JOBRUN language-identifier

OUTPUT(

*NONE *PRINT

*LIBL/ PRTFILE( *CURLIB/ library-name/

QSYSPRT printer-file-name

QTEMP/ TOSRCFILE( *LIBL/ *CURLIB/ library-name/

QSQLTEMP1 source-file-name

TEXT(

*SRCMBRTXT *BLANK 'description'

OPTION Details:

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

747

CRTSQLRPGI
*XREF *NOXREF *GEN *NOGEN *JOB *SYSVAL *PERIOD *COMMA *SYS *SQL *NOSECLVL *SECLVL

*NOSEQSRC *SEQSRC

*NOEVENTF *EVENTF

*OPTLOB *NOOPTLOB

Notes: 1. All parameters preceding this point can be specied in positional form.

Purpose
The Create Structured Query Language ILE RPG Object (CRTSQLRPGI) command calls the Structured Query Language (SQL) precompiler which precompiles RPG source containing SQL statements, produces a temporary source member, and then optionally calls the ILE RPG compiler to create a module, create a program, or create a service program.

Parameters
OBJ Species the qualied name of the object being created. *CURLIB: The new object is created in the current library for the job. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library where the object is created.

object-name: Specify the name of the object being created.


SRCFILE Species the qualied name of the source le that contains the RPG source with SQL statements. The name of the source le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library to be searched. QRPGLESRC: If the source le name is not specied, the IBM-supplied source le QRPGLESRC contains the RPG source.

source-le-name: Specify the name of the source le that contains the RPG source.
SRCMBR Species the name of the source le member that contains the RPG source. This parameter is specied only if the source le name in the SRCFILE

748

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLRPGI
parameter is a database le. If this parameter is not specied, the PGM name specied on the OBJ parameter is used. *OBJ: Species that the RPG source is in the member of the source le that has the same name as that specied on the OBJ parameter.

source-le-member-name: Specify the name of the member that contains the RPG source.
OPTION Species whether one or more of the following options are used when the RPG source is precompiled. If an option is specied more than once, or if two options conict, the last option specied is used. Element 1: Cross-Reference Options *XREF: The precompiler cross-references items in the program to the statement numbers in the program that refer to those items. *NOXREF: The precompiler does not cross-reference names. Element 2: Program Creation Options *GEN: The precompiler creates the object that is specied by the OBJTYPE parameter. *NOGEN: The precompiler does not call the RPG compiler, and a module, program, service program, or SQL package is not created. Element 3: Decimal Point Options *JOB: The value used as the decimal point for numeric constants in SQL is the representation of decimal point specied for the job at precompile time. *SYSVAL: The value used as the decimal point for numeric constants in SQL statements is the QDECFMT system value. Note: If QDECFMT species that the value used as the decimal point is a comma(,), any numeric constants in lists (such as in the SELECT clause or the VALUES clause) must be separated by a comma (,) followed by a blank ( ). For example, VALUES(1,1, 2,23, 4,1) is equivalent to VALUES(1.1,2.23,4.1) in which the decimal point is a period (.). *PERIOD: The value used as the decimal point for numeric constants in SQL statements is a period (.). *COMMA: The value used as the decimal point for numeric constants in SQL statements is a comma (,). Note: Any numeric constants in lists (such as in the SELECT clause or the VALUES clause) must be separated by a comma (,) followed by a blank( ). For example, VALUES(1,1, 2,23, 4,1) is equivalent to VALUES(1.1,2.23,4.1) where the decimal point is a period (.). Element 4: Naming Convention Options

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

749

CRTSQLRPGI
*SYS: The system naming convention (library-name/le-name) is used. *SQL: The SQL naming convention is used (collection-name.table-name). When creating a program on a remote database other than an AS/400 system, *SQL must be specied as the naming convention. Element 5: Second-Level Message Text Option *NOSECLVL: Second-level text descriptions are not added to the listing. *SECLVL: Second-level text with replacement data is added for all messages on the listing. Element 6: Sequence source *NOSEQSRC: The source le member created into QSQLTEMP1 has the same sequence numbers as the original source read by the precompiler. *SEQSRC: The source le member created into QSQLTEMP1 contains sequence numbers starting at 000001 and incremented by 000001. Element 7: Event File Creation *NOEVENTF: The compiler will not produce an Event File for use by CoOperative Development Environment/400 (CODE/400). *EVENTF: The compiler produces an event le for use by CoOperative Development Environment/400 (CODE/400). The event le will be created as a member in the le EVFEVENT in your source library. CODE/400 uses this le to offer error feedback integrated with the CODE/400 editor. This option is normally specied by CODE/400 on your behalf. Element 8: Date Conversion *NOCVTDT: Date, time and timestamp data types which are retrieved from externally-described les are to be processed using the native RPG language. *CVTDT: Date, time and timestamp data types which are retrieved from externally-described les are to be processed as xed-length character. | Element 9: Large Object Optimization for DRDA *OPTLOB: The rst FETCH for a cursor determines how the cursor will be used for LOBs (Large Objects) on all subsequent FETCHes. This option remains in effect until the cursor is closed. If the rst FETCH uses a LOB locator to access a LOB column, no subsequent FETCH for that cursor can fetch that LOB column into a LOB host variable. If the rst FETCH places the LOB column into a LOB host variable, no subsequent FETCH for that cursor can use a LOB locator for that column. *NOOPTLOB: There is no restriction on whether a column is retrieved into a LOB locator or into a LOB host variable. This option can cause performance to degrade.

750

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLRPGI
TGTRLS Species the release of the operating system on which the user intends to use the object being created. In the examples given for the *CURRENT and *PRV values, and when specifying the release-level value, the format VxRxMx is used to specify the release, where Vx is the version, Rx is the release, and Mx is the modication level. For example, V2R3M0 is version 2, release 3, modication level 0. *CURRENT: The object is to be used on the release of the operating system currently running on the users system. For example, if V2R3M5 is running on the system, *CURRENT means the user intends to use the object on a system with V2R3M5 installed. The user can also use the object on a system with any subsequent release of the operating system installed. Note: If V2R3M5 is running on the system, and the object is to be used on a system with V2R3M0 installed, specify TGTRLS(V2R3M0) not TGTRLS(*CURRENT). *PRV: The object is to be used on the previous release with modication level 0 of the operating system. For example, if V2R3M5 is running on the users system, *PRV means the user intends to use the object on a system with V2R2M0 installed. The user can also use the object on a system with any subsequent release of the operating system installed.

release-level: Specify the release in the format VxRxMx. The object can be used on a system with the specied release or with any subsequent release of the operating system installed.
Valid values depend on the current version, release, and modication level, and they change with each new release. If you specify a release-level which is earlier than the earliest release level supported by this command, an error message is sent indicating the earliest supported release. OBJTYPE Species the type of object being created. *PGM: The SQL precompiler issues the CRTBNDRPG command to create the bound program. *MODULE: The SQL precompiler issues the CRTRPGMOD command to create the module. *SRVPGM: The SQL precompiler issues the CRTRPGMOD and CRTSRVPGM commands to create the service program. Notes: 1. When OBJTYPE(*PGM) or OBJTYPE(*SRVPGM) is specied and the RDB parameter is also specied, the CRTSQLPKG command is issued by the SQL precompiler after the program has been created. When OBJTYPE(*MODULE) is specied, an SQL package is not created and you must issue the CRTSQLPKG command after the CRTPGM or CRTSRVPGM command has created the program. 2. If *NOGEN is specied, only the SQL temporary source member is generated and a module, program, service program, and SQL package are not created.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

751

CRTSQLRPGI
INCFILE Species the qualied name of the source le that contains members included in the program with any SQL INCLUDE statement. The name of the source le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library to be searched. *SRCFILE: The qualied source le specied in the SRCFILE parameter contains the source le members specied on any SQL INCLUDE statement.

source-le-name: Specify the name of the source le that contains the source le members specied on any SQL INCLUDE statement. The record length of the source le specied here must be no less than the record length of the source le specied on the SRCFILE parameter.
COMMIT Species whether SQL statements in the compiled unit are run under commitment control. Files referred to in the host language source are not affected by this option. Only SQL tables, SQL views, and SQL packages referred to in SQL statements are affected. *CHG or *UR: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs can be seen. *ALL or *RS: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows selected, updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs cannot be seen. *CS: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows updated, deleted, and inserted are locked until the end of the unit of work (transaction). A row that is selected, but not updated, is locked until the next row is selected. Uncommitted changes in other jobs cannot be seen. *NONE or *NC: Species that commitment control is not used. Uncommitted changes in other jobs can be seen. If the SQL DROP COLLECTION statement is included in the program, *NONE or *NC must be used. If a relational database is specied on the RDB parameter and the relational database is on a system that is not on an AS/400, *NONE or *NC cannot be specied. *RR: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows selected, updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs cannot be seen. All tables referred to in SELECT, UPDATE, DELETE, and INSERT statements are locked exclusively until the end of the unit of work (transaction).

752

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLRPGI
CLOSQLCSR Species when SQL cursors are implicitly closed, SQL prepared statements are implicitly discarded, and LOCK TABLE locks are released. SQL cursors are explicitly closed when you issue the CLOSE, COMMIT, or ROLLBACK (without HOLD) SQL statements. *ENDACTGRP: SQL cursors are closed, SQL prepared statements are implicitly discarded, and LOCK TABLE locks are released when the activation group ends. *ENDMOD: SQL cursors are closed and SQL prepared statements are implicitly discarded when the module is exited. LOCK TABLE locks are released when the rst SQL program on the call stack ends. | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ALWCPYDTA Species whether a copy of the data can be used in a SELECT statement. *OPTIMIZE: The system determines whether to use the data retrieved directly from the database or to use a copy of the data. The decision is based on which method provides the best performance. If COMMIT is *CHG or *CS and ALWBLK is not *ALLREAD, or if COMMIT is *ALL or *RR, then a copy of the data is used only when it is necessary to run a query. *YES: A copy of the data is used only when necessary. *NO: A copy of the data is not allowed. If a temporary copy of the data is required to perform the query, an error message is returned. ALWBLK Species whether the database manager can use record blocking, and the extent to which blocking can be used for read-only cursors. *ALLREAD: Rows are blocked for read-only cursors if *NONE or *CHG is specied on the COMMIT parameter. All cursors in a program that are not explicitly able to be updated are opened for read-only processing even though EXECUTE or EXECUTE IMMEDIATE statements may be in the program. Specifying *ALLREAD: v Allows record blocking under commitment control level *CHG in addition to the blocking allowed for *READ. v Can improve the performance of almost all read-only cursors in programs, but limits queries in the following ways: The Rollback (ROLLBACK) command, a ROLLBACK statement in host languages, or the ROLLBACK HOLD SQL statement does not reposition a read-only cursor when *ALLREAD is specied. Dynamic running of a positioned UPDATE or DELETE statement (for example, using EXECUTE IMMEDIATE), cannot be used to update a row in a cursor unless the DECLARE statement for the cursor includes the FOR UPDATE clause. *NONE: Rows are not blocked for retrieval of data for cursors. Specifying *NONE: v Guarantees that the data retrieved is current.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

753

CRTSQLRPGI
| | | | | | | | | | | | | | | v May reduce the amount of time required to retrieve the rst row of data for a query. v Stops the database manager from retrieving a block of data rows that is not used by the program when only the rst few rows of a query are retrieved before the query is closed. v Can degrade the overall performance of a query that retrieves a large number of rows. *READ: Records are blocked for read-only retrieval of data for cursors when: v *NONE is specied on the COMMIT parameter, which indicates that commitment control is not used. v The cursor is declared with a FOR READ ONLY clause or there are no dynamic statements that could run a positioned UPDATE or DELETE statement for the cursor. Specifying *READ can improve the overall performance of queries that meet the above conditions and retrieve a large number of records. DLYPRP Species whether the dynamic statement validation for a PREPARE statement is delayed until an OPEN, EXECUTE, or DESCRIBE statement is run. Delaying validation improves performance by eliminating redundant validation. *NO: Dynamic statement validation is not delayed. When the dynamic statement is prepared, the access plan is validated. When the dynamic statement is used in an OPEN or EXECUTE statement, the access plan is revalidated. Because the authority or the existence of objects referred to by the dynamic statement may change, you must still check the SQLCODE or SQLSTATE after issuing the OPEN or EXECUTE statement to ensure that the dynamic statement is still valid. *YES: Dynamic statement validation is delayed until the dynamic statement is used in an OPEN, EXECUTE, or DESCRIBE SQL statement. When the dynamic statement is used, the validation is completed and an access plan is built. If you specify *YES on this parameter, you should check the SQLCODE and SQLSTATE after running an OPEN, EXECUTE, or DESCRIBE statement to ensure that the dynamic statement is valid. Note: If you specify *YES, performance is not improved if the INTO clause is used on the PREPARE statement or if a DESCRIBE statement uses the dynamic statement before an OPEN is issued for the statement. GENLVL Species the severity level at which the create operation fails. If errors occur that have a severity level greater than this value, the operation ends. 10: The default severity level is 10.

severity-level: Specify a value ranging from 0 through 40.


DATFMT Species the format used when accessing date result columns. All output date elds are returned in the specied format. For input date strings, the specied value is used to determine whether the date is specied in a valid format.

754

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLRPGI
Note: An input date string that uses the format *USA, *ISO, *EUR, or *JIS is always valid. If a relational database is specied on the RDB parameter and the database is on a system that is not an AS/400 system, then *USA, *ISO, *EUR, or *JIS must be specied. *JOB: The format specied for the job is used. Use the Display Job (DSPJOB) command to determine the current date format for the job. *USA: The United States date format (mm/dd/yyyy) is used. *ISO: The International Organization for Standardization (ISO) date format (yyyy-mm-dd) is used. *EUR: The European date format (dd.mm.yyyy) is used. *JIS: The Japanese Industrial Standard date format (yyyy-mm-dd) is used. *MDY: The date format (mm/dd/yy) is used. *DMY: The date format (dd/mm/yy) is used. *YMD: The date format (yy/mm/dd) is used. *JUL: The Julian date format (yy/ddd) is used. DATSEP Species the separator used when accessing date result columns. Note: This parameter applies only when *JOB, *MDY, *DMY, *YMD, or *JUL is specied on the DATFMT parameter. *JOB: The date separator specied for the job at precompile time is used. Use the Display Job (DSPJOB) command to determine the current value for the job. /: A slash (/) is used. .: A period (.) is used. ,: A comma (,) is used. -: A dash (-) is used. : A blank ( ) is used. *BLANK: A blank ( ) is used. TIMFMT Species the format used when accessing time result columns. For input time strings, the specied value is used to determine whether the time is specied in a valid format. Note: An input time string that uses the format *USA, *ISO, *EUR, or *JIS is always valid.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

755

CRTSQLRPGI
If a relational database is specied on the RDB parameter and the database is on a system that is not another AS/400 system, the time format must be *USA, *ISO, *EUR, *JIS, or *HMS with a time separator of a colon or period. *HMS: The hh:mm:ss format is used. *USA: The United States time format hh:mm xx is used, where xx is AM or PM. *ISO: The International Organization for Standardization (ISO) time format hh.mm.ss is used. *EUR: The European time format hh.mm.ss is used. *JIS: The Japanese Industrial Standard time format hh:mm:ss is used. TIMSEP Species the separator used when accessing time result columns. Note: This parameter applies only when *HMS is specied on the TIMFMT parameter. *JOB: The time separator specied for the job at precompile time is used. Use the Display Job (DSPJOB) command to determine the current value for the job. :: A colon (:) is used. .: A period (.) is used. ,: A comma (,) is used. : A blank ( ) is used. *BLANK: A blank ( ) is used. REPLACE Species if a SQL module, program, service program or package is created when there is an existing SQL module, program, service program, or package of the same name and type in the same library. The value of this parameter is passed to the CRTRPGMOD, CRTBNDRPG, CRTSRVPGM, and CRTSQLPKG commands. *YES: A new SQL module, program, service program, or package is created, any existing SQL object of the same name and type in the specied library is moved to QRPLOBJ. *NO: A new SQL module, program, service program, or package is not created if an SQL object of the same name and type already exists in the specied library. RDB Species the name of the relational database where the SQL package object is created. *LOCAL: The program is created as a distributed SQL program. The SQL statements will access the local database. An SQL package object is not

756

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLRPGI
created as part of the precompile process. The Create Structured Query Language Package (CRTSQLPKG) command can be used.

relational-database-name: Specify the name of the relational database where the new SQL package object is to be created. When the name of the local relational database is specied, the program created is still a distributed SQL program. The SQL statements will access the local database.
*NONE: An SQL package object is not created. The program object is not a distributed program and the Create Structured Query Language Package (CRTSQLPKG) command cannot be used. USER Species the user name sent to the remote system when starting the conversation. This parameter is valid only when RDB is specied. *CURRENT: The user prole under which the current job is running is used.

user-name: Specify the user name being used for the application server job.
PASSWORD Species the password to be used on the remote system. This parameter is valid only if RDB is specied. *NONE: No password is sent. If this value is specied, USER(*CURRENT) must also be specied.

password: Specify the password of the user name specied on the USER parameter.
RDBCNNMTH Species the semantics used for CONNECT statements. Refer to the SQL Reference, SC41-3612 book for more information. *DUW: CONNECT (Type 2) semantics are used to support distributed unit of work. Consecutive CONNECT statements to additional relational databases do not result in disconnection of previous connections. *RUW: CONNECT (Type 1) semantics are used to support remote unit of work. Consecutive CONNECT statements result in the previous connection being disconnected before a new connection is established. DFTRDBCOL Species the collection name used for the unqualied names of tables, views, indexes, and SQL packages. This parameter applies only to static SQL statements. *NONE: The naming convention dened on the OPTION parameter is used.

collection-name: Specify the name of the collection identier. This value is used instead of the naming convention specied on the OPTION parameter.
| | | DYNDFTCOL Species whether the default collection name specied for the DFTRDBCOL parameter is also used for dynamic statements.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

757

CRTSQLRPGI
| | | | | | | *NO: Do not use the value specied on the DFTRDBCOL parameter for unqualied names of tables, views, indexes, and SQL packages for dynamic SQL statements. The naming convention specied on the OPTION parameter is used. *YES: The collection name specied on the DFTRDBCOL parameter will be used for the unqualied names of the tables, views, indexes, and SQL packages in dynamic SQL statements. SQLPKG Species the qualied name of the SQL package created on the relational database specied on the RDB parameter of this command. The possible library values are: *OBJLIB: The package is created in the library with the same name as the library specied on the OBJ parameter.

library-name: Specify the name of the library where the package is created.
*OBJ: The name of the SQL package is the same as the object name specied on the OBJ parameter.

package-name: Specify the name of the SQL package. If the remote system is not an AS/400 system, no more than 8 characters can be specied.
| | | | | | | | | | | | SQLPATH Species the path to be used to nd procedures, functions, and user dened types in static SQL statements. *NAMING: The path used depends on the naming convention specied on the OPTION parameter. For *SYS naming, the path used is *LIBL, the current library list at runtime. For *SQL naming, the path used is QSYS, QSYS2, userid, where userid is the value of the USER special register. If a collection-name is specied on the DFTRDBCOL parameter, the collection-name takes the place of userid. *LIBL: The path used is the library list at runtime.

collection-name: Specify a list of one or more collection names. A maximum of 43 individual collections may be specied.
SAAFLAG Species the IBM SQL agging function. This parameter ags SQL statements to verify whether they conform to IBM SQL syntax. More information about IBM SQL syntax found in IBM database products can be found in the DRDA IBM SQL Reference, SC26325500. *NOFLAG: The precompiler does not check to see whether SQL statements conform to IBM SQL syntax. *FLAG: The precompiler checks to see whether SQL statements conform to IBM SQL syntax.

758

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLRPGI
FLAGSTD Species the American National Standards Institute (ANSI) agging function. This parameter ags SQL statements to verify whether they conform to the following standards.
ANSI X3.135-1992 entry ISO 9075-1992 entry FIPS 127.2 entry

*NONE: The precompiler does not check to see whether SQL statements conform to ANSI standards. *ANS: The precompiler checks to see whether SQL statements conform to ANSI standards. DBGVIEW Species the type of source debug information to be provided by the SQL precompiler. *NONE: The source view will not be generated. *SOURCE: The SQL precompiler will provide the source views for the root and if necessary, SQL INCLUDE statements. A view will be provided which contains the statements generated by the precompiler. USRPRF Species the user prole that is used when the compiled program object is run, including the authority that the program object has for each object in static SQL statements. The prole of either the program owner or the program user is used to control which objects can be used by the program object. *NAMING: The user prole is determined by the naming convention. If the naming convention is *SQL, USRPRF(*OWNER) is used. If the naming convention is *SYS, USRPRF(*USER) is used. *USER: The prole of the user running the program object is used. *OWNER: The user proles of both the program owner and the program user are used when the program is run. DYNUSRPRF Species the user prole to be used for dynamic SQL statements. *USER: For local, dynamic SQL statements run under the user of the programs user. For distributed, dynamic SQL statements run under the prole of the SQL packages user. *OWNER: For local, dynamic SQL statements run under the prole of the programs owner. For distributed, dynamic SQL statements run under the prole of the SQL packages owner. SRTSEQ Species the sort sequence table to be used for string comparisons in SQL statements. Note: *HEX must be specied for this parameter on distributed applications where the application server is not on an AS/400 system or the release level is prior to V2R3M0.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

759

CRTSQLRPGI
*JOB: The SRTSEQ value for the job is retrieved during the precompile. *JOBRUN: The SRTSEQ value for the job is retrieved when the program is run. For distributed applications, SRTSEQ(*JOBRUN) is valid only when LANGID(*JOBRUN) is also specied. *LANGIDUNQ: The unique-weight sort table for the language specied on the LANGID parameter is used. *LANGIDSHR: The sort sequence table uses the same weight for multiple characters, and is the shared-weight sort sequence table associated with the language specied on the LANGID parameter. *HEX: A sort sequence table is not used. The hexadecimal values of the characters are used to determine the sort sequence. The name of the sort sequence table can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used.

library-name: Specify the name of the library to be searched. table-name: Specify the name of the sort sequence table to be used.
LANGID Species the language identier to be used when SRTSEQ(*LANGIDUNQ) or SRTSEQ(*LANGIDSHR) is specied. *JOB: The LANGID value for the job is retrieved during the precompile. *JOBRUN: The LANGID value for the job is retrieved when the program is run. For distributed applications, LANGID(*JOBRUN) is valid only when SRTSEQ(*JOBRUN) is also specied.

language-identier: Specify a language identier.


OUTPUT Species whether the precompiler listing is generated. *NONE: The precompiler listing is not generated. *PRINT: The precompiler listing is generated. PRTFILE Species the qualied name of the printer device le to which the precompiler printout is directed. The le must have a minimum length of 132 bytes. If a le with a record length of less than 132 bytes is specied, information is lost. The name of the printer le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used.

library-name: Specify the name of the library to be searched.

760

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLRPGI
QSYSPRT: If a le name is not specied, the precompiler printout is directed to the IBM-supplied printer le QSYSPRT.

printer-le-name: Specify the name of the printer device le to which the precompiler printout is directed.
| | | | | | | | | | | | | | | | | TOSRCFILE Species the qualied name of the source le that is to contain the output source member that has been processed by the SQL precompiler. If the specied source le is not found, it will be created. The output member will have the same name as the name that is specied for the SRCMBR parameter. The possible library values are: QTEMP: The library QTEMP will be used. *LIBL: The jobs library list is searched for the specied le. If the le is not found in any library in the library list, the le will be created in the current library. *CURLIB: The current library for the job will be used. If no library is specied as the current library for the job, the QGPL library will be used. library-name: Specify the name of the library that is to contain the output source le. QSQLTEMP1: The source le QSQLTEMP1 will be used.

source-le-name: Specify the name of the source le to contain the output source member.
TEXT Species the text that briey describes the function. More information on this parameter is located in Appendix A, Expanded Parameter Descriptions in the CL Reference book. *SRCMBRTXT: The text is taken from the source le member being used to create the RPG program. Text can be added or changed for a database source member by using the Start Source Entry Utility (STRSEU) command, or by using either the Add Physical File Member (ADDPFM) or Change Physical File Member (CHGPFM) command. If the source le is an inline le or a device le, the text is blank. *BLANK: Text is not specied.

description: Specify no more than 50 characters of text, enclosed in apostrophes.

Example
CRTSQLRPGI PAYROLL OBJTYPE(*PGM) TEXT('Payroll Program')

This command runs the SQL precompiler which precompiles the source and stores the changed source in member PAYROLL in le QSQLTEMP1 in library QTEMP. The ILE RPG compiler is called to create program PAYROLL in the current library by using the source member created by the SQL precompiler.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

761

CRTSQLPKG

CRTSQLPKG (Create Structured Query Language Package) Command


Job: B,I Pgm: B,I
PGM( *CURLIB/ library-name/

REXX: B,I
*LIBL/

Exec
program-name )

CRTSQLPKG

(1) *PGM relational-database-name

RDB(

USER(

*CURRENT user-name

PASSWORD(

*NONE password

GENLVL(

10 severity-level

REPLACE(

*YES *NO

DFTRDBCOL(

*PGM *NONE collection-name

*LIBL/ PRTFILE( *CURLIB/ library-name/

QSYSPRT printer-file-name

OBJTYPE(

*PGM *SRVPGM

*ALL (2) MODULE( module-name )

TEXT(

*PGMTXT *BLANK 'description'

762

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLPKG
Notes: 1. All parameters preceding this point can be specied in positional form. 2. A maximum of 256 modules may be specied.

Purpose
The Create Structured Query Language Package (CRTSQLPKG) command is used to create (or re-create) an SQL package on a relational database from an existing distributed SQL program. A distributed SQL program is a program created by specifying the RDB parameter on a CRTSQLxxx (where xxx = C, CI, CBL, CBLI, FTN, PLI, or RPG or RPGI) command.

Parameters
PGM Species the qualied name of the program for which the SQL package is being created. The program must be a distributed SQL program. The name of the program can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library to be searched.

program-name: Specify the name of the program for which the package is being created.
RDB Species the name of the relational database where the SQL package is being created. *PGM: The relational database name specied for the SQL program is used. The relational database name is specied on the RDB parameter of the distributed SQL program.

relational-database-name: Specify the name of the relational database where the SQL package is to be created. Use the Work with Relational Database Directory Entry (WRKRDBDIRE) command to show the relational database names that are valid on this parameter.
USER Species the user name sent to the remote system when starting the conversation. *CURRENT: The user name associated with the current job is used.

user-name: Specify the user name being used for the application server job.
PASSWORD Species the password to be used on the remote system. *NONE: No password is sent. If this value is specied, USER(*CURRENT) must also be specied.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

763

CRTSQLPKG
password: Specify the password of the user name specied on the USER parameter.
GENLVL Species the maximum severity level allowed for errors detected during SQL package creation. If errors occur at a level that exceeds the specied level, the SQL package is not created. 10: The default severity-level is 10.

severity-level: Specify the maximum severity level. Valid values range from 0 through 40.
REPLACE Species whether an existing package is being replaced with the new package. More information on this parameter is in Appendix A, Expanded Parameter Descriptions in the CL Reference book. *YES: An existing SQL package of the same name is replaced by the new SQL package. *NO: An existing SQL package of the same name is not replaced; a new SQL package is not created if the package already exists in the specied library. DFTRDBCOL Species the collection name to be used for unqualied names of tables, views, indexes, and SQL packages. This parameter applies only to static SQL statements in the package. *PGM: The collection name specied for the SQL program is used. The default relational database collection name is specied on the DFTRDBCOL parameter of the distributed SQL program. *NONE: Unqualied names for tables, views, indexes, and SQL packages use the search conventions specied on the OPTION parameter of the CRTSQLxxx command used to create the program.

collection-name: Specify the collection name that is used for unqualied tables, views, indexes, and SQL packages.
PRTFILE Species the qualied name of the printer device le to which the create SQL package error listing is directed. If no errors are detected during the creation of the SQL package, no listing is produced. The name of the printer le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library to be searched. QSYSPRT: If a le name is not specied, the create SQL package error listing is directed to the IBM-supplied printer le QSYSPRT.

764

DB2 UDB for AS/400 SQL Programming V4R4

CRTSQLPKG
printer-le-name: Specify the name of the printer device le to which the create SQL package error listing is directed.
OBJTYPE Species the type of program for which an SQL package is created. *PGM: Create an SQL package from the program specied on the PGM parameter. *SRVPGM: Create an SQL package from the service program specied on the PGM parameter. MODULE Species a list of modules in a bound program. *ALL: An SQL package is created for each module in the program. An error message is sent if none of the modules in the program contain SQL statements or none of the modules is a distributed module. Note: CRTSQLPKG can process programs that do not contain more than 1024 modules.

module-name: Specify the names of up to 256 modules in the program for which an SQL package is to be created. If more than 256 modules exist that need to have an SQL package created, multiple CRTSQLPKG commands must be used.
Duplicate module names in the same program are allowed. This command looks at each module in the program and if *ALL or the module name is specied on the MODULE parameter, processing continues to determine whether an SQL package should be created. If the module is created using SQL and the RDB parameter is specied on the precompile command, an SQL package is created for the module. The SQL package is associated with the module of the bound program. TEXT Species text that briey describes the SQL package and its function. *PGMTXT: The text from the program for which the SQL package is being created is used. *BLANK: No text is specied.

description: Specify a maximum of 50 characters of text, enclosed in apostrophes.

Example
CRTSQLPKG PAYROLL RDB(SYSTEMA) TEXT('Payroll Program')

This command creates an SQL package from the distributed SQL program PAYROLL on relational database SYSTEMA.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

765

CVTSQLCPP
| | | | | |

CVTSQLCPP (Convert Structured Query Language C++ Source) Command


Job: B,I Pgm: B,I REXX: B,I
*LIBL/ CVTSQLCPP SRCFILE( *CURLIB/ library-name/ source-file-name )

Exec

| | | |

SRCMBR(

*OBJ source-file-member-name

(1) )

*LIBL/ TOSRCFILE( *CURLIB/ library-name/

QSQLTEMP source-file-name

| |

OPTION(

OPTION Details

) TGTRLS(

*CURRENT VxRxMx

| |
INCFILE(

*LIBL/ *CURLIB/ library-name/

*SRCFILE source-file-name

| |
COMMIT(

*UR *CHG *ALL *RS *CS *NONE *NC *RR

CLOSQLCSR( )

*ENDACTGRP *ENDMOD

| |
ALWCPYDTA(

*OPTIMIZE *YES *NO

ALWBLK(

*ALLREAD *NONE *READ

| |
DLYPRP(

*NO *YES

GENLVL(

10 severity-level

766

DB2 UDB for AS/400 SQL Programming V4R4

CVTSQLCPP
| |
MARGINS( *SRCFILE left-right *JOB *USA *ISO *EUR *JIS *MDY *DMY *YMD *JUL

DATFMT(

| |
DATSEP(

*JOB '/' '.' ',' '-' ' ' *BLANK

TIMFMT(

*HMS *USA *ISO *EUR *JIS

| |
TIMSEP(

*JOB ':' '.' ',' ' ' *BLANK

| | |
RDB(

*LOCAL relational-database-name *NONE

USER(

*CURRENT user-name

| |
PASSWORD(

*NONE password

RDBCNNMTH(

*DUW *RUW

| |
DFTRDBCOL(

*NONE collection-name

DYNDFTCOL(

*NO *YES

| |
SQLPKG(

*OBJLIB/ library-name/

*OBJ package-name

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

767

CVTSQLCPP
| |
SQLPATH( *NAMING *LIBL

collection-name

| |
SAAFLAG(

*NOFLAG *FLAG

FLAGSTD(

*NONE *ANS

| |
DBGVIEW(

*NONE *SOURCE

USRPRF(

*NAMING *OWNER *USER

| |
DYNUSRPRF(

*USER *OWNER

| |
SRTSEQ(

*JOB *JOBRUN *LANGIDUNQ *LANGIDSHR *HEX *LIBL/ table-name *CURLIB/ library-name/

| |
LANGID(

*JOB *JOBRUN language-identifier

OUTPUT(

*NONE *PRINT

| |
PRTFILE(

*LIBL/ *CURLIB/ library-name/

QSYSPRT printer-file-name

| |
TEXT(

*SRCMBRTXT *BLANK 'description'

| | OPTION Details:

768

DB2 UDB for AS/400 SQL Programming V4R4

CVTSQLCPP
| |
*XREF *NOXREF *JOB *SYSVAL *PERIOD *COMMA *SYS *SQL *NOSECLVL *SECLVL *NOCNULRQD *CNULRQD

| |

*NOEVENTF *EVENTF

*OPTLOB *NOOPTLOB

| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Notes: 1. All parameters preceding this point can be specied in positional form.

Purpose
The Convert Structured Query Language C++ Source (CVTSQLCPP) command calls the Structured Query Language (SQL) precompiler. The precompiler precompiles C++ source that contains SQL statements, and produces a temporary source member. This source member can then be provided as input to the VisualAge C++ for OS/400 compiler.

Parameters
SRCFILE Species the qualied name of the source le that contains the C++ source with SQL statements. One of the following library values can qualify the name of the source le: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used.

library-name: Specify the name of the library to be searched. source-le-name: Specify the name of the source le that contains the C++ source with SQL statements.
SRCMBR Species the name of the source le member that contains the C++ source. TOSRCFILE Species the qualied name of the source le that is to contain the output C++ source member that has been processed by the SQL C++ precompiler. If the specied source le is not found, it will be created. The output member will have the same name as the name specied for the SRCMBR parameter. The name of the source le can be qualied by one of the following library values: *LIBL: The jobs library list is searched for the specied le. If the le is not found in any library in the library list, the le will be created in the current library. *CURLIB: The current library for the job will be used. If no library is specied as the current library for the job, the QGPL library is used.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

769

CVTSQLCPP
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |

library-name: Specify the name of the library that is to contain the output source le.
OPTION Species whether one or more of the following options are used when the C++ source is precompiled. If an option is specied more than once, or if two options conict, the last option specied is used. Element 1: Cross-Reference Options *XREF: The precompiler cross-references items in the program to the statement numbers in the program that refer to those items. *NOXREF: The precompiler does not cross-reference names. Element 2: Decimal Point Options *JOB: The value used as the decimal point for numeric constants in SQL is the representation of decimal point specied for the job at precompile time. Note: If the job decimal point value species that the value used as the decimal point is a comma, any numeric constants in lists (such as in the SELECT clause or the VALUES clause) must be separated by a comma followed by a blank. For example, VALUES(1,1, 2,23, 4,1) is equivalent to VALUES(1.1,2.23,4.1) in which the decimal point is a period. *PERIOD:The value used as the decimal point for numeric constants in SQL statements is a period. *COMMA: The value used as the decimal point for numeric constants in SQL statements is a comma. Note: Any numeric constants in lists (such as in the SELECT clause or the VALUES clause) must be separated by a comma followed by a blank. For example, VALUES(1,1, 2,23, 4,1) is equivalent to VALUES(1.1,2.23,4.1) where the decimal point is a period. Element 3: Naming Convention Options *SYS: The system naming convention (library-name/le-name) is used. *SQL: The SQL naming convention is used (collection-name.table-name). When creating a package on a remote database other than an AS/400 system, *SQL must be specied as the naming convention. Element 4: Second-Level Message Text Option *NOSECLVL: Second-level text descriptions are not added to the listing. *SECLVL: Second-level text with replacement data is added for all messages on the listing. Element 5: NUL Required Options

770

DB2 UDB for AS/400 SQL Programming V4R4

CVTSQLCPP
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | *NOCNULRQD: For output character and graphic host variables, the NUL-terminator is not returned when the host variable is exactly the same length as the data. Input character and graphic host variables do not require a NUL-terminator. *CNULRQD: Output character and graphic host variables always contain the NUL-terminator. If there is not enough space for the NUL-terminator, the data is truncated and the NUL-terminator is added. Input character and graphic host variables require a NUL-terminator. Element 6: Event File Creation *NOEVENTF: The compiler will not produce an event le for use by CoOperative Development Environment/400 (CODE/400). *EVENTF: The compiler produces an event le for use by CoOperative Development Environment/400 (CODE/400). The event le will be created as a member in the le EVFEVENT in your source library. CODE/400 uses this le to offer error feedback integrated with the CODE/400 editor. This option is normally specied by CODE/400 on your behalf. Element 7: Large Object Optimization for DRDA *OPTLOB: The rst FETCH for a cursor determines how the cursor will be used for LOBs (Large Objects) on all subsequent FETCHes. This option remains in effect until the cursor is closed. If the rst FETCH uses a LOB locator to access a LOB column, no subsequent FETCH for that cursor can fetch that LOB column into a LOB host variable. If the rst FETCH places the LOB column into a LOB host variable, no subsequent FETCH for that cursor can use a LOB locator for that column. *NOOPTLOB: There is no restriction on whether a column is retrieved into a LOB locator or into a LOB host variable. This option can cause performance to degrade. TGTRLS Species the release of the operating system on which the user intends to use the object being created. In the examples given for the *CURRENT and *PRV values, and when specifying the release-level value, the format VxRxMx is used to specify the release, where Vx is the version, Rx is the release, and Mx is the modication level. For example, V2R3M0 is version 2, release 3, modication level 0. *CURRENT: The object is to be used on the release of the operating system currently running on the users system. For example, if V2R3M5 is running on the system, *CURRENT means the user intends to use the object on a system with V2R3M5 installed. The user can also use the object on a system with any subsequent release of the operating system installed. Note: If V2R3M5 is running on the system, and the object is to be used on a system with V2R3M0 installed, specify TGTRLS(V2R3M0) not TGTRLS(*CURRENT).

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

771

CVTSQLCPP
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |

release-level: Specify the release in the format VxRxMx. The object can be used on a system with the specied release or with any subsequent release of the operating system installed.
Valid values depend on the current version, release, and modication level, and they change with each new release. If you specify a release-level which is earlier than the earliest release level supported by this command, an error message is sent indicating the earliest supported release. INCFILE Species the qualied name of the source le that contains members included in the program with any SQL INCLUDE statement. The name of the source le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library to be searched. *SRCFILE: The qualied source le specied in the SRCFILE parameter contains the source le members specied on any SQL INCLUDE statement.

source-le-name: Specify the name of the source le that contains the source le members specied on any SQL INCLUDE statement. The record length of the source le specied here must be no less than the record length of the source le specied on the SRCFILE parameter.
COMMIT Species whether SQL statements in the compiled unit are run under commitment control. Files referred to in the host language source are not affected by this option. Only SQL tables, SQL views, and SQL packages referred to in SQL statements are affected. *CHG or *UR: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs can be seen. *ALL or *RS: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows selected, updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs cannot be seen. *CS: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows updated, deleted, and inserted are locked until the end of the unit of work (transaction). A row that is selected, but not updated, is locked until the next row is selected. Uncommitted changes in other jobs cannot be seen. *NONE or *NC: Species that commitment control is not used. Uncommitted changes in other jobs can be seen. If the SQL DROP COLLECTION statement is included in the program, *NONE or *NC must be used. If a relational

772

DB2 UDB for AS/400 SQL Programming V4R4

CVTSQLCPP
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | database is specied on the RDB parameter and the relational database is on a system that is not on an AS/400, *NONE or *NC cannot be specied. *RR: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows selected, updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs cannot be seen. All tables referred to in SELECT, UPDATE, DELETE, and INSERT statements are locked exclusively until the end of the unit of work (transaction). CLOSQLCSR Species when SQL cursors are implicitly closed, SQL prepared statements are implicitly discarded, and LOCK TABLE locks are released. SQL cursors are explicitly closed when you issue the CLOSE, COMMIT, or ROLLBACK (without HOLD) SQL statements. *ENDACTGRP: SQL cursors are closed, SQL prepared statements are implicitly discarded, and LOCK TABLE locks are released when the activation group ends. *ENDMOD: SQL cursors are closed and SQL prepared statements are implicitly discarded when the module is exited. LOCK TABLE locks are released when the rst SQL program on the call stack ends. ALWCPYDTA Species whether a copy of the data can be used in a SELECT statement. *OPTIMIZE: The system determines whether to use the data retrieved directly from the database or to use a copy of the data. The decision is based on which method provides the best performance. If COMMIT is *CHG or *CS and ALWBLK is not *ALLREAD, or if COMMIT is *ALL or *RR, then a copy of the data is used only when it is necessary to run a query. *YES: A copy of the data is used only when necessary. *NO: A copy of the data is not allowed. If a temporary copy of the data is required to perform the query, an error message is returned. ALWBLK Species whether the database manager can use record blocking, and the extent to which blocking can be used for read-only cursors. *ALLREAD: Rows are blocked for read-only cursors if *NONE or *CHG is specied on the COMMIT parameter. All cursors in a program that are not explicitly able to be updated are opened for read-only processing even though EXECUTE or EXECUTE IMMEDIATE statements may be in the program. Specifying *ALLREAD: v Allows record blocking under commitment control level *CHG in addition to the blocking allowed for *READ. v Can improve the performance of almost all read-only cursors in programs, but limits queries in the following ways: The Rollback (ROLLBACK) command, a ROLLBACK statement in host languages, or the ROLLBACK HOLD SQL statement does not reposition a read-only cursor when *ALLREAD is specied.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

773

CVTSQLCPP
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Dynamic running of a positioned UPDATE or DELETE statement (for example, using EXECUTE IMMEDIATE), cannot be used to update a row in a cursor unless the DECLARE statement for the cursor includes the FOR UPDATE clause. *NONE: Rows are not blocked for retrieval of data for cursors. Specifying *NONE: v Guarantees that the data retrieved is current. v May reduce the amount of time required to retrieve the rst row of data for a query. v Stops the database manager from retrieving a block of data rows that is not used by the program when only the rst few rows of a query are retrieved before the query is closed. v Can degrade the overall performance of a query that retrieves a large number of rows. *READ: Records are blocked for read-only retrieval of data for cursors when: v *NONE is specied on the COMMIT parameter, which indicates that commitment control is not used. v The cursor is declared with a FOR READ ONLY clause or there are no dynamic statements that could run a positioned UPDATE or DELETE statement for the cursor. Specifying *READ can improve the overall performance of queries that meet the above conditions and retrieve a large number of records. DLYPRP Species whether the dynamic statement validation for a PREPARE statement is delayed until an OPEN, EXECUTE, or DESCRIBE statement is run. Delaying validation improves performance by eliminating redundant validation. *NO: Dynamic statement validation is not delayed. When the dynamic statement is prepared, the access plan is validated. When the dynamic statement is used in an OPEN or EXECUTE statement, the access plan is revalidated. Because the authority or the existence of objects referred to by the dynamic statement may change, you must still check the SQLCODE or SQLSTATE after issuing the OPEN or EXECUTE statement to ensure that the dynamic statement is still valid. *YES: Dynamic statement validation is delayed until the dynamic statement is used in an OPEN, EXECUTE, or DESCRIBE SQL statement. When the dynamic statement is used, the validation is completed and an access plan is built. If you specify *YES on this parameter, you should check the SQLCODE and SQLSTATE after running an OPEN, EXECUTE, or DESCRIBE statement to ensure that the dynamic statement is valid. Note: If you specify *YES, performance is not improved if the INTO clause is used on the PREPARE statement or if a DESCRIBE statement uses the dynamic statement before an OPEN is issued for the statement. GENLVL Species the severity level at which the create operation fails. If errors occur that have a severity level greater than this value, the operation ends.

774

DB2 UDB for AS/400 SQL Programming V4R4

CVTSQLCPP
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 10: The default severity level is 10.

severity-level: Specify a value ranging from 0 through 40.


MARGINS Species the part of the precompiler input record that contains source text. *SRCFILE: The le member margin values specied by the user on the SRCMBR parameter are used. The margin default values are 1 and 80. Element 1: Left Margin

left: Specify the beginning position for the statements. Valid values range from 1 through 80.
Element 2: Right Margin

right: Specify the ending position for the statements. Valid values range from 1 through 80.
DATFMT Species the format used when accessing date result columns. All output date elds are returned in the specied format. For input date strings, the specied value is used to determine whether the date is specied in a valid format. Note: An input date string that uses the format *USA, *ISO, *EUR, or *JIS is always valid. If a relational database is specied on the RDB parameter and the database is on a system that is not an AS/400 system, then *USA, *ISO, *EUR, or *JIS must be specied. *JOB: The format specied for the job is used. Use the Display Job (DSPJOB) command to determine the current date format for the job. *USA: The United States date format (mm/dd/yyyy) is used. *ISO: The International Organization for Standardization (ISO) date format (yyyy-mm-dd) is used. *EUR: The European date format (dd.mm.yyyy) is used. *JIS: The Japanese Industrial Standard date format (yyyy-mm-dd) is used. *MDY: The date format (mm/dd/yy) is used. *DMY: The date format (dd/mm/yy) is used. *YMD: The date format (yy/mm/dd) is used. *JUL: The Julian date format (yy/ddd) is used. DATSEP Species the separator used when accessing date result columns. Note: This parameter applies only when *JOB, *MDY, *DMY, *YMD, or *JUL is specied on the DATFMT parameter.
Appendix D. DB2 UDB for AS/400 CL Command Descriptions

775

CVTSQLCPP
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | *JOB:The date separator specied for the job at precompile time is used. Use the Display Job (DSPJOB) command to determine the current value for the job. /: A slash (/) is used. .: A period (.) is used. ,: A comma (,) is used. -: A dash (-) is used. : A blank ( ) is used. *BLANK: A blank ( ) is used. TIMFMT Species the format used when accessing time result columns. For input time strings, the specied value is used to determine whether the time is specied in a valid format. Note: An input time string that uses the format *USA, *ISO, *EUR, or *JIS is always valid. If a relational database is specied on the RDB parameter and the database is on a system that is not another AS/400 system, the time format must be *USA, *ISO, *EUR, *JIS, or *HMS with a time separator of colon or period. *HMS: The hh:mm:ss format is used. *USA: The United States time format hh:mm xx is used, where xx is AM or PM. *ISO: The International Organization for Standardization (ISO) time format hh.mm.ss is used. *EUR: The European time format hh.mm.ss is used. *JIS: The Japanese Industrial Standard time format hh:mm:ss is used. TIMSEP Species the separator used when accessing time result columns. Note: This parameter applies only when *HMS is specied on the TIMFMT parameter. *JOB: The time separator specied for the job at precompile time is used. Use the Display Job (DSPJOB) command to determine the current value for the job. :: A colon (:) is used. .: A period (.) is used. ,: A comma (,) is used. : A blank ( ) is used.

776

DB2 UDB for AS/400 SQL Programming V4R4

CVTSQLCPP
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | *BLANK: A blank ( ) is used. RDB Species the name of the relational database where the SQL package object is created. *LOCAL: The program is created as a distributed SQL program. The SQL statements will access the local database. An SQL package object is not created as part of the precompile process. The Create Structured Query Language Package (CRTSQLPKG) command can be used.

relational-database-name: Specify the name of the relational database where the new SQL package object is to be created. When the name of the local relational database is specied, the program created is still a distributed SQL program. The SQL statements will access the local database.
*NONE: An SQL package object is not created. The program object is not a distributed program and the Create Structured Query Language Package (CRTSQLPKG) command cannot be used. USER Species the user name sent to the remote system when starting the conversation. This parameter is valid only when RDB is specied. *CURRENT: The user prole under which the current job is running is used.

user-name: Specify the user name being used for the application server job.
PASSWORD Species the password to be used on the remote system. This parameter is valid only if RDB is specied. *NONE: No password is sent. If this value is specied, USER(*CURRENT) must also be specied.

password: Specify the password of the user name specied on the USER parameter.
RDBCNNMTH Species the semantics used for CONNECT statements. Refer to the SQL Reference, SC41-3612 book for more information. *DUW: CONNECT (Type 2) semantics are used to support distributed unit of work. Consecutive CONNECT statements to additional relational databases do not result in disconnection of previous connections. *RUW: CONNECT (Type 1) semantics are used to support remote unit of work. Consecutive CONNECT statements result in the previous connection being disconnected before a new connection is established. DFTRDBCOL Species the collection name used for the unqualied names of tables, views, indexes, and SQL packages. This parameter applies only to static SQL statements. *NONE: The naming convention dened on the OPTION parameter is used.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

777

CVTSQLCPP
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |

collection-name: Specify the name of the collection identier. This value is used instead of the naming convention specied on the OPTION parameter.
DYNDFTCOL Species whether the default collection name specied for the DFTRDBCOL parameter is also used for dynamic statements. *NO: Do not use the value specied on the DFTRDBCOL parameter for unqualied names of tables, views, indexes, and SQL packages for dynamic SQL statements. The naming convention specied on the OPTION parameter is used. *YES: The collection name specied on the DFTRDBCOL parameter will be used for the unqualied names of the tables, views, indexes, and SQL packages in dynamic SQL statements. SQLPKG Species the qualied name of the SQL package created on the relational database specied on the RDB parameter of this command. The possible library values are: *OBJLIB: The package is created in the library with the same name as the library specied on the OBJ parameter. library-name: Specify the name of the library where the package is created. *OBJ: The name of the SQL package is the same as the object name specied on the OBJ parameter.

package-name: Specify the name of the SQL package. If the remote system is not an AS/400 system, no more than 8 characters can be specied.
SQLPATH Species the path to be used to nd procedures, functions, and user dened types in static SQL statements. *NAMING: The path used depends on the naming convention specied on the OPTION parameter. For *SYS naming, the path used is *LIBL, the current library list at runtime. For *SQL naming, the path used is QSYS, QSYS2, userid, where userid is the value of the USER special register. If a collection-name is specied on the DFTRDBCOL parameter, the collection-name takes the place of userid. *LIBL: The path used is the library list at runtime.

collection-name: Specify a list of one or more collection names. A maximum of 43 individual collections may be specied.
SAAFLAG Species the IBM SQL agging function. This parameter ags SQL statements to verify whether they conform to IBM SQL syntax More information about which IBM database products IBM SQL syntax is in the DRDA IBM SQL Reference, SC26-3255-00. *NOFLAG: The precompiler does not check to see whether SQL statements conform to IBM SQL syntax.

778

DB2 UDB for AS/400 SQL Programming V4R4

CVTSQLCPP
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | *FLAG: The precompiler checks to see whether SQL statements conform to IBM SQL syntax FLAGSTD Species the American National Standards Institute (ANSI) agging function. This parameter ags SQL statements to verify whether they conform to the following standards.
ANSI X3.135-1992 entry ISO 9075-1992 entry FIPS 127.2 entry

*NONE: The precompiler does not check to see whether SQL statements conform to ANSI standards. *ANS: The precompiler checks to see whether SQL statements conform to ANSI standards. DBGVIEW This parameter species the type of source debug information to be provided by the SQL precompiler. *NONE: The source view will not be generated. *SOURCE: The SQL precompiler provides the source views for the root and if necessary, SQL INCLUDE statements. A view is provided that contains the statements generated by the precompiler. USRPRF Species the user prole that is used when the compiled program object is run, including the authority that the program object has for each object in static SQL statements. The prole of either the program owner or the program user is used to control which objects can be used by the program object. *NAMING: The user prole is determined by the naming convention. If the naming convention is *SQL, USRPRF(*OWNER) is used. If the naming convention is *SYS, USRPRF(*USER) is used. *USER: The prole of the user running the program object is used. *OWNER: The user proles of both the program owner and the program user are used when the program is run. DYNUSRPRF Species the user prole to be used for dynamic SQL statements. *USER: Local dynamic SQL statements are run under the prole of the programs user. Distributed dynamic SQL statements are run under the prole of the SQL packages user. *OWNER: Local dynamic SQL statements are run under the prole of the programs owner. Distributed dynamic SQL statements are run under the prole of the SQL packages owner. SRTSEQ Species the sort sequence table to be used for string comparisons in SQL statements.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

779

CVTSQLCPP
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Note: *HEX must be specied for this parameter on distributed applications where the application server is not on an AS/400 system or the release level is prior to V2R3M0. *JOB: The SRTSEQ value for the job is retrieved during the precompile. *JOBRUN: The SRTSEQ value for the job is retrieved when the program is run. For distributed applications, SRTSEQ(*JOBRUN) is valid only when LANGID(*JOBRUN) is also specied. *HEX: A sort sequence table is not used. The hexadecimal values of the characters are used to determine the sort sequence. *LANGIDSHR: The sort sequence table uses the same weight for multiple characters, and is the shared-weight sort sequence table associated with the language specied on the LANGID parameter. *LANGIDUNQ: The unique-weight sort table for the language specied on the LANGID parameter is used. The name of the table name can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used.

library-name: Specify the name of hte library to be searched. table-name: Specify the name of the sort sequence table to be used.
LANGID Species the language identier to be used when SRTSEQ(*LANGIDUNQ) or SRTSEQ(*LANGIDSHR) is specied. *JOB: The LANGID value for the job is retrieved during the precompile. *JOBRUN: The LANGID value for the job is retrieved when the program is run. For distributed applications, LANGID(*JOBRUN) is valid only when SRTSEQ(*JOBRUN) is also specied.

language-identier: Specify a language identier.


OUTPUT Species whether the precompiler listing is generated. *NONE: The precompiler listing is not generated. *PRINT: The precompiler listing is generated. PRTFILE Species the qualied name of the printer device le to which the precompiler printout is directed. The le must have a minimum length of 132 bytes. If a le with a record length of less than 132 bytes is specied, information is lost. The name of the printer le can be qualied by one of the following library values:

780

DB2 UDB for AS/400 SQL Programming V4R4

CVTSQLCPP
| | | | | | | | | | | | | | | | | | | | | | | | | | | | *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library to be searched. QSYSPRT: If a le name is not specied, the precompiler printout is directed to the IBM-supplied printer le QSYSPRT.

printer-le-name: Specify the name of the printer device le to which the precompiler printout is directed.
TEXT Species the text that briey describes the program and the function. More information on this parameter is in Appendix A, Expanded Parameter Descriptions in the CL Reference book. *SRCMBRTXT: The text is taken from the source le member being used as the text for the output source member. Text can be added or changed for a database source member by using the Start Source Entry Utility (STRSEU) command, or by using either the Add Physical File Member (ADDPFM) command or the Change Physical File Member (CHGPFM) command. If the source le is an inline le or a device le, the text is blank. *BLANK: Text is not specied.

description: Specify no more than 50 characters of text, enclosed in apostrophes.

Example
CVTSQLCPP SRCFILE(PAYROLL) SRCMBR(PAYROLL) TOSRCFILE(MYLIB/MYSRCFILE) TEXT('Payroll Program')

This command runs the SQL precompiler which precompiles the source and stores the changed source in member PAYROLL in le MYSRCFILE in library MYLIB. No module or program object is created.

DLTSQLPKG (Delete Structured Query Language Package) Command


Job: B,I Pgm: B,I REXX: B,I Exec

DLTSQLPKG

*LIBL/ SQLPKG( *CURLIB/ *USRLIBL/ *ALL/ *ALLUSR/ library-name/ SQL-package-name generic*-SQL-package name )

(1)

Notes: 1. All parameters preceding this point can be specied in positional form.
Appendix D. DB2 UDB for AS/400 CL Command Descriptions

781

DLTSQLPKG

Purpose
The Delete Structured Query Language Package (DLTSQLPKG) command is used to delete one or more SQL packages. DLTSQLPKG is a local command and must be used on the AS/400 system where the SQL package being deleted is located. To delete an SQL package on a remote system that is also an AS/400 system, use the Submit Remote Command (SBMRMTCMD) command to run the DLTSQLPKG command on the remote system. The user can do the following to delete an SQL package from a remote system that is not an AS/400 system: v Use interactive SQL to run the CONNECT and DROP PACKAGE operations. v Sign on the remote system and use a command local to that system. v Create and run an SQL program that contains a DROP PACKAGE SQL statement.

Parameters
SQLPKG Species the qualied name of the SQL package being deleted. A specic or generic SQL package name can be specied. The name of the SQL Package can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. *USRLIBL: Only the libraries in the user portion of the jobs library list are searched. *ALL: All libraries in the system, including QSYS, are searched. *ALLUSR: All user libraries are searched. All libraries with names that do not begin with the letter Q are searched except for the following:
#CGULIB #COBLIB #DFULIB #DSULIB #RPGLIB #SDALIB #SEULIB

Although the following Qxxx libraries are provided by IBM, they typically contain user data that changes frequently. Therefore, these libraries are considered user libraries and are also searched:
QDSNX QGPL QGPL38 QPFRDATA QRCL QS36F QUSER38 QUSRADSM QUSRBRM QUSRIJS QUSRINFSKR QUSRRDARS QUSRSYS QUSRVxRxMx

Note: A different library name, of the form QUSRVxRxMx, can be created by the user for each release that IBM supports. VxRxMx is the version, release, and modication level of the library.

782

DB2 UDB for AS/400 SQL Programming V4R4

DLTSQLPKG
library-name: Specify the name of the library to be searched. SQL-package-name: Specify the name of the SQL package being deleted. generic*-SQL-package-name: Specify the generic name of the SQL package to be deleted. A generic name is a character string of one or more characters followed by an asterisk (*); for example, ABC*. If a generic name is specied, all SQL packages with names that begin with the generic name, and for which the user has authority, are deleted. If an asterisk is not included with the generic (prex) name, the system assumes it to be the complete SQL package name.

Example
DLTSQLPKG SQLPKG(JONES)

This command deletes the SQL package JONES.

PRTSQLINF (Print Structured Query Language Information) Command


Job: B,I Pgm: B,I
OBJ( *CURLIB/ library-name/

REXX: B,I
*LIBL/

Exec
object-name )

PRTSQLINF

(1) *PGM *SQLPKG *SRVPGM

OBJTYPE(

Notes: 1. All parameters preceding this point can be specied in positional form.

Purpose
The Print Structured Query Language Information (PRTSQLINF) command prints information about the embedded SQL statements in a program, SQL package, or service program. The information includes the SQL statements, the access plans used during the running of the statement, and a list of the command parameters used to precompile the source member for the object.

Parameters
OBJ Species the name of the program or SQL package for which you want SQL information printed. The name of the object can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

783

PRTSQLINF
*CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used.

library-name: Specify the name of the program or SQL package for which you want information printed. object-name: Specify the name of the program or SQL package for which you want information printed.
OBJTYPE Species the type of object. *PGM: The object is a program. *SQLPKG: The object is an SQL package. *SRVPGM: The object is a service program.

Example
Example 1: PRTSQLINF Printing SQL Information PAYROLL

This command will print information about the SQL statements contained in program PAYROLL.

RUNSQLSTM (Run Structured Query Language Statement) Command


Job: B,I Pgm: B,I REXX: B,I
*LIBL/ RUNSQLSTM SRCFILE ( *CURLIB/ library-name/ source-file-name )

Exec

(1) SRCMBR ( source-file-member-name ) *UR *CHG *ALL *RS *CS *NONE *NC *RR

COMMIT (

NAMING (

*SYS *SQL

PROCESS(

*RUN *SYN

ALWCPYDTA (

*OPTIMIZE *YES *NO

ALWBLK (

*ALLREAD *NONE *READ

784

DB2 UDB for AS/400 SQL Programming V4R4

RUNSQLSTM
10 severity-level *JOB *USA *ISO *EUR *JIS *MDY *DMY *YMD *JUL

ERRLVL (

DATFMT (

DATSEP (

*JOB '/' '.' ',' '-' ' ' *BLANK

TIMFMT (

*HMS *USA *ISO *EUR *JIS

TIMSEP (

*JOB ':' '.' ',' ' ' *BLANK

) DECMPT (

*SYSVAL *JOB *PERIOD *COMMA

SRTSEQ (

*JOB *LANGIDUNQ *LANGIDSHR *HEX *LIBL/ table-name *CURLIB/ library-name/

LANGID (

*JOB language-identifier

DFTRDBCOL (

*NONE collection-name

FLAGSTD (

*NONE *ANS

SAAFLAG (

*NOFLAG *FLAG

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

785

RUNSQLSTM
*LIBL/ PRTFILE ( *CURLIB/ library-name/ QSYSPRT printer-file-name

SQL-procedure-parameters:
*CURRENT VxRxMx *ENDACTGRP *ENDMOD

TGTRLS (

CLOSQLCSR (

OUTPUT (

*NONE *PRINT

DBGVIEW (

*NONE *STMT *LIST

USRPRF (

*NAMING *OWNER *USER

DYNUSRPRF (

*USER *OWNER

DLYPRP (

*NO *YES

Notes: 1. All parameters preceding this point can be specied in positional form.

Purpose
The Run Structured Query Language Statement (RUNSQLSTM) command processes a source le of SQL statements.

Parameters
SRCFILE Species the qualied name of the source le that contains the SQL statements to be run. The name of the source le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library to be searched.

source-le-name: Specify the name of the source le that contains the SQL statements to be run. The source le can be a database le or an inline data le.

786

DB2 UDB for AS/400 SQL Programming V4R4

RUNSQLSTM
SRCMBR Species the name of the source le member that contains the SQL statements to be run. COMMIT Species whether SQL statements in the source le are run under commitment control. *CHG or *UR: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs can be seen. *ALL or *RS: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows selected, updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs cannot be seen. *CS: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows updated, deleted, and inserted are locked until the end of the unit of work (transaction). A row that is selected, but not updated, is locked until the next row is selected. Uncommitted changes in other jobs cannot be seen. *NONE or *NC: Species that commitment control is not used. Uncommitted changes in other jobs can be seen. If the SQL DROP COLLECTION statement is included in the program, *NONE or *NC must be used. If a relational database is specied on the RDB parameter and the relational database is on a system that is not on an AS/400, *NONE or *NC cannot be specied. *RR: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows selected, updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs cannot be seen. All tables referred to in SELECT, UPDATE, DELETE, and INSERT statements are locked exclusively until the end of the unit of work (transaction). NAMING Species the naming convention used for naming objects in SQL statements. *SYS: The system naming convention (library-name/le-name) is used. *SQL: The SQL naming convention (collection-name.table-name) is used. PROCESS Species whether SQL statements in the source le member are executed or syntax-checked only. *RUN: Statement are syntax-checked and run. *SYN: Statements are syntax-checked only. ALWCPYDTA Species whether a copy of the data can be used in a SELECT statement.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

787

RUNSQLSTM
*OPTIMIZE: The system determines whether to use the data retrieved directly from the database or to use a copy of the data. The decision is based on which method provides the best performance. If COMMIT is *CHG or *CS and ALWBLK is not *ALLREAD, or if COMMIT is *ALL or *RR, then a copy of the data is used only when it is necessary to run a query. *YES: A copy of the data is used only when necessary. *NO: A copy of the data is not used. If temporary copy of the data is required to perform the query, an error message is returned. ALWBLK Species whether the database manager can use record blocking, and the extent to which blocking can be used for read-only cursors. *ALLREAD: Rows are blocked for read-only cursors if *NONE or *CHG is specied on the COMMIT parameter. All cursors in a program that are not explicitly able to be updated are opened for read-only processing even though EXECUTE or EXECUTE IMMEDIATE statements may be in the program. Specifying *ALLREAD: v Allows record blocking under commitment control level *CHG in addition to the blocking allowed for *READ. v Can improve the performance of almost all read-only cursors in programs, but limits queries in the following ways: The Rollback (ROLLBACK) command, a ROLLBACK statement in host languages, or the ROLLBACK HOLD SQL statement does not reposition a read-only cursor when *ALLREAD is specied. Dynamic running of a positioned UPDATE or DELETE statement (for example, using EXECUTE IMMEDIATE), cannot be used to update a row in a cursor unless the DECLARE statement for the cursor includes the FOR UPDATE clause. *NONE: Rows are not blocked for retrieval of data for cursors. Specifying *NONE: v Guarantees that the data retrieved is current. v May reduce the amount of time required to retrieve the rst row of data for a query. v Stops the database manager from retrieving a block of data rows that is not used by the program when only the rst few rows of a query are retrieved before the query is closed. v Can degrade the overall performance of a query that retrieves a large number of rows. *READ: Records are blocked for read-only retrieval of data for cursors when: v *NONE is specied on the COMMIT parameter, which indicates that commitment control is not used. v The cursor is declared with a FOR FETCH ONLY clause or there are no dynamic statements that could run a positioned UPDATE or DELETE statement for the cursor. Specifying *READ can improve the overall performance of queries that meet the above conditions and retrieve a large number of records.

788

DB2 UDB for AS/400 SQL Programming V4R4

RUNSQLSTM
ERRLVL Species whether the processing is successful, based on the severity of the messages generated by the processing of the SQL statements. If errors that are greater than the value specied on this parameter occur during processing, no more statements are processed and the statements are rolled back if they are running under commitment control. 10: Statement processing is stopped when error messages with a severity level greater than 10 are received.

severity-level: Specify the severity level to be used.


DATFMT Species the format used when accessing date result columns. For input date strings, the specied value is used to determine whether the date is specied in a valid format. Note: An input date string that uses the format *USA, *ISO, *EUR, or *JIS is always valid. *JOB: The format specied for the job is used. Use the Display Job (DSPJOB) command to determine the current date format for the job. *USA: The United States date format (mm/dd/yyyy) is used. *ISO: The International Organization for Standardization (ISO) date format (yyyy-mm-dd) is used. *EUR: The European date format (dd.mm.yyyy) is used. *JIS: The Japanese Industrial Standard date format (yyyy-mm-dd) is used. *MDY: The date format (mm/dd/yy) is used. *DMY: The date format (dd/mm/yy) is used. *YMD: The date format (yy/mm/dd) is used. *JUL: The Julian date format (yy/ddd) is used. DATSEP Species the separator used when accessing date result columns. Note: This parameter applies only when *JOB, *MDY, *DMY, *YMD, or *JUL is specied on the DATFMT parameter. *JOB: The date separator specied for the job is used. Use the Display Job (DSPJOB) command to determine the current value for the job. /: A slash (/) is used. .: A period (.) is used. ,: A comma (,) is used. -: A dash (-) is used.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

789

RUNSQLSTM
: A blank ( ) is used. *BLANK: A blank ( ) is used. TIMFMT Species the format used when accessing time result columns. For input time strings, the specied value is used to determine whether the time is specied in a valid format. Note: An input date string that uses the format *USA, *ISO, *EUR, or *JIS is always valid. *HMS: The hh:mm:ss format is used. *USA: The United States time format hh:mm xx is used, where xx is AM or PM. *ISO: The International Organization for Standardization (ISO) time format hh.mm.ss is used. *EUR: The European time format hh.mm.ss is used. *JIS: The Japanese Industrial Standard time format hh:mm:ss is used. TIMSEP Species the separator used when accessing time result columns. Note: This parameter applies only when *HMS is specied on the TIMFMT parameter. *JOB: The time separator specied for the job is used. Use the Display Job (DSPJOB) command to determine the current value for the job. :: A colon (:) is used. .: A period (.) is used. ,: A comma (,) is used. : A blank ( ) is used. *BLANK: A blank ( ) is used. DECMPT Species the decimal point value used for numeric constants in SQL statements. *JOB: The value used as the decimal point for numeric constants in SQL is the representation of decimal point specied by the job running the statement. *SYSVAL: The QDECFMT system value is used as the decimal point. *PERIOD: A period represents the decimal point. *COMMA: A comma represents the decimal point. SRTSEQ Species the sort sequence table to be used for string comparisons in SQL statements.

790

DB2 UDB for AS/400 SQL Programming V4R4

RUNSQLSTM
*JOB: The LANGID value for the job is retrieved. *LANGIDSHR: The sort sequence table uses the same weight for multiple characters, and is the shared-weight sort sequence table associated with the language specied on the LANGID parameter. *LANGIDUNQ: The unique-weight sort table for the language specied on the LANGID parameter is used. *HEX: A sort sequence table is not used. The hexadecimal values of the characters are used to determine the sort sequence. The name of the table name can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library to be searched.

table-name: Specify the name of the sort sequence table to be used.


LANGID Species the language identier to be used when SRTSEQ(*LANGIDUNQ) or SRTSEQ(*LANGIDSHR) is specied. *JOB: The LANGID value for the job is retrieved during the precompile.

language-identier: Specify a language identier.


DFTRDBCOL Species the collection name used for the unqualied names of tables, views, indexes, and SQL packages. This parameter applies only to static SQL statements. *NONE: The naming convention dened on the OPTION parameter is used.

collection-name: Specify the name of the collection identier. This value is used instead of the naming convention specied on the OPTION parameter.
FLAGSTD Species the American National Standards Institute (ANSI) agging function. This parameter ags SQL statements to verify whether they conform to the following standards.
ANSI X3.135-1992 entry ISO 9075-1992 entry FIPS 127.2 entry

*NONE: The SQL statements are not checked to determine whether they conform to ANSI standards. *ANS: The SQL statements are checked to determine whether they conform to ANSI standards. SAAFLAG Species the IBM SQL agging function. This parameter ags SQL statements

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

791

RUNSQLSTM
to verify whether they conform to IBM SQL syntax More information about which IBM database products IBM SQL syntax is in the DRDA IBM SQL Reference, SC26-3255-00. *NOFLAG: The SQL statements are not checked to determine whether they conform to IBM SQL syntax. *FLAG: The SQL statements are checked to determine whether they conform to IBM SQL syntax. PRTFILE Species the qualied name of the printer device le to which the RUNSQLSTM printout is directed. The le must have a minimum length of 132 bytes. If a le with a record length of less than 132 bytes is specied, information is lost. The name of the printer le can be qualied by one of hte following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library to be searched. QSYSPRT: If a le name is not specied, the RUNSQLSTM printout is directed to the IBM-supplied printer le QSYSPRT.

printer-le-name: Specify the name of the printer device le to which the RUNSQLSTM printout is directed.

Parameters for SQL procedures


The parameters listed below only apply to statements within the source le that create SQL procedures. The parameters are used during the creation of the program object associated with the SQL procedure. TGTRLS Species the release of the operating system on which the user intends to use the object being created. In the examples given for the *CURRENT value, and when specifying the release-level value, the format VxRxMx is used to specify the release, where Vx is the version, Rx is the release, and Mx is the modication level. For example, V2R3M0 is version 2, release 3, modication level 0. *CURRENT The object is to be used on the release of the operating system currently running on the users system. For example, if V2R3M5 is running on the system, *CURRENT means the user intends to use the object on a system with V2R3M5 installed. The user can also use the object on a system with any subsequent release of the operating system installed. Note: If V2R3M5 is running on the system, and the object is to be used on a system with V2R3M0 installed, specify TGTRLS(V2R3M0) not TGRRLS(*CURRENT).

792

DB2 UDB for AS/400 SQL Programming V4R4

RUNSQLSTM
release-level: Specify the release in the format VxRxMx. The object can be used on a system with the specied release or with any subsequent release of the operating system installed.
Valid values depend on the current version, release, and modication level, and they change with each new release. If you specify a release-level which is earlier than the earliest release level supported by this command, an error message is sent indicating the earliest supported release. CLOSQLCSR Species when SQL cursors are implicitly closed, SQL prepared statements are implicitly discarded, and LOCK TABLE locks are released. SQL cursors are explicitly closed when you issue the CLOSE, COMMIT, or ROLLBACK (without HOLD) SQL statements. *ENDACTGRP: SQL cursors are closed and SQL prepared statements are implicitly discarded. ENDMOD: SQL cursors are closed and SQL prepared statements are implicitly discarded when the module is exited. LOCK TABLE locks are released when the rst SQL program on the call stack ends. OUTPUT Species whether the precompiler listing is generated. *NONE: The precompiler listing is not generated. *PRINT: The precompiler listing is generated. DBGVIEW Species the type of source debug information to be provided by the SQL precompiler. *NONE: The source view will not be generated. *STMT: Allows the compiled module to be debugged using program statement numbers and symbolic identiers. *LIST: Generates the listing view for debugging the compiled module object. USRPRF Species the user prole that is used when the compiled program object is run, including the authority that the program object has for each object in static SQL statements. The prole of either the program owner or the program user is used to control which objects can be used by the program object. *NAMING: The user prole is determined by the naming convention. If the naming convention is *SQL, USRPRF(*OWNER) is used. If the naming convention is *SYS, USRPRF(*USER) is used. *USER: The prole of the user running the program object is used. *OWNER: The user proles of both the program owner and the program user are used when the program is run. DYNUSRPRF Species the user prole to be used for dynamic SQL statements.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

793

RUNSQLSTM
*USER: For local, dynamic SQL statements run under the user of the programs user. For distributed, dynamic SQL statements run under the prole of the SQL packages user. *OWNER: For local, dynamic SQL statements run under the prole of the programs owner. For distributed, dynamic SQL statements run under the prole of the SQL packages owner. DLYPRP Species whether the dynamic statement validation for a PREPARE statement is delayed until an OPEN, EXECUTE, or DESCRIBE statement is run. Delaying validation improves performance by eliminating redundant validation. *NO: Dynamic statement validation is not delayed. When the dynamic statement is prepared, the access plan is validated. When the dynamic statement is used in an OPEN or EXECUTE statement, the access plan is revalidated. Because the authority or the existence of objects referred to by the dynamic statement may change, you must still check the SQLCODE or SQLSTATE after issuing the OPEN or EXECUTE statement to ensure that the dynamic statement is still valid. *YES: Dynamic statement validation is delayed until the dynamic statement is used in an OPEN, EXECUTE, or DESCRIBE SQL statement. When the dynamic statement is used, the validation is completed and an access plan is built. If you specify *YES on this parameter, you should check the SQLCODE and SQLSTATE after running an OPEN, EXECUTE, or DESCRIBE statement to ensure that the dynamic statement is valid. Note: If you specify *YES, performance is not improved if the INTO clause is used on the PREPARE statement or if a DESCRIBE statement uses the dynamic statement before an OPEN is issued for the statement.

Example
RUNSQLSTM SRCFILE(MYLIB/MYFILE) SRCMBR(MYMBR)

This command processes the SQL statements in member MYMBR found in le MYFILE in library MYLIB.

STRSQL (Start Structured Query Language) Command


Job: I Pgm: I REXX: I Exec
*SYS *SQL

STRSQL *NC *NONE *CHG *UR *CS *RS *ALL *RR NAMING( ) )

COMMIT(

794

DB2 UDB for AS/400 SQL Programming V4R4

STRSQL
*RUN *VLD *SYN *LIBL *CURLIB *USRLIBL *ALL *ALLUSR library-name

PROCESS(

LIBOPT(

(1) *ALL *SQL *ALWAYS *FORWARD

LISTTYPE(

REFRESH(

ALWCPYDTA(

*YES *OPTIMIZE *NO

DATFMT(

*JOB *USA *ISO *EUR *JIS *MDY *DMY *YMD *JUL

(2) DATSEP(

*JOB *BLANK / . , -

TIMFMT(

*HMS *USA *ISO *EUR *JIS

(3) TIMSEP(

*JOB *BLANK : . ,

DECPNT(

*SYSVAL *PERIOD *COMMA *JOB

(4) PGMLNG(

*NONE *C *CBL *PLI *RPG *FTN

(5) SQLSTRDLM(

(6)

*QUOTESQL *APOSTSQL

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

795

STRSQL
*JOB *JOBRUN *LANGIDUNQ *LANGIDSHR *HEX *LIBL/ table-name *CURLIB/ library-name/

SRTSEQ(

LANGID(

*JOB *JOBRUN language-ID

Notes: 1. All parameters preceding this point can be specied in positional form. 2. DATSEP is only valid when *MDY, *DMY, *YMD, or *JUL is specied on the DATFMT parameter. 3. TIMSEP is only valid when TIMFMT(*HMS) is specied. 4. PGMLNG and SQLSTRDLM are valid only when PROCESS(*SYN) is specied. 5. PGMLNG and SQLSTRDLM are valid only when PROCESS(*SYN) is specied. 6. SQLSTRDLM is valid only when PGMLNG(*CBL) is specied.

Purpose
The Start Structured Query Language (STRSQL) command starts the interactive Structured Query Language (SQL) program. The program starts the statement entry of the interactive SQL program which immediately shows the Enter SQL Statements display. This display allows the user to build, edit, enter, and run an SQL statement in an interactive environment. Messages received during the running of the program are shown on this display.

Parameters
COMMIT Species whether the SQL statements are run under commitment control. *NONE or *NC: Species that commitment control is not used. Uncommitted changes in other jobs can be seen. If the SQL DROP COLLECTION statement is included in the program, *NONE or *NC must be used. If a relational database is specied on the RDB parameter and the relational database is on a system that is not on an AS/400, *NONE or *NC cannot be specied. *CHG or *UR: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs can be seen. *CS: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and

796

DB2 UDB for AS/400 SQL Programming V4R4

STRSQL
the rows updated, deleted, and inserted are locked until the end of the unit of work (transaction). A row that is selected, but not updated, is locked until the next row is selected. Uncommitted changes in other jobs cannot be seen. *ALL or *RS: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows selected, updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs cannot be seen. *RR: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows selected, updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs cannot be seen. All tables referred to in SELECT, UPDATE, DELETE, and INSERT statements are locked exclusively until the end of the unit of work (transaction). Note: The default for this parameter for the CRTSQLXXX commands (when XXX=CI, CPPI, CBL, FTN, PLI, CBLI, RPG or RPGI) is *CHG. NAMING Species the naming convention used for naming objects in SQL statements. *SYS: The system naming convention (library-name/le-name) is used. *SQL: The SQL naming convention (collection-name.table-name) is used. PROCESS Species the values used to process the SQL statements. *RUN: The statements are syntax checked, data checked, and then run. *VLD: The statements are syntax checked and data checked, but not run. *SYN: The statements are syntax checked only. LIBOPT Species which collections and libraries are used as a basis for building a collection list when the F4, F16, F17, or F18 function key is pressed. The name of the collection list can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. *USRLIBL: Only the libraries in the user portion of the jobs library list are searched. *ALL: All libraries in the system, including QSYS, are searched. *ALLUSR: All user libraries are searched. All libraries with names that do not begin with the letter Q are searched except for the following:
#CGULIB #COBLIB #DFULIB #DSULIB #RPGLIB #SDALIB #SEULIB

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

797

STRSQL
Although the following Qxxx libraries are provided by IBM, they typically contain user data that changes frequently. Therefore, these libraries are considered user libraries and are also searched:
QDSNX QGPL QGPL38 QPFRDATA QRCL QS36F QUSER38 QUSRADSM QUSRBRM QUSRIJS QUSRINFSKR QUSRRDARS QUSRSYS QUSRVxRxMx

Note: A different library name, of the form QUSRVxRxMx, can be created by the user for each release that IBM supports. VxRxMx is the version, release, and modication level of the library.

library-name: Specify the name of the library to be searched.


LISTTYPE Species the types of objects that are displayed with list support by pressing the F4, F16, F17, or F18 function key. *ALL: All objects are displayed. *SQL: Only SQL-created objects are displayed. REFRESH Species when the display select output data is refreshed. *ALWAYS: Data is normally refreshed during forward and backward scrolling. *FORWARD: Data is refreshed only during forward scrolling to the end of the data for the rst time. When scrolling backward, a copy of the data already viewed is shown. ALWCPYDTA Species whether a copy of the data can be used in a SELECT statement. If COMMIT(*ALL) is specied, SQL run time ignores the ALWCPYDTA value and uses current data. *YES: A copy of the data is used when necessary. *OPTIMIZE: The system determines whether to use the data retrieved from the database or to use a copy of the data. The determination is based on which will provide the best performance. *NO: A copy of the data is not allowed. If a temporary copy of the data is required to perform the query, an error message is returned. DATFMT Species the date format used in SQL statements. *JOB: The format specied on the job attribute DATFMT is used. *USA: The United States date format (mm/dd/yyyy) is used. *ISO: The International Standards Organization date format (yyyy-mm-dd) is used. *EUR: The European date format (dd.mm.yyyy) is used.

798

DB2 UDB for AS/400 SQL Programming V4R4

STRSQL
*JIS: The Japanese Industry Standard Christian Era date format (yyyy-mm-dd) is used. *MDY: The month, day, and year date format (mm/dd/yy) is used. *DMY: The day, month, and year date format (dd/mm/yy) is used. *YMD: The year, month, and day date format (yy/mm/dd) is used. *JUL: The Julian date format (yy/ddd) is used. DATSEP Species the date separator used in SQL statements. *JOB: The date separator specied on the job attribute is used. If the user species *JOB on a new interactive SQL session, the current value is stored and used. Later changes to the jobs date separator are not detected by interactive SQL. *BLANK: A blank ( ) is used. /: A slash (/) is used. .: A period (.) is used. ,: A comma (,) is used. -: A dash (-) is used. : A blank ( ) is used. TIMFMT Species the time format used in SQL statements. *HMS: The Hour-Minute-Second time format (hh:mm:ss) is used. *USA: The United States time format (hh:mm xx, where xx is AM or PM) is used. *ISO: The International Standards Organization time format (hh.mm.ss) is used. *EUR: The European time format (hh.mm.ss) is used. *JIS: The Japanese Industry Standard Christian Era time format (hh:mm:ss) is used. TIMSEP Species the time separator used in SQL statements. *JOB: The time separator specied on the job attribute is used. If the user species *JOB on a new interactive SQL session, the current value is stored and used. Later changes to the jobs time separator are not detected by interactive SQL. *BLANK: A blank ( ) is used. :: A colon (:) is used.
Appendix D. DB2 UDB for AS/400 CL Command Descriptions

799

STRSQL
.: A period (.) is used. ,: A comma (,) is used. : A blank ( ) is used. DECPNT Species the kind of decimal point to use. *JOB: The value used as the decimal point for numeric constants in SQL is the representation of decimal point specied for the job running the statement. *SYSVAL: The decimal point is extracted from the system value. If the user species *SYSVAL on a new interactive SQL session, the current value is stored and used. Later changes to the systems time separator are not detected by interactive SQL. *PERIOD: A period represents the decimal point. *COMMA: A comma represents the decimal point. PGMLNG Species which program language syntax rules to use. To use this parameter, *SYN must be selected at the PROCESS parameter. *NONE: No specic languages syntax check rules are used. The supported languages are: *C: Syntax checking is done according to the C language syntax rules. *CBL: Syntax checking is done according to the COBOL language syntax rules. *PLI: Syntax checking is done according to the PL/I language syntax rules. *RPG: Syntax checking is done according to the RPG language syntax rules. *FTN: Syntax checking is done according to the FORTRAN language syntax rules. SQLSTRDLM Species the SQL string delimiter. Use of this parameter requires using the COBOL (*CBL) character set. *QUOTESQL: A quotation mark represents the SQL string delimiter. *APOSTSQL: An apostrophe represents the SQL string delimiter. SRTSEQ Species the sort sequence table to be used for string comparisons in SQL statements on the Enter SQL Statements display. *JOB: The SRTSEQ value for the job is retrieved. *JOBRUN: The SRTSEQ value for the job is retrieved each time the user starts interactive SQL.

800

DB2 UDB for AS/400 SQL Programming V4R4

STRSQL
*LANGIDUNQ: The unique-weight sort table for the language specied on the LANGID parameter is used. *LANGIDSHR: The shared-weight sort table for the language specied on the LANGID parameter is used. *HEX: A sort sequence table is not used. The hexadecimal values of the characters are used to determine the sort sequence. The name of the table name can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used.

library-name: Specify the name of the library to be searched. table-name: Specify the name of the sort sequence table to be used with the interactive SQL session.
LANGID Species the language identier to be used when SRTSEQ(*LANGIDUNQ) or SRTSEQ(*LANGIDSHR) is specied. *JOB: The LANGID value for the job is retrieved. *JOBRUN: The LANGID value for the job is retrieved each time interactive SQL is started.

language-ID: Specify the language identier to be used.

Example
STRSQL PROCESS(*SYN) NAMING(*SQL) DECPNT(*COMMA) PGMLNG(*CBL) SQLSTRDLM(*APOSTSQL)

This command starts an interactive SQL session that checks only the syntax of SQL statements. The character set used by the syntax checker uses the COBOL language syntax rules. The SQL naming convention is used for this session. The decimal point is represented by a comma, and the SQL string delimiter is represented by an apostrophe.

Appendix D. DB2 UDB for AS/400 CL Command Descriptions

801

STRSQL

802

DB2 UDB for AS/400 SQL Programming V4R4

Appendix E. Using the C for AS/400 and FORTRAN for AS/400 Precompilers
This appendix contains the syntax diagrams for the C for AS/400 and FORTRAN for AS/400 precompilers, although these are no longer supported on the AS/400. Another appendix, Appendix F. Coding SQL Statements in FORTRAN Applications on page 837, describes the unique application and coding requirements for embedding SQL statements in a FORTRAN/400 program.

Using the C for AS/400 Precompiler


C for AS/400 is no longer a supported compiler for the AS/400 system. This appendix is intended to help those customers who are using the SQL C for AS/400 precompiler with other non-IBM C compilers. The SQL C for AS/400 precompiler support is the same as the ILE C for AS/400 precompiler support with the exception of the information included in this appendix.

Access plans
The SQL C for AS/400 precompiler generates access plan structures that are for use with non-ILE programs.

Host variable data types


The SQL C for AS/400 precompiler does not support the decimal data type.

Using external le descriptions


You can use the C #pragma mapinc directive with the #include directive to include external le descriptions in your program. When used with SQL, only a particular format of the #pragma mapinc directive is recognized by the SQL precompiler. If all of the required elements are not specied, the precompiler ignores the directive and does not generate host variable structures. The required elements are: v Include name v Externally described le name v Format name or a list of format names v Options v p z parameter The library name, union name, and prex name are optional. Although typedef statements coded by the user are not recognized by the precompiler, those created by the #pragma mapinc and #include directives are recognized. Unions declared using the typedef union created by the #pragma mapinc and #include directive cannot be used as host variables in SQL statements; the members of the unions can be used. Structures that contain the typedef structure cannot be used in SQL statements; the structure declared using the typedef can be used. To retrieve the denition of the sample table DEPARTMENT described in Appendix A. DB2 UDB for AS/400 Sample Tables, you can code the following:

Copyright IBM Corp. 1997, 1999

803

#pragma mapinc ("dept","CORPDATA/DEPARTMENT(*ALL)","both","p z") #include "dept" CORPDATA_DEPARTMENT_DEPARTMENT_both_t Dept_Structure;

A host structure named Dept_Structure is dened with the following elements: DEPTNO, DEPTNAME, MGRNO, and ADMRDEPT. These eld names can be used as host variables in SQL statements. Note: DATE, TIME, and TIMESTAMP columns generate character host variable denitions. They are treated by SQL with the same comparison and assignment rules as a DATE, TIME, and TIMESTAMP column. For example, a date host variable can only compared against a DATE column or a character string which is a valid representation of a date. Although packed, zoned, and binary (with non-zero scale elds) are mapped to character elds in C, SQL will treat these elds as numeric. By using the extended program model (EPM) routines, you can manipulate these elds to convert zoned and packed decimal data. For more information, see the ILE C for AS/400 Language Reference book.

CRTSQLC (Create Structured Query Language C) Command


Job: B,I Pgm: B,I
PGM( library-name/

REXX: B,I
*CURLIB/

Exec
program-name )

CRTSQLC

*LIBL/ SRCFILE( *CURLIB/ library-name/

QCSRC source-file-name

(1) *PGM source-file-member-name

SRCMBR(

OPTION(

OPTION Details

) TGTRLS(

*CURRENT *PRV VxRxMx

*LIBL/ INCFILE( *CURLIB/ library-name/

*SRCFILE source-file-name

804

DB2 UDB for AS/400 SQL Programming V4R4

COMMIT(

*CHG *ALL *CS *NONE

CLOSQLCSR(

*ENDPGM *ENDSQL *ENDJOB

ALWCPYDTA(

*YES *OPTIMIZE *NO

ALWBLK(

*READ *NONE *ALLREAD

DLYPRP(

*NO *YES

GENLVL(

10 severity-level

MARGINS(

*SRCFILE left-right

DATFMT(

*JOB *USA *ISO *EUR *JIS *MDY *DMY *YMD *JUL

DATSEP(

*JOB '/' '.' ',' '-' ' ' *BLANK

TIMFMT(

*HMS *USA *ISO *EUR *JIS

TIMSEP(

*JOB ':' '.' ',' ' ' *BLANK

REPLACE(

*YES *NO

RDB(

*NONE relational-database-name

USER(

*CURRENT user-name

PASSWORD(

*NONE password

Appendix E. Using the C for AS/400 and FORTRAN for AS/400 Precompilers

805

RDBCNNMTH(

*DUW *RUW

DFTRDBCOL(

*NONE collection-name

*PGMLIB/ SQLPKG( library-name/

*PGM package-name

SAAFLAG(

*NOFLAG *FLAG

FLAGSTD(

*NONE *ANS

*LIBL/ PRTFILE( *CURLIB/ library-name/

QSYSPRT printer-file-name

SRTSEQ(

*JOB *JOBRUN *LANGIDUNQ *LANGIDSHR *HEX *LIBL/ table-name *CURLIB/ library-name/

LANGID(

*JOB *JOBRUN language-ID

DYNUSRPRF(

*USER *OWNER

QTEMP/ TOSRCFILE *LIBL/ *CURLIB/ library-name/

QSQLTEMP source-file-name

TEXT(

*SRCMBRTXT *BLANK 'description'

OPTION Details:

806

DB2 UDB for AS/400 SQL Programming V4R4

*NOSRC *NOSOURCE *SOURCE *SRC

*NOXREF *XREF

*NOGEN

*JOB *PERIOD *SYSVAL *COMMA

*SYS *SQL

*NOSECLVL *SECLVL

*NODEBUG *DEBUG

*NOCNULRQD *CNULRQD

*NOLSTDBG *LSTDBG

Notes: 1. All parameters preceding this point can be specied in positional form.

Purpose
The Create Structured Query Language C (CRTSQLC) command calls the Structured Query Language (SQL) precompiler which precompiles C source containing SQL statements, produces a temporary source member. Note: The C for AS/400 Compiler is no longer supported. This CRTSQLC command is provided for use by other non-IBM C compilers. The supported IBM compiler is ILE C for AS/400 and the SQL precompiler command is CRTSQLCI.

Parameters
PGM Species the qualied name of the compiled program. The name of the compiled C program can be qualied by one of the following library values: *CURLIB: The compiled C program is created in the current library for the job. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library where the compiled C program is created.

program-name: Specify the name of the compiled C program.


SRCFILE Species the qualied name of the source le that contains the C source with SQL statements. The name of the source le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used.

library-name: Specify the name of the library to be searched.


QCSRC: If the source le name is not specied, the IBM-supplied source le QCSRC contains the C source.

Appendix E. Using the C for AS/400 and FORTRAN for AS/400 Precompilers

807

source-le-name: Specify the name of the source le that contains the C source.
SRCMBR Species the name of the source le member that contains the C source. This parameter is specied only if the source le name in the SRCFILE parameter is a database le. If this parameter is not specied, the PGM name specied on the PGM parameter is used. *PGM: Species that the C source is in the member of the source le that has the same name as that specied on the PGM parameter.

source-le-member-name: Specify the name of the member that contains the C source.
OPTION Species whether one or more of the following options are used when the C source is precompiled. If an option is specied more than once, or if two options conict, the last option specied is used. Element 1: Source Listing Options *NOSOURCE or *NOSRC: A source printout is not produced by the precompiler unless errors are detected by the precompile or create package. *SOURCE or *SRC: The precompiler produces a source listing consisting of C source input. Element 2: Cross-Reference Options *NOXREF: The precompiler does not cross-reference names. *XREF: The precompiler cross-references items in the program to the statement numbers in the program that refer to those items. Element 3: Program Creation Option *NOGEN: The precompiler does not call the C compiler, and a program and SQL package are not created. Element 4: Decimal Point Options *JOB: The value used as the decimal point for numeric constants in SQL is the representation of decimal point specied for the job at precompile time. *PERIOD: The value used as the decimal point for numeric constants in SQL statements is a period. *SYSVAL: The value used as the decimal point for numeric constants in SQL statements is the QDECFMT system value. Note: If QDECFMT species that the value used as the decimal point is a comma, any numeric constants in lists (such as in the SELECT clause or the VALUES clause) must be separated by a comma followed by a blank. For example, VALUES(1,1, 2,23, 4,1) is equivalent to VALUES(1.1,2.23,4.1) in which the decimal point is a period.

808

DB2 UDB for AS/400 SQL Programming V4R4

*COMMA: The value used as the decimal point for numeric constants in SQL statements is a comma. Note: Any numeric constants in lists (such as in the SELECT clause or the VALUES clause) must be separated by a comma followed by a blank. For example, VALUES(1,1, 2,23, 4,1) is equivalent to VALUES(1.1,2.23,4.1) where the decimal point is a period. Element 5: Naming Convention Options *SYS: The system naming convention (library-name/le-name) is used. *SQL: The SQL naming convention is used (collection-name.table-name). When creating a program on a remote database other than an AS/400 system, *SQL must be specied as the naming convention. Element 6: Second-Level Message Text Option *NOSECLVL: Second-level text descriptions are not added to the listing. *SECLVL: Second-level text with replacement data is added for all messages on the listing. Element 7: Debug Options *NODEBUG: Symbolic extended program model (EPM) debug information is not stored with the program. This option is passed to the compiler and does not affect the SQL precompiler. *DEBUG: Symbolic EPM debug information is stored with the program. This option is passed to the compiler and does not affect the SQL precompiler. Element 8: NUL Required Options *NOCNULRQD: For output character and graphic host variables, the NUL-terminator is not returned when the host variable is exactly the same length as the data. Input character and graphic host variables do not require a NUL-terminator. *CNULRQD: Output character and graphic host variables always contain the NUL-terminator. If there is not enough space for the NUL-terminator, the data is truncated and the NUL-terminator is added. Input character and graphic host variables require a NUL-terminator. Element 9: Event File Creation *NOEVENTF: The compiler will not produce an event le for use by CoOperative Development Environment/400 (CODE/400). *EVENTF: The compiler produces an event le for use by CoOperative Development Environment/400 (CODE/400). The event le will be created as a member in the le EVFEVENT in your source library. CODE/400 uses this le to offer error feedback integrated with the CODE/400 editor. This option is normally specied by CODE/400 on your behalf.

Appendix E. Using the C for AS/400 and FORTRAN for AS/400 Precompilers

809

TGTRLS Species the release of the operating system on which the user intends to use the object being created. In the examples given for the *CURRENT and *PRV values, and when specifying the release-level value, the format VxRxMx is used to specify the release, where Vx is the version, Rx is the release, and Mx is the modication level. For example, V2R3M0 is version 2, release 3, modication level 0. *CURRENT: The object is to be used on the release of the operating system currently running on the users system. For example, if V2R3M5 is running on the system, *CURRENT means the user intends to use the object on a system with V2R3M5 installed. The user can also use the object on a system with any subsequent release of the operating system installed. Note: If V2R3M5 is running on the system, and the object is to be used on a system with V2R3M0 installed, specify TGTRLS(V2R3M0) not TGTRLS(*CURRENT). *PRV: The object is to be used on the previous release with modication level 0 of the operating system. For example, if V2R3M5 is running on the users system, *PRV means the user intends to use the object on a system with V2R2M0 installed. The user can also use the object on a system with any subsequent release of the operating system installed.

release-level: Specify the release in the format VxRxMx. The object can be used on a system with the specied release or with any subsequent release of the operating system installed.
Valid values depend on the current version, release, and modication level, and they change with each new release. If you specify a release-level which is earlier than the earliest release level supported by this command, an error message is sent indicating the earliest supported release. INCFILE Species the qualied name of the source le that contains members included in the program with any SQL INCLUDE statement. The name of the source le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used.

library-name: Specify the name of the library to be searched.


*SRCFILE: The qualied source le specied in the SRCFILE parameter contains the source le members specied on any SQL INCLUDE statement.

source-le-name: Specify the name of the source le that contains the source le members specied on any SQL INCLUDE statement. The record length of the source le specied here must be no less than the record length of the source le specied on the SRCFILE parameter.
COMMIT Species whether SQL statements in the compiled program are run under

810

DB2 UDB for AS/400 SQL Programming V4R4

commitment control. Files referred to in the host language source are not affected by this option. Only SQL tables, SQL views, and SQL packages referred to in SQL statements are affected. *CHG: Species the objects referred to in SQL ALTER, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, and REVOKE statements and the rows updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs can be seen. *ALL: Species the objects referred to in SQL ALTER, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, and REVOKE statements and the rows selected, updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs cannot be seen. *CS: Species the objects referred to in SQL ALTER, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, and REVOKE statements and the rows updated, deleted, and inserted are locked until the end of the unit of work (transaction). A row that is selected, but not updated, is locked until the next row is selected. Uncommitted changes in other jobs cannot be seen. *NONE: Species that commitment control is not used. Uncommitted changes in other jobs can be seen. If the SQL DROP COLLECTION statement is included in the program, *NONE must be used. If a relational database is specied on the RDB parameter and the relational database is on a system that is not on an AS/400, *NONE cannot be specied. CLOSQLCSR Species when SQL cursors are implicitly closed, SQL prepared statements are implicitly discarded, and LOCK TABLE locks are released. SQL cursors are explicitly closed when you issue the CLOSE, COMMIT, or ROLLBACK (without HOLD) SQL statements. *ENDPGM: SQL cursors are closed and SQL prepared statements are discarded when the program ends. LOCK TABLE locks are released when the rst SQL program on the call stack ends. *ENDSQL: SQL cursors remain open between calls and can be fetched without running another SQL OPEN. One of the programs higher on the call stack must have run at least one SQL statement. SQL cursors are closed, SQL prepared statements are discarded, and LOCK TABLE locks are released when the rst SQL program on the call stack ends. If *ENDSQL is specied for a program that is the rst SQL program called (the rst SQL program on the call stack), the program is treated as if *ENDPGM was specied. *ENDJOB: SQL cursors remain open between calls and can be fetched without running another SQL OPEN. The programs higher on the call stack do not need to have run SQL statements. SQL cursors are left open, SQL prepared statements are preserved, and LOCK TABLE locks are held when the rst SQL program on the call stack ends. SQL cursors are closed, SQL prepared statements are discarded, and LOCK TABLE locks are released when the job ends. ALWCPYDTA Species whether a copy of the data can be used in a SELECT statement. *OPTIMIZE: The system determines whether to use the data retrieved directly from the database or to use a copy of the data. The decision is based on which
Appendix E. Using the C for AS/400 and FORTRAN for AS/400 Precompilers

811

method provides the best performance. If COMMIT is *CHG or *CS and ALWBLK is not *ALLREAD, or if COMMIT is *ALL or *RR, then a copy of the data is used only when it is necessary to run a query. *YES: A copy of the data is used only when necessary. *NO: A copy of the data is not used. If a temporary copy of the data is required to perform the query, an error message is returned. ALWBLK Species whether the database manager can use record blocking, and the extent to which blocking can be used for read-only cursors. *ALLREAD: Rows are not blocked for retrieval of data for cursors. Specifying *NONE: v Guarantees that the data retrieved is current. v May reduce the amount of time required to retrieve the rst row of data for a query. v Stops the database manager from retrieving a block of data rows that is not used by the program when only the rst few rows of a query are retrieved before the query is closed. v Can degrade the overall performance of a query that retrieves a large number of rows. *NONE: Rows are not blocked for retrieval of data for cursors. Specifying *NONE: v Guarantees that the data retrieved is current. v May reduce the amount of time required to retrieve the rst row of data for a query. v Stops the database manager from retrieving a block of data rows that is not used by the program when only the rst few rows of a query are retrieved before the query is closed. v Can degrade the overall performance of a query that retrieves a large number of rows. *READ: Records are blocked for read-only retrieval of data for cursors when: v *NONE is specied on the COMMIT parameter, which indicates that commitment control is not used. v The cursor is declared with a FOR FETCH ONLY clause or there are no dynamic statements that could run a positioned UPDATE or DELETE statement for the cursor. Specifying *READ can improve the overall performance of queries that meet the above conditions and retrieve a large number of records. DLYPRP Species whether the dynamic statement validation for a PREPARE statement is delayed until an OPEN, EXECUTE, or DESCRIBE statement is run. Delaying validation improves performance by eliminating redundant validation. *NO: Dynamic statement validation is not delayed. When the dynamic statement is prepared, the access plan is validated. When the dynamic

812

DB2 UDB for AS/400 SQL Programming V4R4

statement is used in an OPEN or EXECUTE statement, the access plan is revalidated. Because the authority or the existence of objects referred to by the dynamic statement may change, you must still check the SQLCODE or SQLSTATE after issuing the OPEN or EXECUTE statement to ensure that the dynamic statement is still valid. *YES: Dynamic statement validation is delayed until the dynamic statement is used in an OPEN, EXECUTE, or DESCRIBE SQL statement. When the dynamic statement is used, the validation is completed and an access plan is built. If you specify *YES on this parameter, you should check the SQLCODE and SQLSTATE after running an OPEN, EXECUTE, or DESCRIBE statement to ensure that the dynamic statement is valid. Note: If you specify *YES, performance is not improved if the INTO clause is used on the PREPARE statement or if a DESCRIBE statement uses the dynamic statement before an OPEN is issued for the statement. GENLVL Species the severity level at which the create operation fails. If errors occur that have a severity level greater than or equal to this value, the operation ends. 10: The default severity level is 10.

severity-level: Specify a value ranging from 0 through 40.


MARGINS Species the part of the precompiler input record that contains source text. *SRCFILE:The le member margin values that you specied on the SRCMBR parameter are used. If the member is an SQLC, SQLCLE, C, or CLE source type, the margin values are the values specied on the source entry utility (SEU) services display. If the member is a different source type, the margin values are the default values of 1 and 80. Element 1: Left Margin

left: Specify the beginning position for the statements. Valid values range from 1 through 80.
Element 2: Right Margin

right: Specify the ending position for the statements. Valid values range from 1 through 80.
DATFMT Species the format used when accessing date result columns. All output date elds are returned in the specied format. For input date strings, the specied value is used to determine whether the date is specied in a valid format. Note: An input date string that uses the format *USA, *ISO, *EUR, or *JIS is always valid. If a relational database is specied on the RDB parameter and the database is on a system that is not an AS/400 system, then *USA, *ISO, *EUR, or *JIS must be specied.

Appendix E. Using the C for AS/400 and FORTRAN for AS/400 Precompilers

813

*JOB: The format specied for the job is used. Use the Display Job (DSPJOB) command to determine the current date format for the job. *USA: The United States date format (mm/dd/yyyy) is used. *ISO: The International Organization for Standardization (ISO) date format (yyyy-mm-dd) is used. *EUR: The European date format (dd.mm.yyyy) is used. *JIS: The Japanese Industrial Standard date format (yyyy-mm-dd) is used. *MDY: The date format (mm/dd/yy) is used. *DMY: The date format (dd/mm/yy) is used. *YMD: The date format (yy/mm/dd) is used. *JUL: The Julian date format (yy/ddd) is used. DATSEP Species the separator used when accessing date result columns. Note: This parameter applies only when *JOB, *MDY, *DMY, *YMD, or *JUL is specied on the DATFMT parameter. *JOB: The date separator specied for the job at precompile time is used. Use the Display Job (DSPJOB) command to determine the current value for the job. /: A slash (/) is used. .: A period (.) is used. ,: A comma (,) is used. -: A dash (-) is used. : A blank ( ) is used. *BLANK: A blank ( ) is used. TIMFMT Species the format used when accessing time result columns. For input time strings, the specied value is used to determine whether the time is specied in a valid format. Note: An input date string that uses the format *USA, *ISO, *EUR, or *JIS is always valid. If a relational database is specied on the RDB parameter and the database is on a system that is not another AS/400 system, the time format must be *USA, *ISO, *EUR, *JIS, or *HMS with a time separator of a colon or period. *HMS: The hh:mm:ss format is used.

814

DB2 UDB for AS/400 SQL Programming V4R4

*USA: The United States time format hh:mm xx is used, where xx is AM or PM. *ISO: The International Organization for Standardization (ISO) time format hh.mm.ss is used. *EUR: The European time format hh.mm.ss is used. *JIS: The Japanese Industrial Standard time format hh:mm:ss is used. TIMSEP Species the separator used when accessing time result columns. Note: This parameter applies only when *HMS is specied on the TIMFMT parameter. *JOB: The time separator specied for the job at precompile time is used. Use the Display Job (DSPJOB) command to determine the current value for the job. :: A colon (:) is used. .: A period (.) is used. ,: A comma (,) is used. : A blank ( ) is used. *BLANK: A blank ( ) is used. REPLACE Species whether a new program or SQL package is created when a program or SQL package of the same name exists in the same library. The value of this parameter is passed to the C command.More information on this parameter is in Appendix A, Expanded Parameter Descriptions in the CL Reference (Abridged) book. *YES: A new program or SQL package is created, and any existing program or SQL package of the same name and type in the specied library is moved to QRPLOBJ. *NO: A new program or SQL package is not created if an object of the same name and type already exists in the specied library. RDB Species the name of the relational database where the SQL package object is created. *NONE: An SQL package object is not created. The program object is not a distributed program and the Create Structured Query Language Package (CRTSQLPKG) command cannot be used.

relational-database-name: Specify the name of the relational database where the new SQL package object is to be created. When the name of the local relational database is specied, the program created is still a distributed SQL program. The SQL statements will access the local database.

Appendix E. Using the C for AS/400 and FORTRAN for AS/400 Precompilers

815

USER Species the user name sent to the remote system when starting the conversation. This parameter is valid only when RDB is specied. *CURRENT: The user prole under which the current job is running is used.

user-name: Specify the user name to be used for the application server job.
PASSWORD Species the password to be used on the remote system. This parameter is valid only if RDB is specied. *NONE: No password is sent. If this value is specied, USER(*CURRENT) must also be specied.

password: Specify the password of the user name specied on the USER parameter.
RDBCNNMTH Species the semantics used for CONNECT statements. Refer to the SQL Reference, SC41-3612 book for more information. *DUW: CONNECT (Type 2) semantics are used to support distributed unit of work. Consecutive CONNECT statements to additional relational databases do not result in disconnection of previous connections. *RUW: CONNECT (Type 1) semantics are used to support remote unit of work. Consecutive CONNECT statements result in the previous connection being disconnected before a new connection is established. DFTRDBCOL Species the collection name used for the unqualied names of tables, views, indexes, and SQL packages. This parameter applies only to static SQL statements. *NONE: The naming convention dened on the OPTION parameter is used.

collection-name: Specify the name of the collection identier. This value is used instead of the naming convention specied on the OPTION parameter.
SQLPKG Species the qualied name of the SQL package created on the relational database specied on the RDB parameter of this command. The possible library values are: *PGMLIB: The package is created in the library with the same name as the library containing the program.

library-name: Specify the name of the library where the package is created.
*PGM: The name of the SQL package is the same as the program name.

package-name: Specify the name of the SQL package. If the remote system is not an AS/400 system, no more than 8 characters can be specied.
SAAFLAG Species the IBM SQL agging function. This parameter ags SQL statements

816

DB2 UDB for AS/400 SQL Programming V4R4

to verify whether they conform to IBM SQL syntax More information about which IBM database products IBM SQL syntax is in the DRDA IBM SQL Reference, SC26-3255-00. *NOFLAG: The precompiler does not check to see whether SQL statements conform to IBM SQL standards. *FLAG: The precompiler checks to see whether SQL statements conform to IBM SQL standards. FLAGSTD Species the American National Standards Institute (ANSI) agging function. This parameter ags SQL statements to verify whether they conform to the following standards.
ANSI X3.135-1992 entry ISO 9075-1992 entry FIPS 127.2 entry

*NONE: The precompiler does not check to see whether SQL statements conform to ANSI standards. *ANS: The precompiler checks to see whether SQL statements conform to ANSI standards. PRTFILE Species the qualied name of the printer device le to which the listing is directed. The le must have a minimum record length of 132 bytes or information is lost. The name of the printer le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library to be searched. QSYSPRT: If a le name is not specied, the precompiler printout is directed to the IBM-supplied printer le QSYSPRT.

printer-le-name: Specify the name of the printer device le to which the precompiler printout is directed.
SRTSEQ Species the sort sequence table to be used for string comparisons in SQL statements. Note: *HEX must be specied for this parameter on distributed applications where the application server is not on an AS/400 system or the release level is prior to V2R3M0. *JOB: The SRTSEQ value for hte job is retrieved during the precompile. *JOBRUN: The SRTSEQ value for the job is retrieved when the program is run. For distributed applications, SRTSEQ(*JOBRUN) is valid only when LANGID(*JOBRUN) is also specied.

Appendix E. Using the C for AS/400 and FORTRAN for AS/400 Precompilers

817

*LANGIDUNQ: The unique-weight sort table for the language specied on the LANGID parameter is used. *LANGIDSHR: The shared-weight sort table for the language specied on the LANGID parameter is used. *HEX: A sort sequence table is not used. The hexadecimal values of the characters are used to determine the sort sequence. The name of the sort sequence table can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used.

library-name: Specify the name of the library to be searched. table-name: Specify the name of the sort sequence table to be used.
LANGID Species the language identier to be used when SRTSEQ(*LANGIDUNQ) or SRTSEQ(*LANGIDSHR) is specied. *JOB: The LANGID value for the job is received during the precompile. *JOBRUN: The LANGID value for the job is retrieved when the program is run. For distributed applications, LANGID(*JOBRUN) is valid only when SRTSEQ(*JOBRUN) is also specied.

language-id: Specify a language identier to be used by the program.


DYNUSRPRF Species the user prole used for dynamic SQL statements. *USER: Local dynamic SQL statements are run under the user prole of the job. Distributed dynamic SQL statements are run under the user prole of the application server job. *OWNER: Local dynamic SQL statements are run under the user prole of the programs owner. Distributed dynamic SQL statements are run under the user prole of the SQL packages owner. | | | | | | | | | | | | TOSRCFILE Species the qualied name of the source le that is to contain the output source member that has been processed by the SQL precompiler. If the specied source le is not found, it will be created. The output member will have the same name as the name that is specied for the SRCMBR parameter. The possible library values are: QTEMP: The library QTEMP will be used. *LIBL: The jobs library list is searched for the specied le. If the le is not found in any library in the library list, the le will be created in the current library. *CURLIB: The current library for the job will be used. If no library is specied as the current library for the job, the QGPL library will be used.

818

DB2 UDB for AS/400 SQL Programming V4R4

| | | | |

library-name: Specify the name of the library that is to contain the output source le.
QSQLTEMP: The source le QSQLTEMP will be used.

source-le-name: Specify the name of the source le to contain the output source member.
TEXT Species the text that briey describes the function. More information on this parameter is in Appendix A, Expanded Parameter Descriptions in the CL Reference book. *SRCMBRTXT: The text is taken from the source le member being used to create the FORTRAN program. Text can be added or changed for a database source member by using the Start Source Entry Utility (STRSEU) command, or by using either the Add Physical File Member (ADDPFM) or Change Physical File Member (CHGPFM) command. If the source le is an inline le or a device le, the text is blank. *BLANK: Text is not specied.

description: Specify no more than 50 characters of text, enclosed in apostrophes.

Example
CRTSQLC PAYROLL TEXT('Payroll Program')

This command runs the SQL precompiler which precompiles the source and stores the changed source in member PAYROLL in le QSQLTEMP in library QTEMP.

Using the FORTRAN/400 Precompiler


FORTRAN/400 is no longer a supported compiler for the AS/400 system. This appendix is intended to help those customers who are using the SQL FORTRAN precompiler with other non-IBM FORTRAN compilers. For a description of using the FORTRAN precompiler, see Appendix F. Coding SQL Statements in FORTRAN Applications.

CRTSQLFTN (Create Structured Query Language FORTRAN) Command


Job: B,I Pgm: B,I
PGM( library-name/

REXX: B,I
*CURLIB/

Exec
program-name )

CRTSQLFTN

*LIBL/ SRCFILE( *CURLIB/ library-name/

QFTNSRC source-file-name

Appendix E. Using the C for AS/400 and FORTRAN for AS/400 Precompilers

819

(1) *PGM source-file-member-name

SRCMBR(

OPTION(

OPTION Details

) TGTRLS(

*CURRENT *PRV VxRxMx

*LIBL/ INCFILE( *CURLIB/ library-name/

*SRCFILE source-file-name

COMMIT(

*UR *CHG *ALL *RS *CS *NONE *NC *RR

CLOSQLCSR( )

*ENDPGM *ENDSQL *ENDJOB

ALWCPYDTA(

*YES *OPTIMIZE *NO

ALWBLK(

*READ *NONE *ALLREAD

DLYPRP(

*NO *YES

GENLVL(

10 severity-level

DATFMT(

*JOB *USA *ISO *EUR *JIS *MDY *DMY *YMD *JUL

DATSEP(

*JOB '/' '.' ',' '-' ' ' *BLANK

820

DB2 UDB for AS/400 SQL Programming V4R4

TIMFMT(

*HMS *USA *ISO *EUR *JIS

TIMSEP(

*JOB ':' '.' ',' ' ' *BLANK

REPLACE(

*YES *NO

RDB(

*LOCAL relational-database-name *NONE

USER(

*CURRENT user-name

PASSWORD(

*NONE password

RDBCNNMTH(

*DUW *RUW

DFTRDBCOL(

*NONE collection-name

*PGMLIB/ SQLPKG( library-name/

*PGM package-name

SAAFLAG(

*NOFLAG *FLAG

FLAGSTD(

*NONE *ANS

*LIBL/ PRTFILE( *CURLIB/ library-name/

QSYSPRT printer-file-name

Appendix E. Using the C for AS/400 and FORTRAN for AS/400 Precompilers

821

SRTSEQ(

*JOB *JOBRUN *LANGIDUNQ *LANGIDSHR *HEX *LIBL/ table-name *CURLIB/ library-name/

LANGID(

*JOB *JOBRUN language-ID

USRPRF(

*NAMING *OWNER *USER

DYNUSRPRF(

*USER *OWNER

QTEMP/ TOSRCFILE( *LIBL/ *CURLIB/ library-name/

QSQLTEMP source-file-name

TEXT(

*SRCMBRTXT *BLANK 'description'

OPTION Details:
*NOSRC *NOSOURCE *SOURCE *SRC *NOXREF *XREF *GEN *NOGEN *PERIOD *JOB *SYSVAL *COMMA *SYS *SQL

*NOSECLVL *SECLVL

*NODEBUG *DEBUG

Notes: 1. All parameters preceding this point can be specied in positional form.

Purpose
The Create Structured Query Language FORTRAN (CRTSQLFTN) command calls the Structured Query Language (SQL) precompiler which precompiles FORTRAN

822

DB2 UDB for AS/400 SQL Programming V4R4

source containing SQL statements, produces a temporary source member, and then optionally calls the FORTRAN compiler to compile the program.

Parameters
PGM Species the qualied name of the compiled program. The name of the compiled FORTRAN program can be qualied by one of the following library values: *CURLIB: The compiled FORTRAN program is created in the current library for the job. If no library is specied as the current library for the job, the QGPL library is used.

library-name: Specify the name of hte library where the compiled FORTRAN program is created. program-name: Specify the name of the compiled FORTRAN program.
SRCFILE Species the qualied name of the source le that contains the FORTRAN source with SQL statements. The name of the source le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library to be searched. QFTNSRC: If the source le name is not specied, the IBM-supplied source le QFTNSRC contains the FORTRAN source.

source-le-name: Specify the name of the source le that contains the FORTRAN source.
SRCMBR Species the name of the source le member that contains the C source. This parameter is specied only if the source le name in the SRCFILE parameter is a database le. If this parameter is not specied, the PGM name specied on the PGM parameter is used. *PGM: Species that the FORTRAN source is in the member of the source le that has the same name as that specied on the PGM parameter.

source-le-member-name: Specify the name of the member that contains the FORTRAN source.
OPTION Species whether one or more of the following options are used when the FORTRAN source is precompiled. If an option is specied more than once, or if two options conict, the last option specied is used. Element 1: Source Listing Options

Appendix E. Using the C for AS/400 and FORTRAN for AS/400 Precompilers

823

*NOSOURCE: or *NOSRC: A source printout is not produced by the precompiler unless errors are detected during precompile or create package. *SOURCE or *SRC: The precompiler produces a source printout consisting of FORTRAN source input. Element 2: Cross-Reference Options *NOXREF: The precompiler does not cross-reference names. *XREF:The precompiler cross-references items in the program to the statement numbers in the program that refer to those items. Element 3: Program Creation Options *GEN: *NOGEN: The precompiler does not call the FORTRAN compiler, and a program and SQL package are not created. Element 4: Decimal Point Options *PERIOD: The value used as the decimal point for numeric constants used in SQL statements is a period. *JOB The value used as the decimal point for numeric constants in SQL is the representation of decimal point specied for the job at precompile time. *SYSVAL: The value used as the decimal point for numeric constants in SQL statements is the QDECFMT system value. Note: If QDECFMT species that the value used as the decimal point is a comma, any numeric constants in lists (such as in the SELECT clause or the VALUES clause) must be separated by a comma followed by a blank. For example, VALUES(1,1, 2,23, 4,1) is equivalent to VALUES(1.1,2.23,4.1) in which the decimal point is a period. *COMMA: The value used as the decimal point for numeric constants in SQL statements is a comma. Note: Any numeric constants in lists (such as in the SELECT clause or the VALUES clause) must be separated by a comma followed by a blank. For example, VALUES(1,1, 2,23, 4,1) is equivalent to VALUES(1.1,2.23,4.1) where the decimal point is a period. Element 5: Naming Convention Options *SYS:The system naming convention (library-name/le-name) is used. *SQL: The SQL naming convention is used (collection-name.table-name). When creating a program on a remote database other than an AS/400 system, *SQL must be specied as the naming convention. Element 6: Second-Level Message Text Option *NOSECLVL: Second-level text descriptions are not added to the listing.

824

DB2 UDB for AS/400 SQL Programming V4R4

*SECLVL: Second-level text with replacement data is added for all messages on the listing. Element 7: Debug Options *NODEBUG: Symbolic extended program model (EPM) debug information is not stored with the program. This option is passed to the compiler and does not affect the SQL precompiler. *DEBUG: Symbolic EPM debug information is stored with the program. This option is passed to the compiler and does not affect the SQL precompiler. TGTRLS Species the release of the operating system on which the user intends to use the object being created. In the examples given for the *CURRENT and *PRV values, and when specifying the release-level value, the format VxRxMx is used to specify the release, where Vx is the version, Rx is the release, and Mx is the modication level. For example, V2R3M0 is version 2, release 3, modication level 0. *CURRENT: The object is to be used on the release of the operating system currently running on the users system. For example, if V2R3M5 is running on the system, *CURRENT means the user intends to use the object on a system with V2R3M5 installed. The user can also use the object on a system with any subsequent release of the operating system installed. Note: If V2R3M5 is running on the system, and the object is to be used on a system with V2R3M0 installed, specify TGTRLS(V2R3M0) not TGTRLS(*CURRENT). *PRV: The object is to be used on the previous release with modication level 0 of the operating system. For example, if V2R3M5 is running on the users system, *PRV means the user intends to use the object on a system with V2R2M0 installed. The user can also use the object on a system with any subsequent release of the operating system installed.

release-level: Specify the release in the format VxRxMx. The object can be used on a system with the specied release or with any subsequent release of the operating system installed.
Valid values depend on the current version, release, and modication level, and they change with each new release. If you specify a release-level which is earlier than the earliest release level supported by this command, an error message is sent indicating the earliest supported release. INCFILE Species the qualied name of the source le that contains members included in the program with any SQL INCLUDE statement. The name of the source le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used.
Appendix E. Using the C for AS/400 and FORTRAN for AS/400 Precompilers

825

library-name: Specify the name of the library to be searched.


*SRCFILE: The qualied source le specied in the SRCFILE parameter contains the source le members specied on any SQL INCLUDE statement.

source-le-name: Specify the name of the source le that contains the source le members specied on any SQL INCLUDE statement. The record length of the source le the user species here must be no less than the record length of the source le specied on the SRCFILE parameter.
COMMIT Species whether SQL statements in the compiled program are run under commitment control. Files referred to in the host language source are not affected by this option. Only SQL tables, SQL views, and SQL packages referred to in SQL statements are affected. *CHG or *UR: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs can be seen. *ALL or *RS: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows selected, updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs cannot be seen. *CS: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows updated, deleted, and inserted are locked until the end of the unit of work (transaction). A row that is selected, but not updated, is locked until the next row is selected. Uncommitted changes in other jobs cannot be seen. *NONE or *NC: Species that commitment control is not used. Uncommitted changes in other jobs can be seen. If the SQL DROP COLLECTION statement is included in the program, *NONE or *NC must be used. If a relational database is specied on the RDB parameter and the relational database is on a system that is not on an AS/400, *NONE or *NC cannot be specied. *RR: Species the objects referred to in SQL ALTER, CALL, COMMENT ON, CREATE, DROP, GRANT, LABEL ON, RENAME, and REVOKE statements and the rows selected, updated, deleted, and inserted are locked until the end of the unit of work (transaction). Uncommitted changes in other jobs cannot be seen. All tables referred to in SELECT, UPDATE, DELETE, and INSERT statements are locked exclusively until the end of the unit of work (transaction). CLOSQLCSR Species when SQL cursors are implicitly closed, SQL prepared statements are implicitly discarded, and LOCK TABLE locks are released. SQL cursors are explicitly closed when you issue the CLOSE, COMMIT, or ROLLBACK (without HOLD) SQL statements. *ENDPGM: SQL cursors are closed and SQL prepared statements are discarded when the program ends. LOCK TABLE locks are released when the rst SQL program on the call stack ends.

826

DB2 UDB for AS/400 SQL Programming V4R4

*ENDSQL: SQL cursors remain open between calls and can be fetched without running another SQL OPEN. One of the programs higher on the call stack must have run at least one SQL statement. SQL cursors are closed, SQL prepared statements are discarded, and LOCK TABLE locks are released when the rst SQL program on the call stack ends. If *ENDSQL is specied for a program that is the rst SQL program called (the rst SQL program on the call stack), the program is treated as if *ENDPGM was specied. *ENDJOB: SQL cursors remain open between calls and can be fetched without running another SQL OPEN. The programs higher on the call stack do not need to have run SQL statements. SQL cursors are left open, SQL prepared statements are preserved, and LOCK TABLE locks are held when the rst SQL program on the call stack ends. SQL cursors are closed, SQL prepared statements are discarded, and LOCK TABLE locks are released when the job ends. ALWCPYDTA Species whether a copy of the data can be used in a SELECT statement. *OPTIMIZE: The system determines whether to use the data retrieved directly from the database or to use a copy of the data. The decision is based on which method provides the best performance. If COMMIT is *CHG or *CS and ALWBLK is not *ALLREAD, or if COMMIT is *ALL or *RR, then a copy of the data is used only when it is necessary to run a query. *YES: A copy of the data is used only when necessary. *NO: A copy of the data is not allowed. If a temporary copy of the data is required to perform the query, an error message is returned. ALWBLK Species whether the database manager can use record blocking, and the extent to which blocking can be used for read-only cursors. *ALLREAD: Rows are blocked for read-only cursors if *NONE or *CHG is specied on the COMMIT parameter. All cursors in a program that are not explicitly able to be updated are opened for read-only processing even though EXECUTE or EXECUTE IMMEDIATE statements may be in the program. Specifying *ALLREAD: v Allows record blocking under commitment control level *CHG in addition to the blocking allowed for *READ. v Can improve the performance of almost all read-only cursors in programs, but limits queries in the following ways: The Rollback (ROLLBACK) command, a ROLLBACK statement in host languages, or the ROLLBACK HOLD SQL statement does not reposition a read-only cursor when *ALLREAD is specied. Dynamic running of a positioned UPDATE or DELETE statement (for example, using EXECUTE IMMEDIATE), cannot be used to update a row in a cursor unless the DECLARE statement for the cursor includes the FOR UPDATE clause. *NONE: Rows are not blocked for retrieval of data for cursors. Specifying *NONE: v Guarantees that the data retrieved is current.
Appendix E. Using the C for AS/400 and FORTRAN for AS/400 Precompilers

827

v May reduce the amount of time required to retrieve the rst row of data for a query. v Stops the database manager from retrieving a block of data rows that is not used by the program when only the rst few rows of a query are retrieved before the query is closed. v Can degrade the overall performance of a query that retrieves a large number of rows. *READ: Records are blocked for read-only retrieval of data for cursors when: v *NONE is specied on the COMMIT parameter, which indicates that commitment control is not used. v The cursor is declared with a FOR FETCH ONLY clause or there are no dynamic statements that could run a positioned UPDATE or DELETE statement for the cursor. Specifying *READ can improve the overall performance of queries that meet the above conditions and retrieve a large number of records. DLYPRP Species whether the dynamic statement validation for a PREPARE statement is delayed until an OPEN, EXECUTE, or DESCRIBE statement is run. Delaying validation improves performance by eliminating redundant validation. *NO: Dynamic statement validation is not delayed. When the dynamic statement is prepared, the access plan is validated. When the dynamic statement is used in an OPEN or EXECUTE statement, the access plan is revalidated. Because the authority or the existence of objects referred to by the dynamic statement may change, you must still check the SQLCODE or SQLSTATE after issuing the OPEN or EXECUTE statement to ensure that the dynamic statement is still valid. *YES: Dynamic statement validation is delayed until the dynamic statement is used in an OPEN, EXECUTE, or DESCRIBE SQL statement. When the dynamic statement is used, the validation is completed and an access plan is built. If you specify *YES on this parameter, you should check the SQLCODE and SQLSTATE after running an OPEN, EXECUTE, or DESCRIBE statement to ensure that the dynamic statement is valid. Note: If you specify *YES, performance is not improved if the INTO clause is used on the PREPARE statement or if a DESCRIBE statement uses the dynamic statement before an OPEN is issued for the statement. GENLVL Species the severity level at which the create operation fails. If errors occur that have a severity level greater than or equal to this value, the operation ends. 10: The default severity level is 10.

severity-level: Specify a value ranging from 0 through 40.


DATFMT Species the format used when accessing date result columns. All output date elds are returned in the specied format. For input date strings, the specied value is used to determine whether the date is specied in a valid format.

828

DB2 UDB for AS/400 SQL Programming V4R4

Note: An input date string that uses the format *USA, *ISO, *EUR, or *JIS is always valid. If a relational database is specied on the RDB parameter and the database is on a system that is not an AS/400 system, then *USA, *ISO, *EUR, or *JIS must be specied. *JOB: The format specied for the job is used. Use the Display Job (DSPJOB) command to determine the current date format for the job. *USA: The United States date format (mm/dd/yyyy) is used. *ISO: The International Organization for Standardization (ISO) date format (yyyy-mm-dd) is used. *EUR: The European date format (dd.mm.yyyy) is used. *JIS: The Japanese Industrial Standard date format (yyyy-mm-dd) is used. *MDY: The date format (mm/dd/yy) is used. *DMY: The date format (dd/mm/yy) is used. *YMD: The date format (yy/mm/dd) is used. *JUL: The Julian date format (yy/ddd) is used. DATSEP Species the separator used when accessing date result columns. Note: This parameter applies only when *JOB, *MDY, *DMY, *YMD, or *JUL is specied on the DATFMT parameter. *JOB: The date separator specied for the job at precompile time is used. Use the Display Job (DSPJOB) command to determine the current value for the job. /: A slash (/) is used. .: A period (.) is used. ,: A comma (,) is used. -: A dash (-) is used. : A blank ( ) is used. *BLANK: A blank ( ) is used. TIMFMT Species the format used when accessing time result columns. For input time strings, the specied value is used to determine whether the time is specied in a valid format. Note: An input date string that uses the format *USA, *ISO, *EUR, or *JIS is always valid.

Appendix E. Using the C for AS/400 and FORTRAN for AS/400 Precompilers

829

If a relational database is specied on the RDB parameter and the database is on a system that is not another AS/400 system, the time format must be *USA, *ISO, *EUR, *JIS, or *HMS with a time separator of colon or period. *HMS: The (hh:mm:ss) format is used. *USA: The United States time format (hh:mm xx) is used, where xx is AM or PM. *ISO: The International Organization for Standardization (ISO) time format (hh.mm.ss) is used. *EUR: The European time format (hh.mm.ss) is used. *JIS: The Japanese Industrial Standard time format (hh:mm:ss) is used. TIMSEP Species the separator used when accessing time result columns. Note: This parameter applies only when *HMS is specied on the TIMFMT parameter. *JOB: The time separator specied for the job at precompile time is used. Use the Display Job (DSPJOB) command to determine the current value for the job. :: A colon (:) is used. .: A period (.) is used. ,: A comma (,) is used. : A blank ( ) is used. *BLANK: A blank ( ) is used. REPLACE Species whether a new program or SQL package is created when a program or SQL package of the same name exists in the same library. The value of this parameter is passed to the CRTFTNPGM command. More information on this parameter is in Appendix A, Expanded Parameter Descriptions in the CL Reference (Abridged) book. *YES: A new program or SQL package is created, and any existing program or SQL package of the same name and type in the specied library is moved to QRPLOBJ. *NO: A new program or SQL package is not created if an object of the same name and type already exists in the specied library. RDB Species the name of the relational database where the SQL package object is created. *LOCAL: The program is created as a distributed SQL program. The SQL statements will access the local database. An SQL package object is not

830

DB2 UDB for AS/400 SQL Programming V4R4

created as part of the precompile process. The Create Structured Query Language Package (CRTSQLPKG) command can be used.

relational-database-name: Specify the name of the relational database where the new SQL package object is to be created. When the name of the local relational database is specied, the program created is still a distributed SQL program. The SQL statements will access the local database.
*NONE: An SQL package object is not created. The program object is not a distributed program and the Create Structured Query Language Package (CRTSQLPKG) command cannot be used. USER Species the user name sent to the remote system when starting the conversation. This parameter is valid only when RDB is specied. *CURRENT: The user prole under which the current job is running is used.

user-name: Specify the user name being used for the application server job.
PASSWORD Species the password to be used on the remote system. This parameter is valid only if RDB is specied. *NONE: No password is sent. If this value is specied, USER(*CURRENT) must also be specied.

password: Specify the password of the user name specied on the USER parameter.
RDBCNNMTH Species the semantics used for CONNECT statements. Refer to the SQL Reference book for more information. *DUW: CONNECT (Type 2) semantics are used to support distributed unit of work. Consecutive CONNECT statements to additional relational databases do not result in disconnection of previous connections. *RUW: CONNECT (Type 1) semantics are used to support remote unit of work. Consecutive CONNECT statements result in the previous connection being disconnected before a new connection is established. DFTRDBCOL Species the collection name used for the unqualied names of tables, views, indexes, and SQL packages. This parameter applies only to static SQL statements. *NONE: The naming convention dened on the OPTION parameter is used.

collection-name: Specify the name of the collection identier. This value is used instead of the naming convention specied on the OPTION parameter.
SQLPKG Species the qualied name of the SQL package created on the relational database specied on the RDB parameter of this command. The possible library values are:

Appendix E. Using the C for AS/400 and FORTRAN for AS/400 Precompilers

831

*PGMLIB: The package is created in the library with the same name as the library containing the program. library-name: Specify the name of the library where the package is created. *PGM: The package name is the same as the program name.

package-name: Specify the name of the package created on the remote database specied on the RDB parameter.
SAAFLAG Species the IBM SQL agging function. This parameter ags SQL statements to verify whether they conform to IBM SQL syntax More information about which IBM database products IBM SQL syntax is in the DRDA IBM SQL Reference, SC26-3255-00. *NOFLAG: The precompiler does not check to see whether SQL statements conform to IBM SQL syntax. *FLAG: The precompiler checks to see whether SQL statements conform to IBM SQL syntax. FLAGSTD Species the American National Standards Institute (ANSI) agging function. This parameter ags SQL statements to verify whether they conform to the following standards.
ANSI X3.135-1992 entry ISO 9075-1992 entry FIPS 127.2 entry

*NONE: The precompiler does not check to see whether SQL statements conform to ANSI standards. *ANS: The precompiler checks to see whether SQL statements conform to ANSI standards. PRTFILE Species the qualied name of the printer device le to which the listing is directed. The le must have a minimum record length of 132 bytes or information is lost. The name of the printer le can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library to be searched. QSYSPRT: If a le name is not specied, the precompiler printout is directed to the IBM-supplied printer le QSYSPRT.

printer-le-name: Specify the name of the printer device le to which the precompiler printout is directed.
SRTSEQ Species the sort sequence table to be used for string comparisons in SQL statements.

832

DB2 UDB for AS/400 SQL Programming V4R4

Note: *HEX must be specied for this parameter on distributed applications where the application server is not on an AS/400 system or the release level is prior to V2R3M0. Species the sort sequence table to be used for string comparisons in SQL statements. Note: *HEX must be specied for this parameter on distributed applications where the application server is not on an AS/400 system or the release level is prior to V2R3M0. *JOB: The SRTSEQ value for the job is retrieved during the precompile. *JOBRUN: The SRTSEQ value for the job is retrieved when the program is run. For distributed applications, SRTSEQ(*JOBRUN) is valid only when LANGID(*JOBRUN) is also specied. *LANGIDUNQ: The unique-weight sort table for the language specied on the LANGID parameter is used. *LANGIDSHR: The shared-weight sort table for the language specied on the LANGID parameter is used. *HEX: A sort sequence table is not used. The hexadecimal values of the characters are used to determine the sort sequence. The name of the sort sequence table can be qualied by one of the following library values: *LIBL: All libraries in the jobs library list are searched until the rst match is found. *CURLIB: The current library for the job is searched. If no library is specied as the current library for the job, the QGPL library is used. library-name: Specify the name of the library to be searched.

table-name: Specify the name of the sort sequence table to be used.


LANGID Species the language identier to be used when SRTSEQ(*LANGIDUNQ) or SRTSEQ(*LANGIDSHR) is specied. *JOB: The LANGID value for the job is retrieved during the precompile. *JOBRUN: The LANGID value for the job is retrieved when the program is run. For distributed applications, LANGID(*JOBRUN) is valid only when SRTSEQ(*JOBRUN) is also specied.

language-id: Specify a language identier to be used by the program.


USRPRF Species the user prole that is used when the compiled program object is run, including the authority that the program object has for each object in static SQL statements. The prole of either the program owner or the program user is used to control which objects can be used by the program object.

Appendix E. Using the C for AS/400 and FORTRAN for AS/400 Precompilers

833

*NAMING: The user prole is determined by the naming convention. If the naming convention is *SQL, USRPRF(*OWNER) is used. If the naming convention is *SYS, USRPRF(*USER) is used. *USER: The prole of the user running the program object is used. *OWNER: The user proles of both the program owner and the program user are used when the program is run. DYNUSRPRF Species the user prole used for dynamic SQL statements. *USER: Local dynamic SQL statements are run under the user prole of the job. Distributed dynamic SQL statements are run under the user prole of the application server job. *OWNER: Local dynamic SQL statements are run under the user prole of the programs owner. Distributed dynamic SQL statements are run under the user prole of the SQL packages owner. | | | | | | | | | | | | | | | | | TOSRCFILE Species the qualied name of the source le that is to contain the output source member that has been processed by the SQL precompiler. If the specied source le is not found, it will be created. The output member will have the same name as the name that is specied for the SRCMBR parameter. The possible library values are: QTEMP: The library QTEMP will be used. *LIBL: The jobs library list is searched for the specied le. If the le is not found in any library in the library list, the le will be created in the current library. *CURLIB: The current library for the job will be used. If no library is specied as the current library for the job, the QGPL library will be used. library-name: Specify the name of the library that is to contain the output source le. QSQLTEMP: The source le QSQLTEMP will be used.

source-le-name: Specify the name of the source le to contain the output source member.
TEXT Species the text that briey describes the LANGID. More information on this parameter is in Appendix A, Expanded Parameter Descriptions in the CL Reference (Abridged) book. *SRCMBRTXT: The text is taken from the source le member being used to create the FORTRAN program. Text can be added or changed for a database source member by using the Start Source Entry Utility (STRSEU) command, or by using either the Add Physical File Member (ADDPFM) or Change Physical File Member (CHGPFM) command. If the source le is an inline le or a device le, the text is blank. *BLANK: Text is not specied.

834

DB2 UDB for AS/400 SQL Programming V4R4

description: Specify no more than 50 characters of text, enclosed in apostrophes.

Example
CRTSQLFTN PAYROLL TEXT('Payroll Program')

This command runs the SQL precompiler, which precompiles the source and stores the changed source in member PAYROLL in le QSQLTEMP in library QTEMP. The FORTRAN compiler is called to create program PAYROLL in the current library by using the source member created by the SQL precompiler.

Appendix E. Using the C for AS/400 and FORTRAN for AS/400 Precompilers

835

836

DB2 UDB for AS/400 SQL Programming V4R4

Appendix F. Coding SQL Statements in FORTRAN Applications


This appendix describes the unique application and coding requirements for embedding SQL statements in a FORTRAN/400 program. Requirements for host variables are dened.

Dening the SQL Communications Area


A FORTRAN program that contains SQL statements must include one or both of the following: v An SQLCOD variable declared as INTEGER v An SQLSTA (or SQLSTATE) variable declared as CHARACTER*5 Or, v An SQLCA (which contains an SQLCOD and SQLSTA variable). The SQLCOD and SQLSTA (or SQLSTATE) values are set by the database manager after each SQL statement is executed. An application can check the SQLCOD or SQLSTA (or SQLSTATE) value to determine whether the last SQL statement was successful. The SQLCA can be coded in a FORTRAN program either directly or by using the SQL INCLUDE statement. Using the SQL INCLUDE statement requests the inclusion of a standard declaration:
EXEC SQL INCLUDE SQLCA

The included FORTRAN source statements for the SQLCA are:


* * * The SQL communications area CHARACTER SQLCA(136) CHARACTER SQLCAID*8 INTEGER*4 SQLCABC INTEGER*4 SQLCODE INTEGER*2 SQLERRML CHARACTER SQLERRMC*70 CHARACTER SQLERRP*8 INTEGER*4 SQLERRD(6) CHARACTER SQLWARN*11 CHARACTER SQLSTATE*5 EQUIVALENCE (SQLCA( 1), EQUIVALENCE (SQLCA( 9), EQUIVALENCE (SQLCA( 13), EQUIVALENCE (SQLCA( 17), EQUIVALENCE (SQLCA( 19), EQUIVALENCE (SQLCA( 89), EQUIVALENCE (SQLCA( 97), EQUIVALENCE (SQLCA(121), EQUIVALENCE (SQLCA(132), INTEGER*4 SQLCOD SQLERR(6) INTEGER*2 SQLTXL CHARACTER SQLERP*8, C SQLWRN(0:7)*1, C SQLWRX(1:3)*1, C

SQLCAID) SQLCABC) SQLCODE) SQLERRML) SQLERRMC) SQLERRP) SQLERRD) SQLWARN) SQLSTATE)

Copyright IBM Corp. 1997, 1999

837

C C C C C C

SQLTXT*70, SQLSTT*5, SQLWRNWK*8, SQLWRXWK*3, SQLERRWK*24, SQLERRDWK*24 EQUIVALENCE (SQLWRN(1), SQLWRNWK) EQUIVALENCE (SQLWRX(1), SQLWRXWK) EQUIVALENCE (SQLCA(97), SQLERRDWK) EQUIVALENCE (SQLERR(1), SQLERRWK) COMMON /SQLCA1/SQLCOD,SQLERR,SQLTXTL COMMON /SQLCA2/SQLERP,SQLWRN,SQLTXT,SQLWRX,SQLSTT

SQLSTATE is replaced with SQLSTOTE when a declare for SQLSTATE is found in the program and the SQLCA is provided by the compiler. If compatibility with other IBM SQL implementations is not a primary consideration, it is recommended that the SQLCA be included by coding the FORTRAN variable SQLCOD, SQLSTA, or SQLSTATE in the program. This improves performance, but does not generate a compatible SQLCA. For more information on SQLCA, see Appendix B, SQL Communication Area in the DB2 UDB for AS/400 SQL Reference book. The SQLCOD, SQLSTA, SQLSTATE, and SQLCA variables must be placed before the rst executable SQL statement. All executable SQL statements in a program must be within the scope of the declaration of the SQLCOD, SQLSTA, SQLSTATE, and SQLCA variables. All SQL statements that can be run in a program must be within the scope of the declaration of the SQLCOD variable or SQLCA variables.

Dening SQL Descriptor Areas


The following statements require an SQLDA: EXECUTE...USING DESCRIPTOR descriptor-name FETCH...USING DESCRIPTOR descriptor-name OPEN...USING DESCRIPTOR descriptor-name CALL...USING DESCRIPTOR descriptor-name DESCRIBE statement-name INTO descriptor-name DESCRIBE TABLE host-variable INTO descriptor-name PREPARE statement-name INTO descriptor-name Unlike the SQLCA, there can be more than one SQLDA in a program, and an SQLDA can have any valid name. Dynamic SQL is an advanced programming technique described in Chapter 10. Dynamic SQL Applications. With dynamic SQL, your program can develop and then run SQL statements while the program is running. A SELECT statement with a variable SELECT list (that is, a list of the data to be returned as part of the query) that runs dynamically requires an SQL descriptor area (SQLDA). This is because you cannot know in advance how many or what type of variables to allocate in order to receive the results of the SELECT. Because the SQLDA uses pointer variables, which are not supported by FORTRAN, an INCLUDE SQLDA statement

838

DB2 UDB for AS/400 SQL Programming V4R4

cannot be specied in a FORTRAN program. Unless an SQLDA is set up by a C, COBOL, PL/I, or ILE RPG program and passed to the FORTRAN program, you cannot use the SQLDA. Coding an SQLDA on the multiple-row FETCH statement using a row storage area provides a technique to retrieve multiple rows on each FETCH statement. This technique can improve an applications performance if a large number of rows are read by the application. For more information on using the FETCH statement, see the DB2 UDB for AS/400 SQL Reference book.

Embedding SQL Statements


SQL statements can be coded in a FORTRAN program wherever a statement that can be run appears. If the SQL statement is within an IF statement, any necessary THEN and END IF statements will be generated. Each SQL statement in a FORTRAN program must begin with EXEC SQL. The EXEC SQL keywords must appear all on one line, but the remainder of the statement can appear on the same line and on subsequent lines.

Example:
An UPDATE statement coded in a FORTRAN program might be coded as follows:
C C C EXEC SQL UPDATE DEPARTMENT SET MGRNO = :MGRNUM WHERE DEPTNO = :INTDEPT

An SQL statement cannot be followed on the same line by another SQL statement or by a FORTRAN statement. FORTRAN does not require the use of blanks to delimit words within a statement, but the SQL language does. The rules for embedded SQL follow the rules for SQL syntax, which requires the use of one or more blanks as delimiters.

Comments
In addition to SQL comments (--), FORTRAN comments can be included within the embedded SQL statements wherever a blank is allowed, except between the keywords EXEC and SQL. The comment extends to the end of the line. Comment lines can appear between the lines of a continued SQL statement. The character (!) indicates a comment, except when it appears in a character context or in column 6.

Debug Lines
Lines contain debug statements (D or d in column 1) are treated as comments lines by the precompiler.

Continuation for SQL statements


The line continuation rules for SQL statements are the same as those for other FORTRAN statements, except that EXEC SQL must be specied within one line.

Appendix F. Coding SQL Statements in FORTRAN Applications

839

Constants containing DBCS data can be continued across multiple lines by placing the shift-in character in column 73 of the continued line and placing the shift-out character in column 6 of the continuation line. This SQL statement has a valid graphic constant of G<AABBCCDDEEFFGGHHIIJJKK>.
*...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8 EXEC SQL SELECT * FROM GRAPHTAB WHERE GRAPHCOL = G'<AABBCC> <DDEEFFGGHHIIJJKK>'

Including Code
SQL statements or FORTRAN statements can be included by embedding the following SQL statement at the point in the source code where the statements are to be embedded:
EXEC SQL INCLUDE member-name

The FORTRAN INCLUDE compiler directive cannot be used to include SQL statements or FORTRAN host variable declarations that are to be used in an SQL statement.

Margins
Code the SQL statements (starting with EXEC SQL) in coding columns 7 to 72.

Names
Any valid FORTRAN variable name can be used for a host variable and is subject to the following restrictions: Do not use host variable names or external entry names that begin with 'SQ', 'SQL', 'RDI', or 'DSN'. These names are reserved for the database manager. Do not use the following keywords to identify host variables: FUNCTION IMPLICIT PROGRAM SUBROUTINE

Statement Labels
Executable SQL statements can have statement numbers associated with them, specied in columns 1 to 5. However, during program preparation, a labelled SQL statement causes a CONTINUE statement with that label to be generated before the code runs the statement. A labelled SQL statement should not be the last statement in a DO loop. Because CONTINUE statements can be run, SQL statements that occur before the rst statement that can be run in a FORTRAN program (for example, INCLUDE and BEGIN DECLARE SECTION) should not be labelled.

840

DB2 UDB for AS/400 SQL Programming V4R4

WHENEVER Statement
The target for the GOTO clause in the SQL WHENEVER statement must be a label in the FORTRAN source and must reference a statement in the same subprogram. A WHENEVER statement only applies to SQL statements in the same subprogram.

FORTRAN Compile-Time Options


The FORTRAN PROCESS statement can be used to specify the compile-time options for the FORTRAN compiler. Although the PROCESS statement will be recognized by the FORTRAN compiler when it is called by the precompiler to create the program, the SQL precompiler itself does not recognize the PROCESS statement.

Using Host Variables


All host variables used in SQL statements must be explicitly declared. Implicit declarations of host variables via default typing or by the IMPLICIT statement are not supported. A host variable used in an SQL statement must be declared prior to the rst use of the host variable in an SQL statement. The FORTRAN statements that are used to dene the host variables should be preceded by a BEGIN DECLARE SECTION statement and followed by an END DECLARE SECTION statement. If a BEGIN DECLARE SECTION and END DECLARE SECTION are specied, all host variable declarations used in SQL statements must be between the BEGIN DECLARE SECTION and the END DECLARE SECTION statements. Note: LOB host variables are not supported in FORTRAN. All host variables within an SQL statement must be preceded with a colon (:). The names of host variables should be unique within the program, even if the host variables are in different blocks or procedures. The declaration for a character host variable must not use an expression to dene the length of the character variable. The declaration for a character host variable must not have an undened length (for example, CHARACTER(*)). An SQL statement that uses a host variable must be within the scope of the statement in which the variable was declared. Host variables must be scalar variables; they cannot be elements of arrays (subscripted variables).

Declaring Host Variables


The FORTRAN precompiler only recognizes a subset of valid FORTRAN declarations as valid host variable declarations.

Numeric Host Variables


The following gure shows the syntax for valid numeric host variable declarations.

Appendix F. Coding SQL Statements in FORTRAN Applications

841

Numeric
INTEGER*2 INTEGER *4 REAL *4 REAL*8 DOUBLE PRECISION

, variable-name / numeric-constant /

Character Host Variables


The following gure shows the syntax for valid character host variable declarations.

Character
CHARACTER *n

, variable-name *n / character-constant /

Note: n must be a constant no greater than 32766.

Determining Equivalent SQL and FORTRAN Data Types


The precompiler determines the base SQLTYPE and SQLLEN of host variables based on the following table. If a host variable appears with an indicator variable, the SQLTYPE is the base SQLTYPE plus one.
Table 78. FORTRAN Declarations Mapped to Typical SQL Data Types
FORTRAN Data Type INTEGER*2 INTEGER*4 REAL*4 SQLTYPE of Host Variable 500 496 480 SQLLEN of Host SQL Data Type Variable 2 4 4 SMALLINT INTEGER FLOAT (single precision)

842

DB2 UDB for AS/400 SQL Programming V4R4

Table 78. FORTRAN Declarations Mapped to Typical SQL Data Types (continued)
FORTRAN Data Type REAL*8 CHARACTER*n SQLTYPE of Host Variable 480 452 SQLLEN of Host SQL Data Type Variable 8 n FLOAT (double precision) CHAR(n)

The following table can be used to determine the FORTRAN data type that is equivalent to a given SQL data type.
Table 79. SQL Data Types Mapped to Typical FORTRAN Declarations
SQL Data Type SMALLINT INTEGER DECIMAL(p,s) or NUMERIC(p,s) FLOAT (single precision) FLOAT (double precision) CHAR(n) VARCHAR(n) FORTRAN Equivalent INTEGER*2 INTEGER*4 No exact equivalent REAL*4 REAL*8 CHARACTER*n No exact equivalent Use REAL*8 Explanatory Notes

n is a positive integer from 1 to 32766.


Use a character host variable large enough to contain the largest expected VARCHAR value. Not supported Not supported If the format is *USA, *JIS, *EUR, or *ISO, n must be at least 10 characters. If the format is *YMD, *DMY, or *MDY, n must be at least 8 characters. If the format is *JUL, n must be at least 6 characters.

GRAPHIC(n) VARGRAPHIC(n) DATE

Not supported Not supported CHARACTER*n

TIME

CHARACTER*n

n must be at least 6; to include seconds, n must be at least 8.


n must be at least 19. To include microseconds at full precision, n must be 26. If n is less than 26, truncation occurs on the microseconds part.

TIMESTAMP

CHARACTER*n

Notes on FORTRAN Variable Declaration and Usage


In FORTRAN, a string of digits with a decimal point is interpreted as a real constant. In an SQL statement, such a string is interpreted as a decimal constant. Therefore, use exponent notation when specifying a real (oating-point) constant in an SQL statement.

Appendix F. Coding SQL Statements in FORTRAN Applications

843

In FORTRAN, a real (oating-point) constant having a length of eight bytes uses a D as the exponent indicator (for example, 3.14159D+04). An 8-byte oating-point constant in an SQL statement must use an E (for example, 3.14159E+04).

Using Indicator Variables


An indicator variable is a two-byte integer (INTEGER*2). On retrieval, an indicator variable is used to show if its associated host variable has been assigned a null value. On assignment to a column, a negative indicator variable is used to indicate that a null value should be assigned. See DB2 UDB for AS/400 SQL Reference book for more information on the use of indicator variables. Indicator variables are declared in the same way as host variables. The declarations of the two can be mixed in any way that seems appropriate to the programmer.

Example:
Given the statement:
EXEC SQL FETCH CLS_CURSOR INTO :CLS_CD, C :DAY :DAY_IND, C :BGN :BGN_IND, C :ENDCLS :ENDCLS_IND

The variables can be declared as follows:


EXEC SQL BEGIN DECLARE SECTION CHARACTER*7 CLS_CD INTEGER*2 DAY CHARACTER*8 BGN, ENDCLS INTEGER*2 DAY_IND, BGN_IND, ENDCLS_IND EXEC SQL END DECLARE SECTION

844

DB2 UDB for AS/400 SQL Programming V4R4

Bibliography
This guide lists publications that provide additional information about topics described or referred to in this guide. The manuals in this section are listed with their full title and order number, but when referred to in text, a shortened version of the title is used. v Backup and Recovery, SC41-5304-03 This guide contains a subset of the information found in the Backup and Recovery book The manual contains information about planning a backup and recovery strategy, the different types of media available to save and restore procedures, and disk recovery procedures. It also describes how to install the system again from backup. v Data Management This guide provides information about using les in application programs. v DB2 UDB for AS/400 Database Programming This guide provides a detailed description of the DB2 UDB for AS/400 database organization, including information on how to create, describe, and update database les on the system. v CL Programming, SC41-5721-02 This guide provides a wide-ranging discussion of the AS/400 programming topics, including a general discussion of objects and libraries, CL programming, controlling ow and communicating between programs, working with objects in CL programs, and creating CL programs. Other topics include predened and impromptu messages and handling, dening and creating user-dened commands and menus, application testing, including debug mode, breakpoints, traces, and display functions. v CL Reference (Abridged), SC41-5722-03 This guide provides a description of the AS/400 control language (CL) and its OS/400 commands. (Non-OS/400 commands are described in the respective licensed program publications.) It also provides an overview of all the CL commands for the AS/400 system, and it describes the syntax rules needed to code them. v Security - Reference, SC41-5302-03 This guide provides information about system security concepts, planning for security, and setting up security on the system. It also gives
Copyright IBM Corp. 1997, 1999

information about protecting the system and data from being used by people who do not have the proper authorization, protecting the data from intentional or unintentional damage or destruction, keeping security up-to-date, and setting up security on the system. v DB2 UDB for AS/400 SQL Reference This guide provides information about DB2 UDB for AS/400 statements and their parameters. It also includes an appendix describing the SQL communications area (SQLCA) and SQL description area (SQLDA). v IDDU Use, SC41-5704-00 This guide describes how to use DB2 UDB for AS/400 interactive data denition utility (IDDU) to describe data dictionaries, les, and records to the system. v DATABASE 2/400 Advanced Database Functions, GG24-4249 This guide provides suggestions, guidelines, and practical examples of when and how functions offered by DB2 UDB for AS/400 such as triggers, referential integrity, DRDA-2, 2-phase commit, and stored procedures, can be effectively used. The book reports examples developed in several programming languages (RPG, COBOL, C), using native and SQL data access interface, both in the Integrated Language Environment and with the Original Program Model. v ILE COBOL for AS/400 Programmers Guide, SC09-2540-01 This guide provides information you need to design, write, test, and maintain COBOL for AS/400 programs on the AS/400 system. v ILE RPG for AS/400 Programmers Guide, SC09-2507-02 This guide provides information you need to design, write, test, and maintain ILE RPG for AS/400 programs on the AS/400 system. v ILE C for AS/400 Language Reference, SC09-2711-01 This guide provides information you need to design, write, test, and maintain ILE C for AS/400 programs on the AS/400 system. v ILE C for AS/400 Programmers Guide, SC09-2712-01

845

This guide provides information you need to design, write, test, and maintain ILE C for AS/400 programs on the AS/400 system. v ILE COBOL for AS/400 Reference, SC09-2539-01 This guide provides information you need to design, write, test, and maintain COBOL for AS/400 programs on the AS/400 system. v REXX/400 Programmers Guide, SC41-5728-00 This guide provides information you need to design, write, test, and maintain REXX/400 programs on the AS/400 system. v PL/I Users Guide and Reference, SC09-1825 This guide provides information about using AS/400 PL/I in the System/38 environment. Differences between the System/38 environment and the AS/400 environment are identied as well as the enhancements available in the AS/400 environment. v DB2 Multisystem for AS/400 This guide describes the fundamental concepts of distributed relational database les, nodegroups, and partitioning. The book provides the information you need to create and use database les that are partitioned across multiple AS/400 systems. Information is provided on how to congure the systems, how to create the les, and how the les can be used in applications. v Performance Tools for AS/400, SC41-5340-00 This guide provides the programmer with the information needed to collect data about the system, job, or program performance. This book also has tips for printing and analyzing performance data to identify and correct inefficiencies that might exist. Information about the manager and agent feature is included. v DB2 UDB for AS/400 SQL Call Level Interface This guide provides the information necessary for application programmers to write applications using the DB2 call level interface.

846

DB2 UDB for AS/400 SQL Programming V4R4

Index Special Characters


% (percent sign) use with LIKE 73 : (colon) C++ host variable 230 C host variable 230 COBOL 255 FORTRAN 841 ILE RPG for AS/400 313 PL/I 282 REXX 330 RPG for AS/400 300 - (dash) in COBOL host variable 255 - (minus) COBOL 255 %INCLUDE directive 291 PL/I 281 *APOST 254 *CNULRQD 232 /COPY ILE RPG for AS/400 312, 316 RPG for AS/400 299, 302 #include directive C 228 C++ 228 *NOCNULRQD 232 *NOCVTDT 317 *NOSEQSRC ILE RPG for AS/400 312 RPG for AS/400 299 #pragma mapinc directive C 245 C++ 245 *QUOTE 254 *SEQSRC ILE RPG for AS/400 312 RPG for AS/400 299 access path (continued) keyed sequence 396 sequential 396 temporary keyed from keyed access path 436 from the table 435 access plan 344 denition 11 in a package 12 in a program 11 validation 425 access plan rebuilt summary record 513 accessing remote databases interactive SQL 359 activation groups connection management example 561 add row to table 32 adding data to end of table 552 address variable, in dynamic SQL 197 advanced coding technique complex search condition 72 inserting multiple rows into a table 69 joining data from multiple tables 75 advisor query optimizer index 482 aggregating functions 159 ALIAS statement 48 ALL 86 ALLOCATE clause performance implications 457 allocating storage for SQLDA 208 allow copy data (ALWCPYDTA) parameter 464 ALTER TABLE 93 ALWCPYDTA (allow copy data) parameter 464 ALWCPYDTA parameter effect on query optimimizer 423 AND keyword description 74 multiple search condition 74 ANY 86 API QSQCHKS 2 QSQPRCED 2 apostrophe C 249 C++ 249 application binding 344 dynamic SQL designing and running 199 overview 197 application design user-dened function (UDF) 185 application domain and object-orientation 145 application forms using CREATE TABLE example application plans 344

A
access method dataspace scan 399 hashing access 415 index-from-index 414 index only access 412 key positioning 406 key selection 404 parallel data space scan 403 parallel key positioning 411 parallel key selection access method parallel pre-fetch 401 parallel pre-load 413 row selection method 397 summary table 420 access path denition 396
Copyright IBM Corp. 1997, 1999

405

171

847

application procedure coding SQL statements REXX 325 application program coding SQL statements C 225, 251 C++ 225 COBOL 251, 279 FORTRAN 837, 845 ILE RPG for AS/400 309, 325 PL/I 279, 295 RPG for AS/400 297, 307 compiling, ILE 341 compiling, non-ILE 340 creating 9 SQLCA (SQL communication area) C 225 C++ 225 COBOL 251 FORTRAN 837 ILE RPG for AS/400 309 PL/I 279 RPG for AS/400 297 SQLDA C 226 C++ 226 COBOL 252 FORTRAN 838 ILE RPG for AS/400 310 PL/I 280 RPG for AS/400 298 testing SQL statements in 379 application requester 555 application requester driver (ARD) programs package creation 577 running statements 577 application server 555 ARD (application requester driver) programs 577 arithmetic error in UDFs 188, 192 arithmetic expression error 37, 38 arranging rows 41 arrays of host structures using arrays C 241 C++ 241 COBOL 268 ILE RPG for AS/400 314 PL/I 289 RPG for AS/400 301 arrival sequence summary record 498 assignment rule date 218 host variable using 216 numeric assignment 218 string 217 time 218 timestamp 218 assignments in dynamic SQL example 175

assignments involving different UDTs example assignments involving UDTs example 175 asterisk (select all columns) 38 atomic operation data denition statements (DDL) 373 data integrity 373 denition 373 Auditing C2 security 366 authority, public 365 authorization Create SQL Package (CRTSQLPKG) command 558 for creating package 557 for running using a package 557 ID 366 testing 379, 380 auxiliary storage pools 368, 378 AVG over a UDT example 164

176

B
basic SQL statements and clauses 31 BEGIN DECLARE SECTION statement C 230 C++ 230 COBOL 255 FORTRAN 841 ILE RPG for AS/400 312 PL/I 282 RPG for AS/400 300 BETWEEN clause, multiple search condition BETWEEN keyword 72 bibliography 845 Binary Large OBjects 146 binding 344 BLOBs (Binary Large OBjects) uses and denition 146 blocked insert statement 70 blocking, SQL improving performance 462 blocking consideration using, affect on performance 461

72

C
C++ program #include directive 228 #pragma mapinc directive 245 apostrophes 249 BEGIN/END DECLARE SECTION 230 coding SQL statements 225 comment 228 compiler parameters 341 continuation 228 dynamic SQL coding 226 error and warning message during a compile external le description 245 host structure array indicator structure, declaring 244 arrays, declaring 241 declaring 239

343

848

DB2 UDB for AS/400 SQL Programming V4R4

C++ program (continued) indicator array 228 host variable 230 character 231 declaring 230 externally described 245 graphic 233 numeric 230 using pointers 244 INCLUDE statement 228 including code 228 margin 229 naming convention 229 null 229 preprocessor sequence 229 quotation marks 249 SQL data types determining equivalent C++ SQLCA, declaring 225 SQLCODE, declaring 225 SQLDA, declaring 226 SQLSTATE, declaring 225 statement label 229 trigraph 229 WHENEVER statement 230 C program

246

#include directive 228 #pragma mapinc directive 245 apostrophes 249 BEGIN/END DECLARE SECTION 230 coding SQL statements 225, 251 comment 228 compiler parameters 341 continuation 228 dynamic SQL coding 226 error and warning message during a compile external le description 245 host structure array indicator structure, declaring 244 arrays, declaring 241 declaring 239 indicator array 241 host variable 230 character 231 declaring 230, 236 externally described 245 graphic 233 numeric 230 using pointers 244 INCLUDE statement 228 including code 228 indicator structure 249 indicator variable 249 margin 229 naming convention 229 null 229 preprocessor sequence 229 quotation marks 249 SQL data types determining equivalent C 246 SQLCA, declaring 225

343

C program (continued) SQLCODE, declaring 228 SQLDA, declaring 226 SQLSTATE, declaring 225 statement label 229 trigraph 229 union elements 230 WHENEVER statement 230 C2 security auditing 366 call level interface 2 call-type contents with table functions 190 call-type, passing to UDF 190 calls, number using FETCH statement 462 cancelling a query 392 CAST FROM clause 188, 190, 192 castability 157 casting, UDFs 169 catalog database design, use in 97 denition 6 getting information about 97 column 98 integrity 377 LABEL ON information 48 QSYS2 views 6 table 97 CCSID connection to non-DB2 UDB for AS/400 561 delimited identier effect 561 dynamic SQL statement 200 include le 334 package considerations 561 printer le 335 rule for using 217 source le 334 temporary source le 335 Change Class (CHGCLS) command 367 change information in table host variables 33, 34 Change Job (CHGJOB) command 367 Change Logical File (CHGLF) command 367 Change Physical File (CHGPF) command 367 Change Query Attribute (CHGQRYA) command 402 Change query attributes 543 Change Query Attributes (CHGQRYA) command 381 change session attributes interactive SQL 357 changing data 33 information in a table 25 query options le 546 table denition 93, 554 character host variable C 231 C++ 231 COBOL 258
Index

849

character host variable (continued) FORTRAN 231 ILE RPG for AS/400 314, 318 PL/I 283 RPG for AS/400 300, 303 Character Large OBjects 146 check constraints 99 check pending 107, 375 checking syntax in interactive SQL 353 CHGPF command 33 CHGQRYA (Change Query Attributes) command 381 CL_SCHED table 585 class schedule table 585 clause 47 AND 74 DISTINCT 72 FROM 36 GROUP BY example 40 HAVING 42 INTO example 32 PREPARE statement, use with 202 restriction 208 NOT 74 null value 45 OR 74 ORDER BY 43 SELECT 38 SET 33 USING DESCRIPTOR 213 VALUES 31 WHENEVER NOT FOUND 60 WHERE character string 31 example 38, 213 expression 39 joining tables 76 multiple search condition within 74 NOT keyword 40 WHERE CURRENT OF 61 CLI 2 CLOBs (Character Large OBjects) uses and denition 146 CLOSQLCSR parameter effect on implicit disconnect 565 using 469 COBOL program 272 BEGIN/END DECLARE SECTION 255 COBOL COPY statement 254, 272 COBOL PROCESS statement 254 coding SQL statements 251, 279 comment 253 compile-time option 254 compiler parameters 340 continuation 253 Datetime host variable 263 debug lines 253 dynamic SQL coding 252 error and warning message during a compile 344 external le description 272

COBOL program 262 (continued) le reference variable LOB 262, 316 host structure array indicator structure, declaring 272 arrays, declaring 268 declaring 264 indicator array 268 host variable 255 character 258 declaring 255, 261 externally described 272 oating point 257 graphic 259 LOB 261, 315 numeric 255 including code 254 indicator structure 276 indicator variable 276 locator LOB 262, 316 margin 254 multiple source programs 255 naming convention 254 REDEFINES 276 sample program with SQL statements 613 sequence numbers 254 SQL 613 SQL data types determining equivalent COBOL 274 SQLCA, declaring 251 SQLCODE, declaring 251 SQLDA, declaring 252 SQLSTATE, declaring 251 statement label 255 WHENEVER statement 255 coded character set conversion error 38 coded character set identier (CCSID) 217 coding examples, SQL statements in COBOL 613 ILE C 606 ILE COBOL 613 ILE RPG for AS/400 program PL/I 621 REXX 640 REXX applications 327 RPG for AS/400 628 coding requirement C++ program comment 228 continuation 228 host variable 230 including code 228 margin 229 naming convention 229 null 229 preprocessor sequence 229 statement label 229 trigraph 229 WHENEVER statement 230

634

850

DB2 UDB for AS/400 SQL Programming V4R4

coding requirement (continued) C program comment 228 continuation 228 host variable 230 including code 228 indicator variable 249 margin 229 naming convention 229 null 229 preprocessor sequence 229 statement label 229 trigraph 229 WHENEVER statement 230 COBOL program COBOL PROCESS statement 254 comment 253 compile-time option 254 continuation 253 debug lines 253 host variable 255 indicator variable 276 margin 254 multiple source programs 255 naming convention 254 statement label 255 WHENEVER statement 255 FORTRAN program comment 839 continuation 839 debug lines 839 host variable 841 including code 840 indicator variable 844 margin 840 naming convention 840 statement label 840 WHENEVER statement 841 ILE RPG for AS/400 program comment 311 continuation 311 host variable 312 including code 312 indicator variable 322 naming convention 312 statement label 312 WHENEVER statement 312 PL/I program comment 281 continuation 281 host variable 282 including code 281 indicator variable 294 margin 281 naming convention 282 WHENEVER statement 282 RPG for AS/400 program comment 299 continuation 299 host variable 300 including code 299

coding requirement (continued) RPG for AS/400 program (continued) indicator variable 299 naming convention 299 statement label 300 WHENEVER statement 300 coding SQL statements in REXX applications 325 coding techniques 31, 55, 69 collating rows 41 collection changing table denition 554 creating 13 denition 3, 6 solving problem paging through retrieved data 551 retrieving data a second time 553 colon in C++ host variable 230 in C host variable 230 in COBOL host variable 255 in FORTRAN host variable 841 in ILE RPG for AS/400 host variable 313 in PL/I host variable 282 in RPG for AS/400 host variable 300 column dening heading 16, 48 denition 3, 6 FOR UPDATE OF clause 58 getting catalog information about 98 name denition 39 SET clause, value 33 updating view 29 column functions 159 combining information from multiple tables 23 SELECT statement 80 subselect with UNION example 80 command CHGQRYA 543 CHGQRYA command 543 QAQQINI 543 QAQQINI command 543 RUNSQLSTM errors 362 command, CL Create Structured Query Language Package (CRTSQLPKG) 763 CRTSQLPKG (Create Structured Query Language Package) 763 Delete Structured Query Language Package (DLTSQLPKG) 782 DLTSQLPKG (Delete Structured Query Language Package) 782 command (CL) 819, 835 Change Class (CHGCLS) 367 Change Job (CHGJOB) 367 Change Logical File (CHGLF) 367
Index

851

command (CL) 367, 835 (continued) Change Physical File (CHGPF) 367 Change Query Attribute (CHGQRYA) command 402 Change Query Attributes (CHGQRYA) 381 CHGCLS (Change Class) 367 CHGJOB (Change Job) 367 CHGLF (Change Logical File) 367 CHGPF (Change Physical File) 367 CHGQRYA (Change Query Attribute) command 402 CHGQRYA (Change Query Attributes) 381 Convert SQL C++ (CVTSQLCPP) 781 Create Duplicate Object (CRTDUPOBJ) 380 Create Source Physical File (CRTSRCPF) command 335 Create SQL C++ (CRTSQLCPPI) 712 Create SQL COBOL (CRTSQLCBL) 661 Create SQL ILE C for AS/400 (CRTSQLCI) 695 Create SQL ILE COBOL (CRTSQLCBLI) 678 Create SQL ILE/RPG (CRTSQLRPGI) 761 Create SQL Package (CRTSQLPKG) 557, 765 Create SQL PL/I (CRTSQLPLI) 728 Create SQL RPG (CRTSQLRPG) 744 Create User Prole (CRTUSRPRF) 366 CRTDUPOBJ (Create Duplicate Object) command 380 CRTUSRPRF (Create User Prole) 366 Delete Library (DLTLIB) 374 Delete Override (DLTOVR) 459 Delete SQL Package (DLTSQLPKG) 557, 783 Display Job (DSPJOB) 381 Display Journal (DSPJRN) 461 Display Message Description (DSPMSGD) 587 Display Module (DSPMOD) 345 Display Program (DSPPGM) 345 Display Program References (DSPPGMREF) 345 Display Service Program (DSPSRVPGM) 345 DLTLIB (Delete Library) 374 DLTOVR (Delete Override) 459 DSPJOB (Display Job) 381 DSPJRN (Display Journal) 461 DSPMSGD (Display Message Description) 587 Edit Check Pending Constraints (EDTCPCST) 375 Edit Rebuild of Access Paths (EDTRBDAP) 375 Edit Recovery for Access Paths (EDTRCYAP) 376 EDTCPCST (Edit Check Pending Constraints) 375 EDTRBDAP (Edit Rebuild of Access Paths) 375 EDTRCYAP (Edit Recovery for Access Paths) 376 Grant Object Authority (GRTOBJAUT) 365 GRTOBJAUT (Grant Object Authority) 365, 367 Override Database File (OVRDBF) 62, 302, 346, 367, 459, 461, 462 OVRDBF (Override Database File) 62, 302, 346, 367, 459, 461, 462 Print SQL Information (PRTSQLINF) 345, 382, 393, 784 QAQQINI 546 Reclaim DDM connections (RCLDDMCNV) 573 Retrieve Message (RTVMSG) 587 Revoke Object Authority (RVKOBJAUT) 365 RTVMSG (Retrieve Message) 587 Run SQL Statements (RUNSQLSTM) 1

command (CL) 1, 835 (continued) RUNSQLSTM (Run SQL statements) 367 RUNSQLSTM (Run SQL Statements) 361, 794 RVKOBJAUT (Revoke Object Authority) 365 Send Program Message (SNDPGMMSG) 587 Send User Message (SNDUSRMSG) 587 SNDPGMMSG (Send Program Message) 587 SNDUSRMSG (Send User Message) 587 Start Commitment Control (STRCMTCTL) 370 Start Journal Access Path (STRJRNAP) 376 STRCMTCTL (Start Commitment Control) 370 STRJRNAP (Start Journal Access Path) 376 STRSQL (Start SQL) 801 Trace Job (TRCJOB) 382, 461 TRCJOB (Trace Job) 382, 461 commands End Database Monitor (ENDDBMON) 480 Start Database Monitor (STRDBMON) 479 comment C 228 C++ 228 COBOL 253 for RUNSQLSTM 361 FORTRAN 839 getting 50 ILE RPG for AS/400 311 PL/I 281 REXX 328 RPG for AS/400 299 COMMENT ON statement using, example 49 COMMIT keyword 370 prepared statements 201 statement 559 statement description 6 commitment control activation group example 561 committable updates 567 description 369 displaying 381 distributed connection restrictions 570 DRDA resource 567 INSERT statement 32 job-level commitment denition 565, 570 protected resource 567 rollback required 572 RUNSQLSTM command 362 SQL statement processor 362 sync point manager 567 two-phase commit 567 unprotected resource 567 common database problem solving 551 comparison operators 40 comparisons involving UDTs example 173, 174 compile step warning 343 compile-time option COBOL 254

852

DB2 UDB for AS/400 SQL Programming V4R4

compiled application program object managing object 9 output source le member 11 program 9 user source le member 11 compiling application program ILE 341 non-ILE 340 application program object output source le member 11 program 11 user source le member 11 error message 343 warning message 343 compiling a UDF 160 completing a unit of work 68 complex search condition keyword for use in 72 multiple search condition 72 performing 72 WHERE clause 31 concept assignment rule, using SQL with host language host language, using SQL with handling return code 221 host structure 220 host variable 215 SQLCODEs 221 SQLSTATEs 221 SQLSTATEs 221 concurrency data 367 denition 367 condition keyword for use in search 72 multiple search within a WHERE clause 74 performing complex search 72 CONNECT statement 555, 559 interactive SQL 360 connection DDM 573 determining type 567 ending DDM 573 protected 567 unprotected 567 connection management ARD programs 577 commitment control restrictions 570 distributed unit of work considerations 572 ending connections DDMCNV effect on 573 DISCONNECT statement 573 RELEASE statement 573 example 561 implicit connection default activation group 565 nondefault activation group 566 implicit disconnection default activation group 565 nondefault activation group 566

216

connection management (continued) multiple connections to same relational database 577 connection status determining 570 example 576 consistency token 560 consistent behavior and UDTs 169 constant denition 39 SET clause, value 33 constraint 375 denition 8 referential 8 unique 8 constraint mechanisms on large objects 145 constraints check 99 referential check pending 107 creating tables 100 delete rules 105 deleting from tables 105 inserting into tables 102 removing 102 update rules 103 updating tables 103 continuation C 228 C++ 228 COBOL 253 FORTRAN 839 ILE RPG for AS/400 311 PL/I 281 RPG for AS/400 299 control, commitment 369 control information to access large object data 147 control structures 12 controlling parallel processing 473 convention SQL naming 4 system naming 3 conversion error 37 Convert SQL C++ (CVTSQLCPP) command 781 copy of the data using to improve performance 465 COPY statement COBOL 254 externally described 272 CORPDATA.DEPARTMENT (department) 579 CORPDATA.EMP_ACT (employee to project activity) 581 CORPDATA.EMP_ACT table 581 CORPDATA.EMPLOYEE table 580 CORPDATA.PROJECT (project) 584 CORPDATA.PROJECT table 584 correlated names 91 references 91 correlated subquery denition 88
Index

853

correlated subquery (continued) DELETE statement, use in 88 examples HAVING clause 90 UPDATE statement 91 WHERE clause 89 note on using 92 correlation denition 85 name 23, 79 using subquery 85 cost estimation query optimizer 423 cost of a UDT example 163 counter for UDFs example 194 counting and dening UDFs example 164 CREATE COLLECTION statement 13 CREATE DISTINCT TYPE statement and castability 157 examples of using 171 to dene a UDT 170 Create Duplicate Object (CRTDUPOBJ) command 380 CREATE FUNCTION statement 190 to register a UDF 161 CREATE INDEX sort sequence 53 CREATE SCHEMA statement 362 Create Source Physical File (CRTSRCPF) command precompile use 335 Create SQL C++ (CRTSQLCPPI) command 712 Create SQL C (CRTSQLC) command 819 Create SQL COBOL (CRTSQLCBL) command 661 Create SQL FORTRAN (CRTSQLFTN) command 835 Create SQL ILE C for AS/400 (CRTSQLCI) command 695 Create SQL ILE COBOL (CRTSQLCBLI) command 678 Create SQL ILE/RPG (CRTSQLRPGI) command 761 Create SQL Package (CRTSQLPKG) command 340, 557, 765 authority required 558 Create SQL PL/I (CRTSQLPLI) command 728 Create SQL RPG (CRTSQLRPG) command 744 Create Structured Query Language Package (CRTSQLPKG) command 763 CREATE TABLE prompting 353 CREATE TABLE statement 14 examples of using 171 Create User Prole (CRTUSRPRF) command 366 CREATE VIEW statement 29 creating collection example 13 index example 96 structured query language package 763 table description 14 example 14

creating (continued) view 13 description 28 on a table 29 over multiple tables 30 cross join 78 CRTDUPOBJ (Create Duplicate Object) command 380 CRTSQLC (Create SQL C) command 819 CRTSQLCBL (Create SQL COBOL) command 661 CRTSQLCBLI (Create SQL ILE/COBOL) command 678 CRTSQLCI (Create SQL ILE C for AS/400) command 695 CRTSQLCPPI (Create SQL C++) command 712 CRTSQLFTN (Create SQL FORTRAN) command 835 CRTSQLPKG (Create SQL Package) command 765 CRTSQLPKG (Create Structured Query Language Package) command 763 CRTSQLPLI (Create SQL PL/I) command 728 CRTSQLRPG (Create SQL RPG) command 744 CRTSQLRPGI (Create SQL ILE/RPG) command 761 CRTSQLxxx commands 3 CRTUSRPRF command create user prole 366 ctr() UDF C program listing 194 CURDATE scalar function 46 CURRENT DATE special register 45 current row 60 CURRENT SERVER special register 45 current session printing 357 removing all entries from 357 CURRENT TIME special register 45 CURRENT TIMESTAMP special register 45 CURRENT TIMEZONE special register 45 cursor distributed unit of work 576 example overview 56 example steps 58, 62 open 59 open, effect of recovery on 68 positions retaining across program call 467, 468 rules for retaining 467 using to improve performance 467, 468 retrieving SELECT statement result 212 scrollable positioning within a table 55 serial positioning within a table 55 using 55 WITH HOLD clause 68 CURTIME scalar function 46 CVTSQLCPP (Convert SQL C++) command 781

D
damage tolerance 376 dash in COBOL host variable 255 data adding to the end of table 552

854

DB2 UDB for AS/400 SQL Programming V4R4

data (continued) paging interactively displayed to improve performance 463 retrieved 551 retrieving in reverse order 551 selecting from multiple tables affect on performance 442 updating as it is retrieved 552 previously retrieved 553 view, processing 36 data denition statement (DDL) 4 data dictionary WITH DATA DICTIONARY clause CREATE COLLECTION statement 6 CREATE SCHEMA statement 6 data independence 32, 38 data integrity 99 atomic operation 373 commitment control 369 concurrency 367 constraint 375 damage tolerance 376 data denition statements (DDL) 373 function 366 index recovery 376 journaling 368 save/restore 375 data items ILE RPG for AS/400 314 RPG for AS/400 300 data manipulation statement (DML) 4 data mapping error 37 data path, open 388 data protection 365 data type determining equivalent C 246 C++ 246 COBOL 274 FORTRAN 842 ILE RPG for AS/400 318 PL/I 292 REXX 330 RPG for AS/400 303 data types BLOBs 146 CLOBs 146 DBCLOBs 146 object-oriented 145 database design, using the catalog in 97 relational 3 database monitor end 480 examples 482, 485 logical le DDS 493 physical le DDS 489 start 479

database monitor performance records 481 database query performance monitoring 478 dataspace denition 397 dataspace scan access method 399 date assignment rule host variable, using 218 date format 47 specifying current value 47 date/time arithmetic 47 date/time host variable ILE RPG for AS/400 313 Datetime host variable COBOL 263 DATFMT ILE RPG for AS/400 313, 317 DATSEP ILE RPG for AS/400 313, 317 DB2 Multisystem 2 DB2 Query Manager for AS/400 2 DB2 UDB for AS/400 1 C program 605 distributed relational database support 555 DB2 UDB for AS/400 sample table 579 DB2 UDB Query Manager and SQL Development Kit distributed relational database support 555 DB2 UDB Symmetric Multiprocessing 2 DB2 Universal Database considerations for packages 558 DBCLOBs (Double-Byte Character Large OBjects) uses and denition 146 DBCS (double-byte character set) considerations in interactive SQL 353 DBCS constants continuation C 228 C++ 228 COBOL 254 FORTRAN 839 ILE RPG for AS/400 311 PL/I 281 RPG for AS/400 299 in SQL source 334 DBGVIEW(*SOURCE) parameter 380 dbinfo, passing to UDF 190 DBINFO keyword 190 dbminfo argument, elements of 190 DDM (distributed data management) considerations 346 running a program with embedded SQL 346 DDS database monitor logical le 493 database monitor physical le 489 deadlock detection 367 debug lines COBOL 253 FORTRAN 839 debugging 379 common database problem 551
Index

855

debugging 551 (continued) program 551 DECLARE CURSOR statement using 36 DECLARE statement 198 default collection name (DFTRDBCOL) parameter default lter factors 424 DEFAULT keyword SET clause, value 34 default value 14, 18, 32 inserting in a view 96 dene cursor 58 dening column heading 16, 48 table name 48 dening the UDT and UDFs example 178 denitions 555 access path 396 access plan 11, 344 authorization ID 3 authorization name 3 binding 344 catalog 6 collection 3, 6 column 3, 6 column name 39 concurrency 367 constant 39 constraint 8 correlated subquery 88 correlation 85 CURRENT DATE special register 45 current row 60 CURRENT SERVER special register 45 CURRENT TIME special register 45 CURRENT TIMESTAMP special register 45 CURRENT TIMEZONE special register 45 data denition statement (DDL) 4 data dictionary 6 data manipulation statement (DML) 4 dataspace 397 default lter factors 424 dial 426 distributed unit of work 555 expression 39 eld 3 hashing access method 415 host structure 215 host variable 39, 215 implementation cost 423 index 8 index-from-index access method 414 index only access method 412 indicator structure 220 indicator variable 219 isolatable 437 join 30 join operation 23 journal 6 journal receiver 6

denitions 406 (continued) key positioning access method 396 key selection access method 404 keyed sequence 396 library 3 logical le 3 miniplan 425 NULL value 40 null value 45 open data path 388 outer-level SELECT 84 output source le member 11 package 3, 9, 12, 557 parallel data space scan method 403 parallel key positioning access method 411 parallel key selection access method 405 parallel pre-fetch access method 401 physical le 3 predicate 38 primary table 426 program 11 record 3 referential integrity 8 remote unit of work 555 row 3, 6 search condition 38 secondary tables 426 sequential access path 396 special register 40 SQL package 3 SQLCODE 587 SQLSTATE 587 stored procedure 8 subquery 84 symmetrical multiprocessing 397 table 3, 6 trigger 8 user prole 3 user source le member 11 USER special register 45 view 3, 7 delete current row 61 Delete Library (DLTLIB) command 374 Delete Override (DLTOVR) command 459 Delete SQL Package (DLTSQLPKG) command 557, 783 DELETE statement correlated subquery, use in 92 description 28, 34 Delete Structured Query Language Package (DLTSQLPKG) command 782 deleted rows getting rid of using REUSEDLT(*YES) 399 getting rid of using RGZPFM 399 deleting structured query language package 782 deleting information in a table 28 department table CORPDATA.DEPARTMENT 579 DESCRIBE statement use with dynamic SQL 201

856

DB2 UDB for AS/400 SQL Programming V4R4

DESCRIBE TABLE statement 559 description SQLCODEs and SQLSTATEs 589 descriptions, C for AS/400 external le 803 descriptor-name in REXX 325 designing dynamic SQL application 199 detail record records retrieved 523 DFT_SQLMATHWARN conguration parameter 188, 192 DFTRDBCOL (default collection name) parameter 3 diagnostic-message, passing to UDF 189 DISCONNECT statement 555, 559 ending connection 573 Display Job (DSPJOB) command 381 Display Journal (DSPJRN) command 461 Display Message Description (DSPMSGD) command 587 Display Module (DSPMOD) 345 Display Program (DSPPGM) command 345 Display Program References (DSPPGMREF) command 345 Display Service Program (DSPSRVPGM) 345 displaying SQLCODE and SQLSTATE description 587 DISTINCT 71 clause 72 keyword 553 distinct type 157 distributed data management (DDM) 346 distributed relational database accessing remote databases 359 application requester 555 application server 555 committable updates 567, 570 connection management 561 multiple connections 565 connection restrictions 570 connection type determining 567 protected 567 unprotected 567 consideration for creating packages 558 creating packages 558 DB2 UDB for AS/400 support 555 determining connection status 570 distributed RUW example program 556 distributed unit of work 555, 566, 573 ending connections DDMCNV effect on 573 DISCONNECT statement 573 RELEASE statement 573 rst failure data capture (FFDC) 578 implicit connection default activation group 565 nondefault activation group 566 implicit disconnection default activation group 565 nondefault activation group 566 interactive SQL 359

distributed relational database (continued) packages 359 statement in 558 precompiler diagnostic messages 558 problem handling 578 protected connection 567 protected resource 567 remote unit of work 555, 566 rollback required state 572 session attributes 360 SQL packages 557 sync point manager 567 two-phase commit 567 unprotected connection 567 unprotected resource 567 valid SQL statements 558 Distributed Relational Database Architecture (DRDA) 1 distributed unit of work 555, 566, 573 connection considerations 572 connection status 570 connection type 567 cursors 576 prepared statements 576 sample program 574 DLTSQLPKG (Delete SQL Package) command 783 DLTSQLPKG (Delete Structured Query Language Package) command 782 Double-Byte Character Large OBjects 146 DRDA (Distributed Relational Database Architecture) 555 DRDA level 1 566 DRDA level 2 566 DRDA resource 567 DROP PACKAGE statement 555 DSPJOB (Display Job) command 381 duplicate rows eliminating 81 preventing 71 DUW (distributed unit of work) 555 dynamic SQL address variable 197 allocating storage 203 application 197, 199 building and running statements 197 CCSID 200 coding in C 226 coding in C++ 226 coding in COBOL 252 coding in FORTRAN 838 coding in ILE RPG for AS/400 310 coding in PL/I 280 coding in RPG for AS/400 298 cursor, use in 202 DESCRIBE statement 201 EXECUTE statement 199 FETCH, multiple-row ILE RPG for AS/400 323 xed-list SELECT statement, using 202 parameter marker 213 PREPARE statement 199 processing non-SELECT statements 199
Index

857

dynamic SQL (continued) replacing parameter markers with host variables 197 run-time overhead 197 statements 4 varying-list SELECT statement 201

E
Edit Check Pending Constraints (EDTCPCST) command 375 Edit Rebuild of Access Paths (EDTRBDAP) command 375 Edit Recovery for Access Paths (EDTRCYAP) command 376 eliminating duplicate rows 81 embedded SQL C 227 C++ 227 COBOL 253 FORTRAN 839 ILE RPG for AS/400 311 PL/I 280 precompiling 333 RPG for AS/400 298 running a program with 346 employee-to-project activity table 581 encapsulation and UDTs 169 End Database Monitor (ENDDBMON) command 480 END DECLARE SECTION statement C 230 C++ 230 COBOL 255 FORTRAN 841 ILE RPG for AS/400 312 PL/I 282 RPG for AS/400 300 end-of-data reached 59 ENDDBMON (end database monitor) command 480 entering DBCS data 353 ERRLVL 362 error data mapping ORDER BY 37 error determination in distributed relational database rst failure data capture (FFDC) 578 error message during a compile 343 C++ program 343 C program 343 COBOL program 343, 344 PL/I program 343 RPG program 343, 344 error message during precompile displayed on listing 335 error return code, handling general 221 establishing position at end of table 551 examples 49, 50, 220

examples 74, 50, 220 (continued) AND 74, 75 application forms using CREATE TABLE 171 assignments in dynamic SQL 175 assignments involving different UDTs 176 assignments involving UDTs 175 AVG over a UDT 164 BETWEEN 72 catalog getting column information 97 getting table information 97 changing information in a table 25 changing rows in table host variables 33, 34 COBOL, UPDATE statement 253 COMMENT ON 49 comparisons involving UDTs 173, 174 correlated subquery HAVING clause 90 WHERE clause 89 correlation name 23 cost of a UDT 163 counter for UDFs 194 counting and dening UDFs 164 creating collection 13 index 96 table 14 view on a table 29 views over multiple tables 30 ctr() UDF C program listing 194 CURRENT DATE 47 CURRENT TIMEZONE 47 cursor 56 cursor in DUW program 576 database monitor 482, 485 dening stored procedures with CREATE PROCEDURE 117 dening the UDT and UDFs 178 deleting information in a table 28 determining connection status 576 distributed RUW program 556 distributed unit of work program 574 dynamic CALL 127 embedded CALL 124, 125 EXISTS 87 exploiting LOB function to populate the database 179 exploiting LOB locators to manipulate UDT instances 180 exploiting UDFs to query instances of UDTs 179 exponentiation and dening UDFs 161 extracting a document to a le (CLOB elements in a table) 152 function invocations 165 getting catalog information about column 98 table 97 getting comment 50 getting information about column using catalog 97

858

DB2 UDB for AS/400 SQL Programming V4R4

examples 97, 50, 220 (continued) table using catalog 74 getting information from multiple tables 23 single table 20 governor 394 host variable in SQL statement 215 IN 73 index 446 inserting add row to table 32 multiple rows into a table 69 inserting data into a CLOB column 154 invoking stored procedures 127 where a CREATE PROCEDURE exists 124 where no CREATE PROCEDURE exists 125 join 76 LABEL ON statement 16, 48 LIKE 73 list function in interactive SQL 354 LOBFILE.SQB COBOL program listing 153 LOBFILE.SQC C program listing 153 LOBLOC.SQB COBOL program listing 150 LOBLOC.SQC C program listing 149 money using CREATE DISTINCT TYPE 171 multiple search condition (WHERE clause) 74 OR 75 ORDER BY sort sequence 51 output from precompiler, COBOL 336 parameter markers in functions 166 performance analysis 483, 484 preventing duplicate rows 71 QSYSPRT listing SQL statement processor 363 reducing the number of open database operation 459 removing information from table 28, 34 resume using CREATE DISTINCT TYPE 171 returning completion status to calling program 135 RPG for AS/400 declare variable 306 sales using CREATE TABLE 171 sample table 579 search 72 search string and BLOBs 162 SELECT records sort sequence 52 SELECT statement allocating storage for SQLDA 208 selecting data from multiple tables 442 selecting into table host variables 36 special register 47 stored procedures returning completion status 135 string search and dening UDFs 162 string search over UDT 163 subquery 84

examples 83, 50, 220 (continued) Union simple 83 UNION using host variables 81 UNION ALL using host variables 83 unqualied function reference 167 UPDATE statement 25 use of UDTs in UNION 177 user-dened sourced functions on UDTs 175 using a locator to work with a CLOB value 148 using index 96 using qualied function reference 166 variable declaration 276 view sort sequence 53 WITH CASCADED CHECK OPTION 110 WITH LOCAL CHECK OPTION 110 working with index 96 exception condition 222 exception join 77 EXECSQL REXX command 325, 327 EXECUTE IMMEDIATE statement 199 EXECUTE privileges for packages 557 EXECUTE statement 199, 200 EXISTS keyword, use in subquery 87 exiting interactive SQL 357 exploiting LOB function to populate the database example 179 LOB locators to manipulate UDT instances example 180 UDFs to query instances of UDTs example 179 exponentiation and dening UDFs example 161 expression denition 39 SET clause, value 33 using in the WHERE clause 39 extended dynamic QSQPRCED 2 extensibility and UDTs 169 external le description C 245 C++ 245 C for AS/400 803 COBOL 272 host structure arrays COBOL 273 ILE RPG for AS/400 317 RPG for AS/400 303 ILE RPG for AS/400 316 PL/I 291 RPG for AS/400 302 extracting a document to a le (CLOB elements in a table) example 152

F
failed session, recovering 358
Index

859

FETCH using host structure array multiple-row 63 FETCH statement 212 multiple-row ILE RPG for AS/400 314, 323 RPG for AS/400 301 FFDC (rst failure data capture) 578 eld 3 le query options 546 le description external C 245 C++ 245 C for AS/400 803 COBOL 272 ILE RPG for AS/400 316 PL/I 291 RPG for AS/400 302 host structure arrays COBOL 273 ILE RPG for AS/400 317 RPG for AS/400 303 le reference variable LOB COBOL 262, 316 le reference variables examples of using 152 for manipulating LOBs 146 input values 151 LOB PL/I 286 output values 152 lter factors, default in query optimization 424 rst failure data capture (FFDC) 578 xed-list SELECT statement denition 201 using 201 exibility and UDTs 169 oating point host variable COBOL 257 FOR UPDATE OF clause restrictions 58 format, SQLDA 204 FORTRAN program BEGIN/END DECLARE SECTION 841 coding SQL statements 837, 845 comment 839 compile-time options 841 continuation 839 debug lines 839 dynamic SQL coding 838 host variable 841 character 842 declaring 841, 842 numeric 841 IMPLICIT statement 841 including code 840 indicator variable 844

FORTRAN program (continued) margin 841 naming convention 840 PROCESS statement 841 SQL data types determining equivalent FORTRAN 842 SQLCA, declaring 837 SQLCOD, declaring 837 SQLCODE, declaring 837 SQLSTA, declaring 837 SQLSTATE, declaring 837 statement label 840 WHENEVER statement 841 FROM clause 36 function interactive SQL 349 function invocations example 165 function-name, passing to UDF 189 function path and UDFs 158 function references, summary for UDFs 167 function selection algorithm and UDFs 158 functions aggregating functions 159 column functions 159 scalar functions 159 syntax for referring to 165 table functions 159

G
generic query information summary record 520 getting catalog information about column 98 table 97 comment 50 information from multiple table 23 from single table 20 governor 391 *DFT 393 *RQD 393 *SYSRPYL 393 CHGQRYA 391 JOB 392 QRYTIMLMT 391 time limit 392 Grant Object Authority (GRTOBJAUT) command GRANT PACKAGE statement 555 graphic host variable C 233 C++ 233 COBOL 259 ILE RPG for AS/400 318 GROUP BY clause 40 keyword 553 using null value with 41 grouping optimization 442 grouping the row you select 41

365

860

DB2 UDB for AS/400 SQL Programming V4R4

H
halfword binary integer (SMALLINT) 218 handling error return code SQLCODEs and SQLSTATEs 221 exception condition (WHENEVER statement) hash join 427 hashing access method 415 HAVING clause 42 host language concepts and rules 215 host structure C 239 C++ 239 COBOL 264 denition 215 ILE RPG for AS/400 314 indicator array C 241, 244 C++ 241, 244 COBOL 268, 272 PL/I 288, 290 PL/I 286 RPG for AS/400 300 used to set null value 220 using arrays C 241 C++ 241 COBOL 268, 273 ILE RPG for AS/400 314 PL/I 289 RPG for AS/400 301 using indicator variable with, example 220 host structure array multiple-row FETCH 63 host structure indicator array C 241 C++ 241 COBOL 268 PL/I 288 host variable 230 assignment rule 216 C 230 using pointers 244 C++ 230 using pointers 244 character C 231 C++ 231 COBOL 258 FORTRAN 842 ILE RPG for AS/400 314, 318 PL/I 283 RPG for AS/400 300, 303 COBOL 255 date/time ILE RPG for AS/400 313, 318 Datetime COBOL 263 denition 39, 215

222

host variable 245 (continued) external le description C 245 C++ 245 COBOL 272 ILE RPG for AS/400 316 PL/I 291 RPG for AS/400 302 oating point COBOL 257 FORTRAN 841 declaring 841 general use in SQL statement 215 graphic C 233 C++ 233 COBOL 259 ILE RPG for AS/400 318 ILE RPG for AS/400 312 declaring 313 LOB COBOL 261, 315 PL/I 284 numeric C 230 C++ 230 COBOL 255 FORTRAN 841 ILE RPG for AS/400 318 PL/I 283 RPG for AS/400 303 PL/I 282 declaring 282 requirement for COBOL program 255 requirement for ILE RPG for AS/400 312 requirement for PL/I program 282 REXX 330 RPG for AS/400 300 declaring 300 SET clause, value 33 SQL statement, use in rule for date, time, and timestamp assignment 218 rule for numeric assignment 218 string assignment, rule 217 host variable and ODP implementation summary record 518

I
ID, authorization 366 IDDU (interactive data denition utility) 6 ILE (Integrated Language Environment) compiling application 341 ILE C program SQL statements in, sample 606 ILE COBOL program sample program with SQL statements 613 SQL 613 ILE programs package 559
Index

861

ILE RPG for AS/400 program /COPY statement 312, 316 character host variables 314 coding SQL statements 309, 325 comment 311 compiler parameters 341 continuation 311 dynamic SQL coding 310 error and warning message during a compile 344 external le description 316 host structure declaring 314 host structure array declaring 314 host variable 312 character 318 date/time 313, 318 declaring 313 externally described 316 graphic 318 numeric 318 including code 312 indicator structure 322 indicator variable 322 naming convention 312 notes and usage 322 occurrence data structure 314 sequence numbers 312 SQL data types determining equivalent RPG 318 SQL statements in sample 634 SQLCA 309 SQLCA placement 309 SQLDA example 323 SQLDA, declaring 310 statement label 312 variable declaration 322 WHENEVER statement 312 ILE RPG program SQLCA placement 605 ILE service programs package 559 immediate sensitivity 63, 67 implementing a UDF 160 implicit connect 565 implicit disconnect 565 IMPLICIT statement FORTRAN 841 improving performance 464, 465 blocking, using 461 join queries 439 paging interactively displayed data 463 PREPARE statement 470 retaining cursor positions across program call 467, 468 SELECT statements, using effectively 464 selecting data from multiple tables 442 SQL blocking 462

improving performance 467, 465 (continued) using close SQL cursor (CLOSQLCSR) 467, 468 FETCH FOR n ROWS 462 INSERT n ROWS 463 parameter passing techniques 472 precompile options 471 IN keyword description 73 subquery, use in 87 in tray table 585 IN_TRAY table 585 include le C 228 C++ 228 CCSID 334 COBOL 254 ILE RPG for AS/400 312 input to precompiler 334 PL/I 281 RPG for AS/400 299 INCLUDE statement 334 C 228 C++ 228 COBOL 254 ILE RPG for AS/400 312 PL/I 281 RPG for AS/400 299 including code C 228 C++ 228 COBOL 254 COBOL COPY statement 254 FORTRAN 840 ILE RPG for AS/400 312 PL/I 281 RPG for AS/400 299 index columns used for keys 396 creating from another index 414 denition 8 recovery 376 using 96 using effectively, example 446 working with 96 index advisor query optimizer 482 index created summary record 505 index-from-index access method 414 index only access method 412 indexes using with sort sequence 449 indicator array C 241, 244 C++ 241, 244 COBOL 268, 272 PL/I 288, 290

862

DB2 UDB for AS/400 SQL Programming V4R4

indicator structure 220 indicator variable C 249 C++ 249 COBOL 276 denition 219 FORTRAN 844 ILE RPG for AS/400 322 PL/I 294 REXX 332 RPG for AS/400 306 used to set null value 220 used with host structure, example 220 with host structure 220 indicator variables stored procedures 132 indicator variables and LOB locators 151 inx notation and UDFs 168 information, inserting into table 18 information messages open data path 388, 390 performance 382, 388 inner join 75 INSERT n ROWS improving performance 463 INSERT statement blocked 31 ILE RPG for AS/400 314 RPG for AS/400 301 column value 216 default value 18, 32 description 31 VALUES clause 31 inserting information into table 18 multiple rows into tables 69 note 70 inserting data into a CLOB column example 154 instances of object-oriented data types, storing 145 Integrated Language Environment (ILE) module 12 program 11 service program 12 integrity catalog 377 data 99, 366 referential 99 interactive data denition utility 6 interactive interface concepts 1 Interactive SQL 1 interactive SQL accessing remote databases 359 Interactive SQL adding DBCS data 353 interactive SQL change session attributes 357 description 349 exiting 357

interactive SQL (continued) function 357 general use 349 getting started 350 overview 349 package 360 Interactive SQL prompting 354 interactive SQL prompting DBCS consideration 353 overview 349 session services 349, 356, 357 statement entry 349, 351 statement processing mode 353 Interactive SQL syntax checking 353 interactive SQL terminology 3 testing your SQL statements with 349, 358 interactively displayed data, paging affect on performance 463 INTO clause description 32 PREPARE statements 202 restriction 208 invoking UDFs 164

J
JOB 392 job attribute DDMCNV 573 job-level commitment denition 565, 570 join cross 78 denitions 30 exception 77 hash 427 inner 75 left outer 76 optimization 426 join operation denition 23 in a view 30 join optimization performance tips 439 join order optimization 432 join position 385 join secondary dials costing 432 joining data from multiple tables 75 table with WHERE clause 76 technique 79 journal 6 journal receiver 6 journaling 368

K
key positioning access method 406
Index

863

key range estimate 424 key selection access method 404 keyed sequence access path 396 keyword AND 74 BETWEEN 72 COMMIT 370 DISTINCT 553 EXISTS 87 GROUP BY 553 IN 73, 87 LIKE 73 NOT 40 OR 74 search condition, use in 72 UNION 80, 553 UNION ALL, specifying 83

L
LABEL ON statement 16, 48 information in catalog 48 package 560 language, host concepts and rules 215 large object descriptor 146 large object value 146 learn how to prompt using interactive SQL 354 leaving interactive SQL 357 left outer join 76 library denition 3 LIKE keyword 73 limit, time 392 linking a UDF 160 list function 356 list function in interactive SQL description 354 listing output from precompiler 335 live data using to improve performance 464 LOB le reference variable COBOL 262, 316 LOB le reference variables PL/I 286 LOB host variable COBOL 261, 315 PL/I 284 LOB locator COBOL 262, 316 LOB locators PL/I 285 LOBEVAL.SQB COBOL program listing 153 LOBEVAL.SQC C program listing 153 LOBLOC.SQB COBOL program listing 150 LOBLOC.SQC C program listing 149

LOBs (Large Objects) and DB2 object extensions 145 le reference variables 146 examples of using 152 input values 151 output values 152 SQL_FILE_APPEND, output value option 152 SQL_FILE_CREATE, output value option 152 SQL_FILE_OVERWRITE, output value option 152 SQL_FILE_READ, input value option 152 large object descriptor 146 large object value 146 locators 146, 147 example of using 148 indicator variables 151 manipulating 145 programming options for values 147 storing 145 synergy with UDTs and UDFs examples of complex applications 177 locator LOB COBOL 262, 316 locators LOB PL/I 285 locators for manipulating LOBs 146 locks analyzing 381 logical le 3, 7 logical le DDS database monitor 493 long object names performance 470 LONG VARCHAR storage limits 146 LONG VARGRAPHIC storage limits 146 Loosely Coupled Parallelism 2 LR indicator ending RPG for AS/400 programs 307

M
manipulating large objects 145 mapping error data 37 margins C 229 C++ 229 COBOL 254 FORTRAN 840 PL/I 281 REXX 329 MARGINS parameter C 229 C++ 229 marker, parameter 213 maximum size for large object columns, dening

147

864

DB2 UDB for AS/400 SQL Programming V4R4

member output source le 11 user source le 11 message analyzing error and warning messages 343 cause and user response 382 error and warning during a compile 343 open data path information 388, 390 performance information 382, 388 running in debug mode 382 minus COBOL 255 mode interactive SQL 353 modelling entities as independent objects 145 module Integrated Language Environment (ILE) object 12 money using CREATE DISTINCT TYPE example 171 monitor (ENDDBMON) command, end database 480 monitoring database query performance 478 moving large objects using a le reference variable 146 multiple row inserting into a table 69 notes on inserting 70 search condition within a WHERE clause 74 table improving performance when selecting data from 442 joining data from 75 multiple-row FETCH statement using descriptor area 64 host structure arrays 63 row storage area 64 with languages 63

N
naming convention *SQL 3 *SYS 3 C 229 C++ 229 COBOL 254 FORTRAN 840 ILE RPG for AS/400 312 PL/I 282 REXX 329 RPG for AS/400 299 SQL 4 system 3 negative SQLCODEs 591 nested loop join 426 new release considerations 346 non-SELECT statements, processing NOT keyword 40, 74

NOW scalar function 46 NUL-terminator C 232 C++ 232 character host variables C 231 C++ 231 null usage in C 229 usage in C++ 229 null string in REXX 329 NULL value 14 null value 45 NULL value denition 40 null value INSERT statement 32 inserting in a view 96 set by indicator variable 220 SET clause, value 33 UPDATE statement 33 used with GROUP BY clause 41 used with ORDER BY clause 44 null value, SQL contrasted with null value in REXX 329 number of calls using a FETCH statement 462 number of open database operations improving performance by reducing 459 numbers sequence COBOL 254 ILE RPG for AS/400 312 RPG for AS/400 299 numeric assignment rule host variable, using 218 numeric conversion error 38 numeric host variable C 230 C++ 230 COBOL 255 FORTRAN 841 ILE RPG for AS/400 318 PL/I 283 RPG for AS/400 303

O
object application program 9 collection 3 module 9 Integrated Language Environment (ILE) package 9 program Integrated Language Environment (ILE) service program 9 Integrated Language Environment (ILE) SQL 5 object-orientation and UDFs 156 object-oriented extensions and UDTs 169

12

11 12

199

Index

865

object-relational application domain and object-orientation 145 constraint mechanisms 145 data types 145 denition 145 LOBs 145 support for 146 triggers 145 UDTs and UDFs 145 why use the DB2 object extensions 145 occurrence data structure ILE RPG for AS/400 314 RPG for AS/400 301 ODBC 199 ODP (open data path) 459 ODP implementation and host variable summary record 518 open closing 459 determing number 461 effect on performance 459 reducing number 459 open cursor during a unit of work 68 open data path 459 denition 388 information messages 388 open database connectivity (ODBC) 199 OPEN statement 213 operation, atomic 373 operators, comparison 40 OPNQRYF (Open Query File) command 477 optimization 395 grouping 442 join 426 join order 432 nested loop join 426 OPTIMIZE FOR n ROWS clause effect on query optimizer 423 optimizer operation 422 query index advisor 482 optimizer timed out summary record 515 options, precompile improving performance by using 471 ORDER BY clause 43 using null values with 44 data mapping errors 37 sort sequence, using 50 using 51 outer join 76 outer-level SELECT 84 output all queries that performed table scans 484 SQL queries that performed table scans 483 output source le member denition 11 overloaded function names and UDFs 158

override consideration running a program with embedded SQL 346 Override Database File (OVRDBF) command 62, 346, 367, 459, 462 used with RPG for AS/400 /COPY 302 overview, interactive SQL 349

P
package authority to create 557 authority to run 557 bind to an application 9 CCSID considerations for 561 consistency token 560 Create SQL Package (CRTSQLPKG) command 557 authority required 558 creating authority required 557 effect of ARD programs 577 errors during 558 on local system 560 RDB parameter 557 RDBCNNMTH parameter 560 TGTRLS parameter 559 type of connection 560 unit of work boundary 560 creating on a non-DB2 UDB for AS/400 errors during 558 required precompiler options for DB2 Common Server 558 unsupported precompiler options 558 DB2 UDB for AS/400 support 557 denition 9, 12, 557 Delete SQL Package (DLTSQLPKG) command 557 deleting 557 interactive SQL 360 labeling 560 restore 560 save 560 SQL statement size 559 statements that do not require package 559 page fault 397 paging interactively displayed data 463 retrieved data 551 parallel data space scan access method 403 parallel key positioning access method 411 parallel key selection access method 405 parallel pre-fetch access method 401 parallel pre-load index-based 413 table-based 413 parallel processing controlling in jobs (CHGQRYA command) 474 system wide (QQRYDEGREE) value 474 parameter markers in functions example 166

866

DB2 UDB for AS/400 SQL Programming V4R4

parameter passing differences 473 PL/I 294 RPG for AS/400 307 stored procedures 128, 132 table 128 parameters marker 213 parameters, command ALWCPYDTA (allow copy data) 464, 465 CLOSQLCSR (close SQL cursor) 467, 468 passing argument to UDF call-type 190 dbinfo 190 diagnostic-message 189 function-name 189 scratchpad 190 specic-name 189 SQL-argument 190, 191 SQL-argument-ind 188 SQL-argument-ind-array 191 SQL-result 190, 192 SQL-result-ind 188, 192 SQL-state 188 path, open data 388 pending check 107 performance 395 information messages 382, 388 monitoring 477 monitoring query 478 open data path messages 388, 390 OPNQRYF 477 optimizing 477 tools 477 UDFs 156 using long object names 470 performance analysis example 1 483 example 2 484 example 3 484 performance and UDTs 169 performance considerations 393, 459 performance improvement blocking, using 461 paging interactively displayed data 463 PREPARE statement 470 reducing number of open database operation 459 retaining cursor positions across program call 467, 468 SELECT statements, using effectively 464 selecting data from multiple tables 442 SQL blocking 462 using copy of the data 465 using INSERT n ROWS 463 using live data 464 using precompile options 471 performance records database monitor 481 performance verication 381 performing complex search condition 72

physical le 3, 6 physical le DDS database monitor 489 PL/I SQL statements in, sample 621 PL/I program %INCLUDE directive 281, 291 BEGIN/END DECLARE SECTION 282 coding SQL statements 279, 295 comment 281 compiler parameters 340 continuation 281 dynamic SQL coding 280 error and warning message during a compile external le description 291 le reference variables LOB 286 host structure array indicator structure, declaring 290 arrays, declaring 289 declaring 286 indicator array 288 host variable 282 character 283 declaring 282, 284 externally described 291 LOB 284 numeric 283 INCLUDE statement 281 including code 281 indicator structure 294 indicator variable 294 locators LOB 285 margin 281 naming convention 282 SQL data types determining equivalent PL/I 292 SQLCA, declaring 279 SQLCODE, declaring 279 SQLDA, declaring 280 SQLSTATE, declaring 279 structure parameter passing 294 WHENEVER statement 282 pointer C 244 C++ 244 positive SQLCODEs 589 pre-fetching 399 precompile options improving performance, using 471 precompiler basic process 333 complete diagnostics 334 concepts 1 diagnostic messages 558 diagnostics 335 displaying options 345 errors 343
Index

343

867

precompiler (continued) include le CCSID 334 input to 334 other preprocessors 334 output from listing 335 sample 336 temporary source le member 335 parameters passed to compiler 340 passing host variables 472 record number 337 reference column 339 secondary input 334 sequence number 337 source le CCSID 334 containing DBCS constants 334 margins 334 source record 337 VisualAge C++ for OS/400 342 warning 343 precompiler command CRTSQLC 819 CRTSQLCBL 340 CRTSQLCBLI 341 CRTSQLCI 229, 232, 234, 341 CRTSQLCPPI 229, 232, 234, 341 CRTSQLFTN 835 CRTSQLPLI 281, 340 CRTSQLRPG 340 CRTSQLRPGI 341 CRTSQLxxx 51, 558 CVTSQLCPP 229, 232, 234, 341 default 468 description 340 precompiler le QSQLTEMP 335 QSQLTEMP1 335 precompiler parameter *CVTDT 316 *NOCVTDT 316, 317 ALWCPYDTA 464 CLOSQLCSR 469 DATFMT 313, 317 DATSEP 313, 317 DBGVIEW(*SOURCE) 380 displayed on listing 335 INCFILE 334 MARGINS 281, 334, 343 C 229 C++ 229 OBJ 335 OBJTYPE(*MODULE) 341 OBJTYPE(*PGM) 341 OBJTYPE(*SRVPGM) 341 OPTION(*APOST) 254 OPTION(*CNULRQD) 232, 234 OPTION(*CVTDT) 316 OPTION(*NOCNULRQD) 232, 234

precompiler parameter (continued) OPTION(*NOGEN) 316, 341 OPTION(*NOSEQSRC) 312 OPTION(*SEQSRC) 299 OPTION(*QUOTE) 254 OPTION(*SEQSRC) 312 OPTION(*SOURCE) 334 OPTION(*XREF) 334, 335 OUTPUT 334 parameters passed to compiler 340 PGM 335 PRTFILE 335 RDB Effect on precompile 333 TIMFMT 313, 317 TIMSEP 313, 317 predicate denition 38 transitive closure 436 Predictive Query Governor 391 PREPARE statement improving performance 470 non-SELECT statement 200 restrictions 199 using 213 prepared statement distributed unit of work 576 preparing program with SQL statements 333 preprocessor usage with SQL C++ program 229 usage with SQL C program 229 with SQL 334 preventing duplicate rows 71 Print SQL Information (PRTSQLINF) 345, 382, 393 printer le 335 CCSID 335 printing current session 357 problem handling 221 problems join query performance 438 problems, solving database 551 process, basic precompiler 333 PROCESS statement COBOL 254 FORTRAN 841 processing data in a view 36 non-SELECT statements 199 SELECT statement with SQLDA 201 producing reports from sample programs 643 program application 379 compiling application ILE 341 non-ILE 340 debugging 380 denition 11 Integrated Language Environment (ILE) object 11 non-ILE object 11 performance verication 381

868

DB2 UDB for AS/400 SQL Programming V4R4

program (continued) preparing and running with SQL statements 379 reference 345 report produced by sample 643 running with embedded SQL DDM consideration 346 instruction 346 override consideration 346 return code 347 sample 605 SQL statements in COBOL 613 ILE C 606 ILE COBOL 613 ILE RPG for AS/400 program 634 PL/I 621 REXX 640 RPG for AS/400 628 program calls rules for retaining cursor positions 469 project table 584 prompt using interactive SQL 349, 354 prompting CREATE TABLE 353 function 349, 351 overview 349 subqueries 353 protected connections dropping 570 protected resource 567 protection, data 365 PRTSQLINF (Print SQL Information) command 784 public authority 365

Query options le 543 query options le changing 546 query performance monitoring 478 query sort summary record 508 query time limit 392 quotation mark C 249 C++ 249

R
re-use and UDFs 156 read-only table 59 view 96 read-only connection 567 receiver, journal 6 Reclaim DDM connections (RCLDDMCNV) command 573 record, denition 3 record selection 52 sort sequence, using 50 records database monitor performance 481 records retrieved detail record 523 recovering effect on open cursor 68 index 376 interactive SQL saved or failed session 358 reducing number of open database operations improving performance, example 459 reference, program 345 referential constraints check pending 107 creating tables 100 denition 8 delete rules 105 deleting from tables 105 inserting into tables 102 removing 102 update rules 103 updating tables 103 referential integrity 99 denition 8 registering UDFs 160 related information 845 relational database 3 RELEASE statement 555, 559 ending connection 573 remote databases accessing from interactive SQL 359 remote unit of work 555, 566 connection status 570 connection type 567 example program 556
Index

Q
QAQQINI 546 QDT 425 QRYTIMLMT parameter CHGQRYA (Change Query Attributes) command 381 QSQCHKS 2 QSQLTEMP 335 QSQLTEMP1 335 QSQPRCED 2 package 9 QSYS2 catalog views 6 QSYSPRT listing SQL statement processor example 363 query cancelling 392 Query Denition Template (QDT) 425 query optimizer 395 cost estimation 423 decision-making rules 425 default lter factors 424 optimization goals 423 query optimizer index advisor 482 query options le 546

869

removing all entries from current session 357 Reorganize Physical File Member (RGZPFM) command effect on variable-length columns 458 getting rid of deleted rows 399 report produced by sample programs 643 resource optimization 395 restriction FOR UPDATE OF 553 result table 80 resume using CREATE DISTINCT TYPE example 171 retaining cursor positions across program call improving performance 467, 468 all program calls rules 469 Retrieve Message (RTVMSG) command 587 retrieving data from a table. 20 in reverse order 551 row using a cursor 60 SELECT statement result cursor, using 212 RETRN statement ending RPG for AS/400 programs 307 return code 38 handling in general 221 running a program with embedded SQL 347 RETURNS TABLE clause 188, 190, 192 reuse deleted records INSERT 33 Revoke Object Authority (RVKOBJAUT) command 365 REVOKE PACKAGE statement 555 REXX 2 coding SQL statements 325, 332 SQL statements in sample 640 ROLLBACK prepared statements 201 rollback rollback required state 572 ROLLBACK statement 559 row denition 3, 6 delete current 61 inserting multiple into a table 69 note 70 preventing duplicate 71 ROWS, INSERT n improving performance 463 RPG 297, 309 RPG for AS/400 program 309 /COPY statement 299, 302 character host variables 300 coding SQL statements 297, 307 comment 299 compiler parameters 340

RPG for AS/400 program 299 (continued) continuation 299 dynamic SQL coding 298 ending using LR indicator 307 using RETRN statement 307 error and warning message during a compile 344 external le description 302 host structure array, declaring 301 declaring 300 host variable 300 character 303 declaring 300 externally described 302 numeric 303 including code 299 indicator structure 306 indicator variable 306 naming convention 299 occurrence data structure 301 sequence numbers 299 SQL data types determining equivalent RPG 303 SQL statements in sample 628 SQLCA placement 297 statement label 300 structure parameter passing 307 using the SQLDA 298 WHENEVER statement 300 RRN scalar function 77 rule host variable, using 218 retaining cursor positions program calls 469 rule 216, 218 SQL with host language, using 215 rules that govern operations on large objects 145 run mode interactive SQL 353 Run SQL Statements (RUNSQLSTM) command 1 run-time support concepts 1 running dynamic SQL application 199 program with embedded SQL DDM consideration 346 instruction 346 override consideration 346 return code 347 programs 346 RUNSQLSTM (Run SQL Statements) 357, 358 command 1, 361 command errors 362 commitment control 362 RUNSQLSTM (Run SQL Statements) command 794 RUW (remote unit of work) 555

S
sales using CREATE TABLE example 171

870

DB2 UDB for AS/400 SQL Programming V4R4

sample programs DB2 UDB for AS/400 statements, using 605 distributed RUW program 556 report 643 SQL statements in COBOL 613 ILE C 606 ILE COBOL 613 ILE RPG for AS/400 program 634 PL/I 621 REXX 640 RPG for AS/400 628 sample tables DB2 UDB for AS/400 579 save/restore 375 packages 560 saved session in a source le 357, 358 recovering 358 scalar functions 159 schedule table class 585 schema-name and UDFs 158 schemas SQL statement processor 362 scratchpad, passing to UDF 190 scrollable cursor 55 search condition denition 38 performing complex 72 subqueries 85 using keyword in 72 security 365 authorization 380 authorization ID 366 commitment control 369 data integrity 366 concurrency 367 public authority 365 view 366 SELECT clause 38 select information into host variables 36 SELECT INTO statement column value 216 restriction 199 retrieving row 35 SELECT statement denition 20 example of allocating storage for SQLDA 208 processing and using SQLDA 201 using effectively to improve performance 464 using xed-list 201 using varying-list 202 selecting column 70 data from multiple tables 442 semantic behavior of stored objects 145 Send Program Message (SNDPGMMSG) command 587 Send User Message (SNDUSRMSG) command 587

sensitivity immediate 63, 67 sequence numbers COBOL 254 ILE RPG for AS/400 program 312 RPG for AS/400 program 299 sequential access path 396 serial cursor 55 service program Integrated Language Environment (ILE) object 12 services, session 356 session 358 printing current 357 removing all entries from current 357 saving in a source le 357, 358 session services in interactive SQL 349, 356, 357 SET clause description 33 value column name 33 constant 33 expression 33 host variable 33 null 33 scalar subselect 34 special register 33 SET CONNECTION statement 555, 559 SET CURRENT FUNCTION PATH statement SET TRANSACTION statement effect on implicit disconnect 565 not allowed in package 558 setting query time limit 394 SEU (source entry utility) 358 SIGNAL ON ERROR in REXX 329 SIGNAL ON FAILURE in REXX 329 signature, two functions and the same 158 SMALLINT 188, 192 solving 551 common database problem 551 solving common problems 551 SOME 86 sort sequence CREATE INDEX 53 used with ORDER BY 50 used with record selection 50 using 50 using indexes 449 views 53 source entry utility (SEU) 358 source le CCSID 334 containing DBCS constants 334 for RUNSQLSTM 361 include les 334 input to precompiler 334 margins 334 member, output denition 11

160

Index

871

source le (continued) member, temporary output from precompiler 335 member, user 11 multiple source in COBOL 255 saving a session in 357, 358 temporary for precompile 335 sourced UDF 174 special register CURRENT DATE 45 CURRENT SERVER 45 CURRENT TIME 45 CURRENT TIMESTAMP 45 CURRENT TIMEZONE 45 denition 40 SET clause, value 33 USER 45 specic-name, passing to UDF 189 specifying column, SELECT INTO statement 38 UNION ALL 83 SQL 1 call level interface 2 introduction 1 object 5 statements COBOL 613 ILE COBOL 613 ILE RPG for AS/400 program 634 PL/I 606, 621 REXX 640 RPG for AS/400 628 types 4 using host variable 215 using with host language, concepts and rules SQL-argument, passing to UDF 190, 191 SQL-argument 188 SQL-argument-ind, passing to UDF 188 SQL-argument-ind-array, passing to UDF 191 SQL blocking improving performance 462 SQL data types determining equivalent C 246 C++ 246 COBOL 274 FORTRAN 842 ILE RPG for AS/400 318 PL/I 292 REXX 330 RPG for AS/400 303 SQL_FILE_READ, input value option 152 SQL information summary record 494, 526 SQL naming convention 4 SQL package 3 SQL-result, passing to UDF 190, 192 SQL-result 188 SQL-result-ind, passing to UDF 188, 192 SQL-state, passing to UDF 188

215

SQL statement processor commitment control 362 example QSYSPRT listing 363 schemas 362 using 361 SQLCA (SQL communication area) C 225 C++ 225 COBOL 251 FORTRAN 837 ILE RPG for AS/400 309 PL/I 279 REXX 325 RPG for AS/400 297 SQLCOD FORTRAN 837 SQLCODE C 225 C++ 225 COBOL 251 FORTRAN 837 in REXX 325 PL/I 279 SQLCODEs denition 221, 587 description 589 negative 591 positive 589 testing application program 380 SQLD 204 SQLD eld of SQLDA in REXX 326 SQLDA (SQL descriptor area) allocating storage for 208 C 226 C++ 226 COBOL 252 format 204 FORTRAN 838 ILE RPG for AS/400 310 PL/I 280 processing SELECT statement 201 programming language, use in 203 REXX 325 RPG for AS/400 298 SELECT statement for allocating storage for SQLDA 208 SQLDABC 204 SQLDAID 204 SQLDATA 206 SQLDATA eld of SQLDA in REXX 327 SQLERRD eld of SQLCA 325 SQLERRD(3) eld of SQLCA determining connection status 570 determining number of rows fetched 63 SQLERRD(4) eld of SQLCA 570 determining connection type 567 determining length of each row retrieved 63

872

DB2 UDB for AS/400 SQL Programming V4R4

SQLERRD eld of SQLCA 570 (continued) SQLERRD(5) eld of SQLCA determining end-of-le 63 SQLERRMC eld of SQLCA 325 SQLERROR statement WHENEVER 221 SQLERRP eld of SQLCA 325 SQLIND 206 SQLIND eld of SQLDA in REXX 327 SQLLEN 204 SQLLEN eld of SQLDA in REXX 326 SQLN 204 SQLNAME 206 SQLNAME eld of SQLDA in REXX 326 SQLPRECISION eld of SQLDA 326 SQLRES 206 SQLSCALE eld of SQLDA 327 SQLSTA FORTRAN 837 SQLSTATE C 225 C++ 225 COBOL 251 FORTRAN 837 in REXX 325 PL/I 279 SQLSTATEs code denition 587 denition 221, 587 description 589 testing application program 380 SQLTYPE 204 SQLTYPE eld of SQLDA in REXX 326 sqludf.h include le for UDFs 190 SQLVAR 204 SQLWARN eld of SQLCA 325 Start Commitment Control (STRCMTCTL) command 370 Start Database Monitor (STRDBMON) command 479 Start Journal Access Path (STRJRNAP) command 376 Start SQL (STRSQL) command 801 starting interactive SQL 350 statement entry 349, 351 statement label COBOL 255 in C 229 in C++ 229 requirements for FORTRAN program 840 requirements for ILE RPG for AS/400 312 RPG for AS/400 300 statement-name in DESCRIBE in REXX 325 statement processing mode interactive SQL 353 statements 45, 221, 606, 613, 621, 628, 634, 640

statements 48, 221, 606, 613, 621, 628, 634, 640 (continued) ALIAS statement example 48 basic, using 31 COMMENT ON statement 49 COMMIT 6 CONNECT 555 CREATE COLLECTION 13 CREATE INDEX sort sequence 53 CREATE PROCEDURE external procedure 117 SQL procedure 117 CREATE SCHEMA 362 CREATE TABLE 14 CREATE VIEW 29 data denition (DDL) 4 data manipulation (DML) 4 date value 47 DECLARE CURSOR 36 DELETE example 34 WHERE clause 28 DISCONNECT 555 DROP PACKAGE 555 dynamic 4 EXECUTE 199, 200 FETCH 212 FOR n ROWS 462 multiple-row 62 number of calls 462 GRANT PACKAGE 555 host variable in SQL, using 215 INSERT assignment operation 216 n ROWS 463 using 31 LABEL ON statement example 48 examples 16 multiple-row FETCH 64 OPEN 213 package not required 559 packages 558 PREPARE cursor 213 improving performance 470 non-SELECT statement 200 using 199 preparing and running a program with 333 processing non select 199 RELEASE 555 REVOKE PACKAGE 555 ROLLBACK 6 sample programs 605 select 20 SELECT INTO column value 216 example 35 processing data (view) 36
Index

873

statements 216, 221, 606, 613, 621, 628, 634, 640 (continued) restriction 48 specifying column 38 SET CONNECTION 555 SQL packages 558 testing in application program 379 using interactive SQL 349, 358 time value 47 timestamp value 47 UPDATE assignment operation 216 changing data value 25 example 33 WHENEVER 230, 255, 282, 841 handling exception condition 222 ILE RPG for AS/400 312 RPG for AS/400 300 WHENEVER SQLERROR 221 stopping interactive SQL 357 storage, allocating for SQLDA 208 stored procedures 117, 144 denition 8 parameter passing 128 indicator variables 132 table 128 storing large objects 145 STRDBMON (Start Database Monitor) command 479 STRDBMON/ENDDBMON commands summary record 522 string assignment rule using host variable 217 string search and dening UDFs example 162 string search on BLOBs 162 string search over UDT example 163 strong typing and UDTs 172 STRSQL (Start SQL) command 350, 801 structure parameter passing 473 PL/I 294 RPG for AS/400 307 Structured Query Language 1 structured query language package creating 763 deleting 782 subelds ILE RPG for AS/400 314 RPG for AS/400 300 subquery 88 basic comparison 86 correlated 85, 88 correlated names and references 91 denition 84 examples 84 EXISTS keyword 87 IN keyword 87 notes on using with UPDATE and DELETE 88 prompting 353 quantied comparison 86 search condition 85

subquery processing summary record 517 subselect combining with the UNION keyword, example 80 SET clause, value 34 summary records access plan rebuilt 513 arrival sequence 498 generic query information 520 host variable and ODP implementation 518 index created 505 optimizer timed out 515 query sort 508 SQL information 494, 526 STRDBMON/ENDDBMON commands 522 subquery processing 517 table locked 511 temporary le 509 using existing index 502, 530, 531, 533, 535, 536, 537, 538, 539 Symmetric Multiprocessing 2 symmetrical multiprocessing 397 sync point manager 567 syntax check QSQCHKS 2 syntax check mode interactive SQL 353 syntax for referring to functions 165 system naming convention 3 system table name 17

T
table adding data to the end 552 changing denition 93, 554 changing information in 25 CL_SCHED (class schedule) 585 CORPDATA.DEPARTMENT (department) 579 CORPDATA.EMP_ACT (employee to project activity) 581 CORPDATA.EMPLOYEE 580 CORPDATA.PROJECT (project) 584 creating CREATE TABLE statement 14 view 29 data management methods 420 DB2 UDB for AS/400 sample 579 dening name 48 denition 3, 6 deleting information in 28 establishing position at the end 551 getting catalog information about column 97 getting information from multiple 23 from one 20 IN_TRAY 585 inserting information into 18 multiple rows into 69 joining 75

874

DB2 UDB for AS/400 SQL Programming V4R4

table (continued) the WHERE clause 552 multiple creating view over 30 improving performance when selecting data from 442 sample 579 used in examples CORPDATA.DEPARTMENT (department) 579 CORPDATA.EMP_ACT (employee to project activity) 581 CORPDATA.EMPLOYEE 580 CORPDATA.PROJECT (project) 584 using 14 table functions 159 contents of call-type argument 190 table locked summary record 511 table name system 17 table scans output for all queries 484 output for SQL queries 483 TAG statement ILE RPG for AS/400 312 RPG for AS/400 300 technique coding 31, 55, 69 solving database problem 551 temporary le summary record 509 temporary keyed access path 435, 436 temporary source le member output from precompiler 335 terminology interactive SQL 3 relational database 3 relationship table *SQL 3 *SYS 3 testing authorization 379, 380 debugging your program 380 input data 379 performance verication 381 SQL statements using interactive SQL 349, 358 statements in application program 379 view 379 time assignment rule host variable, using 218 time format 47 specifying current value 47 timestamp assignment rule host variable, using 218 timestamp format 47 specifying current value 47 TIMFMT ILE RPG for AS/400 313, 317 TIMSEP ILE RPG for AS/400 313, 317 tolerance, damage 376

tools performance 477 Trace Job (TRCJOB) command 382, 461 transitive closure 436 TRCJOB (Trace Job) command 382 trigger denition 8 event 8 trigger support 111 triggers and DB2 object extensions 145 trigraph C 229 C++ 229 truncation error 36 two-phase commit 567 typing interactive SQL 351

U
UDFs (User-dened functions) and DB2 object extensions 145 casting 169 concepts 158 denition 156 function path 158 function selection algorithm 158 general considerations 168 implementing UDFs 156 inx notation 168 invoking examples of invocations 164 parameter markers in functions 166 qualied function reference 166 unqualied function reference 167 LOB types 168 overloaded function names 158 process of implementation 160 referring to functions 165 registering UDFs 161 examples of registering 161 schema-name and UDFs 158 sourced 174 summary of function references 167 synergy with UDTs and LOBs examples of complex applications 177 type of functions 159 unqualied reference 158 why use UDFs 156 writing your own UDF 185 UDFs and LOB types 168 UDTs (User-dened types) and DB2 object extensions 145 dening a UDT 170 dening tables 171 manipulating examples of 172 resolving unqualied UDTs 171 strong typing 172
Index

875

UDTs (User-dened types) (continued) synergy with UDFs and LOBs examples of complex applications 177 why use UDTs 169 union C 230 C++ 230 UNION ALL, specifying 83 UNION keyword restriction 553 using to combine subselects 80 unique constraint denition 8 unit of work distributed 555 effect on open cursor 68 package creation 560 remote 555 rollback required 572 unit of work boundary package creation 560 unprotected resource 567 unqualied function reference example 167 unqualied reference 158 UPDATE statement assignment operation 216 correlated subquery, using in 91 description 33 WHERE clause 25 updating data as it is retrieved, restrictions 552 committable updates 567 previously retrieved 553 use of UDTs in UNION example 177 user auxiliary storage pool (ASP) 378 user-dened sourced functions on UDTs example user prole authorization ID 3 authorization name 3 user source le member denition 11 USER special register 45 using a copy of the data 464, 465 allow copy data (ALWCPYDTA) 464, 465 blocked insert statement 70 USING clause 210 using close SQL cursor (CLOSQLCSR) 464, 469 cursor example 56 retrieve row 60 date value 47 USING DESCRIPTOR clause 213 using FETCH statement 462 index 96 null value 45 ORDER BY 51

using (continued) parameter markers 462 parameter passing techniques performance improvement 472 record selection 52 sort sequence 50 time value 47 timestamp value 47 Using views 95 using a locator to work with a CLOB value example 148 using existing index summary record 502, 530, 531, 533, 535, 536, 537, 538, 539 using interactive SQL 349 after rst time 356 list selection function 354 prompting 351 statement entry 351 using JOB parameter 394 using qualied function reference example 166 using SQL application programs 395

V
validate mode interactive SQL 353 value default 14, 18 inserting into table or view 31 VALUES clause 31 variable 230, 249 host REXX 330 indicator 219 use of indicator with host structure, example used to set null value 220 variable-length data tips 456 varying-list SELECT statement denition 202 using 202 verication performance 381 view creating 95 CREATE VIEW statement 28 on a table 29 over multiple tables 30 denition 3, 7 limiting access 28 processing data in 36 read-only 96 security 366 sort sequence 53 testing 379 using 95 WITH CASCADED CHECK 108

175

220

876

DB2 UDB for AS/400 SQL Programming V4R4

view (continued) WITH CHECK 95 WITH LOCAL CHECK

109

W
warning test for negative SQLCODEs C++ program 343 C program 343 COBOL program 343, 344 PL/I program 343 RPG program 343, 344 WHENEVER NOT FOUND clause WHENEVER SQLERROR WHENEVER statement C 230 C++ 230 COBOL 255 FORTRAN 841 handling exception condition with ILE RPG for AS/400 312 PL/I 282 REXX, substitute for 329 RPG for AS/400 300 WHERE clause character string 31 constant 39 description 38 example 213 expression in, using 39 joining tables 76 multiple search condition within a NOT keyword 40 WHERE CURRENT OF clause WITH CHECK OPTION 108 6 61 108 WITH CASCADED CHECK OPTION WITH DATA DICTIONARY clause CREATE COLLECTION statement CREATE SCHEMA statement 6 creating data dictionary 6 WITH LOCAL CHECK OPTION working with index 96 109 221 60 221 343 warning message during a compile

222

74

X
X/Open call level interface 2

Index

877

878

DB2 UDB for AS/400 SQL Programming V4R4

Readers Comments Wed Like to Hear from You

AS/400e DB2 UDB for AS/400 SQL Programming Version 4 Publication No. RBAF-Y000-00 Overall, how satised are you with the information in this book? Very Satised h Satised h Neutral h Dissatised h Very Dissatised h

Overall satisfaction

How satised are you that the information in this book is: Very Satised h h h h h h Satised h h h h h h Neutral h h h h h h Dissatised h h h h h h Very Dissatised h h h h h h

Accurate Complete Easy to nd Easy to understand Well organized Applicable to your tasks

Please tell us how we can improve this book:

Thank you for your responses. May we contact you?

h Yes

h No

When you send comments to IBM, you grant IBM a nonexclusive right to use or distribute your comments in any way it believes appropriate without incurring any obligation to you.

Name Company or Organization Phone No.

Address

___________________________________________________________________________________________________

Readers Comments Wed Like to Hear from You


RBAF-Y000-00

Cut or Fold Along Line

Please _ _ _ _ staple Fold and _ _ _ _ _ _ _ _ _ _Fold and_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ do not_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Tape _ _ _ _ _ _ _ _ Tape NO POSTAGE NECESSARY IF MAILED IN THE UNITED STATES

BUSINESS REPLY MAIL


FIRST-CLASS MAIL PERMIT NO. 40 ARMONK, NEW YORK POSTAGE WILL BE PAID BY ADDRESSEE

IBM CORPORATION ATTN DEPT 542 IDCLERK 3605 HWY 52 N ROCHESTER MN 55901-7829

________________________________________________________________________________________ Fold and Tape Please do not staple Fold and Tape

RBAF-Y000-00

Cut or Fold Along Line

Printed in U.S.A.

RBAF-Y000-00

You might also like