ibm db2 9.7 for linux, unix, and windows

481
IBM DB2 9.7 for Linux, UNIX, and Windows SQL Procedural Languages: Application Enablement and Support Updated November, 2009 Version 9 Release 7 SC27-2470-01

Upload: syasminbanu

Post on 18-Nov-2014

1.776 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: IBM DB2 9.7 for Linux, UNIX, And Windows

IBM DB2 9.7for Linux, UNIX, and Windows

SQL Procedural Languages: Application Enablement and SupportUpdated November, 2009

Version 9 Release 7

SC27-2470-01

���

Page 2: IBM DB2 9.7 for Linux, UNIX, And Windows
Page 3: IBM DB2 9.7 for Linux, UNIX, And Windows

IBM DB2 9.7for Linux, UNIX, and Windows

SQL Procedural Languages: Application Enablement and SupportUpdated November, 2009

Version 9 Release 7

SC27-2470-01

���

Page 4: IBM DB2 9.7 for Linux, UNIX, And Windows

NoteBefore using this information and the product it supports, read the general information under Appendix B, “Notices,” onpage 455.

Edition Notice

This document contains proprietary information of IBM. It is provided under a license agreement and is protectedby copyright law. The information contained in this publication does not include any product warranties, and anystatements provided in this manual should not be interpreted as such.

You can order IBM publications online or through your local IBM representative.v To order publications online, go to the IBM Publications Center at www.ibm.com/shop/publications/order

v To find your local IBM representative, go to the IBM Directory of Worldwide Contacts at www.ibm.com/planetwide

To order DB2 publications from DB2 Marketing and Sales in the United States or Canada, call 1-800-IBM-4YOU(426-4968).

When you send information to IBM, you grant IBM a nonexclusive right to use or distribute the information in anyway it believes appropriate without incurring any obligation to you.

© Copyright International Business Machines Corporation 1993, 2009.US Government Users Restricted Rights – Use, duplication or disclosure restricted by GSA ADP Schedule Contractwith IBM Corp.

Page 5: IBM DB2 9.7 for Linux, UNIX, And Windows

Contents

Part 1. SQL Procedural Language(SQL PL) . . . . . . . . . . . . . . 1

Chapter 1. Inline SQL PL . . . . . . . 3

Chapter 2. SQL PL in SQL procedures. . 5

Chapter 3. Inline SQL PL and SQLfunctions, triggers, and compound SQLstatements . . . . . . . . . . . . . 7

Chapter 4. SQL PL data types . . . . . 9Anchored data type . . . . . . . . . . . . 9

Features of the anchored data type . . . . . . 9Restrictions on the anchored data type . . . . 10Anchored data type variables . . . . . . . 10Declaring local variables of the anchored datatype . . . . . . . . . . . . . . . . 10Examples: Anchored data type use . . . . . 11

Row types . . . . . . . . . . . . . . . 13Features of the row data type . . . . . . . 13Restrictions on the row data type . . . . . . 13Row variables . . . . . . . . . . . . 14Creating row variables. . . . . . . . . . 14Assigning values to row variables . . . . . . 16Comparing row variables and row field values 18Referencing row values . . . . . . . . . 19Passing rows as routine parameters . . . . . 21Dropping a row data type . . . . . . . . 21Examples: Row data type use . . . . . . . 21

Array types . . . . . . . . . . . . . . 28Comparison of arrays and associative arrays . . 28Ordinary array data type . . . . . . . . . 29Associative array data type . . . . . . . . 40

Cursor types . . . . . . . . . . . . . . 44Overview of cursor data types . . . . . . . 45Cursor variables . . . . . . . . . . . . 47Cursor predicates . . . . . . . . . . . 47Creating cursor variables . . . . . . . . . 49Assigning values to cursor variables . . . . . 51Referencing cursor variables . . . . . . . . 52Determining the number of fetched rows for acursor . . . . . . . . . . . . . . . 53Example: Cursor variable use . . . . . . . 54

Boolean data type . . . . . . . . . . . . 57Restrictions on the Boolean data type. . . . . 57

Chapter 5. SQL routines . . . . . . . 59Overview of SQL routines . . . . . . . . . 59

CREATE statements for SQL routines . . . . . 59Determining when to use SQL routines orexternal routines. . . . . . . . . . . . 60

Determining when to use SQL procedures orSQL functions . . . . . . . . . . . . 61Determining when to use SQL routines ordynamically prepared compound SQL statements 62Rewriting SQL procedures as SQL user-definedfunctions . . . . . . . . . . . . . . 63

SQL procedures . . . . . . . . . . . . . 65Features of SQL procedures . . . . . . . . 65Designing SQL procedures . . . . . . . . 66Creating SQL procedures . . . . . . . . . 89Improving the performance of SQL procedures 92

SQL functions . . . . . . . . . . . . . 97Features of SQL functions . . . . . . . . 97Designing SQL functions . . . . . . . . . 98Creating SQL scalar functions . . . . . . . 99Creating SQL table functions . . . . . . . 101

Chapter 6. Compound statements . . 103Restrictions on compound statements . . . . . 103Creating compound statements . . . . . . . 104

Part 2. PL/SQL support . . . . . . 105

Chapter 7. PL/SQL features . . . . . 107

Chapter 8. Creating PL/SQLprocedures and functions from a CLPscript . . . . . . . . . . . . . . . 109

Chapter 9. Restrictions on PL/SQLsupport . . . . . . . . . . . . . . 111

Chapter 10. PL/SQL sample schema 113

Chapter 11. Blocks (PL/SQL) . . . . . 121Anonymous block statement (PL/SQL) . . . . . 121

Chapter 12. Procedures (PL/SQL) . . . 125CREATE PROCEDURE statement (PL/SQL) . . . 125Procedure references (PL/SQL) . . . . . . . 127Function invocation syntax support (PL/SQL) . . 128

Chapter 13. Functions (PL/SQL) . . . 131CREATE FUNCTION statement (PL/SQL) . . . 131Function references (PL/SQL) . . . . . . . . 133

Chapter 14. Collections (PL/SQL) . . . 135VARRAY collection type declaration (PL/SQL) . . 135CREATE TYPE (VARRAY) statement (PL/SQL) . . 136Associative arrays (PL/SQL) . . . . . . . . 137Collection methods (PL/SQL) . . . . . . . . 141

© Copyright IBM Corp. 1993, 2009 iii

Page 6: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 15. Variables (PL/SQL) . . . . 147Variable declarations (PL/SQL) . . . . . . . 147Parameter modes (PL/SQL) . . . . . . . . 148Data types (PL/SQL) . . . . . . . . . . . 149%TYPE attribute in variable declarations (PL/SQL) 152Record variables based on user-defined recordtypes (PL/SQL) . . . . . . . . . . . . 154%ROWTYPE attribute in record type declarations(PL/SQL). . . . . . . . . . . . . . . 155

Chapter 16. Basic statements(PL/SQL) . . . . . . . . . . . . . 157NULL statement (PL/SQL) . . . . . . . . . 157Assignment statement (PL/SQL) . . . . . . . 157EXECUTE IMMEDIATE statement (PL/SQL) . . . 158SQL statements (PL/SQL) . . . . . . . . . 161BULK COLLECT INTO clause (PL/SQL) . . . . 162RETURNING INTO clause (PL/SQL) . . . . . 163Statement attributes (PL/SQL). . . . . . . . 165

Chapter 17. Control statements(PL/SQL) . . . . . . . . . . . . . 167IF statement (PL/SQL) . . . . . . . . . . 167CASE statement (PL/SQL) . . . . . . . . . 171

Simple CASE statement (PL/SQL) . . . . . 171Searched CASE statement (PL/SQL). . . . . 173

Loops (PL/SQL) . . . . . . . . . . . . 174FOR (cursor variant) statement (PL/SQL) . . . 175FOR (integer variant) statement (PL/SQL). . . 175FORALL statement (PL/SQL) . . . . . . . 177EXIT statement (PL/SQL) . . . . . . . . 179LOOP statement (PL/SQL) . . . . . . . . 179WHILE statement (PL/SQL) . . . . . . . 180

Exception handling (PL/SQL) . . . . . . . . 181Raise application error (PL/SQL) . . . . . . . 182RAISE statement (PL/SQL). . . . . . . . . 183Oracle-DB2 error mapping (PL/SQL) . . . . . 184

Chapter 18. Cursors (PL/SQL) . . . . 187Static cursors (PL/SQL) . . . . . . . . . . 187

Parameterized cursors (PL/SQL) . . . . . . 187Opening a cursor (PL/SQL) . . . . . . . 188Fetching rows from a cursor (PL/SQL) . . . . 189Closing a cursor (PL/SQL) . . . . . . . . 191Using %ROWTYPE with cursors (PL/SQL) . . 191Cursor attributes (PL/SQL). . . . . . . . 192

Cursor variables (PL/SQL) . . . . . . . . . 193SYS_REFCURSOR cursor variables (PL/SQL) 193User-defined REF CURSOR type variables(PL/SQL). . . . . . . . . . . . . . 194Dynamic queries with cursor variables(PL/SQL). . . . . . . . . . . . . . 194Example: Returning a REF CURSOR from aprocedure (PL/SQL) . . . . . . . . . . 196Example: Modularizing cursor operations(PL/SQL). . . . . . . . . . . . . . 197

Chapter 19. Triggers (PL/SQL) . . . . 201Types of triggers (PL/SQL) . . . . . . . . . 201

Trigger variables (PL/SQL) . . . . . . . . . 201Transactions and exceptions (PL/SQL) . . . . . 201CREATE TRIGGER statement (PL/SQL) . . . . 202Dropping triggers (PL/SQL) . . . . . . . . 204Examples: Triggers (PL/SQL) . . . . . . . . 205

Chapter 20. Packages (PL/SQL) . . . 209Package components (PL/SQL) . . . . . . . 209Creating packages (PL/SQL) . . . . . . . . 209

Creating package specifications (PL/SQL) . . . 209CREATE PACKAGE statement (PL/SQL) . . . 210Creating the package body (PL/SQL) . . . . 211CREATE PACKAGE BODY statement (PL/SQL) 213

Referencing package objects (PL/SQL) . . . . . 215Packages with user-defined types (PL/SQL) . . 215

Dropping packages (PL/SQL) . . . . . . . . 218

Part 3. System-defined modules 221

Chapter 21. DBMS_ALERT module 223REGISTER procedure - Register to receive aspecified alert . . . . . . . . . . . . . 224REMOVE procedure - Remove registration for aspecified alert . . . . . . . . . . . . . 225REMOVEALL procedure - Remove registration forall alerts . . . . . . . . . . . . . . . 225SET_DEFAULTS - Set the polling interval forWAITONE and WAITANY . . . . . . . . . 226SIGNAL procedure - Signal occurrence of aspecified alert . . . . . . . . . . . . . 226WAITANY procedure - Wait for any registeredalerts . . . . . . . . . . . . . . . . 227WAITONE procedure - Wait for a specified alert 229

Chapter 22. DBMS_JOB module . . . 231BROKEN procedure - Set the state of a job to eitherbroken or not broken . . . . . . . . . . . 232CHANGE procedure - Modify job attributes . . . 233INTERVAL procedure - Set run frequency . . . . 234NEXT_DATE procedure - Set the date and timewhen a job is run . . . . . . . . . . . . 234REMOVE procedure - Delete the job definitionfrom the database . . . . . . . . . . . . 235RUN procedure - Force a broken job to run . . . 235SUBMIT procedure - Create a job definition andstore it in the database . . . . . . . . . . 236WHAT procedure - Change the SQL statement runby a job . . . . . . . . . . . . . . . 237

Chapter 23. DBMS_LOB module . . . 239APPEND procedures - Append one large object toanother . . . . . . . . . . . . . . . 240CLOSE procedures - Close an open large object 240COMPARE function - Compare two large objects 241CONVERTTOBLOB procedure - Convert characterdata to binary . . . . . . . . . . . . . 241CONVERTTOCLOB procedure - Convert binarydata to character . . . . . . . . . . . . 242

iv SQL Procedural Languages: Application Enablement and Support

Page 7: IBM DB2 9.7 for Linux, UNIX, And Windows

COPY procedures - Copy one large object toanother . . . . . . . . . . . . . . . 243ERASE procedures - Erase a portion of a largeobject . . . . . . . . . . . . . . . . 244GET_STORAGE_LIMIT function - Return the limiton the largest allowable large object . . . . . . 245GETLENGTH function - Return the length of thelarge object . . . . . . . . . . . . . . 245INSTR function - Return the location of the nthoccurrence of a given pattern . . . . . . . . 245ISOPEN function - Test if the large object is open 246OPEN procedures - Open a large object . . . . 246READ procedures - Read a portion of a large object 247SUBSTR function - Return a portion of a largeobject . . . . . . . . . . . . . . . . 247TRIM procedures - Truncate a large object to thespecified length . . . . . . . . . . . . 248WRITE procedures - Write data to a large object 248WRITEAPPEND procedures - Append data to theend of a large object . . . . . . . . . . . 249

Chapter 24. DBMS_OUTPUT module 251DISABLE procedure - Disable the message buffer 252ENABLE procedure - Enable the message buffer 252GET_LINE procedure - Get a line from themessage buffer . . . . . . . . . . . . . 253GET_LINES procedure - Get multiple lines fromthe message buffer . . . . . . . . . . . 254NEW_LINE procedure - Put an end-of-linecharacter sequence in the message buffer . . . . 256PUT procedure - Put a partial line in the messagebuffer . . . . . . . . . . . . . . . . 256PUT_LINE procedure - Put a complete line in themessage buffer . . . . . . . . . . . . . 257

Chapter 25. DBMS_PIPE module . . . 259CREATE_PIPE function - Create a pipe . . . . . 261NEXT_ITEM_TYPE function - Return the data typecode of the next item . . . . . . . . . . . 262PACK_MESSAGE function - Put a data item in thelocal message buffer . . . . . . . . . . . 263PACK_MESSAGE_RAW procedure - Put a dataitem of type RAW in the local message buffer . . 264PURGE procedure - Remove unreceived messagesfrom a pipe . . . . . . . . . . . . . . 265RECEIVE_MESSAGE function - Get a messagefrom a specified pipe . . . . . . . . . . . 266REMOVE_PIPE function - Delete a pipe . . . . 268RESET_BUFFER procedure - Reset the localmessage buffer . . . . . . . . . . . . . 269SEND_MESSAGE procedure - Send a message to aspecified pipe . . . . . . . . . . . . . 270UNIQUE_SESSION_NAME function - Return aunique session name . . . . . . . . . . . 271UNPACK_MESSAGE procedures - Get a data itemfrom the local message buffer . . . . . . . . 272

Chapter 26. DBMS_SQL module . . . 275BIND_VARIABLE_BLOB procedure - Bind a BLOBvalue to a variable. . . . . . . . . . . . 278

BIND_VARIABLE_CHAR procedure - Bind aCHAR value to a variable . . . . . . . . . 278BIND_VARIABLE_CLOB procedure - Bind a CLOBvalue to a variable. . . . . . . . . . . . 279BIND_VARIABLE_DATE procedure - Bind a DATEvalue to a variable. . . . . . . . . . . . 279BIND_VARIABLE_DOUBLE procedure - Bind aDOUBLE value to a variable . . . . . . . . 280BIND_VARIABLE_INT procedure - Bind anINTEGER value to a variable . . . . . . . . 280BIND_VARIABLE_NUMBER procedure - Bind aNUMBER value to a variable . . . . . . . . 281BIND_VARIABLE_RAW procedure - Bind a RAWvalue to a variable. . . . . . . . . . . . 281BIND_VARIABLE_TIMESTAMP procedure - Bind aTIMESTAMP value to a variable . . . . . . . 282BIND_VARIABLE_VARCHAR procedure - Bind aVARCHAR value to a variable . . . . . . . 282CLOSE_CURSOR procedure - Close a cursor . . . 283COLUMN_VALUE_BLOB procedure - Return aBLOB column value into a variable . . . . . . 283COLUMN_VALUE_CHAR procedure - Return aCHAR column value into a variable . . . . . . 284COLUMN_VALUE_CLOB procedure - Return aCLOB column value into a variable . . . . . . 284COLUMN_VALUE_DATE procedure - Return aDATE column value into a variable . . . . . . 285COLUMN_VALUE_DOUBLE procedure - Return aDOUBLE column value into a variable . . . . . 286COLUMN_VALUE_INT procedure - Return anINTEGER column value into a variable. . . . . 286COLUMN_VALUE_LONG procedure - Return aLONG column value into a variable . . . . . . 287COLUMN_VALUE_NUMBER procedure - Return aDECFLOAT column value into a variable . . . . 288COLUMN_VALUE_RAW procedure - Return aRAW column value into a variable . . . . . . 288COLUMN_VALUE_TIMESTAMP procedure -Return a TIMESTAMP column value into avariable . . . . . . . . . . . . . . . 289COLUMN_VALUE_VARCHAR procedure - Returna VARCHAR column value into a variable . . . 289DEFINE_COLUMN_BLOB- Define a BLOB columnin the SELECT list . . . . . . . . . . . . 290DEFINE_COLUMN_CHAR procedure - Define aCHAR column in the SELECT list . . . . . . 291DEFINE_COLUMN_CLOB - Define a CLOBcolumn in the SELECT list . . . . . . . . . 291DEFINE_COLUMN_DATE - Define a DATEcolumn in the SELECT list . . . . . . . . . 292DEFINE_COLUMN_DOUBLE - Define a DOUBLEcolumn in the SELECT list . . . . . . . . . 292DEFINE_COLUMN_INT- Define an INTEGERcolumn in the SELECT list . . . . . . . . . 292DEFINE_COLUMN_LONG procedure - Define aLONG column in the SELECT list . . . . . . 293DEFINE_COLUMN_NUMBER procedure - Definea DECFLOAT column in the SELECT list . . . . 293DEFINE_COLUMN_RAW procedure - Define aRAW column or expression in the SELECT list . . 294

Contents v

Page 8: IBM DB2 9.7 for Linux, UNIX, And Windows

DEFINE_COLUMN_TIMESTAMP - Define aTIMESTAMP column in the SELECT list . . . . 294DEFINE_COLUMN_VARCHAR procedure - Definea VARCHAR column in the SELECT list . . . . 295DESCRIBE_COLUMNS procedure - Retrieve adescription of the columns in a SELECT list . . . 295DESCRIBE_COLUMNS2 procedure - Retrieve adescription of column names in a SELECT list . . 299EXECUTE procedure - Run a parsed SQLstatement. . . . . . . . . . . . . . . 300EXECUTE_AND_FETCH procedure - Run a parsedSELECT command and fetch one row . . . . . 301FETCH_ROWS procedure - Retrieve a row from acursor . . . . . . . . . . . . . . . . 304IS_OPEN procedure - Check if a cursor is open . . 305LAST_ROW_COUNT procedure - return thecumulative number of rows fetched . . . . . . 306OPEN_CURSOR procedure - Open a cursor . . . 307PARSE procedure - Parse an SQL statement . . . 308VARIABLE_VALUE_BLOB procedure - Return thevalue of a BLOB INOUT or OUT parameter . . . 310VARIABLE_VALUE_CHAR procedure - Return thevalue of a CHAR INOUT or OUT parameter . . . 311VARIABLE_VALUE_CLOB procedure - Return thevalue of a CLOB INOUT or OUT parameter . . . 311VARIABLE_VALUE_DATE procedure - Return thevalue of a DATE INOUT or OUT parameter . . . 312VARIABLE_VALUE_DOUBLE procedure - Returnthe value of a DOUBLE INOUT or OUT parameter. 312VARIABLE_VALUE_INT procedure - Return thevalue of an INTEGER INOUT or OUT parameter . 313VARIABLE_VALUE_NUMBER procedure - Returnthe value of a DECFLOAT INOUT or OUTparameter . . . . . . . . . . . . . . 313VARIABLE_VALUE_RAW procedure - Return thevalue of a BLOB(32767) INOUT or OUT parameter . 314VARIABLE_VALUE_TIMESTAMP procedure -Return the value of a TIMESTAMP INOUT or OUTparameter . . . . . . . . . . . . . . 314VARIABLE_VALUE_VARCHAR procedure -Return the value of a VARCHAR INOUT or OUTparameter . . . . . . . . . . . . . . 315

Chapter 27. DBMS_UTILITY module 317ANALYZE_DATABASE procedure - Gatherstatistics on tables, clusters, and indexes . . . . 318ANALYZE_PART_OBJECT procedure - Gatherstatistics on a partitioned table or partitioned index 318ANALYZE_SCHEMA procedure - Gather statisticson schema tables, clusters, and indexes . . . . . 320CANONICALIZE procedure - Canonicalize a string 320COMMA_TO_TABLE procedures - Convert acomma-delimited list of names into a table ofnames . . . . . . . . . . . . . . . . 322COMPILE_SCHEMA procedure - Compile allfunctions, procedures, triggers, and packages in aschema . . . . . . . . . . . . . . . 323DB_VERSION procedure - Retrieve the databaseversion . . . . . . . . . . . . . . . 323EXEC_DDL_STATEMENT procedure - Run a DDLstatement. . . . . . . . . . . . . . . 324

GET_CPU_TIME function - Retrieve the currentCPU time. . . . . . . . . . . . . . . 325GET_DEPENDENCY procedure - List objectsdependent on the given object . . . . . . . . 325GET_HASH_VALUE function - Compute a hashvalue for a given string . . . . . . . . . . 326GET_TIME function - Return the current time . . 327NAME_RESOLVE procedure - Obtain the schemaand other membership information for a databaseobject . . . . . . . . . . . . . . . . 328NAME_TOKENIZE procedure - Parse the givenname into its component parts . . . . . . . 332TABLE_TO_COMMA procedures - Convert a tableof names into a comma-delimited list of names . . 334VALIDATE procedure - Change an invalid routineinto a valid routine . . . . . . . . . . . 335

Chapter 28. MONREPORT module . . 337CONNECTION procedure - generate a report onconnection metrics. . . . . . . . . . . . 338CURRENTAPPS procedure - generate a report ofpoint-in-time application processing metrics . . . 339CURRENTSQL procedure - generate a report thatsummarizes activities . . . . . . . . . . . 340DBSUMMARY procedure - generate a summaryreport of system and application performancemetrics . . . . . . . . . . . . . . . 340LOCKWAIT procedure - generate a report ofcurrent lock waits . . . . . . . . . . . . 341PKGCACHE procedure - generate a summaryreport of package cache metrics . . . . . . . 344

Chapter 29. UTL_DIR module . . . . 347CREATE_DIRECTORY procedure - Create adirectory alias . . . . . . . . . . . . . 347CREATE_OR_REPLACE_DIRECTORY procedure -Create or replace a directory alias . . . . . . 348DROP_DIRECTORY procedure - Drop a directoryalias . . . . . . . . . . . . . . . . 349GET_DIRECTORY_PATH procedure - Get the pathfor a directory alias . . . . . . . . . . . 349

Chapter 30. UTL_FILE module . . . . 351FCLOSE procedure - Close an open file . . . . 352FCLOSE_ALL procedure - Close all open files . . 353FCOPY procedure - Copy text from one file toanother . . . . . . . . . . . . . . . 354FFLUSH procedure - Flush unwritten data to a file 355FOPEN function - Open a file . . . . . . . . 356FREMOVE procedure - Remove a file . . . . . 357FRENAME procedure - Rename a file . . . . . 358GET_LINE procedure - Get a line from a file . . . 359IS_OPEN function - Determine whether a specifiedfile is open . . . . . . . . . . . . . . 360NEW_LINE procedure - Write an end-of-linecharacter sequence to a file . . . . . . . . . 361PUT procedure - Write a string to a file . . . . 363PUT_LINE procedure - Write a line of text to a file 364PUTF procedure - Write a formatted string to a file 365UTL_FILE.FILE_TYPE . . . . . . . . . . 366

vi SQL Procedural Languages: Application Enablement and Support

Page 9: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 31. UTL_MAIL module . . . . 369SEND procedure - Send an e-mail to an SMTPserver . . . . . . . . . . . . . . . . 369SEND_ATTACH_RAW procedure - Send an e-mailwith a BLOB attachment to an SMTP server . . . 371SEND_ATTACH_VARCHAR2 procedure - Send ane-mail with a VARCHAR attachment to an SMTPserver . . . . . . . . . . . . . . . . 372

Chapter 32. UTL_SMTP module. . . . 375CLOSE_DATA procedure - End an e-mail message 377COMMAND procedure - Run an SMTP command 377COMMAND_REPLIES procedure - Run an SMTPcommand where multiple reply lines are expected . 378DATA procedure - Specify the body of an e-mailmessage . . . . . . . . . . . . . . . 379EHLO procedure - Perform initial handshakingwith an SMTP server and return extendedinformation . . . . . . . . . . . . . . 379HELO procedure - Perform initial handshakingwith an SMTP server . . . . . . . . . . . 380HELP procedure - Send the HELP command . . . 381MAIL procedure - Start a mail transaction . . . . 381NOOP procedure - Send the null command . . . 382OPEN_CONNECTION function - Return aconnection handle to an SMTP server . . . . . 382OPEN_CONNECTION procedure - Open aconnection to an SMTP server . . . . . . . . 383OPEN_DATA procedure - Send the DATAcommand to the SMTP server . . . . . . . . 384QUIT procedure - Close the session with the SMTPserver . . . . . . . . . . . . . . . . 384RCPT procedure - Provide the e-mail address ofthe recipient . . . . . . . . . . . . . . 385RSET procedure - End the current mail transaction 385VRFY procedure - Validate and verify therecipient’s e-mail address . . . . . . . . . 386WRITE_DATA procedure - Write a portion of ane-mail message . . . . . . . . . . . . . 386WRITE_RAW_DATA procedure - Add RAW data toan e-mail message . . . . . . . . . . . . 387

Part 4. DB2 compatibility features 389

Chapter 33. Introduction to DB2compatibility features . . . . . . . . 391

Chapter 34.DB2_COMPATIBILITY_VECTORregistry variable . . . . . . . . . . 393

Chapter 35. Setting up DB2 for Oracleapplication enablement . . . . . . . 395

Chapter 36. Data types . . . . . . . 397DATE data type based on TIMESTAMP(0). . . . 397NUMBER data type . . . . . . . . . . . 398VARCHAR2 data type . . . . . . . . . . 401

Chapter 37. Character and graphicconstant handling . . . . . . . . . 405

Chapter 38. Outer join operator. . . . 407

Chapter 39. Hierarchical queries . . . 409CONNECT_BY_ROOT unary operator . . . . . 413PRIOR unary operator . . . . . . . . . . 414SYS_CONNECT_BY_PATH . . . . . . . . . 415

Chapter 40. Database configurationparameters . . . . . . . . . . . . 417

Chapter 41. ROWNUM pseudocolumn 419

Chapter 42. DUAL table . . . . . . . 421

Chapter 43. Currently committedsemantics improve concurrency . . . 423

Chapter 44. Oracle datadictionary-compatible views . . . . . 425

Chapter 45. DB2-Oracle terminologymapping . . . . . . . . . . . . . 427

Part 5. DB2CI applicationdevelopment . . . . . . . . . . . 433

Chapter 46. IBM Data Server Driver forDB2CI . . . . . . . . . . . . . . 435

Chapter 47. Building DB2CIapplications . . . . . . . . . . . . 437DB2CI application compile and link options (AIX) 437DB2CI application compile and link options(HP-UX) . . . . . . . . . . . . . . . 438DB2CI application compile and link options(Linux) . . . . . . . . . . . . . . . 440DB2CI application compile and link options(Solaris) . . . . . . . . . . . . . . . 440DB2CI application compile and link options(Windows) . . . . . . . . . . . . . . 441

Part 6. Appendixes . . . . . . . . 443

Appendix A. Overview of the DB2technical information . . . . . . . . 445DB2 technical library in hardcopy or PDF format 445Ordering printed DB2 books . . . . . . . . 448Displaying SQL state help from the command lineprocessor . . . . . . . . . . . . . . . 449Accessing different versions of the DB2Information Center . . . . . . . . . . . 449

Contents vii

Page 10: IBM DB2 9.7 for Linux, UNIX, And Windows

Displaying topics in your preferred language in theDB2 Information Center . . . . . . . . . . 449Updating the DB2 Information Center installed onyour computer or intranet server . . . . . . . 450Manually updating the DB2 Information Centerinstalled on your computer or intranet server . . 451DB2 tutorials . . . . . . . . . . . . . 453

DB2 troubleshooting information . . . . . . . 453Terms and Conditions . . . . . . . . . . 454

Appendix B. Notices . . . . . . . . 455

Index . . . . . . . . . . . . . . . 459

viii SQL Procedural Languages: Application Enablement and Support

Page 11: IBM DB2 9.7 for Linux, UNIX, And Windows

Part 1. SQL Procedural Language (SQL PL)

The SQL Procedural Language (SQL PL) is a language extension of SQL thatconsists of statements and language elements that can be used to implementprocedural logic in SQL statements. SQL PL provides statements for declaringvariables and condition handlers, assigning values to variables, and forimplementing procedural logic.

© Copyright IBM Corp. 1993, 2009 1

Page 12: IBM DB2 9.7 for Linux, UNIX, And Windows

2 SQL Procedural Languages: Application Enablement and Support

Page 13: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 1. Inline SQL PL

Inline SQL PL is a subset of SQL PL features that can be used in compound SQL(inlined) statements. Compound SQL (inlined) statements can be executedindependently or can be used to implement the body of a trigger, SQL function, orSQL method. Compound SQL (inlined) statements can be executed independentlyfrom the DB2® CLP when it is in interactive mode to provide support for a basicSQL scripting language.

Inline SQL PL is described as ″inline″, because the logic is expanded into andexecuted with the SQL statements that reference them.

The following SQL PL statements are considered to be part of the set of inline SQLPL statements:v Variable related statements

– DECLARE <variable>– DECLARE <condition>– SET statement (assignment statement)

v Conditional statements– IF– CASE expression

v Looping statements– FOR– WHILE

v Transfer of control statements– GOTO– ITERATE– LEAVE– RETURN

v Error management statements– SIGNAL– GET DIAGNOSTICS

Other SQL PL statements that are supported in SQL procedures are not supportedin compound SQL (inlined) statements. Cursors and condition handlers are notsupported in inline SQL PL and therefore neither is the RESIGNAL statement.

Because inline SQL PL statements must be executed in compound SQL (inlined)statements, there is no support for PREPARE, EXECUTE, or EXECUTEIMMEDIATE statements.

Also, because ATOMIC must be specified in a compound SQL (inlined) statementthat is dynamically prepared or executed, all or none of the member statementsmust commit successfully. Therefore the COMMIT and ROLLBACK statements arenot supported either.

As for the LOOP and REPEAT statements, the WHILE statement can be used toimplement equivalent logic.

© Copyright IBM Corp. 1993, 2009 3

Page 14: IBM DB2 9.7 for Linux, UNIX, And Windows

Standalone scripting with inline SQL PL consists of executing a compound SQL(inlined) statement that is dynamically prepared or executed within a CommandLine Processor (CLP) script or directly from a CLP prompt. Compound SQL(inlined) statements that are dynamically prepared or executed are bounded by thekeywords BEGIN and END and must end with a non-default terminator character.They can contain SQL PL and other SQL statements.

Because inline SQL PL statements are expanded within the SQL statements thatreference them rather than being individually compiled, there are some minorperformance considerations that should be considered when you are planning onwhether to implement your procedural logic in SQL PL in an SQL procedure orwith inline SQL PL in a function, trigger, or compound SQL (compiled) statementthat is dynamically prepared or executed.

4 SQL Procedural Languages: Application Enablement and Support

Page 15: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 2. SQL PL in SQL procedures

SQL PL statements are primarily used in SQL procedures. SQL procedures cancontain basic SQL statements for querying and modifying data, but they can alsoinclude SQL PL statements for implementing control flow logic around the otherSQL statements. The complete set of SQL PL statements can be used in SQLprocedures.

SQL procedures also support parameters, variables, assignment statements, apowerful condition and error handling mechanism, nested and recursive calls,transaction and savepoint support, and the ability to return multiple result sets tothe procedure caller or a client application.

SQL PL, when used within SQL procedures, allows you to effectively program inSQL. The high-level language of SQL PL and the additional features that SQLprocedures provide makes programming with SQL PL fast and easy to do.

As a simple example of SQL PL statements being used in a SQL procedure,consider the following example:

CREATE PROCEDURE UPDATE_SAL (IN empNum CHAR(6),INOUT rating SMALLINT)

LANGUAGE SQLBEGIN

IF rating = 1 THENUPDATE employee

SET salary = salary * 1.10, bonus = 1000WHERE empno = empNum;

ELSEIF rating = 2 THENUPDATE employee

SET salary = salary * 1.05, bonus = 500WHERE empno = empNum;

ELSEUPDATE employee

SET salary = salary * 1.03, bonus = 0WHERE empno = empNum;

END IF;END

© Copyright IBM Corp. 1993, 2009 5

Page 16: IBM DB2 9.7 for Linux, UNIX, And Windows

6 SQL Procedural Languages: Application Enablement and Support

Page 17: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 3. Inline SQL PL and SQL functions, triggers, andcompound SQL statements

Inline SQL PL statements can be executed in compound SQL (compiled)statements, compound SQL (inlined) statements, SQL functions, and triggers.

A compound SQL (inlined) statement is one that allows you to group multiple SQLstatements into an optionally atomic block in which you can declare variables, andcondition handling elements. These statements are compiled by DB2 as a singleSQL statement and can contain inline SQL PL statements.

The bodies of SQL functions and triggers can contain compound SQL (inlined)statements and can also include some inline SQL PL statements.

On their own, compound SQL (inlined) statements are useful for creating shortscripts that perform small units of logical work with minimal control flow, but thathave significant data flow. Within functions and triggers, they allow for morecomplex logic to be executed when those objects are used.

As an example of a compound SQL (inlined) statement that contains SQL PL,consider the following:

BEGIN ATOMICFOR row AS

SELECT pk, c1, discretize(c1) AS v FROM sourceDO

IF row.v is NULL THENINSERT INTO except VALUES(row.pk, row.c1);

ELSEINSERT INTO target VALUES(row.pk, row.d);

END IF;END FOR;

END

The compound SQL (inlined) statement is bounded by the keywords BEGIN andEND. It includes use of both the FOR and IF/ELSE control-statements that are partof SQL PL. The FOR statement is used to iterate through a defined set of rows. Foreach row a column’s value is checked and conditionally, based on the value, a setof values is inserted into another table.

As an example of a trigger that contains SQL PL, consider the following:CREATE TRIGGER validate_schedNO CASCADE BEFORE INSERT ON c1_schedFOR EACH ROWMODE DB2SQLVs: BEGIN ATOMIC

IF (n.ending IS NULL) THENSET n.ending = n.starting + 1 HOUR;

END IF;

IF (n.ending > '21:00') THENSIGNAL SQLSTATE '80000' SET MESSAGE_TEXT =

'Class ending time is after 9 PM';ELSE IF (n.DAY=1 or n.DAY-7) THEN

© Copyright IBM Corp. 1993, 2009 7

Page 18: IBM DB2 9.7 for Linux, UNIX, And Windows

SIGNAL SQLSTATE '80001' SET MESSAGE_TEXT ='Class cannot be scheduled on a weekend';

END IF;END vs;

This trigger is activated upon an insert to a table named c1_sched and uses SQLPL to check for and provide a class end time if one has not been provided and toraise an error if the class end time is after 9 pm or if the class is scheduled on aweekend. As an example of a scalar SQL function that contains SQL PL, considerthe following:

CREATE FUNCTION GetPrice (Vendor CHAR(20), Pid INT)RETURNS DECIMAL(10,3)LANGUAGE SQL MODIFIES SQLBEGIN

DECLARE price DECIMAL(10,3);

IF Vendor = 'Vendor 1'THEN SET price = (SELECT ProdPrice FROM V1Table WHERE Id = Pid);

ELSE IF Vendor = 'Vendor 2'THEN SET price = (SELECT Price FROM V2Table WHERE Pid = GetPrice.Pid);

END IF;

RETURN price;END

This simple function returns a scalar price value, based on the value of an inputparameter that identifies a vendor. It also uses the IF statement.

For more complex logic that requires output parameters, the passing of result setsor other more advanced procedural elements SQL procedures might be moreappropriate.

8 SQL Procedural Languages: Application Enablement and Support

Page 19: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 4. SQL PL data types

Anchored data typeAn anchored data type is a data type that is defined to be the same as that ofanother object. If the underlying object data type changes, the anchored data typealso changes.

The following topics provide more information about anchored data types:

Features of the anchored data typeAn anchored type defines a data type based on another SQL object such as acolumn, global variable, SQL variable, SQL parameter, or the row of a table orview.

A data type defined using an anchored type definition maintains a dependency onthe object to which it is anchored. Any change in the data type of the anchor objectwill impact the anchored data type. If anchored to the row of a table or view, theanchored data type is ROW with the fields defined by the columns of the anchortable or anchor view.

This data type is useful when declaring variables in cases where you require thatthe variable have the same data type as another object, for example a column in atable, but you do not know exactly what is the data type.

An anchored data type can be of the same type as one of:v a row in a tablev a row in a viewv a cursor variable row definitionv a column in a tablev a column in a viewv a local variable, including a local cursor variable or row variablev a global variable

Anchored data types can only be specified when declaring or creating one of thefollowing:v a local variable in an SQL procedure, including a row variablev a local variable in a compiled SQL function, including a row variablev a routine parameterv a user-defined cursor data type using the CREATE TYPE statement.

– It cannot be referenced in a DECLARE CURSOR statement.v a function return data typev a global variable

To define an anchored data type specify the ANCHOR DATA TYPE TO clause (orthe shorter form ANCHOR clause) to specify what the data type will be. If theanchored data type is a row data type, the ANCHOR ROW OF clause, or one of itssynonyms, must be specified. These clauses are supported within the followingstatements:

© Copyright IBM Corp. 1993, 2009 9

Page 20: IBM DB2 9.7 for Linux, UNIX, And Windows

v DECLAREv CREATE TYPEv CREATE VARIABLE

– In this version, global variables can only be anchored to other globalvariables, a column in a table, or a column in a view.

Restrictions on the anchored data typeReview the restrictions on the use of the anchored data type before declaringvariables of this type or when troubleshooting problems related to their use.

The following restrictions apply to the use of anchored data types:v Anchored data types are not supported in inline SQL functions.v Anchored data types cannot reference nicknames or columns in nicknames.v Anchored data types cannot reference typed tables, columns of typed tables,

typed views, or columns of typed views.v Anchored data types cannot reference declared temporary tables, or columns of

declared temporary tables.v Anchored data types cannot reference row definitions associated with a weakly

typed cursor.v Anchored data types cannot reference objects with a code page or collation that

is different from the database code page or database collation.

Anchored data type variablesAn anchored variable is a local variable or parameter with a data type that is ananchored data type.

Anchored variables are supported in the following contexts:v SQL procedures

– In SQL procedures, parameters and local variables can be specified to be of ananchored data type.

v Compiled SQL functions– SQL functions created using the CREATE FUNCTION statement that specify

the BEGIN clause instead of the BEGIN ATOMIC clause can includeparameter or local variable specification that are of the anchored data type.

v Module variables– Anchored variables can be specified as published or unpublished variables

defined within a module.v Global variables

– Global variables can be created of the anchored data type.

Anchored variables are declared using the DECLARE statement.

Declaring local variables of the anchored data typeDeclaring local variables or parameters of the anchored data type is a task that youwould perform whenever it is necessary that the data type of the variable orparameter remain consistent with the data type of the object to which it isanchored.

Before you begin

The object of the data type that the variable will be anchored to must be defined.

10 SQL Procedural Languages: Application Enablement and Support

Page 21: IBM DB2 9.7 for Linux, UNIX, And Windows

Procedure

1. Formulate a DECLARE statementa. Specify the name of the variable.b. Specify the ANCHOR DATA TYPE TO clause.c. Specify the name of the object that is of the data type that the variable is to

be anchored.2. Execute the DECLARE statement from a supported DB2 interface.

Results

If the DECLARE statement executes successfully, the variable is defined in thedatabase with the specified anchor data type.

Example

The following is an example of an anchored data type declaration in which avariable named v1 is anchored to the data type of a column named c1 in a tablenamed emp:DECLARE v1 ANCHOR DATA TYPE TO emp.c1;

What to do next

Once the variable is defined it can be assigned a value, be referenced, or passed asa parameter to routines.

Examples: Anchored data type useExamples of anchored data type use can be useful as a reference when using thisdata type.

The following topics include examples of anchored data type use:

Example: Variable declarations of anchored data typesExamples of anchored data type declarations can be useful references whendeclaring variables.

The following is an example of a declaration of a variable named v1 that has thesame data type as the column name in table staff:DECLARE v1 ANCHOR DATA TYPE TO staff.name;

The following is an example of a CREATE TYPE statement that defines a typenamed empRow1 that is anchored to a row defined in a table named employee:CREATE TYPE empRow1 AS ROW ANCHOR DATA TYPE TO ROW OF employee;

For variables declared of type empRow1, the field names are the same as the tablecolumn names.

If the data type of the column name is VARCHAR(128), then the variable v1 willalso be of data type VARCHAR(128).

Examples: Anchored data type use in SQL routinesExamples of anchored data type use in SQL routines are useful to reference whencreating your own SQL routines.

Chapter 4. SQL PL data types 11

Page 22: IBM DB2 9.7 for Linux, UNIX, And Windows

The set of examples below demonstrate various features and uses of anchored datatypes in SQL routines. The anchored data type features are demonstrated more sothan the features of the SQL routines that contain them.

The following is an example that demonstrates a declared variable that is anchoredto the data type of a column in a table:CREATE TABLE tab1(col1 INT, col2 CHAR)@

INSERT INTO tab1 VALUES (1,2)@

INSERT INTO tab1 VALUES (3,4)@

CREATE TABLE tab2 (col1a INT, col2a CHAR)@

CREATE PROCEDURE p1()BEGIN

DECLARE var1 ANCHOR tab1.col1;SELECT col1 INTO var1 FROM tab1 WHERE col2 = 2;INSERT INTO tab2 VALUES (var1, 'a');

END@

CALL p1()@

When the procedure p1 is called, the value of the column col1 for a particular rowis selected into the variable var1 of the same type.

The following CLP script includes an example of a function that demonstrates theuse of an anchored data type for a parameter to a function:-- Create a table with multiple columnsCREATE TABLE tt1 (c1 VARCHAR(18), c2 CHAR(8), c3 INT, c4 FLOAT)@

INSERT INTO tt1 VALUES ('aaabbb', 'ab', 1, 1.1)@

INSERT INTO tt1 VALUES ('cccddd', 'cd', 2, 2.2)@

SELECT c1, c2, c3, c4 FROM tt1@

-- Creation of the functionCREATE FUNCTION func_a(p1 ANCHOR tt1.c3)RETURNS INTBEGIN

RETURN p1 + 1;END@

-- Invocation of the functionSELECT c1, c2 FROM tt1 WHERE c3 = func_a(2)@

-- Another invocation of the functionSELECT c1, c2 FROM tt1 WHERE c3 = func_a(1)@

DROP FUNCTION func_a@

DROP TABLE tt1@

12 SQL Procedural Languages: Application Enablement and Support

Page 23: IBM DB2 9.7 for Linux, UNIX, And Windows

When the function func_a is invoked, the function performs a basic operationusing the value of the anchored data type parameter.

Row typesA row data type is a user-defined type containing an ordered sequence of namedfields each with an associated data type.

A row type can be used as the type for global variables, SQL variables, and SQLparameters in SQL PL to provide flexible manipulation of the columns in a row ofdata, typically retrieved using a query.

Features of the row data typeThe features of the row data type make it useful for simplifying SQL PL code.

The row data type is supported for use with the SQL Procedural language only. Itis a structure composed of multiple fields each with their own name and data typethat can be used to store the column values of a row in a result set or othersimilarly formatted data.

This data type can be used to:v Simplify the coding of logic within SQL Procedural Language applications. For

example, database applications process records one at a time and requireparameters and variables to temporarily store records. A single row data typecan replace the multiple parameters and variables required to otherwise processand store the record values. This greatly simplifies the ability to pass row valuesas parameters within applications and routines.

v Facilitate the porting to DB2 SQL PL of code written in other procedural SQLlanguages that support a similar data type.

v Reference row data in data-change statements and queries including: INSERTstatement, FETCH statement, VALUES INTO statement and SELECT INTOstatement.

Row data types must be created using the CREATE TYPE (ROW) statement. Oncecreated, variables of the defined data type can be declared within SQL PL contextsusing the DECLARE statements. These variables can then be used to store valuesof the row type.

Row field values can be explicitly assigned and referenced using single-dot, ″.″notation.

Restrictions on the row data typeIt is important to note the restrictions on the use of the row data type before usingit or when troubleshooting an error that might be related to its use.

The following restrictions apply to the row data type:v The maximum number of fields supported in a row data type is 1012.v The row data type cannot be passed as an input parameter value to procedures

and functions from the CLP.v The row data type cannot be passed as an input-output or output parameter

value from procedures and functions to the CLP.v Row data type variables cannot be directly compared. To compare row type

variables, each field can be compared.

Chapter 4. SQL PL data types 13

Page 24: IBM DB2 9.7 for Linux, UNIX, And Windows

v The following data types are not supported for row fields:– XML data type– LONG VARCHAR– LONG VARGRAPHIC– structured data types– row data types– array data types

v Global variables of type row that contain one or more fields of type LOB are notsupported.

v Use of the CAST function to cast a parameter value to a row data type is notsupported.

Other general restrictions might apply related to the use of a data type,authorizations, execution of SQL, scope of use of the data type or other causes.

Row variablesRow variables are variables based on user-defined row data types. Row variablescan be declared, assigned a value, set to another value, or passed as a parameter toand from SQL procedures. Row variables inherit the properties of the row datatypes upon which they are based. Row variables are used to hold a row of datafrom within a result set or can be assigned other tuple-format data.

Row variables can be declared within SQL procedures using the DECLAREstatement.

Creating row variablesTo create row variables you must first create the row type and then declare therow variable.

The following topics show you how to create the row data type and variable:

Creating a row data typeCreating a row data type is a prerequisite to creating a row variable.

Before you begin

Before you create a row data type:v Read: “Row types” on page 13v Read: “Restrictions on the row data type” on page 13

About this task

This task can be done from any interface that supports the execution of theCREATE TYPE statement.

Procedure

To create a row data type within a database, you must successfully execute theCREATE TYPE (ROW) statement from any DB2 interface that supports theexecution of SQL statements.1. Formulate a CREATE TYPE (ROW) statement:

a. Specify a name for the type.

14 SQL Procedural Languages: Application Enablement and Support

Page 25: IBM DB2 9.7 for Linux, UNIX, And Windows

b. Specify the row field definition for the row by specifying a name and datatype for each field in the row.

The following is an example of how to create a row data type that can beassociated with result sets with the same format as the empRow row data type:CREATE TYPE empRow AS ROW (name VARCHAR(128), id VARCHAR(8));

2. Execute the CREATE TYPE statement from a supported DB2 interface.

Results

If the CREATE TYPE statement executes successfully, the row data type is createdin the database. If the statement does not execute successfully, verify the syntax ofthe statement and verify that the data type does not already exist.

What to do next

Once the row data type is created, row variables can be declared based on thisdata type.

Declaring local variables of type rowVariables of type row can be declared once the row data type has been created.

Before you begin

Before you create a row data type:v Read: “Row types” on page 13v Read: “Restrictions on the row data type” on page 13

About this task

Row data type variables can only be declared in SQL PL contexts including SQLprocedures and functions where execution of the DECLARE statement issupported.

Procedure

The following steps must be followed to declare a local row variable:1. Formulate a declare statement:

a. Specify a name for the variable.b. Specify the row data type that will define the variable. The specified row

data type must be already defined in the database.

The following is an example of how to formulate a DECLARE statement thatdefines a row variable of type empRow:DECLARE r1 empRow;

2. Execute the DECLARE statement within a supported context.

Results

If execution of the DECLARE statement is successful, the row variable is created.

Upon creation of a row variable each field in the row is initialized to a NULLvalue.

The row variable can be assigned values, be referenced, or passed as a parameter.

Chapter 4. SQL PL data types 15

Page 26: IBM DB2 9.7 for Linux, UNIX, And Windows

Assigning values to row variablesValues can be assigned to variables of type row in multiple ways. A row variablevalue can be assigned to another row variable. Variable field values can beassigned and referenced. Field values of a row are referenced by using a single-dot“.” notation.

The following topics show how to assign values to row type variables and arraysof row type variables:

Supported assignments to row data typesA variety of values are supported for assignment to rows and row fields.

When a row variable or parameter is declared, each field in the row has a defaultvalue of NULL until a value is assigned to it.

The following types of values can be assigned to a row variable:v another row variable of the same row data type using the SET statement

– Row variable values can only be assigned to row variables if they are typecompatible. Two row variables are compatible if they are both of the samerow data type or if the source row variable is anchored to a table or viewdefinition. For two variables to be type compatible, it is not sufficient forthem to have the same field names and field data types.For example, if a row data type named row1 is created and another data typenamed row2 is created and they are identical in definition, the value of avariable of type row1 cannot be assigned to the variable of type row2. Norcan the value of the variable of type row2 be assigned to the variable of typerow1. However, the value of variable v1 of type row1 can be assigned to avariable v2 that is also of type row1.

v A tuple with the same number of elements as the row and elements of the samedata types as the fields of the row.– The following is an example of a literal tuple being assigned to a row:

SET v1 = (1, 'abc')

v expression that resolves to a row value– An example of an expression that resolves to a row value that can be

assigned to a row variable is the resolved expression in a VALUES ... INTOstatement. The following is an example of such an assignment:VALUES (1, 'abc') INTO rv1

v the return type of a function (if it is of the same row data type as the targetvariable):– The following is an example where the return type of a function named foo is

of the same row data type as the target variable:SET v1 = foo()

If the return data type is defined as an anchored data type, the anchored datatype assignment rules apply.

v the single row result set of a query– The result set must have the same number of elements as the row and the

columns must be assignable to the same data types as the fields of the row.The following is an example of this type of assignment:SET v1 = (select c1, c2 from T)

v NULL

16 SQL Procedural Languages: Application Enablement and Support

Page 27: IBM DB2 9.7 for Linux, UNIX, And Windows

– When NULL is assigned to a row variable, all the row fields are set to NULLbut the row variable itself remains NOT NULL.

The following types of values can be assigned to a row variable field:v literalv parameterv variablev expressionv NULL

Values can be assigned to row field values in the following ways:v Using the SET statementv Using a SELECT INTO statement that resolves to a row valuev Using a FETCH INTO statement that resolves to a row valuev Using a VALUES INTO statement that resolves to a row value

The ROW data type can be specified as the return-type of an SQL scalar function.

Assigning values to a row variable using the SET statementAssigning values to a row variable can be done using the SET statement. A rowvalue can be assigned to a row variable. A row field value or expression can beassigned to a row field.

Row values can be assigned to row variables using the SET statement if they areboth of the same user-defined row data type.

The following is an example of how to assign a row value to a row variable of thesame format:

SET empRow = newHire;

The row value newHire has the same format as the empRow variable - the numberand types of the row fields are identical:

empRow.lastName /* VARCHAR(128) */empRow.firstName /* VARCHAR(128) */empRow.id /* VARCHAR(10) */empRow.hireDate /* TIMESTAMP */empRow.dept /* VARCHAR(3) */

newHire.lastName /* VARCHAR(128) */newHire.firstName /* VARCHAR(128) */newHire.id /* VARCHAR(10) */newHire.hireDate /* TIMESTAMP */newHire.dept /* VARCHAR(3) */

If you attempt to assign a row value to a variable that does not have an identicalformat an error will be raised.

Row values can be assigned by assigning values to the individual fields in a row.The following is an example of how to assign values to the fields in the rownamed empRow using the SET statement:SET empRow.lastName = 'Brown'; // Literal value assignment

SET empRow.firstName = parmFirstName; // Parameter value of same type assignment

SET empRow.id = var1; // Local variable of same type assignment

Chapter 4. SQL PL data types 17

Page 28: IBM DB2 9.7 for Linux, UNIX, And Windows

SET empRow.hiredate = CURRENT_TIMESTAMP; // Special register expression assignment

SET empRow.dept = NULL; // NULL value assignment

Any supported field assignment can be used to initialize a row value.

Assigning row values to row variables using SELECT, VALUES,or FETCH statementsA row value can be assigned to a variable of type row by using a SELECT INTOstatement, a VALUES INTO statement, or a FETCH INTO statement. The fieldvalues of the source row value must be assignable to the field values of the targetrow variable.

The following is an example of how to assign a single row value to a row variablenamed empRow using a SELECT statement:SELECT * FROM employeeINTO empRowWHERE id=5;

If the select query resolves to more than one row value, an error is raised.

The following is an example of how to assign a row value to a row variable namedempEmpBasics using a VALUES INTO statement:VALUES (5, 'Jane Doe', 10000) INTO empBasics;

The following is an example of how to assign a row value to a row variable namedempRow using a FETCH statement that references a cursor named cur1 thatdefines a row with compatible field values as the variable empRow:FETCH cur1 INTO empRow;

Other variations of use are possible with each of these statements.

Comparing row variables and row field valuesRow variables cannot be directly compared even if they are the same row datatype, however individual row fields can be compared.

Individual fields within a row type can be compared to other values and thecomparison rules for the data type of the field apply.

To compare two row variables, individual corresponding field values must becompared.

The following is an example of a comparison of two row values with compatiblefield definitions in SQL PL:

IF ROW1.field1 = ROW2.field1 ANDROW1.field2 = ROW2.field2 ANDROW1.field3 = ROW2.field3

THENSET EQUAL = 1;

ELSESET EQUAL = 0;

In the example the IF statement is used to perform the procedural logic which setsa local variable EQUAL to 1 if the field values are equal, or 0 if the field values arenot equal.

18 SQL Procedural Languages: Application Enablement and Support

Page 29: IBM DB2 9.7 for Linux, UNIX, And Windows

Referencing row valuesRow values and row field values can be referenced within SQL and SQLstatements.

The following topics demonstrate where and how row values can be referenced:

Referencing row variablesRow variable values can be referenced by name wherever row variable data typereferences are supported.

Supported row variable reference contexts include the following:v Source or target of a SET statementv INSERT statementv Target of SELECT INTO, VALUES INTO, or FETCH statements

The following is an example of a row variable being assigned to another rowvariable with the same definition using the SET statement:

-- Referencing row variables as source andtarget of a SET statement

SET v1 = v2;

The following is an example of row variables being referenced in an INSERTstatement that inserts two rows. The row variables v1 and v2 have a fielddefinition that is type compatible with the column definition of the table that is thetarget of the INSERT statement:

-- Referencing row variables in an INSERT statementINSERT INTO employee VALUES v1, v2;

The following is an example of a row variable being referenced in a FETCHstatement. The row variable empRow has the same column definition as the resultset associated with the cursor c1:-- Referencing row variables in a FETCH statementFETCH c1 INTO empRow;

The following is an example of a row variable named v3 being referenced in aSELECT statement. Two column values in the employee table are being selectedinto the two fields of the variable v3:-- Referencing row variables in a SELECT statementSELECT id, name INTO v3 FROM employee;

Referencing fields in row variablesField values can be referenced in multiple contexts.

A row field value can be referenced wherever a value of the field’s data type ispermitted. The following contexts are supported for referencing row fields:v Wherever a value of the field’s data type is permitted including, but not limited

to:– As the source of an assignment (SET statement)– As the target of an assignment (SET statement)– As the target of SELECT INTO, VALUES INTO, or FETCH INTO statement.

To reference the values of fields in a row variable a single-dot notation is used.Field values are associated with variables as follows:<row-variable-name>.<field-name>

Chapter 4. SQL PL data types 19

Page 30: IBM DB2 9.7 for Linux, UNIX, And Windows

The following is an example of how to access the field id of variable employee:employee.id

Examples of supported references to row variable field values follow.

The following is an example that shows how to assign a literal value to a field inrow variable v1:-- Literal assignment to a row variable fieldSET v1.c1 = 5;

The following example shows how to assign literal and expression values tomultiple row variable fields:-- Literal assignment to fields of row variableSET (emp.id, emp.name) = (v1.c1 + 1, 'James');

The following example shows how to reference field values in an INSERTstatement:-- Field references in an INSERT statementINSERT INTO employeeVALUES(v1.c1, 'Beth'),

(emp.id, emp.name);

The following example shows how to reference field values in an UPDATEstatement:-- Field references in an UPDATE statementUPDATE employeeSET name = 'Susan'WHERE id = v1.c1;

The following example shows how to reference field values in a SELECT INTOstatement:-- Field references in a SELECT INTO statementSELECT employee.firstname INTO v2.c1FROM employeeWHERE name=emp.name;

Referencing row variables in INSERT statementsRow variables can be used in INSERT statements to append or modify an entiretable row.

The following is an example of an INSERT statement that inserts a row into tabledemployee:INSERT INTO employee VALUES empRow;

For the INSERT statement, the number of fields in the row variable must match thenumber of columns in the implicit or explicit target column list.

The INSERT statement shown above inserts into each column in the table, thecorresponding row field value. Thus the INSERT statement above is equivalent tothe following INSERT statement:INSERT INTO employee VALUES (emp.id,

emp.name,emp.salary,emp.phone);

20 SQL Procedural Languages: Application Enablement and Support

Page 31: IBM DB2 9.7 for Linux, UNIX, And Windows

Passing rows as routine parametersRow type values and arrays of row type variables can be passed as parameters toprocedures and functions. Procedures support these data types as IN, OUT, andINOUT parameters.

The following is an example of a procedure that takes a CHAR type as an inputparameter, modifies a field in the output row parameter and then returns.CREATE PROCEDURE p(IN basicChar CHAR, OUT outEmpRow empRow)BEGIN

SET outEmpRow.field2 = basicChar;

END@

The following is an example of a CALL statement that invokes the procedure:CALL p('1', myEmpRow)@

Dropping a row data typeDropping a row data type is done when the row data type is no longer required orwhen you want to reuse the name of an existing row data type.

Before you begin

The following prerequisites must be met before you can drop a row data type:v A connection to the database must be established.v The row data type must exist in the database.

About this task

Dropping a row data type is done when the row data type is no longer required orwhen you want to reuse the name of an existing row data type. Dropping a rowcan be done from any interface that supports the execution of the DROP statement.

Procedure

1. Formulate a DROP statement that specifies the name of the row data type to bedropped.

2. Execute the DROP statement from a supported DB2 interface.

Example

The following is an example of how to drop a row data type named simpleRow.DROP TYPE simpleRow;

What to do next

If the DROP statement executes successfully, the row data type is dropped fromthe database.

Examples: Row data type useExamples of row data type use provide a useful reference for understanding howand when to use the row data type.

The following topics demonstrate how to use the row data type:

Chapter 4. SQL PL data types 21

Page 32: IBM DB2 9.7 for Linux, UNIX, And Windows

Example: Row data type use in a CLP scriptSome basic features of row data types are shown within a DB2 CLP script todemonstrate how row data types are most commonly used.

The following DB2 CLP script demonstrates the use of the row data type and itsrelated operations. It includes demonstrations of:v Creating row data typesv Creating a tablev Creating a procedure that includes:

– Row data type declarations– Inserting values to a type that include some row field values– Updating row values based on a row field value– Selecting values into a row field value– Assigning a row value to a row– Assigning row field values to a parameter

v Calling the procedurev Dropping the row data types and table-- Creating row types

CREATE TYPE row01 AS ROW (c1 INTEGER)@

CREATE TYPE empRow AS ROW (id INTEGER, name VARCHAR(10))@

CREATE TABLE employee (id INTEGER, name VARCHAR(10))@

CREATE procedure proc01 (OUT p0 INTEGER, OUT p1 INTEGER)BEGIN

DECLARE v1, v2 row01;DECLARE emp empRow;

-- Assigning values to row fieldsSET v1.c1 = 5;SET (emp.id, emp.name) = (v1.c1 + 1, 'James');

-- Using row fields in DMLINSERT INTO employeeVALUES (v1.c1, 'Beth'), (emp.id, emp.name);

UPDATE employeeSET name = 'Susan' where id = v1.c1;

-- SELECT INTO a row fieldSELECT id INTO v2.c1FROM employeeWHERE name = emp.name;

-- Row level assignmentSET v1 = v2;

-- Assignment to parametersSET (p0, p1) = (v1.c1, emp.id);

END@

CALL proc01(?, ?)@

SELECT * FROM employee@

DROP procedure proc01@

22 SQL Procedural Languages: Application Enablement and Support

Page 33: IBM DB2 9.7 for Linux, UNIX, And Windows

DROP TABLE employee@

-- Dropping row typesDROP TYPE empRow@

DROP TYPE row01@

This script can be saved and run from a DB2 Command Line by issuing thefollowing:DB2 -td@ -vf <filename>;

The following is the output of running the script:CREATE TYPE row01 AS ROW (c1 INTEGER)DB20000I The SQL command completed successfully.

CREATE TYPE empRow AS ROW (id INTEGER, name VARCHAR(10))DB20000I The SQL command completed successfully.

CREATE TABLE employee (id INTEGER, name VARCHAR(10))DB20000I The SQL command completed successfully.

CREATE procedure proc01 (OUT p0 INTEGER, OUT p1 INTEGER)BEGIN DECLARE v1, v2 row01;DECLARE emp empRow;SET v1.c1 = 5;SET (emp.id, emp.name) = (v1.c1 + 1, 'James');INSERT INTO employee VALUES (v1.c1, 'Beth'), (emp.id, emp.name);UPDATE employee SET name = 'Susan' where id = v1.c1;SELECT id INTO v2.c1 FROM employee WHERE name = emp.name;SET v1 = v2;SET (p0, p1) = (v1.c1, emp.id);

END

DB20000I The SQL command completed successfully.

CALL proc01(?, ?)

Value of output parameters--------------------------Parameter Name : P0Parameter Value : 6

Parameter Name : P1Parameter Value : 6

Return Status = 0

SELECT * FROM employee

ID NAME----------- ----------

5 Susan6 James

2 record(s) selected.

DROP procedure proc01DB20000I The SQL command completed successfully.

DROP TABLE employeeDB20000I The SQL command completed successfully.

DROP TYPE empRowDB20000I The SQL command completed successfully.

Chapter 4. SQL PL data types 23

Page 34: IBM DB2 9.7 for Linux, UNIX, And Windows

DROP TYPE row01DB20000I The SQL command completed successfully.

Example: Row data type use in an SQL procedureThe row data type can be used in SQL procedures to retrieve record data and passit as a parameter.

This topic contains an example of a CLP script that includes the definitions ofmultiple SQL procedures that demonstrate some of the many uses of rows.

The procedure named ADD_EMP takes a row data type as an input parameterwhich it then inserts into a table.

The procedure named NEW_HIRE uses a SET statement to assign values to a rowvariable and passes a row data type value as a parameter in a CALL statement thatinvokes another procedure.

The procedure named FIRE_EMP selects a row of table data into a row variableand inserts row field values into a table.

The following is the CLP script - it is followed by the output of running the scriptfrom the CLP in verbose mode:--#SET TERMINATOR @;CREATE TABLE employee (id INT,

name VARCHAR(10),salary DECIMAL(9,2))@

INSERT INTO employee VALUES (1, 'Mike', 35000),(2, 'Susan', 35000)@

CREATE TABLE former_employee (id INT, name VARCHAR(10))@

CREATE TYPE empRow AS ROW ANCHOR ROW OF employee@CREATE PROCEDURE ADD_EMP (IN newEmp empRow)BEGIN

INSERT INTO employee VALUES newEmp;END@

CREATE PROCEDURE NEW_HIRE (IN newName VARCHAR(10))BEGIN

DECLARE newEmp empRow;DECLARE maxID INT;

-- Find the current maximum ID;SELECT MAX(id) INTO maxID FROM employee;

SET (newEmp.id, newEmp.name, newEmp.salary)= (maxID + 1, newName, 30000);

-- Call a procedure to insert the new employeeCALL ADD_EMP (newEmp);

END@

CREATE PROCEDURE FIRE_EMP (IN empID INT)BEGIN

DECLARE emp empRow;

-- SELECT INTO a row variableSELECT * INTO emp FROM employee WHERE id = empID;

DELETE FROM employee WHERE id = empID;

24 SQL Procedural Languages: Application Enablement and Support

Page 35: IBM DB2 9.7 for Linux, UNIX, And Windows

INSERT INTO former_employee VALUES (emp.id, emp.name);END@

CALL NEW_HIRE('Adam')@

CALL FIRE_EMP(1)@

SELECT * FROM employee@

SELECT * FROM former_employee@

The following is the output of running the script from the CLP in verbose mode:CREATE TABLE employee (id INT, name VARCHAR(10), salary DECIMAL(9,2))DB20000I The SQL command completed successfully.

INSERT INTO employee VALUES (1, 'Mike', 35000), (2, 'Susan', 35000)DB20000I The SQL command completed successfully.

CREATE TABLE former_employee (id INT, name VARCHAR(10))DB20000I The SQL command completed successfully.

CREATE TYPE empRow AS ROW ANCHOR ROW OF employeeDB20000I The SQL command completed successfully.

CREATE PROCEDURE ADD_EMP (IN newEmp empRow)BEGIN

INSERT INTO employee VALUES newEmp;ENDDB20000I The SQL command completed successfully.

CREATE PROCEDURE NEW_HIRE (IN newName VARCHAR(10))BEGIN

DECLARE newEmp empRow;DECLARE maxID INT;

-- Find the current maximum ID;SELECT MAX(id) INTO maxID FROM employee;

SET (newEmp.id, newEmp.name, newEmp.salary) = (maxID + 1, newName, 30000);

-- Call a procedure to insert the new employeeCALL ADD_EMP (newEmp);

ENDDB20000I The SQL command completed successfully.

CREATE PROCEDURE FIRE_EMPLOYEE (IN empID INT)BEGIN

DECLARE emp empRow;

-- SELECT INTO a row variableSELECT * INTO emp FROM employee WHERE id = empID;

DELETE FROM employee WHERE id = empID;

INSERT INTO former_employee VALUES (emp.id, emp.name);ENDDB20000I The SQL command completed successfully.

CALL NEW_HIRE('Adam')

Return Status = 0

CALL FIRE_EMPLOYEE(1)

Return Status = 0

Chapter 4. SQL PL data types 25

Page 36: IBM DB2 9.7 for Linux, UNIX, And Windows

SELECT * FROM employee

ID NAME SALARY----------- ---------- -----------

2 Susan 35000.003 Adam 30000.00

2 record(s) selected.

SELECT * FROM former_employee

ID NAME----------- ----------

1 Mike

1 record(s) selected.

Example: Row data type use in an SQL functionRow data types can be used in SQL functions to construct, store, or modify recorddata.

Variables based on row data types can be used as a simple way to hold a rowvalue that has the same format as a table. When used in this way, it is helpful toinitialize the row variable upon its first use.

The following is an example of a DB2 CLP script that contains SQL statements thatcreate a table, a row data type, and a function that includes the declaration of arow variable, a row reference and an invocation of the UDF:CREATE TABLE t1 (deptNo VARCHAR(3),

reportNo VARCHAR(3),deptName VARCHAR(29),mgrNo VARCHAR (8),location VARCHAR(128))@

INSERT INTO t1 VALUES ('123', 'MM1', 'Sales-1', '0112345', 'Miami')@INSERT INTO t1 VALUES ('456', 'MM2', 'Sales-2', '0221345', 'Chicago')@INSERT INTO t1 VALUES ('789', 'MM3', 'Marketing-1', '0331299', 'Toronto')@

CREATE TYPE deptRow AS ROW (r_deptNo VARCHAR(3),r_reportNo VARCHAR(3),r_depTName VARCHAR(29),r_mgrNo VARCHAR (8),r_location VARCHAR(128))@

CREATE FUNCTION getLocation(theDeptNo VARCHAR(3),reportNo VARCHAR(3),theName VARCHAR(29))

RETURNS VARCHAR(128)BEGIN

-- Declare a row variableDECLARE dept deptRow;

-- Assign values to the fields of the row variableSET dept.r_deptno = theDeptNo;SET dept.r_reportNo = reportNo;SET dept.r_deptname = theName;SET dept.r_mgrno = '';SET dept.r_location = '';

RETURN(SELECT location FROM t1 WHERE deptNo = dept.r_deptno);

26 SQL Procedural Languages: Application Enablement and Support

Page 37: IBM DB2 9.7 for Linux, UNIX, And Windows

END@

VALUES (getLocation ('789', 'MM3','Marketing-1'))@

When executed this CLP script creates a table, inserts rows into the table, creates arow data type, and a UDF.

The function getLocation is an SQL UDF that declares a row variable and assignsvalues to it fields using the input parameter values. It references one of the fieldsin the row variable within the SELECT statement that defines the scalar valuereturned by the function.

When the VALUES statement is executed at the end of the script, the UDF isinvoked and the scalar return value is returned.

The following is the output of running this script from the CLP:CREATE TABLE t1 (deptNo VARCHAR(3), reportNo VARCHAR(3),deptName VARCHAR(29), mgrNo VARCHAR (8), location VARCHAR(128))DB20000I The SQL command completed successfully.

INSERT INTO t1 VALUES ('123', 'MM1', 'Sales-1', '0112345', 'Miami')DB20000I The SQL command completed successfully.

INSERT INTO t1 VALUES ('456', 'MM2', 'Sales-2', '0221345', 'Chicago')DB20000I The SQL command completed successfully.

INSERT INTO t1 VALUES ('789', 'MM3', 'Marketing-1', '0331299', 'Toronto')DB20000I The SQL command completed successfully.

CREATE TYPE deptRow AS ROW (r_deptNo VARCHAR(3), r_reportNo VARCHAR(3), r_depTName VARCHAR(29), r_mgrNo VARCHAR (8), r_location VARCHAR(128))DB20000I The SQL command completed successfully.

CREATE FUNCTION getLocation(theDeptNo VARCHAR(3),reportNo VARCHAR(3),theName VARCHAR(29))

RETURNS VARCHAR(128)BEGIN

DECLARE dept deptRow;SET dept.r_deptno = theDeptNo;SET dept.r_reportNo = reportNo;SET dept.r_deptname = theName;SET dept.r_mgrno = '';SET dept.r_location = '';

RETURN(SELECT location FROM t1 WHERE deptNo = dept.r_deptno);

ENDDB20000I The SQL command completed successfully.

VALUES (getLocation ('789', 'MM3','Marketing-1'))

1

--------------------------------------------------------------------------------------------------------------------------------Toronto

1 record(s) selected.

Chapter 4. SQL PL data types 27

Page 38: IBM DB2 9.7 for Linux, UNIX, And Windows

Array typesAn array type is a user-defined data type consisting of an ordered set of elementsof a single data type.

An ordinary array type has a defined upper bound on the number of elements anduses the ordinal position as the array index.

An associative array type has no specific upper bound on the number of elementsand each element has an associated index value. The data type of the index valuecan be an integer or a character string but is the same data type for the entirearray.

An array type can be used as the type for global variables, SQL variables, and SQLparameters in SQL PL to provide flexible manipulation of a collection of values ofa single data type.

Comparison of arrays and associative arraysSimple arrays and associative arrays differ in multiple ways. Understanding thedifferences can help you to choose the right data type to use.

The following table highlights the differences between arrays and associativearrays:

Table 1. Comparison of arrays and associative arrays

Arrays Associative arrays

The maximum cardinality of a simple array is definedwhen the simple array is defined. When a value isassigned to index N, the elements with indices betweenthe current cardinality of the array and N are implicitlyinitialized to NULL.

There is no user-specified maximum cardinality and noelements are initialized when an associative arrayvariable is declared. The maximum cardinality is limitedby the available free memory.

The index data type for a simple array must be aninteger value.

The index type for an associative array can be one of aset of supported data types.

The index values in a simple array must be a contiguousset of integer values.

In an associative array the index values can be sparse.

The CREATE TYPE statement for a simple array does notrequire the specification of the array cardinality. Forexample, in this statement, no cardinality is specified:

CREATE TYPE simple AS INTEGER ARRAY[];

In the CREATE TYPE statement for an associative array,instead of requiring a specification of the arraycardinality, the index data type is required. For example,in this statement, the cardinality for the index data typeis specified as INTEGER:

CREATE TYPE assoc AS INTEGER ARRAY[INTEGER];

28 SQL Procedural Languages: Application Enablement and Support

Page 39: IBM DB2 9.7 for Linux, UNIX, And Windows

Table 1. Comparison of arrays and associative arrays (continued)

Arrays Associative arrays

A first assignment to a simple array results in theinitialization of array elements with index valuesbetween 1 and the index value assigned to the array. Thefollowing compound SQL (compiled) statement containsthe declaration of a simple array variable and theassignment of a value to the variable:

BEGINDECLARE mySimpleA simple;

SET mySimpleA[100] = 123;

END

After the execution of the assignment statement, thecardinality of mySimpleA is 100; the elements with indiceswith values 1 to 99 are implicitly initialized to NULL.

A first assignment to an associative array results in theinitialization of a single element with a single indexvalue. The following compound SQL (compiled)statement contains the declaration of an associative arrayvariable and the assignment of a value to the variable:

BEGINDECLARE myAssocA assoc;

SET myAssocA[100] = 123;END

After the execution of the assignment statement, thecardinality of the array is 1.

Example

Ordinary array data typeAn ordinary array data type is a structure that contains an ordered collection ofdata elements in which each element can be referenced by its ordinal position inthe collection.

If N is the cardinality (number of elements) in an array, the ordinal positionassociated with each element, called the index, is an integer value greater than orequal to 1 and less than or equal to N. All elements in an array have the same datatype.

Features of the array data typeThe many features of the array data type make it ideal for use in SQL PL logic.

An array type is a data type that is defined as an array of another data type.

Every array type has a maximum cardinality, which is specified on the CREATETYPE statement. If A is an array type with maximum cardinality M, the cardinalityof a value of type A can be any value between 0 and M, inclusive. Unlike themaximum cardinality of arrays in programming languages such as C, themaximum cardinality of SQL arrays is not related to their physical representation.Instead, the maximum cardinality is used by the system at run time to ensure thatsubscripts are within bounds. The amount of memory required to represent anarray value is usually proportional to its cardinality, and not to the maximumcardinality of its type.

When an array is being referenced, all of the values in the array are stored in mainmemory. Therefore, arrays that contain a large amount of data will consume largeamounts of main memory.

Array element values can be retrieved by specifying the element’s correspondingindex value.

Chapter 4. SQL PL data types 29

Page 40: IBM DB2 9.7 for Linux, UNIX, And Windows

Array data types are useful when you want to store a set of values of a single datatype. This set of values can be used to greatly simplify the passing of values toroutines, because a single array value can be passed instead of multiple, possiblynumerous, individual parameters.

Array data types differ from associative array data types. Whereas array data typesare a simple collection of values, associative arrays are conceptually like an arrayof arrays. That is associative arrays are ordered arrays that contain zero or moresubarray elements, such that the array elements are accessed by a primary indexand the subarray elements are accessed by a subindex.

Restrictions on the array data typeIt is important to note the restrictions on the array data type before you use it orwhen troubleshooting problems with their declaration or use.

The following restrictions apply to the array data type:v Use of the array data type in dynamic compound statements is not supported.v Use of the ARRAY_AGG function outside of SQL procedures is not supported.v Use of the UNNEST function outside of SQL procedures is not supported.v Use of parameters of the array data type in external procedures other than Java™

procedures is not supported.v The casting of an array to any data type other than a user-defined arrays data

type is not supported.v The containment of elements of any data type other than that specified for the

array is not supported.v The casting of an array with a cardinality larger than that of the target array is

not supported.v The use of arrays as parameters or return types in methods is not supported.v The use of arrays as parameters or return types in sourced or template functions

is not supported.v The use of arrays as parameters or return types in external scalar or external

table functions is not supported.v The use of arrays as parameters or return types in SQL scalar functions, SQL

table functions, or SQL row functions is not supported.v The assignment or casting of the result value of a TRIM_ARRAY function to any

data type other than an array is not supported.v The assignment or casting of the result value of an ARRAY constructor or an

ARRAY_AGG function to any data type other than an array is not supported.v

Array variablesArray variables are variables based on user-defined array data types. Arrayvariables can be declared, assigned a value, set to another value, or passed as aparameter to and from SQL procedures.

Array variables inherit the properties of the array data types upon which they arebased. Array variables are used to hold a set of data of the same data type.

Local array variables can be declared within SQL procedures using the DECLAREstatement.

Global array variables can be created using the CREATE VARIABLE statement.

30 SQL Procedural Languages: Application Enablement and Support

Page 41: IBM DB2 9.7 for Linux, UNIX, And Windows

Creating array variablesTo create array variables you must first create the array type and then declare thelocal array variable or create the global array variable.

The following topics show you how to create array data types and array variables:

Creating an array data type (CREATE TYPE statement):

Creating an array data type is a task that you would perform as a prerequisite tocreating a variable of the array data type.

Before you begin

Before you create an array data type, ensure that you have the privileges requiredto execute the CREATE TYPE statement.

About this task

Array data types can only be created in SQL PL contexts where execution of theCREATE TYPE statement is supported.

Restrictions

See: “Restrictions on the array data type” on page 30

Procedure

1. Define the CREATE TYPE statementa. Specify a name for the array data type.b. Specify the AS keyword followed by the keyword name for the data type of

the array element. For example, INTEGER, VARCHAR.c. Specify the ARRAY keyword and the domain of the subindices in the array.

For example, if you specify 100, the valid indices will be from 1 to 100. Thisnumber is the same as the cardinality of the array - the number of elementsin the array.

2. Execute the CREATE TYPE statement from a supported interface.

The CREATE type statement should execute successfully and the array type shouldbe created.

Example 1:

CREATE TYPE simpleArray AS INTEGER ARRAY[100];

This array data type can contain up to 100 integer values indexed by integer valuesranging from 1 to 100.Example 2:

CREATE TYPE id_Phone AS VARCHAR(20) ARRAY[100];

This array data type can contain up to 100 phone values stored as VARCHAR(20)data type values indexed by integer values ranging from 1 to 100.

What to do next

After creating the array data type you can declare an array variable.

Chapter 4. SQL PL data types 31

Page 42: IBM DB2 9.7 for Linux, UNIX, And Windows

Declaring local variables of type array:

Declaring array data type variables is a task that you perform after creating arraydata types if you want to be able to temporarily store or pass array data typevalues.

Before you create a local variable of type row:v Read: Array data typesv Read: “Restrictions on the array data type” on page 30v Read: “Creating an array data type (CREATE TYPE statement)” on page 31v Ensure that you have the privileges required to execute the DECLARE

statement.

Declaring array data types can be done in supported contexts including within:SQL procedures, SQL functions, and triggers.1. Define the DECLARE statement.

a. Specify a name for the array data type variable.b. Specify the name of the array data type that you used when you created the

array data type.If the array data type was declared using the following CREATE TYPEstatement:CREATE TYPE simpleArray AS INTEGER ARRAY[10];

You would declare a variable of this data type as follows:DECLARE myArray simpleArray;

If the array data type was declared using the following CREATE TYPEstatement:CREATE TYPE id_Phone AS VARCHAR(20) ARRAY[100];

You would create a variable of this data type as follows:DECLARE id_Phone_Toronto_List id_Phone;

This array can contain up to 100 phone values stored as VARCHAR(20) datatype values indexed by integer values ranging from 1 to 100. The variable nameindicates that the phone values are Toronto phone numbers.

2. Include the DECLARE statement within a supported context. This can bewithin a CREATE PROCEDURE, CREATE FUNCTION, or CREATE TRIGGERstatement.

3. Execute the statement which contains the DECLARE statement.

The statement should execute successfully.

If the statement does not execute successfully due to an error with the DECLAREstatement:v Verify the SQL statement syntax of the DECLARE statement and execute the

statement again.v Verify that no other variable with the same name has already been declared

within the same context.v Verify that the array data type was created successfully.

After declaring associative array variables, you might want to assign values tothem.

32 SQL Procedural Languages: Application Enablement and Support

Page 43: IBM DB2 9.7 for Linux, UNIX, And Windows

Assigning values to arraysValues can be assigned to arrays in multiple ways. The following topics show youhow to assign values to arrays:

Assigning array values using the subindex and literal values:

Values can be assigned to associative arrays using subindices and literal values.v Read: “Ordinary array data type” on page 29v Read: “Restrictions on the array data type” on page 30v Privileges required to execute the SET statement

You would perform this task before performing SQL PL that is conditional on thevariable having an assigned value or before passing the variable as a parameter toa routine.1. Define a SET statement.

a. Specify the array variable name.b. Specify the assignment symbol, ’=″.c. Specify the ARRAY keyword and specify within the required brackets sets

of paired values.2. Execute the SET statement.

The following is an example of how to assign element values to an array named,myArray:SET myArray[1] = 123;SET myArray[2] = 124;...SET myArray[100] = 223;

If the SET statements execute successfully, the array elements have been definedsuccessfully. To validate that the array was created you can attempt to retrievevalues from the array.

If the SET statement failed to execute successfully:v Verify the SQL statement syntax of the SET statement and execute the statement

again.v Verify that the data type was created successfully.

Retrieving array valuesRetrieving array values can be done in multiple ways. The following topics showyou how to retrieve values from arrays:

Retrieving array values using an index:

Retrieving array element values can be done directly by referencing the array andspecifying a sub-index value.

The following are prerequisites to this task:v Read: “Ordinary array data type” on page 29v Read: “Restrictions on the array data type” on page 30v Privileges required to execute the SET statement or any SQL statement that

contains the array reference

Chapter 4. SQL PL data types 33

Page 44: IBM DB2 9.7 for Linux, UNIX, And Windows

You would perform this task within SQL PL code in order to access values storedwithin an array. You might access the array element value as part of an assignment(SET) statement or directly within an expression.1. Define a SET statement.

a. Specify a variable name of the same data type as the array element.b. Specify the assignment symbol, ″=″.c. Specify the name of the array, square brackets, and within the square

brackets an index value.2. Execute the SET statement.

The following is an example of a SET statement that retrieves an array value:SET mylocalVar = myArray[1];

If the SET statement executes successfully, the local variable should contain thearray element value.

If the SET statement failed to execute successfully:v Verify the SQL statement syntax of the SET statement and execute the statement

again.v Verify that the variable is of the same data type as the array element.v Verify that the array was created successfully and currently exists.

Retrieving the number of array elements:

Retrieving the number of array elements in a simple array can most easily be doneby using the CARDINALITY function and retrieving the maximum allowed size ofan array can be done using the MAX_CARDINALITY function.v Read: “Ordinary array data type” on page 29v Read: “Restrictions on the array data type” on page 30v Privileges required to execute the SET statement

You would perform this task within SQL PL code in order to access a count valueof the number of elements in an array. You might access the array element value aspart of an assignment (SET) statement or access the value directly within anexpression.1. Define a SET statement.

a. Declare and specify a variable name of type integer that will hold thecardinality value.

b. Specify the assignment symbol, ‘=’.c. Specify the name of the CARDINALITY or MAX_CARDINALTIY function

and within the required brackets, the name of the array.2. Execute the SET statement.

If the SET statement executes successfully, the local variable should contain thecount value of the number of elements in the array.

The following is an example of two SET statements that demonstrate theseassignments:SET card = CARDINALITY(arrayName);

SET maxcard = MAX_CARDINALITY(arrayName);

34 SQL Procedural Languages: Application Enablement and Support

Page 45: IBM DB2 9.7 for Linux, UNIX, And Windows

If the SET statement failed to execute successfully:v Verify the SQL statement syntax of the SET statement and execute the statement

again.v Verify that the local variable is of the integer data type.v Verify that the array was created successfully and currently exists.

Retrieving the first and last array elements (FIRST, LAST functions):

Retrieving the first and last elements in a simple array can most easily be done byusing the FIRST and LAST functions.v Read: “Ordinary array data type” on page 29v Read: “Restrictions on the array data type” on page 30v Privileges required to execute the SET statement

You would perform this task within SQL PL code in order to quickly access thefirst element in an array.

Define a SET statement:1. Declare and specify a variable that is of the same type as the array element.2. Specify the assignment symbol, ‘=’.3. Specify the name of the FIRST or LAST function and within the required

brackets, the name of the array.

If the SET statement executes successfully, the local variable should contain thevalue of the first or last (as appropriate) index value in the array.

For an array of phone numbers defined as:firstPhone index 0 1 2 3

phone '416-223-2233' '416-933-9333' '416-887-8887' '416-722-7227'

If the following SQL statement is executed:SET firstPhoneIx = FIRST(phones);

The variable firstPhoneIx will have the value 0. This would be true even if theelement value in this position was NULL.

The following SET statement accesses the element value in the first position in thearray:SET firstPhone = A[FIRST(A)]

If the SET statement failed to execute successfully:v Verify the SQL statement syntax of the SET statement and execute the statement

again.v Verify that the local variable is of the correct data type.v Verify that the array was created successfully and currently exists.

Retrieving the next and previous array elements:

Retrieving the next or previous elements in a simple array can most easily be doneby using the PREV and NEXT functions.v Read: “Ordinary array data type” on page 29v Read: “Restrictions on the array data type” on page 30

Chapter 4. SQL PL data types 35

Page 46: IBM DB2 9.7 for Linux, UNIX, And Windows

v Privileges required to execute the SET statement

You would perform this task within SQL PL code in order to quickly access theimmediately adjacent element value in an array.1. Define a SET statement:

a. Declare and specify a variable that is of the same type as the array element.b. Specify the assignment symbol, ‘=’.c. Specify the name of the NEXT or PREV function and within the required

brackets, the name of the array.2. Execute the SET statement.

For an array of phone numbers defined as:firstPhone index 0 1 2 3

phone '416-223-2233' '416-933-9333' '416-887-8887' '416-722-7227'

The following SQL statement sets the variable firstPhone to the value 0..SET firstPhone = FIRST(phones);

The following SQL statement sets the variable nextPhone to the value 1.SET nextPhone = NEXT(phones, firstPhone);

The following SQL statement sets the variable phoneNumber to the value of thephone number at the next position in the array after nextPhone. This is the arrayelement value at index value position 2.SET phoneNumber = phones[NEXT(phones, nextPhone)];

If the SET statement failed to execute successfully:v Verify the SQL statement syntax of the SET statement and execute the statement

again.v Verify that the local variable is of the correct data type.v Verify that the array was created successfully and currently exists.

Trimming the array (TRIM_ARRAY function)Trimming an array is a task that you would perform using the TRIM_ARRAYfunction when you want to remove unnecessary array elements from the end of anarray.v Read: Array data typesv Read: Restrictions on array data typesv Privileges required to execute the SET statement

You would perform this task within SQL PL code in order to quickly remove arrayelements from the end of an array.1. Define a SET statement:

a. Declare and specify an array variable that is of the same type as the arrayto be modified, or re-use the same array variable.

b. Specify the assignment symbol, ‘=’.c. Specify the name of the TRIM_ARRAY function and within the required

brackets, the name of the array and the number of elements to be trimmed.2. Execute the SET statement.

If the SET statement executes successfully, the array phones should contain theupdated value.

36 SQL Procedural Languages: Application Enablement and Support

Page 47: IBM DB2 9.7 for Linux, UNIX, And Windows

For an array of phone numbers defined as:phones index 0 1 2 3

phone '416-223-2233' '416-933-9333' '416-887-8887' '416-722-7227'

After executing the following:SET phones = TRIM_ARRAY ( phones, 2 );

The array, phones, will be defined as:phones index 0 1

phone '416-223-2233' '416-933-9333'

If the SET statement failed to execute successfully:v Verify the SQL statement syntax of the SET statement and execute the statement

again.v Verify that the local variable is of the correct data type.v Verify that the array was created successfully and currently exists.

Deleting an array element (ARRAY_DELETE)Deleting an element permanently from an array can be done using theARRAY_DELETE function.v Read: Array data typesv Read: Restrictions on array data typesv Privileges required to execute the SET statement

You would perform this task within SQL PL code in order to delete an element inan array.1. Define a SET statement:

a. Declare and specify a variable that is of the same type as the array element.b. Specify the assignment symbol, ‘=’.c. Specify the name of the ARRAY_DELETE function and within the required

brackets, the name of the array, and the subindices that define the range ofthe elements to be deleted.

2. Execute the SET statement.

If the SET statement executes successfully, the array phones should contain theupdated value.

For an array of phone numbers defined as:phones index 0 1 2 3

phone '416-223-2233' '416-933-9333' '416-887-8887' '416-722-7227'

After executing the following SQL statement:SET phones = ARRAY_DELETE ( phones, 1, 2 );

The array, phones, will be defined as:phones index 0 3

phone '416-223-2233' '416-722-7227'

If the SET statement failed to execute successfully:v Verify the SQL statement syntax of the SET statement and execute the statement

again.v Verify that the local variable is of the correct data type.

Chapter 4. SQL PL data types 37

Page 48: IBM DB2 9.7 for Linux, UNIX, And Windows

v Verify that the array was created successfully and currently exists.

Determining if an array element existsDetermining if an array element exists and has a value is a task that can be doneusing the ARRAY_EXISTS function.v Read: “Ordinary array data type” on page 29v Read: “Restrictions on the array data type” on page 30v Privileges required to execute the IF statement or any SQL statement in which

the ARRAY_EXISTS function is referenced.

You would perform this task within SQL PL code in order to determine if an arrayelement exists within an array.1. Define an IF statement:

a. Define a condition that includes the ARRAY_EXISTS function.b. Specify the THEN clause and include any logic that you want to have

performed if the condition is true and add any ELSE caluse values youwant.

c. Close the IF statement with the END IF clause.2. Execute the IF statement.

For an array of phone numbers defined as:phones index 0 1 2 3

phone '416-223-2233' '416-933-9333' '416-887-8887' '416-722-7227'

After executing the following, the variable x will be set to 1.IF (ARRAY_EXISTS(phones, 2)) THEN

SET x = 1;END IF;

If the SET statement failed to execute successfully:v Verify the SQL statement syntax of the SET statement and execute the statement

again.v Verify that the local variable is of the correct data type.v Verify that the array was created successfully and currently exists.

Array support in SQL proceduresSQL procedures support parameters and variables of array types. Arrays are aconvenient way of passing transient collections of data between an application anda stored procedure or between two stored procedures.

Within SQL stored procedures, arrays can be manipulated as arrays inconventional programming languages. Furthermore, arrays are integrated withinthe relational model in such a way that data represented as an array can be easilyconverted into a table and data in a table column can be aggregated into an array.The examples below illustrate several operations on arrays. Both examples arecommand line processor (CLP) scripts that use the percentage character (%) as astatement terminator.

Example 1

This example shows two procedures, sub and main. Procedure main creates anarray of 6 integers using an array constructor. It then passes the array to proceduresum, which computes the sum of all the elements in the input array and returns

38 SQL Procedural Languages: Application Enablement and Support

Page 49: IBM DB2 9.7 for Linux, UNIX, And Windows

the result to main. Procedure sum illustrates the use of array subindexing and ofthe CARDINALITY function, which returns the number of elements in an array.create type intArray as integer array[100] %

create procedure sum(in numList intArray, out total integer)begindeclare i, n integer;

set n = CARDINALITY(numList);

set i = 1;set total = 0;

while (i <= n) doset total = total + numList[i];set i = i + 1;end while;

end %

create procedure main(out total integer)begindeclare numList intArray;

set numList = ARRAY[1,2,3,4,5,6];

call sum(numList, total);

end %

Example 2

In this example, we use two array data types (intArray and stringArray), and apersons table with two columns (id and name). Procedure processPersons addsthree additional persons to the table, and returns an array with the person namesthat contain letter ’o’, ordered by id. The ids and name of the three persons to beadded are represented as two arrays (ids and names). These arrays are used asarguments to the UNNEST function, which turns the arrays into a two-columntable, whose elements are then inserted into the persons table. Finally, the last setstatement in the procedure uses the ARRAY_AGG aggregate function to computethe value of the output parameter.create type intArray as integer array[100] %create type stringArray as varchar(10) array[100] %

create table persons (id integer, name varchar(10)) %insert into persons values(2, 'Tom') %insert into persons values(4, 'Jill') %insert into persons values(1, 'Joe') %insert into persons values(3, 'Mary') %

create procedure processPersons(out witho stringArray)begindeclare ids intArray;declare names stringArray;

set ids = ARRAY[5,6,7];set names = ARRAY['Bob', 'Ann', 'Sue'];

insert into persons(id, name)(select T.i, T.n from UNNEST(ids, names) as T(i, n));

Chapter 4. SQL PL data types 39

Page 50: IBM DB2 9.7 for Linux, UNIX, And Windows

set witho = (select array_agg(name order by id)from personswhere name like '%o%');end %

Associative array data typeAn associative array data type is a data type used to represent a generalized arraywith no predefined cardinality. Associative arrays contain an ordered set of zero ormore elements of the same data type, where each element is ordered by and can bereferenced by an index value.

The index values of associative arrays are unique, are of the same data type, anddo not have to be contiguous.

The following topics provide more information about the associative array datatype:

Features of associative arraysThe associative array data type is used to represent associative arrays. It has manyfeatures which contribute to its utility.

The associative array data type supports the following associative array properties:v No predefined cardinality is specified for associative arrays. This enables you to

continue adding elements to the array without concern for a maximum sizewhich is useful if you do not know in advance how many elements willconstitute a set.

v The array index value can be a non integer data type. VARCHAR and INTEGERare supported index values for the associative array index.

v Index values do not have to be contiguous. In contrast to a conventional arraywhich is indexed by position, an associative array is an array that is indexed byvalues of another data type and there are not necessarily index elements for allpossible index values between the lowest and highest. This is useful if forexample you want to create a set that stores names and phone numbers. Pairs ofdata can be added to the set in any order and be sorted using which ever dataitem in the pair is defined as the index.

v The elements in an associative array are sorted in ascending order of indexvalues. The insertion order of elements does not matter.

v Associative array data can be accessed and set using direct references or byusing a set of available scalar functions.

v Associative arrays are supported in SQL PL contexts.v Associative arrays can be used to manage and pass sets of values of the same

kind in the form of a collection instead of having to:– Reduce the data to scalar values and use one-element-at-a-time processing

which can cause network traffic problems.– Use cursors passed as parameters.– Reduce the data into scalar values and reconstitute them as a set using a

VALUES clause.

Restrictions on associative array data typesIt is important to note the restrictions on the array data type before you use it orwhen troubleshooting problems with their declaration or use.

The following restrictions apply to the array data type:

40 SQL Procedural Languages: Application Enablement and Support

Page 51: IBM DB2 9.7 for Linux, UNIX, And Windows

v An associative array can only be declared, created, or referenced in SQL PLcontexts. The following is a list of SQL PL contexts in which this data type canbe used:– Parameter to an SQL function that is defined in a module.– Parameter to an SQL function that is not defined in a module, but that has a

compound SQL (compiled) statement as function body not defined in amodule.

– Return type from an SQL functions that is defined in a module.– Return type from an SQL function that is not defined in a module, but that

has a compound SQL (compiled) statement as function body.– Parameter to an SQL procedure.– Local variable declared in an SQL function that is defined in a module.– Local variable declared in an SQL function that is not defined in a module,

but that has a compound SQL (compiled) statement as function body.– Local variable declared in an SQL procedure.– Local variable declared in a trigger with a compound SQL (compiled)

statement as trigger body.– Expressions in SQL statements within compound compiled (SQL) statements.– Expressions in SQL statements in SQL PL contexts.– Global variable.

Any use outside of one of the above SQL PL contexts is not valid.v Associative arrays cannot be the type of a table column.v NULL is not permitted as an index value.v The maximum size of an associative array is limited by system resources.v Associative arrays can not be input to the TRIM_ARRAY function. Associative

array values cannot be stored in table columns.v The MAX_CARDINALITY function is supported for use with associative arrays,

but always returns null because associative arrays do not have a specifiedmaximum size.

Creating an associative array data typeCreating an associative array data type is a task that you would perform as aprerequisite to creating a variable of the associative array data type. Associativearray data types are created by executing the CREATE TYPE (array) statement.

Ensure you have the privileges required to execute the CREATE TYPE statement.

Associative array data types can only be used in certain contexts.1. Define the CREATE TYPE statement:

a. Specify a name for the associative array data type. A good name is one thatclearly specifies the type of data stored in the array. For example: Productsmight be a good name for an array that contains information aboutproducts where the array index is the product identifier. As anotherexample, the name y_coordinate might be a good name for an array wherethe array index is the x coordinate value in a graph function.

a. Specify the AS keyword followed by the keyword name for the data type ofthe array elements (e.g. INTEGER).

Chapter 4. SQL PL data types 41

Page 52: IBM DB2 9.7 for Linux, UNIX, And Windows

b. Specify the ARRAY keyword. Within the square brackets of the ARRAYclause, specify the data type of the array index. Note: With associativearrays, there is no explicit limit on the number of. elements or on thedomain of the array index values.

2. Execute the CREATE TYPE statement from a supported interface.

Example 1:The following is an example of a CREATE TYPE statement that creates an arraynamed assocArray with 20 elements and a array index of type VARCHAR.CREATE TYPE assocArray AS INTEGER ARRAY[VARCHAR(20)];

Example 2:The following is an example of a basic associative array definition that uses thenames of provinces for indices and where the elements are capital cities:CREATE TYPE capitalsArray AS VARCHAR(12) ARRAY[VARCHAR(16)];

If the statement executes successfully the array data type is created in the databaseand the array data type can be referenced..

After creating the array data type you might want to create an associative arrayvariable.

Declaring associative array variablesDeclaring associative array variables is a task that you perform after creatingassociative array data typeso be able to temporarily store or pass associative arraydata type values. Local variables are declared using the DECLARE statement.Global variables are created using the CREATE VARIABLE statement.v Read: Associative array data typesv Read: Restrictions on associative array data typesv Read: Creating the associative array data typev For global variables, you require the privilege to execute the CREATE

VARIABLE statement. For local variables, no privileges required to execute theDECLARE statement

Associative array variables can be declared and used in supported contexts to storesets of row data.1. Define the DECLARE statement for a local variable or the CREATE TYPE

statement for a global variable:a. Specify a name for the associative array data type.b. Specify the name of the associative array data type that you used when you

created the associative array data type.2. Execute the CREATE TYPE statement from a supported interface.

Example 1:Consider an associative array data type defined as:CREATE TYPE Representative_Location AS VARCHAR(20) ARRAY[VARCHAR(30)];

To declare a variable of this data type you would use the DECLARE statement asfollows:DECLARE RepsByCity Representative_Location;

This array can contain up to the maximum number of associative array elementvalues stored as VARCHAR(20) data type values indexed by unique variable

42 SQL Procedural Languages: Application Enablement and Support

Page 53: IBM DB2 9.7 for Linux, UNIX, And Windows

character data type values. The variable name indicates that a set of names of salesrepresentatives is indexed by the name of the city that they represent. In this array,no two sales representative names can be represented by the same city which is thearray index value.

Example 2:Consider an associative array data type defined to store as element values, thenames of capital cities, where the indices are province names:CREATE TYPE capitalsArray AS VARCHAR(12) ARRAY[VARCHAR(16)];

To create a variable of this data type you would use the CREATE VARIABLEstatement as follows:CREATE VARIABLE capitals capitalsArray;

This array can contain up to the maximum number of associative array elementvalues stored as VARCHAR(20) data type values indexed by unique variablecharacter data type values. The variable name indicates that a set of names of salesrepresentatives is indexed by the name of the city that they represent. In this array,no two sales representative names can be represented by the same city which is thearray index value.

If the DECLARE statement or CREATE VARIABLE statement executes successfully,the array data type will have been defined successfully and can be referenced. Tovalidate that the associative array variables was created you can assign values tothe array or attempt to reference values in the array.

If the DECLARE statement or CREATE VARIABLE statement failed to executesuccessfully, verify the SQL statement syntax of the DECLARE statement andexecute the statement again. See the DECLARE statement.

Assigning values to arrays using subindices and literal valuesOnce an associative array variable has been created or declared, values can beassigned to it. One way of assigning values to associative arrays is by directassignment.v Read: Associative array data typesv Read: Restrictions on associative array data typesv Ensure that an associative array variable is in the current scope of use.

Assigning values to associative array variable elements can be done by using theassignment statement in which the array is named, the index value is specified andthe corresponding element value is assigned.1. Define the assignment statement for an associative array variable.v Specify the variable name, the index value, and the element value.v Specify another associative array variable.

2. Execute the assignment statement from a supported interface.

Example 1:The following is an example of a variable declaration and a series of assignmentstatements that define values in the array:DECLARE capitals capitalsArray;

SET capitals['British Columbia'] = 'Victoria';

Chapter 4. SQL PL data types 43

Page 54: IBM DB2 9.7 for Linux, UNIX, And Windows

SET capitals['Alberta'] = 'Edmonton';SET capitals['Manitoba'] = 'Winnipeg';SET capitals['Ontario'] = 'Toronto';SET capitals['Nova Scotia'] = 'Halifax';

In the capitals array, the array index values are province names and the associatedarray element values are the names of the corresponding capital cities. Associativearrays are sorted in ascending order of index value. The order in which values areassigned to associative array elements does not matter.

Example 2:An associative array variable can also be assigned an associative array variablevalue of the same associative array data type. This can be done using theassignment statement. For example, consider two associative array variables,capitalsA and capitalsB defined as:DECLARE capitalsA capitalsArray;DECLARE capitalsB capitalsArray;

SET capitalsA['British Columbia'] = 'Victoria';SET capitalsA['Alberta'] = 'Edmonton';SET capitalsA['Manitoba'] = 'Winnipeg';SET capitalsA['Ontario'] = 'Toronto';SET capitalsA['Nova Scotia'] = 'Halifax';

The variable capitalsB can be assigned the value of the variable capitalsA byexecuting the following assignment statement:SET capitalsB = capitalsA;

Once executed, capitalsB will have the same value as capitalsA.

If the assignment statement executes successfully, the value has been successfullyassigned and the new variable value can be referenced.

If the statement failed to execute successfully, verify and correct the SQL statementsyntax and verify that the variables named are defined before executing thestatement again.

Cursor typesA cursor type can be the built-in data type CURSOR or a user-defined type that isbased on the built-in CURSOR data type. A user-defined cursor type can also bedefined with a specific row type to restrict the attributes of the result row of theassociated cursor.

When a cursor type is associated with a row data structure (specified by a row), itis called a strongly typed cursor. Only result sets that match the definition can beassigned to and stored in a variable of a strongly typed cursor data type. When noresult set definition is associated with a cursor data type definition, the cursor datatype is said to be weakly typed. Any result set can be stored in a variable of aweakly typed cursor data type.

The cursor data type is only supported for use with SQL PL. It is primarily used tocreate cursor type definitions that can be used for cursor variable declarations.

This data type can be used to:v Define cursor variable declarations.

44 SQL Procedural Languages: Application Enablement and Support

Page 55: IBM DB2 9.7 for Linux, UNIX, And Windows

v Simplify the coding of logic within SQL Procedural Language applications. Forexample, database applications process sets of records called result sets and insome cases the same result set might need to be referenced and processed indifferent contexts. Passing defined result sets between interfaces can requirecomplex logic. A cursor data type permits the creation of cursor variables whichcan be used to store result sets, process result sets, and pass result sets asparameters.

v Facilitate the porting to DB2 SQL PL of code which has a similar data type.

Cursor data types must be created using the CREATE TYPE statement. Once this isdone variables of this data type can be declared and referenced. Cursor variablescan be assigned a row data structure definition, opened, closed, assigned a set ofrows from another cursor variable, or be passed as a parameter from SQLprocedures.

Overview of cursor data typesThis overview of cursor data types introduces the types of cursor data types, thescope in which they can be used, as well as provides information about therestrictions and privileges that pertain to their use.

Types of cursor data typesThere are two main types of cursor data types: weakly-typed cursor data types andstrongly-typed cursor data types. The property of being strongly or weakly typedis defined when the data type is created. This property is maintained in variablescreated of each type.

The characteristics of strongly-typed cursor data types and weakly typed cursordata types are provided here:

Strongly-typed cursor data typesA strongly-typed cursor data type is one that is created with a result setdefinition specified by a row data structure. These data types are calledstrongly typed, because when result set values are assigned to them thedata types of the result sets can be checked. Cursor data type result setdefinitions can be defined by providing a row type definition. Only resultsets that match the definition can be assigned to and stored in a stronglytyped cursor data type. Strong type checking is performed at assignmenttime and if there are any data type mismatches, an error is raised.

Result set definitions for strongly-typed cursor data types can be providedby a row data type definition or an SQL statement definition.

The following is an example of a cursor data type definition that is definedto return a result set with the same row format as the rowType data type:CREATE TYPE cursorType AS rowType CURSOR@

Only result sets that contain columns of data with the same data typedefinition as the rowType row definition can be successfully assigned tovariables declared to be of the cursorType cursor data type.

The following is an example of a cursor data type definition that is definedto return a result set with the same row format as that which defines tableT1:CREATE TABLE T1 (C1 INT)

CREATE TYPE cursorType AS ANCHOR ROW OF t1 CURSOR;

Chapter 4. SQL PL data types 45

Page 56: IBM DB2 9.7 for Linux, UNIX, And Windows

Only result sets that contain columns of data with the same data typedefinition as the column definition for the table t1 can be successfullyassigned to variables declared to be of the cursorType cursor data type.

The row definition associated with a strongly typed cursor can bereferenced as the definition of an anchored data type. The followingexample illustrates this:CREATE TYPE r1 AS ROW (C1 INT);CREATE TYPE c1 AS RTEST CURSOR;

DECLARE c1 CTEST;DECLARE r1 ANCHOR ROW OF CV1;

A row data type named r1 is defined, a cursor type named c1 associatedwith the row definition of r1 is defined. The subsequent SQL statementsare examples of variable declarations might appear in an SQL procedure.The second variable declaration is for a variable named r1 which is definedto be of the anchored data type - it is anchored to the row type that wasused to define the cursor cv1.

Weakly-typed cursor data typesA weakly typed cursor type is not associated with any row data typedefinition. No type checking is performed when values are assigned toweakly typed cursor variables.

There is a system-defined weakly typed cursor data type named CURSORthat can be used to declare weakly typed cursor variables or parameters.The following is an example of a weakly typed cursor variable declarationbased on the system-defined weakly typed cursor data type CURSOR:DECLARE cv1 CURSOR;

Weakly typed cursor variables are useful when you must store a result setwith an unknown row definition.To return a weakly typed cursor variable as an output parameter, thecursor must be opened.In this version, variables based on weakly typed cursor data types cannotbe referenced as anchored data types.User-defined weakly typed cursor data types can be defined.

All other characteristics of cursor variables are common for each type of cursorvariable.

Restrictions on cursor data typesRestrictions on cursor data types and cursor variables limit cursor variablefunctionality as well as where cursor variables can be defined and referenced.

The restrictions on cursor data types and variables are important to note beforeimplementing them. The restrictions can be important in determining whether acursor variable is appropriate for your needs and can be useful to review whentroubleshooting errors related to cursor data type and variable use.

The following restrictions apply to cursor data types in this version:v Cursor data types can only be created as local types in SQL procedures.

The following restrictions apply to cursor variables in this version:v Cursor variables are not supported for use in applications. Cursor variables can

only be declared and referenced in SQL PL contexts.

46 SQL Procedural Languages: Application Enablement and Support

Page 57: IBM DB2 9.7 for Linux, UNIX, And Windows

v Cursor variables are read-only cursors.v Rows accessed through the use of a cursor variable are not updatable.v Cursor variables are not scrollable cursors.v Strongly typed cursor variable columns cannot be referenced as anchored data

types.v There is no support for global cursor variables.v XML columns cannot be referenced in cursor variable definitions.v XQuery language statements cannot be used to define strongly-typed cursor

result sets.

Privileges related to cursor data type useSpecific privileges related to cursor data types and variables exist to restrict andcontrol who can create them.

To create cursor data types, you require the following privilege:v Privilege to execute the CREATE TYPE statement to create a cursor data type.

To declare cursor variables based on existing cursor data types, no privileges arerequired.

To initialize cursor variables, to open the cursor referenced by a cursor variable, orto fetch values from an opened cursor variable reference, you require the sameprivileges as are required to execute the DECLARE CURSOR statement.

Cursor variablesCursor variables are cursors based on predefined cursor data type. Cursorvariables can be un-initialized, initialized, assigned a value, set to another value, orpassed as a parameter from SQL procedures. Cursor variables inherit theproperties of the cursor data types upon which they are based. Cursor variablescan be strongly-typed or weakly-typed. Cursor variables hold a reference to thecontext of the cursor defined by the cursor data type.

Cursor variables can be declared within SQL procedures using the DECLAREstatement.

Cursor predicatesCursor predicates are SQL keywords that can be used to determine the state of acursor defined within the current scope. They provide a means for easilyreferencing whether a cursor is open, closed or if there are rows associated withthe cursor.

Cursor predicates can be referenced in SQL and SQL PL statements wherever thestatus of a cursor can be used as a predicate condition. The cursor predicates thatcan be used include:

IS OPENThis predicate can be used to determine if the cursor is in an open state.This can be a useful predicate in cases where cursors are passed asparameters to functions and procedures. Before attempting to open thecursor, this predicate can be used to determine if the cursor is alreadyopen.

IS NOT OPENThis predicate can be used to determine if the cursor is closed. Its value is

Chapter 4. SQL PL data types 47

Page 58: IBM DB2 9.7 for Linux, UNIX, And Windows

the logical inverse of IS OPEN. This predicate can be useful to determinewhether a cursor is closed before attempting to actually close the cursor.

IS FOUNDThis predicate can be used to determine if the cursor contains rows afterthe execution of a FETCH statement. If the last FETCH statement executedwas successful, the IS FOUND predicate value is true. If the last FETCHstatement executed resulted in a condition where rows were not found, theresult is false. The result is unknown when:v the value of cursor-variable-name is nullv the underlying cursor of cursor-variable-name is not openv the predicate is evaluated before the first FETCH action was performed

on the underlying cursorv the last FETCH action returned an error

The IS FOUND predicate can be useful within a portion of SQL PL logicthat loops and performs a fetch with each iteration. The predicate can beused to determine if rows remain to be fetched. It provides an efficientalternative to using a condition handler that checks for the error conditionthat is raised when no more rows remain to be fetched.

An alternative to using IS FOUND is to use IS NOT FOUND which has theopposite value.

Example

The following script defines an SQL procedure that contains references to thesepredicates as well as the prerequisite objects required to successfully compile andcall the procedure:CREATE TABLE T1 (c1 INT, c2 INT, c3 INT)@

insert into t1 values (1,1,1),(2,2,2),(3,3,3) @

CREATE TYPE myRowType AS ROW(c1 INT, c2 INT, c3 INT)@

CREATE TYPE myCursorType AS myRowType CURSOR@

CREATE PROCEDURE p(OUT count INT)LANGUAGE SQLBEGIN

DECLARE C1 cursor;DECLARE lvarInt INT;

SET count = -1;SET c1 = CURSOR FOR SELECT c1 FROM t1;

IF (c1 IS NOT OPEN) THENOPEN c1;

ELSEset count = -2;

END IF;

set count = 0;IF (c1 IS OPEN) THEN

FETCH c1 into lvarInt;

WHILE (c1 IS FOUND) DOSET count = count + 1;FETCH c1 INTO lvarInt;

END WHILE;

48 SQL Procedural Languages: Application Enablement and Support

Page 59: IBM DB2 9.7 for Linux, UNIX, And Windows

ELSESET count = 0;

END IF;

END@

CALL p()@

Creating cursor variablesTo create cursor variables you must first create a cursor type and then create acursor variable based on the type. The following topics show you how to do thesetasks:

Creating cursor data types using the CREATE TYPE statementCreating a cursor data type is a prerequisite to creating a cursor variable. Cursordata types are created using the CREATE TYPE (cursor) statement.

Before you begin

To perform this task you require:v Privileges to execute the CREATE TYPE (cursor) statement.v If creating a strongly typed cursor data type, you must either prepare a row

specification or base it on an existing row from a table, view, or cursor.

About this task

The CREATE TYPE (cursor) statement defines a cursor data type that can be usedin SQL PL to declare parameters and local variables of the cursor data type. Astrongly typed cursor data type is created if the row-type-name clause is specifiedin the CREATE TYPE (cursor) statement. A weakly defined cursor data type iscreated when the row-type-name clause is omitted.

As an alternative to creating a weakly defined cursor data type, the system-definedweakly defined cursor data type CURSOR can be used when declaring cursorvariables.CREATE TYPE weakCursorType AS CURSOR@

If you want to create a strongly-typed cursor data type, a row data type definitionmust exist that will define the result set that can be associated with the cursor. Arow data type definition can be derived from an explicitly defined row data type, atable or view, or strongly typed cursor. The following is an example of a row typedefinition:CREATE TYPE empRow AS ROW (name varchar(128), ID varchar(8))@

The following is an example of a table definition from which a row type definitioncan be derived:CREATE TABLE empTable AS ROW (name varchar(128), ID varchar(8))@

To define a strongly-typed cursor data type within a database you mustsuccessfully execute the CREATE TYPE (CURSOR) statement from any DB2interface that supports the execution of SQL statements.

Procedure

1. Formulate a CREATE TYPE (CURSOR) statement:a. Specify a name for the type.

Chapter 4. SQL PL data types 49

Page 60: IBM DB2 9.7 for Linux, UNIX, And Windows

b. Specify a row definition by doing one of: referencing the name of a rowdata type, specifying that the type should be anchored to a table or view, oranchored to the result set definition associated with an existing strongcursor type.

2. Execute the CREATE TYPE statement from a supported DB2 interface.

Results

If the CREATE TYPE statement executes successfully, the cursor data type iscreated in the database.

Example

The following is an example of how to create a weakly typed cursor data type thatcan be associated with result sets with the same format as the empRow row datatype:CREATE TYPE cursorType AS empRow CURSOR@

The following is an example of how to create a cursor data type that can beassociated with result sets with the same format as the table empTable :CREATE TYPE cursorType AS ANCHOR ROW OF empTable@

What to do next

Once the cursor data type is created, cursor variables can be declared based on thisdata type.

Declaring local variables of type cursorLocal variables of type cursor can be declared once a cursor data type has beencreated.

Before you begin

A cursor data type definition must exist in the database. Cursor data types arecreated by successfully executing the CREATE TYPE (CURSOR) statement. Thefollowing is an example of a strongly-typed cursor type definition:CREATE TYPE cursorType AS empRow CURSOR;

In this version, cursor variables can only be declared as local variables within SQLprocedures. Both strongly-typed and weakly-typed cursor variables can bedeclared.

Procedure

1. Formulate a DECLARE statement:a. Specify a name for the variable.b. Specify the cursor data type that will define the variable. If the cursor

variable is to be weakly-typed, a user-defined weakly typed cursor datatype must be specified or the system-defined weakly-typed cursor data typeCURSOR. If the cursor variable is to be based on a strongly-typed cursordata type, you can initialize the variable immediately.

The following is an example of how to formulate a DECLARE statement thatwill define a cursor variable of type cursorType that is not initialized:DECLARE Cv1 cursorType@

50 SQL Procedural Languages: Application Enablement and Support

Page 61: IBM DB2 9.7 for Linux, UNIX, And Windows

The following is an example of how to formulate a DECLARE statement thatwill define a cursor variable Cv2 with a type that is anchored to the type of theexisting cursor variable named Cv1:DECLARE Cv2 ANCHOR DATA TYPE TO Cv1@

The following is an example of how to formulate a DECLARE statement thatwill define a weakly-typed cursor variable:DECLARE Cv1 CURSOR@

2. Execute the DECLARE statement within a supported context.

Results

If execution of the DECLARE statement is successful, the cursor variable is created.

What to do next

Once this cursor variable is created, the cursor variable can be assigned values,referenced, or passed as a parameter.

Assigning values to cursor variablesResult sets can be assigned to cursor variables at different times and in multipleways using the SET statement.

Assigning a query result set to a cursor variable

A result set of a select query can be assigned to a cursor variable by using the SETstatement and the CURSOR FOR keywords. The following is an example of howthe result set associated with a query on a table named T is assigned to a cursorvariable named c1 that has an identical row definition as the table:

If T is defined as:CREATE TABLE T (C1 INT, C2 INT, C3 INT);

If C1 is a strongly-typed cursor variable that was defined as:CREATE TYPE simpleRow AS ROW (c1 INT, c2 INT, c3 INT);CREATE TYPE simpleCur AS CURSOR RETURNS simpleRow;DECLARE c1 simpleCur;

The assignment can be done as follows:SET c1 = CURSOR FOR SELECT * FROM T;

The strong type checking will be successful since c1 has a compatible definition totable T. If c1 was a weakly-typed cursor this assignment would also be successful,because no data type checking would be performed.

Assigning literal values to a cursor variable

A result set of a select query can be assigned to a cursor variable by using the SETstatement and the CURSOR FOR keywords. The following is an example of howthe result set associated with a query on a table named T is assigned to a cursorvariable named c1 that has an identical row definition as the table.

Let T be a table defined as:CREATE TABLE T (C1 INT, C2 INT, C3 INT);

Chapter 4. SQL PL data types 51

Page 62: IBM DB2 9.7 for Linux, UNIX, And Windows

Let simpleRow be a row type and simpleCur be a cursor type that are respectivelycreated as:CREATE TYPE simpleRow AS ROW (c1 INT, c2 INT, c3 INT);CREATE TYPE simpleCur AS CURSOR RETURNS simpleRow;

Let c1 be a strongly-typed cursor variable that is declared within a procedure as:DECLARE c1 simpleCur;

The assignment of literal values to cursor c1 can be done as follows:SET c1 = CURSOR FOR VALUES (1, 2, 3);

The strong type checking will be successful since the literal values are compatiblewith the cursor definition. The following is an example of an assignment of literalvalues that will fail, because the literal data types are incompatible with the cursortype definition:SET c1 = CURSOR FOR VALUES ('a', 'b', 'c');

Assigning cursor variable values to cursor variable values

A cursor variable value can be assigned to another cursor variable only if thecursor variables have identical result set definitions. For example:

If c1 and c2 are strongly-typed cursor variable that was defined as:CREATE TYPE simpleRow AS ROW (c1 INT, c2 INT, c3 INT);

CREATE TYPE simpleCur AS CURSOR RETURNS simpleRow

DECLARE c1 simpleCur;

DECLARE c2 simpleCur;

If c2 has been assigned values as follows:SET c2 = CURSOR FOR VALUES (1, 2, 3);

The assignment of the result set of c2 to cursor variable c1 can be done as follows:SET c1 = c2;

Once cursor variables have been assigned values, the cursor variables and cursorvariables field values can be assigned and referenced.

Referencing cursor variablesCursor variables can be referenced in multiple ways as part of cursor operationsrelated to retrieving and accessing a result set or when calling a procedure andpassing cursor variables as parameters.

The following statements can be used to reference cursor variables within an SQLPL context:v CALLv SETv OPENv FETCHv CLOSE

52 SQL Procedural Languages: Application Enablement and Support

Page 63: IBM DB2 9.7 for Linux, UNIX, And Windows

The OPEN, FETCH, and CLOSE statements are most often used together whenaccessing the result set associated with a cursor variable. The OPEN statement isused to initialize the result set associated with the cursor variable. Upon successfulexecution of this statement, the cursor variable is associated with the result set andthe rows in the result set can be accessed. The FETCH statement is used tospecifically retrieve the column values in the current row being accessed by thecursor variable. The CLOSE statement is used to end the processing of the cursorvariable.

The following is an example of a created row data type definition and an SQLprocedure definition that contains a cursor variable definition. Use of the OPEN,FETCH, and CLOSE statements with the cursor variable are demonstrated withinthe SQL procedure:CREATE TYPE simpleRow AS ROW (c1 INT, c2 INT, c3 INT);

CREATE PROCEDURE P(OUT p1 INT, OUT p2 INT, PUT p3 INT, OUT pRow simpleRow)LANGUAGE SQLBEGIN

CREATE TYPE simpleCur AS CURSOR RETURNS simpleRowDECLARE c1 simpleCur;DECLARE localVar1 INTEGER;DECLARE localVar2 INTEGER;DECLARE localVar3 INTEGER;DECLARE localRow simpleRow;

SET c1 = CURSOR FOR SELECT * FROM T;

OPEN C1;

FETCH c1 INTO localVar1, localVar2, localVar3;

FETCH c1 into localRow;

SET p1 = localVar1;

SET p2 = localVar2;

SET p3 = localVar3;

SET pRow = localRow;

CLOSE c1;

END;

Cursor variables can also be referenced as parameters in the CALL statement. Aswith other parameters, cursor variable parameters are simply referenced by name.The following is an example of a CALL statement within an SQL procedure thatreferences a cursor variable named curVar which is an output parameter:CALL P2(curVar);

Determining the number of fetched rows for a cursorDetermining the number of rows associated with a cursor can be efficiently doneby using the cursor_rowCount scalar function which takes a cursor variable as aparameter and returns an integer value as an output corresponding to the numberof rows that have been fetched since the cursor was opened.

Before you begin

Chapter 4. SQL PL data types 53

Page 64: IBM DB2 9.7 for Linux, UNIX, And Windows

The following prerequisites must be met before you use the cursor_rowCountfunction:v A cursor data type must be created.v A cursor variable of the cursor data type must be declared.v An OPEN statement referencing the cursor must have been executed.

About this task

You can use the cursor_rowCount function within SQL PL contexts and wouldperform this task whenever in your procedural logic it is necessary to access thecount of the number of rows that have been fetched for a cursor so far or the totalcount of rows fetched. The use of the cursor_rowCount function simplifiesaccessing the fetched row count which otherwise might require that within loopingprocedural logic you maintain the count with a declared variable and a repeatedlyexecuted SET statement.

Restrictions

The cursor_rowCount function can only be used in SQL PL contexts.

Procedure

1. Formulate an SQL statement with a reference to the cursor_rowCount scalarfunction. The following is an example of a SET statement that assigns theoutput of the cursor_rowCount scalar function to a local variable namedrows_fetched:SET rows_fetched = CURSOR_ROWCOUNT(curEmp)

2. Include the SQL statement containing the cursor_rowCount function referencewithin a supported SQL PL context. This might be, for example, within aCREATE PROCEDURE statement or a CREATE FUNCTION statement andcompile the statement.

3.

Results

The statement should compile successfully.

Example

The following is an example of an SQL procedure that includes a reference to thecursor_rowCount function:CREATE PROCEDURE p()LANGUAGE SQLBEGIN

SET rows_fetched = CURSOR_ROWCOUNT(curEmp)

END@

What to do next

Execute the SQL procedure or invoke the SQL function.

Example: Cursor variable useReferencing examples of cursor variable use an be useful when designing andimplementing cursor variables.

54 SQL Procedural Languages: Application Enablement and Support

Page 65: IBM DB2 9.7 for Linux, UNIX, And Windows

Cursor variable use within an SQL procedureReferencing examples that demonstrate cursor variable use is a good way to learnhow and where you can use cursor variables.

This example shows the following:v CREATE TYPE statement to create a ROW data typev CREATE TYPE statement to create a strongly-typed cursor based on a row data

type specificationv CREATE PROCEDURE statement to create a procedure that has an output

cursor parameterv CREATE PROCEDURE statement to create a procedure that calls another

procedure and passes a cursor as an input parameter

A prerequisite to running this example is that the SAMPLE database must exist. Tocreate the sample database, issue the following command from a DB2 CommandWindow:db2sampl;

The following is an example CLP script that demonstrates the core features ofcursor variable use within SQL procedures. The script contains a row data typedefinition, a cursor type definition and two SQL procedure definitions. Theprocedure P_CALLER contains a cursor variable definition and a call to aprocedure named P. The procedure P defines a cursor, opens the cursor and passesthe cursor as an output parameter value. The procedure P_CALLER receives thecursor parameter, fetches the cursor value into a local variable, and then sets twooutput parameter values named edlvel and lastname based on the local variablevalue.--#SET TERMINATOR @update command options using c off @connect to sample @

CREATE TYPE myRowType AS ROW (edlevel SMALLINT, name VARCHAR(128))@

CREATE TYPE myCursorType AS myRowType CURSOR@

CREATE PROCEDURE P(IN pempNo VARCHAR(8), OUT pcv1 SYSCURSOR)LANGUAGE SQLBEGIN

SET pcv1 = CURSOR FOR SELECT edlevel, lastname FROM employee WHERE empNo = pempNo;OPEN pcv1;

END@

CREATE PROCEDURE P_CALLER( IN pempNo VARCHAR(8) ,OUT edlevel SMALLINT,OUT lastname VARCHAR(128))

LANGUAGE SQLBEGIN

DECLARE rv1 myRowType;DECLARE c1 SYSCURSOR;

CALL P (pempNo,c1);FETCH c1 INTO rv1;CLOSE c1;

SET edlevel = rv1.edlevel;SET lastname = rv1.name;

Chapter 4. SQL PL data types 55

Page 66: IBM DB2 9.7 for Linux, UNIX, And Windows

END @

CALL P_CALLER('000180',?,?) @

When the above script is run, the following output is generated:update command options using c offDB20000I The UPDATE COMMAND OPTIONS command completed successfully.

connect to sample

Database Connection Information

Database server = DB2/LINUXX8664 9.7.0SQL authorization ID = REGRESS5Local database alias = SAMPLE

CREATE TYPE myRowType AS ROW (edlevel SMALLINT, name VARCHAR(128))DB20000I The SQL command completed successfully.

CREATE TYPE myCursorType AS CURSOR RETURNS myRowTypeDB20000I The SQL command completed successfully.

CREATE PROCEDURE P(IN pempNo VARCHAR(8),OUT pcv1 SYSCURSOR)LANGUAGE SQLBEGIN

SET pcv1 = CURSOR FOR SELECT edlevel, lastname FROM employee WHERE empNo = pempNo;OPEN pcv1;

ENDDB20000I The SQL command completed successfully.

CREATE PROCEDURE P_CALLER( IN pempNo VARCHAR(8) ,OUT edlevel SMALLINT,OUT lastname VARCHAR(128))

LANGUAGE SQLBEGIN

DECLARE rv1 myRowType;DECLARE c1 SYSCURSOR;

CALL P (pempNo,c1);FETCH c1 INTO rv1;CLOSE c1;

SET EDLEVEL = rv1.edlevel;SET LASTNAME = rv1.name;

ENDDB20000I The SQL command completed successfully.

CALL P_CALLER('000180',?,?)

Value of output parameters--------------------------Parameter Name : EDLEVELParameter Value : 17

Parameter Name : LASTNAMEParameter Value : SCOUTTEN

Return Status = 0

56 SQL Procedural Languages: Application Enablement and Support

Page 67: IBM DB2 9.7 for Linux, UNIX, And Windows

Boolean data typeThe BOOLEAN type is a built-in data type that can only be used for localvariables, global variables, parameters, or return types in compound SQL(compiled) statements. A Boolean value represents a truth value of TRUE orFALSE. A Boolean expression or predicate can result in a value of unknown, whichis represented as the null value.

Restrictions on the Boolean data typeIt is important to note the restrictions on the Boolean data type before you use it orwhen troubleshooting problems with their use.

The following restrictions apply to the boolean data type:v The Boolean data type can only be referenced as:

– Local variables declared in SQL functions– Local variables declared in SQL procedures– Local variables declared in triggers with a compound SQL (compiled)

statement as trigger body– Parameter to SQL functions with a compound SQL (compiled) statement as

function body– Parameter to SQL procedure with a compound SQL (compiled) statement as

procedure body– Return type– Global variable in a module

v The Boolean data type cannot be used to define the data type of a column in atable or view.

v The system-defined values TRUE and FALSE cannot be referenced as values tobe inserted into a table.

v The Boolean data type cannot be referenced in external routines or clientapplications.

v The Boolean data type cannot be cast to other data types.v The Boolean data type cannot be returned as a return code value from an SQL

procedure.v Variables of the Boolean data type can only be assigned one of the following

values: TRUE, FALSE, or NULL. Numeric or other data type assignments are notsupported.

v Selecting or fetching values into variables of the Boolean data type is notsupported.

v The Boolean data type cannot be returned in a result set.v A Boolean variable cannot be used as a predicate. For example, the following

SQL clause is not supported:IF (gb) THEN ...

Use of predicates is only supported in the SET statement and RETURNstatement from a UDF.

If these restrictions prevent you from using this data type consider using aninteger data type instead and assign it values such as 1 for TRUE, 0 for FALSE,and -1 for NULL.

Chapter 4. SQL PL data types 57

Page 68: IBM DB2 9.7 for Linux, UNIX, And Windows

58 SQL Procedural Languages: Application Enablement and Support

Page 69: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 5. SQL routines

SQL routines are routines that have logic implemented with only SQL statements,including SQL Procedural Language (SQL PL) statements. They are characterizedby having their routine-body logic contained within the CREATE statement that isused to create them. This is in contrast with external routines that have theirroutine logic implemented in a library built form programming source code. Ingeneral SQL routines can contain and execute fewer SQL statements than externalroutines; however they can be every bit as powerful and high performing whenimplemented according to best practices.

You can create SQL procedures, SQL functions, and SQL methods. Although theyare all implemented in SQL, each routine functional type has different features.

Overview of SQL routinesSQL routines are routines that have logic implemented with only SQL statements,including SQL Procedural Language (SQL PL) statements. They are characterizedby having their routine-body logic contained within the CREATE statement that isused to create them. You can create SQL procedures, SQL functions, and SQLmethods. Although they are all implemented in SQL, each routine functional typehas different features.

Before deciding to implement a SQL routine, it is important that you firstunderstand what SQL routines are, how they are implemented, and used byreading an ″Overview of routines″. With that knowledge you can then learn moreabout SQL routine from the following concept topics so that you can makeinformed decisions about when and how to use them in your databaseenvironment:v SQL proceduresv SQL functionsv Tools for developing SQL routinesv SQL Procedural Language (SQL PL)v Comparison of SQL PL and inline SQL PLv SQL PL statements and featuresv Supported inline SQL PL statements and featuresv Determining when to use SQL procedures or SQL functionsv Restrictions on SQL routines

After having learned about SQL routines, you might want to do one of thefollowing tasks:v Develop SQL proceduresv Develop SQL functionsv Develop SQL methods

CREATE statements for SQL routinesSQL routines are created by executing the appropriate CREATE statement for theroutine type. In the CREATE statement you also specify the routine body, whichfor an SQL routine must be composed only of SQL or SQL PL statements. You can

© Copyright IBM Corp. 1993, 2009 59

Page 70: IBM DB2 9.7 for Linux, UNIX, And Windows

use the IBM® DB2 Development Center to help you create, debug, and run SQLprocedures. SQL procedures, functions, and methods can also be created using theDB2 command line processor.

SQL procedures, functions, and methods each have a respective CREATEstatement. Although the syntax for these statements is different, there are somecommon elements to them. In each you must specify the routine name, andparameters if there are to be any as well as a return type. You can also specifyadditional keywords that provide DB2 with information about the logic containedin the routine. DB2 uses the routine prototype and the additional keywords toidentify the routine at invocation time, and to execute the routine with the requiredfeature support and best performance possible.

For specific information on creating SQL procedures in the DB2 DevelopmentCenter or from the Command Line Processor, or on creating functions andmethods, refer to the related topics.

Determining when to use SQL routines or external routines

When implementing routine logic you can choose to implement SQL routines orexternal routines. There are reasons for choosing each of these twoimplementations.

To determine when to choose to implement an SQL routine or an external routine,read the following to determine what if any factors might limit your choice.v Choose to implement SQL routines if:

– SQL PL and SQL statements provide adequate support to implement the logicthat you require.

– The routine logic consists primarily of SQL statements that query or modifydata and performance is a concern. Logic that contains a relatively smallamount of control-flow logic relative to the number of SQL statements thatquery or modify database data will generally perform better with an SQLroutine implementation. SQL PL is intended to be used for implementingprocedural logic around database operations and not primarily forprogramming complex logic.

– The SQL statements that you need to execute can be executed in an externalroutine implementation.

– You want to make the modules highly portable between operating systemenvironments and minimize the dependency on programming language codecompilers and script interpreters.

– You want to implement the logic quickly and easily using a high levelprogramming language.

– You are more comfortable working with SQL than with scripting orprogramming languages.

– You want to secure the logic within the database management system.– You want to minimize routine maintenance and routine package maintenance

upon release upgrades or operating system upgrades.– You want to minimize the amount of code required to implement the logic.– You want to maximize the safety of the code that is implemented by

minimizing the risk of memory management, pointer manipulation, or othercommon programming pitfalls.

– You want to benefit from special SQL caching support made available whenSQL PL is used.

60 SQL Procedural Languages: Application Enablement and Support

Page 71: IBM DB2 9.7 for Linux, UNIX, And Windows

v Choose to implement an external procedure if:– If the routine logic is very complex and consists of few SQL statements and

routine performance is a concern. Logic such as a complex math algorithm,that involves a large amount of string manipulation, or that does not accessthe database will generally perform better with an external routineimplementation.

– If the SQL statements that you need to execute can be executed in an externalroutine implementation.

– The routine logic will make operating system calls - this can only be donewith external routines.

– The routine logic must read from or write to files - this can only be done withexternal routines.

– Write to the server file system. Do this only with caution.– Invoke an application or script that resides on the database server.– Issue particular SQL statements that are not supported in SQL procedures.– You are more comfortable programming in a programming language other

than SQL PL.

By default if SQL routines can meet your needs, use them. Generally it is arequirement to implement complex logic or to access files or scripts on thedatabase server that motivates the decision to use external routines. Particularlysince SQL PL is fast and easy to learn and implement.

Determining when to use SQL procedures or SQL functions

When faced with the choice of implementing logic with SQL PL in an SQLprocedure or an SQL function, there are reasons for choosing each of these twoimplementations.

Read the following to determine when to choose to use an SQL procedure or anSQL function.Choose to implement an SQL function if:v Functional requirements can be met by an SQL function and you don’t anticipate

later requiring the features provided by an SQL procedure.v Performance is a priority and the logic to be contained in the routine consists

only of queries or returns only a single result set.When they only contain queries or the return of a single result set an SQLfunction performs better than a logically equivalent SQL procedure, because ofhow SQL functions are compiled.In SQL procedures, static queries in the form of SELECT statements andfull-select statements are compiled individually, such that each query becomes asection of a query access plan in a package when the SQL procedure is created.There is no recompilation of this package until the SQL procedure is recreated orthe package is rebound to the database. This means that the performance of thequeries is determined based on information available to the database manager ata time earlier than the SQL procedure execution time and hence might not beoptimal. Also with an SQL procedure there is also a small overhead entailedwhen the database manager transfers between executing procedural flowstatements and SQL statements that query or modify data.SQL functions however are expanded and compiled within the SQL statementthat references them which means that they are compiled each time that SQLstatement is compiled which depending on the statement might happen

Chapter 5. SQL routines 61

Page 72: IBM DB2 9.7 for Linux, UNIX, And Windows

dynamically. Because SQL functions are not directly associated with a package,there is no overhead entailed when the database manager transfers betweenexecuting procedural flow statements and SQL statements that query or modifydata.

Choose to implement an SQL procedure if:v SQL PL features that are only supported in SQL procedures are required. This

includes: output parameter support, use of a cursor, the ability to returnmultiple result sets to the caller, full condition handling support, transaction andsavepoint control, or other features.

v You want to execute non-SQL PL statements that can only be executed in SQLprocedures.

v You want to modify data and modifying data is not supported for the type offunction you need.

Although it isn’t always obvious, you can often easily re-write SQL procedures asSQL functions that perform equivalent logic. This can be an effective way tomaximize performance when every little performance improvement counts.

Determining when to use SQL routines or dynamicallyprepared compound SQL statements

When determining how to implement an atomic block of SQL PL and other SQLstatements you might be faced with a choice between using SQL routines ordynamically prepared compound SQL statements. Although SQL routinesinternally make use of compound SQL statements, the choice of which to usemight depend on other factors.

Performance

If a dynamically prepared compound SQL statement can functionally meet yourneeds, using one is preferable, because the SQL statements that appear indynamically prepared compound SQL statements are compiled and executed as asingle block. Also these statements generally perform better than CALL statementsto logically equivalent SQL procedures.

At SQL procedure creation time, the procedure is compiled and a package iscreated. The package contains the best execution path for accessing data as of theSQL procedure compile time. Dynamically prepared compound SQL statements arecompiled when they are executed. The best execution path for accessing data forthese statements is determined using the most up to date database informationwhich can mean that their access plan can be better than that of a logicallyequivalent SQL procedure that was created at an earlier time which means thatthey might perform better.

Complexity of the required logic

If the logic is quite simple and the number of SQL statements is relatively small,consider using inline SQL PL in a dynamically prepared compound SQL statement(specifying ATOMIC) or in an SQL function. SQL procedures can also handlesimple logic, but use of SQL procedures incurs some overhead, such as creating theprocedure and calling it, that, if not required, is best avoided.

62 SQL Procedural Languages: Application Enablement and Support

Page 73: IBM DB2 9.7 for Linux, UNIX, And Windows

Number of SQL statements to be executed

In cases where only one or two SQL statements are to be executed, there might beno benefit in using an SQL procedure. This might actually negatively impact thetotal performance required to execute these statements. In such a case, it is betterto use inline SQL PL in a dynamically prepared compound SQL statement.

Atomicity and transaction control

Atomicity is another consideration. A compound SQL (inlined) statement must beatomic. Commits and rollbacks are not supported in compound SQL (inlined)statements. If transaction control is required or if support for rollback to asavepoint is required, SQL procedures must be used.

Security

Security can also be a consideration. SQL procedures can only be executed by userswith EXECUTE privilege on the procedure. This can be useful if you need to limitwho can execute a particular piece of logic. The ability to execute a dynamicallyprepared compound SQL statement can also be managed. However SQL procedureexecution authorization provides an extra layer of security control.

Feature support

If you need to return one or more result sets, you must use SQL procedures.

Modularity, longevity, and re-use

SQL procedures are database objects that are persistently stored in the databaseand can be consistently referenced by multiple applications or scripts. Dynamicallyprepared compound SQL statements are not stored in the database and thereforethe logic they contain cannot be readily re-used.

If SQL procedures can meet your needs, use them. Generally it is a requirement toimplement complex logic or to use the features supported by SQL procedures, butnot available to dynamically prepared compound SQL statements that motivatesthe decision to use SQL procedures.

Rewriting SQL procedures as SQL user-defined functions

To maximize performance in a database management system, if possible, it cansometimes be beneficial to rewrite simple SQL procedures as SQL functions.Procedures and functions share the fact that their routine-bodies are implementedwith a compound block that can contain SQL PL. In both, the same SQL PLstatements are included within compound blocks bounded by BEGIN and ENDkeywords.

There are some things to note when translating an SQL procedure into an SQLfunction:v The primary and only reason to do this is to improve routine performance when

the logic only queries data.v In a scalar function you might have to declare variables to hold the return value

to get around the fact that you cannot directly assign a value to any outputparameter of the function. The output value of a user-defined scalar function isonly specified in the RETURN statement for the function.

Chapter 5. SQL routines 63

Page 74: IBM DB2 9.7 for Linux, UNIX, And Windows

v If an SQL function is going to modify data, it must be explicitly created usingthe MODIFIES SQL clause so that is can contain SQL statements that modifydata.

In the example that follows an SQL procedure and an SQL scalar function that arelogically equivalent are shown. These two routines functionally provide the sameoutput value given the same input values, however they are implemented andinvoked in slightly different ways.

CREATE PROCEDURE GetPrice (IN Vendor CHAR(20),IN Pid INT,OUT price DECIMAL(10,3))

LANGUAGE SQLBEGIN

IF Vendor = 'Vendor 1'THEN SET price = (SELECT ProdPrice FROM V1Table WHERE Id = Pid);ELSE IF Vendor = 'Vendor 2'THEN SET price = (SELECT Price FROM V2Table

WHERE Pid = GetPrice.Pid);END IF;

END

This procedure takes in two input parameter values and returns an outputparameter value that is conditionally determined based on the input parametervalues. It uses the IF statement. This SQL procedure is invoked by executing theCALL statement. For example from the CLP, you might execute the following:

CALL GetPrice( 'Vendor 1', 9456, ?)

The SQL procedure can be rewritten as a logically-equivalent SQL table-function asfollows:

CREATE FUNCTION GetPrice (Vendor CHAR(20), Pid INT)RETURNS DECIMAL(10,3)

LANGUAGE SQL MODIFIES SQLBEGIN

DECLARE price DECIMAL(10,3);

IF Vendor = 'Vendor 1'THEN SET price = (SELECT ProdPrice FROM V1Table WHERE Id = Pid);

ELSE IF Vendor = 'Vendor 2'THEN SET price = (SELECT Price FROM V2Table

WHERE Pid = GetPrice.Pid);END IF;

RETURN price;END

This function takes in two input parameters and returns a single scalar value,conditionally based on the input parameter values. It requires the declaration anduse of a local variable named price to hold the value to be returned until thefunction returns whereas the SQL procedure can use the output parameter as avariable. Functionally these two routines are performing the same logic.

Now, of course the execution interface for each of these routines is different.Instead of simply calling the SQL procedure with the CALL statement, the SQLfunction must be invoked within an SQL statement where an expression isallowed. In most cases this isn’t a problem and might actually be beneficial if theintention is to immediately operate on the data returned by the routine. Here aretwo examples of how the SQL function can be invoked.

It can be invoked using the VALUES statement:

64 SQL Procedural Languages: Application Enablement and Support

Page 75: IBM DB2 9.7 for Linux, UNIX, And Windows

VALUES (GetPrice('Vendor 1', 9456))

It can also be invoked in a SELECT statement that for example might select valuesfrom a table and filter rows based on the result of the function:

SELECT VName FROM Vendors WHERE GetPrice(Vname, Pid) < 10

SQL proceduresSQL procedures are procedures implemented completely with SQL that can beused to encapsulate logic that can be invoked like a programming sub-routine.There are many useful applications of SQL procedures within a database ordatabase application architecture. SQL procedures can be used to create simplescripts for quickly querying transforming, and updating data or for generatingbasic reports, for improving application performance, for modularizingapplications, and for improving overall database design, and database security.

There are many features of SQL procedures which make them powerful routineoptions.

Before deciding to implement a SQL procedure, it is important that youunderstand what SQL procedures are in the context of SQL routines, how they areimplemented, and how they can be used, by first learning about routines and thenby referring to the topic, ″Overview of SQL procedures″.

Features of SQL proceduresSQL procedures are characterized by many features. SQL procedures:v Can contain SQL Procedural Language statements and features which support

the implementation of control-flow logic around traditional static and dynamicSQL statements.

v Are supported in the entire DB2 family brand of database products in whichmany if not all of the features supported in DB2 Version 9 are supported.

v Are easy to implement, because they use a simple high-level, strongly typedlanguage.

v SQL procedures are more reliable than equivalent external procedures.v Adhere to the SQL99 ANSI/ISO/IEC SQL standard.v Support input, output, and input-output parameter passing modes.v Support a simple, but powerful condition and error-handling model.v Allow you to return multiple result sets to the caller or to a client application.v Allow you to easily access the SQLSTATE and SQLCODE values as special

variables.v Reside in the database and are automatically backed up and restored.v Can be invoked wherever the CALL statement is supported.v Support nested procedure calls to other SQL procedures or procedures

implemented in other languages.v Support recursion.v Support savepoints and the rolling back of executed SQL statements to provide

extensive transaction control.v Can be called from triggers.

Chapter 5. SQL routines 65

Page 76: IBM DB2 9.7 for Linux, UNIX, And Windows

SQL procedures provide extensive support not limited to what is listed above.When implemented according to best practices, they can play an essential role indatabase architecture, database application design, and in database systemperformance.

Designing SQL procedures

Designing SQL procedures requires an understanding of your requirements, SQLprocedure features, how to use the SQL features, and knowledge of any restrictionsthat might impede your design. The following topics about SQL procedure designwill help you learn how to design SQL procedures that make best use of SQLprocedure features.v Parts of SQL proceduresv Cross-platform SQL stored procedure considerationsv Supported SQL PL statements and language features in SQL proceduresv OLTP considerations for SQL proceduresv Performance of SQL proceduresv Rewriting SQL procedures as SQL user-defined functionsv Handling DB2 errors and warnings

Parts of SQL proceduresTo understand SQL procedures, it helps to understand the parts of an SQLprocedure. The following are just some of the parts of SQL procedures:v Structure of SQL proceduresv Parameters in SQL proceduresv Variables in SQL proceduresv SQLCODE and SQLSTATE in SQL proceduresv Atomic blocks and scope of variables in SQL proceduresv Cursors in SQL proceduresv Logic elements in SQL PLv Condition and error handlers in SQL proceduresv SQL statements that can be executed in SQL procedures

Structure of SQL proceduresSQL procedures consist of several logic parts and SQL procedure developmentrequires you to implement these parts according to a structured format. The formatis quite straight-forward and easy to follow and is intended to simplify the designand semantics of routines.

The core of an SQL procedure is a compound statement. Compound statements arebounded by the keywords BEGIN and END. These statements can be ATOMIC orNOT ATOMIC. By default they are NOT ATOMIC.

Within a compound statement, multiple optional SQL PL objects can be declaredand referenced with SQL statements. The following diagram illustrates thestructured format of a compound statement within SQL procedures:

label: BEGINVariable declarationsCondition declarationsCursor declarationsCondition handler declarationsAssignment, flow of control, SQL statements and other compound statements

END label

66 SQL Procedural Languages: Application Enablement and Support

Page 77: IBM DB2 9.7 for Linux, UNIX, And Windows

The diagram shows that SQL procedures can consist of one or more optionallyatomic compound statements (or blocks) and that these blocks can be nested orserially introduced within a single SQL procedure. Within each of these atomicblocks there is a prescribed order for the optional variable, condition, and handlerdeclarations. These must precede the introduction of procedural logic implementedwith SQL-control statements and other SQL statements and cursor declarations.Cursors can be declared anywhere with the set of SQL statements contained in theSQL procedure body.

To clarify control-flow, SQL procedure atomic blocks can be labeled as can many ofthe SQL control-statements contained within them. This makes it easier to beprecise when referencing variables and transfer of control statement references.

Here is an example of an SQL procedure that demonstrates each of the elementslisted above:

CREATE PROCEDURE DEL_INV_FOR_PROD (IN prod INT, OUT err_buffer VARCHAR(128))LANGUAGE SQLDYNAMIC RESULT SETS 1BEGIN

DECLARE SQLSTATE CHAR(5) DEFAULT '00000';DECLARE SQLCODE integer DEFAULT 0;DECLARE NO_TABLE CONDITION FOR SQLSTATE '42704';DECLARE cur1 CURSOR WITH RETURN TO CALLER

FOR SELECT * FROM Inv;

A: BEGIN ATOMICDECLARE EXIT HANDLER FOR NO_TABLE

BEGINSET ERR_BUFFER='Table Inv does not exist';

END;

SET err_buffer = '';

IF (prod < 200)DELETE FROM Inv WHERE product = prod;

ELSE IF (prod < 400)UPDATE Inv SET quantity = 0 WHERE product = prod;

ELSEUPDATE Inv SET quantity = NULL WHERE product = prod;

END IF;

B: OPEN cur1;

END

NOT ATOMIC compound statements in SQL procedures

The previous example illustrated a NOT ATOMIC compound statement and is thedefault type used in SQL procedures. If an unhandled error condition occurswithin the compound statement, any work that is completed before the error willnot be rolled back, but will not be committed either. The group of statements canonly be rolled back if the unit of work is explicitly rolled back using ROLLBACKor ROLLBACK TO SAVEPOINT statements. You can also use the COMMITstatement to commit successful statements if it makes sense to do so.

Here is an example of an SQL procedure with a NOT ATOMIC compoundstatement:

CREATE PROCEDURE not_atomic_proc ()LANGUAGE SQLSPECIFIC not_atomic_proc

Chapter 5. SQL routines 67

Page 78: IBM DB2 9.7 for Linux, UNIX, And Windows

nap: BEGIN NOT ATOMIC

INSERT INTO c1_sched (class_code, day)VALUES ('R11:TAA', 1);

SIGNAL SQLSTATE '70000';

INSERT INTO c1_sched (class_code, day)VALUES ('R22:TBB', 1);

END nap

When the SIGNAL statement is executed it explicitly raises an error that is nothandled. The procedure returns immediately afterwards. After the procedurereturns, although an error occurred, the first INSERT statement did successfullyexecute and inserted a row into the c1_sched table. The procedure neithercommitted, nor rolled back the row insert and this remains to be done for thecomplete unit of work in which the SQL procedure was called.

ATOMIC compound statements in SQL procedures

As the name suggests, ATOMIC compound statements, can be thought of as asingular whole. If any unhandled error conditions arise within it, all statementsthat have executed up to that point are considered to have failed as well and aretherefore rolled back.

Atomic compound statements cannot be nested inside other ATOMIC compoundstatements.

You cannot use the SAVEPOINT statement, the COMMIT statement, or theROLLBACK statement from within an ATOMIC compound statement. These areonly supported in NOT ATOMIC compound statements within SQL procedures.

Here is an example of an SQL procedure with an ATOMIC compound statement:CREATE PROCEDURE atomic_proc ()LANGUAGE SQLSPECIFIC atomic_proc

ap: BEGIN ATOMIC

INSERT INTO c1_sched (class_code, day)VALUES ('R33:TCC', 1);

SIGNAL SQLSTATE '70000';

INSERT INTO c1_sched (class_code, day)VALUES ('R44:TDD', 1);

END ap

When the SIGNAL statement is executed it explicitly raises an error that is nothandled. The procedure returns immediately afterwards. The first INSERTstatement is rolled back despite successfully executing resulting in a table with noinserted rows for this procedure.

Labels and SQL procedure compound statements

Labels can optionally be used to name any executable statement in an SQLprocedure, including compound statements and loops. By referencing labels inother statements you can force the flow of execution to jump out of a compound

68 SQL Procedural Languages: Application Enablement and Support

Page 79: IBM DB2 9.7 for Linux, UNIX, And Windows

statement or loop or additionally to jump to the beginning of a compoundstatement or loop. Labels can be referenced by the GOTO, ITERATE, and LEAVEstatements.

Optionally you can supply a corresponding label for the END of a compoundstatement. If an ending label is supplied, it must be same as the label used at itsbeginning.

Each label must be unique within the body of an SQL procedure.

Labels can also be used to avoid ambiguity if a variable with the same name hasbeen declared in more than one compound statement if the stored procedure. Alabel can be used to qualify the name of an SQL variable.

Parameters in SQL proceduresSQL procedures support parameters for the passing of SQL values into and out ofprocedures.

Parameters can be useful in SQL procedures when implementing logic that isconditional on a particular input or set of input scalar values or when you need toreturn one or more output scalar values and you do not want to return a result set.

It is good to understand the features of and limitations of parameters in SQLprocedures when designing or creating SQL procedures.v DB2 supports the optional use of a large number of input, output, and

input-output parameters in SQL procedures. The keywords IN, OUT, andINOUT in the routine signature portion of CREATE PROCEDURE statementsindicate the mode or intended use of the parameter. IN and OUT parameters arepassed by value, and INOUT parameters are passed by reference.

v When multiple parameters are specified for a procedure they must each have aunique name.

v If a variable is to be declared within the procedure with the same name as aparameter, the variable must be declared within a labeled atomic block nestedwithin the procedure. Otherwise DB2 will detect what would otherwise be anambiguous name reference.

v Parameters to SQL procedures cannot be named either of SQLSTATE orSQLCODE regardless of the data type for the parameter.

Refer to the CREATE PROCEDURE (SQL) statement for complete details aboutparameter references in SQL procedures.

The following SQL procedure named myparams illustrates the use of IN, INOUT,and OUT parameter modes. Let us say that SQL procedure is defined in a CLP filenamed myfile.db2 and that we are using the command line.

CREATE PROCEDURE myparams (IN p1 INT, INOUT p2 INT, OUT p3 INT)LANGUAGE SQLBEGIN

SET p2 = p1 + 1;SET p3 = 2 * p2;

END@

Parameter markersA parameter marker, often denoted by a question mark (?) or a colon followed bya variable name (:var1), is a place holder in an SQL statement whose value isobtained during statement execution. An application associates parameter markers

Chapter 5. SQL routines 69

Page 80: IBM DB2 9.7 for Linux, UNIX, And Windows

to application variables. During the execution of the statement, the values of thesevariables replace each respective parameter marker. Data conversion might takeplace during the process.

Benefits of parameter markers

For SQL statements that need to be executed many times, it is often beneficial toprepare the SQL statement once, and reuse the query plan by using parametermarkers to substitute the input values during runtime. In DB2® 9, a parametermarker is represented in one of two ways:v The first style, with a ″?″ character, is used in dynamic SQL execution (dynamic

Embedded SQL, CLI, Perl, etc).v The second style represents the embedded SQL standard construction where the

name of the variable is prefixed with a colon (:var1) . This style is used in staticSQL execution and is commonly referred to as a host variable.

Use of either style indicates where an application variable is to be substitutedinside an SQL statement. Parameter markers are referenced by number, and arenumbered sequentially from left to right, starting at one. Before the SQL statementis executed, the application must bind a variable storage area to each parametermarker specified in the SQL statement. In addition, the bound variables must be avalid storage area, and must contain input data values when the preparedstatement is executed against the database.

The following example illustrates an SQL statement containing two parametermarkers.

SELECT * FROM customers WHERE custid = ? AND lastname = ?

Supported types

DB2 supports untyped parameter markers, which can be used in selected locationsof an SQL statement. Table 1 lists the restrictions on parameter marker usage.

Table 2. Restrictions on parameter marker usage

Untyped parameter marker location Data type

Expression: Alone in a select list Error

Expression: Both operands of an arithmeticoperator

Error

Predicate: Left-hand side operand of an INpredicate

Error

Predicate: Both operands of a relationaloperator

Error

Function: Operand of an aggregationfunction

Error

Examples

DB2® provides a rich set of standard interfaces including CLI/ODBC, JDBC, andADO.NET to access data efficiently. The following code snippets show the use ofprepared statement with parameter markers for each data access API.

70 SQL Procedural Languages: Application Enablement and Support

Page 81: IBM DB2 9.7 for Linux, UNIX, And Windows

Consider the following table schema for table t1, where column c1 is the primarykey for table t1.

Table 3. Example table schema

Column name DB2 data type Nullable

c1 INTEGER false

c2 SMALLINT true

c3 CHAR(20) true

c4 VARCHAR(20) true

c5 DECIMAL(8,2) true

c6 DATE true

c7 TIME true

c8 TIMESTAMP true

c9 BLOB(30) true

The following examples illustrate how to insert a row into table t1 using aprepared statement.

CLI Examplevoid parameterExample1(void){

SQLHENV henv;SQLHDBC hdbc;SQLHSTMT hstmt;SQLRETURN rc;TCHAR server[] = _T("C:\\mysample\\");TCHAR uid[] = _T("db2e");TCHAR pwd[] = _T("db2e");long p1 = 10;short p2 = 100;TCHAR p3[100];TCHAR p4[100];TCHAR p5[100];TCHAR p6[100];TCHAR p7[100];TCHAR p8[100];char p9[100];long len = 0;

_tcscpy(p3, _T("data1"));_tcscpy(p4, _T("data2"));_tcscpy(p5, _T("10.12"));_tcscpy(p6, _T("2003-06-30"));_tcscpy(p7, _T("12:12:12"));_tcscpy(p8, _T("2003-06-30-17.54.27.710000"));

memset(p9, 0, sizeof(p9));p9[0] = 'X';p9[1] = 'Y';p9[2] = 'Z';

rc = SQLAllocEnv(&henv);// check return code ...

rc = SQLAllocConnect(henv, &hdbc);// check return code ...

rc = SQLConnect(hdbc, (SQLTCHAR*)server, SQL_NTS,

Chapter 5. SQL routines 71

Page 82: IBM DB2 9.7 for Linux, UNIX, And Windows

(SQLTCHAR*)uid, SQL_NTS, (SQLTCHAR*)pwd, SQL_NTS);// check return code ...

rc = SQLAllocStmt(hdbc, &hstmt);// check return code ...

// prepare the statementrc = SQLPrepare(hstmt, _T("INSERT INTO t1 VALUES (?,?,?,?,?,?,?,?,?)"), SQL_NTS);// check return code ...

// bind input parametersrc = SQLBindParameter(hstmt, (unsigned short)1, SQL_PARAM_INPUT,SQL_C_LONG, SQL_INTEGER, 4, 0, &p1, sizeof(p1), &len);// check return code ...

rc = SQLBindParameter(hstmt, (unsigned short)2, SQL_PARAM_INPUT, SQL_C_LONG,SQL_SMALLINT, 2, 0, &p2, sizeof(p2), &len);

// check return code ...

len = SQL_NTS;rc = SQLBindParameter(hstmt, (unsigned short)3, SQL_PARAM_INPUT, SQL_C_TCHAR,

SQL_CHAR, 0, 0, &p3[0], 100, &len);// check return code ...

rc = SQLBindParameter(hstmt, (unsigned short)4, SQL_PARAM_INPUT, SQL_C_TCHAR,SQL_VARCHAR, 0, 0, &p4[0], 100, &len);

// check return code ...

rc = SQLBindParameter(hstmt, (unsigned short)5, SQL_PARAM_INPUT, SQL_C_TCHAR,SQL_DECIMAL, 8, 2, &p5[0], 100, &len);

// check return code ...

rc = SQLBindParameter(hstmt, (unsigned short)6, SQL_PARAM_INPUT, SQL_C_TCHAR,SQL_TYPE_DATE, 0, 0, &p6[0], 100, &len);

// check return code ...

rc = SQLBindParameter(hstmt, (unsigned short)7, SQL_PARAM_INPUT, SQL_C_TCHAR,SQL_TYPE_TIME, 0, 0, &p7[0], 100, &len);

// check return code ...

rc = SQLBindParameter(hstmt, (unsigned short)8, SQL_PARAM_INPUT, SQL_C_TCHAR,SQL_TYPE_TIMESTAMP, 0, 0, &p8[0], 100, &len);

// check return code ...

len = 3;rc = SQLBindParameter(hstmt, (unsigned short)9, SQL_PARAM_INPUT, SQL_C_BINARY,

SQL_BINARY, 0, 0, &p9[0], 100, &len);// check return code ...

// execute the prepared statementrc = SQLExecute(hstmt);// check return code ...

rc = SQLFreeStmt(hstmt, SQL_DROP);// check return code ...

rc = SQLDisconnect(hdbc);// check return code ...

rc = SQLFreeConnect(hdbc);// check return code ...

rc = SQLFreeEnv(henv);// check return code ...

72 SQL Procedural Languages: Application Enablement and Support

Page 83: IBM DB2 9.7 for Linux, UNIX, And Windows

C ExampleEXEC SQL BEGIN DECLARE SECTION;

char hostVarStmt1[50];short hostVarDeptnumb;

EXEC SQL END DECLARE SECTION;

/* prepare the statement with a parameter marker */strcpy(hostVarStmt1, "DELETE FROM org WHERE deptnumb = ?");EXEC SQL PREPARE Stmt1 FROM :hostVarStmt1;

/* execute the statement for hostVarDeptnumb = 15 */hostVarDeptnumb = 15;EXEC SQL EXECUTE Stmt1 USING :hostVarDeptnumb;

JDBC Examplepublic static void parameterExample1() {

String driver = "com.ibm.db2e.jdbc.DB2eDriver";String url = "jdbc:db2e:mysample";Connection conn = null;PreparedStatement pstmt = null;

try{

Class.forName(driver);

conn = DriverManager.getConnection(url);

// prepare the statementpstmt = conn.prepareStatement("INSERT INTO t1 VALUES

(?, ?, ?, ?, ?, ?, ?, ?, ?)");

// bind the input parameterspstmt.setInt(1, 1);pstmt.setShort(2, (short)2);pstmt.setString(3, "data1");pstmt.setString(4, "data2");pstmt.setBigDecimal(5, new java.math.BigDecimal("12.34"));pstmt.setDate(6, new java.sql.Date(System.currentTimeMillis() ) );pstmt.setTime(7, new java.sql.Time(System.currentTimeMillis() ) );pstmt.setTimestamp (8, new java.sql.Timestamp(System.currentTimeMillis() ) );pstmt.setBytes(9, new byte[] { (byte)'X', (byte)'Y', (byte)'Z' } );

// execute the statementpstmt.execute();

pstmt.close();

conn.close();}catch (SQLException sqlEx){

while(sqlEx != null){

System.out.println("SQLERROR: \n" + sqlEx.getErrorCode() +", SQLState: " + sqlEx.getSQLState() +", Message: " + sqlEx.getMessage() +", Vendor: " + sqlEx.getErrorCode() );

sqlEx = sqlEx.getNextException();}

}catch (Exception ex){

ex.printStackTrace();}

}

Chapter 5. SQL routines 73

Page 84: IBM DB2 9.7 for Linux, UNIX, And Windows

ADO.NET Example [C#]public static void ParameterExample1(){

DB2eConnection conn = null;DB2eCommand cmd = null;String connString = @"database=.\; uid=db2e; pwd=db2e";int i = 1;

try{

conn = new DB2eConnection(connString);

conn.Open();

cmd = new DB2eCommand("INSERT INTO t1 VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)", conn);

// prepare the commandcmd.Prepare();

// bind the input parametersDB2eParameter p1 = new DB2eParameter("@p1", DB2eType.Integer);p1.Value = ++i;cmd.Parameters.Add(p1);

DB2eParameter p2 = new DB2eParameter("@p2", DB2eType.SmallInt);p2.Value = 100;cmd.Parameters.Add(p2);

DB2eParameter p3 = new DB2eParameter("@p3", DB2eType.Char);p3.Value = "data1";cmd.Parameters.Add(p3);

DB2eParameter p4 = new DB2eParameter("@p4", DB2eType.VarChar);p4.Value = "data2";cmd.Parameters.Add(p4);

DB2eParameter p5 = new DB2eParameter("@p5", DB2eType.Decimal);p5.Value = 20.25;cmd.Parameters.Add(p5);

DB2eParameter p6 = new DB2eParameter("@p6", DB2eType.Date);p6.Value = DateTime.Now;cmd.Parameters.Add(p6);

DB2eParameter p7 = new DB2eParameter("@p7", DB2eType.Time);p7.Value = new TimeSpan(23, 23, 23);cmd.Parameters.Add(p7);

DB2eParameter p8 = new DB2eParameter("@p8", DB2eType.Timestamp);p8.Value = DateTime.Now;cmd.Parameters.Add(p8);

byte []barr = new byte[3];barr[0] = (byte)'X';barr[1] = (byte)'Y';barr[2] = (byte)'Z';

DB2eParameter p9 = new DB2eParameter("@p9", DB2eType.Blob);p9.Value = barr;cmd.Parameters.Add(p9);

// execute the prepared commandcmd.ExecuteNonQuery();

}catch (DB2eException e1){

74 SQL Procedural Languages: Application Enablement and Support

Page 85: IBM DB2 9.7 for Linux, UNIX, And Windows

for (int i=0; i < e1.Errors.Count; i++){

Console.WriteLine("Error #" + i + "\n" +"Message: " + e1.Errors[i].Message + "\n" +"Native: " + e1.Errors[i].NativeError.ToString() + "\n" +"SQL: " + e1.Errors[i].SQLState + "\n");

}}catch (Exception e2){

Console.WriteLine(e2.Message);}finally{

if (conn != null && conn.State != ConnectionState.Closed){

conn.Close();conn = null;

}}

}

Variables in SQL procedures (DECLARE, SET statements)Local variable support in SQL procedures allows you to assign and retrieve SQLvalues in support of SQL procedure logic.

Variables in SQL procedures are defined by using the DECLARE statement.

Values can be assigned to variables using the SET statement or the SELECT INTOstatement or as a default value when the variable is declared. Literals, expressions,the result of a query, and special register values can be assigned to variables.

Variable values can be assigned to SQL procedure parameters, other variables inthe SQL procedure, and can be referenced as parameters within SQL statementsthat executed within the routine.

The following example demonstrates various methods for assigning and retrievingvariable values.

CREATE PROCEDURE proc_vars()SPECIFIC proc_varsLANGUAGE SQLBEGIN

DECLARE v_rcount INTEGER;

DECLARE v_max DECIMAL (9,2);

DECLARE v_adate, v_another DATE;

DECLARE v_total INTEGER DEFAULT 0; -- (1)

DECLARE v_rowsChanged BOOLEAN DEFAULT FALSE; -- (2)

SET v_total = v_total + 1 -- (3)

SELECT MAX(salary) -- (4)INTO v_max FROM employee;

VALUES CURRENT_DATE INTO v_date; -- (5)

SELECT CURRENT DATE, CURRENT DATE -- (6)INTO v_adate, v_another

FROM SYSIBM.SYSDUMMY1;

Chapter 5. SQL routines 75

Page 86: IBM DB2 9.7 for Linux, UNIX, And Windows

DELETE FROM T;GET DIAGNOSTICS v_rcount = ROW_COUNT; -- (7)

IF v_rcount > 0 THEN -- (8)SET is_done = TRUE;

END IF;END

When declaring a variable, you can specify a default value using the DEFAULTclause as in line (1). Line (2) shows the declaration of a variable of the Booleandata type with a default value of FALSE. Line (3) shows that a SET statement canbe used to assign a single variable value. Variables can also be set by executing aSELECT or FETCH statement in combination with the INTO clause as shown inline (4). Lines (5) and (6) show how the VALUES INTO statement can be used toevaluate a function or special register and assign the value to a variable or tomultiple variables.

You can also assign the result of a GET DIAGNOSTICS statement to a variable.GET DIAGNOSTICS can be used to get a handle on the number of affected rows(updated for an UPDATE statement, DELETE for a DELETE statement) or to getthe return status of a just executed SQL statement. Line (7) shows how the numberof rows modified by the just previously executed DELETE statement can beassigned to a variable.

Line (8) demonstrates how a piece of logic can be used to determine the value tobe assigned to a variable. In this case, if rows were changed as part of the earlierDELETE statement and the GET DIAGNOSTICS statement execution resulted inthe variable v_rcount being assigned a value greater than zero, the variableis_done is assigned the value TRUE.

SQLCODE and SQLSTATE variables in SQL proceduresTo perform error handling or to help you debug your SQL procedures, you mightfind it useful to test the value of the SQLCODE or SQLSTATE values, return thesevalues as output parameters or as part of a diagnostic message string, or insertthese values into a table to provide basic tracing support.

To use the SQLCODE and SQLSTATE values within SQL procedures, you mustdeclare the following SQL variables in the SQL procedure body:

DECLARE SQLCODE INTEGER DEFAULT 0;DECLARE SQLSTATE CHAR(5) DEFAULT '00000';

DB2 implicitly sets these variables whenever a statement is executed. If a statementraises a condition for which a handler exists, the values of the SQLSTATE andSQLCODE variables are available at the beginning of the handler execution.However, the variables are reset as soon as the first statement in the handler isexecuted. Therefore, it is common practice to copy the values of SQLSTATE andSQLCODE into local variables in the first statement of the handler. In the followingexample, a CONTINUE handler for any condition is used to copy the SQLCODEvariable into another variable named retcode. The variable retcode can then beused in the executable statements to control procedural logic, or pass the valueback as an output parameter.BEGIN

DECLARE SQLCODE INTEGER DEFAULT 0;DECLARE retcode INTEGER DEFAULT 0;

DECLARE CONTINUE HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND

76 SQL Procedural Languages: Application Enablement and Support

Page 87: IBM DB2 9.7 for Linux, UNIX, And Windows

SET retcode = SQLCODE;

executable-statementsEND

Note: When you access the SQLCODE or SQLSTATE variables in an SQLprocedure, DB2 sets the value of SQLCODE to 0 and SQLSTATE to ‘00000’ for thesubsequent statement.

Compound statements and scope of variables in SQLproceduresSQL procedures can contain one or more compound statements. They can beintroduced in serial or can be nested within another compound statement. Eachcompound statement introduces a new scope in which variables might or mightnot be available for use.

The use of labels to identify a compound statement is important as the label can beused to qualify and uniquely identify variables declared within the compoundstatement. This is particularly important when referencing of variables in differentcompound statements or in nested compound statements.

In the following example there are two declarations of the variable a. One instanceof it is declared in the outer compound statement that is labelled by lab1, and thesecond instance is declared in the inner compound statement labelled by lab2. As itis written, DB2 will presume that the reference to a in the assignment-statement isthe one which is in the local scope of the compound block, labelled by lab2.However, if the intended instance of the variable a is the one declared in thecompound statement block labeled with lab1, then to correctly reference it in theinnermost compound block, the variable should be qualified with the label of thatblock. That is, it should be qualified as: lab1.a.CREATE PROCEDURE P1 ()LANGUAGE SQL

lab1: BEGINDECLARE a INT DEFAULT 100;lab2: BEGIN

DECLARE a INT DEFAULT NULL;

SET a = a + lab1.a;

UPDATE T1SET T1.b = 5WHERE T1.b = a; <-- Variable a refers to lab2.a

unless qualified otherwise

END lab2;END lab1

The outermost compound statement in an SQL procedure can be declared to beatomic, by adding the keyword ATOMIC after the BEGIN keyword. If any erroroccurs in the execution of the statements that comprise the atomic compoundstatement, then the entire compound statement is rolled back.

Cursors in SQL proceduresIn SQL procedures, a cursor make it possible to define a result set (a set of datarows) and perform complex logic on a row by row basis. By using the samemechanics, an SQL procedure can also define a result set and return it directly tothe caller of the SQL procedure or to a client application.

Chapter 5. SQL routines 77

Page 88: IBM DB2 9.7 for Linux, UNIX, And Windows

A cursor can be viewed as a pointer to one row in a set of rows. The cursor canonly reference one row at a time, but can move to other rows of the result set asneeded.

To use cursors in SQL procedures, you need to do the following:1. Declare a cursor that defines a result set.2. Open the cursor to establish the result set.3. Fetch the data into local variables as needed from the cursor, one row at a time.4. Close the cursor when done

To work with cursors you must use the following SQL statements:v DECLARE CURSORv OPENv FETCHv CLOSE

The following example demonstrates the basic use of a read-only cursor within anSQL procedure:

CREATE PROCEDURE sum_salaries(OUT sum INTEGER)LANGUAGE SQLBEGIN

DECLARE p_sum INTEGER;DECLARE p_sal INTEGER;DECLARE c CURSOR FOR SELECT SALARY FROM EMPLOYEE;DECLARE SQLSTATE CHAR(5) DEFAULT '00000';

SET p_sum = 0;

OPEN c;

FETCH FROM c INTO p_sal;

WHILE(SQLSTATE = '00000') DOSET p_sum = p_sum + p_sal;FETCH FROM c INTO p_sal;

END WHILE;

CLOSE c;

SET sum = p_sum;

END%

Here is a more complex example of use of a cursor within an SQL procedure. Thisexample demonstrates the combined use of a cursor and SQL PL statements.

SQL PL logic elements in the SQL-procedure bodySequential execution is the most basic path that program execution can take. Withthis method, the program starts execution at the first line of the code, followed bythe next, and continues until the final statement in the code has been executed.This approach works fine for very simple tasks, but tends to lack usefulnessbecause it can only handle one situation. Programs often need to be able to decidewhat to do in response to changing circumstances. By controlling a code’sexecution path, a specific piece of code can then be used to intelligently handlemore than one situation.

SQL PL provides support for variables and flow of control statements that can beused to control the sequence of statement execution. Statements such as IF and

78 SQL Procedural Languages: Application Enablement and Support

Page 89: IBM DB2 9.7 for Linux, UNIX, And Windows

CASE are used to conditionally execute blocks of SQL PL statements, while otherstatements, such as WHILE and REPEAT, are typically used to execute a set ofstatements repetitively until a task is complete.

Although there are many types of SQL PL statements, there are a few categoriesinto which these can be sorted:v Variable related statementsv Conditional statementsv Loop statementsv Transfer of control statements

Variable related statements in SQL procedures: Variable related SQL statementsare used to declare variables and to assign values to variables. There are a fewtypes of variable related statements:v DECLARE <variable> statement in SQL proceduresv DECLARE <condition> statement in SQL proceduresv DECLARE <condition handler> statement in SQL proceduresv DECLARE CURSOR in SQL proceduresv SET (assignment-statement) in SQL procedures

These statements provide the necessary support required to make use of the othertypes of SQL PL statements and SQL statements that will make use of variablevalues.

Conditional statements in SQL procedures: Conditional statements are used todefine what logic is to be executed based on the status of some condition beingsatisfied. There are two types of conditional statements supported in SQLprocedures:v CASEv IF

These statements are similar; however the CASE statements extends the IFstatement.

CASE statement in SQL procedures: CASE statements can be used to conditionallyenter into some logic based on the status of a condition being satisfied. There aretwo types of CASE statements:v Simple case statement: used to enter into some logic based on a literal valuev Searched case statement: used to enter into some logic based on the value of an

expression

The WHEN clause of the CASE statement defines the value that when satisfieddetermines the flow of control.

Here is an example of an SQL procedure with a CASE statement with asimple-case-statement-when-clause:

CREATE PROCEDURE UPDATE_DEPT (IN p_workdept)LANGUAGE SQLBEGIN

DECLARE v_workdept CHAR(3);SET v_workdept = p_workdept;

CASE v_workdept

Chapter 5. SQL routines 79

Page 90: IBM DB2 9.7 for Linux, UNIX, And Windows

WHEN 'A00' THENUPDATE department SET deptname = 'D1';

WHEN 'B01' THENUPDATE department SET deptname = 'D2';

ELSEUPDATE department SET deptname = 'D3';

END CASE

END

Here is an example of CASE statement with a searched-case-statement-when-clause:

CREATE PROCEDURE UPDATE_DEPT (IN p_workdept)LANGUAGE SQLBEGIN

DECLARE v_workdept CHAR(3);SET v_workdept = p_workdept;

CASEWHEN v_workdept = 'A00' THEN

UPDATE department SET deptname = 'D1';WHEN v_workdept = 'B01' THEN

UPDATE department SET deptname = 'D2';ELSE

UPDATE department SET deptname = 'D3';END CASE

END

The examples provided above are logically equivalent, however it is important tonote that CASE statements with a searched-case-statement-when-clause can be verypowerful. Any supported SQL expression can be used here. These expressions cancontain references to variables, parameters, special registers, and more.

IF statement in SQL procedures: IF statements can be used to conditionally enterinto some logic based on the status of a condition being satisfied. The IF statementis logically equivalent to a CASE statements with a searched-case-statement-whenclause.

The IF statement supports the use of optional ELSE IF clauses and a default ELSEclause. An END IF clause is required to indicate the end of the statement.

Here is an example of procedure that contains an IF statement:CREATE PROCEDURE UPDATE_SAL (IN empNum CHAR(6),

INOUT rating SMALLINT)LANGUAGE SQLBEGIN

IF rating = 1 THENUPDATE employeeSET salary = salary * 1.10, bonus = 1000

WHERE empno = empNum;ELSEIF rating = 2 THEN

UPDATE employeeSET salary = salary * 1.05, bonus = 500

WHERE empno = empNum;ELSE

UPDATE employeeSET salary = salary * 1.03, bonus = 0

WHERE empno = empNum;END IF;

END

80 SQL Procedural Languages: Application Enablement and Support

Page 91: IBM DB2 9.7 for Linux, UNIX, And Windows

Looping statements in SQL procedures: Looping statements provide support forrepeatedly executing some logic until a condition is met. The following loopingstatements are supported in SQL PL:v FORv LOOPv REPEATv WHILE

The FOR statement is distinct from the others, because it is used to iterate overrows of a defined result set, whereas the others are using for iterating over a seriesof SQL statements until for each a condition is satisfied.

Labels can be defined for all loop-control-statements to identify them.

FOR statement in SQL procedures: FOR statements are a special type of loopingstatement, because they are used to iterate over rows in a defined read-only resultset. When a FOR statement is executed a cursor is implicitly declared such that foreach iteration of the FOR-loop the next row is the result set if fetched. Loopingcontinues until there are no rows left in the result set.

The FOR statement simplifies the implementation of a cursor and makes it easy toretrieve a set of column values for a set of rows upon which logical operations canbe performed.

Here is an example of an SQL procedure that contains only a simple FORstatement:

CREATE PROCEDURE P()LANGUAGE SQLBEGIN ATOMIC

DECLARE fullname CHAR(40);

FOR v AS cur1 CURSOR FORSELECT firstnme, midinit, lastname FROM employee

DOSET fullname = v.lastname || ',' || v.firstnme

||' ' || v.midinit;INSERT INTO tnames VALUES (fullname);

END FOR;END

Note: Logic such as is shown in the example above would be better implementedusing the CONCAT function. The simple example serves to demonstrate thesyntax.

The for-loop-name specifies a label for the implicit compound statement generatedto implemented the FOR statement. It follows the rules for the label of acompound statement. The for-loop-name can be used to qualify the column namesin the result set as returned by the select-statement.

The cursor-name simply names the cursor that is used to select the rows from theresult set. If it is not specified, the DB2 database manager will automaticallygenerate a unique cursor name internally.

The column names of the select statement must be unique and a FROM clausespecifying a table (or multiple tables if doing some kind of JOIN or UNION) is

Chapter 5. SQL routines 81

Page 92: IBM DB2 9.7 for Linux, UNIX, And Windows

required. The tables and columns referenced must exist prior to the loop beingexecuted. Global temporary tables and declared temporary tables can bereferenced.

Positioned updates and deletes, and searched updates and deletes are supported inthe FOR loop. To ensure correct results, the FOR loop cursor specification mustinclude a FOR UPDATE clause.

The cursor that is created in support of the FOR statement cannot be referencedoutside of the FOR loop.

LOOP statement in SQL procedures: The LOOP statement is a special type oflooping statement, because has no terminating condition clause. It defines a seriesof statements that are executed repeatedly until another piece of logic, generally atransfer of control statement, forces the flow of control to jump to some pointoutside of the loop.

The LOOP statement is generally used in conjunction with one of the followingstatements: LEAVE, GOTO, ITERATE, or RETURN. These statements can forcecontrol to just after the loop, to a specified location in the SQL procedure, to thestart of the loop to begin another iteration of the loop, or to exit the SQLprocedure. To indicate where to pass flow to when using these statements, labelsare used.

The LOOP statement is useful when you have complicated logic in a loop whichyou might need to exit in more than one way, however it should be used with careto avoid instances of infinite loops.

If the LOOP statement is used alone without a transfer of control statement, theseries of statements included in the loop will be executed indefinitely or until adatabase condition occurs that raises a condition handler that forces a change inthe control flow or a condition occurs that is not handled that forces the return ofthe SQL procedure.

Here is an example of an SQL procedure that contains a LOOP statement. It alsouses the ITERATE and LEAVE statements.

CREATE PROCEDURE ITERATOR()LANGUAGE SQLBEGIN

DECLARE v_deptno CHAR(3); DECLARE v_deptname VARCHAR(29);DECLARE at_end INTEGER DEFAULT 0;DECLARE not_found CONDITION FOR SQLSTATE '02000';

DECLARE c1 CURSOR FOR SELECT deptno, deptnameFROM department ORDER BY deptno;

DECLARE CONTINUE HANDLER FOR not_found SET at_end = 1;OPEN c1;

ins_loop: LOOP

FETCH c1 INTO v_deptno, v_deptname;

IF at_end = 1 THENLEAVE ins_loop;

ELSEIF v_dept = 'D11' THENITERATE ins_loop;

END IF;

INSERT INTO department (deptno, deptname)VALUES ('NEW', v_deptname);

82 SQL Procedural Languages: Application Enablement and Support

Page 93: IBM DB2 9.7 for Linux, UNIX, And Windows

END LOOP;

CLOSE c1;END

WHILE statement in SQL procedures: The WHILE statement defines a set ofstatements to be executed until a condition that is evaluated at the beginning ofthe WHILE loop is false. The while-loop-condition (an expression) is evaluatedbefore each iteration of the loop.

Here is an example of an SQL procedure with a simple WHILE loop:CREATE PROCEDURE sum_mn (IN p_start INT

,IN p_end INT,OUT p_sum INT)

SPECIFIC sum_mnLANGUAGE SQLsmn: BEGIN

DECLARE v_temp INTEGER DEFAULT 0;DECLARE v_current INTEGER;

SET v_current = p_start;

WHILE (v_current <= p_end) DOSET v_temp = v_temp + v_current;SET v_current = v_current + 1;

END WHILE;p_sum = v_current;END smn;

Note: Logic such as is shown in the example above would be better implementedusing a mathematical formula. The simple example serves to demonstrate thesyntax.

REPEAT statement in SQL procedures: The REPEAT statement defines a set ofstatements to be executed until a condition that is evaluated at the end of theREPEAT loop is true. The repeat-loop-condition is evaluated at the completion ofeach iteration of the loop.

With a WHILE statement, the loop is not entered if the while-loop-condition isfalse at 1st pass. The REPEAT statement is useful alternative; however it isnoteworthy that while-loop logic can be rewritten as a REPEAT statement.

Here is an SQL procedure that includes a REPEAT statement:CREATE PROCEDURE sum_mn2 (IN p_start INT

,IN p_end INT,OUT p_sum INT)

SPECIFIC sum_mn2LANGUAGE SQLsmn2: BEGIN

DECLARE v_temp INTEGER DEFAULT 0;DECLARE v_current INTEGER;

SET v_current = p_start;

REPEATSET v_temp = v_temp + v_current;

Chapter 5. SQL routines 83

Page 94: IBM DB2 9.7 for Linux, UNIX, And Windows

SET v_current = v_current + 1;UNTIL (v_current > p_end)END REPEAT;

END

Transfer of control statements in SQL procedures: Transfer of control statementsare used to redirect the flow of control within an SQL procedure. Thisunconditional branching can be used to cause the flow of control to jump from onepoint to another point, which can either precede or follow the transfer of controlstatement. The supported transfer of control statements in SQL procedures are:v GOTOv ITERATEv LEAVEv RETURN

Transfer of control statements can be used anywhere within an SQL procedure,however ITERATE and LEAVE are generally used in conjunction with a LOOPstatement or other looping statements.

GOTO statement in SQL procedures: The GOTO statement is a straightforward andbasic flow of control statement that causes an unconditional change in the flow ofcontrol. It is used to branch to a specific user-defined location using labels definedin the SQL procedure.

Use of the GOTO statement is generally considered to be poor programmingpractice and is not recommended. Extensive use of GOTO tends to lead tounreadable code especially when procedures grow long. Besides, GOTO is notnecessary because there are better statements available to control the executionpath. There are no specific situations that require the use of GOTO; instead it ismore often used for convenience.

Here is an example of an SQL procedure that contains a GOTO statement:CREATE PROCEDURE adjust_salary ( IN p_empno CHAR(6),

IN p_rating INTEGER,OUT p_adjusted_salary DECIMAL (8,2) )

LANGUAGE SQLBEGIN

DECLARE new_salary DECIMAL (9,2);DECLARE service DATE; -- start date

SELECT salary, hiredate INTO v_new_salary, v_serviceFROM employee

WHERE empno = p_empno;

IF service > (CURRENT DATE - 1 year) THENGOTO exit;

END IF;

IF p_rating = 1 THENSET new_salary = new_salary + (new_salary * .10);

END IF;

UPDATE employee SET salary = new_salary WHERE empno = p_empno;

exit:SET p_adjusted_salary = v_new_salary;

END

84 SQL Procedural Languages: Application Enablement and Support

Page 95: IBM DB2 9.7 for Linux, UNIX, And Windows

This example demonstrates what of the good uses of the GOTO statement:skipping almost to the end of a procedure or loop so as not to execute some logic,but to ensure that some other logic does still get executed.

You should be aware of a few additional scope considerations when using theGOTO statement:v If the GOTO statement is defined in a FOR statement, the label must be defined

inside the same FOR statement, unless it is in a nested FOR statement or nestedcompound statement.

v If the GOTO statement is defined in a compound statement, the label must bedefined in side the same compound statement, unless it is in a nested FORstatement or nested compound statement.

v If the GOTO statement is defined in a handler, the label must be defined in thesame handler, following the other scope rules.

v If the GOTO statement is defined outside of a handler, the label must not bedefined within a handler.

v If the label is not defined within a scope that the GOTO statement can reach, anerror is returned (SQLSTATE 42736).

ITERATE statement in SQL procedures: The ITERATE statement is used to cause theflow of control to return to the beginning of a labeled LOOP statement.

Here is an example of an SQL procedure that contains an ITERATE statement:CREATE PROCEDURE ITERATOR()LANGUAGE SQLBEGIN

DECLARE v_deptno CHAR(3); DECLARE v_deptname VARCHAR(29);DECLARE at_end INTEGER DEFAULT 0;DECLARE not_found CONDITION FOR SQLSTATE '02000';

DECLARE c1 CURSOR FOR SELECT deptno, deptnameFROM department ORDER BY deptno;

DECLARE CONTINUE HANDLER FOR not_found SET at_end = 1;OPEN c1;

ins_loop: LOOPFETCH c1 INTO v_deptno, v_deptname;

IF at_end = 1 THENLEAVE ins_loop;

ELSEIF v_dept = 'D11' THENITERATE ins_loop;

END IF;

INSERT INTO department (deptno, deptname)VALUES ('NEW', v_deptname);

END LOOP;

CLOSE c1;

END

In the example, the ITERATE statement is used to return the flow of control to theLOOP statement defined with label ins_loop when a column value in a fetchedrow matches a certain value. The position of the ITERATE statement ensures thatno values are inserted into the department table.

LEAVE statement in SQL procedures: The LEAVE statement is used to transfer theflow of control out of a loop or compound statement.

Chapter 5. SQL routines 85

Page 96: IBM DB2 9.7 for Linux, UNIX, And Windows

Here is an example of an SQL procedure that contain a LEAVE statement:CREATE PROCEDURE ITERATOR()LANGUAGE SQLBEGIN

DECLARE v_deptno CHAR(3); DECLARE v_deptname VARCHAR(29);DECLARE at_end INTEGER DEFAULT 0;DECLARE not_found CONDITION FOR SQLSTATE '02000';

DECLARE c1 CURSOR FOR SELECT deptno, deptnameFROM department ORDER BY deptno;

DECLARE CONTINUE HANDLER FOR not_found SET at_end = 1;

OPEN c1;

ins_loop: LOOP

FETCH c1 INTO v_deptno, v_deptname;

IF at_end = 1 THENLEAVE ins_loop;

ELSEIF v_dept = 'D11' THENITERATE ins_loop;

END IF;

INSERT INTO department (deptno, deptname)VALUES ('NEW', v_deptname);

END LOOP;

CLOSE c1;END

In the example, the LEAVE statement is used to exit the LOOP statement definedwith label ins_loop. It is nested within an IF statement and therefore isconditionally executed when the IF-condition is true which becomes true whenthere are no more rows found in the cursor. The position of the LEAVE statementensures that no further iterations of the loop are executed once a NOT FOUNDerror is raised.

RETURN statement in SQL procedures: The RETURN statement is used tounconditionally and immediately terminate an SQL procedure by returning theflow of control to the caller of the stored procedure.

It is mandatory that when the RETURN statement is executed that it return aninteger value. If the return value is not provided, the default is 0. The value istypically used to indicate success or failure of the procedure’s execution. The valuecan be a literal, variable, or an expression that evaluates to an integer value.

You can use one or more RETURN statements in a stored procedure. The RETURNstatement can be used anywhere after the declaration blocks within theSQL-procedure-body.

To return multiple output values, parameters can be used instead. Parametervalues must be set prior to the RETURN statement being executed.

Here is an example of an SQL procedure that uses the RETURN statement:CREATE PROCEDURE return_test (IN p_empno CHAR(6),

IN p_emplastname VARCHAR(15) )LANGUAGE SQLSPECIFIC return_testBEGIN

86 SQL Procedural Languages: Application Enablement and Support

Page 97: IBM DB2 9.7 for Linux, UNIX, And Windows

DECLARE v_lastname VARCHAR (15);

SELECT lastname INTO v_lastnameFROM employee

WHERE empno = p_empno;

IF v_lastname = p_emplastname THENRETURN 1;

ELSERETURN -1;

END IF;

END rt

In the example, if the parameter p_emplastname matches the value stored in tableemployee, the procedure returns 1. If it does not match, it returns -1.

Condition handlers in SQL procedures: Condition handlers determine thebehavior of your SQL procedure when a condition occurs. You can declare one ormore condition handlers in your SQL procedure for general conditions, namedconditions, or specific SQLSTATE values.

If a statement in your SQL procedure raises an SQLWARNING or NOT FOUNDcondition, and you have declared a handler for the respective condition, DB2passes control to the corresponding handler. If you have not declared a handler forsuch a condition, DB2 passes control to the next statement in the SQL procedurebody. If the SQLCODE and SQLSTATE variables have been declared, they willcontain the corresponding values for the condition.

If a statement in your SQL procedure raises an SQLEXCEPTION condition, andyou declared a handler for the specific SQLSTATE or the SQLEXCEPTIONcondition, DB2 passes control to that handler. If the SQLSTATE and SQLCODEvariables have been declared, their values after the successful execution of ahandler will be ‘00000’ and 0 respectively.

If a statement in your SQL procedure raises an SQLEXCEPTION condition, andyou have not declared a handler for the specific SQLSTATE or theSQLEXCEPTION condition, DB2 terminates the SQL procedure and returns to thecaller.

The handler declaration syntax for condition handlers is described in CompoundSQL (Procedure) statement.

Returning result sets from SQL procedures

In SQL procedures, cursors can be used to do more than iterate through rows of aresult set. They can also be used to return result sets to the calling program. Resultsets can be retrieved by SQL procedures (in the case of a nested procedure calls) orclient applications programmed in C using the CLI application programminginterface, Java, CLI, or .NET CLR languages.

Prerequisites

v Authority to create an SQL procedure

To return a result set from an SQL procedure, you must:1. Specify the DYNAMIC RESULT SETS clause in the CREATE PROCEDURE

statement

Chapter 5. SQL routines 87

Page 98: IBM DB2 9.7 for Linux, UNIX, And Windows

2. DECLARE the cursor using the WITH RETURN clause3. Open the cursor in the SQL procedure4. Keep the cursor open for the client application - do not close it

Here is an example of an SQL procedure that only returns a single result set:CREATE PROCEDURE read_emp()SPECIFIC read_empLANGUAGE SQLDYNAMIC RESULT SETS 1

Re: BEGIN

DECLARE c_emp CURSOR WITH RETURN FORSELECT salary, bonus, comm.FROM employeeWHERE job != 'PRES';

OPEN c_emp;

END Re

If the cursor is closed using the CLOSE statement prior to the return of the SQLprocedure, the cursor result set will not be returned to the caller or clientapplication.

Multiple result sets can be returned from an SQL procedure by using multiplecursors. To return multiple cursors the following must be done:v Specify the DYNAMIC RESULT SETS clause in the CREATE PROCEDURE

statement. Specify the maximum possible number of result sets likely to bereturned. The number of results sets actually returned must not exceed thisnumber.

v Declare cursors for each of the result sets to be returned that specify the WITHRETURN clause.

v Open the cursors to be returned.v Keep the cursor open for the client application - do not close them.

One cursor is required per result set that is to be returned.

Result sets are returned to the caller in the order in which they are opened.

Once you have created the SQL procedure that returns a result set you might wantto call it and retrieve the result set.

Multiple result sets can also be returned by enabling multiple instances of a samecursor. You must DECLARE the cursor using the WITH RETURN TO CLIENT.

An example to enable multiple instances of an open cursor using the WITHRETURN TO CLIENT:CREATE PROCEDURE PROC(IN a INT)BEGIN

DECLARE index INTEGER DEFAULT 1;WHILE index < a DO

BEGINDECLARE cur CURSOR WITH RETURN TO CLIENT FOR SELECT * FROM T WHERE pk = index;OPEN cur;SET index = index + 1;

88 SQL Procedural Languages: Application Enablement and Support

Page 99: IBM DB2 9.7 for Linux, UNIX, And Windows

END;END WHILE;

END@

Receiving procedure result sets in SQL routinesYou can receive result sets from procedures you invoke from within an SQL-bodiedroutine.

You must know how many result sets the invoked procedure will return. For eachresult set that the invoking routine receives, a result set must be declared.

To accept procedure result sets from within an SQL-bodied routine:1. DECLARE result set locators for each result set that the procedure will return.

For example:DECLARE result1 RESULT_SET_LOCATOR VARYING;DECLARE result2 RESULT_SET_LOCATOR VARYING;DECLARE result3 RESULT_SET_LOCATOR VARYING;

2. Invoke the procedure. For example:CALL targetProcedure();

3. ASSOCIATE the result set locator variables (defined above) with the invokedprocedure. For example:

ASSOCIATE RESULT SET LOCATORS(result1, result2, result3)WITH PROCEDURE targetProcedure;

4. ALLOCATE the result set cursors passed from the invoked procedure to theresult set locators. For example:

ALLOCATE rsCur CURSOR FOR RESULT SET result1;

5. FETCH rows from the result sets. For example:FETCH rsCur INTO ...

Creating SQL procedures

Creating SQL procedures is similar to creating any database object in that itconsists of executing a DDL SQL statement.

SQL procedures are created by executing the CREATE PROCEDURE statementwhich can be done using graphical development environment tools or by directlyexecuting the statement from the DB2 Command Line Processor (CLP), a DB2Command Window, the DB2 Command Editor, or another DB2 interface.

When creating SQL procedures, you can specify how the precompiler and bindershould generate the procedure package, what authorization ID should be used toset the SQL procedure definer in the DB2 catalog views, and to set other packageoptions.

Creating SQL procedures from the command line

Prerequisites

v The user must have the privileges required to execute the CREATEPROCEDURE statement for an SQL procedure.

v Privileges to execute all of the SQL statements included within theSQL-procedure-body of the procedure.

v Any database objects referenced in the CREATE PROCEDURE statement for theSQL procedure must exist prior to the execution of the statement.

Chapter 5. SQL routines 89

Page 100: IBM DB2 9.7 for Linux, UNIX, And Windows

Procedure

v Select an alternate terminating character for the Command Line Processor (DB2CLP) other than the default terminating character, which is a semicolon (’;’), touse in the script that you will prepare in the next step.This is required so that the CLP can distinguish the end of SQL statements thatappear within the body of a routine’s CREATE statement from the end of theCREATE PROCEDURE statement itself. The semicolon character must be used toterminate SQL statements within the SQL routine body and the chosen alternateterminating character should be used to terminate the CREATE statement andany other SQL statements that you might contain within your CLP script.For example, in the following CREATE PROCEDURE statement, the ’at;’ sign(’@’) is used as the terminating character for a DB2 CLP script namedmyCLPscript.db2:

CREATE PROCEDURE UPDATE_SALARY_IF(IN employee_number CHAR(6), IN rating SMALLINT)LANGUAGE SQLBEGIN

DECLARE not_found CONDITION FOR SQLSTATE '02000';DECLARE EXIT HANDLER FOR not_found

SIGNAL SQLSTATE '20000' SET MESSAGE_TEXT = 'Employee not found';

IF (rating = 1)THEN UPDATE employee

SET salary = salary * 1.10, bonus = 1000WHERE empno = employee_number;

ELSEIF (rating = 2)THEN UPDATE employee

SET salary = salary * 1.05, bonus = 500WHERE empno = employee_number;

ELSE UPDATE employeeSET salary = salary * 1.03, bonus = 0WHERE empno = employee_number;

END IF;END

@

v Run the DB2 CLP script containing the CREATE PROCEDURE statement for theprocedure from the command line, using the following CLP command:

db2 -td <terminating-character> -vf <CLP-script-name>

where <terminating-character> is the terminating character used in the CLP scriptfile CLP-script-name that is to be run.The DB2 CLP option -td indicates that the CLP terminator default is to be resetwith terminating character. The -vf indicates that the CLP’s optional verbose (-v)option is to be used, which will cause each SQL statement or command in thescript to be displayed to the screen as it is run, along with any output thatresults from its execution. The -f option indicates that the target of the commandis a file.To run the specific script shown in the first step, issue the following commandfrom the system command prompt:

db2 -td@ -vf myCLPscript.db2

Customizing precompile and bind options for compiled SQLobjects

The precompile and bind options for SQL procedures, compiled functions,compiled triggers and compound SQL (complied) statements can be customized bysetting the instance-wide DB2 registry variable, DB2_SQLROUTINE_PREPOPTS with thecommand:

90 SQL Procedural Languages: Application Enablement and Support

Page 101: IBM DB2 9.7 for Linux, UNIX, And Windows

db2set DB2_SQLROUTINE_PREPOPTS=<options>

The options can be changed at the procedure level with the SET_ROUTINE_OPTSstored procedure. The values of the options set for the creation of SQL proceduresin the current session can be obtained with the GET_ROUTINE_OPTS function.The options used to compile a given routine are stored in the system catalog tableROUTINES.PRECOMPILE_OPTIONS, in the row corresponding to the routine. Ifthe routine is revalidated, those stored options are also used during therevalidation.After a routine is created, the compile options can be altered using theSYSPROC.ALTER_ROUTINE_PACKAGE andSYSPROC.REBIND_ROUTINE_PACKAGE procedures. The altered options arereflected in the ROUTINES_PRECOMPILE_OPTIONS system catalog table.

Note: Cursor blocking is disabled in SQL procedures for cursors referenced inFETCH statements and for implicit cursors in FOR statements. Regardless of thevalue specified for the BLOCKING bind option, data will be retrieved one row at atime in an optimized, highly efficient manner.

Example.

The SQL procedures used in this example will be defined in CLP scripts(given below). These scripts are not in the sqlpl samples directory, but youcan easily create these files by cutting-and-pasting the CREATE procedurestatements into your own files.

The examples use a table named ″expenses″, which you can create in thesample database as follows:

db2 connect to sampledb2 CREATE TABLE expenses(amount DOUBLE, date DATE)db2 connect reset

To begin, specify the use of ISO format for dates as an instance-widesetting:

db2set DB2_SQLROUTINE_PREPOPTS="DATETIME ISO"db2stopdb2start

Stopping and restarting DB2 is necessary for the change to take affect.

Then connect to the database:db2 connect to sample

The first procedure is defined in CLP script maxamount.db2 as follows:CREATE PROCEDURE maxamount(OUT maxamnt DOUBLE)BEGIN

SELECT max(amount) INTO maxamnt FROM expenses;END @

It will be created with options DATETIME ISO and ISOLATION UR:db2 "CALL SET_ROUTINE_OPTS(GET_ROUTINE_OPTS() || ' ISOLATION UR')"db2 -td@ -vf maxamount.db2

The next procedure is defined in CLP script fullamount.db2 as follows:CREATE PROCEDURE fullamount(OUT fullamnt DOUBLE)BEGIN

SELECT sum(amount) INTO fullamnt FROM expenses;END @

Chapter 5. SQL routines 91

Page 102: IBM DB2 9.7 for Linux, UNIX, And Windows

It will be created with option ISOLATION CS (note that we are not using theinstance-wide DATETIME ISO setting in this case):

CALL SET_ROUTINE_OPTS('ISOLATION CS')db2 -td@ -vf fullamount.db2

The last procedure in the example is defined in CLP script perday.db2 asfollows:CREATE PROCEDURE perday()BEGIN

DECLARE cur1 CURSOR WITH RETURN FORSELECT date, sum(amount)FROM expensesGROUP BY date;

OPEN cur1;END @

The last SET_ROUTINE_OPTS call uses the NULL value as the argument. Thisrestores the global setting specified in the DB2_SQLROUTINE_PREPOPTSregistry, so the last procedure will be created with option DATETIME ISO:

CALL SET_ROUTINE_OPTS(NULL)db2 -td@ -vf perday.db2

Improving the performance of SQL proceduresOverview of how DB2 compiles SQL PL and inline SQL PL

Before discussing how to improve the performance of SQL procedures we shoulddiscuss how DB2 compiles them upon the execution of the CREATE PROCEDUREstatement.

When an SQL procedure is created, DB2 separates the SQL queries in theprocedure body from the procedural logic. To maximize performance, the SQLqueries are statically compiled into sections in a package. For a statically compiledquery, a section consists mainly of the access plan selected by the DB2 optimizerfor that query. A package is a collection of sections. For more information onpackages and sections, please refer to the DB2 SQL Reference. The procedural logicis compiled into a dynamically linked library.

During the execution of a procedure, every time control flows from the procedurallogic to an SQL statement, there is a ″context switch″ between the DLL and theDB2 engine. As of DB2 Version 8.1, SQL procedures run in ″unfenced mode″. Thatis they run in the same addressing space as the DB2 engine. Therefore the contextswitch we refer to here is not a full context switch at the operating system level,but rather a change of layer within DB2. Reducing the number of context switchesin procedures that are invoked very often, such as procedures in an OLTPapplication, or that process large numbers of rows, such as procedures thatperform data cleansing, can have a noticeable impact on their performance.

Whereas an SQL procedure containing SQL PL is implemented by staticallycompiling its individual SQL queries into sections in a package, an inline SQL PLfunction is implemented, as the name suggests, by inlining the body of thefunction into the query that uses it. Queries in SQL functions are compiledtogether, as if the function body were a single query. The compilation occurs everytime a statement that uses the function is compiled. Unlike what happens in SQLprocedures, procedural statements in SQL functions are not executed in a differentlayer than dataflow statements. Therefore, there is no context switch every timecontrol flows from a procedural to a dataflow statement or vice versa.

92 SQL Procedural Languages: Application Enablement and Support

Page 103: IBM DB2 9.7 for Linux, UNIX, And Windows

If there are no side-effects in your logic use an SQL functioninstead

Because of the difference in compilation between SQL PL in procedures and inlineSQL PL in functions, it is reasonable to presume that a piece of procedural codewill execute faster in a function than in a procedure if it only queries SQL data anddoes no data modifications - that is it has no side-effects on the data in thedatabase or external to the database.

That is only good news if all the statements that you need to execute aresupported in SQL functions. SQL functions can not contain SQL statements thatmodify the database. As well, only a subset of SQL PL is available in the inlineSQL PL of functions. For example, you cannot execute CALL statements, declarecursors, or return result sets in SQL functions.

Here is an example of an SQL procedure containing SQL PL that was a goodcandidate for conversion to an SQL function to maximize performance:

CREATE PROCEDURE GetPrice (IN Vendor CHAR&(20&),IN Pid INT, OUT price DECIMAL(10,3))

LANGUAGE SQLBEGIN

IF Vendor eq; ssq;Vendor 1ssq;THEN SET price eq; (SELECT ProdPrice

FROM V1TableWHERE Id = Pid);

ELSE IF Vendor eq; ssq;Vendor 2ssq;THEN SET price eq; (SELECT Price FROM V2Table

WHERE Pid eq; GetPrice.Pid);END IF;

END

Here is the rewritten SQL function:CREATE FUNCTION GetPrice (Vendor CHAR(20), Pid INT)RETURNS DECIMAL(10,3)LANGUAGE SQLBEGIN

DECLARE price DECIMAL(10,3);IF Vendor = 'Vendor 1'

THEN SET price = (SELECT ProdPriceFROM V1TableWHERE Id = Pid);

ELSE IF Vendor = 'Vendor 2'THEN SET price = (SELECT Price FROM V2Table

WHERE Pid = GetPrice.Pid);END IF;RETURN price;

END

Remember that the invocation of a function is different than a procedure. Toinvoke the function, use the VALUES statement or invoke the function where anexpression is valid, such as in a SELECT or SET statement. Any of the followingare valid ways of invoking the new function:

VALUES (GetPrice('IBM', 324))

SELECT VName FROM Vendors WHERE GetPrice(Vname, Pid) < 10

SET price = GetPrice(Vname, Pid)

Chapter 5. SQL routines 93

Page 104: IBM DB2 9.7 for Linux, UNIX, And Windows

Avoid multiple statements in an SQL PL procedure when justone is sufficient

Although it is generally a good idea to write concise SQL, it is very ease to forgetto do this in practice. For example the following SQL statements:

INSERT INTO tab_comp VALUES (item1, price1, qty1);INSERT INTO tab_comp VALUES (item2, price2, qty2);INSERT INTO tab_comp VALUES (item3, price3, qty3);

can be rewritten as a single statement:INSERT INTO tab_comp VALUES (item1, price1, qty1),

(item2, price2, qty2),(item3, price3, qty3);

The multi-row insert will require roughly one third of the time required to executethe three original statements. Isolated, this improvement might seem negligible,but if the code fragment is executed repeatedly, for example in a loop or in atrigger body, the improvement can be significant.

Similarly, a sequence of SET statements like:SET A = expr1;SET B = expr2;SET C = expr3;

can be written as a single VALUES statement:VALUES expr1, expr2, expr3 INTO A, B, C;

This transformation preserves the semantics of the original sequence if there are nodependencies between any two statements. To illustrate this, consider:

SET A = monthly_avg * 12;SET B = (A / 2) * correction_factor;

Converting the previous two statements to:VALUES (monthly_avg * 12, (A / 2) * correction_factor) INTO A, B;

does not preserve the original semantics because the expressions before the INTOkeyword are evaluated ’in parallel’. This means that the value assigned to B is notbased on the value assigned to A, which was the intended semantics of the originalstatements.

Reduce multiple SQL statements to a single SQL expression

Like other programming languages, the SQL language provides two types ofconditional constructs: procedural (IF and CASE statements) and functional (CASEexpressions). In most circumstances where either type can be used to express acomputation, using one or the other is a matter of taste. However, logic writtenusing CASE expressions is not only more compact, but also more efficient thanlogic written using CASE or IF statements.

Consider the following fragment of SQL PL code:IF (Price <= MaxPrice) THEN

INSERT INTO tab_comp(Id, Val) VALUES(Oid, Price);ELSE

INSERT INTO tab_comp(Id, Val) VALUES(Oid, MaxPrice);END IF;

94 SQL Procedural Languages: Application Enablement and Support

Page 105: IBM DB2 9.7 for Linux, UNIX, And Windows

The condition in the IF clause is only being used to decide what value is insertedin the tab_comp.Val column. To avoid the context switch between the proceduraland the dataflow layers, the same logic can be expressed as a single INSERT with aCASE expression:

INSERT INTO tab_comp(Id, Val)VALUES(Oid,

CASEWHEN (Price <= MaxPrice) THEN PriceELSE MaxPrice

END);

It’s worth noting that CASE expressions can be used in any context where a scalarvalue is expected. In particular, they can be used on the right-hand side ofassignments. For example:

IF (Name IS NOT NULL) THENSET ProdName = Name;

ELSEIF (NameStr IS NOT NULL) THENSET ProdName = NameStr;

ELSESET ProdName = DefaultName;

END IF;

can be rewritten as:SET ProdName = (CASE

WHEN (Name IS NOT NULL) THEN NameWHEN (NameStr IS NOT NULL) THEN NameStrELSE DefaultName

END);

In fact, this particular example admits an even better solution:SET ProdName = COALESCE(Name, NameStr, DefaultName);

Don’t underestimate the benefit of taking the time to analyze and considerrewriting your SQL. The performance benefits will pay you back many times overfor the time invested in analyzing and rewriting your procedure.

Exploit the set-at-a-time semantics of SQL

Procedural constructs such as loops, assignment and cursors allow us to expresscomputations that would not be possible to express using just SQL DMLstatements. But when we have procedural statements at our disposal, there is arisk that we could turn to them even when the computation at hand can, in fact,be expressed using just SQL DML statements. As we’ve mentioned earlier, theperformance of a procedural computation can be orders of magnitude slower thanthe performance of an equivalent computation expressed using DML statements.Consider the following fragment of code:

DECLARE cur1 CURSOR FOR SELECT col1, col2 FROM tab_comp;OPEN cur1;FETCH cur1 INTO v1, v2;WHILE SQLCODE <> 100 DO

IF (v1 > 20) THENINSERT INTO tab_sel VALUES (20, v2);

ELSEINSERT INTO tab_sel VALUES (v1, v2);

END IF;FETCH cur1 INTO v1, v2;

END WHILE;

Chapter 5. SQL routines 95

Page 106: IBM DB2 9.7 for Linux, UNIX, And Windows

To begin with, the loop body can be improved by applying the transformationdiscussed in the last section - ″Reduce multiple SQL statements to a single SQLexpression″:

DECLARE cur1 CURSOR FOR SELECT col1, col2 FROM tab_comp;OPEN cur1;FETCH cur1 INTO v1, v2;WHILE SQLCODE <> 100 DO

INSERT INTO tab_sel VALUES (CASEWHEN v1 > 20 THEN 20ELSE v1

END, v2);FETCH cur1 INTO v1, v2;

END WHILE;

But upon closer inspection, the whole block of code can be written as an INSERTwith a sub-SELECT:

INSERT INTO tab_sel (SELECT (CASEWHEN col1 > 20 THEN 20ELSE col1

END),col2

FROM tab_comp);

In the original formulation, there was a context switch between the procedural andthe dataflow layers for each row in the SELECT statements. In the last formulation,there is no context switch at all, and the optimizer has a chance to globallyoptimize the full computation.

On the other hand, this dramatic simplification would not have been possible ifeach of the INSERT statements targeted a different table, as shown below:

DECLARE cur1 CURSOR FOR SELECT col1, col2 FROM tab_comp;OPEN cur1;FETCH cur1 INTO v1, v2;WHILE SQLCODE <> 100 DO

IF (v1 > 20) THENINSERT INTO tab_default VALUES (20, v2);

ELSEINSERT INTO tab_sel VALUES (v1, v2);

END IF;FETCH cur1 INTO v1, v2;

END WHILE;

However, the set-at-a-time nature of SQL can also be exploited here:INSERT INTO tab_sel (SELECT col1, col2

FROM tab_compWHERE col1 <= 20);

INSERT INTO tab_default (SELECT col1, col2FROM tab_compWHERE col1 > 20);

When looking at improving the performance of existing procedural logic, any timespent in eliminating cursor loops will likely pay off.

Keep the DB2 optimizer informed

When a procedure is created, its individual SQL queries are compiled into sectionsin a package. The DB2 optimizer chooses an execution plan for a query based,among other things, on table statistics (for example, table sizes or the relativefrequency of data values in a column) and indexes available at the time the queryis compiled. When tables suffer significant changes, it may be a good idea to let

96 SQL Procedural Languages: Application Enablement and Support

Page 107: IBM DB2 9.7 for Linux, UNIX, And Windows

DB2 collect statistics on these tables again. And when statistics are updated or newindexes are created, it may also be a good idea to rebind the packages associatedwith SQL procedures that use the tables, to let DB2 create plans that exploit thelatest statistics and indexes.

Table statistics can be updated using the RUNSTATS command. To rebind thepackage associated with an SQL procedure, you can use theREBIND_ROUTINE_PACKAGE built-in procedure that is available in DB2 Version8.1. For example, the following command can be used to rebind the package forprocedure MYSCHEMA.MYPROC:

CALL SYSPROC.REBIND_ROUTINE_PACKAGE('P', 'MYSCHEMA.MYPROC', 'ANY')

where ’P’ indicates that the package corresponds to a procedure and ’ANY’indicates that any of the functions and types in the SQL path are considered forfunction and type resolution. See the Command Reference entry for the REBINDcommand for more details.

Use arrays

You can use arrays to efficiently pass collections of data between applications andstored procedures and to store and manipulate transient collections of data withinSQL procedures without having to use relational tables. Operators on arraysavailable within SQL procedures allow for the efficient storage and retrieval ofdata. Applications that create arrays of moderate size will experience significantlybetter performance than applications that create very large arrays (on the scale ofmultiple megabytes), as the entire array is stored in main memory. See Related linkssection for additional information.

SQL functionsSQL functions are functions implemented completely with SQL that can be used toencapsulate logic that can be invoked like a programming sub-routine. You cancreate SQL scalar functions and SQL table functions.

There are many useful applications for SQL functions within a database ordatabase application architecture. SQL functions can be used to create operators oncolumn data, for extending the support of built-in functions, for makingapplication logic more modular, and for improving overall database design, anddatabase security.

The following topics provide more information about SQL functions:

Features of SQL functionsSQL functions are characterized by many general features:

SQL functions:v Can contain SQL Procedural Language statements and features which support

the implementation of control-flow logic around traditional static and dynamicSQL statements.

v Are supported in the entire DB2 family brand of database products in whichmany if not all of the features supported in DB2 Version 9 are supported.

v Are easy to implement, because they use a simple high-level, strongly typedlanguage.

v SQL functions are more reliable than equivalent external functions.

Chapter 5. SQL routines 97

Page 108: IBM DB2 9.7 for Linux, UNIX, And Windows

v Support input parameters.v SQL scalar functions return a scalar value.v SQL table functions return a table result set.v Support a simple, but powerful condition and error-handling model.v Allow you to easily access the SQLSTATE and SQLCODE values as special

variables.v Reside in the database and are automatically backed up and restored as part of

backup and restore operations.v Can be invoked wherever expressions in an SQL statement are supported.v Support nested functions calls to other SQL functions or functions implemented

in other languages.v Support recursion (when dynamic SQL is used in compiled functions).v Can be invoked from triggers.v Many SQL statements can be included within SQL functions, however there are

exceptions. For the complete list of SQL statements that can included andexecuted in SQL functions, see:SQL statements that can be executed in routines

SQL functions provide extensive support not limited to what is listed above. Whenimplemented according to best practices, they can play an essential role indatabase architecture, database application design, and in database systemperformance.

Designing SQL functionsDesigning SQL functions is a task that you perform before creating SQL functionsin a database.

To design SQL functions it is important to be familiar with the features of SQLfunctions. The following topics provide more information about SQL functiondesign concepts:

Inlined SQL functions and compiled SQL functionsThere are two implementation types for SQL functions: inlined SQL functions andcompiled SQL functions.

Inlined SQL functions

Inlined SQL functions are SQL functions that are created using theCREATE FUNCTION statement with a body that is either a RETURNstatement or an inline compound statement. Inline compound statementsare defined with the BEGIN ATOMIC and END keywords.

Inlined SQL functions can contain SQL statements and inline SQL PLstatements - a subset of SQL PL statements.

Compiled SQL functions

Compiled SQL functions are SQL functions that are created using theCREATE FUNCTION statement with a body that is either a RETURNstatement or a compiled compound statement. Compiled compoundstatements are defined with the BEGIN and END keywords.

When the ATOMIC clause is omitted, SQL functions are compiled and assuch can include or reference more SQL PL features than inlined SQLfunctions. Compiled SQL functions can include the following featureswhich are not supported in inlined SQL functions:v SQL PL statements, including:

98 SQL Procedural Languages: Application Enablement and Support

Page 109: IBM DB2 9.7 for Linux, UNIX, And Windows

– CASE statement– REPEAT statement

v Cursor processingv Dynamic SQLv Condition handlers

Restrictions on SQL functionsIt is important to note the restrictions on SQL functions before creating them orwhen troubleshooting problems related to their implementation and use.

The following restrictions apply to SQL functions:v SQL table functions cannot contain compiled compound statements.v SQL scalar functions containing compiled compound statements cannot be

invoked in partitioned database environments.v By definition, SQL functions cannot contain cursors defined with the WITH

RETURN clause.v Compiled SQL scalar functions cannot be invoked in partitioned database

environments.v The following data types are not supported within compiled SQL functions:

structured data types, XML data type, LONG VARCHAR data type, and LONGVARGRAPHIC data type.

v In this version, use of the DECLARE TYPE statement within compiled SQLfunctions is not supported.

Creating SQL scalar functionsCreating SQL scalar functions is a task that you would perform when designing adatabase or when developing applications. SOL scalar functions are generallycreated when there is an identifiable benefit in encapsulating a piece of reusablelogic so that it can be referenced within SQL statements in multiple applications orwithin database objects.

Before you begin

Before you create an SQL function:v Read: “SQL functions” on page 97v Read: “Features of SQL functions” on page 97v Ensure that you have the privileges required to execute the CREATE

FUNCTION (scalar) statement.

Restrictions

See:“Restrictions on SQL functions”

Procedure

1. Define the CREATE FUNCTION (scalar) statement:a. Specify a name for the function.b. Specify a name and data type for each input parameter.c. Specify the RETURNS keyword and the data type of the scalar return value.d. Specify the BEGIN keyword to introduce the function-body. Note: Use of

the BEGIN ATOMIC keyword is not recommended for new functions.

Chapter 5. SQL routines 99

Page 110: IBM DB2 9.7 for Linux, UNIX, And Windows

e. Specify the function body. Specify the RETURN clause and a scalar returnvalue or variable.

f. Specify the END keyword.2. Execute the CREATE FUNCTION (scalar) statement from a supported interface.

Results

The CREATE FUNCTION (scalar) statement should execute successfully and thescalar function should be created.

Example

Example 1:

The following is an example of a compiled SQL function:CREATE FUNCTION GetPrice (Vendor CHAR(20), Pid INT)

RETURNS DECIMAL(10,3)LANGUAGE SQLMODIFIES SQLBEGIN

DECLARE price DECIMAL(10,3);

IF Vendor = 'Vendor 1'THEN SET price = (SELECT ProdPrice FROM V1Table WHERE Id = Pid);

ELSE IF Vendor = 'Vendor 2'THEN SET price = (SELECT Price

FROM V2TableWHERE Pid = GetPrice.Pid);

END IF;

RETURN price;END

This function takes in two input parameters and returns a single scalar value,conditionally based on the input parameter values. It requires the declaration anduse of a local variable named price to hold the value to be returned until thefunction returns.

Example 2:

The following example demonstrates a compiled SQL function definitioncontaining a cursor, condition handler statement, and a REPEAT statement:

CREATE FUNCTION exit_func(a INTEGER)SPECIFIC exit_funcLANGUAGE SQLRETURNS INTEGERBEGIN

DECLARE val INTEGER DEFAULT 0;

DECLARE myint INTEGER DEFAULT 0;

DECLARE cur2 CURSOR FORSELECT c2 FROM udfd1

WHERE c1 <= aORDER BY c1;

DECLARE EXIT HANDLER FOR NOT FOUNDBEGIN

SIGNAL SQLSTATE '70001'SET MESSAGE_TEXT =

'Exit handler for not found fired';

100 SQL Procedural Languages: Application Enablement and Support

Page 111: IBM DB2 9.7 for Linux, UNIX, And Windows

END;

OPEN cur2;

REPEATFETCH cur2 INTO val;SET myint = myint + val;

UNTIL (myint >= a)END REPEAT;

CLOSE cur2;

RETURN myint;

END@

What to do next

After creating the scalar function you might want to invoke the function to test it.

Creating SQL table functionsThe task of creating SQL table functions can be done at any time.

Before you begin

Before you create an SQL table function ensure that you have the privilegesrequired to execute the CREATE FUNCTION (table) statement.

Restrictions

See: “Restrictions on SQL functions” on page 99

Procedure

1. Define the CREATE FUNCTION (table) statement:a. Specify a name for the function.b. Specify a name and data type for each input parameter.c. Specify the routine attributes.d. Specify the RETURNS TABLE keyword.e. Specify the BEGIN ATOMIC keyword to introduce the function-body.f. Specify the function body.g. Specify the RETURN clause with brackets in which you specify a query

that defines the result set to be returned.h. Specify the END keyword.

2. Execute the CREATE FUNCTION (table) statement from a supported interface.

Results

The CREATE FUNCTION (table) statement should execute successfully and thetable function should be created.

Example

Example 1:

Chapter 5. SQL routines 101

Page 112: IBM DB2 9.7 for Linux, UNIX, And Windows

The following is an example of a compiled SQL table function that is used to trackand audit updates made to employee salary data:

CREATE FUNCTION update_salary (updEmpNum CHAR(4), amount INTEGER)RETURNS TABLE (emp_lastname VARCHAR(10),

emp_firstname VARCHAR(10),newSalary INTEGER)

LANGUAGE SQLMODIFIES SQL DATANO EXTERNAL ACTIONNOT DETERMINISTICBEGIN ATOMIC

INSERT INTO audit_table(user, table, action, time)VALUES (USER, 'EMPLOYEE','Salary update. Values: ' || updEmpNum || ' ' || char(amount), CURRENT_TIMESTAMP);

RETURN (SELECT lastname, firstname, salaryFROM FINAL TABLE(UPDATE employee SET salary = salary + amount WHERE employee.empnum = updEmpNum));

END

This function updates the salary of an employee specified by updEmpNum, by theamount specified by amount, and also records in an audit table named audit_table,the user that invoked the routine, the name of the table that was modified, and thetype of modification made by the user. A SELECT statement that references a datachange statement in the FROM clause is used to get back the updated row values.

Example 2:

The following is an example of a compiled SQL table function:CREATE TABLE t1(pk INT

CREATE TABLE t1_archive LIKE T1%

CREATE FUNCTION archive_tbl_t1(ppk INT)RETURNS TABLE(pk INT, c1 INT, date)

LANGUAGE SQLMODIFIES SQL DATABEGIN ATOMIC

DECLARE c1 INT;

DECLARE date DATE;

SET (c1, date) = (SELECT * FROM OLD TABLE(DELETE FROM t1 WHERE t1.pk = ppk));

INSERT INTO T1_ARCHIVE VALUES (ppk, c1, date);

RETURN VALUES (pk, c1, date);END%

What to do next

After creating the table function you might want to invoke the function to test it.

102 SQL Procedural Languages: Application Enablement and Support

Page 113: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 6. Compound statements

A compound statement groups other statements together into an executable block.Compound statements can be executed independently or be included in thedefinitions of database objects such as procedures, functions, methods, andtriggers. There are different SQL statements for these because there are uniquedifferences and restrictions that apply to each.

Compound statements can be either inline compound statements (formerly calleddynamic compound statements) or compiled compound statements. Thedifferences between these two statements are shown below.

Inline compound statementsInline compound statements are atomic and are defined with the BEGINATOMIC and END keywords, between which other SQL statements can bedefined and executed. Inline compound statements can contain variabledeclarations, SQL statements and the subset of SQL PL statements knownas inline SQL PL statements.

Compiled compound statementsCompiled compound statements are not atomic and are defined with theBEGIN and END keywords, between which other SQL statements can bedefined and executed. Compiled compound statements can contain SQLstatements and all SQL PL statements.

You would choose to use a compiled compound statement instead of an inlinecompound statement if you want to make use of the additional features availablewith compiled compound statements.

Uses of compound statements

Compound statements are primarily useful for creating short scripts that can beexecuted from the DB2 Command Line Processor. They are also used to define thebody of a routine or trigger.

Restrictions on compound statementsIt is important to note the restrictions on compound statements before creatingthem or when troubleshooting problems related to their implementation and use.

The following restrictions apply to inlined SQL functions:v Only a subset of SQL PL statements are supported.v The DECLARE TYPE statement is not supported.

The following restrictions apply to compiled SQL functions:v SQL table functions cannot contain compiled compound statements.v SQL scalar functions containing compiled compound statements cannot be

invoked in partitioned database environments.v The DECLARE TYPE statement is supported, but the following data types are

not supported with its use: structured data types, XML data type, LONGVARCHAR data type, and LONG VARGRAPHIC data type.

© Copyright IBM Corp. 1993, 2009 103

Page 114: IBM DB2 9.7 for Linux, UNIX, And Windows

Creating compound statementsCreating and executing compound statements is a task that you would performwhen you need to run a script consisting of SQL statements.

Before you begin

Before you create a compound statement:v Read: Chapter 6, “Compound statements,” on page 103v Ensure that you have the privileges required to execute the Compound

statement.

Restrictions

For a list of restrictions on compound statements, so:v “Restrictions on compound statements” on page 103

Procedure

1. Define a compound SQL statement.2. Execute the compound SQL statement from a supported interface.

Results

If executed dynamically, the SQL statement should execute successfully.

Example

The following is an example of an inlined compound SQL statement that containsSQL PL:BEGINFOR row AS

SELECT pk, c1, discretize(c1) AS v FROM sourceDO

IF row.v is NULL THENINSERT INTO except VALUES(row.pk, row.c1);

ELSEINSERT INTO target VALUES(row.pk, row.d);

END IF;END FOR;END

The compound statement is bounded by the keywords BEGIN and END. Itincludes use of both the FOR and IF/ELSE control-statements that are part of SQLPL. The FOR statement is used to iterate through a defined set of rows. For eachrow a column’s value is checked and conditionally, based on the value, a set ofvalues is inserted into another table.

104 SQL Procedural Languages: Application Enablement and Support

Page 115: IBM DB2 9.7 for Linux, UNIX, And Windows

Part 2. PL/SQL support

PL/SQL (Procedural Language/Structured Query Language) statements can becompiled and executed using DB2 interfaces. This support reduces the complexityof enabling existing PL/SQL solutions so that they will work with the DB2 dataserver.

The supported interfaces include:v DB2 command line processor (CLP)v DB2 CLPPlusv IBM Data Studiov IBM Optim™ Development Studio

PL/SQL statement execution is not enabled from these interfaces by default.PL/SQL statement execution support must be enabled on the DB2 data server.

© Copyright IBM Corp. 1993, 2009 105

Page 116: IBM DB2 9.7 for Linux, UNIX, And Windows

106 SQL Procedural Languages: Application Enablement and Support

Page 117: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 7. PL/SQL features

PL/SQL statements and scripts can be compiled and executed using DB2interfaces.

You can execute the following PL/SQL statements:v Anonymous blocks; for example, DECLARE...BEGIN...ENDv CREATE OR REPLACE FUNCTION statementv CREATE OR REPLACE PACKAGE statementv CREATE OR REPLACE PACKAGE BODY statementv CREATE OR REPLACE PROCEDURE statementv CREATE OR REPLACE TRIGGER statementv DROP PACKAGE statementv DROP PACKAGE BODY statement

PL/SQL procedures and functions can be invoked from other PL/SQL statementsor from DB2 SQL PL statements. You can call a PL/SQL procedure from SQL PLby using the CALL statement.

The following statements and language elements are supported in PL/SQLcontexts:v Type declarations (In this version, type declarations are only supported within

packages. They are not supported within procedures, functions, triggers, oranonymous blocks.)– Associative arrays– Record types– VARRAY types

v Variable declarations:– %ROWTYPE– %TYPE

v Basic statements, clauses, and statement attributes:– Assignment statement– NULL statement– RETURNING INTO clause– Statement attributes, including SQL%FOUND, SQL%NOTFOUND, and

SQL%ROWCOUNTv Control statements and structures:

– CASE statements:- Simple CASE statement- Searched CASE statement

– Exception handling– EXIT statement– FOR statement– GOTO statement– IF statement– LOOP statement

© Copyright IBM Corp. 1993, 2009 107

Page 118: IBM DB2 9.7 for Linux, UNIX, And Windows

– WHILE statementv Static cursors:

– CLOSE statement– Cursor FOR loop statement– FETCH statement (including FETCH INTO a %ROWTYPE variable)– OPEN statement– Parameterized cursors– Cursor attributes

v REF CURSOR support:– Variables and parameters of type REF CURSOR– Strong REF CURSORs– OPEN FOR statement– Returning REF CURSORs to JDBC applications

v Error support:– RAISE_APPLICATION_ERROR procedure– RAISE statement– SQLCODE function– SQLERRM function

108 SQL Procedural Languages: Application Enablement and Support

Page 119: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 8. Creating PL/SQL procedures and functions from aCLP script

You can create PL/SQL procedures and functions from a DB2 command lineprocessor (CLP) script.1. Formulate PL/SQL procedure or function definitions within a CLP script file.

Terminate each statement with a new line and a forward slash character (/).Other statement termination characters are also supported.

2. Save the file. In this example, the file name is script.db2.3. Execute the script from the CLP. If a forward slash character or a semicolon

was used to terminate statements, issue the following command:db2 -td/ -vf script.db2

If another statement termination character (for example, the @ character) wasused in the script file, you must specify that character in the command string.For example:db2 -td@ -vf script.db2

Results

The CLP script should execute successfully if there are no syntax errors.

Example

The following example of a CLP script creates a PL/SQL function and procedure,and then calls the PL/SQL procedure.CONNECT TO mydb/

CREATE TABLE emp (name VARCHAR2(10),salary NUMBER,comm NUMBER,tot_comp NUMBER

)/

INSERT INTO emp VALUES ('Larry', 1000, 50, 0)/INSERT INTO emp VALUES ('Curly', 200, 5, 0)/INSERT INTO emp VALUES ('Moe', 10000, 1000, 0)/

CREATE OR REPLACE FUNCTION emp_comp (p_sal NUMBER,p_comm NUMBER )

RETURN NUMBERISBEGIN

RETURN (p_sal + NVL(p_comm, 0)) * 24;END emp_comp/

CREATE OR REPLACE PROCEDURE update_comp(p_name IN VARCHAR) ASBEGIN

UPDATE emp SET tot_comp = emp_comp(salary, comm)

© Copyright IBM Corp. 1993, 2009 109

Page 120: IBM DB2 9.7 for Linux, UNIX, And Windows

WHERE name = p_name;END update_comp/

CALL update_comp('Curly')/

SELECT * FROM emp/

CONNECT RESET/

This script produces the following sample output:CALL update_comp('Curly')

Return Status = 0

SELECT * FROM emp

NAME SALARY COMM TOT_COMP---------- ------...--------- ----...----------- --------...-------Larry 1000 50 0Curly 200 5 4920Moe 10000 1000 0

3 record(s) selected.

What to do next

Test your new procedures or functions by invoking them. For procedures, use theCALL statement. For functions, execute queries or other SQL statements thatcontain references to those functions.

110 SQL Procedural Languages: Application Enablement and Support

Page 121: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 9. Restrictions on PL/SQL support

It is important to note the restrictions on PL/SQL compilation support beforeperforming PL/SQL compilation, or when troubleshooting PL/SQL compilation orruntime problems.

In this version:v PL/SQL statement compilation and execution for the following product editions

is not supported:– DB2 Express-C– DB2 Personal Edition

v PL/SQL functions and triggers cannot be created in a partitioned databaseenvironment.

v The NCLOB data type is not supported for use in PL/SQL statements or inPL/SQL contexts when the database is not defined as a Unicode database. InUnicode databases, the NCLOB data type is mapped to a DB2 DBCLOB datatype.

v The XMLTYPE data type is not supported.v TYPE declaration is not supported in a function, procedure, trigger, or

anonymous block.v The FOR EACH STATEMENT option is not supported for PL/SQL triggers.

© Copyright IBM Corp. 1993, 2009 111

Page 122: IBM DB2 9.7 for Linux, UNIX, And Windows

112 SQL Procedural Languages: Application Enablement and Support

Page 123: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 10. PL/SQL sample schema

Most of the PL/SQL examples are based on a PL/SQL sample schema thatrepresents employees in an organization.

The following script (plsql_sample.sql) defines that PL/SQL sample schema.---- Script that creates the 'sample' tables, views, procedures,-- functions, triggers, and so on.---- Create and populate tables used in the documentation examples.---- Create the 'dept' table--CREATE TABLE dept (

deptno NUMBER(2) NOT NULL CONSTRAINT dept_pk PRIMARY KEY,dname VARCHAR2(14) NOT NULL CONSTRAINT dept_dname_uq UNIQUE,loc VARCHAR2(13)

);---- Create the 'emp' table--CREATE TABLE emp (

empno NUMBER(4) NOT NULL CONSTRAINT emp_pk PRIMARY KEY,ename VARCHAR2(10),job VARCHAR2(9),mgr NUMBER(4),hiredate DATE,sal NUMBER(7,2) CONSTRAINT emp_sal_ck CHECK (sal > 0),comm NUMBER(7,2),deptno NUMBER(2) CONSTRAINT emp_ref_dept_fk

REFERENCES dept(deptno));---- Create the 'jobhist' table--CREATE TABLE jobhist (

empno NUMBER(4) NOT NULL,startdate DATE NOT NULL,enddate DATE,job VARCHAR2(9),sal NUMBER(7,2),comm NUMBER(7,2),deptno NUMBER(2),chgdesc VARCHAR2(80),CONSTRAINT jobhist_pk PRIMARY KEY (empno, startdate),CONSTRAINT jobhist_ref_emp_fk FOREIGN KEY (empno)

REFERENCES emp(empno) ON DELETE CASCADE,CONSTRAINT jobhist_ref_dept_fk FOREIGN KEY (deptno)

REFERENCES dept (deptno) ON DELETE SET NULL,CONSTRAINT jobhist_date_chk CHECK (startdate <= enddate)

);---- Create the 'salesemp' view--CREATE OR REPLACE VIEW salesemp AS

SELECT empno, ename, hiredate, sal, comm FROM emp WHERE job = 'SALESMAN';---- Sequence to generate values for function 'new_empno'--CREATE SEQUENCE next_empno START WITH 8000 INCREMENT BY 1;--

© Copyright IBM Corp. 1993, 2009 113

Page 124: IBM DB2 9.7 for Linux, UNIX, And Windows

-- Issue PUBLIC grants--GRANT ALL ON emp TO PUBLIC;GRANT ALL ON dept TO PUBLIC;GRANT ALL ON jobhist TO PUBLIC;GRANT ALL ON salesemp TO PUBLIC;---- Load the 'dept' table--INSERT INTO dept VALUES (10,'ACCOUNTING','NEW YORK');INSERT INTO dept VALUES (20,'RESEARCH','DALLAS');INSERT INTO dept VALUES (30,'SALES','CHICAGO');INSERT INTO dept VALUES (40,'OPERATIONS','BOSTON');---- Load the 'emp' table--INSERT INTO emp VALUES (7369,'SMITH','CLERK',7902,'17-DEC-80',800,NULL,20);INSERT INTO emp VALUES (7499,'ALLEN','SALESMAN',7698,'20-FEB-81',1600,300,30);INSERT INTO emp VALUES (7521,'WARD','SALESMAN',7698,'22-FEB-81',1250,500,30);INSERT INTO emp VALUES (7566,'JONES','MANAGER',7839,'02-APR-81',2975,NULL,20);INSERT INTO emp VALUES (7654,'MARTIN','SALESMAN',7698,'28-SEP-81',1250,1400,30);INSERT INTO emp VALUES (7698,'BLAKE','MANAGER',7839,'01-MAY-81',2850,NULL,30);INSERT INTO emp VALUES (7782,'CLARK','MANAGER',7839,'09-JUN-81',2450,NULL,10);INSERT INTO emp VALUES (7788,'SCOTT','ANALYST',7566,'19-APR-87',3000,NULL,20);INSERT INTO emp VALUES (7839,'KING','PRESIDENT',NULL,'17-NOV-81',5000,NULL,10);INSERT INTO emp VALUES (7844,'TURNER','SALESMAN',7698,'08-SEP-81',1500,0,30);INSERT INTO emp VALUES (7876,'ADAMS','CLERK',7788,'23-MAY-87',1100,NULL,20);INSERT INTO emp VALUES (7900,'JAMES','CLERK',7698,'03-DEC-81',950,NULL,30);INSERT INTO emp VALUES (7902,'FORD','ANALYST',7566,'03-DEC-81',3000,NULL,20);INSERT INTO emp VALUES (7934,'MILLER','CLERK',7782,'23-JAN-82',1300,NULL,10);---- Load the 'jobhist' table--INSERT INTO jobhist VALUES (7369,'17-DEC-80',NULL,'CLERK',800,NULL,20,

'New Hire');INSERT INTO jobhist VALUES (7499,'20-FEB-81',NULL,'SALESMAN',1600,300,30,

'New Hire');INSERT INTO jobhist VALUES (7521,'22-FEB-81',NULL,'SALESMAN',1250,500,30,

'New Hire');INSERT INTO jobhist VALUES (7566,'02-APR-81',NULL,'MANAGER',2975,NULL,20,

'New Hire');INSERT INTO jobhist VALUES (7654,'28-SEP-81',NULL,'SALESMAN',1250,1400,30,

'New Hire');INSERT INTO jobhist VALUES (7698,'01-MAY-81',NULL,'MANAGER',2850,NULL,30,

'New Hire');INSERT INTO jobhist VALUES (7782,'09-JUN-81',NULL,'MANAGER',2450,NULL,10,

'New Hire');INSERT INTO jobhist VALUES (7788,'19-APR-87','12-APR-88','CLERK',1000,NULL,20,

'New Hire');INSERT INTO jobhist VALUES (7788,'13-APR-88','04-MAY-89','CLERK',1040,NULL,20,

'Raise');INSERT INTO jobhist VALUES (7788,'05-MAY-90',NULL,'ANALYST',3000,NULL,20,

'Promoted to Analyst');INSERT INTO jobhist VALUES (7839,'17-NOV-81',NULL,'PRESIDENT',5000,NULL,10,

'New Hire');INSERT INTO jobhist VALUES (7844,'08-SEP-81',NULL,'SALESMAN',1500,0,30,

'New Hire');INSERT INTO jobhist VALUES (7876,'23-MAY-87',NULL,'CLERK',1100,NULL,20,

'New Hire');INSERT INTO jobhist VALUES (7900,'03-DEC-81','14-JAN-83','CLERK',950,NULL,10,

'New Hire');INSERT INTO jobhist VALUES (7900,'15-JAN-83',NULL,'CLERK',950,NULL,30,

'Changed to Dept 30');INSERT INTO jobhist VALUES (7902,'03-DEC-81',NULL,'ANALYST',3000,NULL,20,

'New Hire');INSERT INTO jobhist VALUES (7934,'23-JAN-82',NULL,'CLERK',1300,NULL,10,

'New Hire');

114 SQL Procedural Languages: Application Enablement and Support

Page 125: IBM DB2 9.7 for Linux, UNIX, And Windows

SET SQLCOMPAT PLSQL;---- Procedure that lists all employees' numbers and names-- from the 'emp' table using a cursor--CREATE OR REPLACE PROCEDURE list_empIS

v_empno NUMBER(4);v_ename VARCHAR2(10);CURSOR emp_cur IS

SELECT empno, ename FROM emp ORDER BY empno;BEGIN

OPEN emp_cur;DBMS_OUTPUT.PUT_LINE('EMPNO ENAME');DBMS_OUTPUT.PUT_LINE('----- -------');LOOP

FETCH emp_cur INTO v_empno, v_ename;EXIT WHEN emp_cur%NOTFOUND;DBMS_OUTPUT.PUT_LINE(v_empno || ' ' || v_ename);

END LOOP;CLOSE emp_cur;

END;/---- Procedure that selects an employee row given the employee-- number and displays certain columns--CREATE OR REPLACE PROCEDURE select_emp (

p_empno IN NUMBER)IS

v_ename emp.ename%TYPE;v_hiredate emp.hiredate%TYPE;v_sal emp.sal%TYPE;v_comm emp.comm%TYPE;v_dname dept.dname%TYPE;v_disp_date VARCHAR2(10);

BEGINSELECT ename, hiredate, sal, NVL(comm, 0), dname

INTO v_ename, v_hiredate, v_sal, v_comm, v_dnameFROM emp e, dept dWHERE empno = p_empno

AND e.deptno = d.deptno;v_disp_date := TO_CHAR(v_hiredate, 'YYYY/MM/DD');DBMS_OUTPUT.PUT_LINE('Number : ' || p_empno);DBMS_OUTPUT.PUT_LINE('Name : ' || v_ename);DBMS_OUTPUT.PUT_LINE('Hire Date : ' || v_disp_date);DBMS_OUTPUT.PUT_LINE('Salary : ' || v_sal);DBMS_OUTPUT.PUT_LINE('Commission: ' || v_comm);DBMS_OUTPUT.PUT_LINE('Department: ' || v_dname);

EXCEPTIONWHEN NO_DATA_FOUND THEN

DBMS_OUTPUT.PUT_LINE('Employee ' || p_empno || ' not found');WHEN OTHERS THEN

DBMS_OUTPUT.PUT_LINE('The following is SQLERRM:');DBMS_OUTPUT.PUT_LINE(SQLERRM);DBMS_OUTPUT.PUT_LINE('The following is SQLCODE:');DBMS_OUTPUT.PUT_LINE(SQLCODE);

END;/---- Procedure that queries the 'emp' table based on-- department number and employee number or name. Returns-- employee number and name as IN OUT parameters and job,-- hire date, and salary as OUT parameters.--

Chapter 10. PL/SQL sample schema 115

Page 126: IBM DB2 9.7 for Linux, UNIX, And Windows

CREATE OR REPLACE PROCEDURE emp_query (p_deptno IN NUMBER,p_empno IN OUT NUMBER,p_ename IN OUT VARCHAR2,p_job OUT VARCHAR2,p_hiredate OUT DATE,p_sal OUT NUMBER

)ISBEGIN

SELECT empno, ename, job, hiredate, salINTO p_empno, p_ename, p_job, p_hiredate, p_salFROM empWHERE deptno = p_deptno

AND (empno = p_empnoOR ename = UPPER(p_ename));

END;/---- Procedure to call 'emp_query_caller' with IN and IN OUT-- parameters. Displays the results received from IN OUT and-- OUT parameters.--CREATE OR REPLACE PROCEDURE emp_query_callerIS

v_deptno NUMBER(2);v_empno NUMBER(4);v_ename VARCHAR2(10);v_job VARCHAR2(9);v_hiredate DATE;v_sal NUMBER;

BEGINv_deptno := 30;v_empno := 0;v_ename := 'Martin';emp_query(v_deptno, v_empno, v_ename, v_job, v_hiredate, v_sal);DBMS_OUTPUT.PUT_LINE('Department : ' || v_deptno);DBMS_OUTPUT.PUT_LINE('Employee No: ' || v_empno);DBMS_OUTPUT.PUT_LINE('Name : ' || v_ename);DBMS_OUTPUT.PUT_LINE('Job : ' || v_job);DBMS_OUTPUT.PUT_LINE('Hire Date : ' || v_hiredate);DBMS_OUTPUT.PUT_LINE('Salary : ' || v_sal);

EXCEPTIONWHEN TOO_MANY_ROWS THEN

DBMS_OUTPUT.PUT_LINE('More than one employee was selected');WHEN NO_DATA_FOUND THEN

DBMS_OUTPUT.PUT_LINE('No employees were selected');END;/---- Function to compute yearly compensation based on semimonthly-- salary--CREATE OR REPLACE FUNCTION emp_comp (

p_sal NUMBER,p_comm NUMBER

) RETURN NUMBERISBEGIN

RETURN (p_sal + NVL(p_comm, 0)) * 24;END;/---- After statement-level triggers that display a message after-- an insert, update, or deletion to the 'emp' table. One message-- per SQL command is displayed.--

116 SQL Procedural Languages: Application Enablement and Support

Page 127: IBM DB2 9.7 for Linux, UNIX, And Windows

CREATE OR REPLACE TRIGGER user_ins_audit_trigAFTER INSERT ON empFOR EACH ROW

DECLAREv_action VARCHAR2(24);

BEGINv_action := ' added employee(s) on ';DBMS_OUTPUT.PUT_LINE('User ' || USER || v_action ||

TO_CHAR(SYSDATE,'YYYY-MM-DD'));END;/CREATE OR REPLACE TRIGGER user_upd_audit_trig

AFTER UPDATE ON empFOR EACH ROW

DECLAREv_action VARCHAR2(24);

BEGINv_action := ' updated employee(s) on ';DBMS_OUTPUT.PUT_LINE('User ' || USER || v_action ||

TO_CHAR(SYSDATE,'YYYY-MM-DD'));END;/CREATE OR REPLACE TRIGGER user_del_audit_trig

AFTER DELETE ON empFOR EACH ROW

DECLAREv_action VARCHAR2(24);

BEGINv_action := ' deleted employee(s) on ';DBMS_OUTPUT.PUT_LINE('User ' || USER || v_action ||

TO_CHAR(SYSDATE,'YYYY-MM-DD'));END;/---- Before row-level triggers that display employee number and-- salary of an employee that is about to be added, updated,-- or deleted in the 'emp' table--CREATE OR REPLACE TRIGGER emp_ins_sal_trig

BEFORE INSERT ON empFOR EACH ROW

DECLAREsal_diff NUMBER;

BEGINDBMS_OUTPUT.PUT_LINE('Inserting employee ' || :NEW.empno);DBMS_OUTPUT.PUT_LINE('..New salary: ' || :NEW.sal);

END;/CREATE OR REPLACE TRIGGER emp_upd_sal_trig

BEFORE UPDATE ON empFOR EACH ROW

DECLAREsal_diff NUMBER;

BEGINsal_diff := :NEW.sal - :OLD.sal;DBMS_OUTPUT.PUT_LINE('Updating employee ' || :OLD.empno);DBMS_OUTPUT.PUT_LINE('..Old salary: ' || :OLD.sal);DBMS_OUTPUT.PUT_LINE('..New salary: ' || :NEW.sal);DBMS_OUTPUT.PUT_LINE('..Raise : ' || sal_diff);

END;/CREATE OR REPLACE TRIGGER emp_del_sal_trig

BEFORE DELETE ON empFOR EACH ROW

DECLAREsal_diff NUMBER;

BEGIN

Chapter 10. PL/SQL sample schema 117

Page 128: IBM DB2 9.7 for Linux, UNIX, And Windows

DBMS_OUTPUT.PUT_LINE('Deleting employee ' || :OLD.empno);DBMS_OUTPUT.PUT_LINE('..Old salary: ' || :OLD.sal);

END;/---- Package specification for the 'emp_admin' package--CREATE OR REPLACE PACKAGE emp_adminIS

FUNCTION get_dept_name (p_deptno NUMBER

) RETURN VARCHAR2;FUNCTION update_emp_sal (

p_empno NUMBER,p_raise NUMBER

) RETURN NUMBER;PROCEDURE hire_emp (

p_empno NUMBER,p_ename VARCHAR2,p_job VARCHAR2,p_sal NUMBER,p_hiredate DATE,p_comm NUMBER,p_mgr NUMBER,p_deptno NUMBER

);PROCEDURE fire_emp (

p_empno NUMBER);

END emp_admin;/---- Package body for the 'emp_admin' package--CREATE OR REPLACE PACKAGE BODY emp_adminIS

---- Function that queries the 'dept' table based on the department-- number and returns the corresponding department name--FUNCTION get_dept_name (

p_deptno IN NUMBER) RETURN VARCHAR2IS

v_dname VARCHAR2(14);BEGIN

SELECT dname INTO v_dname FROM dept WHERE deptno = p_deptno;RETURN v_dname;

EXCEPTIONWHEN NO_DATA_FOUND THEN

DBMS_OUTPUT.PUT_LINE('Invalid department number ' || p_deptno);RETURN '';

END;---- Function that updates an employee's salary based on the-- employee number and salary increment/decrement passed-- as IN parameters. Upon successful completion the function-- returns the new updated salary.--FUNCTION update_emp_sal (

p_empno IN NUMBER,p_raise IN NUMBER

) RETURN NUMBERIS

v_sal NUMBER := 0;BEGIN

SELECT sal INTO v_sal FROM emp WHERE empno = p_empno;

118 SQL Procedural Languages: Application Enablement and Support

Page 129: IBM DB2 9.7 for Linux, UNIX, And Windows

v_sal := v_sal + p_raise;UPDATE emp SET sal = v_sal WHERE empno = p_empno;RETURN v_sal;

EXCEPTIONWHEN NO_DATA_FOUND THEN

DBMS_OUTPUT.PUT_LINE('Employee ' || p_empno || ' not found');RETURN -1;

WHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('The following is SQLERRM:');DBMS_OUTPUT.PUT_LINE(SQLERRM);DBMS_OUTPUT.PUT_LINE('The following is SQLCODE:');DBMS_OUTPUT.PUT_LINE(SQLCODE);RETURN -1;

END;---- Procedure that inserts a new employee record into the 'emp' table--PROCEDURE hire_emp (

p_empno NUMBER,p_ename VARCHAR2,p_job VARCHAR2,p_sal NUMBER,p_hiredate DATE,p_comm NUMBER,p_mgr NUMBER,p_deptno NUMBER

)ASBEGIN

INSERT INTO emp(empno, ename, job, sal, hiredate, comm, mgr, deptno)VALUES(p_empno, p_ename, p_job, p_sal,

p_hiredate, p_comm, p_mgr, p_deptno);END;---- Procedure that deletes an employee record from the 'emp' table based-- on the employee number--PROCEDURE fire_emp (

p_empno NUMBER)ASBEGIN

DELETE FROM emp WHERE empno = p_empno;END;

END;/

SET SQLCOMPAT DB2;

Chapter 10. PL/SQL sample schema 119

Page 130: IBM DB2 9.7 for Linux, UNIX, And Windows

120 SQL Procedural Languages: Application Enablement and Support

Page 131: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 11. Blocks (PL/SQL)

PL/SQL block structures can be included within PL/SQL procedure, function, ortrigger definitions or executed independently as an anonymous block statement.

PL/SQL block structures and the anonymous block statement contain one or moreof the following sections:v An optional declaration sectionv A mandatory executable sectionv An optional exception section

These sections can include SQL statements, PL/SQL statements, data type andvariable declarations, or other PL/SQL language elements.

Anonymous block statement (PL/SQL)The PL/SQL anonymous block statement is an executable statement that cancontain PL/SQL control statements and SQL statements. It can be used toimplement procedural logic in a scripting language. In PL/SQL contexts, thisstatement can be compiled and executed by the DB2 data server.

The anonymous block statement, which does not persist in the database, canconsist of up to three sections: an optional declaration section, a mandatoryexecutable section, and an optional exception section.

The optional declaration section, which can contain the declaration of variables,cursors, and types that are to be used by statements within the executable andexception sections, is inserted before the executable BEGIN-END block.

The optional exception section can be inserted near the end of the BEGIN-ENDblock. The exception section must begin with the keyword EXCEPTION, andcontinues until the end of the block in which it appears.

Invocation

This statement can be executed from an interactive tool or command line interfacesuch as the CLP. This statement can also be embedded within a PL/SQL proceduredefinition, function definition, or trigger definition. Within these contexts, thestatement is called a block structure instead of an anonymous block statement.

Authorization

No privileges are required to invoke an anonymous block. However, the privilegesheld by the authorization ID of the statement must include all necessary privilegesto invoke the SQL statements that are embedded within the anonymous block.

Syntax

��

� declarationDECLARE

�BEGIN statement �

© Copyright IBM Corp. 1993, 2009 121

Page 132: IBM DB2 9.7 for Linux, UNIX, And Windows

� � �EXCEPTION WHEN exception-condition THEN handler-statementOR

END ��

Description

DECLAREAn optional keyword that starts the DECLARE statement, which can be usedto declare data types, variables, or cursors. The use of this keyword dependsupon the context in which the block appears.

declarationSpecifies a variable, cursor, or type declaration whose scope is local to theblock. Each declaration must be terminated by a semicolon.

BEGINA mandatory keyword that introduces the executable section, which caninclude one or more SQL or PL/SQL statements. A BEGIN-END block cancontain nested BEGIN-END blocks.

statementSpecifies a PL/SQL or SQL statement. Each statement must be terminated by asemicolon.

EXCEPTIONAn optional keyword that introduces the exception section.

WHEN exception-conditionSpecifies a conditional expression that tests for one or more types ofexceptions.

THEN handler-statementSpecifies a PL/SQL or SQL statement that is executed if a thrown exceptionmatches an exception in exception-condition. Each statement must be terminatedby a semicolon.

ENDA mandatory keyword that ends the block.

Examples

The following example shows the simplest possible anonymous block statementthat the DB2 data server can compile:BEGIN

NULL;END;

The following example shows an anonymous block that you can enter interactivelythrough the DB2 CLP:SET SERVEROUTPUT ON;

BEGINdbms_output.put_line( 'Hello' );

END;

The following example shows an anonymous block with a declaration section thatyou can enter interactively through the DB2 CLP:

122 SQL Procedural Languages: Application Enablement and Support

Page 133: IBM DB2 9.7 for Linux, UNIX, And Windows

SET SERVEROUTPUT ON;

DECLAREcurrent_date DATE := SYSDATE;

BEGINdbms_output.put_line( current_date );

END;

Chapter 11. Blocks (PL/SQL) 123

Page 134: IBM DB2 9.7 for Linux, UNIX, And Windows

124 SQL Procedural Languages: Application Enablement and Support

Page 135: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 12. Procedures (PL/SQL)

The DB2 data server supports the compilation and execution of PL/SQLprocedures. PL/SQL procedures are database objects that contain PL/SQLprocedural logic and SQL statements that can be invoked in contexts where theCALL statement or procedure references are valid.

PL/SQL procedures are created by executing the PL/SQL CREATE PROCEDUREstatement. Such procedures can be dropped from the database by using the DB2SQL DROP statement. If you want to replace the implementation for a procedure,you do not need to drop it. You can use the CREATE PROCEDURE statement andspecify the OR REPLACE option to replace the procedure implementation.

CREATE PROCEDURE statement (PL/SQL)The CREATE PROCEDURE statement defines a procedure that is stored in thedatabase.

Invocation

This statement can be executed from the DB2 command line processor (CLP), anysupported interactive SQL interface, an application, or a routine.

Authorization

The privileges held by the authorization ID of the statement must include at leastone of the following:v If the schema name of the procedure does not exist, IMPLICIT_SCHEMA

authority on the databasev If the schema name of the procedure refers to an existing schema, CREATEIN

privilege on the schemav DBADM authority

The privileges held by the authorization ID of the statement must also include allof the privileges necessary to invoke the SQL statements that are specified in theprocedure body.

The authorization ID of the statement must be the owner of the matched procedureif OR REPLACE is specified (SQLSTATE 42501).

Syntax

�� CREATE PROCEDUREOR REPLACE

© Copyright IBM Corp. 1993, 2009 125

Page 136: IBM DB2 9.7 for Linux, UNIX, And Windows

( ),

INparameter-name data-type

OUT default-clauseIN OUT

�READS SQL DATA

ISAS

declaration

�BEGIN statement �

� � �EXCEPTION WHEN exception THEN statementOR exception

� ENDprocedure-name

��

Description

PROCEDURE procedure-nameSpecifies an identifier for the procedure. The unqualified form ofprocedure-name is an SQL identifier with a maximum length of 128. In dynamicSQL statements, the value of the CURRENT SCHEMA special register is usedto qualify an unqualified object name. In static SQL statements, theQUALIFIER precompile or bind option implicitly specifies the qualifier forunqualified object names. The qualified form of procedure-name is a schemaname followed by a period character and an SQL identifier. If a two-part nameis specified, the schema name cannot begin with ’SYS’; otherwise, an error isreturned (SQLSTATE 42939).

The name (including an implicit or explicit qualifier), together with the numberof parameters, must not identify a procedure that is described in the catalog(SQLSTATE 42723). The unqualified name, together with the number ofparameters, is unique within its schema, but does not need to be unique acrossschemas.

parameter-nameSpecifies the name of a parameter. The parameter name must be unique forthis procedure (SQLSTATE 42734).

data-typeSpecifies one of the supported PL/SQL data types.

READS SQL DATAIndicates that SQL statements that do not modify SQL data can be included inthe procedure. This clause is a DB2 extension.

IS or ASIntroduces the procedure body definition.

declarationSpecifies one or more variable, cursor, or REF CURSOR type declarations.

126 SQL Procedural Languages: Application Enablement and Support

Page 137: IBM DB2 9.7 for Linux, UNIX, And Windows

BEGINIntroduces the executable block. The BEGIN-END block can contain anEXCEPTION section.

statementSpecifies a PL/SQL or SQL statement. The statement must be terminated by asemicolon.

EXCEPTIONAn optional keyword that introduces the exception section.

WHEN exception-conditionSpecifies a conditional expression that tests for one or more types ofexceptions.

statementSpecifies a PL/SQL or SQL statement. The statement must be terminated by asemicolon.

ENDA mandatory keyword that ends the block. You can optionally specify thename of the procedure.

Examples

The following example shows a simple procedure that takes no parameters:CREATE OR REPLACE PROCEDURE simple_procedureISBEGIN

DBMS_OUTPUT.PUT_LINE('That''s all folks!');END simple_procedure;

The following example shows a procedure that takes an IN and an OUT parameter,and that has GOTO statements whose labels are of the standard PL/SQL form(<<label>>):CREATE OR REPLACE PROCEDURE test_goto( p1 IN INTEGER, out1 OUT VARCHAR2(30) )ISBEGIN<<LABEL2ABOVE>>IF p1 = 1 THENout1 := out1 || 'one';GOTO LABEL1BELOW;END IF;if out1 IS NULL THENout1 := out1 || 'two';GOTO LABEL2ABOVE;END IF;

out1 := out1 || 'three';

<<LABEL1BELOW>>out1 := out1 || 'four';

END test_goto;

Procedure references (PL/SQL)Invocation references to PL/SQL procedures within PL/SQL contexts can becompiled by the DB2 data server.

Chapter 12. Procedures (PL/SQL) 127

Page 138: IBM DB2 9.7 for Linux, UNIX, And Windows

A valid PL/SQL procedure reference consists of the procedure name followed byits parameters, if any.

Syntax

�� procedure-name

,

( )parameter-value

��

Description

procedure-nameSpecifies an identifier for the procedure.

parameter-valueSpecifies a parameter value. If no parameters are to be passed, the procedurecan be called either with or without parentheses.

Example

The following example shows how to call a PL/SQL procedure within a PL/SQLcontext:BEGIN

simple_procedure;END;

After a PL/SQL procedure has been created in a DB2 database, it can also be calledusing the CALL statement, which is supported in DB2 SQL contexts andapplications using supported DB2 application programming interfaces.

Function invocation syntax support (PL/SQL)A number of procedures support function invocation syntax in a PL/SQLassignment statement.

These procedures include:v DBMS_SQL.EXECUTEv DBMS_SQL.EXECUTE_AND_FETCHv DBMS_SQL.FETCH_ROWSv DBMS_SQL.IS_OPENv DBMS_SQL.LAST_ERROR_POSITIONv DBMS_SQL.LAST_ROW_COUNTv DBMS_SQL.OPEN_CURSORv UTL_SMTP.CLOSE_DATAv UTL_SMTP.COMMANDv UTL_SMTP.COMMAND_REPLIESv UTL_SMTP.DATAv UTL_SMTP.EHLOv UTL_SMTP.HELOv UTL_SMTP.HELPv UTL_SMTP.MAIL

128 SQL Procedural Languages: Application Enablement and Support

Page 139: IBM DB2 9.7 for Linux, UNIX, And Windows

v UTL_SMTP.NOOPv UTL_SMTP.OPEN_DATAv UTL_SMTP.QUITv UTL_SMTP.RCPTv UTL_SMTP.RSETv UTL_SMTP.VRFY

ExamplesDECLARE

cursor1 NUMBER;rowsProcessed NUMBER;

BEGINcursor1 := DBMS_SQL.OPEN_CURSOR;DBMS_SQL.PARSE(cursor1, 'INSERT INTO T1 VALUES (10)', DBMS_SQL.NATIVE);rowsProcessed := DBMS_SQL.EXECUTE(cursor1);DBMS_SQL.CLOSE_CURSOR(cursor1);

END;/

DECLAREv_connection UTL_SMTP.CONNECTION;v_reply UTL_SMTP.REPLY;

BEGINUTL_SMTP.OPEN_CONNECTION('127.0.0.1', 25, v_connection, 10, v_reply);UTL_SMTP.HELO(v_connection,'127.0.0.1');UTL_SMTP.MAIL(v_connection, '[email protected]');UTL_SMTP.RCPT(v_connection, '[email protected]');v_reply := UTL_SMTP.OPEN_DATA (v_connection);UTL_SMTP.WRITE_DATA (v_connection, 'Test message');UTL_SMTP.CLOSE_DATA (v_connection);UTL_SMTP.QUIT(v_connection);

END;/

Chapter 12. Procedures (PL/SQL) 129

Page 140: IBM DB2 9.7 for Linux, UNIX, And Windows

130 SQL Procedural Languages: Application Enablement and Support

Page 141: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 13. Functions (PL/SQL)

The DB2 data server supports the compilation and execution of PL/SQL functions.PL/SQL functions are database objects that contain PL/SQL procedural logic andSQL statements that can be invoked in contexts where expressions are valid. Whenevaluated, a PL/SQL function returns a value that is substituted within theexpression in which the function is embedded.

PL/SQL functions are created by executing the CREATE FUNCTION statement.Such functions can be dropped from the database by using the DB2 SQL DROPstatement. If you want to replace the implementation for a function, you do notneed to drop it. You can use the CREATE FUNCTION statement and specify theOR REPLACE option to replace the function implementation.

CREATE FUNCTION statement (PL/SQL)The CREATE FUNCTION statement defines an SQL scalar function that is storedin the database. A scalar function returns a single value each time it is invoked,and is generally valid wherever an SQL expression is valid. PL/SQL functions donot support output parameters.

Invocation

This statement can be executed from the DB2 command line processor, anysupported interactive SQL interface, an application, or routine.

Authorization

The privileges held by the authorization ID of the statement must include at leastone of the following:v If the schema name of the function does not exist, IMPLICIT_SCHEMA authority

on the databasev If the schema name of the function refers to an existing schema, CREATEIN

privilege on the schemav DBADM authority

The privileges held by the authorization ID of the statement must also include allof the privileges necessary to invoke the SQL statements that are specified in thefunction body.

The authorization ID of the statement must be the owner of the matched functionif OR REPLACE is specified (SQLSTATE 42501).

Syntax

�� CREATE FUNCTION nameOR REPLACE

© Copyright IBM Corp. 1993, 2009 131

Page 142: IBM DB2 9.7 for Linux, UNIX, And Windows

( ),

INparameter-name data-type

OUTINOUT

� RETURN return-typeMODIFIES SQL DATA

ISAS

declaration�

� �BEGIN statement �

� � �EXCEPTION WHEN exception THEN statementOR exception

� ENDname

��

Description

The CREATE FUNCTION statement specifies the name of the function, theoptional parameters, the return type of the function, and the body of the function.The body of the function is a block that is enclosed by the BEGIN and ENDkeywords. It can contain an optional EXCEPTION section that defines an action tobe taken when a defined exception condition occurs.

OR REPLACEIndicates that if a function with the same name already exists in the schema,the new function is to replace the existing one. If this option is not specified,the new function cannot replace an existing one with the same name in thesame schema.

FUNCTION nameSpecifies an identifier for the function.

parameter-nameSpecifies the name of a parameter. The name cannot be the same as any otherparameter-name in the parameter list (SQLSTATE 42734).

data-typeSpecifies one of the supported PL/SQL data types.

RETURN return-typeSpecifies the data type of the scalar value that is returned by the function.

MODIFIES SQL DATAIndicates that the function can issue any SQL statement except statements thatare not supported in functions (SQLSTATE 38002 or 42985).

132 SQL Procedural Languages: Application Enablement and Support

Page 143: IBM DB2 9.7 for Linux, UNIX, And Windows

This clause is a DB2 extension. It must be used when dynamic SQL statementsthat could modify SQL data are specified in statement, otherwise issuing of adynamic statement that attempts to modify SQL data will fail during functioninvocation (SQLSTATE 38002).

IS or ASIntroduces the block that defines the function body.

declarationSpecifies one or more variable, cursor, or REF CURSOR type declarations.

statementSpecifies one or more PL/SQL program statements. Each statement must beterminated by a semicolon.

exceptionSpecifies an exception condition name.

Notes

A PL/SQL function cannot take any action that changes the state of an object thatthe database manager does not manage.

Examples

The following example shows a basic function that takes no parameters:CREATE OR REPLACE FUNCTION simple_function

RETURN VARCHAR2ISBEGIN

RETURN 'That''s All Folks!';END simple_function;

The following example shows a function that takes two input parameters:CREATE OR REPLACE FUNCTION emp_comp (

p_sal NUMBER,p_comm NUMBER )

RETURN NUMBERISBEGIN

RETURN (p_sal + NVL(p_comm, 0)) * 24;END emp_comp;

Function references (PL/SQL)PL/SQL functions can be referenced wherever an expression is supported.

Syntax

�� function-name

,

( parameter-value )

��

Description

function-nameSpecifies an identifier for the function.

Chapter 13. Functions (PL/SQL) 133

Page 144: IBM DB2 9.7 for Linux, UNIX, And Windows

parameter-valueSpecifies a value for a parameter.

Examples

The following example shows how a function named SIMPLE_FUNCTION,defined in the PL/SQL sample schema, can be called from a PL/SQL anonymousblock:BEGIN

DBMS_OUTPUT.PUT_LINE(simple_function);END;

The following example shows how a function can be used within an SQLstatement:SELECT

empno "EMPNO", ename "ENAME", sal "SAL", comm "COMM",emp_comp(sal, comm) "YEARLY COMPENSATION"

FROM emp

134 SQL Procedural Languages: Application Enablement and Support

Page 145: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 14. Collections (PL/SQL)

The use of PL/SQL collections is supported by the DB2 data server. A PL/SQLcollection is a set of ordered data elements with the same data type. Individual dataitems in the set can be referenced by using subscript notation within parentheses.

In PL/SQL contexts, the DB2 server supports both the VARRAY collection type andassociative arrays.

VARRAY collection type declaration (PL/SQL)A VARRAY is a type of collection in which each element is referenced by a positiveinteger called the array index. The maximum cardinality of the VARRAY is specifiedin the type definition.

The TYPE IS VARRAY statement is used to define a VARRAY collection type.

Syntax

�� TYPE varraytype IS VARRAY ( n ) OF datatype ; ��

Description

varraytypeAn identifier that is assigned to the array type.

n The maximum number of elements in the array type.

datatypeA supported data type, such as NUMBER, VARCHAR2, or a record type. The%TYPE attribute and the %ROWTYPE attribute are also supported.

Example

The following example reads employee names from the EMP table, stores thenames in an array variable of type VARRAY, and then displays the results. TheEMP table contains one column named ENAME. The code is executed from a DB2script (script.db2). The following commands should be issued from the DB2command window before executing the script (db2 -tvf script.db2):db2set DB2_COMPATIBILITY_VECTOR=FFFdb2stopdb2start

The script contains the following code:SET SQLCOMPAT PLSQL;

connect to mydb/

CREATE PACKAGE fooAS

TYPE emp_arr_typ IS VARRAY(5) OF VARCHAR2(10);END;/

© Copyright IBM Corp. 1993, 2009 135

Page 146: IBM DB2 9.7 for Linux, UNIX, And Windows

SET SERVEROUTPUT ON/

DECLAREemp_arr foo.emp_arr_typ;CURSOR emp_cur IS SELECT ename FROM emp WHERE ROWNUM <= 5;i INTEGER := 0;

BEGINFOR r_emp IN emp_cur LOOP

i := i + 1;emp_arr(i) := r_emp.ename;

END LOOP;FOR j IN 1..5 LOOP

DBMS_OUTPUT.PUT_LINE(emp_arr(j));END LOOP;

END;/

DROP PACKAGE foo/

connect reset/

This script produces the following sample output:CurlyLarryMoeShempJoe

CREATE TYPE (VARRAY) statement (PL/SQL)The CREATE TYPE (VARRAY) statement defines a VARRAY data type.

Invocation

This statement can be executed from the DB2 command line processor (CLP), anysupported interactive SQL interface, an application, or a routine.

Authorization

The privileges held by the authorization ID of the statement must include at leastone of the following:v If the schema name of the VARRAY type does not exist, IMPLICIT_SCHEMA

authority on the databasev If the schema name of the VARRAY type refers to an existing schema,

CREATEIN privilege on the schemav DBADM authority

Syntax

�� CREATE TYPE varraytypeOR REPLACE

ISAS

VARRAY ( n ) �

� OF datatype ��

136 SQL Procedural Languages: Application Enablement and Support

Page 147: IBM DB2 9.7 for Linux, UNIX, And Windows

Description

OR REPLACEIndicates that if a user-defined data type with the same name already exists inthe schema, the new data type is to replace the existing one. If this option isnot specified, the new data type cannot replace an existing one with the samename in the same schema.

varraytypeSpecifies an identifier for the VARRAY type. The unqualified form of varraytypeis an SQL identifier with a maximum length of 128. The value of theCURRENT SCHEMA special register is used to qualify an unqualified objectname. The qualified form of varraytype is a schema name followed by a periodcharacter and an SQL identifier. If a two-part name is specified, the schemaname cannot begin with ’SYS’; otherwise, an error is returned (SQLSTATE42939). The name (including an implicit or explicit qualifier) must not identifya user-defined data type that is described in the catalog (SQLSTATE 42723).The unqualified name is unique within its schema, but does not need to beunique across schemas.

n Specifies the maximum number of elements in the array type. The maximumcardinality of an array on a given system is limited by the total amount ofmemory that is available to DB2 applications. As such, although arrays of largecardinalities (up to 2,147,483,647) can be created, not all elements might beavailable for use.

datatypeSpecifies a supported data type, such as NUMBER, VARCHAR2, or a recordtype. The %TYPE attribute and the %ROWTYPE attribute are also supported.

Example

The following example creates a VARRAY data type with a maximum of 10elements, where each element has the data type NUMBER:CREATE TYPE AS NUMARRAY1 VARRAY (10) OF NUMBER

Associative arrays (PL/SQL)A PL/SQL associative array is a collection type that associates a unique key with avalue.

An associative array has the following characteristics:v An associative array type must be defined before array variables of that array

type can be declared. Data manipulation occurs in the array variable.v The array does not need to be initialized; simply assign values to array elements.v There is no defined limit on the number of elements in the array; it grows

dynamically as elements are added.v The array can be sparse; there can be gaps in the assignment of values to keys.v An attempt to reference an array element that has not been assigned a value

results in an exception.

Use the TYPE IS TABLE OF statement to define an associative array type.

Syntax

Chapter 14. Collections (PL/SQL) 137

Page 148: IBM DB2 9.7 for Linux, UNIX, And Windows

�� TYPE assoctype IS TABLE OF datatyperectype

� INDEX BY BINARY_INTEGERPLS_INTEGERVARCHAR2 ( n )

��

Description

TYPE assoctypeSpecifies an identifer for the array type.

datatypeSpecifies a scalar data type, such as VARCHAR2 or NUMBER. The %TYPEattribute is also supported.

rectypeSpecifies a previously defined record type. The %ROWTYPE attribute is alsosupported.

INDEX BYSpecifies that the associative array is to be indexed by one of the data typesintroduced by this clause.

BINARY INTEGERInteger numeric data.

PLS_INTEGERInteger numeric data.

VARCHAR2 (n)A variable-length character string of maximum length n. The %TYPEattribute is also supported if the object to which the %TYPE attribute isbeing applied is of the BINARY_INTEGER, PLS_INTEGER, or VARCHAR2data type.

To declare a variable with an associative array type, specify array-name assoctype,where array-name represents an identifier that is assigned to the associative array,and assoctype represents the identifier for a previously declared array type.

To reference a particular element of the array, specify array-name(n), wherearray-name represents the identifier for a previously declared array, and nrepresents a value of INDEX BY data type of assoctype. If the array is defined froma record type, the reference becomes array-name(n).field, where field is definedwithin the record type from which the array type is defined. To reference the entirerecord, omit field.

Examples

The following example reads the first ten employee names from the EMP table,stores them in an array, and then displays the contents of the array.SET SERVEROUTPUT ON/

CREATE OR REPLACE PACKAGE pkg_test_type1IS

TYPE emp_arr_typ IS TABLE OF VARCHAR2(10) INDEX BY BINARY_INTEGER;END pkg_test_type1/

138 SQL Procedural Languages: Application Enablement and Support

Page 149: IBM DB2 9.7 for Linux, UNIX, And Windows

DECLAREemp_arr pkg_test_type1.emp_arr_typ;CURSOR emp_cur IS SELECT ename FROM emp WHERE ROWNUM <= 10;i INTEGER := 0;

BEGINFOR r_emp IN emp_cur LOOP

i := i + 1;emp_arr(i) := r_emp.ename;

END LOOP;FOR j IN 1..10 LOOP

DBMS_OUTPUT.PUT_LINE(emp_arr(j));END LOOP;

END/

This code generates the following sample output:SMITHALLENWARDJONESMARTINBLAKECLARKSCOTTKINGTURNER

The example can be modified to use a record type in the array definition.SET SERVEROUTPUT ON/

CREATE OR REPLACE PACKAGE pkg_test_type2IS

TYPE emp_rec_typ IS RECORD (empno INTEGER,ename VARCHAR2(10)

);END pkg_test_type2/

CREATE OR REPLACE PACKAGE pkg_test_type3IS

TYPE emp_arr_typ IS TABLE OF pkg_test_type2.emp_rec_typ INDEX BY BINARY_INTEGER;END pkg_test_type3/

DECLAREemp_arr pkg_test_type3.emp_arr_typ;CURSOR emp_cur IS SELECT empno, ename FROM emp WHERE ROWNUM <= 10;i INTEGER := 0;

BEGINDBMS_OUTPUT.PUT_LINE('EMPNO ENAME');DBMS_OUTPUT.PUT_LINE('----- -------');FOR r_emp IN emp_cur LOOP

i := i + 1;emp_arr(i).empno := r_emp.empno;emp_arr(i).ename := r_emp.ename;

END LOOP;FOR j IN 1..10 LOOP

DBMS_OUTPUT.PUT_LINE(emp_arr(j).empno || ' ' ||emp_arr(j).ename);

END LOOP;END/

Chapter 14. Collections (PL/SQL) 139

Page 150: IBM DB2 9.7 for Linux, UNIX, And Windows

The modified code generates the following sample output:EMPNO ENAME----- -------1001 SMITH1002 ALLEN1003 WARD1004 JONES1005 MARTIN1006 BLAKE1007 CLARK1008 SCOTT1009 KING1010 TURNER

This example can be further modified to use the emp%ROWTYPE attribute todefine emp_arr_typ, instead of using the emp_rec_typ record type.SET SERVEROUTPUT ON/

CREATE OR REPLACE PACKAGE pkg_test_type4IS

TYPE emp_arr_typ IS TABLE OF emp%ROWTYPE INDEX BY BINARY_INTEGER;END pkg_test_type4/

DECLAREemp_arr pkg_test_type4.emp_arr_typ;CURSOR emp_cur IS SELECT empno, ename FROM emp WHERE ROWNUM <= 10;i INTEGER := 0;

BEGINDBMS_OUTPUT.PUT_LINE('EMPNO ENAME');DBMS_OUTPUT.PUT_LINE('----- -------');FOR r_emp IN emp_cur LOOP

i := i + 1;emp_arr(i).empno := r_emp.empno;emp_arr(i).ename := r_emp.ename;

END LOOP;FOR j IN 1..10 LOOP

DBMS_OUTPUT.PUT_LINE(emp_arr(j).empno || ' ' ||emp_arr(j).ename);

END LOOP;END/

In this case, the sample output is identical to that of the previous example.

Finally, instead of assigning each field of the record individually, a record-levelassignment can be made from r_emp to emp_arr:SET SERVEROUTPUT ON/

CREATE OR REPLACE PACKAGE pkg_test_type5IS

TYPE emp_rec_typ IS RECORD (empno INTEGER,ename VARCHAR2(10)

);END pkg_test_type5/

CREATE OR REPLACE PACKAGE pkg_test_type6IS

TYPE emp_arr_typ IS TABLE OF pkg_test_type5.emp_rec_typ INDEX BY BINARY_INTEGER;END pkg_test_type6

140 SQL Procedural Languages: Application Enablement and Support

Page 151: IBM DB2 9.7 for Linux, UNIX, And Windows

/

DECLAREemp_arr pkg_test_type6.emp_arr_typ;CURSOR emp_cur IS SELECT empno, ename FROM emp WHERE ROWNUM <= 10;i INTEGER := 0;

BEGINDBMS_OUTPUT.PUT_LINE('EMPNO ENAME');DBMS_OUTPUT.PUT_LINE('----- -------');FOR r_emp IN emp_cur LOOP

i := i + 1;emp_arr(i) := r_emp;

END LOOP;FOR j IN 1..10 LOOP

DBMS_OUTPUT.PUT_LINE(emp_arr(j).empno || ' ' ||emp_arr(j).ename);

END LOOP;END/

Collection methods (PL/SQL)Collection methods can be used to obtain information about collections or tomodify collections.

The following commands should be executed before attempting to run theexamples in Table 4 on page 142.db2set DB2_COMPATIBILITY_VECTOR=ORAdb2stopdb2startdb2 connect to mydb

The MYDB database has one table, EMP, which has one column, ENAME (definedas VARCHAR(10)):db2 select * from emp

ENAME----------CurlyLarryMoeShempJoe

5 record(s) selected.

Chapter 14. Collections (PL/SQL) 141

Page 152: IBM DB2 9.7 for Linux, UNIX, And Windows

Table 4. Collection methods that are supported (or tolerated) by the DB2 data server in a PL/SQL context

Collection method Description Example

COUNT Returns thenumber ofelements in acollection.

CREATE PACKAGE fooAS

TYPE sparse_arr_typ IS TABLE OF NUMBERINDEX BY BINARY_INTEGER;

END;/

SET SERVEROUTPUT ON/

DECLAREsparse_arr foo.sparse_arr_typ;

BEGINsparse_arr(-10) := -10;sparse_arr(0) := 0;sparse_arr(10) := 10;DBMS_OUTPUT.PUT_LINE('COUNT: ' ||

sparse_arr.COUNT);END;/

DELETE Removes allelements from acollection.

CREATE PACKAGE fooAS

TYPE names_typ IS TABLE OF VARCHAR2(10)INDEX BY BINARY INTEGER;

END;/

SET SERVEROUTPUT ON/

DECLAREactor_names foo.names_typ;

BEGIN

actor_names(1) := 'Chris';actor_names(2) := 'Steve';actor_names(3) := 'Kate';actor_names(4) := 'Naomi';actor_names(5) := 'Peter';actor_names(6) := 'Philip';actor_names(7) := 'Michael';actor_names(8) := 'Gary';

DBMS_OUTPUT.PUT_LINE('COUNT: ' ||actor_names.COUNT);

actor_names.DELETE(2);DBMS_OUTPUT.PUT_LINE('COUNT: ' ||

actor_names.COUNT);

actor_names.DELETE(3, 5);DBMS_OUTPUT.PUT_LINE('COUNT: ' ||

actor_names.COUNT);

actor_names.DELETE;DBMS_OUTPUT.PUT_LINE('COUNT: ' ||

actor_names.COUNT);

END;/

142 SQL Procedural Languages: Application Enablement and Support

Page 153: IBM DB2 9.7 for Linux, UNIX, And Windows

Table 4. Collection methods that are supported (or tolerated) by the DB2 data server in a PL/SQL context (continued)

Collection method Description Example

DELETE (n) Removes element nfrom an associativearray. You cannotdelete individualelements from aVARRAY collectiontype.

See “DELETE”.

DELETE (n1, n2) Removes allelements from n1to n2 from anassociative array.You cannot deleteindividualelements from aVARRAY collectiontype.

See “DELETE”.

EXISTS (n) Returns TRUE ifthe specifiedelement exists.

CREATE PACKAGE fooAS

TYPE emp_arr_typ IS VARRAY(5) OF VARCHAR2(10);END;/

SET SERVEROUTPUT ON/

DECLAREemp_arr foo.emp_arr_typ;CURSOR emp_cur IS SELECT ename FROM emp

WHERE ROWNUM <= 5;i INTEGER := 0;

BEGINFOR r_emp IN emp_cur LOOP

i := i + 1;emp_arr(i) := r_emp.ename;

END LOOP;emp_arr.TRIM;FOR j IN 1..5 LOOP

IF emp_arr.EXISTS(j) = true THENDBMS_OUTPUT.PUT_LINE(emp_arr(j));

ELSEDBMS_OUTPUT.PUT_LINE('THIS ELEMENT

HAS BEEN DELETED');END IF;

END LOOP;END;/

EXTEND Appends a singleNULL element to acollection.

No-op

EXTEND (n) Appends n NULLelements to acollection.

No-op

EXTEND (n1, n2) Appends n1 copiesof the n2th elementto a collection.

No-op

Chapter 14. Collections (PL/SQL) 143

Page 154: IBM DB2 9.7 for Linux, UNIX, And Windows

Table 4. Collection methods that are supported (or tolerated) by the DB2 data server in a PL/SQL context (continued)

Collection method Description Example

FIRST Returns thesmallest indexnumber in acollection.

CREATE PACKAGE fooAS

TYPE emp_arr_typ IS VARRAY(5) OF VARCHAR2(10);END;/

SET SERVEROUTPUT ON/

DECLAREemp_arr foo.emp_arr_typ;CURSOR emp_cur IS SELECT ename FROM emp

WHERE ROWNUM <= 5;i INTEGER := 0;k INTEGER := 0;l INTEGER := 0;

BEGIN

FOR r_emp IN emp_cur LOOPi := i + 1;emp_arr(i) := r_emp.ename;

END LOOP;

-- Use FIRST and LAST to specify the lower and-- upper bounds of a loop range:FOR j IN emp_arr.FIRST..emp_arr.LAST LOOP

DBMS_OUTPUT.PUT_LINE(emp_arr(j));END LOOP;

-- Use NEXT(n) to obtain the subscript of-- the next element:k := emp_arr.FIRST;WHILE k IS NOT NULL LOOP

DBMS_OUTPUT.PUT_LINE(emp_arr(k));k := emp_arr.NEXT(k);

END LOOP;

-- Use PRIOR(n) to obtain the subscript of-- the previous element:l := emp_arr.LAST;WHILE l IS NOT NULL LOOP

DBMS_OUTPUT.PUT_LINE(emp_arr(l));l := emp_arr.PRIOR(l);

END LOOP;

DBMS_OUTPUT.PUT_LINE('COUNT: ' || emp_arr.COUNT);

emp_arr.TRIM;DBMS_OUTPUT.PUT_LINE('COUNT: ' || emp_arr.COUNT);

emp_arr.TRIM(2);DBMS_OUTPUT.PUT_LINE('COUNT: ' || emp_arr.COUNT);

DBMS_OUTPUT.PUT_LINE('Max. no. elements = ' ||emp_arr.LIMIT);

END;/

LAST Returns the largestindex number in acollection.

See “FIRST”.

144 SQL Procedural Languages: Application Enablement and Support

Page 155: IBM DB2 9.7 for Linux, UNIX, And Windows

Table 4. Collection methods that are supported (or tolerated) by the DB2 data server in a PL/SQL context (continued)

Collection method Description Example

LIMIT Returns themaximum numberof elements for aVARRAY, or NULLfor nested tables.

See “FIRST”.

NEXT (n) Returns the indexnumber of theelementimmediatelyfollowing thespecified element.

See “FIRST”.

PRIOR (n) Returns the indexnumber of theelementimmediately priorto the specifiedelement.

See “FIRST”.

TRIM Removes a singleelement from theend of a collection.You cannot trimelements from anassociative arraycollection type.

See “FIRST”.

TRIM (n) Removes nelements from theend of a collection.You cannot trimelements from anassociative arraycollection type.

See “FIRST”.

Chapter 14. Collections (PL/SQL) 145

Page 156: IBM DB2 9.7 for Linux, UNIX, And Windows

146 SQL Procedural Languages: Application Enablement and Support

Page 157: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 15. Variables (PL/SQL)

Variables must be declared before they are referenced.

Variables that are used in a block must generally be defined in the declarationsection of the block unless they are global variables or package-level variables. Thedeclaration section contains the definitions of variables, cursors, and other typesthat can be used in PL/SQL statements within the block. A variable declarationconsists of a name that is assigned to the variable and the data type of thevariable. Optionally, the variable can be initialized to a default value within thevariable declaration.

Procedures and functions can have parameters for passing input values.Procedures can also have parameters for passing output values, or parameters forpassing both input and output values.

PL/SQL also includes variable data types to match the data types of existingcolumns, rows, or cursors using the %TYPE and %ROWTYPE qualifiers.

Variable declarations (PL/SQL)Variables that are used in a block must generally be defined in the declarationsection of the block unless they are global variables or package-level variables. Avariable declaration consists of a name that is assigned to the variable and the datatype of the variable. Optionally, the variable can be initialized to a default valuewithin the variable declaration.

Syntax

�� nameCONSTANT

typeNOT NULL := expression

DEFAULT NULL

��

Description

nameSpecifies an identifier that is assigned to the variable.

CONSTANTSpecifies that the variable value is constant. A default expression must beassigned, and a new value cannot be assigned to the variable within theapplication program.

typeSpecifies a data type for the variable.

NOT NULLSpecifies that the variable cannot have a null value. If NOT NULL is specified,a default expression must be assigned, and the variable cannot be made nullwithin the application program.

DEFAULTSpecifies a default value for the variable. This default is evaluated every timethat the block is entered. For example, if SYSDATE has been assigned to a

© Copyright IBM Corp. 1993, 2009 147

Page 158: IBM DB2 9.7 for Linux, UNIX, And Windows

variable of type DATE, the variable resolves to the current invocation time, notto the time at which the procedure or function was precompiled.

:= The assignment operator is a synonym for the DEFAULT keyword. However, ifthis operator is specified without expression, the variable is initialized to thevalue NULL.

expressionSpecifies the initial value that is to be assigned to the variable when the blockis entered.

NULLSpecifies the SQL value NULL, which has a null value.

Example

The following procedure shows variable declarations that utilize defaults consistingof string and numeric expressions:CREATE OR REPLACE PROCEDURE dept_salary_rpt (

p_deptno NUMBER)IS

todays_date DATE := SYSDATE;rpt_title VARCHAR2(60) := 'Report For Department # ' || p_deptno

|| ' on ' || todays_date;base_sal INTEGER := 35525;base_comm_rate NUMBER := 1.33333;base_annual NUMBER := ROUND(base_sal * base_comm_rate, 2);

BEGINDBMS_OUTPUT.PUT_LINE(rpt_title);DBMS_OUTPUT.PUT_LINE('Base Annual Salary: ' || base_annual);

END;

The following sample output was obtained by calling this procedure:CALL dept_salary_rpt(20);

Report For Department # 20 on 10-JUL-07 16:44:45Base Annual Salary: 47366.55

Parameter modes (PL/SQL)PL/SQL procedure parameters can have one of three possible modes: IN, OUT, orIN OUT. PL/SQL function parameters can only be IN.v An IN formal parameter is initialized to the actual parameter with which it was

called, unless it was explicitly initialized with a default value. The IN parametercan be referenced within the called program; however, the called programcannot assign a new value to the IN parameter. After control returns to thecalling program, the actual parameter always contains the value to which it wasset prior to the call.

v An OUT formal parameter is initialized to the actual parameter with which itwas called. The called program can reference and assign new values to theformal parameter. If the called program terminates without an exception, theactual parameter takes on the value to which the formal parameter was last set.If a handled exception occurs, the actual parameter takes on the last value towhich the formal parameter was set. If an unhandled exception occurs, the valueof the actual parameter remains what it was prior to the call.

v Like an IN parameter, an IN OUT formal parameter is initialized to the actualparameter with which it was called. Like an OUT parameter, an IN OUT formalparameter is modifiable by the called program, and the last value of the formal

148 SQL Procedural Languages: Application Enablement and Support

Page 159: IBM DB2 9.7 for Linux, UNIX, And Windows

parameter is passed to the calling program’s actual parameter if the calledprogram terminates without an exception. If a handled exception occurs, theactual parameter takes on the last value to which the formal parameter was set.If an unhandled exception occurs, the value of the actual parameter remainswhat it was prior to the call.

Table 5 summarizes this behavior.

Table 5. Parameter modes

Mode property IN IN OUT OUT

Formal parameterinitialized to:

Actual parametervalue

Actual parametervalue

Actual parametervalue

Formal parametermodifiable by thecalled program?

No Yes Yes

After normaltermination of thecalled program,actual parametercontains:

Original actualparameter valueprior to the call

Last value of theformal parameter

Last value of theformal parameter

After a handledexception in thecalled program,actual parametercontains:

Original actualparameter valueprior to the call

Last value of theformal parameter

Last value of theformal parameter

After an unhandledexception in thecalled program,actual parametercontains:

Original actualparameter valueprior to the call

Original actualparameter valueprior to the call

Original actualparameter valueprior to the call

Data types (PL/SQL)The DB2 data server supports a wide range of data types that can be used todeclare variables in a PL/SQL block.

Table 6. Supported scalar data types that are available in PL/SQL

PL/SQL data type DB2 SQL data type Description

BINARY_INTEGER INTEGER Integer numeric data

BLOB BLOB (4096) Binary data

BLOB (n) BLOB (n)n = 1 to 2 147 483 647

Binary large object data

BOOLEAN BOOLEAN Logical Boolean (true orfalse)

CHAR CHAR (1) Fixed-length character stringdata of length 1

CHAR (n) CHAR (n)n = 1 to 254

Fixed-length character stringdata of length n

CHAR VARYING (n) VARCHAR (n) Variable-length characterstring data of maximumlength n

Chapter 15. Variables (PL/SQL) 149

Page 160: IBM DB2 9.7 for Linux, UNIX, And Windows

Table 6. Supported scalar data types that are available in PL/SQL (continued)

PL/SQL data type DB2 SQL data type Description

CHARACTER CHARACTER (1) Fixed-length character stringdata of length 1

CHARACTER (n) CHARACTER (n)n = 1 to 254

Fixed-length character stringdata of length n

CHARACTER VARYING (n) VARCHAR (n)n = 1 to 32 672

Variable-length characterstring data of maximumlength n

CLOB CLOB (1M) Character large object data

CLOB (n) CLOB (n)n = 1 to 2 147 483 647

Fixed-length long characterstring data of length n

DATE DATE 1 Date and time data(expressed to the second)

DEC DEC (9, 2) Decimal numeric data

DEC (p) DEC (p)p = 1 to 31

Decimal numeric data ofprecision p

DEC (p, s) DEC (p, s)p = 1 to 31; s = 1 to 31

Decimal numeric data ofprecision p and scale s

DECIMAL DECIMAL (9, 2) Decimal numeric data

DECIMAL (p) DECIMAL (p)p = 1 to 31

Decimal numeric data ofprecision p

DECIMAL (p, s) DECIMAL (p, s)p = 1 to 31; s = 1 to 31

Decimal numeric data ofprecision p and scale s

DOUBLE DOUBLE Double precisionfloating-point number

DOUBLE PRECISION DOUBLE PRECISION Double precisionfloating-point number

FLOAT FLOAT Float numeric data

FLOAT (n)n = 1 to 24

REAL Real numeric data

FLOAT (n)n = 25 to 53

DOUBLE Double numeric data

INT INT Signed four-byte integernumeric data

INTEGER INTEGER Signed four-byte integernumeric data

LONG CLOB (32760) Character large object data

LONG RAW BLOB (32760) Binary large object data

LONG VARCHAR CLOB (32760) Character large object data

NATURAL INTEGER Signed four-byte integernumeric data

NCHAR GRAPHIC (127) Fixed-length graphic stringdata

NCHAR (n)n = 1 to 2000

GRAPHIC (n)n = 1 to 127

Fixed-length graphic stringdata of length n

NCLOB 2 DBCLOB (1M) Double-byte character largeobject data

150 SQL Procedural Languages: Application Enablement and Support

Page 161: IBM DB2 9.7 for Linux, UNIX, And Windows

Table 6. Supported scalar data types that are available in PL/SQL (continued)

PL/SQL data type DB2 SQL data type Description

NCLOB (n) DBCLOB (2000) Double-byte long characterstring data of maximumlength n

NVARCHAR2 VARGRAPHIC (2048) Variable-length graphicstring data

NVARCHAR2 (n) VARGRAPHIC (n) Variable-length graphicstring data of maximumlength n

NUMBER NUMBER 3 Exact numeric data

NUMBER (p) NUMBER (p) 3 Exact numeric data ofmaximum precision p

NUMBER (p, s) NUMBER (p, s) 3

p = 1 to 31Exact numeric data ofmaximum precision p andscale s

NUMERIC NUMERIC (9.2) Exact numeric data

NUMERIC (p) NUMERIC (p)p = 1 to 31

Exact numeric data ofmaximum precision p

NUMERIC (p, s) NUMERIC (p, s)p = 1 to 31; s = 0 to 31

Exact numeric data ofmaximum precision p andscale s

PLS_INTEGER INTEGER Integer numeric data

RAW BLOB (32767) Binary large object data

RAW (n) BLOB (n)n = 1 to 32 767

Binary large object data

SMALLINT SMALLINT Signed two-byte integer data

TIMESTAMP (0) TIMESTAMP (0) Date data with timestampinformation

TIMESTAMP (p) TIMESTAMP (p) Date and time data withoptional fractional secondsand precision p

VARCHAR VARCHAR (4096) Variable-length characterstring data with a maximumlength of 4096 characters

VARCHAR (n) VARCHAR (n) Variable-length characterstring data with a maximumlength of n characters

VARCHAR2 (n) VARCHAR2 (n) 4 Variable-length characterstring data with a maximumlength of n characters

1. When the DB2_COMPATIBILITY_VECTOR registry variable is set for the DATE datatype, DATE is equivalent to TIMESTAMP (0).

2. For restrictions on the NCLOB data type in certain database environments,see “Restrictions on PL/SQL support”.

3. This data type is supported when the number_compat database configurationparameter set to ON.

4. This data type is supported when the varchar2_compat database configurationparameter set to ON.

Chapter 15. Variables (PL/SQL) 151

Page 162: IBM DB2 9.7 for Linux, UNIX, And Windows

In addition to the scalar data types described in Table 6 on page 149, the DB2 dataserver also supports collection types, record types, and REF CURSOR types.

%TYPE attribute in variable declarations (PL/SQL)The %TYPE attribute, used in PL/SQL variable and parameter declarations, issupported by the DB2 data server. Use of this attribute ensures that typecompatibility between table columns and PL/SQL variables is maintained.

A qualified column name in dot notation or the name of a previously declaredvariable must be specified as a prefix to the %TYPE attribute. The data type of thiscolumn or variable is assigned to the variable being declared. If the data type ofthe column or variable changes, there is no need to modify the declaration code.

The %TYPE attribute can also be used with formal parameter declarations.

Syntax

�� name table . columnview

variable

%TYPE ��

Description

nameSpecifies an identifier for the variable or formal parameter that is beingdeclared.

tableSpecifies an identifier for the table whose column is to be referenced.

viewSpecifies an identifier for the view whose column is to be referenced.

columnSpecifies an identifier for the table or view column that is to be referenced.

variableSpecifies an identifier for a previously declared variable that is to bereferenced. The variable does not inherit any other column attributes, such as,for example, the nullability attribute.

Example

The following example shows a procedure that queries the EMP table using anemployee number, displays the employee’s data, finds the average salary of allemployees in the department to which the employee belongs, and then comparesthe chosen employee’s salary with the department average.CREATE OR REPLACE PROCEDURE emp_sal_query (

p_empno IN NUMBER)IS

v_ename VARCHAR2(10);v_job VARCHAR2(9);v_hiredate DATE;v_sal NUMBER(7,2);v_deptno NUMBER(2);v_avgsal NUMBER(7,2);

BEGIN

152 SQL Procedural Languages: Application Enablement and Support

Page 163: IBM DB2 9.7 for Linux, UNIX, And Windows

SELECT ename, job, hiredate, sal, deptnoINTO v_ename, v_job, v_hiredate, v_sal, v_deptnoFROM emp WHERE empno = p_empno;

DBMS_OUTPUT.PUT_LINE('Employee # : ' || p_empno);DBMS_OUTPUT.PUT_LINE('Name : ' || v_ename);DBMS_OUTPUT.PUT_LINE('Job : ' || v_job);DBMS_OUTPUT.PUT_LINE('Hire Date : ' || v_hiredate);DBMS_OUTPUT.PUT_LINE('Salary : ' || v_sal);DBMS_OUTPUT.PUT_LINE('Dept # : ' || v_deptno);

SELECT AVG(sal) INTO v_avgsalFROM emp WHERE deptno = v_deptno;

IF v_sal > v_avgsal THENDBMS_OUTPUT.PUT_LINE('Employee''s salary is more than the department '

|| 'average of ' || v_avgsal);ELSE

DBMS_OUTPUT.PUT_LINE('Employee''s salary does not exceed the department '|| 'average of ' || v_avgsal);

END IF;END;

This procedure could be rewritten without explicitly coding the EMP table datatypes in the declaration section.CREATE OR REPLACE PROCEDURE emp_sal_query (

p_empno IN emp.empno%TYPE)IS

v_ename emp.ename%TYPE;v_job emp.job%TYPE;v_hiredate emp.hiredate%TYPE;v_sal emp.sal%TYPE;v_deptno emp.deptno%TYPE;v_avgsal v_sal%TYPE;

BEGINSELECT ename, job, hiredate, sal, deptno

INTO v_ename, v_job, v_hiredate, v_sal, v_deptnoFROM emp WHERE empno = p_empno;

DBMS_OUTPUT.PUT_LINE('Employee # : ' || p_empno);DBMS_OUTPUT.PUT_LINE('Name : ' || v_ename);DBMS_OUTPUT.PUT_LINE('Job : ' || v_job);DBMS_OUTPUT.PUT_LINE('Hire Date : ' || v_hiredate);DBMS_OUTPUT.PUT_LINE('Salary : ' || v_sal);DBMS_OUTPUT.PUT_LINE('Dept # : ' || v_deptno);

SELECT AVG(sal) INTO v_avgsalFROM emp WHERE deptno = v_deptno;

IF v_sal > v_avgsal THENDBMS_OUTPUT.PUT_LINE('Employee''s salary is more than the department '

|| 'average of ' || v_avgsal);ELSE

DBMS_OUTPUT.PUT_LINE('Employee''s salary does not exceed the department '|| 'average of ' || v_avgsal);

END IF;END;

The p_empno parameter is an example of a formal parameter that is defined usingthe %TYPE attribute. The v_avgsal variable is an example of the %TYPE attributereferring to another variable instead of a table column.

The following sample output is generated by a call to the EMP_SAL_QUERYprocedure:CALL emp_sal_query(7698);

Employee # : 7698

Chapter 15. Variables (PL/SQL) 153

Page 164: IBM DB2 9.7 for Linux, UNIX, And Windows

Name : BLAKEJob : MANAGERHire Date : 01-MAY-81 00:00:00Salary : 2850.00Dept # : 30Employee's salary is more than the department average of 1566.67

Record variables based on user-defined record types (PL/SQL)PL/SQL record variable declarations based on user-defined record type definitionsare supported by the DB2 data server in PL/SQL contexts.

A record type is a definition of a record that consists of one or more identifiers andtheir corresponding data types. A record type cannot, by itself, be used tomanipulate data. You can declare PL/SQL record variables that are based onexisting user-defined record types, and you can create user-defined record types byusing the PL/SQL TYPE IS RECORD statement. A record type definition is onlysupported in the CREATE PACKAGE or CREATE PACKAGE BODY statement.

A record variable (or record) is an instance of a record type. A record variable isdeclared from a record type. The properties of the record, such as its field namesand types, are inherited from the record type.

Dot notation is used to reference fields in a record. For example, record.field.

Syntax

�� TYPE rectype IS RECORD �

,

( field datatype ) ��

Description

TYPE rectype IS RECORDSpecifies an identifier for the record type.

fieldSpecifies an identifier for a field of the record type.

datatypeSpecifies the corresponding data type of the field. The %TYPE attribute issupported; the %ROWTYPE attribute is not supported.

Example

The following example shows a package that references a user-defined record type:CREATE OR REPLACE PACKAGE pkg7aISTYPE t1_typ IS RECORD (

c1 T1.C1%TYPE,c2 VARCHAR(10)

);END;

154 SQL Procedural Languages: Application Enablement and Support

Page 165: IBM DB2 9.7 for Linux, UNIX, And Windows

%ROWTYPE attribute in record type declarations (PL/SQL)The %ROWTYPE attribute, used to declare PL/SQL variables of type record withfields that correspond to the columns of a table or view, is supported by the DB2data server. Each field in a PL/SQL record assumes the data type of thecorresponding column in the table.

A record is a named, ordered collection of fields. A field is similar to a variable; ithas an identifier and a data type, but it also belongs to a record, and must bereferenced using dot notation, with the record name as a qualifier.

Syntax

�� record tableview

%ROWTYPE ��

Description

recordSpecifies an identifier for the record.

tableSpecifies an identifier for the table whose column definitions will be used todefine the fields in the record.

viewSpecifies an identifier for the view whose column definitions will be used todefine the fields in the record.

%ROWTYPESpecifies that the record field data types are to be derived from the columndata types that are associated with the identified table or view. Record fieldsdo not inherit any other column attributes, such as, for example, the nullabilityattribute.

Example

The following example shows how to use the %ROWTYPE attribute to create arecord (named r_emp) instead of declaring individual variables for the columns inthe EMP table.CREATE OR REPLACE PROCEDURE emp_sal_query (

p_empno IN emp.empno%TYPE)IS

r_emp emp%ROWTYPE;v_avgsal emp.sal%TYPE;

BEGINSELECT ename, job, hiredate, sal, deptno

INTO r_emp.ename, r_emp.job, r_emp.hiredate, r_emp.sal, r_emp.deptnoFROM emp WHERE empno = p_empno;

DBMS_OUTPUT.PUT_LINE('Employee # : ' || p_empno);DBMS_OUTPUT.PUT_LINE('Name : ' || r_emp.ename);DBMS_OUTPUT.PUT_LINE('Job : ' || r_emp.job);DBMS_OUTPUT.PUT_LINE('Hire Date : ' || r_emp.hiredate);DBMS_OUTPUT.PUT_LINE('Salary : ' || r_emp.sal);DBMS_OUTPUT.PUT_LINE('Dept # : ' || r_emp.deptno);

SELECT AVG(sal) INTO v_avgsalFROM emp WHERE deptno = r_emp.deptno;

IF r_emp.sal > v_avgsal THEN

Chapter 15. Variables (PL/SQL) 155

Page 166: IBM DB2 9.7 for Linux, UNIX, And Windows

DBMS_OUTPUT.PUT_LINE('Employee''s salary is more than the department '|| 'average of ' || v_avgsal);

ELSEDBMS_OUTPUT.PUT_LINE('Employee''s salary does not exceed the department '

|| 'average of ' || v_avgsal);END IF;

END;

156 SQL Procedural Languages: Application Enablement and Support

Page 167: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 16. Basic statements (PL/SQL)

The programming statements that can be used in a PL/SQL application include:assignment, DELETE, EXECUTE IMMEDIATE, INSERT, NULL, SELECT INTO, andUPDATE.

NULL statement (PL/SQL)The NULL statement is an executable statement that does nothing. The NULLstatement can act as a placeholder whenever an executable statement is required,but no SQL operation is wanted; for example, within a branch of theIF-THEN-ELSE statement.

Syntax

�� NULL ��

Examples

The following example shows the simplest valid PL/SQL program that the DB2data server can compile:BEGIN

NULL;END;

The following example shows the NULL statement within an IF...THEN...ELSEstatement:CREATE OR REPLACE PROCEDURE divide_it (

p_numerator IN NUMBER,p_denominator IN NUMBER,p_result OUT NUMBER

)ISBEGIN

IF p_denominator = 0 THENNULL;

ELSEp_result := p_numerator / p_denominator;

END IF;END;

Assignment statement (PL/SQL)The assignment statement sets a previously-declared variable or formal OUT or INOUT parameter to the value of an expression.

Syntax

�� variable := expression ��

© Copyright IBM Corp. 1993, 2009 157

Page 168: IBM DB2 9.7 for Linux, UNIX, And Windows

Description

variableSpecifies an identifier for a previously-declared variable, OUT formalparameter, or IN OUT formal parameter.

expressionSpecifies an expression that evaluates to a single value. The data type of thisvalue must be compatible with the data type of variable.

Example

The following example shows assignment statements in the executable section of aprocedure:CREATE OR REPLACE PROCEDURE dept_salary_rpt (

p_deptno IN NUMBER,p_base_annual OUT NUMBER

)IS

todays_date DATE;rpt_title VARCHAR2(60);base_sal INTEGER;base_comm_rate NUMBER;

BEGINtodays_date := SYSDATE;rpt_title := 'Report For Department # ' || p_deptno || ' on '

|| todays_date;base_sal := 35525;base_comm_rate := 1.33333;p_base_annual := ROUND(base_sal * base_comm_rate, 2);

DBMS_OUTPUT.PUT_LINE(rpt_title);DBMS_OUTPUT.PUT_LINE('Base Annual Salary: ' || p_base_annual);

END/

EXECUTE IMMEDIATE statement (PL/SQL)The EXECUTE IMMEDIATE statement prepares an executable form of an SQLstatement from a character string form of the statement and then executes the SQLstatement. EXECUTE IMMEDIATE combines the basic functions of the PREPAREand EXECUTE statements.

Invocation

This statement can only be specified in a PL/SQL context.

Authorization

The authorization rules are those defined for the specified SQL statement.

The authorization ID of the statement might be affected by the DYNAMICRULESbind option.

Syntax

�� EXECUTE IMMEDIATE sql-expression �

158 SQL Procedural Languages: Application Enablement and Support

Page 169: IBM DB2 9.7 for Linux, UNIX, And Windows

,

INTO variable,

BULK COLLECT INTO array-variable

,IN

USING expressionIN OUT variableOUT variable

��

Description

sql-expressionAn expression returning the statement string to be executed. The expressionmust return a character-string type that is less than the maximum statementsize of 2 097 152 bytes. Note that a CLOB(2097152) can contain a maximumsize statement, but a VARCHAR cannot.

The statement string must be one of the following SQL statements:v ALTERv CALLv COMMENTv COMMITv Compound SQL (compiled)v Compound SQL (inlined)v CREATEv DECLARE GLOBAL TEMPORARY TABLEv DELETEv DROPv EXPLAINv FLUSH EVENT MONITORv FLUSH PACKAGE CACHEv GRANTv INSERTv LOCK TABLEv MERGEv REFRESH TABLEv RELEASE SAVEPOINTv RENAMEv REVOKEv ROLLBACKv SAVEPOINTv SELECT (only when the EXECUTE IMMEDIATE statement also specifies the

BULK COLLECT INTO clause)v SET COMPILATION ENVIRONMENTv SET CURRENT DECFLOAT ROUNDING MODE

Chapter 16. Basic statements (PL/SQL) 159

Page 170: IBM DB2 9.7 for Linux, UNIX, And Windows

v SET CURRENT DEFAULT TRANSFORM GROUPv SET CURRENT DEGREEv SET CURRENT FEDERATED ASYNCHRONYv SET CURRENT EXPLAIN MODEv SET CURRENT EXPLAIN SNAPSHOTv SET CURRENT IMPLICIT XMLPARSE OPTIONv SET CURRENT ISOLATIONv SET CURRENT LOCALE LC_TIMEv SET CURRENT LOCK TIMEOUTv SET CURRENT MAINTAINED TABLE TYPES FOR OPTIMIZATIONv SET CURRENT MDC ROLLOUT MODEv SET CURRENT OPTIMIZATION PROFILEv SET CURRENT QUERY OPTIMIZATIONv SET CURRENT REFRESH AGEv SET CURRENT SQL_CCFLAGSv SET ROLE (only if DYNAMICRULES run behavior is in effect for the

package)v SET ENCRYPTION PASSWORDv SET EVENT MONITOR STATE (only if DYNAMICRULES run behavior is in

effect for the package)v SET INTEGRITYv SET PASSTHRUv SET PATHv SET SCHEMAv SET SERVER OPTIONv SET SESSION AUTHORIZATIONv SET variablev TRANSFER OWNERSHIP (only if DYNAMICRULES run behavior is in

effect for the package)v TRUNCATE (only if DYNAMICRULES run behavior is in effect for the

package)v UPDATE

The statement string must not contain a statement terminator, with theexception of compound SQL statements which can contain semicolons (;) toseparate statements within the compound block. A compound SQL statement isused within some CREATE and ALTER statements which, therefore, can alsocontain semicolons.

When an EXECUTE IMMEDIATE statement is executed, the specifiedstatement string is parsed and checked for errors. If the SQL statement isinvalid, it is not executed, and an exception is thrown.

INTO variableSpecifies the name of a variable that is to receive an output value from thecorresponding parameter marker.

BULK COLLECT INTO array-variableIdentifies one or more variables with an array data type. Each row of thequery is assigned to an element in each array in the order of the result set,with the array index assigned in sequence.

160 SQL Procedural Languages: Application Enablement and Support

Page 171: IBM DB2 9.7 for Linux, UNIX, And Windows

v If exactly one array-variable is specified:– If the data type of the array-variable element is not a record type, the

SELECT list must have exactly one column and the column data typemust be assignable to the array element data type.

– If the data type of the array-variable element is a record type, the SELECTlist must be assignable to the record type.

v If multiple array variables are specified:– The data type of the array-variable element must not be a record type.– There must be an array-variable for each column in the SELECT list.– The data type of each column in the SELECT list must be assignable to

the array element data type of the corresponding array-variable.

If the data type of array-variable is an ordinary array, the maximum cardinalitymust be greater than or equal to the number of rows that are returned by thequery.

This clause can only be used if the sql-expression is a SELECT statement.

USING

IN expressionSpecifies a value that is passed to an input parameter marker. IN is thedefault.

IN OUT variableSpecifies the name of a variable that is to provide an input value to, orreceive an output value from the corresponding parameter marker.

OUT variableSpecifies the name of a variable that is to receive an output value from thecorresponding parameter marker.

The number and order of evaluated expressions or variables must match thenumber and order of—and be type-compatible with—the parameter markers insql-expression.

Notesv Statement caching affects the behavior of an EXECUTE IMMEDIATE statement.

ExampleCREATE OR REPLACE PROCEDURE proc1( p1 IN NUMBER, p2 IN OUT NUMBER, p3 OUT NUMBER )ISBEGIN

p3 := p1 + 1;p2 := p2 + 1;

END;/

EXECUTE IMMEDIATE 'BEGIN proc1( :1, :2, :3 ); END' USING IN p1 + 10, IN OUT p3,OUT p2;

EXECUTE IMMEDIATE 'BEGIN proc1( :1, :2, :3 ); END' INTO p3, p2 USING p1 + 10, p3;

SQL statements (PL/SQL)SQL statements that are supported within PL/SQL contexts can be used to modifydata or to specify the manner in which statements are to be executed.

Chapter 16. Basic statements (PL/SQL) 161

Page 172: IBM DB2 9.7 for Linux, UNIX, And Windows

Table 7 lists these statements. The behavior of these statements when executed inPL/SQL contexts is equivalent to the behavior of the corresponding DB2 SQLstatements.

Table 7. SQL statements that can be executed by the DB2 server within PL/SQL contexts

Command Description

DELETE Deletes rows from a table

INSERT Inserts rows into a table

MERGE Updates a target (a table or view) using datafrom a source (result of a table reference)

SELECT INTO Retrieves rows from a table

UPDATE Updates rows in a table

BULK COLLECT INTO clause (PL/SQL)A SELECT INTO statement with the optional BULK COLLECT keywordspreceding the INTO keyword retrieves multiple rows into an array.

Syntax

�� �

,

BULK COLLECT INTO array-variable ��

Description

BULK COLLECT INTO array-variableIdentifies one or more variables with an array data type. Each row of the resultis assigned to an element in each array in the order of the result set, with thearray index assigned in sequence.v If exactly one array-variable is specified:

– If the data type of the array-variable element is not a record type, theSELECT list must have exactly one column, and the column data typemust be assignable to the array element data type.

– If the data type of the array-variable element is a record type, the SELECTlist must be assignable to the record type.

v If multiple array variables are specified:– The data type of the array-variable element must not be a record type.– There must be an array-variable for each column in the SELECT list.– The data type of each column in the SELECT list must be assignable to

the array element data type of the corresponding array-variable.

If the data type of array-variable is an ordinary array, the maximum cardinalitymust be greater than or equal to the number of rows that are returned by thequery.

Notesv Variations of the BULK COLLECT INTO clause are also supported with the

FETCH statement and the EXECUTE IMMEDIATE statement.

162 SQL Procedural Languages: Application Enablement and Support

Page 173: IBM DB2 9.7 for Linux, UNIX, And Windows

Example

The following example shows a procedure that uses the BULK COLLECT INTOclause to return an array of rows from the procedure. The procedure and the typefor the array are defined in a package.CREATE OR REPLACE PACAKGE bci_sampleISTYPE emps_array IS VARRAY (30) OF VARCHAR2(6);

PROCEDURE get_dept_empno (dno IN emp.deptno%TYPE,emps_dno OUT emps_array);

END bci_sample;

CREATE OR REPLACE PACKAGE BODY bci_sampleISPROCEDURE get_dept_empno (dno IN emp.deptno%TYPE,emps_dno OUT emps_array)ISBEGINSELECT empno BULK COLLECT INTO emps_dnoFROM empWHERE deptno=dno;

END get_dept_empno;END bci_sample;

RETURNING INTO clause (PL/SQL)INSERT, UPDATE, and DELETE statements that are appended with the optionalRETURNING INTO clause can be compiled by the DB2 data server. When used inPL/SQL contexts, this clause captures the newly added, modified, or deletedvalues from executing INSERT, UPDATE, or DELETE statements, respectively.

Syntax

�� insert-statementupdate-statementdelete-statement

RETURNING *,

expr �

INTO record,

field

��

Description

insert-statementSpecifies a valid INSERT statement. An exception is raised if the INSERTstatement returns a result set that contains more than one row.

update-statementSpecifies a valid UPDATE statement. An exception is raised if the UPDATEstatement returns a result set that contains more than one row.

delete-statementSpecifies a valid DELETE statement. An exception is raised if the DELETEstatement returns a result set that contains more than one row.

RETURNING *Specifies that all of the values from the row that is affected by the INSERT,UPDATE, or DELETE statement are to be made available for assignment.

Chapter 16. Basic statements (PL/SQL) 163

Page 174: IBM DB2 9.7 for Linux, UNIX, And Windows

RETURNING exprSpecifies an expression to be evaluated against the row that is affected by theINSERT, UPDATE, or DELETE statement. The evaluated results are assigned toa specified record or fields.

INTO recordSpecifies that the returned values are to be stored in a record with compatiblefields and data types. The fields must match in number, order, and data typethose values that are specified with the RETURNING clause. If the result setcontains no rows, the fields in the record are set to the null value.

INTO fieldSpecifies that the returned values are to be stored in a set of variables withcompatible fields and data types. The fields must match in number, order, anddata type those values that are specified with the RETURNING clause. If theresult set contains no rows, the fields are set to the null value.

Examples

The following example shows a procedure that uses the RETURNING INTOclause:CREATE OR REPLACE PROCEDURE emp_comp_update (

p_empno IN emp.empno%TYPE,p_sal IN emp.sal%TYPE,p_comm IN emp.comm%TYPE

)IS

v_empno emp.empno%TYPE;v_ename emp.ename%TYPE;v_job emp.job%TYPE;v_sal emp.sal%TYPE;v_comm emp.comm%TYPE;v_deptno emp.deptno%TYPE;

BEGINUPDATE emp SET sal = p_sal, comm = p_comm WHERE empno = p_empnoRETURNING

empno,ename,job,sal,comm,deptno

INTOv_empno,v_ename,v_job,v_sal,v_comm,v_deptno;

IF SQL%FOUND THENDBMS_OUTPUT.PUT_LINE('Updated Employee # : ' || v_empno);DBMS_OUTPUT.PUT_LINE('Name : ' || v_ename);DBMS_OUTPUT.PUT_LINE('Job : ' || v_job);DBMS_OUTPUT.PUT_LINE('Department : ' || v_deptno);DBMS_OUTPUT.PUT_LINE('New Salary : ' || v_sal);DBMS_OUTPUT.PUT_LINE('New Commission : ' || v_comm);

ELSEDBMS_OUTPUT.PUT_LINE('Employee # ' || p_empno || ' not found');

END IF;END;

This procedure returns the following sample output:

164 SQL Procedural Languages: Application Enablement and Support

Page 175: IBM DB2 9.7 for Linux, UNIX, And Windows

EXEC emp_comp_update(9503, 6540, 1200);

Updated Employee # : 9503Name : PETERSONJob : ANALYSTDepartment : 40New Salary : 6540.00New Commission : 1200.00

The following example shows a procedure that uses the RETURNING INTO clausewith record types:CREATE OR REPLACE PROCEDURE emp_delete (

p_empno IN emp.empno%TYPE)IS

r_emp emp%ROWTYPE;BEGIN

DELETE FROM emp WHERE empno = p_empnoRETURNING

*INTO

r_emp;

IF SQL%FOUND THENDBMS_OUTPUT.PUT_LINE('Deleted Employee # : ' || r_emp.empno);DBMS_OUTPUT.PUT_LINE('Name : ' || r_emp.ename);DBMS_OUTPUT.PUT_LINE('Job : ' || r_emp.job);DBMS_OUTPUT.PUT_LINE('Manager : ' || r_emp.mgr);DBMS_OUTPUT.PUT_LINE('Hire Date : ' || r_emp.hiredate);DBMS_OUTPUT.PUT_LINE('Salary : ' || r_emp.sal);DBMS_OUTPUT.PUT_LINE('Commission : ' || r_emp.comm);DBMS_OUTPUT.PUT_LINE('Department : ' || r_emp.deptno);

ELSEDBMS_OUTPUT.PUT_LINE('Employee # ' || p_empno || ' not found');

END IF;END;

This procedure returns the following sample output:EXEC emp_delete(9503);

Deleted Employee # : 9503Name : PETERSONJob : ANALYSTManager : 7902Hire Date : 31-MAR-05 00:00:00Salary : 6540.00Commission : 1200.00Department : 40

Statement attributes (PL/SQL)SQL%FOUND, SQL%NOTFOUND, and SQL%ROWCOUNT are PL/SQL attributesthat can be used to determine the effect of an SQL statement.v The SQL%FOUND attribute has a Boolean value that returns TRUE if at least

one row was affected by an INSERT, UPDATE, or DELETE statement, or if aSELECT INTO statement retrieved one row. The following example shows ananonymous block in which a row is inserted and a status message is displayed.BEGIN

INSERT INTO emp (empno,ename,job,sal,deptno)VALUES (9001, 'JONES', 'CLERK', 850.00, 40);

Chapter 16. Basic statements (PL/SQL) 165

Page 176: IBM DB2 9.7 for Linux, UNIX, And Windows

IF SQL%FOUND THENDBMS_OUTPUT.PUT_LINE('Row has been inserted');

END IF;END;

v The SQL%NOTFOUND attribute has a Boolean value that returns TRUE if norows were affected by an INSERT, UPDATE, or DELETE statement, or if aSELECT INTO statement did not retrieve a row. For example:BEGIN

UPDATE emp SET hiredate = '03-JUN-07' WHERE empno = 9000;IF SQL%NOTFOUND THEN

DBMS_OUTPUT.PUT_LINE('No rows were updated');END IF;

END;

v The SQL%ROWCOUNT attribute has an integer value that represents thenumber of rows that were affected by an INSERT, UPDATE, or DELETEstatement. For example:BEGIN

UPDATE emp SET hiredate = '03-JUN-07' WHERE empno = 9001;DBMS_OUTPUT.PUT_LINE('# rows updated: ' || SQL%ROWCOUNT);

END;

166 SQL Procedural Languages: Application Enablement and Support

Page 177: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 17. Control statements (PL/SQL)

Control statements are the programming statements that make PL/SQL a fullprocedural complement to SQL.

A number of PL/SQL control statements can be compiled by the DB2 data server.

IF statement (PL/SQL)Use the IF statement within PL/SQL contexts to execute SQL statements on thebasis of certain criteria.

The four forms of the IF statement are:v IF...THEN...END IFv IF...THEN...ELSE...END IFv IF...THEN...ELSE IF...END IFv IF...THEN...ELSIF...THEN...ELSE...END IF

IF...THEN...END IF

The syntax of this statement is:IF boolean-expression THEN

statementsEND IF;

IF...THEN statements are the simplest form of IF. The statements between THENand END IF are executed only if the condition evaluates to TRUE. In the followingexample, an IF...THEN statement is used to test for and to display those employeeswho have a commission.DECLARE

v_empno emp.empno%TYPE;v_comm emp.comm%TYPE;CURSOR emp_cursor IS SELECT empno, comm FROM emp;

BEGINOPEN emp_cursor;DBMS_OUTPUT.PUT_LINE('EMPNO COMM');DBMS_OUTPUT.PUT_LINE('----- -------');LOOP

FETCH emp_cursor INTO v_empno, v_comm;EXIT WHEN emp_cursor%NOTFOUND;

---- Test whether or not the employee gets a commission--

IF v_comm IS NOT NULL AND v_comm > 0 THENDBMS_OUTPUT.PUT_LINE(v_empno || ' ' ||TO_CHAR(v_comm,'$99999.99'));

END IF;END LOOP;CLOSE emp_cursor;

END;

This program generates the following sample output:

© Copyright IBM Corp. 1993, 2009 167

Page 178: IBM DB2 9.7 for Linux, UNIX, And Windows

EMPNO COMM----- -------7499 $300.007521 $500.007654 $1400.00

IF...THEN...ELSE...END IF

The syntax of this statement is:IF boolean-expression THEN

statementsELSE

statementsEND IF;

IF...THEN...ELSE statements specify an alternative set of statements that should beexecuted if the condition evaluates to FALSE. In the following example, theprevious example is modified so that an IF...THEN...ELSE statement is used todisplay the text “Non-commission” if an employee does not have a commission.DECLARE

v_empno emp.empno%TYPE;v_comm emp.comm%TYPE;CURSOR emp_cursor IS SELECT empno, comm FROM emp;

BEGINOPEN emp_cursor;DBMS_OUTPUT.PUT_LINE('EMPNO COMM');DBMS_OUTPUT.PUT_LINE('----- -------');LOOP

FETCH emp_cursor INTO v_empno, v_comm;EXIT WHEN emp_cursor%NOTFOUND;

---- Test whether or not the employee gets a commission--

IF v_comm IS NOT NULL AND v_comm > 0 THENDBMS_OUTPUT.PUT_LINE(v_empno || ' ' ||TO_CHAR(v_comm,'$99999.99'));

ELSEDBMS_OUTPUT.PUT_LINE(v_empno || ' ' || 'Non-commission');

END IF;END LOOP;CLOSE emp_cursor;

END;

This program generates the following sample output:EMPNO COMM----- -------7369 Non-commission7499 $ 300.007521 $ 500.007566 Non-commission7654 $ 1400.007698 Non-commission7782 Non-commission7788 Non-commission7839 Non-commission7844 Non-commission7876 Non-commission7900 Non-commission7902 Non-commission7934 Non-commission

168 SQL Procedural Languages: Application Enablement and Support

Page 179: IBM DB2 9.7 for Linux, UNIX, And Windows

IF...THEN...ELSE IF...END IF

The syntax of this statement is:IF boolean-expression THEN

IF boolean-expression THENstatements

ELSEIF boolean-expression THEN

statementsEND IF;

You can nest IF statements so that alternative IF statements are invoked, dependingon whether the conditions of an outer IF statement evaluate to TRUE or FALSE. Inthe following example, the outer IF...THEN...ELSE statement tests whether or notan employee has a commission. The inner IF...THEN...ELSE statementssubsequently test whether the employee’s total compensation exceeds or is lessthan the company average. When you use this form of the IF statement, you areactually nesting an IF statement inside of the ELSE part of an outer IF statement.You therefore need one END IF for each nested IF and one for the parent IF...ELSE.(Note that the logic in this program can be simplified considerably by calculatingeach employee’s yearly compensation using an NVL function within the SELECTstatement of the cursor declaration; however, the purpose of this example is todemonstrate how IF statements can be used.)DECLARE

v_empno emp.empno%TYPE;v_sal emp.sal%TYPE;v_comm emp.comm%TYPE;v_avg NUMBER(7,2);CURSOR emp_cursor IS SELECT empno, sal, comm FROM emp;

BEGIN---- Calculate the average yearly compensation--

SELECT AVG((sal + NVL(comm,0)) * 24) INTO v_avg FROM emp;DBMS_OUTPUT.PUT_LINE('Average Yearly Compensation: ' ||

TO_CHAR(v_avg,'$999,999.99'));OPEN emp_cursor;DBMS_OUTPUT.PUT_LINE('EMPNO YEARLY COMP');DBMS_OUTPUT.PUT_LINE('----- -----------');LOOP

FETCH emp_cursor INTO v_empno, v_sal, v_comm;EXIT WHEN emp_cursor%NOTFOUND;

---- Test whether or not the employee gets a commission--

IF v_comm IS NOT NULL AND v_comm > 0 THEN---- Test whether the employee's compensation with commission exceeds-- the company average--

IF (v_sal + v_comm) * 24 > v_avg THENDBMS_OUTPUT.PUT_LINE(v_empno || ' ' ||

TO_CHAR((v_sal + v_comm) * 24,'$999,999.99') ||' Exceeds Average');

ELSEDBMS_OUTPUT.PUT_LINE(v_empno || ' ' ||

TO_CHAR((v_sal + v_comm) * 24,'$999,999.99') ||' Below Average');

END IF;ELSE

---- Test whether the employee's compensation without commission exceeds-- the company average

Chapter 17. Control statements (PL/SQL) 169

Page 180: IBM DB2 9.7 for Linux, UNIX, And Windows

--IF v_sal * 24 > v_avg THEN

DBMS_OUTPUT.PUT_LINE(v_empno || ' ' ||TO_CHAR(v_sal * 24,'$999,999.99') || ' Exceeds Average');

ELSEDBMS_OUTPUT.PUT_LINE(v_empno || ' ' ||

TO_CHAR(v_sal * 24,'$999,999.99') || ' Below Average');END IF;

END IF;END LOOP;CLOSE emp_cursor;

END;

This program generates the following sample output:Average Yearly Compensation: $ 53,528.57EMPNO YEARLY COMP----- -----------7369 $ 19,200.00 Below Average7499 $ 45,600.00 Below Average7521 $ 42,000.00 Below Average7566 $ 71,400.00 Exceeds Average7654 $ 63,600.00 Exceeds Average7698 $ 68,400.00 Exceeds Average7782 $ 58,800.00 Exceeds Average7788 $ 72,000.00 Exceeds Average7839 $ 120,000.00 Exceeds Average7844 $ 36,000.00 Below Average7876 $ 26,400.00 Below Average7900 $ 22,800.00 Below Average7902 $ 72,000.00 Exceeds Average7934 $ 31,200.00 Below Average

IF...THEN...ELSIF...THEN...ELSE...END IF

The syntax of this statement is:IF boolean-expression THEN

statements[ ELSIF boolean-expression THEN

statements[ ELSIF boolean-expression THEN

statements ] ...][ ELSE

statements ]END IF;

IF...THEN...ELSIF...ELSE statements provide the means for checking manyalternatives in one statement. Formally, this statement is equivalent to nestedIF...THEN...ELSE...IF...THEN statements, but only one END IF is needed. Thefollowing example uses an IF...THEN...ELSIF...ELSE statement to count the numberof employees by compensation, in steps of $25,000.DECLARE

v_empno emp.empno%TYPE;v_comp NUMBER(8,2);v_lt_25K SMALLINT := 0;v_25K_50K SMALLINT := 0;v_50K_75K SMALLINT := 0;v_75K_100K SMALLINT := 0;v_ge_100K SMALLINT := 0;CURSOR emp_cursor IS SELECT empno, (sal + NVL(comm,0)) * 24 FROM emp;

BEGINOPEN emp_cursor;LOOP

FETCH emp_cursor INTO v_empno, v_comp;EXIT WHEN emp_cursor%NOTFOUND;

170 SQL Procedural Languages: Application Enablement and Support

Page 181: IBM DB2 9.7 for Linux, UNIX, And Windows

IF v_comp < 25000 THENv_lt_25K := v_lt_25K + 1;

ELSIF v_comp < 50000 THENv_25K_50K := v_25K_50K + 1;

ELSIF v_comp < 75000 THENv_50K_75K := v_50K_75K + 1;

ELSIF v_comp < 100000 THENv_75K_100K := v_75K_100K + 1;

ELSEv_ge_100K := v_ge_100K + 1;

END IF;END LOOP;CLOSE emp_cursor;DBMS_OUTPUT.PUT_LINE('Number of employees by yearly compensation');DBMS_OUTPUT.PUT_LINE('Less than 25,000 : ' || v_lt_25K);DBMS_OUTPUT.PUT_LINE('25,000 - 49,9999 : ' || v_25K_50K);DBMS_OUTPUT.PUT_LINE('50,000 - 74,9999 : ' || v_50K_75K);DBMS_OUTPUT.PUT_LINE('75,000 - 99,9999 : ' || v_75K_100K);DBMS_OUTPUT.PUT_LINE('100,000 and over : ' || v_ge_100K);

END;

This program generates the following sample output:Number of employees by yearly compensationLess than 25,000 : 225,000 - 49,9999 : 550,000 - 74,9999 : 675,000 - 99,9999 : 0100,000 and over : 1

CASE statement (PL/SQL)The CASE statement executes a set of one or more statements when a specifiedsearch condition is true. CASE is a standalone statement that is distinct from theCASE expression, which must appear as part of an expression.

There are two forms of the CASE statement: the simple CASE statement and thesearched CASE statement.

Simple CASE statement (PL/SQL)The simple CASE statement attempts to match an expression (known as theselector) to another expression that is specified in one or more WHEN clauses. Amatch results in the execution of one or more corresponding statements.

Syntax

�� CASE selector-expression �

� � �WHEN match-expression THEN statements

�ELSE statements

Chapter 17. Control statements (PL/SQL) 171

Page 182: IBM DB2 9.7 for Linux, UNIX, And Windows

� END CASE ��

Description

CASE selector-expressionSpecifies an expression whose value has a data type that is compatible witheach match-expression. If the value of selector-expression matches the firstmatch-expression, the statements in the corresponding THEN clause areexecuted. If there are no matches, the statements in the corresponding ELSEclause are executed. If there are no matches and there is no ELSE clause, anexception is thrown.

WHEN match-expressionSpecifies an expression that is evaluated within the CASE statement. Ifselector-expression matches a match-expression, the statements in thecorresponding THEN clause are executed.

THENA keyword that introduces the statements that are to be executed when thecorresponding Boolean expression evaluates to TRUE.

statementsSpecifies one or more SQL or PL/SQL statements, each terminated with asemicolon.

ELSEA keyword that introduces the default case of the CASE statement.

Example

The following example uses a simple CASE statement to assign a departmentname and location to a variable that is based upon the department number.DECLARE

v_empno emp.empno%TYPE;v_ename emp.ename%TYPE;v_deptno emp.deptno%TYPE;v_dname dept.dname%TYPE;v_loc dept.loc%TYPE;CURSOR emp_cursor IS SELECT empno, ename, deptno FROM emp;

BEGINOPEN emp_cursor;DBMS_OUTPUT.PUT_LINE('EMPNO ENAME DEPTNO DNAME '

|| ' LOC');DBMS_OUTPUT.PUT_LINE('----- ------- ------ ----------'

|| ' ---------');LOOP

FETCH emp_cursor INTO v_empno, v_ename, v_deptno;EXIT WHEN emp_cursor%NOTFOUND;CASE v_deptno

WHEN 10 THEN v_dname := 'Accounting';v_loc := 'New York';

WHEN 20 THEN v_dname := 'Research';v_loc := 'Dallas';

WHEN 30 THEN v_dname := 'Sales';v_loc := 'Chicago';

WHEN 40 THEN v_dname := 'Operations';v_loc := 'Boston';

ELSE v_dname := 'unknown';v_loc := '';

172 SQL Procedural Languages: Application Enablement and Support

Page 183: IBM DB2 9.7 for Linux, UNIX, And Windows

END CASE;DBMS_OUTPUT.PUT_LINE(v_empno || ' ' || RPAD(v_ename, 10) ||

' ' || v_deptno || ' ' || RPAD(v_dname, 14) || ' ' ||v_loc);

END LOOP;CLOSE emp_cursor;

END;

This program returns the following sample output:EMPNO ENAME DEPTNO DNAME LOC----- ------- ------ ---------- ---------7369 SMITH 20 Research Dallas7499 ALLEN 30 Sales Chicago7521 WARD 30 Sales Chicago7566 JONES 20 Research Dallas7654 MARTIN 30 Sales Chicago7698 BLAKE 30 Sales Chicago7782 CLARK 10 Accounting New York7788 SCOTT 20 Research Dallas7839 KING 10 Accounting New York7844 TURNER 30 Sales Chicago7876 ADAMS 20 Research Dallas7900 JAMES 30 Sales Chicago7902 FORD 20 Research Dallas7934 MILLER 10 Accounting New York

Searched CASE statement (PL/SQL)A searched CASE statement uses one or more Boolean expressions to determinewhich statements to execute.

Syntax

�� CASE � WHEN boolean-expression THEN statements ELSE statements �

� END CASE ��

Description

CASEA keyword that introduces the first WHEN clause in the CASE statement.

WHEN boolean-expressionSpecifies an expression that is evaluated when control flow enters the WHENclause in which the expression is defined. If boolean-expression evaluates toTRUE, the statements in the corresponding THEN clause are executed. Ifboolean-expression does not evaluate to TRUE, the statements in thecorresponding ELSE clause are executed.

THENA keyword that introduces the statements that are to be executed when thecorresponding Boolean expression evaluates to TRUE.

statementsSpecifies one or more SQL or PL/SQL statements, each terminated with asemicolon.

Chapter 17. Control statements (PL/SQL) 173

Page 184: IBM DB2 9.7 for Linux, UNIX, And Windows

ELSEA keyword that introduces the default case of the CASE statement.

Example

The following example uses a searched CASE statement to assign a departmentname and location to a variable that is based upon the department number.DECLARE

v_empno emp.empno%TYPE;v_ename emp.ename%TYPE;v_deptno emp.deptno%TYPE;v_dname dept.dname%TYPE;v_loc dept.loc%TYPE;CURSOR emp_cursor IS SELECT empno, ename, deptno FROM emp;

BEGINOPEN emp_cursor;DBMS_OUTPUT.PUT_LINE('EMPNO ENAME DEPTNO DNAME '

|| ' LOC');DBMS_OUTPUT.PUT_LINE('----- ------- ------ ----------'

|| ' ---------');LOOP

FETCH emp_cursor INTO v_empno, v_ename, v_deptno;EXIT WHEN emp_cursor%NOTFOUND;CASE

WHEN v_deptno = 10 THEN v_dname := 'Accounting';v_loc := 'New York';

WHEN v_deptno = 20 THEN v_dname := 'Research';v_loc := 'Dallas';

WHEN v_deptno = 30 THEN v_dname := 'Sales';v_loc := 'Chicago';

WHEN v_deptno = 40 THEN v_dname := 'Operations';v_loc := 'Boston';

ELSE v_dname := 'unknown';v_loc := '';

END CASE;DBMS_OUTPUT.PUT_LINE(v_empno || ' ' || RPAD(v_ename, 10) ||

' ' || v_deptno || ' ' || RPAD(v_dname, 14) || ' ' ||v_loc);

END LOOP;CLOSE emp_cursor;

END;

This program returns the following sample output:EMPNO ENAME DEPTNO DNAME LOC----- ------- ------ ---------- ---------7369 SMITH 20 Research Dallas7499 ALLEN 30 Sales Chicago7521 WARD 30 Sales Chicago7566 JONES 20 Research Dallas7654 MARTIN 30 Sales Chicago7698 BLAKE 30 Sales Chicago7782 CLARK 10 Accounting New York7788 SCOTT 20 Research Dallas7839 KING 10 Accounting New York7844 TURNER 30 Sales Chicago7876 ADAMS 20 Research Dallas7900 JAMES 30 Sales Chicago7902 FORD 20 Research Dallas7934 MILLER 10 Accounting New York

Loops (PL/SQL)Use the EXIT, FOR, LOOP, and WHILE statements to repeat a series of commandsin your PL/SQL program.

174 SQL Procedural Languages: Application Enablement and Support

Page 185: IBM DB2 9.7 for Linux, UNIX, And Windows

FOR (cursor variant) statement (PL/SQL)The cursor FOR loop statement opens a previously declared cursor, fetches all rowsin the cursor result set, and then closes the cursor.

Use this statement instead of separate SQL statements to open a cursor, define aloop construct to retrieve each row of the result set, test for the end of the resultset, and then finally close the cursor.

Invocation

This statement can be invoked within a PL/SQL procedure, function, trigger, oranonymous block.

Authorization

No specific authorization is required to reference a row expression within an SQLstatement; however, for successful statement execution, all other authorizationrequirements for processing a cursor are required.

Syntax

�� FOR record IN cursor LOOP statements END LOOP ��

Description

FORIntroduces the condition that must be true if the FOR loop is to proceed.

recordSpecifies an identifier that was assigned to an implicitly declared record withdefinition cursor%ROWTYPE.

IN cursorSpecifies the name of a previously declared cursor.

LOOP and END LOOPStarts and ends the loop containing SQL statements that are to be executedduring each iteration through the loop.

statementsOne or more PL/SQL statements. A minimum of one statement is required.

Example

The following example shows a procedure that contains a cursor FOR loop:CREATE OR REPLACE PROCEDURE cursor_exampleIS

CURSOR emp_cur_1 IS SELECT * FROM emp;BEGIN

DBMS_OUTPUT.PUT_LINE('EMPNO ENAME');DBMS_OUTPUT.PUT_LINE('----- -------');FOR v_emp_rec IN emp_cur_1 LOOP

DBMS_OUTPUT.PUT_LINE(v_emp_rec.empno || ' ' || v_emp_rec.ename);END LOOP;

END;

FOR (integer variant) statement (PL/SQL)Use the FOR statement to execute a set of SQL statements more than once.

Chapter 17. Control statements (PL/SQL) 175

Page 186: IBM DB2 9.7 for Linux, UNIX, And Windows

Invocation

This statement can be embedded within a PL/SQL procedure, function, oranonymous block statement.

Authorization

No privileges are required to invoke the FOR statement; however, theauthorization ID of the statement must hold the necessary privileges to invoke theSQL statements that are embedded in the FOR statement.

Syntax

�� FOR integer-variable INREVERSE

expression1 .. expression2 �

� LOOP statements END LOOP ��

Description

integer-variableAn automatically defined integer variable that is used during loop processing.The initial value of integer-variable is expression1. After the initial iteration, thevalue of integer-variable is incremented at the beginning of each subsequentiteration. Both expression1 and expression2 are evaluated when entering the loop,and loop processing stops when integer-variable is equal to expression2.

IN Introduces the optional REVERSE keyword and expressions that define therange of integer variables for the loop.

REVERSESpecifies that the iteration is to proceed from expression2 to expression1. Notethat expression2 must have a higher value than expression1, regardless ofwhether the REVERSE keyword is specified, if the statements in the loop are tobe processed.

expression1Specifies the initial value of the range of integer variables for the loop. If theREVERSE keyword is specified, expression1 specifies the end value of the rangeof integer variables for the loop.

expression2Specifies the end value of the range of integer variables for the loop. If theREVERSE keyword is specified, expression2 specifies the initial value of therange of integer variables for the loop.

statementsSpecifies the PL/SQL and SQL statements that are executed each time that theloop is processed.

Examples

The following example shows a basic FOR statement within an anonymous block:BEGIN

FOR i IN 1 .. 10 LOOPDBMS_OUTPUT.PUT_LINE('Iteration # ' || i);

END LOOP;END;

176 SQL Procedural Languages: Application Enablement and Support

Page 187: IBM DB2 9.7 for Linux, UNIX, And Windows

This example generates the following output:Iteration # 1Iteration # 2Iteration # 3Iteration # 4Iteration # 5Iteration # 6Iteration # 7Iteration # 8Iteration # 9Iteration # 10

If the start value is greater than the end value, the loop body is not executed at all,but no error is returned, as shown by the following example:BEGIN

FOR i IN 10 .. 1 LOOPDBMS_OUTPUT.PUT_LINE('Iteration # ' || i);

END LOOP;END;

This example generates no output, because the loop body is never executed.

The following example uses the REVERSE keyword:BEGIN

FOR i IN REVERSE 1 .. 10 LOOPDBMS_OUTPUT.PUT_LINE('Iteration # ' || i);

END LOOP;END;

This example generates the following output:Iteration # 10Iteration # 9Iteration # 8Iteration # 7Iteration # 6Iteration # 5Iteration # 4Iteration # 3Iteration # 2Iteration # 1

FORALL statement (PL/SQL)The FORALL statement executes a data change statement for all elements of anarray or for a range of elements of an array.

Invocation

This statement can only be specified in a PL/SQL block.

Authorization

The privileges held by the authorization ID of the statement must include all of theprivileges necessary to invoke the data change statement that is specified in theFORALL statement.

Syntax

�� FORALL index-variable IN lower-bound .. upper-boundINDICES OF indexing-arrayVALUES OF indexing-array

Chapter 17. Control statements (PL/SQL) 177

Page 188: IBM DB2 9.7 for Linux, UNIX, And Windows

� insert-statementsearched-delete-statementsearched-update-statementexecute-immediate-statement

��

Description

index-variableIdentifies a name to be used as an array index. It is implicitly declared as anINTEGER and it can only be referenced in the FORALL statement.

lower-bound .. upper-boundIdentifies a range of index values that are assignable to the index-variable withlower-bound less than upper-bound. The range represents every integer valuestarting with lower-bound and incrementing by 1 up to and includingupper-bound.

INDICES OF indexing-arrayIdentifies the set of array index values of the array identified by indexing–array.If indexing-array is an associative array, array index values must be assignableto index-variable and could be a sparse set.

VALUES OF indexing-arrayIdentifies the set of element values of the array identified by indexing–array.The element values must be assignable to index-variable and could be anunordered sparse set.

insert-statementSpecifies an INSERT statement that is effectively executed for eachindex-variable value.

searched-delete-statementSpecifies a searched DELETE statement that is effectively executed for eachindex-variable value.

searched-update-statementSpecifies a searched UPDATE statement that is effectively executed for eachindex-variable value.

execute-immediate-statementSpecifies an EXECUTE IMMEDIATE statement that is effectively executed foreach index-variable value.

Notesv FORALL statement processing is not atomic. If an error occurs while iterating in

the FORALL statement, any data change operations that have already beenprocessed are not implicitly rolled back. An application can use a ROLLBACKstatement to roll back the entire transaction when an error occurs in theFORALL statement.

Example

The following example shows a basic FORALL statement:FORALL x

IN in_customer_list.FIRST..in_customer_list.LASTDELETE FROM customer

WHERE cust_id IN in_customer_list(x);

178 SQL Procedural Languages: Application Enablement and Support

Page 189: IBM DB2 9.7 for Linux, UNIX, And Windows

EXIT statement (PL/SQL)The EXIT statement terminates execution of a loop within a PL/SQL code block.

Invocation

This statement can be embedded within a FOR, LOOP, or WHILE statement, orwithin a PL/SQL procedure, function, or anonymous block statement.

Authorization

No privileges are required to invoke the EXIT statement. However, theauthorization ID of the statement must hold the necessary privileges to invoke theSQL statements that are embedded within the FOR, LOOP, or WHILE statement.

Syntax

�� EXIT ��

Example

The following example shows a basic LOOP statement with an EXIT statementwithin an anonymous block:DECLARE

sum PLS_INTEGER := 0;BEGIN

LOOPsum := sum + 1;IF sum > 10 THEN

EXIT;END IF;

END LOOP;END

LOOP statement (PL/SQL)The LOOP statement executes a sequence of statements within a PL/SQL codeblock multiple times.

Invocation

This statement can be embedded in a PL/SQL procedure, function, or anonymousblock statement.

Authorization

No privileges are required to invoke the LOOP statement. However, theauthorization ID of the statement must hold the necessary privileges to invoke theSQL statements that are embedded within the LOOP statement.

Syntax

�� LOOP statements END LOOP ��

Chapter 17. Control statements (PL/SQL) 179

Page 190: IBM DB2 9.7 for Linux, UNIX, And Windows

Description

statementsSpecifies one or more PL/SQL or SQL statements. These statements areexecuted during each iteration of the loop.

Example

The following example shows a basic LOOP statement within an anonymousblock:DECLARE

sum INTEGER := 0;BEGIN

LOOPsum := sum + 1;IF sum > 10 THEN

EXIT;END IF;

END LOOP;END

WHILE statement (PL/SQL)The WHILE statement repeats a set of SQL statements as long as a specifiedexpression is true. The condition is evaluated immediately before each entry intothe loop body.

Invocation

This statement can be embedded within a PL/SQL procedure, function, oranonymous block statement.

Authorization

No privileges are required to invoke the WHILE statement; however, theauthorization ID of the statement must hold the necessary privileges to invoke theSQL statements that are embedded in the WHILE statement.

Syntax

�� WHILE expression LOOP statements END LOOP ��

Description

expressionSpecifies an expression that is evaluated immediately before each entry into theloop body to determine whether or not the loop is to be executed. If theexpression is logically true, the loop is executed. If the expression is logicallyfalse, loop processing ends. An EXIT statement can be used to terminate theloop while the expression is true.

statementsSpecifies the PL/SQL and SQL statements that are executed each time that theloop is processed.

180 SQL Procedural Languages: Application Enablement and Support

Page 191: IBM DB2 9.7 for Linux, UNIX, And Windows

Example

The following example shows a basic WHILE statement within an anonymousblock:DECLARE

sum INTEGER := 0;BEGIN

WHILE sum < 11 LOOPsum := sum + 1;

END LOOP;END

The WHILE statement within this anonymous block executes until sum is equal to11; loop processing then ends, and processing of the anonymous block proceeds tocompletion.

Exception handling (PL/SQL)By default, any error encountered in a PL/SQL program stops execution of theprogram. You can trap and recover from errors by using an EXCEPTION section.

The syntax for exception handlers is an extension of the syntax for a BEGIN block.

Syntax

��

�DECLARE declaration

�BEGINstatement

� �EXCEPTION WHEN exception-condition THEN handler-statementOR condition

END ��

If no error occurs, the block simply executes statement, and control passes to thestatement after END. But if an error occurs while executing a statement, furtherprocessing of the statement is abandoned, and control passes to the EXCEPTIONlist. The list is searched for the first condition matching the error that occurred. If amatch is found, the corresponding handler-statement is executed, and control passesto the statement after END. If no match is found, the program stops executing.

If a new error occurs during execution of the handler-statement, it can only becaught by a surrounding EXCEPTION clause.

Table 8 summarizes the system-defined conditions that you can use. The specialcondition name OTHERS matches every error type. Condition names are not casesensitive.

Table 8. System-defined exception condition names

Condition name Description

CASE_NOT_FOUND None of the cases in a CASE statementevaluates to “true”, and there is no ELSEcondition.

Chapter 17. Control statements (PL/SQL) 181

Page 192: IBM DB2 9.7 for Linux, UNIX, And Windows

Table 8. System-defined exception condition names (continued)

Condition name Description

CURSOR_ALREADY_OPEN An attempt was made to open a cursor thatis already open.

DUP_VAL_ON_INDEX There are duplicate values for the index key.

INVALID_CURSOR An attempt was made to access anunopened cursor.

INVALID_NUMBER The numeric value is invalid.

LOGIN_DENIED The user name or password is invalid.

NO_DATA_FOUND No rows satisfied the selection criteria.

NOT_LOGGED_ON A database connection does not exist.

OTHERS For any exception that has not been caughtby a prior condition in the exception section.

SUBSCRIPT_BEYOND_COUNT An array index is out of range or does notexist.

SUBSCRIPT_OUTSIDE_LIMIT The data type of an array index expressionis not assignable to the array index type.

TOO_MANY_ROWS More than one row satisfied the selectioncriteria, but only one row is allowed to bereturned.

VALUE_ERROR The value is invalid.

ZERO_DIVIDE Division by zero was attempted.

Raise application error (PL/SQL)The RAISE_APPLICATION_ERROR procedure makes a user-defined code anderror message available to the program which can then be used to identify theexception. This procedure is only supported in PL/SQL contexts.

Syntax

�� RAISE_APPLICATION_ERROR ( error-number , message ) ; ��

Description

error-numberA vendor-specific number (expressed as a literal) that is mapped to a DB2 errorcode before it is stored in a variable named SQLCODE. TheRAISE_APPLICATION_ERROR procedure accepts user-defined error-numbervalues from -20000 to -20999. The SQLCODE that is returned in the errormessage is SQL0438N. The SQLSTATE contains class ’UD’ plus three charactersthat correspond to the last three digits of the error-number value.

messageA user-defined message with a maximum length of 70 bytes.

Example

The following example uses the RAISE_APPLICATION_ERROR procedure todisplay error codes and messages that are specific to missing employeeinformation:

182 SQL Procedural Languages: Application Enablement and Support

Page 193: IBM DB2 9.7 for Linux, UNIX, And Windows

CREATE OR REPLACE PROCEDURE verify_emp (p_empno NUMBER

)IS

v_ename emp.ename%TYPE;v_job emp.job%TYPE;v_mgr emp.mgr%TYPE;v_hiredate emp.hiredate%TYPE;

BEGINSELECT ename, job, mgr, hiredate

INTO v_ename, v_job, v_mgr, v_hiredate FROM empWHERE empno = p_empno;

IF v_ename IS NULL THENRAISE_APPLICATION_ERROR(-20010, 'No name for ' || p_empno);

END IF;IF v_job IS NULL THEN

RAISE_APPLICATION_ERROR(-20020, 'No job for' || p_empno);END IF;IF v_mgr IS NULL THEN

RAISE_APPLICATION_ERROR(-20030, 'No manager for ' || p_empno);END IF;IF v_hiredate IS NULL THEN

RAISE_APPLICATION_ERROR(-20040, 'No hire date for ' || p_empno);END IF;DBMS_OUTPUT.PUT_LINE('Employee ' || p_empno ||

' validated without errors');EXCEPTION

WHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('SQLCODE: ' || SQLCODE);DBMS_OUTPUT.PUT_LINE('SQLERRM: ' || SQLERRM);

END;

CALL verify_emp(7839);

SQLCODE: -438SQLERRM: SQL0438N Application raised error or warning withdiagnostic text: "No manager for 7839". SQLSTATE=UD030

RAISE statement (PL/SQL)The RAISE statement raises a previously-defined condition.

Syntax

�� RAISE condition ��

Description

conditionSpecifies a previously-defined condition.

Example

The following example shows a procedure that raises a defined condition:CREATE OR REPLACE PROCEDURE raise_demo (inval NUMBER) IS

evenno EXCEPTION;oddno EXCEPTION;

BEGINIF MOD(inval, 2) = 1 THEN

RAISE oddno;ELSE

RAISE evenno;END IF;

Chapter 17. Control statements (PL/SQL) 183

Page 194: IBM DB2 9.7 for Linux, UNIX, And Windows

EXCEPTIONWHEN evenno THEN

dbms_output.put_line(TO_CHAR(inval) || ' is even');WHEN oddno THEN

dbms_output.put_line(TO_CHAR(inval) || ' is odd');END raise_demo;/

SET SERVEROUTPUT ON;

CALL raise_demo;

Oracle-DB2 error mapping (PL/SQL)PL/SQL error codes and exception names have corresponding DB2 error codes andSQLSTATE values.

These error codes, exception names, and SQLSTATE values are summarized inTable 9.

Table 9. Mapping of PL/SQL error codes and exception names to DB2 error codes andSQLSTATE values

plsqlCode plsqlName db2Code db2State

-1 DUP_VAL_ON_INDEX -803 23505

+100 NO_DATA_FOUND +100 02000

-1012 NOT_LOGGED_ON -1024 08003

-1017 LOGIN_DENIED -30082 08001

-1476 ZERO_DIVIDE -801 22012

-1722 INVALID_NUMBER -420 22018

-1001 INVALID_CURSOR -501 24501

-1422 TOO_MANY_ROWS -811 21000

-6502 VALUE_ERROR -433 22001

-6511 CURSOR_ALREADY_OPEN -502 24502

-6532 SUBSCRIPT_OUTSIDE_LIMIT -20438 428H1

-6533 SUBSCRIPT_BEYOND_COUNT -20439 2202E

-6592 CASE_NOT_FOUND -773 20000

-54 -904 57011

-60 -911 40001

-310 -206 42703

-595 -390 42887

-597 -303 42806

-598 -407 23502

-600 -30071 58015

-603 -119 42803

-604 -119 42803

-610 -20500 428HR

-611 -117 42802

-612 -117 42802

-613 -811 21000

184 SQL Procedural Languages: Application Enablement and Support

Page 195: IBM DB2 9.7 for Linux, UNIX, And Windows

Table 9. Mapping of PL/SQL error codes and exception names to DB2 error codes andSQLSTATE values (continued)

plsqlCode plsqlName db2Code db2State

-615 -420 22018

-616 -420 22018

-617 -418 42610

-618 -420 22018

-619 -418 42610

-620 -171 42815

-622 -304 22003

-623 -604 42611

-904 -206 42703

-911 -7 42601

-942 -204 42704

-955 -601 42710

-996 -1022 57011

-1119 -292 57047

-1002 +231 02000

-1403 -100 02000

-1430 -612 42711

-1436 -20451 560CO

-1438 -413 22003

-1450 -614 54008

-1578 -1007 58034

-2112 -811 21000

-2261 +605 01550

-2291 -530 23503

-2292 -532 23001

-3113 -30081 08001

-3114 -1024 08003

-3214 -20170 57059

-3297 -20170 57059

-4061 -727 56098

-4063 -727 56098

-4091 -723 09000

-6502 -304 22003

-6508 -440 42884

-6550 -104 42601

-6553 -104 42601

-14028 -538 42830

-19567 -1523 55039

-30006 -904 57011

Chapter 17. Control statements (PL/SQL) 185

Page 196: IBM DB2 9.7 for Linux, UNIX, And Windows

Table 9. Mapping of PL/SQL error codes and exception names to DB2 error codes andSQLSTATE values (continued)

plsqlCode plsqlName db2Code db2State

-30041 -1139 54047

186 SQL Procedural Languages: Application Enablement and Support

Page 197: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 18. Cursors (PL/SQL)

A cursor is a named control structure used by an application program to point toand select a row of data from a result set. Instead of executing a query all at once,you can use a cursor to read and process the query result set one row at a time.

A cursor in a PL/SQL context is treated as a WITH HOLD cursor. For moreinformation about WITH HOLD cursors, see “DECLARE CURSOR statement”.

The DB2 data server supports both PL/SQL static cursors and cursor variables.

Static cursors (PL/SQL)A static cursor is a cursor whose associated query is fixed at compile time.Declaring a cursor is a prerequisite to using it. Declarations of static cursors usingPL/SQL syntax within PL/SQL contexts are supported by the DB2 server.

Syntax

�� CURSOR cursor-name IS query ��

Description

cursor-nameSpecifies an identifier for the cursor that can be used to reference the cursorand its result set.

querySpecifies a SELECT statement that determines a result set for the cursor.

Example

The following example shows a procedure that contains multiple static cursordeclarations:CREATE OR REPLACE PROCEDURE cursor_exampleIS

CURSOR emp_cur_1 IS SELECT * FROM emp;

CURSOR emp_cur_2 IS SELECT empno, ename FROM emp;

CURSOR emp_cur_3 IS SELECT empno, enameFROM empWHERE deptno = 10ORDER BY empno;

BEGINOPEN emp_cur_1;

...END;

Parameterized cursors (PL/SQL)Parameterized cursors are static cursors that can accept passed-in parameter valueswhen they are opened.

© Copyright IBM Corp. 1993, 2009 187

Page 198: IBM DB2 9.7 for Linux, UNIX, And Windows

The following example includes a parameterized cursor. The cursor displays thename and salary of each employee in the EMP table whose salary is less than thatspecified by a passed-in parameter value.DECLARE

my_record emp%ROWTYPE;CURSOR c1 (max_wage NUMBER) IS

SELECT * FROM emp WHERE sal < max_wage;BEGIN

OPEN c1(2000);LOOP

FETCH c1 INTO my_record;EXIT WHEN c1%NOTFOUND;DBMS_OUTPUT.PUT_LINE('Name = ' || my_record.ename || ', salary = '

|| my_record.sal);END LOOP;CLOSE c1;

END;

If 2000 is passed in as the value of max_wage, only the name and salary data forthose employees whose salary is less than 2000 is returned:Name = SMITH, salary = 800.00Name = ALLEN, salary = 1600.00Name = WARD, salary = 1250.00Name = MARTIN, salary = 1250.00Name = TURNER, salary = 1500.00Name = ADAMS, salary = 1100.00Name = JAMES, salary = 950.00Name = MILLER, salary = 1300.00

Opening a cursor (PL/SQL)The result set that is associated with a cursor cannot be referenced until the cursorhas been opened.

Syntax

��

OPEN cursor-name,

( expression )expression

��

Description

cursor-nameSpecifies an identifier for a cursor that was previously declared within aPL/SQL context. The specified cursor cannot already be open.

expressionWhen cursor-name is a parameterized cursor, specifies one or more optionalactual parameters. The number of actual parameters must match the number ofcorresponding formal parameters.

Example

The following example shows an OPEN statement for a cursor that is part of theCURSOR_EXAMPLE procedure:CREATE OR REPLACE PROCEDURE cursor_exampleIS

CURSOR emp_cur_3 IS SELECT empno, ename

188 SQL Procedural Languages: Application Enablement and Support

Page 199: IBM DB2 9.7 for Linux, UNIX, And Windows

FROM empWHERE deptno = 10ORDER BY empno;

BEGINOPEN emp_cur_3;

...END;

Fetching rows from a cursor (PL/SQL)The FETCH statement that is required to fetch rows from a PL/SQL cursor issupported by the DB2 data server in PL/SQL contexts.

Syntax

�� FETCH cursor-name

INTO record,

variablebulk-collect-clause

��

bulk-collect-clause:

,

BULK COLLECT INTO array-variableLIMIT integer-constant

Description

cursor-nameName of a static cursor or cursor variable.

recordIdentifier for a previously-defined record. This can be a user-defined record ora record definition that is derived from a table using the %ROWTYPEattribute.

variableA PL/SQL variable that will hold the field data from the fetched row. One ormore variables can be defined, but they must match in order and number thefields that are returned in the select list of the query that was specified in thecursor declaration. The data types of the fields in the select list must match orbe implicitly convertible to the data types of the fields in the record or the datatypes of the variables.

The variable data types can be defined explicitly or by using the %TYPEattribute.

BULK COLLECT INTO array-variableIdentifies one or more variables with an array data type. Each row of the resultis assigned to an element in each array in the order of the result set, with thearray index assigned in sequence.v If exactly one array-variable is specified:

– If the data type of the array-variable element is not a record type, theresult row of the cursor must have exactly one column, and the columndata type must be assignable to the array element data type.

Chapter 18. Cursors (PL/SQL) 189

Page 200: IBM DB2 9.7 for Linux, UNIX, And Windows

– If the data type of the array-variable element is a record type, the resultrow of the cursor must be assignable to the record type.

v If multiple array variables are specified:– The data type of the array-variable element must not be a record type.– There must be an array-variable for each column in the result row of the

cursor.– The data type of each column in the result row of the cursor must be

assignable to the array element data type of the correspondingarray-variable.

If the data type of array-variable is an ordinary array, the maximum cardinalitymust be greater than or equal to the number of rows that are returned by thequery, or greater than or equal to the integer-constant that is specified in theLIMIT clause.

LIMIT integer-constantIdentifies a limit for the number of rows stored in the target array. The cursorposition is moved forward integer-constant rows or to the end of the result set.

Example

The following example shows a procedure that contains a FETCH statement.CREATE OR REPLACE PROCEDURE cursor_exampleIS

v_empno NUMBER(4);v_ename VARCHAR2(10);CURSOR emp_cur_3 IS SELECT empno, ename FROM emp WHERE deptno = 10

ORDER BY empno;BEGIN

OPEN emp_cur_3;FETCH emp_cur_3 INTO v_empno, v_ename;

...END;

If the %TYPE attribute is used to define the data type of a target variable, thetarget variable declaration in a PL/SQL application program does not need tochange if the data type of the database column changes. The following exampleshows a procedure with variables that are defined using the %TYPE attribute.CREATE OR REPLACE PROCEDURE cursor_exampleIS

v_empno emp.empno%TYPE;v_ename emp.ename%TYPE;CURSOR emp_cur_3 IS SELECT empno, ename FROM emp WHERE deptno = 10

ORDER BY empno;BEGIN

OPEN emp_cur_3;FETCH emp_cur_3 INTO v_empno, v_ename;

...END;

If all of the columns in a table are retrieved in the order in which they are defined,the %ROWTYPE attribute can be used to define a record into which the FETCHstatement will place the retrieved data. Each field within the record can then beaccessed using dot notation. The following example shows a procedure with arecord definition that uses %ROWTYPE. This record is used as the target of theFETCH statement.CREATE OR REPLACE PROCEDURE cursor_exampleIS

v_emp_rec emp%ROWTYPE;

190 SQL Procedural Languages: Application Enablement and Support

Page 201: IBM DB2 9.7 for Linux, UNIX, And Windows

CURSOR emp_cur_1 IS SELECT * FROM emp;BEGIN

OPEN emp_cur_1;FETCH emp_cur_1 INTO v_emp_rec;DBMS_OUTPUT.PUT_LINE('Employee Number: ' || v_emp_rec.empno);DBMS_OUTPUT.PUT_LINE('Employee Name : ' || v_emp_rec.ename);

END;

Closing a cursor (PL/SQL)After all rows have been retrieved from the result set that is associated with acursor, the cursor must be closed. The result set cannot be referenced after thecursor has been closed.

However, the cursor can be reopened and the rows of the new result set can befetched.

Syntax

�� CLOSE cursor-name ��

Description

cursor-nameSpecifies an identifier for an open cursor that was previously declared within aPL/SQL context.

Example

The following example shows a CLOSE statement for a cursor that is part of theCURSOR_EXAMPLE procedure:CREATE OR REPLACE PROCEDURE cursor_exampleIS

v_emp_rec emp%ROWTYPE;CURSOR emp_cur_1 IS SELECT * FROM emp;

BEGINOPEN emp_cur_1;FETCH emp_cur_1 INTO v_emp_rec;DBMS_OUTPUT.PUT_LINE('Employee Number: ' || v_emp_rec.empno);DBMS_OUTPUT.PUT_LINE('Employee Name : ' || v_emp_rec.ename);CLOSE emp_cur_1;

END;

Using %ROWTYPE with cursors (PL/SQL)The %ROWTYPE attribute is used to define a record with fields corresponding toall of the columns that are fetched from a cursor or cursor variable. Each fieldassumes the data type of its corresponding column.

The %ROWTYPE attribute is prefixed by a cursor name or a cursor variable name.The syntax is record cursor%ROWTYPE, where record is an identifier that is assignedto the record, and cursor is an explicitly declared cursor within the current scope.

The following example shows how to use a cursor with the %ROWTYPE attributeto retrieve department information about each employee in the EMP table.CREATE OR REPLACE PROCEDURE emp_infoIS

CURSOR empcur IS SELECT ename, deptno FROM emp;myvar empcur%ROWTYPE;

Chapter 18. Cursors (PL/SQL) 191

Page 202: IBM DB2 9.7 for Linux, UNIX, And Windows

BEGINOPEN empcur;LOOP

FETCH empcur INTO myvar;EXIT WHEN empcur%NOTFOUND;DBMS_OUTPUT.PUT_LINE( myvar.ename || ' works in department '

|| myvar.deptno );END LOOP;CLOSE empcur;

END;

A call to this procedure (CALL emp_info;) returns the following sample output:SMITH works in department 20ALLEN works in department 30WARD works in department 30JONES works in department 20MARTIN works in department 30BLAKE works in department 30CLARK works in department 10SCOTT works in department 20KING works in department 10TURNER works in department 30ADAMS works in department 20JAMES works in department 30FORD works in department 20MILLER works in department 10

Cursor attributes (PL/SQL)Each cursor has a set of attributes that enables an application program to test thestate of the cursor.

These attributes are %ISOPEN, %FOUND, %NOTFOUND, and %ROWCOUNT.

%ISOPENThis attribute is used to determine whether a cursor is in the open state.When a cursor is passed as a parameter to a function or procedure, it isuseful to know (before attempting to open the cursor) whether the cursoris already open.

%FOUNDThis attribute is used to determine whether a cursor contains rows afterthe execution of a FETCH statement. If FETCH statement execution wassuccessful, the %FOUND attribute has a value of true. If FETCH statementexecution was not successful, the %FOUND attribute has a value of false.The result is unknown when:v The value of cursor-variable-name is nullv The underlying cursor of cursor-variable-name is not openv The %FOUND attribute is evaluated before the first FETCH statement

was executed against the underlying cursorv FETCH statement execution returns an error

The %FOUND attribute provides an efficient alternative to using acondition handler that checks for the error that is returned when no morerows remain to be fetched.

%NOTFOUNDThis attribute is the logical opposite of the %FOUND attribute.

%ROWCOUNTThis attribute is used to determine the number of rows that have beenfetched since a cursor was opened.

192 SQL Procedural Languages: Application Enablement and Support

Page 203: IBM DB2 9.7 for Linux, UNIX, And Windows

Table 10 summarizes the attribute values that are associated with certain cursorevents.

Table 10. Summary of cursor attribute values

Cursor attribute %ISOPEN %FOUND %NOTFOUND %ROWCOUNT

Before OPEN False Undefined Undefined “Cursor notopen” exception

After OPEN andbefore 1stFETCH

True Undefined Undefined 0

After 1stsuccessfulFETCH

True True False 1

After nthsuccessfulFETCH (lastrow)

True True False n

After n+1stFETCH (afterlast row)

True False True n

After CLOSE False Undefined Undefined “Cursor notopen” exception

Cursor variables (PL/SQL)A cursor variable is a cursor that contains a pointer to a query result set. The resultset is determined by execution of the OPEN FOR statement using the cursorvariable.

A cursor variable, unlike a static cursor, is not associated with a particular query.The same cursor variable can be opened a number of times with separate OPENFOR statements containing different queries. A new result set is created each timeand made available through the cursor variable.

SYS_REFCURSOR cursor variables (PL/SQL)The DB2 server supports the declaration of cursor variables of theSYS_REFCURSOR built-in data type, which can be associated with any result set.

The SYS_REFCURSOR data type is known as a weakly-typed REF CURSOR type.Strongly-typed cursor variables of the REF CURSOR type require a result setspecification.

Syntax

�� DECLARE cursor-variable-name SYS_REFCURSOR ��

Description

cursor-variable-nameSpecifies an identifier for the cursor variable.

Chapter 18. Cursors (PL/SQL) 193

Page 204: IBM DB2 9.7 for Linux, UNIX, And Windows

SYS_REFCURSORSpecifies that the data type of the cursor variable is the system-definedSYS_REFCURSOR data type.

Example

The following example shows a SYS_REFCURSOR variable declaration:DECLARE emprefcur SYS_REFCURSOR;

User-defined REF CURSOR type variables (PL/SQL)The DB2 server supports the user-defined REF CURSOR data type and cursorvariable declarations.

The user-defined REF CURSOR type can be defined by executing the TYPEdeclaration in a PL/SQL context. After the type has been defined, you can declarea cursor variable of that type.

Syntax

�� TYPE cursor-type-name IS REF CURSORRETURN return-type

��

Description

TYPE cursor-type-nameSpecifies an identifier for the cursor data type.

IS REF CURSORSpecifies that the cursor is of a user-defined REF CURSOR data type.

RETURN return-typeSpecifies the return type that is associated with the cursor. If a return-type isspecified, this REF CURSOR type is strongly typed; otherwise, it is weaklytyped.

Example

The following example shows a cursor variable declaration in the DECLAREsection of an anonymous block:DECLARE

TYPE emp_cur_type IS REF CURSOR RETURN emp%ROWTYPE;my_rec emp_cur_type;

BEGIN...

END

Dynamic queries with cursor variables (PL/SQL)The DB2 data server supports dynamic queries through the OPEN FOR statementin PL/SQL contexts.

194 SQL Procedural Languages: Application Enablement and Support

Page 205: IBM DB2 9.7 for Linux, UNIX, And Windows

Syntax

�� OPEN cursor-variable-name FOR dynamic-string

,

USING bind-arg

��

Description

OPEN cursor-variable-nameSpecifies an identifier for a cursor variable that was previously declared withina PL/SQL context.

FOR dynamic-stringSpecifies a string literal or string variable that contains a SELECT statement(without the terminating semicolon). The statement can contain namedparameters, such as, for example, :param1.

USING bind-argSpecifies one or more bind arguments whose values are substituted forplaceholders in dynamic-string when the cursor opens.

Examples

The following example shows a dynamic query that uses a string literal:CREATE OR REPLACE PROCEDURE dept_queryIS

emp_refcur SYS_REFCURSOR;v_empno emp.empno%TYPE;v_ename emp.ename%TYPE;

BEGINOPEN emp_refcur FOR 'SELECT empno, ename FROM emp WHERE deptno = 30' ||

' AND sal >= 1500';DBMS_OUTPUT.PUT_LINE('EMPNO ENAME');DBMS_OUTPUT.PUT_LINE('----- -------');LOOP

FETCH emp_refcur INTO v_empno, v_ename;EXIT WHEN emp_refcur%NOTFOUND;DBMS_OUTPUT.PUT_LINE(v_empno || ' ' || v_ename);

END LOOP;CLOSE emp_refcur;

END;

The following example output is generated by the DEPT_QUERY procedure:CALL dept_query;

EMPNO ENAME----- -------7499 ALLEN7698 BLAKE7844 TURNER

The query in the previous example can be modified with bind arguments to passthe query parameters:CREATE OR REPLACE PROCEDURE dept_query (

p_deptno emp.deptno%TYPE,p_sal emp.sal%TYPE

)IS

emp_refcur SYS_REFCURSOR;v_empno emp.empno%TYPE;

Chapter 18. Cursors (PL/SQL) 195

Page 206: IBM DB2 9.7 for Linux, UNIX, And Windows

v_ename emp.ename%TYPE;BEGIN

OPEN emp_refcur FOR 'SELECT empno, ename FROM emp WHERE deptno = :dept'|| ' AND sal >= :sal' USING p_deptno, p_sal;

DBMS_OUTPUT.PUT_LINE('EMPNO ENAME');DBMS_OUTPUT.PUT_LINE('----- -------');LOOP

FETCH emp_refcur INTO v_empno, v_ename;EXIT WHEN emp_refcur%NOTFOUND;DBMS_OUTPUT.PUT_LINE(v_empno || ' ' || v_ename);

END LOOP;CLOSE emp_refcur;

END;

The following CALL statement generates the same output that was generated inthe previous example:CALL dept_query(30, 1500);

A string variable to pass the SELECT statement provides the most flexibility:CREATE OR REPLACE PROCEDURE dept_query (

p_deptno emp.deptno%TYPE,p_sal emp.sal%TYPE

)IS

emp_refcur SYS_REFCURSOR;v_empno emp.empno%TYPE;v_ename emp.ename%TYPE;p_query_string VARCHAR2(100);

BEGINp_query_string := 'SELECT empno, ename FROM emp WHERE ' ||

'deptno = :dept AND sal >= :sal';OPEN emp_refcur FOR p_query_string USING p_deptno, p_sal;DBMS_OUTPUT.PUT_LINE('EMPNO ENAME');DBMS_OUTPUT.PUT_LINE('----- -------');LOOP

FETCH emp_refcur INTO v_empno, v_ename;EXIT WHEN emp_refcur%NOTFOUND;DBMS_OUTPUT.PUT_LINE(v_empno || ' ' || v_ename);

END LOOP;CLOSE emp_refcur;

END;

This version of the DEPT_QUERY procedure generates the following exampleoutput:CALL dept_query(20, 1500);

EMPNO ENAME----- -------7566 JONES7788 SCOTT7902 FORD

Example: Returning a REF CURSOR from a procedure(PL/SQL)

This example demonstrates how to define and open a REF CURSOR variable, andthen pass it as a procedure parameter.

The cursor variable is specified as an IN OUT parameter so that the result set ismade available to the caller of the procedure:

196 SQL Procedural Languages: Application Enablement and Support

Page 207: IBM DB2 9.7 for Linux, UNIX, And Windows

CREATE OR REPLACE PROCEDURE emp_by_job (p_job VARCHAR2,p_emp_refcur IN OUT SYS_REFCURSOR

)ISBEGIN

OPEN p_emp_refcur FOR SELECT empno, ename FROM emp WHERE job = p_job;END;

The EMP_BY_JOB procedure is invoked in the following anonymous block byassigning the procedure’s IN OUT parameter to a cursor variable that was declaredin the anonymous block’s declaration section. The result set is fetched using thiscursor variable.DECLARE

v_empno emp.empno%TYPE;v_ename emp.ename%TYPE;v_job emp.job%TYPE := 'SALESMAN';v_emp_refcur SYS_REFCURSOR;

BEGINDBMS_OUTPUT.PUT_LINE('EMPLOYEES WITH JOB ' || v_job);DBMS_OUTPUT.PUT_LINE('EMPNO ENAME');DBMS_OUTPUT.PUT_LINE('----- -------');emp_by_job(v_job, v_emp_refcur);LOOP

FETCH v_emp_refcur INTO v_empno, v_ename;EXIT WHEN v_emp_refcur%NOTFOUND;DBMS_OUTPUT.PUT_LINE(v_empno || ' ' || v_ename);

END LOOP;CLOSE v_emp_refcur;

END;

The following example output is generated when the anonymous block executes:EMPLOYEES WITH JOB SALESMANEMPNO ENAME----- -------7499 ALLEN7521 WARD7654 MARTIN7844 TURNER

Example: Modularizing cursor operations (PL/SQL)This example demonstrates how various operations on cursor variables can bemodularized into separate programs or PL/SQL components.

The following example shows a procedure that opens a cursor variable whosequery retrieves all rows in the EMP table:CREATE OR REPLACE PROCEDURE open_all_emp (

p_emp_refcur IN OUT SYS_REFCURSOR)ISBEGIN

OPEN p_emp_refcur FOR SELECT empno, ename FROM emp;END;

In the next example, a procedure opens a cursor variable whose query retrieves allrows for a given department:CREATE OR REPLACE PROCEDURE open_emp_by_dept (

p_emp_refcur IN OUT SYS_REFCURSOR,p_deptno emp.deptno%TYPE

)IS

Chapter 18. Cursors (PL/SQL) 197

Page 208: IBM DB2 9.7 for Linux, UNIX, And Windows

BEGINOPEN p_emp_refcur FOR SELECT empno, ename FROM emp

WHERE deptno = p_deptno;END;

The following example shows a procedure that opens a cursor variable whosequery retrieves all rows in the DEPT table:CREATE OR REPLACE PROCEDURE open_dept (

p_dept_refcur IN OUT SYS_REFCURSOR)ISBEGIN

OPEN p_dept_refcur FOR SELECT deptno, dname FROM dept;END;

In the next example, a procedure fetches and displays a cursor variable result setconsisting of employee number and name:CREATE OR REPLACE PROCEDURE fetch_emp (

p_emp_refcur IN OUT SYS_REFCURSOR)IS

v_empno emp.empno%TYPE;v_ename emp.ename%TYPE;

BEGINDBMS_OUTPUT.PUT_LINE('EMPNO ENAME');DBMS_OUTPUT.PUT_LINE('----- -------');LOOP

FETCH p_emp_refcur INTO v_empno, v_ename;EXIT WHEN p_emp_refcur%NOTFOUND;DBMS_OUTPUT.PUT_LINE(v_empno || ' ' || v_ename);

END LOOP;END;

The following example shows a procedure that fetches and displays a cursorvariable result set consisting of department number and name:CREATE OR REPLACE PROCEDURE fetch_dept (

p_dept_refcur IN SYS_REFCURSOR)IS

v_deptno dept.deptno%TYPE;v_dname dept.dname%TYPE;

BEGINDBMS_OUTPUT.PUT_LINE('DEPT DNAME');DBMS_OUTPUT.PUT_LINE('---- ---------');LOOP

FETCH p_dept_refcur INTO v_deptno, v_dname;EXIT WHEN p_dept_refcur%NOTFOUND;DBMS_OUTPUT.PUT_LINE(v_deptno || ' ' || v_dname);

END LOOP;END;

The following example shows a procedure that closes a cursor variable:CREATE OR REPLACE PROCEDURE close_refcur (

p_refcur IN OUT SYS_REFCURSOR)ISBEGIN

CLOSE p_refcur;END;

The following example shows an anonymous block that executes these procedures:

198 SQL Procedural Languages: Application Enablement and Support

Page 209: IBM DB2 9.7 for Linux, UNIX, And Windows

DECLAREgen_refcur SYS_REFCURSOR;

BEGINDBMS_OUTPUT.PUT_LINE('ALL EMPLOYEES');open_all_emp(gen_refcur);fetch_emp(gen_refcur);DBMS_OUTPUT.PUT_LINE('****************');

DBMS_OUTPUT.PUT_LINE('EMPLOYEES IN DEPT #10');open_emp_by_dept(gen_refcur, 10);fetch_emp(gen_refcur);DBMS_OUTPUT.PUT_LINE('****************');

DBMS_OUTPUT.PUT_LINE('DEPARTMENTS');open_dept(gen_refcur);fetch_dept(gen_refcur);DBMS_OUTPUT.PUT_LINE('*****************');

close_refcur(gen_refcur);END;

The following example output is generated when the anonymous block executes:ALL EMPLOYEESEMPNO ENAME----- -------7369 SMITH7499 ALLEN7521 WARD7566 JONES7654 MARTIN7698 BLAKE7782 CLARK7788 SCOTT7839 KING7844 TURNER7876 ADAMS7900 JAMES7902 FORD7934 MILLER****************EMPLOYEES IN DEPT #10EMPNO ENAME----- -------7782 CLARK7839 KING7934 MILLER****************DEPARTMENTSDEPT DNAME---- ---------10 ACCOUNTING20 RESEARCH30 SALES40 OPERATIONS*****************

Chapter 18. Cursors (PL/SQL) 199

Page 210: IBM DB2 9.7 for Linux, UNIX, And Windows

200 SQL Procedural Languages: Application Enablement and Support

Page 211: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 19. Triggers (PL/SQL)

A PL/SQL trigger is a named database object that encapsulates and defines a set ofactions that are to be performed in response to an insert, update, or deleteoperation against a table. Triggers are created using the PL/SQL CREATETRIGGER statement.

Types of triggers (PL/SQL)The DB2 data server supports row-level triggers within a PL/SQL context.

A row-level trigger fires once for each row that is affected by a triggering event. Forexample, if deletion is defined as a triggering event for a particular table, and asingle DELETE statement deletes five rows from that table, the trigger will fire fivetimes, once for each row.

The trigger code block is executed either before or after each row is affected by thetriggering statement.

Trigger variables (PL/SQL)NEW and OLD are special variables that you can use with PL/SQL triggerswithout explicitly defining them.v NEW is a pseudo-record name that refers to the new table row for insert and

update operations in row-level triggers. Its usage is :NEW.column, where columnis the name of a column in the table on which the trigger is defined.– When used in a before row-level trigger, the initial content of :NEW.column is

the column value in the new row that is to be inserted or in the row that is toreplace the old row.

– When used in an after row-level trigger, the new column value has alreadybeen stored in the table.

In the trigger code block, :NEW.column can be used like any other variable. If avalue is assigned to :NEW.column in the code block of a before row-level trigger,the assigned value is used in the inserted or updated row.

v OLD is a pseudo-record name that refers to the old table row for update anddelete operations in row-level triggers. Its usage is :OLD.column, where column isthe name of a column in the table on which the trigger is defined.– When used in a before row-level trigger, the initial content of :OLD.column is the

column value in the row that is to be deleted or in the old row that is to bereplaced by the new row.

– When used in an after row-level trigger, the old column value is no longerstored in the table.

In the trigger code block, :OLD.column can be used like any other variable. If avalue is assigned to :OLD.column in the code block of a before row-level trigger,the assigned value has no affect on the action of the trigger.

Transactions and exceptions (PL/SQL)A trigger is always executed as part of the same transaction within which thetriggering statement is executing.

© Copyright IBM Corp. 1993, 2009 201

Page 212: IBM DB2 9.7 for Linux, UNIX, And Windows

If no exceptions occur within the trigger code block, the effects of datamanipulation language (DML) within the trigger are committed only if thetransaction that contains the triggering statement commits. If the transaction isrolled back, the effects of DML within the trigger are also rolled back.

A DB2 rollback can only occur within an atomic block or by using an UNDOhandler. The triggering statement itself is not rolled back unless the applicationforces a rollback of the encapsulating transaction.

If an unhandled exception occurs within the trigger code block, the callingstatement is rolled back.

CREATE TRIGGER statement (PL/SQL)The CREATE TRIGGER statement defines a PL/SQL trigger in the database.

Syntax

�� CREATE TRIGGER trigger-nameOR REPLACE

BEFOREAFTER

INSERTDELETEUPDATE

,

OF column-name

ON table-name �

�(1) AS

REFERENCING OLD correlation-nameAS

NEW correlation-name

FOR EACH ROW �

�WHEN ( search-condition )

�DECLARE declaration

� �BEGIN statement �

� �

� �EXCEPTION WHEN condition THEN handler-statementOR

END ��

Notes:

1 OLD and NEW can only be specified once each.

202 SQL Procedural Languages: Application Enablement and Support

Page 213: IBM DB2 9.7 for Linux, UNIX, And Windows

Description

OR REPLACESpecifies to replace the definition for the trigger if one exists at the currentserver. The existing definition is effectively dropped before the new definitionis replaced in the catalog. This option is ignored if a definition for the triggerdoes not exist at the current server.

trigger-nameNames the trigger. The name, including the implicit or explicit schema name,must not identify a trigger already described in the catalog (SQLSTATE 42710).If a two-part name is specified, the schema name cannot begin with ’SYS’(SQLSTATE 42939).

BEFORESpecifies that the associated triggered action is to be applied before anychanges caused by the actual update of the subject table are applied to thedatabase. It also specifies that the triggered action of the trigger will not causeother triggers to be activated.

AFTERSpecifies that the associated triggered action is to be applied after the changescaused by the actual update of the subject table are applied to the database.

INSERTSpecifies that the triggered action associated with the trigger is to be executedwhenever an INSERT operation is applied to the subject table.

DELETESpecifies that the triggered action associated with the trigger is to be executedwhenever a DELETE operation is applied to the subject table.

UPDATESpecifies that the triggered action associated with the trigger is to be executedwhenever an UPDATE operation is applied to the subject table, subject to thecolumns specified or implied.

If the optional column-name list is not specified, every column of the table isimplied. Therefore, omission of the column-name list implies that the triggerwill be activated by the update of any column of the table.

OF column-name,...Each column-name specified must be a column of the base table (SQLSTATE42703). If the trigger is a BEFORE trigger, the column-name specified cannotbe a generated column other than the identity column (SQLSTATE 42989).No column-name can appear more than once in the column-name list(SQLSTATE 42711). The trigger will only be activated by the update of acolumn that is identified in the column-name list.

ON table-nameDesignates the subject table of the BEFORE trigger or AFTER trigger definition.The name must specify a base table or an alias that resolves to a base table(SQLSTATE 42704 or 42809). The name must not specify a catalog table(SQLSTATE 42832), a materialized query table (SQLSTATE 42997), a createdtemporary table, a declared temporary table (SQLSTATE 42995), or a nickname(SQLSTATE 42809).

REFERENCINGSpecifies the correlation names for the transition variables and the table namesfor the transition tables. Correlation names identify a specific row in the set ofrows affected by the triggering SQL operation. Table names identify the

Chapter 19. Triggers (PL/SQL) 203

Page 214: IBM DB2 9.7 for Linux, UNIX, And Windows

complete set of affected rows. Each row affected by the triggering SQLoperation is available to the triggered action by qualifying columns withcorrelation-names specified as follows.

OLD AS correlation-nameSpecifies a correlation name that identifies the row state prior to thetriggering SQL operation.

NEW AS correlation-nameSpecifies a correlation name that identifies the row state as modified by thetriggering SQL operation and by any SET statement in a BEFORE triggerthat has already executed.

FOR EACH ROWSpecifies that the triggered action is to be applied once for each row of thesubject table that is affected by the triggering SQL operation.

WHEN

(search-condition)Specifies a condition that is true, false, or unknown. The search-conditionprovides a capability to determine whether or not a certain triggered actionshould be executed. The associated action is performed only if thespecified search condition evaluates as true.

declarationSpecifies a variable declaration.

statement or handler-statementSpecifies a PL/SQL program statement. The trigger body can contain nestedblocks.

conditionSpecifies an exception condition name, such as NO_DATA_FOUND.

Example

The following example shows a before row-level trigger that calculates thecommission of every new employee belonging to department 30 before a record forthat employee is inserted into the EMP table:CREATE TABLE emp (

name VARCHAR2(10),deptno NUMBER,sal NUMBER,comm NUMBER

)/

CREATE OR REPLACE TRIGGER emp_comm_trigBEFORE INSERT ON empFOR EACH ROW

BEGINIF :NEW.deptno = 30 THEN

:NEW.comm := :NEW.sal * .4;END IF;

END/

Dropping triggers (PL/SQL)You can remove a trigger from the database by using the DROP TRIGGERstatement.

204 SQL Procedural Languages: Application Enablement and Support

Page 215: IBM DB2 9.7 for Linux, UNIX, And Windows

Syntax

�� DROP TRIGGER trigger-name ��

Description

trigger-nameSpecifies the name of the trigger that is to be dropped.

Examples: Triggers (PL/SQL)PL/SQL trigger definitions can be compiled by the DB2 data server. Theseexamples will help you to create valid triggers and to troubleshoot PL/SQL triggercompilation errors.

Before row-level triggers

The following example shows a before row-level trigger that calculates thecommission of every new employee belonging to department 30 before a record forthat employee is inserted into the EMP table:CREATE OR REPLACE TRIGGER emp_comm_trig

BEFORE INSERT ON empFOR EACH ROW

BEGINIF :NEW.deptno = 30 THEN

:NEW.comm := :NEW.sal * .4;END IF;

END;

The trigger computes the commissions for two new employees and inserts thosevalues as part of the new employee rows:INSERT INTO emp VALUES (9005,'ROBERS','SALESMAN',7782,SYSDATE,3000.00,NULL,30);

INSERT INTO emp VALUES (9006,'ALLEN','SALESMAN',7782,SYSDATE,4500.00,NULL,30);

SELECT * FROM emp WHERE empno IN (9005, 9006);

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO---------- ---------- --------- ---------- --------- ---------- ---------- ----------

9005 ROBERS SALESMAN 7782 01-APR-05 3000 1200 309006 ALLEN SALESMAN 7782 01-APR-05 4500 1800 30

After row-level triggers

The following example shows three after row-level triggers.v When a new employee row is inserted into the EMP table, one trigger

(EMP_INS_TRIG) adds a new row to the JOBHIST table for that employee andadds a row to the EMPCHGLOG table with a description of the action.

v When an existing employee row is updated, the second trigger(EMP_CHG_TRIG) sets the ENDDATE column of the latest JOBHIST row(assumed to be the one with a null ENDDATE) to the current date and inserts anew JOBHIST row with the employee’s new information. This trigger also addsa row to the EMPCHGLOG table with a description of the action

v When an employee row is deleted from the EMP table, the third trigger(EMP_DEL_TRIG) adds a row to the EMPCHGLOG table with a description ofthe action.

Chapter 19. Triggers (PL/SQL) 205

Page 216: IBM DB2 9.7 for Linux, UNIX, And Windows

CREATE TABLE empchglog (chg_date DATE,chg_desc VARCHAR2(30)

);CREATE OR REPLACE TRIGGER emp_ins_trig

AFTER INSERT ON empFOR EACH ROW

DECLAREv_empno emp.empno%TYPE;v_deptno emp.deptno%TYPE;v_dname dept.dname%TYPE;v_action VARCHAR2(7);v_chgdesc jobhist.chgdesc%TYPE;

BEGINv_action := 'Added';v_empno := :NEW.empno;v_deptno := :NEW.deptno;INSERT INTO jobhist VALUES (:NEW.empno, SYSDATE, NULL,

:NEW.job, :NEW.sal, :NEW.comm, :NEW.deptno, 'New Hire');

INSERT INTO empchglog VALUES (SYSDATE,v_action || ' employee # ' || v_empno);

END;

CREATE OR REPLACE TRIGGER emp_chg_trigAFTER UPDATE ON empFOR EACH ROW

DECLAREv_empno emp.empno%TYPE;v_deptno emp.deptno%TYPE;v_dname dept.dname%TYPE;v_action VARCHAR2(7);v_chgdesc jobhist.chgdesc%TYPE;

BEGINv_action := 'Updated';v_empno := :NEW.empno;v_deptno := :NEW.deptno;v_chgdesc := '';IF NVL(:OLD.ename, '-null-') != NVL(:NEW.ename, '-null-') THEN

v_chgdesc := v_chgdesc || 'name, ';END IF;IF NVL(:OLD.job, '-null-') != NVL(:NEW.job, '-null-') THEN

v_chgdesc := v_chgdesc || 'job, ';END IF;IF NVL(:OLD.sal, -1) != NVL(:NEW.sal, -1) THEN

v_chgdesc := v_chgdesc || 'salary, ';END IF;IF NVL(:OLD.comm, -1) != NVL(:NEW.comm, -1) THEN

v_chgdesc := v_chgdesc || 'commission, ';END IF;IF NVL(:OLD.deptno, -1) != NVL(:NEW.deptno, -1) THEN

v_chgdesc := v_chgdesc || 'department, ';END IF;v_chgdesc := 'Changed ' || RTRIM(v_chgdesc, ', ');UPDATE jobhist SET enddate = SYSDATE WHERE empno = :OLD.empno

AND enddate IS NULL;INSERT INTO jobhist VALUES (:NEW.empno, SYSDATE, NULL,

:NEW.job, :NEW.sal, :NEW.comm, :NEW.deptno, v_chgdesc);

INSERT INTO empchglog VALUES (SYSDATE,v_action || ' employee # ' || v_empno);

END;

CREATE OR REPLACE TRIGGER emp_del_trigAFTER DELETE ON empFOR EACH ROW

DECLARE

206 SQL Procedural Languages: Application Enablement and Support

Page 217: IBM DB2 9.7 for Linux, UNIX, And Windows

v_empno emp.empno%TYPE;v_deptno emp.deptno%TYPE;v_dname dept.dname%TYPE;v_action VARCHAR2(7);v_chgdesc jobhist.chgdesc%TYPE;

BEGINv_action := 'Deleted';v_empno := :OLD.empno;v_deptno := :OLD.deptno;

INSERT INTO empchglog VALUES (SYSDATE,v_action || ' employee # ' || v_empno);

END;

In the following example, two employee rows are added using two separateINSERT statements, and then both rows are updated using a single UPDATEstatement. The JOBHIST table shows the action of the trigger for each affected row:two new hire entries for the two new employees and two changed commissionrecords. The EMPCHGLOG table also shows that the trigger was fired a total offour times, once for each action against the two rows.INSERT INTO emp VALUES (9003,'PETERS','ANALYST',7782,SYSDATE,5000.00,NULL,40);

INSERT INTO emp VALUES (9004,'AIKENS','ANALYST',7782,SYSDATE,4500.00,NULL,40);

UPDATE emp SET comm = sal * 1.1 WHERE empno IN (9003, 9004);

SELECT * FROM jobhist WHERE empno IN (9003, 9004);

EMPNO STARTDATE ENDDATE JOB SAL COMM DEPTNO CHGDESC---------- --------- --------- --------- ---------- ---------- ---------- ------------------

9003 31-MAR-05 31-MAR-05 ANALYST 5000 40 New Hire9004 31-MAR-05 31-MAR-05 ANALYST 4500 40 New Hire9003 31-MAR-05 ANALYST 5000 5500 40 Changed commission9004 31-MAR-05 ANALYST 4500 4950 40 Changed commission

SELECT * FROM empchglog;

CHG_DATE CHG_DESC--------- ------------------------------31-MAR-05 Added employee # 900331-MAR-05 Added employee # 900431-MAR-05 Updated employee # 900331-MAR-05 Updated employee # 9004

After both employees are deleted with a single DELETE statement, theEMPCHGLOG table shows that the trigger was fired twice, once for each deletedemployee:DELETE FROM emp WHERE empno IN (9003, 9004);

SELECT * FROM empchglog;

CHG_DATE CHG_DESC--------- ------------------------------31-MAR-05 Added employee # 900331-MAR-05 Added employee # 900431-MAR-05 Updated employee # 900331-MAR-05 Updated employee # 900431-MAR-05 Deleted employee # 900331-MAR-05 Deleted employee # 9004

Chapter 19. Triggers (PL/SQL) 207

Page 218: IBM DB2 9.7 for Linux, UNIX, And Windows

208 SQL Procedural Languages: Application Enablement and Support

Page 219: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 20. Packages (PL/SQL)

PL/SQL package definitions are supported by the DB2 data server. A PL/SQLpackage is a named collection of functions, procedures, variables, cursors,user-defined types, and records that are referenced using a common qualifier, thepackage name.

Packages have the following characteristics:v Packages provide a convenient way of organizing the functions and procedures

that have a related purpose. Permission to use the package functions andprocedures is dependent upon one privilege that is granted to the entirepackage.

v Certain items in a package can be declared public. Public entities are visible andcan be referenced by other programs that hold the EXECUTE privilege on thepackage. In the case of public functions and procedures, only their signatures arevisible. The PL/SQL code for these function and procedures is not accessible toothers; therefore, applications that utilize such a package are dependent upononly the information that is available in the signatures.

v Other items in a package can be declared private. Private entities can bereferenced and used by functions and procedures within the package, but not byexternal applications.

Package components (PL/SQL)Packages consist of two main components: the package specification and thepackage body.v The package specification is the public interface, comprising the elements that can

be referenced outside of the package. A package specification is created byexecuting the CREATE PACKAGE statement.

v The package body contains the actual implementation of all of the procedures andfunctions that are declared within the package specification, as well as anydeclaration of private types, variables, and cursors. A package body is created byexecuting the CREATE PACKAGE BODY statement.

Creating packages (PL/SQL)Creating a package specification enables you to encapsulate related data type,procedure, and function definitions within a single context in the database.

Packages are extensions of schemas that provide namespace support for the objectsthat they reference. They are repositories in which executable code can be defined.Using a package involves referencing or executing objects that are defined in thepackage specification and implemented within the package.

Creating package specifications (PL/SQL)A package specification establishes which package objects can be referenced fromoutside of the package. Objects that can be referenced from outside of a packageare called the public elements of that package.

The following example shows how to create a package specification namedEMP_ADMIN, consisting of two functions and two stored procedures.

© Copyright IBM Corp. 1993, 2009 209

Page 220: IBM DB2 9.7 for Linux, UNIX, And Windows

CREATE OR REPLACE PACKAGE emp_adminIS

FUNCTION get_dept_name (p_deptno NUMBER DEFAULT 10

)RETURN VARCHAR2;FUNCTION update_emp_sal (

p_empno NUMBER,p_raise NUMBER

)RETURN NUMBER;PROCEDURE hire_emp (

p_empno NUMBER,p_ename VARCHAR2,p_job VARCHAR2,p_sal NUMBER,p_hiredate DATE DEFAULT sysdate,p_comm NUMBER DEFAULT 0,p_mgr NUMBER,p_deptno NUMBER DEFAULT 10

);PROCEDURE fire_emp (

p_empno NUMBER);

END emp_admin;

CREATE PACKAGE statement (PL/SQL)The CREATE PACKAGE statement creates a package specification, which definesthe interface to a package.

Syntax

�� CREATE PACKAGE package-nameOR REPLACE

ISAS

,

declaration�

PROCEDURE procedure-name,

( )procedure-parameter

FUNCTION function-name RETURN return-type,

( )function-parameter

� END package-name ��

Description

package-nameSpecifies an identifier for the package.

210 SQL Procedural Languages: Application Enablement and Support

Page 221: IBM DB2 9.7 for Linux, UNIX, And Windows

declarationSpecifies an identifier for a public item. The public item can be accessed fromoutside of the package using the syntax package-name.item-name. There can bezero or more public items. Public item declarations must come beforeprocedure or function declarations. The declaration can be any of the following:v Collection declarationv EXCEPTION declarationv Record declarationv REF CURSOR and cursor variable declarationv TYPE definition for a collection, record, or REF CURSOR type variablev Variable declaration

procedure-nameSpecifies an identifier for a public procedure. The public procedure can beinvoked from outside of the package using the syntax package-name.procedure-name().

procedure-parameterSpecifies an identifier for a formal parameter of the procedure.

function-nameSpecifies an identifier for a public function. The public function can be invokedfrom outside of the package using the syntax package-name.function-name().

function-parameterSpecifies an identifier for a formal parameter of the function. Input (IN mode)parameters can be initialized with a default value.

return-typeSpecifies a data type for the value that is returned by the function.

Creating the package body (PL/SQL)A package body contains the implementation of all of the procedures and functionsthat are declared within the package specification.

The following example shows how to create a package body for the EMP_ADMINpackage specification.---- Package body for the 'emp_admin' package.--CREATE OR REPLACE PACKAGE BODY emp_adminIS

---- Function that queries the 'dept' table based on the department-- number and returns the corresponding department name.--FUNCTION get_dept_name (

p_deptno IN NUMBER DEFAULT 10)RETURN VARCHAR2IS

v_dname VARCHAR2(14);BEGIN

SELECT dname INTO v_dname FROM dept WHERE deptno = p_deptno;RETURN v_dname;

EXCEPTIONWHEN NO_DATA_FOUND THEN

DBMS_OUTPUT.PUT_LINE('Invalid department number ' || p_deptno);RETURN '';

END;

Chapter 20. Packages (PL/SQL) 211

Page 222: IBM DB2 9.7 for Linux, UNIX, And Windows

---- Function that updates an employee's salary based on the-- employee number and salary increment/decrement passed-- as IN parameters. Upon successful completion the function-- returns the new updated salary.--FUNCTION update_emp_sal (

p_empno IN NUMBER,p_raise IN NUMBER

)RETURN NUMBERIS

v_sal NUMBER := 0;BEGIN

SELECT sal INTO v_sal FROM emp WHERE empno = p_empno;v_sal := v_sal + p_raise;UPDATE emp SET sal = v_sal WHERE empno = p_empno;RETURN v_sal;

EXCEPTIONWHEN NO_DATA_FOUND THEN

DBMS_OUTPUT.PUT_LINE('Employee ' || p_empno || ' not found');RETURN -1;

WHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('The following is SQLERRM:');DBMS_OUTPUT.PUT_LINE(SQLERRM);DBMS_OUTPUT.PUT_LINE('The following is SQLCODE:');DBMS_OUTPUT.PUT_LINE(SQLCODE);RETURN -1;

END;---- Procedure that inserts a new employee record into the 'emp' table.--PROCEDURE hire_emp (

p_empno NUMBER,p_ename VARCHAR2,p_job VARCHAR2,p_sal NUMBER,p_hiredate DATE DEFAULT sysdate,p_comm NUMBER DEFAULT 0,p_mgr NUMBER,p_deptno NUMBER DEFAULT 10

)ASBEGIN

INSERT INTO emp(empno, ename, job, sal, hiredate, comm, mgr, deptno)VALUES(p_empno, p_ename, p_job, p_sal,

p_hiredate, p_comm, p_mgr, p_deptno);END;---- Procedure that deletes an employee record from the 'emp' table based-- on the employee number.--PROCEDURE fire_emp (

p_empno NUMBER)ASBEGIN

DELETE FROM emp WHERE empno = p_empno;END;

END;

212 SQL Procedural Languages: Application Enablement and Support

Page 223: IBM DB2 9.7 for Linux, UNIX, And Windows

CREATE PACKAGE BODY statement (PL/SQL)The CREATE PACKAGE BODY statement creates a package body, which containsthe implementation of all of the procedures and functions that are declared withinthe package specification, as well as any declaration of private types, variables, andcursors.

Syntax

�� CREATE PACKAGE BODY package-nameOR REPLACE

ISAS

� �

private-declaration

procedure-specification�

� �

function-specification

�BEGIN initialization-statement

� END ��

procedure-specification:

PROCEDURE procedure-name

,

( parameter )

ISAS

�procedure-declaration

BEGIN statement �

� �EXCEPTION WHEN condition THEN handler-statementOR

END

function-specification:

FUNCTION function-name

,

( parameter )

RETURN return-type �

� ISAS function-declaration

BEGIN statement �

Chapter 20. Packages (PL/SQL) 213

Page 224: IBM DB2 9.7 for Linux, UNIX, And Windows

� �EXCEPTION WHEN condition THEN handler-statementOR

END

Description

package-nameSpecifies the name of the package whose body is to be created. A packagespecification with the same name must exist.

private-declarationSpecifies the name of a private variable that can be accessed by any procedureor function within the package. There can be zero or more private variables.The private-declaration can be any of the following:v Variable declarationv Record declarationv Collection declarationv REF CURSOR and cursor variable declarationv TYPE definitions for records, collections, or variables of the REF CURSOR

type

procedure-nameSpecifies the name of a public procedure that is declared in the packagespecification and its signature. The signature can specify any one of thefollowing: the formal parameter names, data types, parameter modes, the orderof the formal parameters, or the number of formal parameters. When theprocedure name and package specification exactly match the signature of thepublic procedure’s declaration, procedure-name defines the body of this publicprocedure.

If none of these conditions is true, procedure-name defines a new privateprocedure.

parameterSpecifies a formal parameter of the procedure.

procedure-declarationSpecifies a declaration that can be accessed only from within procedureprocedure-name. This is a PL/SQL statement.

statementSpecifies a PL/SQL program statement.

function-nameSpecifies the name of a public function that is declared in the packagespecification and its signature. The signature can specify any one of thefollowing: the formal parameter names, data types, parameter modes, the orderof the formal parameters, or the number of formal parameters. When thefunction name and package specification exactly match the signature of thepublic function’s declaration, function-name defines the body of this publicfunction.

If none of these conditions is true, function-name defines a new privatefunction.

parameterSpecifies a formal parameter of the function.

214 SQL Procedural Languages: Application Enablement and Support

Page 225: IBM DB2 9.7 for Linux, UNIX, And Windows

return-typeSpecifies the data type of the value that is returned by the function.

function-declarationSpecifies a declaration that can be accessed only from within functionfunction-name. This is a PL/SQL statement.

statementSpecifies a PL/SQL program statement.

initialization-statementSpecifies a statement in the initialization section of the package body. Theinitialization section, if specified, must contain at least one statement. Thestatements in the initialization section are executed once per user session whenthe package is first referenced.

Referencing package objects (PL/SQL)References to objects that are defined within a package must sometimes bequalified with the package name.

To reference the objects that are declared in a package specification, specify thepackage name, a period character, and then the name of the object. If the packageis not defined in the current schema, specify the schema name as well. Forexample:package_name.type_namepackage_name.item_namepackage_name.subprogram_nameschema.package_name.subprogram_name

Example

The following example contains a reference to a function namedGET_DEPT_NAME that is defined in a package named EMP_ADMIN:

select emp_admin.get_dept_name(10) from dept

Packages with user-defined types (PL/SQL)User-defined types can be declared and referenced in packages.

The following example shows a package specification for the EMP_RPT package.This definition includes the following declarations:v A publicly accessible record type, EMPREC_TYPv A publicly accessible weakly-typed REF CURSOR type, EMP_REFCURv Two functions, GET_DEPT_NAME and OPEN_EMP_BY_DEPT; the latter

function returns the REF CURSOR type EMP_REFCURv Two procedures, FETCH_EMP and CLOSE_REFCUR; both declare a

weakly-typed REF CURSOR type as a formal parameterCREATE OR REPLACE PACKAGE emp_rptIS

TYPE emprec_typ IS RECORD (empno NUMBER(4),ename VARCHAR(10)

);TYPE emp_refcur IS REF CURSOR;

FUNCTION get_dept_name (p_deptno IN NUMBER

) RETURN VARCHAR2;

Chapter 20. Packages (PL/SQL) 215

Page 226: IBM DB2 9.7 for Linux, UNIX, And Windows

FUNCTION open_emp_by_dept (p_deptno IN emp.deptno%TYPE

) RETURN EMP_REFCUR;PROCEDURE fetch_emp (

p_refcur IN OUT SYS_REFCURSOR);PROCEDURE close_refcur (

p_refcur IN OUT SYS_REFCURSOR);

END emp_rpt;

The definition of the associated package body includes the following privatevariable declarations:v A static cursor, DEPT_CURv An associative array type, DEPTTAB_TYPv An associative array variable, T_DEPTv An integer variable, T_DEPT_MAXv A record variable, R_EMPCREATE OR REPLACE PACKAGE BODY emp_rptIS

CURSOR dept_cur IS SELECT * FROM dept;TYPE depttab_typ IS TABLE of dept%ROWTYPE

INDEX BY BINARY_INTEGER;t_dept DEPTTAB_TYP;t_dept_max INTEGER := 1;r_emp EMPREC_TYP;

FUNCTION get_dept_name (p_deptno IN NUMBER

) RETURN VARCHAR2ISBEGIN

FOR i IN 1..t_dept_max LOOPIF p_deptno = t_dept(i).deptno THEN

RETURN t_dept(i).dname;END IF;

END LOOP;RETURN 'Unknown';

END;

FUNCTION open_emp_by_dept(p_deptno IN emp.deptno%TYPE

) RETURN EMP_REFCURIS

emp_by_dept EMP_REFCUR;BEGIN

OPEN emp_by_dept FOR SELECT empno, ename FROM empWHERE deptno = p_deptno;

RETURN emp_by_dept;END;

PROCEDURE fetch_emp (p_refcur IN OUT SYS_REFCURSOR

)ISBEGIN

DBMS_OUTPUT.PUT_LINE('EMPNO ENAME');DBMS_OUTPUT.PUT_LINE('----- -------');LOOP

FETCH p_refcur INTO r_emp;EXIT WHEN p_refcur%NOTFOUND;DBMS_OUTPUT.PUT_LINE(r_emp.empno || ' ' || r_emp.ename);

END LOOP;END;

216 SQL Procedural Languages: Application Enablement and Support

Page 227: IBM DB2 9.7 for Linux, UNIX, And Windows

PROCEDURE close_refcur (p_refcur IN OUT SYS_REFCURSOR

)ISBEGIN

CLOSE p_refcur;END;

BEGINOPEN dept_cur;LOOP

FETCH dept_cur INTO t_dept(t_dept_max);EXIT WHEN dept_cur%NOTFOUND;t_dept_max := t_dept_max + 1;

END LOOP;CLOSE dept_cur;t_dept_max := t_dept_max - 1;

END emp_rpt;

This package contains an initialization section that loads the private associativearray variable T_DEPT, using the private static cursor DEPT_CUR. T_DEPT servesas a department name lookup table in function GET_DEPT_NAME. The functionOPEN_EMP_BY_DEPT returns a REF CURSOR variable for the result set ofemployee numbers and names for a given department. This REF CURSOR variablecan then be passed to procedure FETCH_EMP to retrieve and list the individualrows of the result set. Finally, procedure CLOSE_REFCUR can be used to close theREF CURSOR variable that is associated with this result set.

The following anonymous block runs the package functions and procedures. Thedeclaration section includes the declaration of cursor variable V_EMP_CUR, usingthe public REF CURSOR type, EMP_REFCUR. V_EMP_CUR contains a pointer tothe result set that is passed between the package function and procedures.DECLARE

v_deptno dept.deptno%TYPE DEFAULT 30;v_emp_cur emp_rpt.EMP_REFCUR;

BEGINv_emp_cur := emp_rpt.open_emp_by_dept(v_deptno);DBMS_OUTPUT.PUT_LINE('EMPLOYEES IN DEPT #' || v_deptno ||

': ' || emp_rpt.get_dept_name(v_deptno));emp_rpt.fetch_emp(v_emp_cur);DBMS_OUTPUT.PUT_LINE('**********************');DBMS_OUTPUT.PUT_LINE(v_emp_cur%ROWCOUNT || ' rows were retrieved');emp_rpt.close_refcur(v_emp_cur);

END;

This anonymous block produces the following sample output:EMPLOYEES IN DEPT #30: SALESEMPNO ENAME----- -------7499 ALLEN7521 WARD7654 MARTIN7698 BLAKE7844 TURNER7900 JAMES**********************6 rows were retrieved

The following anonymous block shows another way of achieving the same result.Instead of using the package procedures FETCH_EMP and CLOSE_REFCUR, thelogic is coded directly into the anonymous block. Note the declaration of recordvariable R_EMP, using the public record type EMPREC_TYP.

Chapter 20. Packages (PL/SQL) 217

Page 228: IBM DB2 9.7 for Linux, UNIX, And Windows

DECLAREv_deptno dept.deptno%TYPE DEFAULT 30;v_emp_cur emp_rpt.EMP_REFCUR;r_emp emp_rpt.EMPREC_TYP;

BEGINv_emp_cur := emp_rpt.open_emp_by_dept(v_deptno);DBMS_OUTPUT.PUT_LINE('EMPLOYEES IN DEPT #' || v_deptno ||

': ' || emp_rpt.get_dept_name(v_deptno));DBMS_OUTPUT.PUT_LINE('EMPNO ENAME');DBMS_OUTPUT.PUT_LINE('----- -------');LOOP

FETCH v_emp_cur INTO r_emp;EXIT WHEN v_emp_cur%NOTFOUND;DBMS_OUTPUT.PUT_LINE(r_emp.empno || ' ' ||

r_emp.ename);END LOOP;DBMS_OUTPUT.PUT_LINE('**********************');DBMS_OUTPUT.PUT_LINE(v_emp_cur%ROWCOUNT || ' rows were retrieved');CLOSE v_emp_cur;

END;

This anonymous block produces the following sample output:EMPLOYEES IN DEPT #30: SALESEMPNO ENAME----- -------7499 ALLEN7521 WARD7654 MARTIN7698 BLAKE7844 TURNER7900 JAMES**********************6 rows were retrieved

Dropping packages (PL/SQL)You can drop a package if it is no longer needed. Alternatively, if you want toreuse the package, you have the option to drop only the package body.

Syntax

�� DROP PACKAGE package-nameBODY

��

Description

BODYSpecifies that only the package body is to be dropped. If this keyword isomitted, both the package specification and the package body are dropped.

package-nameSpecifies the name of a package.

Examples

The following example shows how to drop only the body of a package namedEMP_ADMIN:DROP PACKAGE BODY emp_admin

218 SQL Procedural Languages: Application Enablement and Support

Page 229: IBM DB2 9.7 for Linux, UNIX, And Windows

The following example shows how to drop both the specification and the body ofthe package:DROP PACKAGE emp_admin

Chapter 20. Packages (PL/SQL) 219

Page 230: IBM DB2 9.7 for Linux, UNIX, And Windows

220 SQL Procedural Languages: Application Enablement and Support

Page 231: IBM DB2 9.7 for Linux, UNIX, And Windows

Part 3. System-defined modules

The system-defined modules provide an easy-to-use programmatic interface forperforming a variety of useful operations.

For example, you can use system-defined modules to perform the followingfunctions:v Send and receive messages and alerts across connections.v Write to and read from files and directories on the operating system’s file

system.v Generate reports containing a variety of monitor information.

System-defined modules can be invoked from an SQL-based application, a DB2command line, or a command script.

System-defined modules are not supported for the following product editions:v DB2 Express™

v DB2 Express-Cv DB2 Personal Edition

© Copyright IBM Corp. 1993, 2009 221

Page 232: IBM DB2 9.7 for Linux, UNIX, And Windows

222 SQL Procedural Languages: Application Enablement and Support

Page 233: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 21. DBMS_ALERT module

The DBMS_ALERT module provides a set of procedures for registering for alerts,sending alerts, and receiving alerts.

Alerts are stored in SYSTOOLS.DBMS_ALERT_INFO, which is created in theSYSTOOLSPACE when you first reference this module for each database.

The schema for this module is SYSIBMADM.

The DBMS_ALERT module includes the following system-defined routines.

Table 11. System-defined routines available in the DBMS_ALERT module

Routine name Description

REGISTER procedure Registers the current session to receive aspecified alert.

REMOVE procedure Removes registration for a specified alert.

REMOVEALL procedure Removes registration for all alerts.

SIGNAL procedure Signals the occurrence of a specified alert.

SET_DEFAULTS procedure Sets the polling interval for the WAITONEand WAITANY procedures.

WAITANY procedure Waits for any registered alert to occur.

WAITONE procedure Waits for a specified alert to occur.

Usage notes

The procedures in the DBMS_ALERT module are useful when you want to send analert for a specific event. For example, you might want to send an alert when atrigger is activated as the result of changes to one or more tables.

The DBMS_ALERT module requires that the database configuration parameterCUR_COMMIT is set to ON

Example

When a trigger, TRIG1, is activated, send an alert from connection 1 to connection2 . First, create the table and the trigger.CREATE TABLE T1 (C1 INT)@

CREATE TRIGGER TRIG1AFTER INSERT ON T1REFERENCING NEW AS NEWFOR EACH ROWBEGIN ATOMICCALL DBMS_ALERT.SIGNAL( 'trig1', NEW.C1 );END@

From connection 1, issue an INSERT statement.INSERT INTO T1 values (10)@-- Commit to send messages to the listeners (required in early program)CALL DBMS_ALERT.COMMIT()@

© Copyright IBM Corp. 1993, 2009 223

Page 234: IBM DB2 9.7 for Linux, UNIX, And Windows

From connection 2, register to receive the alert called trig1 and wait for the alert.CALL DBMS_ALERT.REGISTER('trig1')@CALL DBMS_ALERT.WAITONE('trig1', ?, ?, 5)@

This example results in the following output:Value of output parameters--------------------------Parameter Name : MESSAGEParameter Value : -

Parameter Name : STATUSParameter Value : 1

Return Status = 0

REGISTER procedure - Register to receive a specified alertThe REGISTER procedure registers the current session to receive a specified alert.

Syntax

�� DBMS_ALERT.REGISTER ( name ) ��

Procedure parameters

nameAn input argument of type VARCHAR(128) that specifies the name of the alert.

Authorization

EXECUTE privilege on the DBMS_ALERT module.

Example

Use the REGISTER procedure to register for an alert named alert_test, and thenwait for the signal.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE v_name VARCHAR(30) DEFAULT 'alert_test';DECLARE v_msg VARCHAR(80);DECLARE v_status INTEGER;DECLARE v_timeout INTEGER DEFAULT 5;CALL DBMS_ALERT.REGISTER(v_name);CALL DBMS_OUTPUT.PUT_LINE('Waiting for signal...');CALL DBMS_ALERT.WAITONE(v_name , v_msg , v_status , v_timeout);CALL DBMS_OUTPUT.PUT_LINE('Alert name : ' || v_name);CALL DBMS_OUTPUT.PUT_LINE('Alert status : ' || v_status);CALL DBMS_ALERT.REMOVE(v_name);

END@

CALL proc1@

This example results in the following output:Waiting for signal...Alert name : alert_testAlert status : 1

224 SQL Procedural Languages: Application Enablement and Support

Page 235: IBM DB2 9.7 for Linux, UNIX, And Windows

REMOVE procedure - Remove registration for a specified alertThe REMOVE procedure removes registration from the current session for aspecified alert.

Syntax

�� DBMS_ALERT.REMOVE ( name ) ��

Procedure parameters

nameAn input argument of type VARCHAR(128) that specifies the name of the alert.

Authorization

EXECUTE privilege on the DBMS_ALERT module.

Example

Use the REMOVE procedure to remove an alert named alert_test.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE v_name VARCHAR(30) DEFAULT 'alert_test';DECLARE v_msg VARCHAR(80);DECLARE v_status INTEGER;DECLARE v_timeout INTEGER DEFAULT 5;CALL DBMS_ALERT.REGISTER(v_name);CALL DBMS_OUTPUT.PUT_LINE('Waiting for signal...');CALL DBMS_ALERT.WAITONE(v_name , v_msg , v_status , v_timeout);CALL DBMS_OUTPUT.PUT_LINE('Alert name : ' || v_name);CALL DBMS_OUTPUT.PUT_LINE('Alert status : ' || v_status);CALL DBMS_ALERT.REMOVE(v_name);

END@

CALL proc1@

This example results in the following output:Waiting for signal...Alert name : alert_testAlert status : 1

REMOVEALL procedure - Remove registration for all alertsThe REMOVEALL procedure removes registration from the current session for allalerts.

Syntax

�� DBMS_ALERT.REMOVEALL ��

Authorization

EXECUTE privilege on the DBMS_ALERT module.

Chapter 21. DBMS_ALERT module 225

Page 236: IBM DB2 9.7 for Linux, UNIX, And Windows

Example

Use the REMOVEALL procedure to remove registration for all alerts.CALL DBMS_ALERT.REMOVEALL@

SET_DEFAULTS - Set the polling interval for WAITONE and WAITANYThe SET_DEFAULTS procedure sets the polling interval that is used by theWAITONE and WAITANY procedures.

Syntax

�� DBMS_ALERT.SET_DEFAULTS ( sensitivity ) ��

Procedure parameters

sensitivityAn input argument of type INTEGER that specifies an interval in seconds forthe WAITONE and WAITANY procedures to check for signals. If a value is notspecified, then the interval is 1 second by default.

Authorization

EXECUTE privilege on the DBMS_ALERT module.

Example

Use the SET_DEFAULTS procedure to specify the polling interval for theWAITONE and WAITANY procedures.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE v_name VARCHAR(30) DEFAULT 'alert_test';DECLARE v_msg VARCHAR(80);DECLARE v_status INTEGER;DECLARE v_timeout INTEGER DEFAULT 20;DECLARE v_polling INTEGER DEFAULT 3;CALL DBMS_ALERT.REGISTER(v_name);CALL DBMS_OUTPUT.PUT_LINE('Waiting for signal...');CALL DBMS_ALERT.SET_DEFAULTS(v_polling);CALL DBMS_OUTPUT.PUT_LINE('Polling interval: ' || v_polling);CALL DBMS_ALERT.WAITONE(v_name , v_msg , v_status , v_timeout);CALL DBMS_ALERT.REMOVE(v_name);

END@

CALL proc1@

This example results in the following output:Polling interval : 3

SIGNAL procedure - Signal occurrence of a specified alertThe SIGNAL procedure signals the occurrence of a specified alert. The signalincludes a message that is passed with the alert. The message is distributed to thelisteners (processes that have registered for the alert) when the SIGNAL call isissued.

226 SQL Procedural Languages: Application Enablement and Support

Page 237: IBM DB2 9.7 for Linux, UNIX, And Windows

Syntax

�� DBMS_ALERT.SIGNAL ( name , message ) ��

Procedure parameters

nameAn input argument of type VARCHAR(128) that specifies the name of the alert.

messageAn input argument of type VARCHAR(32672) that specifies the information topass with this alert. This message can be returned by the WAITANY orWAITONE procedures when an alert occurs.

Authorization

EXECUTE privilege on the DBMS_ALERT module.

Example

Use the SIGNAL procedure to signal the occurrence of an alert named alert_test.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE v_name VARCHAR(30) DEFAULT 'alert_test';CALL DBMS_ALERT.SIGNAL(v_name,'This is the message from ' || v_name);CALL DBMS_OUTPUT.PUT_LINE('Issued alert for ' || v_name);

END@

CALL proc1@

This example results in the following output:Issued alert for alert_test

WAITANY procedure - Wait for any registered alertsThe WAITANY procedure waits for any registered alerts to occur.

Syntax

�� DBMS_ALERT.WAITANY ( name , message , status , timeout ) ��

Procedure parameters

nameAn output argument of type VARCHAR(128) that contains the name of thealert.

messageAn output argument of type VARCHAR(32672) that contains the message sentby the SIGNAL procedure.

statusAn output argument of type INTEGER that contains the status code returnedby the procedure. The following values are possible

0 An alert occurred.

Chapter 21. DBMS_ALERT module 227

Page 238: IBM DB2 9.7 for Linux, UNIX, And Windows

1 A timeout occurred.

timeoutAn input argument of type INTEGER that specifies the amount of time inseconds to wait for an alert.

Authorization

EXECUTE privilege on the DBMS_ALERT module.

Example

From one connection, run a CLP script called waitany.clp to receive any registeredalerts.waitany.clp:

SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE v_name VARCHAR(30);DECLARE v_msg VARCHAR(80);DECLARE v_status INTEGER;DECLARE v_timeout INTEGER DEFAULT 20;CALL DBMS_ALERT.REGISTER('alert_test');CALL DBMS_ALERT.REGISTER('any_alert');CALL DBMS_OUTPUT.PUT_LINE('Registered for alert alert_test and any_alert');CALL DBMS_OUTPUT.PUT_LINE('Waiting for signal...');CALL DBMS_ALERT.WAITANY(v_name , v_msg , v_status , v_timeout);CALL DBMS_OUTPUT.PUT_LINE('Alert name : ' || v_name);CALL DBMS_OUTPUT.PUT_LINE('Alert msg : ' || v_msg);CALL DBMS_OUTPUT.PUT_LINE('Alert status : ' || v_status);CALL DBMS_OUTPUT.PUT_LINE('Alert timeout: ' || v_timeout || ' seconds');CALL DBMS_ALERT.REMOVEALL;

END@

call proc1@

From another connection, run a script called signal.clp to issue a signal for analert named any_alert.signal.clp:

SET SERVEROUTPUT ON@

CREATE PROCEDURE proc2BEGINDECLARE v_name VARCHAR(30) DEFAULT 'any_alert';CALL DBMS_ALERT.SIGNAL(v_name,'This is the message from ' || v_name);CALL DBMS_OUTPUT.PUT_LINE('Issued alert for ' || v_name);

END@

CALL proc2@

The script signal.clp results in the following output:Issued alert for any_alert

The script waitany.clp results in the following output:

228 SQL Procedural Languages: Application Enablement and Support

Page 239: IBM DB2 9.7 for Linux, UNIX, And Windows

Registered for alert alert_test and any_alertWaiting for signal...Alert name : any_alertAlert msg : This is the message from any_alertAlert status : 0Alert timeout: 20 seconds

Usage notes

If no alerts are registered when the WAITANY procedure is called, the procedurereturns SQL0443N.

WAITONE procedure - Wait for a specified alertThe WAITONE procedure waits for a specified alert to occur.

Syntax

�� DBMS_ALERT.WAITONE ( name , message , status , timeout ) ��

Procedure parameters

nameAn input argument of type VARCHAR(128) that specifies the name of the alert.

messageAn output argument of type VARCHAR(32672) that contains the message sentby the SIGNAL procedure.

statusAn output argument of type INTEGER that contains the status code returnedby the procedure. The following values are possible

0 An alert occurred.

1 A timeout occurred.

timeoutAn input argument of type INTEGER that specifies the amount of time inseconds to wait for the specified alert.

Authorization

EXECUTE privilege on the DBMS_ALERT module.

Example

Run a CLP script named waitone.clp to receive an alert named alert_test.waitone.clp:

SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE v_name VARCHAR(30) DEFAULT 'alert_test';DECLARE v_msg VARCHAR(80);DECLARE v_status INTEGER;DECLARE v_timeout INTEGER DEFAULT 20;CALL DBMS_ALERT.REGISTER(v_name);CALL DBMS_OUTPUT.PUT_LINE('Waiting for signal...');CALL DBMS_ALERT.WAITONE(v_name , v_msg , v_status , v_timeout);

Chapter 21. DBMS_ALERT module 229

Page 240: IBM DB2 9.7 for Linux, UNIX, And Windows

CALL DBMS_OUTPUT.PUT_LINE('Alert name : ' || v_name);CALL DBMS_OUTPUT.PUT_LINE('Alert msg : ' || v_msg);CALL DBMS_OUTPUT.PUT_LINE('Alert status : ' || v_status);CALL DBMS_OUTPUT.PUT_LINE('Alert timeout: ' || v_timeout || ' seconds');CALL DBMS_ALERT.REMOVE(v_name);

END@

CALL proc1@

From a different connection, run a script named signalalert.clp to issue a signalfor an alert named alert_test.signalalert.clp:

SET SERVEROUTPUT ON@

CREATE PROCEDURE proc2BEGIN

DECLARE v_name VARCHAR(30) DEFAULT 'alert_test';CALL DBMS_ALERT.SIGNAL(v_name,'This is the message from ' || v_name);CALL DBMS_OUTPUT.PUT_LINE('Issued alert for ' || v_name);

END@

CALL proc2@

The script signalalert.clp results in the following output:Issued alert for alert_test

The script waitone.clp results in the following output:Waiting for signal...Alert name : alert_testAlert msg : This is the message from alert_testAlert status : 0Alert timeout: 20 seconds

230 SQL Procedural Languages: Application Enablement and Support

Page 241: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 22. DBMS_JOB module

The DBMS_JOB module provides procedures for the creation, scheduling, andmanaging of jobs.

The DBMS_JOB module provides an alternate interface for the Administrative TaskScheduler (ATS). A job is created by adding a task to the ATS. The actual taskname is constructed by concatenating the DBMS_JOB.TASK_NAME_PREFIX procedurename with the assigned job identifier, such as SAMPLE_JOB_TASK_1 where 1 is thejob identifier.

A job runs a stored procedure which has been previously stored in the database.The SUBMIT procedure is used to create and store a job definition. A job identifieris assigned to every job, along with its associated stored procedure and theattributes describing when and how often the job is run.

On first run of the SUBMIT procedure in a database, the SYSTOOLSPACE tablespace is created if necessary.

To enable job scheduling for the DBMS_JOB routines, run:db2set DB2_ATS_ENABLE=1

When and how often a job runs depends upon two interacting parameters –next_date and interval. The next_date parameter is a datetime value that specifiesthe next date and time when the job is to be executed. The interval parameter is astring that contains a date function that evaluates to a datetime value. Just prior toany execution of the job, the expression in the interval parameter is evaluated, andthe resulting value replaces the next_date value stored with the job. The job is thenexecuted. In this manner, the expression in interval is re-evaluated prior to eachjob execution, supplying the next_date date and time for the next execution.

The first run of a scheduled job, as specified by the next_date parameter, should beset at least 5 minutes after the current time, and the interval between running eachjob should also be at least 5 minutes.

The schema for this module is SYSIBMADM.

The DBMS_JOB module includes the following system-defined routines.

Table 12. System-defined routines available in the DBMS_JOB module

Routine name Description

BROKEN procedure Specify that a given job is either broken ornot broken.

CHANGE procedure Change the parameters of the job.

INTERVAL procedure Set the execution frequency by means of adate function that is recalculated each timethe job runs. This value becomes the nextdate and time for execution.

NEXT_DATE procedure Set the next date and time when the job is tobe run.

REMOVE procedure Delete the job definition from the database.

© Copyright IBM Corp. 1993, 2009 231

Page 242: IBM DB2 9.7 for Linux, UNIX, And Windows

Table 12. System-defined routines available in the DBMS_JOB module (continued)

Routine name Description

RUN procedure Force execution of a job even if it is markedas broken.

SUBMIT procedure Create a job and store the job definition inthe database.

WHAT procedure Change the stored procedure run by a job.

Table 13. System-defined constants available in the DBMS_JOB module

Constant name Description

ANY_INSTANCE The only supported value for the instanceargument for the DBMS_JOB routines.

TASK_NAME_PREFIX This constant contains the string that is usedas the prefix for constructing the task namefor the administrative task scheduler.

Usage notes

When the first job is submitted through the DBMS_JOB module for each database,the Administrative Task Scheduler setup is performed:1. Create the SYSTOOLSPACE table space if it does not exist;2. Create the ATS table and views, such as SYSTOOLS.ADMIN_TASK_LIST.

To list the scheduled jobs, run:db2 SELECT * FROM systools.admin_task_list

WHERE name LIKE DBMS_JOB.TASK_NAME_PREFIX || '_%'

To view the status of the job execution, run:db2 SELECT * FROM systools.admin_task_status

WHERE name LIKE DBMS_JOB.TASK_NAME_PREFIX || '_%'

Examples

Example 1: The DBMS_JOB module examples use the following stored procedure,job_proc. This stored procedure simply inserts a timestamp into the jobrun tablewhich contains a single VARCHAR2 column.CREATE TABLE jobrun (

runtime VARCHAR2(40));

CREATE OR REPLACE PROCEDURE job_procISBEGIN

INSERT INTO jobrun VALUES ('job_proc run at ' || TO_CHAR(SYSDATE,'yyyy-mm-dd hh24:mi:ss'));

END;/

BROKEN procedure - Set the state of a job to either broken or notbroken

The BROKEN procedure sets the state of a job to either broken or not broken.

A broken job cannot be executed except by using the RUN procedure.

232 SQL Procedural Languages: Application Enablement and Support

Page 243: IBM DB2 9.7 for Linux, UNIX, And Windows

Syntax

�� BROKEN ( job , broken [ , next_date ] ) ��

Parameters

job An input argument of type DECIMAL(20) that specifies the identifier of the jobto be set as broken or not broken.

brokenAn input argument of type BOOLEAN that specifies the job status. If set to″true″, the job state is set to broken. If set to ″false″, the job state is set to notbroken. Broken jobs cannot be run except through the RUN procedure.

next_dateAn optional input argument of type DATE that specifies the date and timewhen the job runs. The default is SYSDATE.

Authorization

EXECUTE privilege on the DBMS_JOB module.

Examples

Example 1: Set the state of a job with job identifier 104 to broken:BEGIN

DBMS_JOB.BROKEN(104,true);END;

Example 2: Change the state back to not broken:BEGIN

DBMS_JOB.BROKEN(104,false);END;

CHANGE procedure - Modify job attributesThe CHANGE procedure modifies certain job attributes, including the executableSQL statement, the next date and time the job is run, and how often it is run.

Syntax

�� CHANGE ( job , what , next_date , interval ) ��

Parameters

job An input argument of type DECIMAL(20) that specifies the identifier of the jobwith the attributes to modify.

whatAn input argument of type VARCHAR(1024) that specifies the executable SQLstatement. Set this argument to NULL if the existing value is to remainunchanged.

next_dateAn input argument of type TIMESTAMP(0) that specifies the next date andtime when the job is to run. Set this argument to NULL if the existing value isto remain unchanged.

Chapter 22. DBMS_JOB module 233

Page 244: IBM DB2 9.7 for Linux, UNIX, And Windows

intervalAn input argument of type VARCHAR(1024) that specifies the date functionthat, when evaluated, provides the next date and time the job is to run. Set thisargument to NULL if the existing value is to remain unchanged.

Authorization

EXECUTE privilege on the DBMS_JOB module.

Examples

Example 1: Change the job to run next on December 13, 2009. Leave otherparameters unchanged.BEGIN

DBMS_JOB.CHANGE(104,NULL,TO_DATE('13-DEC-09','DD-MON-YY'),NULL);END;

INTERVAL procedure - Set run frequencyThe INTERVAL procedure sets the frequency of how often a job is run.

Syntax

�� INTERVAL ( job , interval ) ��

Parameters

job An input argument of type DECIMAL(20) that specifies the identifier of the jobwhose frequency is being changed.

intervalAn input argument of type VARCHAR(1024) that specifies the date functionthat, when evaluated, provides the next date and time the job is to run.

Authorization

EXECUTE privilege on the DBMS_JOB module.

Examples

Example 1: Change the job to run once a week:BEGIN

DBMS_JOB.INTERVAL(104,'SYSDATE + 7');END;

NEXT_DATE procedure - Set the date and time when a job is runThe NEXT_DATE procedure sets the next date and time of when the job is to run.

Syntax

�� NEXT_DATE ( job , next_date ) ��

234 SQL Procedural Languages: Application Enablement and Support

Page 245: IBM DB2 9.7 for Linux, UNIX, And Windows

Parameters

job An input argument of type DECIMAL(20) that specifies the identifier of the jobwhose next run date is to be modified.

next_dateAn input argument of type TIMESTAMP(0) that specifies the date and timewhen the job is to be run next.

Authorization

EXECUTE privilege on the DBMS_JOB module.

Examples

Example 1: Change the job to run next on December 14, 2009:BEGIN

DBMS_JOB.NEXT_DATE(104, TO_DATE('14-DEC-09','DD-MON-YY'));END;

REMOVE procedure - Delete the job definition from the databaseThe REMOVE procedure deletes the specified job from the database.

In order to have it executed again in the future, the job must be resubmitted usingthe SUBMIT procedure.

Note: The stored procedure associated with the job is not deleted when the job isremoved.

Syntax

�� REMOVE ( job ) ��

Parameters

job An input argument of type DECIMAL(20) that specifies the identifier of the jobto be removed from the database.

Authorization

EXECUTE privilege on the DBMS_JOB module.

Examples

Example 1: Remove a job from the database:BEGIN

DBMS_JOB.REMOVE(104);END;

RUN procedure - Force a broken job to runThe RUN procedure forces a job to run, even if it has a broken state.

Chapter 22. DBMS_JOB module 235

Page 246: IBM DB2 9.7 for Linux, UNIX, And Windows

Syntax

�� RUN ( job ) ��

Parameters

job An input argument of type DECIMAL(20) that specifies the identifier of the jobto run.

Authorization

EXECUTE privilege on the DBMS_JOB module.

Examples

Example 1: Force a job to run.BEGIN

DBMS_JOB.RUN(104);END;

SUBMIT procedure - Create a job definition and store it in the databaseThe SUBMIT procedure creates a job definition and stores it in the database.

A job consists of a job identifier, the stored procedure to be executed, when the jobis first executed, and a date function that calculates the next date and time for thejob to be run.

Syntax

�� SUBMIT ( job , what [ , next_date �

� [ , interval [ , no_parse ] ] ] ) ��

Parameters

job An output argument of type DECIMAL(20) that specifies the identifierassigned to the job.

whatAn input argument of type VARCHAR(1024) that specifies the name of thedynamically executable SQL statement.

next_dateAn optional input argument of type TIMESTAMP(0) that specifies the nextdate and time when the job is to be run. The default is SYSDATE.

intervalAn optional input argument of type VARCHAR(1024) that specifies a datefunction that, when evaluated, provides the next date and time when the job isto run. If interval is set to NULL, then the job is run only once. NULL is thedefault.

no_parseAn optional input argument of type BOOLEAN. If set to ″true″, do notsyntax-check the SQL statement at job creation; instead, perform syntax

236 SQL Procedural Languages: Application Enablement and Support

Page 247: IBM DB2 9.7 for Linux, UNIX, And Windows

checking only when the job first executes. If set to ″false″, syntax check theSQL statement at job creation. The default is ″false″.

Authorization

EXECUTE privilege on the DBMS_JOB module.

Examples

Example 1: The following example creates a job using the stored procedure,job_proc. The job will execute immediately and run once a day thereafter as set bythe interval argument, SYSDATE + 1.DECLARE

jobid INTEGER;BEGIN

DBMS_JOB.SUBMIT(jobid,'job_proc;',SYSDATE,'SYSDATE + 1');

DBMS_OUTPUT.PUT_LINE('jobid: ' || jobid);END;

jobid: 104

The job immediately executes the procedure job_proc, populating the jobrun tablewith a row:SELECT * FROM jobrun;

RUNTIME------------------------------------job_proc run at 2007-12-11 11:43:25

WHAT procedure - Change the SQL statement run by a jobThe WHAT procedure changes the SQL statement run by a specified job.

Syntax

�� WHAT ( job , what ) ��

Parameters

job An input argument of type DECIMAL(20) that specifies the job identifier forwhich the dynamically executable SQL statement is to be changed.

whatAn input argument of type VARCHAR(1024) that specifies the dynamicallyexecuted SQL statement.

Authorization

EXECUTE privilege on the DBMS_JOB module.

Examples

Example 1: Change the job to run the list_emp procedure:BEGIN

DBMS_JOB.WHAT(104,'list_emp;');END;

Chapter 22. DBMS_JOB module 237

Page 248: IBM DB2 9.7 for Linux, UNIX, And Windows

238 SQL Procedural Languages: Application Enablement and Support

Page 249: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 23. DBMS_LOB module

The DBMS_LOB module provides the capability to operate on large objects.

In the following sections describing the individual procedures and functions,lengths and offsets are measured in bytes if the large objects are BLOBs. Lengthsand offsets are measured in characters if the large objects are CLOBs.

The DBMS_LOB module supports LOB data up to 10M bytes.

The schema for this module is SYSIBMADM.

The DBMS_LOB module includes the following routines.

Table 14. System-defined routines available in the DBMS_LOB module

Routine Name Description

APPEND procedure Appends one large object to another.

CLOSE procedure Close an open large object.

COMPARE function Compares two large objects.

CONVERTTOBLOB procedure Converts character data to binary.

CONVERTTOCLOB procedure Converts binary data to character.

COPY procedure Copies one large object to another.

ERASE procedure Erase a large object.

GET_STORAGE_LIMIT function Get the storage limit for large objects.

GETLENGTH function Get the length of the large object.

INSTR function Get the position of the nth occurrence of apattern in the large object starting at offset.

ISOPEN function Check if the large object is open.

OPEN procedure Open a large object.

READ procedure Read a large object.

SUBSTR function Get part of a large object.

TRIM procedure Trim a large object to the specified length.

WRITE procedure Write data to a large object.

WRITEAPPEND procedure Write data from the buffer to the end of alarge object.

The following table lists the public variables available in the module.

Table 15. DBMS_LOB public variables

Public variables Data type Value

lob_readonly INTEGER 0

lob_readwrite INTEGER 1

© Copyright IBM Corp. 1993, 2009 239

Page 250: IBM DB2 9.7 for Linux, UNIX, And Windows

APPEND procedures - Append one large object to anotherThe APPEND procedures provide the capability to append one large object toanother.

Note: Both large objects must be of the same type.

Syntax

�� APPEND_BLOB ( dest_lob , src_lob ) ��

�� APPEND_CLOB ( dest_lob , src_lob ) ��

Parameters

dest_lobAn input or output argument of type BLOB(10M) or CLOB(10M) that specifiesthe large object locator for the destination object. Must be the same data typeas src_lob.

src_lobAn input argument of type BLOB(10M) or CLOB(10M) that specifies the largeobject locator for the source object. Must be the same data type as dest_lob.

Authorization

EXECUTE privilege on the DBMS_LOB module.

CLOSE procedures - Close an open large objectThe CLOSE procedures are a no-op.

Syntax

�� CLOSE_BLOB ( lob_loc ) ��

�� CLOSE_CLOB ( lob_loc ) ��

Parameters

lob_locAn input or output argument of type BLOB(10M) or CLOB(10M) that specifiesthe large object locator of the large object to be closed.

Authorization

EXECUTE privilege on the DBMS_LOB module.

Examples

Example 1:

240 SQL Procedural Languages: Application Enablement and Support

Page 251: IBM DB2 9.7 for Linux, UNIX, And Windows

COMPARE function - Compare two large objectsThe COMPARE function performs an exact byte-by-byte comparison of two largeobjects for a given length at given offsets.

The function returns:v Zero if both large objects are exactly the same for the specified length for the

specified offsetsv Non-zero if the objects are not the samev Null if amount, offset_1, or offset_2 are less than zero.

Note: The large objects being compared must be the same data type.

Syntax

�� COMPARE ( lob_1 , lob_2 [ , amount [ , offset_1 [ , offset_2 ] ] ] ) ��

Parameters

lob_1An input argument of type BLOB(10M) or CLOB(10M) that specifies the largeobject locator of the first large object to be compared. Must be the same datatype as lob_2.

lob_2An input argument of type BLOB(10M) or CLOB(10M) that specifies the largeobject locator of the second large object to be compared. Must be the same datatype as lob_1.

amountAn optional input argument of type INTEGER. If the data type of the largeobjects is BLOB, then the comparison is made for amount bytes. If the data typeof the large objects is CLOB, then the comparison is made for amountcharacters. The default is the maximum size of a large object.

offset_1An optional input argument of type INTEGER that specifies the positionwithin the first large object to begin the comparison. The first byte (orcharacter) is offset 1. The default is 1.

offset_2An optional input argument of type INTEGER that specifies the positionwithin the second large object to begin the comparison. The first byte (orcharacter) is offset 1. The default is 1.

Authorization

EXECUTE privilege on the DBMS_LOB module.

CONVERTTOBLOB procedure - Convert character data to binaryThe CONVERTTOBLOB procedure provides the capability to convert characterdata to binary.

Chapter 23. DBMS_LOB module 241

Page 252: IBM DB2 9.7 for Linux, UNIX, And Windows

Syntax

�� CONVERTTOBLOB ( dest_lob , src_clob , amount , �

� dest_offset , src_offset , blob_csid , lang_context , warning ) ��

Parameters

dest_lobAn input or output argument of type BLOB(10M) that specifies the large objectlocator into which the character data is to be converted.

src_clobAn input argument of type CLOB(10M) that specifies the large object locator ofthe character data to be converted.

amountAn input argument of type INTEGER that specifies the number of characters ofsrc_clob to be converted.

dest_offsetAn input or output argument of type INTEGER that specifies the position (inbytes) in the destination BLOB where writing of the source CLOB shouldbegin. The first byte is offset 1.

src_offsetAn input or output argument of type INTEGER that specifies the position (incharacters) in the source CLOB where conversion to the destination BLOBshould begin. The first character is offset 1.

blob_csidAn input argument of type INTEGER that specifies the character set ID of thedestination BLOB. This value must match the database codepage.

lang_contextAn input argument of type INTEGER that specifies the language context forthe conversion. This value must be 0.

warningAn output argument of type INTEGER that always returns 0.

Authorization

EXECUTE privilege on the DBMS_LOB module.

CONVERTTOCLOB procedure - Convert binary data to characterThe CONVERTTOCLOB procedure provides the capability to convert binary datato character.

Syntax

�� CONVERTTOCLOB ( dest_lob , src_blob , amount , �

� dest_offset , src_offset , blob_csid , lang_context , warning ) ��

242 SQL Procedural Languages: Application Enablement and Support

Page 253: IBM DB2 9.7 for Linux, UNIX, And Windows

Parameters

dest_lobAn input or output argument of type CLOB(10M) that specifies the large objectlocator into which the binary data is to be converted.

src_clobAn input argument of type BLOB(10M) that specifies the large object locator ofthe binary data to be converted.

amountAn input argument of type INTEGER that specifies the number of characters ofsrc_blob to be converted.

dest_offsetAn input or output argument of type INTEGER that specifies the position (incharacters) in the destination CLOB where writing of the source BLOB shouldbegin. The first byte is offset 1.

src_offsetAn input or output argument of type INTEGER that specifies the position (inbytes) in the source BLOB where conversion to the destination CLOB shouldbegin. The first character is offset 1.

blob_csidAn input argument of type INTEGER that specifies the character set ID of thesource BLOB. This value must match the database codepage.

lang_contextAn input argument of type INTEGER that specifies the language context forthe conversion. This value must be 0.

warningAn output argument of type INTEGER that always returns 0.

Authorization

EXECUTE privilege on the DBMS_LOB module.

COPY procedures - Copy one large object to anotherThe COPY procedures provide the capability to copy one large object to another.

Note: The source and destination large objects must be the same data type.

Syntax

�� COPY_BLOB ( dest_lob , src_lob , amount �

� [ , dest_offset [ , src_offset ] ] ) ��

�� COPY_CLOB ( dest_lob , src_lob , amount �

� [ , dest_offset [ , src_offset ] ] ) ��

Chapter 23. DBMS_LOB module 243

Page 254: IBM DB2 9.7 for Linux, UNIX, And Windows

Parameters

dest_lobAn input or output argument of type BLOB(10M) or CLOB(10M) that specifiesthe large object locator of the large object to which src_lob is to be copied. Mustbe the same data type as src_lob.

src_lobAn input argument of type BLOB(10M) or CLOB(10M) that specifies the largeobject locator of the large object from which dest_lob is to be copied. Must bethe same data type as dest_lob.

amountAn input argument of type INTEGER that specifies the number of bytes orcharacters of src_lob to be copied.

dest_offsetAn optional input argument of type INTEGER that specifies the position in thedestination large object where writing of the source large object should begin.The first position is offset 1. The default is 1.

src_offsetAn optional input argument of type INTEGER that specifies the position in thesource large object where copying to the destination large object should begin.The first position is offset 1. The default is 1.

Authorization

EXECUTE privilege on the DBMS_LOB module.

ERASE procedures - Erase a portion of a large objectThe ERASE procedures provide the capability to erase a portion of a large object.

To erase a large object means to replace the specified portion with zero-byte fillersfor BLOBs or with spaces for CLOBs. The actual size of the large object is notaltered.

Syntax

�� ERASE_BLOB ( lob_loc , amount [ , offset ] ) ��

�� ERASE_CLOB ( lob_loc , amount [ , offset ] ) ��

Parameters

lob_locAn input or output argument of type BLOB(10M) or CLOB(10M) that specifiesthe large object locator of the large object to be erased.

amountAn input or output argument of type INTEGER that specifies the number ofbytes or characters to be erased.

offsetAn optional input argument of type INTEGER that specifies the position in thelarge object where erasing is to begin. The first byte or character is at position1. The default is 1.

244 SQL Procedural Languages: Application Enablement and Support

Page 255: IBM DB2 9.7 for Linux, UNIX, And Windows

Authorization

EXECUTE privilege on the DBMS_LOB module.

GET_STORAGE_LIMIT function - Return the limit on the largestallowable large object

The GET_STORAGE_LIMIT function returns the limit on the largest allowablelarge object.

The function returns an INTEGER value that reflects the maximum allowable sizeof a large object in this database.

Syntax

�� GET_STORAGE_LIMIT ( ) ��

Authorization

EXECUTE privilege on the DBMS_LOB module.

GETLENGTH function - Return the length of the large objectThe GETLENGTH function returns the length of a large object.

The function returns an INTEGER value that reflects the length of the large objectin bytes (for a BLOB) or characters (for a CLOB).

Syntax

�� GETLENGTH ( lob_loc ) ��

Parameters

lob_locAn input argument of type BLOB(10M) or CLOB(10M) that specifies the largeobject locator of the large object whose length is to be obtained.

Authorization

EXECUTE privilege on the DBMS_LOB module.

INSTR function - Return the location of the nth occurrence of a givenpattern

The INSTR function returns the location of the nth occurrence of a given patternwithin a large object.

The function returns an INTEGER value of the position within the large objectwhere the pattern appears for the nth time, as specified by nth. This value startsfrom the position given by offset.

Chapter 23. DBMS_LOB module 245

Page 256: IBM DB2 9.7 for Linux, UNIX, And Windows

Syntax

�� INSTR ( lob_loc , pattern [ , offset [ , nth ] ] ) ��

Parameters

lob_locAn input argument of type BLOB or CLOB that specifies the large objectlocator of the large object in which to search for the pattern.

patternAn input argument of type BLOB(32767) or VARCHAR(32672) that specifiesthe pattern of bytes or characters to match against the large object. Note thatpattern must be BLOB if lob_loc is a BLOB; and pattern must be VARCHAR iflob_loc is a CLOB.

offsetAn optional input argument of type INTEGER that specifies the positionwithin lob_loc to start searching for the pattern. The first byte or character is atposition 1. The default value is 1.

nthAn optional argument of type INTEGER that specifies the number of times tosearch for the pattern, starting at the position given by offset. The default valueis 1.

Authorization

EXECUTE privilege on the DBMS_LOB module.

ISOPEN function - Test if the large object is openThe ISOPEN function always returns an INTEGER value of 1..

Syntax

�� ISOPEN ( lob_loc ) ��

Parameters

lob_locAn input argument of type BLOB(10M) or CLOB(10M) that specifies the largeobject locator of the large object to be tested by the function.

Authorization

EXECUTE privilege on the DBMS_LOB module.

OPEN procedures - Open a large objectThe OPEN procedures are a no-op.

Syntax

�� OPEN_BLOB ( lob_loc , open_mode ) ��

246 SQL Procedural Languages: Application Enablement and Support

Page 257: IBM DB2 9.7 for Linux, UNIX, And Windows

�� OPEN_CLOB ( lob_loc , open_mode ) ��

Parameters

lob_locAn input or output argument of type BLOB(10M) or CLOB(10M) that specifiesthe large object locator of the large object to be opened.

open_modeAn input argument of type INTEGER that specifies the mode in which to openthe large object. Set to 0 (lob_readonly) for read-only mode. Set to 1(lob_readwrite) for read-write mode.

Authorization

EXECUTE privilege on the DBMS_LOB module.

READ procedures - Read a portion of a large objectThe READ procedures provide the capability to read a portion of a large objectinto a buffer.

Syntax

�� READ_BLOB ( lob_loc , amount , offset , buffer ) ��

�� READ_CLOB ( lob_loc , amount , offset , buffer ) ��

Parameters

lob_locAn input argument of type BLOB(10M) or CLOB(10M) that specifies the largeobject locator of the large object to be read.

amountAn input or output argument of type INTEGER that specifies the number ofbytes or characters to read.

offsetAn input argument of type INTEGER that specifies the position to beginreading. The first byte or character is at position 1.

bufferAn output argument of type BLOB(32762) or VARCHAR(32672) that specifiesthe variable to receive the large object. If lob_loc is a BLOB, then buffer must beBLOB. If lob_loc is a CLOB, then buffer must be VARCHAR.

Authorization

EXECUTE privilege on the DBMS_LOB module.

SUBSTR function - Return a portion of a large objectThe SUBSTR function provides the capability to return a portion of a large object.

Chapter 23. DBMS_LOB module 247

Page 258: IBM DB2 9.7 for Linux, UNIX, And Windows

The function returns a BLOB(32767) (for a BLOB) or VARCHAR (for a CLOB)value for the returned portion of the large object read by the function.

Syntax

�� SUBSTR ( lob_loc [ , amount [ , offset ] ] ) ��

Parameters

lob_locAn input argument of type BLOB(10M) or CLOB(10M) that specifies the largeobject locator of the large object to be read.

amountAn optional input argument of type INTEGER that specifies the number ofbytes or characters to be returned. The default value is 32,767.

offsetAn optional input argument of type INTEGER that specifies the positionwithin the large object to begin returning data. The first byte or character is atposition 1. The default value is 1.

Authorization

EXECUTE privilege on the DBMS_LOB module.

TRIM procedures - Truncate a large object to the specified lengthThe TRIM procedures provide the capability to truncate a large object to thespecified length.

Syntax

�� TRIM_BLOB ( lob_loc , newlen ) ��

�� TRIM_CLOB ( lob_loc , newlen ) ��

Parameters

lob_locAn input or output argument of type BLOB(10M) or CLOB(10M) that specifiesthe large object locator of the large object to be trimmed.

newlenAn input argument of type INTEGER that specifies the new number of bytesor characters to which the large object is to be trimmed.

Authorization

EXECUTE privilege on the DBMS_LOB module.

WRITE procedures - Write data to a large objectThe WRITE procedures provide the capability to write data into a large object.

248 SQL Procedural Languages: Application Enablement and Support

Page 259: IBM DB2 9.7 for Linux, UNIX, And Windows

Any existing data in the large object at the specified offset for the given length isoverwritten by data given in the buffer.

Syntax

�� WRITE_BLOB ( lob_loc , amount , offset , buffer ) ��

�� WRITE_CLOB ( lob_loc , amount , offset , buffer ) ��

Parameters

lob_locAn input or output argument of type BLOB(10M) or CLOB(10M) that specifiesthe large object locator of the large object to be written.

amountAn input argument of type INTEGER that specifies the number of bytes orcharacters in buffer to be written to the large object.

offsetAn input argument of type INTEGER that specifies the offset in bytes orcharacters from the beginning of the large object for the write operation tobegin. The start value of the large object is 1.

bufferAn input argument of type BLOB(32767) or VARCHAR(32672) that contains thedata to be written to the large object. If lob_loc is a BLOB, then buffer must beBLOB. If lob_loc is a CLOB, then buffer must be VARCHAR.

Authorization

EXECUTE privilege on the DBMS_LOB module.

WRITEAPPEND procedures - Append data to the end of a large objectThe WRITEAPPEND procedures provide the capability to add data to the end of alarge object.

Syntax

�� WRITEAPPEND_BLOB ( lob_loc , amount , buffer ) ��

�� WRITEAPPEND_CLOB ( lob_loc , amount , buffer ) ��

Parameters

lob_locAn input or output argument of type BLOB or CLOB that specifies the largeobject locator of the large object to which data is to appended.

amountAn input argument of type INTEGER that specifies the number of bytes orcharacters from buffer to be appended to the large object.

Chapter 23. DBMS_LOB module 249

Page 260: IBM DB2 9.7 for Linux, UNIX, And Windows

bufferAn input argument of type BLOB(32767) or VARCHAR(32672) that contains thedata to be appended to the large object. If lob_loc is a BLOB, then buffer mustbe BLOB. If lob_loc is a CLOB, then buffer must be VARCHAR.

Authorization

EXECUTE privilege on the DBMS_LOB module.

250 SQL Procedural Languages: Application Enablement and Support

Page 261: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 24. DBMS_OUTPUT module

The DBMS_OUTPUT module provides a set of procedures for putting messages(lines of text) in a message buffer and getting messages from the message buffer.These procedures are useful during application debugging when you need to writemessages to standard output.

The schema for this module is SYSIBMADM.

The DBMS_OUTPUT module includes the following system-defined routines.

Table 16. System-defined routines available in the DBMS_OUTPUT module

Routine name Description

DISABLE procedure Disables the message buffer.

ENABLE procedure Enables the message buffer

GET_LINE procedure Gets a line of text from the message buffer.

GET_LINES procedure Gets one or more lines of text from themessage buffer and places the text into acollection

NEW_LINE procedure Puts an end-of-line character sequence in themessage buffer.

PUT procedure Puts a string that includes no end-of-linecharacter sequence in the message buffer.

PUT_LINE procedure Puts a single line that includes anend-of-line character sequence in themessage buffer.

The procedures in this module allow you to work with the message buffer. Use thecommand line processor (CLP) command SET SERVEROUTPUT ON to redirect theoutput to standard output.

Example

In proc1 use the PUT and PUT_LINE procedures to put a line of text in themessage buffer. When proc1 runs for the first time, SET SERVEROUTPUT ON isspecified, and the line in the message buffer is printed to the CLP window. Whenproc1 runs a second time, SET SERVEROUTPUT OFF is specified, and no linesfrom the message buffer are printed to the CLP window.CREATE PROCEDURE proc1( P1 VARCHAR(10) )BEGIN

CALL DBMS_OUTPUT.PUT( 'P1 = ' );CALL DBMS_OUTPUT.PUT_LINE( P1 );

END@

SET SERVEROUTPUT ON@

CALL proc1( '10' )@

SET SERVEROUTPUT OFF@

CALL proc1( '20' )@

© Copyright IBM Corp. 1993, 2009 251

Page 262: IBM DB2 9.7 for Linux, UNIX, And Windows

The example results in the following output:CALL proc1( '10' )

Return Status = 0

P1 = 10

SET SERVEROUTPUT OFFDB20000I The SET SERVEROUTPUT command completed successfully.

CALL proc1( '20' )

Return Status = 0

DISABLE procedure - Disable the message bufferThe DISABLE procedure disables the message buffer.

After this procedure runs, any messages that are in the message buffer arediscarded. Calls to the PUT, PUT_LINE, or NEW_LINE procedures are ignored,and no error is returned to the sender.

Syntax

�� DBMS_OUTPUT.DISABLE ��

Authorization

EXECUTE privilege on the DBMS_OUTPUT module.

Example

The following example disables the message buffer for the current session:CALL DBMS_OUTPUT.DISABLE@

Usage notes

To send and receive messages after the message buffer has been disabled, use theENABLE procedure.

ENABLE procedure - Enable the message bufferThe ENABLE procedure enables the message buffer. During a single session,applications can put messages in the message buffer and get messages from themessage buffer.

Syntax

�� DBMS_OUTPUT.ENABLE ( buffer_size ) ��

Procedure parameters

buffer_sizeAn input argument of type INTEGER that specifies the maximum length of the

252 SQL Procedural Languages: Application Enablement and Support

Page 263: IBM DB2 9.7 for Linux, UNIX, And Windows

message buffer in bytes. If you specify a value of less than 2000 for buffer_size,the buffer size is set to 2000. If the value is NULL, then the default buffer sizeis 20000.

Authorization

EXECUTE privilege on the DBMS_OUTPUT module.

Example

The following example enables the message buffer:CALL DBMS_OUTPUT.ENABLE( NULL )@

Usage notes

You can call the ENABLE procedure to increase the size of an existing messagebuffer. Any messages in the old buffer are copied to the enlarged buffer.

GET_LINE procedure - Get a line from the message bufferThe GET_LINE procedure gets a line of text from the message buffer. The textmust be terminated by an end-of-line character sequence.

Tip: To add an end-of-line character sequence to the message buffer, use thePUT_LINE procedure, or, after a series of calls to the PUT procedure, use theNEW_LINE procedure.

Syntax

�� DBMS_OUTPUT.GET_LINE ( line , status ) ��

Procedure parameters

lineAn output argument of type VARCHAR(32672) that returns a line of text fromthe message buffer.

statusAn output argument of type INTEGER that indicates whether a line wasreturned from the message buffer:v 0 indicates that a line was returnedv 1 indicates that there was no line to return

Authorization

EXECUTE privilege on the DBMS_OUTPUT module.

Example

Use the GET_LINE procedure to get a line of text from the message buffer. In thisexample, proc1 puts a line of text in the message buffer. proc3 gets the text fromthe message buffer and inserts it into a table named messages. proc2 then runs, butbecause the message buffer is disabled, no text is added to the message buffer.When the select statement runs, it returns only the text added by proc1.

Chapter 24. DBMS_OUTPUT module 253

Page 264: IBM DB2 9.7 for Linux, UNIX, And Windows

CALL DBMS_OUTPUT.ENABLE( NULL )@

CREATE PROCEDURE proc1()BEGIN

CALL DBMS_OUTPUT.PUT_LINE( 'PROC1 put this line in the message buffer.' );END@

CREATE PROCEDURE proc2()BEGIN

CALL DBMS_OUTPUT.PUT_LINE( 'PROC2 put this line in the message buffer.' );END@

CREATE TABLE messages ( msg VARCHAR(100) )@

CREATE PROCEDURE proc3()BEGIN

DECLARE line VARCHAR(32672);DECLARE status INT;

CALL DBMS_OUTPUT.GET_LINE( line, status );while status = 0 do

INSERT INTO messages VALUES ( line );CALL DBMS_OUTPUT.GET_LINE( line, status );

end while;END@

CALL proc1@

CALL proc3@

CALL DBMS_OUTPUT.DISABLE@

CALL proc2@

CALL proc3@

SELECT * FROM messages@

This example results in the following output:MSG----------------------------------------------PROC1 put this line in the message buffer.

1 record(s) selected.

GET_LINES procedure - Get multiple lines from the message bufferThe GET_LINES procedure gets one or more lines of text from the message bufferand stores the text in a collection. Each line of text must be terminated by anend-of-line character sequence.

Tip: To add an end-of-line character sequence to the message buffer, use thePUT_LINE procedure, or, after a series of calls to the PUT procedure, use theNEW_LINE procedure.

Syntax

�� DBMS_OUTPUT.GET_LINES ( lines , numlines ) ��

254 SQL Procedural Languages: Application Enablement and Support

Page 265: IBM DB2 9.7 for Linux, UNIX, And Windows

Procedure parameters

linesAn output argument of type DBMS_OUTPUT.CHARARR that returns the linesof text from the message buffer. The type DBMS_OUTPUT.CHARARR isinternally defined as a VARCHAR(32672) ARRAY[2147483647] array.

numlinesAn input and output argument of type INTEGER. When used as input,specifies the number of lines to retrieve from the message buffer. When used asoutput, indicates the actual number of lines that were retrieved from themessage buffer. If the output value of numlines is less than the input value,then there are no more lines remaining in the message buffer.

Authorization

EXECUTE privilege on the DBMS_OUTPUT module.

Example

Use the GET_LINES procedure to get lines of text from the message buffer andstore the text in an array. The text in the array can be inserted into a table andqueried.CALL DBMS_OUTPUT.ENABLE( NULL )@

CREATE PROCEDURE proc1()BEGIN

CALL DBMS_OUTPUT.PUT_LINE( 'PROC1 put this line in the message buffer.' );CALL DBMS_OUTPUT.PUT_LINE( 'PROC1 put this line in the message buffer.' );

END@

CREATE PROCEDURE proc2()BEGIN

CALL DBMS_OUTPUT.PUT_LINE( 'PROC2 put this line in the message buffer.' );END@

CREATE TABLE messages ( msg VARCHAR(100) )@

CREATE PROCEDURE proc3()BEGIN

DECLARE lines DBMS_OUTPUT.CHARARR;DECLARE numlines INT;DECLARE i INT;

CALL DBMS_OUTPUT.GET_LINES( lines, numlines );SET i = 1;WHILE i <= numlines DO

INSERT INTO messages VALUES ( lines[i] );SET i = i + 1;

END WHILE;END@

CALL proc1@

CALL proc3@

CALL DBMS_OUTPUT.DISABLE@

CALL proc2@

CALL proc3@

SELECT * FROM messages@

Chapter 24. DBMS_OUTPUT module 255

Page 266: IBM DB2 9.7 for Linux, UNIX, And Windows

This example results in the following output:MSG------------------------------------------PROC1 put this line in the message buffer.PROC1 put this line in the message buffer

2 record(s) selected.

NEW_LINE procedure - Put an end-of-line character sequence in themessage buffer

The NEW_LINE procedure puts an end-of-line character sequence in the messagebuffer.

Syntax

�� DBMS_OUTPUT.NEW_LINE ��

Authorization

EXECUTE privilege on the DBMS_OUTPUT module.

Example

Use the NEW_LINE procedure to write an end-of-line character sequence to themessage buffer. In this example, the text that is followed by an end-of-linecharacter sequence displays as output because SET SERVEROUTPUT ON isspecified. However, the text that is in the message buffer, but is not followed by anend-of-line character, does not display.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

CALL DBMS_OUTPUT.PUT( 'T' );CALL DBMS_OUTPUT.PUT( 'h' );CALL DBMS_OUTPUT.PUT( 'i' );CALL DBMS_OUTPUT.PUT( 's' );CALL DBMS_OUTPUT.NEW_LINE;CALL DBMS_OUTPUT.PUT( 'T' );CALL DBMS_OUTPUT.PUT( 'h' );CALL DBMS_OUTPUT.PUT( 'a' );CALL DBMS_OUTPUT.PUT( 't' );

END@

CALL proc1@

SET SERVEROUTPUT OFF@

This example results in the following output:This

PUT procedure - Put a partial line in the message bufferThe PUT procedure puts a string in the message buffer. No end-of-line charactersequence is written at the end of the string.

256 SQL Procedural Languages: Application Enablement and Support

Page 267: IBM DB2 9.7 for Linux, UNIX, And Windows

Syntax

�� DBMS_OUTPUT.PUT ( item ) ��

Procedure parameters

itemAn input argument of type VARCHAR(32672) that specifies the text to write tothe message buffer.

Authorization

EXECUTE privilege on the DBMS_OUTPUT module.

Example

Use the PUT procedure to put a partial line in the message buffer. In this example,the NEW_LINE procedure adds an end-of-line character sequence to the messagebuffer. When proc1 runs, because SET SERVEROUTPUT ON is specified, a line oftext is returned.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

CALL DBMS_OUTPUT.PUT( 'H' );CALL DBMS_OUTPUT.PUT( 'e' );CALL DBMS_OUTPUT.PUT( 'l' );CALL DBMS_OUTPUT.PUT( 'l' );CALL DBMS_OUTPUT.PUT( 'o' );CALL DBMS_OUTPUT.PUT( '.' );CALL DBMS_OUTPUT.NEW_LINE;

END@

CALL proc1@

SET SERVEROUTPUT OFF@

This example results in the following output:Hello.

Usage notes

After using the PUT procedure to add text to the message buffer, use theNEW_LINE procedure to add an end-of-line character sequence to the messagebuffer. Otherwise, the text is not returned by the GET_LINE and GET_LINESprocedures because it is not a complete line.

PUT_LINE procedure - Put a complete line in the message bufferThe PUT_LINE procedure puts a single line that includes an end-of-line charactersequence in the message buffer.

Syntax

�� DBMS_OUTPUT.PUT_LINE ( item ) ��

Chapter 24. DBMS_OUTPUT module 257

Page 268: IBM DB2 9.7 for Linux, UNIX, And Windows

Procedure parameters

itemAn input argument of type VARCHAR(32672) that specifies the text to write tothe message buffer.

Authorization

EXECUTE privilege on the PUT_LINE procedure.

Example

Use the PUT_LINE procedure to write a line that includes an end-of-line charactersequence to the message buffer.SET SERVEROUTPUT ON@

CREATE PROCEDURE PROC1()BEGIN

CALL DBMS_OUTPUT.PUT( 'a' );CALL DBMS_OUTPUT.NEW_LINE;CALL DBMS_OUTPUT.PUT_LINE( 'b' );

END@

CALL PROC1@

SET SERVEROUTPUT OFF@

This example results in the following output:ab

258 SQL Procedural Languages: Application Enablement and Support

Page 269: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 25. DBMS_PIPE module

The DBMS_PIPE module provides a set of routines for sending messages through apipe within or between sessions that are connected to the same database.

The schema for this module is SYSIBMADM.

The DBMS_PIPE module includes the following system-defined routines.

Table 17. System-defined routines available in the DBMS_PIPE module

Routine name Description

CREATE_PIPE function Explicitly creates a private or public pipe.

NEXT_ITEM_TYPE function Determines the data type of the next item ina received message.

PACK_MESSAGE function Puts an item in the session’s local messagebuffer.

PACK_MESSAGE_RAW procedure Puts an item of type RAW in the session’slocal message buffer.

PURGE procedure Removes unreceived messages in thespecified pipe.

RECEIVE_MESSAGE function Gets a message from the specified pipe.

REMOVE_PIPE function Deletes an explicitly created pipe.

RESET_BUFFER procedure Resets the local message buffer.

SEND_MESSAGE procedure Sends a message on the specified pipe.

UNIQUE_SESSION_NAME function Returns a unique session name.

UNPACK_MESSAGE procedures Retrieves the next data item from a messageand assigns it to a variable.

Usage notes

Pipes are created either implicitly or explicitly during procedure calls. An implicitpipe is created when a procedure call contains a reference to a pipe name that doesnot exist. For example, if a pipe named ″mailbox″ is passed to theSEND_MESSAGE procedure and that pipe does not already exist, a new pipenamed ″mailbox″ is created. An explicit pipe is created by calling the CREATE_PIPEfunction and specifying the name of the pipe.

Pipes can be private or public. A private pipe can only be accessed by the user whocreated the pipe. Even an administrator cannot access a private pipe that wascreated by another user. A public pipe can be accessed by any user who has accessto the DBMS_PIPE module. To specify the access level for a pipe, use theCREATE_PIPE function and specify a value for the private parameter: ″false″specifies that the pipe is public; ″true″ specifies that the pipe is private. If no valueis specified, the default is to create a private pipe. All implicit pipes are private.

To send a message through a pipe, call the PACK_MESSAGE function to putindividual data items (lines) in a local message buffer that is unique to the currentsession. Then, call the SEND_MESSAGE procedure to send the message throughthe pipe.

© Copyright IBM Corp. 1993, 2009 259

Page 270: IBM DB2 9.7 for Linux, UNIX, And Windows

To receive a message, call the RECEIVE_MESSAGE function to get a message fromthe specified pipe. The message is written to the receiving session’s local messagebuffer. Then, call the UNPACK_MESSAGE procedure to retrieve the next data itemfrom the local message buffer and assign it to a specified program variable. If apipe contains multiple messages, the RECEIVE_MESSAGE function gets themessages in FIFO (first-in-first-out) order.

Each session maintains separate message buffers for messages that are created bythe PACK_MESSAGE function and messages that are retrieved by theRECEIVE_MESSAGE function. The separate message buffers allow you to buildand receive messages in the same session. However, when consecutive calls aremade to the RECEIVE_MESSAGE function, only the message from the lastRECEIVE_MESSAGE call is preserved in the local message buffer.

Example

In connection 1, create a pipe that is named pipe1. Put a message in the session’slocal message buffer, and send the message through pipe1.BEGIN

DECLARE status INT;SET status = DBMS_PIPE.CREATE_PIPE( 'pipe1' );SET status = DBMS_PIPE.PACK_MESSAGE('message1');SET status = DBMS_PIPE.SEND_MESSAGE( 'pipe1' );

END@

In connection 2, receive the message, unpack it, and display it to standard output.SET SERVEROUTPUT ON@

BEGINDECLARE status INT;DECLARE int1 INTEGER;DECLARE date1 DATE;DECLARE raw1 BLOB(100);DECLARE varchar1 VARCHAR(100);DECLARE itemType INTEGER;

SET status = DBMS_PIPE.RECEIVE_MESSAGE( 'pipe1' );IF( status = 0 ) THEN

SET itemType = DBMS_PIPE.NEXT_ITEM_TYPE();CASE itemType

WHEN 6 THENCALL DBMS_PIPE.UNPACK_MESSAGE_INT( int1 );CALL DBMS_OUTPUT.PUT_LINE( 'int1: ' || int1 );

WHEN 9 THENCALL DBMS_PIPE.UNPACK_MESSAGE_CHAR( varchar1 );CALL DBMS_OUTPUT.PUT_LINE( 'varchar1: ' || varchar1 );

WHEN 12 THENCALL DBMS_PIPE.UNPACK_MESSAGE_DATE( date1 );CALL DBMS_OUTPUT.PUT_LINE( 'date1:' || date1 );

WHEN 23 THENCALL DBMS_PIPE.UNPACK_MESSAGE_RAW( raw1 );CALL DBMS_OUTPUT.PUT_LINE( 'raw1: ' || VARCHAR(raw1) );

ELSECALL DBMS_OUTPUT.PUT_LINE( 'Unexpected value' );

END CASE;END IF;SET status = DBMS_PIPE.REMOVE_PIPE( 'pipe1' );

END@

This example results in the following output:varchar1: message1

260 SQL Procedural Languages: Application Enablement and Support

Page 271: IBM DB2 9.7 for Linux, UNIX, And Windows

CREATE_PIPE function - Create a pipeThe CREATE_PIPE function explicitly creates a public or private pipe with thespecified name.

For more information about explicit public and private pipes, see the topic aboutthe DBMS_PIPE module.

Syntax

�� DBMS_PIPE.CREATE_PIPE ( pipename , , )maxpipesize private

��

Return value

This function returns the status code 0 if the pipe is created successfully.

Function parameters

pipenameAn input argument of type VARCHAR(128) that specifies the name of the pipe.For more information about pipes, see Chapter 25, “DBMS_PIPE module,” onpage 259.

maxpipesizeAn optional input argument of type INTEGER that specifies the maximumcapacity of the pipe in bytes. The default is 8192 bytes.

privateAn optional input argument that specifies the access level of the pipe:

For non-DPF systemsA value of ″0″ or ″FALSE″ creates a public pipe.

A value of ″1″ or ″TRUE creates a private pipe. This is the default.

For DPF systemsA value of ″0″ creates a public pipe.

A value of ″1″ creates a private pipe. This is the default.

Authorization

EXECUTE privilege on the DBMS_PIPE module.

Example

Example 1: Create a private pipe that is named messages:SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE v_status INTEGER;SET v_status = DBMS_PIPE.CREATE_PIPE('messages');DBMS_OUTPUT.PUT_LINE('CREATE_PIPE status: ' || v_status);

END@

CALL proc1@

This example results in the following output:

Chapter 25. DBMS_PIPE module 261

Page 272: IBM DB2 9.7 for Linux, UNIX, And Windows

CREATE_PIPE status: 0

Example 2: Create a public pipe that is named mailbox:SET SERVEROUTPUT ON@

CREATE PROCEDURE proc2()BEGIN

DECLARE v_status INTEGER;SET v_status = DBMS_PIPE.CREATE_PIPE('mailbox',0);DBMS_OUTPUT.PUT_LINE('CREATE_PIPE status: ' || v_status);

END@

CALL proc2@

This example results in the following output:CREATE_PIPE status: 0

NEXT_ITEM_TYPE function - Return the data type code of the nextitem

The NEXT_ITEM_TYPE function returns an integer code that identifies the datatype of the next data item in a received message.

The received message is stored in the session’s local message buffer. Use theUNPACK_MESSAGE procedure to move each item off of the local message buffer,and then use the NEXT_ITEM_TYPE function to return the data type code for thenext available item. A code of 0 is returned when there are no more items left inthe message.

Syntax

�� DBMS_PIPE.NEXT_ITEM_TYPE ��

Return value

This function returns one of the following codes that represents a data type.

Table 18. NEXT_ITEM_TYPE data type codes

Type code Data type

0 No more data items

6 INTEGER

9 VARCHAR

12 DATE

23 BLOB

Authorization

EXECUTE privilege on the DBMS_PIPE module.

Example

In proc1, pack and send a message. In proc2, receive the message and then unpackit by using the NEXT_ITEM_TYPE function to determine its type.

262 SQL Procedural Languages: Application Enablement and Support

Page 273: IBM DB2 9.7 for Linux, UNIX, And Windows

SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE status INT;SET status = DBMS_PIPE.CREATE_PIPE( 'pipe1' );SET status = DBMS_PIPE.PACK_MESSAGE('message1');SET status = DBMS_PIPE.SEND_MESSAGE( 'pipe1' );

END@

CREATE PROCEDURE proc2()BEGIN

DECLARE status INT;DECLARE num1 DECFLOAT;DECLARE date1 DATE;DECLARE raw1 BLOB(100);DECLARE varchar1 VARCHAR(100);DECLARE itemType INTEGER;

SET status = DBMS_PIPE.RECEIVE_MESSAGE( 'pipe1' );IF( status = 0 ) THEN

SET itemType = DBMS_PIPE.NEXT_ITEM_TYPE();CASE itemType

WHEN 6 THENCALL DBMS_PIPE.UNPACK_MESSAGE_NUMBER( num1 );CALL DBMS_OUTPUT.PUT_LINE( 'num1: ' || num1 );

WHEN 9 THENCALL DBMS_PIPE.UNPACK_MESSAGE_CHAR( varchar1 );CALL DBMS_OUTPUT.PUT_LINE( 'varchar1: ' || varchar1 );

WHEN 12 THENCALL DBMS_PIPE.UNPACK_MESSAGE_DATE( date1 );CALL DBMS_OUTPUT.PUT_LINE( 'date1:' || date1 );

WHEN 23 THENCALL DBMS_PIPE.UNPACK_MESSAGE_RAW( raw1 );CALL DBMS_OUTPUT.PUT_LINE( 'raw1: ' || VARCHAR(raw1) );

ELSECALL DBMS_OUTPUT.PUT_LINE( 'Unexpected value' );

END CASE;END IF;SET status = DBMS_PIPE.REMOVE_PIPE( 'pipe1' );

END@

CALL proc1@

CALL proc2@

This example results in the following output:varchar1: message1

PACK_MESSAGE function - Put a data item in the local messagebuffer

The PACK_MESSAGE function puts a data item in the session’s local messagebuffer.

Syntax

�� DBMS_PIPE.PACK_MESSAGE ( item ) ��

Chapter 25. DBMS_PIPE module 263

Page 274: IBM DB2 9.7 for Linux, UNIX, And Windows

Procedure parameters

itemAn input argument of type VARCHAR(4096), DATE, or DECFLOAT thatcontains an expression. The value returned by this expression is added to thelocal message buffer of the session.

Tip: To put data items of type RAW in the local message buffer, use thePACK_MESSAGE_RAW procedure.

Authorization

EXECUTE privilege on the DBMS_PIPE module.

Example

Use the PACK_MESSAGE function to put a message for Sujata in the local messagebuffer, and then use the SEND_MESSAGE procedure to send the message on apipe.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE v_status INTEGER;DECLARE status INTEGER;SET status = DBMS_PIPE.PACK_MESSAGE('Hi, Sujata');SET status = DBMS_PIPE.PACK_MESSAGE('Can you attend a meeting at 3:00, today?');SET status = DBMS_PIPE.PACK_MESSAGE('If not, is tomorrow at 8:30 ok with you?');SET v_status = DBMS_PIPE.SEND_MESSAGE('pipe');CALL DBMS_OUTPUT.PUT_LINE('SEND_MESSAGE status: ' || v_status);

END@

CALL proc1@

This example results in the following output:SEND_MESSAGE status: 0

Usage notes

The PACK_MESSAGE function or PACK_MESSAGE_RAW procedure must becalled at least once before issuing a SEND_MESSAGE call.

PACK_MESSAGE_RAW procedure - Put a data item of type RAW in thelocal message buffer

The PACK_MESSAGE_RAW procedure puts a data item of type RAW in thesession’s local message buffer.

Syntax

�� DBMS_PIPE.PACK_MESSAGE_RAW ( item ) ��

Procedure parameters

itemAn input argument of type BLOB(4096) that specifies an expression. The valuereturned by this expression is added to the session’s local message buffer.

264 SQL Procedural Languages: Application Enablement and Support

Page 275: IBM DB2 9.7 for Linux, UNIX, And Windows

Authorization

EXECUTE privilege on the DBMS_PIPE module.

Example

Use the PACK_MESSAGE_RAW procedure to put a data item of type RAW in thelocal message buffer.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE v_raw BLOB(100);DECLARE v_raw2 BLOB(100);DECLARE v_status INTEGER;SET v_raw = BLOB('21222324');SET v_raw2 = BLOB('30000392');CALL DBMS_PIPE.PACK_MESSAGE_RAW(v_raw);CALL DBMS_PIPE.PACK_MESSAGE_RAW(v_raw2);SET v_status = DBMS_PIPE.SEND_MESSAGE('datatypes');CALL DBMS_OUTPUT.PUT_LINE('SEND_MESSAGE status: ' || v_status);

END@

CALL proc1@

This example results in the following output:SEND_MESSAGE status: 0

Usage notes

The PACK_MESSAGE function or PACK_MESSAGE_RAW procedure must becalled at least once before issuing a SEND_MESSAGE call.

PURGE procedure - Remove unreceived messages from a pipeThe PURGE procedure removes unreceived messages in the specified implicit pipe.

Tip: Use the REMOVE_PIPE function to delete an explicit pipe.

Syntax

�� DBMS_PIPE.PURGE ( pipename ) ��

Procedure parameters

pipenameAn input argument of type VARCHAR(128) that specifies the name of theimplicit pipe.

Authorization

EXECUTE privilege on the DBMS_PIPE module.

Chapter 25. DBMS_PIPE module 265

Page 276: IBM DB2 9.7 for Linux, UNIX, And Windows

Example

In proc1 send two messages on a pipe: Message #1 and Message #2. In proc2,receive the first message, unpack it, and then purge the pipe. When proc3 runs, thecall to the RECEIVE_MESSAGE function times out and returns the status code 1because no message is available.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE v_status INTEGER;DECLARE status INTEGER;SET status = DBMS_PIPE.PACK_MESSAGE('Message #1');SET v_status = DBMS_PIPE.SEND_MESSAGE('pipe');CALL DBMS_OUTPUT.PUT_LINE('SEND_MESSAGE status: ' || v_status);SET status = DBMS_PIPE.PACK_MESSAGE('Message #2');SET v_status = DBMS_PIPE.SEND_MESSAGE('pipe');CALL DBMS_OUTPUT.PUT_LINE('SEND_MESSAGE status: ' || v_status);

END@

CREATE PROCEDURE proc2()BEGIN

DECLARE v_item VARCHAR(80);DECLARE v_status INTEGER;SET v_status = DBMS_PIPE.RECEIVE_MESSAGE('pipe',1);CALL DBMS_OUTPUT.PUT_LINE('RECEIVE_MESSAGE status: ' || v_status);CALL DBMS_PIPE.UNPACK_MESSAGE_CHAR(v_item);CALL DBMS_OUTPUT.PUT_LINE('Item: ' || v_item);CALL DBMS_PIPE.PURGE('pipe');

END@

CREATE PROCEDURE proc3()BEGIN

DECLARE v_item VARCHAR(80);DECLARE v_status INTEGER;SET v_status = DBMS_PIPE.RECEIVE_MESSAGE('pipe',1);CALL DBMS_OUTPUT.PUT_LINE('RECEIVE_MESSAGE status: ' || v_status);

END@

CALL proc1@

CALL proc2@

CALL proc3@

This example results in the following output.

From proc1:SEND_MESSAGE status: 0SEND_MESSAGE status: 0

From proc2:RECEIVE_MESSAGE status: 0Item: Hi, Sujata

From proc3:RECEIVE_MESSAGE status: 1

RECEIVE_MESSAGE function - Get a message from a specified pipeThe RECEIVE_MESSAGE function gets a message from a specified pipe.

266 SQL Procedural Languages: Application Enablement and Support

Page 277: IBM DB2 9.7 for Linux, UNIX, And Windows

Syntax

�� DBMS_PIPE.RECEIVE_MESSAGE ( pipename ), timeout

��

Return value

The RECEIVE_MESSAGE function returns one of the following status codes oftype INTEGER.

Table 19. RECEIVE_MESSAGE status codes

Status code Description

0 Success

1 Time out

Function parameters

pipenameAn input argument of type VARCHAR(128) that specifies the name of the pipe.If the specified pipe does not exist, the pipe is created implicitly. For moreinformation about pipes, see Chapter 25, “DBMS_PIPE module,” on page 259.

timeoutAn optional input argument of type INTEGER that specifies the wait time inseconds. The default is 86400000 (1000 days).

Authorization

EXECUTE privilege on the DBMS_PIPE module.

Example

In proc1, send a message. In proc2, receive and unpack the message. Timeout if themessage is not received within 1 second.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE status INTEGER;SET status = DBMS_PIPE.CREATE_PIPE( 'pipe1' );SET status = DBMS_PIPE.PACK_MESSAGE('message1');SET status = DBMS_PIPE.SEND_MESSAGE( 'pipe1' );

END@

CREATE PROCEDURE proc2()BEGIN

DECLARE v_item VARCHAR(80);DECLARE v_status INTEGER;SET v_status = DBMS_PIPE.RECEIVE_MESSAGE('pipe1',1);CALL DBMS_OUTPUT.PUT_LINE('RECEIVE_MESSAGE status: ' || v_status);CALL DBMS_PIPE.UNPACK_MESSAGE(v_item);CALL DBMS_OUTPUT.PUT_LINE('Item: ' || v_item);

END@

CALL proc1@CALL proc2@

This example results in the following output:

Chapter 25. DBMS_PIPE module 267

Page 278: IBM DB2 9.7 for Linux, UNIX, And Windows

RECEIVE_MESSAGE status: 0Item: message1

REMOVE_PIPE function - Delete a pipeThe REMOVE_PIPE function deletes an explicitly created pipe. Use this function todelete any public or private pipe that was created by the CREATE_PIPE function.

Syntax

�� DBMS_PIPE.REMOVE_PIPE ( pipename ) ��

Return value

This function returns one of the following status codes of type INTEGER.

Table 20. REMOVE_PIPE status codes

Status code Description

0 Pipe successfully removed or does not exist

NULL An exception is thrown

Function parameters

pipenameAn input argument of type VARCHAR(128) that specifies the name of the pipe.

Authorization

EXECUTE privilege on the DBMS_PIPE module.

Example

In proc1 send two messages on a pipe: Message #1 and Message #2. In proc2,receive the first message, unpack it, and then delete the pipe. When proc3 runs, thecall to the RECEIVE_MESSAGE function times out and returns the status code 1because the pipe no longer exists.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE v_status INTEGER;DECLARE status INTEGER;SET v_status = DBMS_PIPE.CREATE_PIPE('pipe1');CALL DBMS_OUTPUT.PUT_LINE('CREATE_PIPE status : ' || v_status);

SET status = DBMS_PIPE.PACK_MESSAGE('Message #1');SET v_status = DBMS_PIPE.SEND_MESSAGE('pipe1');CALL DBMS_OUTPUT.PUT_LINE('SEND_MESSAGE status: ' || v_status);

SET status = DBMS_PIPE.PACK_MESSAGE('Message #2');SET v_status = DBMS_PIPE.SEND_MESSAGE('pipe1');CALL DBMS_OUTPUT.PUT_LINE('SEND_MESSAGE status: ' || v_status);

END@

CREATE PROCEDURE proc2()BEGIN

DECLARE v_item VARCHAR(80);

268 SQL Procedural Languages: Application Enablement and Support

Page 279: IBM DB2 9.7 for Linux, UNIX, And Windows

DECLARE v_status INTEGER;DECLARE status INTEGER;SET v_status = DBMS_PIPE.RECEIVE_MESSAGE('pipe1',1);CALL DBMS_OUTPUT.PUT_LINE('RECEIVE_MESSAGE status: ' || v_status);CALL DBMS_PIPE.UNPACK_MESSAGE(v_item);CALL DBMS_OUTPUT.PUT_LINE('Item: ' || v_item);SET status = DBMS_PIPE.REMOVE_PIPE('pipe1');

END@

CREATE PROCEDURE proc3()BEGIN

DECLARE v_item VARCHAR(80);DECLARE v_status INTEGER;SET v_status = DBMS_PIPE.RECEIVE_MESSAGE('pipe1',1);CALL DBMS_OUTPUT.PUT_LINE('RECEIVE_MESSAGE status: ' || v_status);

END@

CALL proc1@

CALL proc2@

CALL proc3@

This example results in the following output.

From proc1:CREATE_PIPE status : 0SEND_MESSAGE status: 0SEND_MESSAGE status: 0

From proc2:RECEIVE_MESSAGE status: 0Item: Message #1

From proc3:RECEIVE_MESSAGE status: 1

RESET_BUFFER procedure - Reset the local message bufferThe RESET_BUFFER procedure resets a pointer to the session’s local messagebuffer back to the beginning of the buffer. Resetting the buffer causes subsequentPACK_MESSAGE calls to overwrite any data items that existed in the messagebuffer prior to the RESET_BUFFER call.

Syntax

�� DBMS_PIPE.RESET_BUFFER ��

Authorization

EXECUTE privilege on the DBMS_PIPE module.

Example

In proc1, use the PACK_MESSAGE function to put a message for an employeenamed Sujata in the local message buffer. Call the RESET_BUFFER procedure toreplace the message with a message for Bing, and then send the message on apipe. In proc2, receive and unpack the message for Bing.

Chapter 25. DBMS_PIPE module 269

Page 280: IBM DB2 9.7 for Linux, UNIX, And Windows

SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGINDECLARE v_status INTEGER;DECLARE status INTEGER;SET status = DBMS_PIPE.PACK_MESSAGE('Hi, Sujata');SET status = DBMS_PIPE.PACK_MESSAGE('Can you attend a meeting at 3:00, today?');SET status = DBMS_PIPE.PACK_MESSAGE('If not, is tomorrow at 8:30 ok with you?');CALL DBMS_PIPE.RESET_BUFFER;SET status = DBMS_PIPE.PACK_MESSAGE('Hi, Bing');SET status = DBMS_PIPE.PACK_MESSAGE('Can you attend a meeting at 9:30, tomorrow?');SET v_status = DBMS_PIPE.SEND_MESSAGE('pipe');CALL DBMS_OUTPUT.PUT_LINE('SEND_MESSAGE status: ' || v_status);

END@

CREATE PROCEDURE proc2()BEGINDECLARE v_item VARCHAR(80);DECLARE v_status INTEGER;SET v_status = DBMS_PIPE.RECEIVE_MESSAGE('pipe',1);CALL DBMS_OUTPUT.PUT_LINE('RECEIVE_MESSAGE status: ' || v_status);CALL DBMS_PIPE.UNPACK_MESSAGE_CHAR(v_item);CALL DBMS_OUTPUT.PUT_LINE('Item: ' || v_item);CALL DBMS_PIPE.UNPACK_MESSAGE(v_item);CALL DBMS_OUTPUT.PUT_LINE('Item: ' || v_item);

END@

CALL proc1@

CALL proc2@

This example results in the following output:

From proc1:SEND_MESSAGE status: 0

From proc2:RECEIVE_MESSAGE status: 0Item: Hi, BingItem: Can you attend a meeting at 9:30, tomorrow?

SEND_MESSAGE procedure - Send a message to a specified pipeThe SEND_MESSAGE procedure sends a message from the session’s local messagebuffer to a specified pipe.

Syntax

�� DBMS_PIPE.SEND_MESSAGE ( pipename ), timeout , maxpipesize

��

Return value

This procedure returns one of the following status codes of type INTEGER.

Table 21. SEND_MESSAGE status codes

Status code Description

0 Success

1 Time out

270 SQL Procedural Languages: Application Enablement and Support

Page 281: IBM DB2 9.7 for Linux, UNIX, And Windows

Procedure parameters

pipenameAn input argument of type VARCHAR(128) that specifies the name of the pipe.If the specified pipe does not exist, the pipe is created implicitly. For moreinformation about pipes, see Chapter 25, “DBMS_PIPE module,” on page 259.

timeoutAn optional input argument of type INTEGER that specifies the wait time inseconds. The default is 86400000 (1000 days).

maxpipesizeAn optional input argument of type INTEGER that specifies the maximumcapacity of the pipe in bytes. The default is 8192 bytes.

Authorization

EXECUTE privilege on the DBMS_PIPE module.

Example

In proc1, send a message. In proc2, receive and unpack the message. Timeout if themessage is not received within 1 second.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE status INTEGER;SET status = DBMS_PIPE.CREATE_PIPE( 'pipe1' );SET status = DBMS_PIPE.PACK_MESSAGE('message1');SET status = DBMS_PIPE.SEND_MESSAGE( 'pipe1' );

END@

CREATE PROCEDURE proc2()BEGIN

DECLARE v_item VARCHAR(80);DECLARE v_status INTEGER;SET v_status = DBMS_PIPE.RECEIVE_MESSAGE('pipe1',1);CALL DBMS_OUTPUT.PUT_LINE('RECEIVE_MESSAGE status: ' || v_status);CALL DBMS_PIPE.UNPACK_MESSAGE(v_item);CALL DBMS_OUTPUT.PUT_LINE('Item: ' || v_item);

END@

CALL proc1@CALL proc2@

This example results in the following output:RECEIVE_MESSAGE status: 0Item: message1

UNIQUE_SESSION_NAME function - Return a unique session nameThe UNIQUE_SESSION_NAME function returns a unique name for the currentsession.

You can use this function to create a pipe that has the same name as the currentsession. To create this pipe, pass the value returned by theUNIQUE_SESSION_NAME function to the SEND_MESSAGE procedure as thepipe name. An implicit pipe is created that has the same name as the currentsession.

Chapter 25. DBMS_PIPE module 271

Page 282: IBM DB2 9.7 for Linux, UNIX, And Windows

Syntax

�� DBMS_PIPE.UNIQUE_SESSION_NAME ��

Return value

This function returns a value of type VARCHAR(128) that represents the uniquename for the current session.

Authorization

EXECUTE privilege on the DBMS_PIPE module.

Example

Create a pipe that has the same name as the current session.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE status INTEGER;DECLARE v_session VARCHAR(30);SET v_session = DBMS_PIPE.UNIQUE_SESSION_NAME;SET status = DBMS_PIPE.PACK_MESSAGE('message1');SET status = DBMS_PIPE.SEND_MESSAGE(v_session);CALL DBMS_OUTPUT.PUT_LINE('Sent message on pipe ' || v_session);

END@

CALL proc1@

This example results in the following output:Sent message on pipe *LOCAL.myschema.080522010048

UNPACK_MESSAGE procedures - Get a data item from the localmessage buffer

The UNPACK_MESSAGE procedures retrieve the next data item from a messageand assign it to a variable.

Before calling one of the UNPACK_MESSAGE procedures, use theRECEIVE_MESSAGE procedure to place the message in the local message buffer.

Syntax

�� DBMS_PIPE.UNPACK_MESSAGE_NUMBER ( item ) ��

�� DBMS_PIPE.UNPACK_MESSAGE_CHAR ( item ) ��

�� DBMS_PIPE.UNPACK_MESSAGE_DATE ( item ) ��

�� DBMS_PIPE.UNPACK_MESSAGE_RAW ( item ) ��

272 SQL Procedural Languages: Application Enablement and Support

Page 283: IBM DB2 9.7 for Linux, UNIX, And Windows

Procedure parameters

itemAn output argument of one of the following types that specifies a variable toreceive data items from the local message buffer.

Routine Data type

UNPACK_MESSAGE_NUMBER DECFLOAT

UNPACK_MESSAGE_CHAR VARCHAR(4096)

UNPACK_MESSAGE_DATE DATE

UNPACK_MESSAGE_RAW BLOB(4096)

Authorization

EXECUTE privilege on the DBMS_PIPE module.

Example

In proc1, pack and send a message. In proc2, receive the message, unpack it usingthe appropriate procedure based on the item’s type, and display the message tostandard output.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE status INT;SET status = DBMS_PIPE.CREATE_PIPE( 'pipe1' );SET status = DBMS_PIPE.PACK_MESSAGE('message1');SET status = DBMS_PIPE.SEND_MESSAGE( 'pipe1' );

END@

CREATE PROCEDURE proc2()BEGIN

DECLARE status INT;DECLARE num1 DECFLOAT;DECLARE date1 DATE;DECLARE raw1 BLOB(100);DECLARE varchar1 VARCHAR(100);DECLARE itemType INTEGER;

SET status = DBMS_PIPE.RECEIVE_MESSAGE( 'pipe1' );IF( status = 0 ) THEN

SET itemType = DBMS_PIPE.NEXT_ITEM_TYPE();CASE itemType

WHEN 6 THENCALL DBMS_PIPE.UNPACK_MESSAGE_NUMBER( num1 );CALL DBMS_OUTPUT.PUT_LINE( 'num1: ' || num1 );

WHEN 9 THENCALL DBMS_PIPE.UNPACK_MESSAGE_CHAR( varchar1 );CALL DBMS_OUTPUT.PUT_LINE( 'varchar1: ' || varchar1 );

WHEN 12 THENCALL DBMS_PIPE.UNPACK_MESSAGE_DATE( date1 );CALL DBMS_OUTPUT.PUT_LINE( 'date1:' || date1 );

WHEN 23 THENCALL DBMS_PIPE.UNPACK_MESSAGE_RAW( raw1 );CALL DBMS_OUTPUT.PUT_LINE( 'raw1: ' || VARCHAR(raw1) );

ELSECALL DBMS_OUTPUT.PUT_LINE( 'Unexpected value' );

END CASE;END IF;SET status = DBMS_PIPE.REMOVE_PIPE( 'pipe1' );

Chapter 25. DBMS_PIPE module 273

Page 284: IBM DB2 9.7 for Linux, UNIX, And Windows

END@

CALL proc1@

CALL proc2@

This example results in the following output:varchar1: message1

274 SQL Procedural Languages: Application Enablement and Support

Page 285: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 26. DBMS_SQL module

The DBMS_SQL module provides a set of procedures for executing dynamic SQL,and therefore supports various data manipulation language (DML) or datadefinition language (DDL) statement.

The schema for this module is SYSIBMADM.

The DBMS_SQL module includes the following system-defined routines.

Table 22. System-defined routines available in the DBMS_SQL module

Procedure name Description

BIND_VARIABLE_BLOB procedure Provides the input BLOB value for the IN orINOUT parameter; and defines the data typeof the output value to be BLOB for theINOUT or OUT parameter.

BIND_VARIABLE_CHAR procedure Provides the input CHAR value for the INor INOUT parameter; and defines the datatype of the output value to be CHAR for theINOUT or OUT parameter.

BIND_VARIABLE_CLOB procedure Provides the input CLOB value for the IN orINOUT parameter; and defines the data typeof the output value to be CLOB for theINOUT or OUT parameter.

BIND_VARIABLE_DATE procedure Provides the input DATE value for the IN orINOUT parameter; and defines the data typeof the output value to be DATE for theINOUT or OUT parameter.

BIND_VARIABLE_DOUBLE procedure Provides the input DOUBLE value for theIN or INOUT parameter; and defines thedata type of the output value to be DOUBLEfor the INOUT or OUT parameter.

BIND_VARIABLE_INT procedure Provides the input INTEGER value for theIN or INOUT parameter; and defines thedata type of the output value to beINTEGER for the INOUT or OUT parameter.

BIND_VARIABLE_NUMBER procedure Provides the input DECFLOAT value for theIN or INOUT parameter; and defines thedata type of the output value to beDECFLOAT for the INOUT or OUTparameter.

BIND_VARIABLE_RAW procedure Provides the input BLOB(32767) value forthe IN or INOUT parameter; and defines thedata type of the output value to beBLOB(32767) for the INOUT or OUTparameter.

BIND_VARIABLE_TIMESTAMP procedure Provides the input TIMESTAMP value forthe IN or INOUT parameter; and defines thedata type of the output value to beTIMESTAMP for the INOUT or OUTparameter.

© Copyright IBM Corp. 1993, 2009 275

Page 286: IBM DB2 9.7 for Linux, UNIX, And Windows

Table 22. System-defined routines available in the DBMS_SQL module (continued)

Procedure name Description

BIND_VARIABLE_VARCHAR procedure Provides the input VARCHAR value for theIN or INOUT parameter; and defines thedata type of the output value to beVARCHAR for the INOUT or OUTparameter.

CLOSE_CURSOR procedure Closes a cursor.

COLUMN_VALUE_BLOB procedure Retrieves the value of column of type BLOB.

COLUMN_VALUE_CHAR procedure Retrieves the value of column of typeCHAR.

COLUMN_VALUE_CLOB procedure Retrieves the value of column of type CLOB.

COLUMN_VALUE_DATE procedure Retrieves the value of column of type DATE.

COLUMN_VALUE_DOUBLE procedure Retrieves the value of column of typeDOUBLE.

COLUMN_VALUE_INT procedure Retrieves the value of column of typeINTEGER.

COLUMN_VALUE_LONG procedure Retrieves the value of column of typeCLOB(32767).

COLUMN_VALUE_NUMBER procedure Retrieves the value of column of typeDECFLOAT.

COLUMN_VALUE_RAW procedure Retrieves the value of column of typeBLOB(32767).

COLUMN_VALUE_TIMESTAMP procedure Retrieves the value of column of typeTIMESTAMP

COLUMN_VALUE_VARCHAR procedure Retrieves the value of column of typeVARCHAR.

DEFINE_COLUMN_BLOB procedure Defines the data type of the column to beBLOB.

DEFINE_COLUMN_CHAR procedure Defines the data type of the column to beCHAR.

DEFINE_COLUMN_CLOB procedure Defines the data type of the column to beCLOB.

DEFINE_COLUMN_DATE procedure Defines the data type of the column to beDATE.

DEFINE_COLUMN_DOUBLE procedure Defines the data type of the column to beDOUBLE.

DEFINE_COLUMN_INT procedure Defines the data type of the column to beINTEGER.

DEFINE_COLUMN_LONG procedure Defines the data type of the column to beCLOB(32767).

DEFINE_COLUMN_NUMBER procedure Defines the data type of the column to beDECFLOAT.

DEFINE_COLUMN_RAW procedure Defines the data type of the column to beBLOB(32767).

DEFINE_COLUMN_TIMESTAMP procedure Defines the data type of the column to beTIMESTAMP.

DEFINE_COLUMN_VARCHAR procedure Defines the data type of the column to beVARCHAR.

276 SQL Procedural Languages: Application Enablement and Support

Page 287: IBM DB2 9.7 for Linux, UNIX, And Windows

Table 22. System-defined routines available in the DBMS_SQL module (continued)

Procedure name Description

DESCRIBE_COLUMNS procedure Return a description of the columnsretrieved by a cursor.

DESCRIBE_COLUMNS2 procedure Identical to DESCRIBE_COLUMNS, butallows for column names greater than 32characters.

EXECUTE procedure Executes a cursor.

EXECUTE_AND_FETCH procedure Executes a cursor and fetch one row.

FETCH_ROWS procedure Fetches rows from a cursor.

IS_OPEN procedure Checks if a cursor is open.

LAST_ROW_COUNT procedure Returns the total number of rows fetched.

OPEN_CURSOR procedure Opens a cursor.

PARSE procedure Parses a DDL statement.

VARIABLE_VALUE_BLOB procedure Retrieves the value of INOUT or OUTparameters as BLOB.

VARIABLE_VALUE_CHAR procedure Retrieves the value of INOUT or OUTparameters as CHAR.

VARIABLE_VALUE_CLOB procedure Retrieves the value of INOUT or OUTparameters as CLOB.

VARIABLE_VALUE_DATE procedure Retrieves the value of INOUT or OUTparameters as DATE.

VARIABLE_VALUE_DOUBLE procedure Retrieves the value of INOUT or OUTparameters as DOUBLE.

VARIABLE_VALUE_INT procedure Retrieves the value of INOUT or OUTparameters as INTEGER.

VARIABLE_VALUE_NUMBER procedure Retrieves the value of INOUT or OUTparameters as DECFLOAT.

VARIABLE_VALUE_RAW procedure Retrieves the value of INOUT or OUTparameters as BLOB(32767).

VARIABLE_VALUE_TIMESTAMP procedure Retrieves the value of INOUT or OUTparameters as TIMESTAMP.

VARIABLE_VALUE_VARCHAR procedure Retrieves the value of INOUT or OUTparameters as VARCHAR.

The following table lists the system-defined types and constants available in theDBMS_SQL module.

Table 23. DBMS_SQL system-defined types and constants

Name Type or constant Description

DESC_REC Type A record of columninformation.

DESC_REC2 Type A record of columninformation.

DESC_TAB Type An array of records of typeDESC_REC.

DESC_TAB2 Type An array of records of typeDESC_REC2.

Chapter 26. DBMS_SQL module 277

Page 288: IBM DB2 9.7 for Linux, UNIX, And Windows

Table 23. DBMS_SQL system-defined types and constants (continued)

Name Type or constant Description

NATIVE Constant The only value supported forlanguage_flag parameter ofthe PARSE procedure.

Usage notes

The routines in the DBMS_SQL module are useful when you want to construct andrun dynamic SQL statements. For example, you might want execute DDL or DMLstatements such as ″ALTER TABLE″ or ″DROP TABLE″, construct and execute SQLstatements on the fly, or call a function which uses dynamic SQL from within aSQL statement.

BIND_VARIABLE_BLOB procedure - Bind a BLOB value to a variableThe BIND_VARIABLE_BLOB procedure provides the capability to associate aBLOB value with an IN, INOUT, or OUT argument in an SQL command.

Syntax

�� BIND_VARIABLE_BLOB ( c , name , value ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID for the SQLcommand with bind variables.

nameAn input argument of type VARCHAR(128) that specifies the name of the bindvariable in the SQL command.

valueAn input argument of type BLOB(2G) that specifies the value to be assigned.

Authorization

EXECUTE privilege on the DBMS_SQL module.

BIND_VARIABLE_CHAR procedure - Bind a CHAR value to a variableThe BIND_VARIABLE_CHAR procedure provides the capability to associate aCHAR value with an IN, INOUT, or OUT argument in an SQL command.

Syntax

�� BIND_VARIABLE_CHAR ( c , name , value [ , out_value_size ] ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID for the SQLcommand with bind variables.

278 SQL Procedural Languages: Application Enablement and Support

Page 289: IBM DB2 9.7 for Linux, UNIX, And Windows

nameAn input argument of type VARCHAR(128) that specifies the name of the bindvariable in the SQL command.

valueAn input argument of type CHAR(254) that specifies the value to be assigned.

out_value_sizeAn optional input argument of type INTEGER that specifies the length limitfor the IN or INOUT argument, and the maximum length of the output valuefor the INOUT or OUT argument. If it is not specified, the length of value isassumed.

Authorization

EXECUTE privilege on the DBMS_SQL module.

BIND_VARIABLE_CLOB procedure - Bind a CLOB value to a variableThe BIND_VARIABLE_CLOB procedure provides the capability to associate aCLOB value with an IN, INOUT, or OUT argument in an SQL command.

Syntax

�� BIND_VARIABLE_CLOB ( c , name , value ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID for the SQLcommand with bind variables.

nameAn input argument of type VARCHAR(128) that specifies the name of the bindvariable in the SQL command.

valueAn input argument of type CLOB(2G) that specifies the value to be assigned.

Authorization

EXECUTE privilege on the DBMS_SQL module.

BIND_VARIABLE_DATE procedure - Bind a DATE value to a variableThe BIND_VARIABLE_DATE procedure provides the capability to associate aDATE value with an IN, INOUT, or OUT argument in an SQL command.

Syntax

�� BIND_VARIABLE_DATE ( c , name , value ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID for the SQLcommand with bind variables.

Chapter 26. DBMS_SQL module 279

Page 290: IBM DB2 9.7 for Linux, UNIX, And Windows

nameAn input argument of type VARCHAR(128) that specifies the name of the bindvariable in the SQL command.

valueAn input argument of type DATE that specifies the value to be assigned.

Authorization

EXECUTE privilege on the DBMS_SQL module.

BIND_VARIABLE_DOUBLE procedure - Bind a DOUBLE value to avariable

The BIND_VARIABLE_DOUBLE procedure provides the capability to associate aDOUBLE value with an IN, INOUT, or OUT argument in an SQL command.

Syntax

�� BIND_VARIABLE_DOUBLE ( c , name , value ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID for the SQLcommand with bind variables.

nameAn input argument of type VARCHAR(128) that specifies the name of the bindvariable in the SQL command.

valueAn input argument of type DOUBLE that specifies the value to be assigned.

Authorization

EXECUTE privilege on the DBMS_SQL module.

BIND_VARIABLE_INT procedure - Bind an INTEGER value to a variableThe BIND_VARIABLE_INT procedure provides the capability to associate anINTEGER value with an IN or INOUT bind variable in an SQL command.

Syntax

�� BIND_VARIABLE_INT ( c , name , value ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID for the SQLcommand with bind variables.

nameAn input argument of type VARCHAR(128) that specifies the name of the bindvariable in the SQL command.

valueAn input argument of type INTEGER that specifies the value to be assigned.

280 SQL Procedural Languages: Application Enablement and Support

Page 291: IBM DB2 9.7 for Linux, UNIX, And Windows

Authorization

EXECUTE privilege on the DBMS_SQL module.

BIND_VARIABLE_NUMBER procedure - Bind a NUMBER value to avariable

The BIND_VARIABLE_NUMBER procedure provides the capability to associate aNUMBER value with an IN, INOUT, or OUT argument in an SQL command.

Syntax

�� BIND_VARIABLE_NUMBER ( c , name , value ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID for the SQLcommand with bind variables.

nameAn input argument of type VARCHAR(128) that specifies the name of the bindvariable in the SQL command.

valueAn input argument of type DECFLOAT that specifies the value to be assigned.

Authorization

EXECUTE privilege on the DBMS_SQL module.

BIND_VARIABLE_RAW procedure - Bind a RAW value to a variableThe BIND_VARIABLE_RAW procedure provides the capability to associate a RAWvalue with an IN, INOUT, or OUT argument in an SQL command.

Syntax

�� BIND_VARIABLE_RAW ( c , name , value [ , out_value_size ] ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID for the SQLcommand with bind variables.

nameAn input argument of type VARCHAR(128) that specifies the name of the bindvariable in the SQL command.

valueAn input argument of type BLOB(32767) that specifies the value to beassigned.

out_value_sizeAn optional input argument of type INTEGER that specifies the length limitfor the IN or INOUT argument, and the maximum length of the output valuefor the INOUT or OUT argument. If it is not specified, the length of value isassumed.

Chapter 26. DBMS_SQL module 281

Page 292: IBM DB2 9.7 for Linux, UNIX, And Windows

Authorization

EXECUTE privilege on the DBMS_SQL module.

BIND_VARIABLE_TIMESTAMP procedure - Bind a TIMESTAMP value toa variable

The BIND_VARIABLE_TIMESTAMP procedure provides the capability to associatea TIMESTAMP value with an IN, INOUT, or OUT argument in an SQL command.

Syntax

�� BIND_VARIABLE_TIMESTAMP ( c , name , value ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID for the SQLcommand with bind variables.

nameAn input argument of type VARCHAR(128) that specifies the name of the bindvariable in the SQL command.

valueAn input argument of type TIMESTAMP that specifies the value to beassigned.

Authorization

EXECUTE privilege on the DBMS_SQL module.

BIND_VARIABLE_VARCHAR procedure - Bind a VARCHAR value to avariable

The BIND_VARIABLE_VARCHAR procedure provides the capability to associate aVARCHAR value with an IN, INOUT, or OUT argument in an SQL command.

Syntax

�� BIND_VARIABLE_VARCHAR ( c , name , value [ , out_value_size ] ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID for the SQLcommand with bind variables.

nameAn input argument of type VARCHAR(128) that specifies the name of the bindvariable in the SQL command.

valueAn input argument of type VARCHAR(32672) that specifies the value to beassigned.

out_value_sizeAn input argument of type INTEGER that specifies the length limit for the IN

282 SQL Procedural Languages: Application Enablement and Support

Page 293: IBM DB2 9.7 for Linux, UNIX, And Windows

or INOUT argument, and the maximum length of the output value for theINOUT or OUT argument. If it is not specified, the length of value is assumed.

Authorization

EXECUTE privilege on the DBMS_SQL module.

CLOSE_CURSOR procedure - Close a cursorThe CLOSE_CURSOR procedure closes an open cursor. The resources allocated tothe cursor are released and it cannot no longer be used.

Syntax

�� CLOSE_CURSOR ( c ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorto be closed.

Authorization

EXECUTE privilege on the DBMS_SQL module.

Examples

Example 1: This example illustrates closing a previously opened cursor.DECLARE

curid INTEGER;BEGIN

curid := DBMS_SQL.OPEN_CURSOR;...

DBMS_SQL.CLOSE_CURSOR(curid);END;

COLUMN_VALUE_BLOB procedure - Return a BLOB column value intoa variable

The COLUMN_VALUE_BLOB procedure defines a variable that will receive aBLOB value from a cursor.

Syntax

�� COLUMN_VALUE_BLOB ( c , position , value ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorthat is returning data to the variable being defined.

positionAn input argument of type INTEGER that specifies the position of the returneddata within the cursor. The first value in the cursor is position 1.

Chapter 26. DBMS_SQL module 283

Page 294: IBM DB2 9.7 for Linux, UNIX, And Windows

valueAn output argument of type BLOB(2G) that specifies the variable receiving thedata returned by the cursor in a prior fetch call.

Authorization

EXECUTE privilege on the DBMS_SQL module.

COLUMN_VALUE_CHAR procedure - Return a CHAR column value intoa variable

The COLUMN_VALUE_CHAR procedure defines a variable to receive a CHARvalue from a cursor.

Syntax

�� COLUMN_VALUE_CHAR ( c , position , value �

� [ , column_error [ , actual_length ] ] ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorthat is returning data to the variable being defined.

positionAn input argument of type INTEGER that specifies the position of the returneddata within the cursor. The first value in the cursor is position 1.

valueAn output argument of type CHAR that specifies the variable receiving thedata returned by the cursor in a prior fetch call.

column_errorAn optional output argument of type INTEGER that returns the SQLCODE, ifany, associated with the column.

actual_lengthAn optional output argument of type INTEGER that returns the actual lengthof the data, prior to any truncation.

Authorization

EXECUTE privilege on the DBMS_SQL module.

COLUMN_VALUE_CLOB procedure - Return a CLOB column value intoa variable

The COLUMN_VALUE_CLOB procedure defines a variable that will receive aCLOB value from a cursor.

Syntax

�� COLUMN_VALUE_CLOB ( c , position , value ��

284 SQL Procedural Languages: Application Enablement and Support

Page 295: IBM DB2 9.7 for Linux, UNIX, And Windows

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorthat is returning data to the variable being defined.

positionAn input argument of type INTEGER that specifies the position of the returneddata within the cursor. The first value in the cursor is position 1.

valueAn output argument of type CLOB(2G) that specifies the variable receiving thedata returned by the cursor in a prior fetch call.

Authorization

EXECUTE privilege on the DBMS_SQL module.

COLUMN_VALUE_DATE procedure - Return a DATE column value intoa variable

The COLUMN_VALUE_DATE procedure defines a variable that will receive aDATE value from a cursor.

Syntax

�� COLUMN_VALUE_DATE ( c , position , value �

� [ , column_error [ , actual_length ] ] ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorthat is returning data to the variable being defined.

positionAn input argument of type INTEGER that specifies the position of the returneddata within the cursor. The first value in the cursor is position 1.

valueAn output argument of type DATE that specifies the variable receiving thedata returned by the cursor in a prior fetch call.

column_errorAn output argument of type INTEGER that returns the SQLCODE, if any,associated with the column.

actual_lengthAn output argument of type INTEGER that returns the actual length of thedata, prior to any truncation.

Authorization

EXECUTE privilege on the DBMS_SQL module.

Chapter 26. DBMS_SQL module 285

Page 296: IBM DB2 9.7 for Linux, UNIX, And Windows

COLUMN_VALUE_DOUBLE procedure - Return a DOUBLE columnvalue into a variable

The COLUMN_VALUE_DOUBLE procedure defines a variable that will receive aDOUBLE value from a cursor.

Syntax

�� COLUMN_VALUE_DOUBLE ( c , position , value �

� [ , column_error [ , actual_length ] ] ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorthat is returning data to the variable being defined.

positionAn input argument of type INTEGER that specifies the position of the returneddata within the cursor. The first value in the cursor is position 1.

valueAn output argument of type DOUBLE that specifies the variable receiving thedata returned by the cursor in a prior fetch call.

column_errorAn output argument of type INTEGER that returns the SQLCODE, if any,associated with the column.

actual_lengthAn output argument of type INTEGER that returns the actual length of thedata, prior to any truncation.

Authorization

EXECUTE privilege on the DBMS_SQL module.

COLUMN_VALUE_INT procedure - Return an INTEGER column valueinto a variable

The COLUMN_VALUE_INT procedure defines a variable that will receive aINTEGER value from a cursor.

Syntax

�� COLUMN_VALUE_INT ( c , position , value �

� [ , column_error [ , actual_length ] ] ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorthat is returning data to the variable being defined.

positionAn input argument of type INTEGER that specifies the position of the returneddata within the cursor. The first value in the cursor is position 1.

286 SQL Procedural Languages: Application Enablement and Support

Page 297: IBM DB2 9.7 for Linux, UNIX, And Windows

valueAn output argument of type INTEGER that specifies the variable receiving thedata returned by the cursor in a prior fetch call.

column_errorAn output argument of type INTEGER that returns the SQLCODE, if any,associated with the column.

actual_lengthAn output argument of type INTEGER that returns the actual length of thedata, prior to any truncation.

Authorization

EXECUTE privilege on the DBMS_SQL module.

COLUMN_VALUE_LONG procedure - Return a LONG column value intoa variable

The COLUMN_VALUE_LONG procedure defines a variable that will receive aportion of a LONG value from a cursor.

Syntax

�� COLUMN_VALUE_LONG ( c , position , length , �

� offset , value , value_length ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorthat is returning data to the variable being defined.

positionAn input argument of type INTEGER that specifies the position of the returneddata within the cursor. The first value in the cursor is position 1.

lengthAn input argument of type INTEGER that specifies the desired number ofbytes of the LONG data to retrieve beginning at offset.

offsetAn input argument of type INTEGER that specifies the position within theLONG value to start data retrieval.

valueAn output argument of type CLOB(32760) that specifies the variable receivingthe data returned by the cursor in a prior fetch call.

value_lengthAn output argument of type INTEGER that returns the actual length of thedata returned.

Authorization

EXECUTE privilege on the DBMS_SQL module.

Chapter 26. DBMS_SQL module 287

Page 298: IBM DB2 9.7 for Linux, UNIX, And Windows

COLUMN_VALUE_NUMBER procedure - Return a DECFLOAT columnvalue into a variable

The COLUMN_VALUE_NUMBER procedure defines a variable that will receive aDECFLOAT value from a cursor.

Syntax

�� COLUMN_VALUE_NUMBER ( c , position , value �

� [ , column_error [ , actual_length ] ] ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorthat is returning data to the variable being defined.

positionAn input argument of type INTEGER that specifies the position of the returneddata within the cursor. The first value in the cursor is position 1.

valueAn output argument of type DECFLOAT that specifies the variable receivingthe data returned by the cursor in a prior fetch call.

column_errorAn optional output argument of type INTEGER that returns the SQLCODE, ifany, associated with the column.

actual_lengthAn optional output argument of type INTEGER that returns the actual lengthof the data, prior to any truncation.

Authorization

EXECUTE privilege on the DBMS_SQL module.

COLUMN_VALUE_RAW procedure - Return a RAW column value into avariable

The COLUMN_VALUE_RAW procedure defines a variable that will receive a RAWvalue from a cursor.

Syntax

�� COLUMN_VALUE_RAW ( c , position , value �

� [ , column_error [ , actual_length ] ] ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorthat is returning data to the variable being defined.

positionAn input argument of type INTEGER that specifies the position of the returneddata within the cursor. The first value in the cursor is position 1.

288 SQL Procedural Languages: Application Enablement and Support

Page 299: IBM DB2 9.7 for Linux, UNIX, And Windows

valueAn output argument of type BLOB(32767) that specifies the variable receivingthe data returned by the cursor in a prior fetch call.

column_errorAn optional output argument of type INTEGER that returns the SQLCODE, ifany, associated with the column.

actual_lengthAn optional output argument of type INTEGER that returns the actual lengthof the data, prior to any truncation.

Authorization

EXECUTE privilege on the DBMS_SQL module.

COLUMN_VALUE_TIMESTAMP procedure - Return a TIMESTAMPcolumn value into a variable

The COLUMN_VALUE_TIMESTAMP procedure defines a variable that will receivea TIMESTAMP value from a cursor.

Syntax

�� COLUMN_VALUE_TIMESTAMP ( c , position , value �

� [ , column_error [ , actual_length ] ] ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorthat is returning data to the variable being defined.

positionAn input argument of type INTEGER that specifies the position of the returneddata within the cursor. The first value in the cursor is position 1.

valueAn output argument of type TIMESTAMP that specifies the variable receivingthe data returned by the cursor in a prior fetch call.

column_errorAn output argument of type INTEGER that returns the SQLCODE, if any,associated with the column.

actual_lengthAn output argument of type INTEGER that returns the actual length of thedata, prior to any truncation.

Authorization

EXECUTE privilege on the DBMS_SQL module.

COLUMN_VALUE_VARCHAR procedure - Return a VARCHAR columnvalue into a variable

The COLUMN_VALUE_VARCHAR procedure defines a variable that will receive aVARCHAR value from a cursor.

Chapter 26. DBMS_SQL module 289

Page 300: IBM DB2 9.7 for Linux, UNIX, And Windows

Syntax

�� COLUMN_VALUE_VARCHAR ( c , position , value �

� [ , column_error [ , actual_length ] ] ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorthat is returning data to the variable being defined.

positionAn input argument of type INTEGER that specifies the position of the returneddata within the cursor. The first value in the cursor is position 1.

valueAn output argument of type VARCHAR(32672) that specifies the variablereceiving the data returned by the cursor in a prior fetch call.

column_errorAn output argument of type INTEGER that returns the SQLCODE, if any,associated with the column.

actual_lengthAn output argument of type INTEGER that returns the actual length of thedata, prior to any truncation.

Authorization

EXECUTE privilege on the DBMS_SQL module.

DEFINE_COLUMN_BLOB- Define a BLOB column in the SELECT listThe DEFINE_COLUMN_BLOB procedure defines a BLOB column or expression inthe SELECT list that is to be returned and retrieved in a cursor.

Syntax

�� DEFINE_COLUMN_BLOB ( c , position , column ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor handleassociated with the SELECT command.

positionAn input argument of type INTEGER that specifies the position of the columnor expression in the SELECT list that is being defined.

columnAn input argument of type BLOB(2G).

Authorization

EXECUTE privilege on the DBMS_SQL module.

290 SQL Procedural Languages: Application Enablement and Support

Page 301: IBM DB2 9.7 for Linux, UNIX, And Windows

DEFINE_COLUMN_CHAR procedure - Define a CHAR column in theSELECT list

The DEFINE_COLUMN_CHAR procedure defines a CHAR column or expressionin the SELECT list that is to be returned and retrieved in a cursor.

Syntax

�� DEFINE_COLUMN_CHAR ( c , position , column , column_size ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor handleassociated with the SELECT command.

positionAn input argument of type INTEGER that specifies the position of the columnor expression in the SELECT list that is being defined.

columnAn input argument of type CHAR(254).

column_sizeAn input argument of type INTEGER that specifies the maximum length of thereturned data. Returned data exceeding column_size is truncated to column_sizecharacters.

Authorization

EXECUTE privilege on the DBMS_SQL module.

DEFINE_COLUMN_CLOB - Define a CLOB column in the SELECT listThe DEFINE_COLUMN_CLOB procedure defines a CLOB column or expression inthe SELECT list that is to be returned and retrieved in a cursor.

Syntax

�� DEFINE_COLUMN_CLOB ( c , position , column ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor handleassociated with the SELECT command.

positionAn input argument of type INTEGER that specifies the position of the columnor expression in the SELECT list that is being defined.

columnAn input argument of type CLOB(2G).

Authorization

EXECUTE privilege on the DBMS_SQL module.

Chapter 26. DBMS_SQL module 291

Page 302: IBM DB2 9.7 for Linux, UNIX, And Windows

DEFINE_COLUMN_DATE - Define a DATE column in the SELECT listThe DEFINE_COLUMN_DATE procedure defines a DATE column or expression inthe SELECT list that is to be returned and retrieved in a cursor.

Syntax

�� DEFINE_COLUMN_DATE ( c , position , column ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor handleassociated with the SELECT command.

positionAn input argument of type INTEGER that specifies the position of the columnor expression in the SELECT list that is being defined.

columnAn input argument of type DATE.

Authorization

EXECUTE privilege on the DBMS_SQL module.

DEFINE_COLUMN_DOUBLE - Define a DOUBLE column in the SELECTlist

The DEFINE_COLUMN_DOUBLE procedure defines a DOUBLE column orexpression in the SELECT list that is to be returned and retrieved in a cursor.

Syntax

�� DEFINE_COLUMN_DOUBLE ( c , position , column ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor handleassociated with the SELECT command.

positionAn input argument of type INTEGER that specifies the position of the columnor expression in the SELECT list that is being defined.

columnAn input argument of type DOUBLE.

Authorization

EXECUTE privilege on the DBMS_SQL module.

DEFINE_COLUMN_INT- Define an INTEGER column in the SELECT listThe DEFINE_COLUMN_INT procedure defines an INTEGER column or expressionin the SELECT list that is to be returned and retrieved in a cursor.

292 SQL Procedural Languages: Application Enablement and Support

Page 303: IBM DB2 9.7 for Linux, UNIX, And Windows

Syntax

�� DEFINE_COLUMN_INT ( c , position , column ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor handleassociated with the SELECT command.

positionAn input argument of type INTEGER that specifies the position of the columnor expression in the SELECT list that is being defined.

columnAn input argument of type INTEGER.

Authorization

EXECUTE privilege on the DBMS_SQL module.

DEFINE_COLUMN_LONG procedure - Define a LONG column in theSELECT list

The DEFINE_COLUMN_LONG procedure defines a LONG column or expressionin the SELECT list that is to be returned and retrieved in a cursor.

Syntax

�� DEFINE_COLUMN_LONG ( c , position ��

Parameters

c An input argument of type INTEGER that specifies the cursor handleassociated with the SELECT command.

positionAn input argument of type INTEGER that specifies the position of the columnor expression in the SELECT list that is being defined.

Authorization

EXECUTE privilege on the DBMS_SQL module.

DEFINE_COLUMN_NUMBER procedure - Define a DECFLOAT columnin the SELECT list

The DEFINE_COLUMN_NUMBER procedure defines a DECFLOAT column orexpression in the SELECT list that is to be returned and retrieved in a cursor.

Syntax

�� DEFINE_COLUMN_NUMBER ( c , position , column ) ��

Chapter 26. DBMS_SQL module 293

Page 304: IBM DB2 9.7 for Linux, UNIX, And Windows

Parameters

c An input argument of type INTEGER that specifies the cursor handleassociated with the SELECT command.

positionAn input argument of type INTEGER that specifies the position of the columnor expression in the SELECT list that is being defined.

columnAn input argument of type DECFLOAT.

Authorization

EXECUTE privilege on the DBMS_SQL module.

DEFINE_COLUMN_RAW procedure - Define a RAW column orexpression in the SELECT list

The DEFINE_COLUMN_RAW procedure defines a RAW column or expression inthe SELECT list that is to be returned and retrieved in a cursor.

Syntax

�� DEFINE_COLUMN_RAW ( c , position , column , column_size ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor handleassociated with the SELECT command.

positionAn input argument of type INTEGER that specifies the position of the columnor expression in the SELECT list that is being defined.

columnAn input argument of type BLOB(32767).

column_sizeAn input argument of type INTEGER that specifies the maximum length of thereturned data. Returned data exceeding column_size is truncated to column_sizecharacters.

Authorization

EXECUTE privilege on the DBMS_SQL module.

DEFINE_COLUMN_TIMESTAMP - Define a TIMESTAMP column in theSELECT list

The DEFINE_COLUMN_TIMESTAMP procedure defines a TIMESTAMP column orexpression in the SELECT list that is to be returned and retrieved in a cursor.

Syntax

�� DEFINE_COLUMN_TIMESTAMP ( c , position , column ) ��

294 SQL Procedural Languages: Application Enablement and Support

Page 305: IBM DB2 9.7 for Linux, UNIX, And Windows

Parameters

c An input argument of type INTEGER that specifies the cursor handleassociated with the SELECT command.

positionAn input argument of type INTEGER that specifies the position of the columnor expression in the SELECT list that is being defined.

columnAn input argument of type TIMESTAMP.

Authorization

EXECUTE privilege on the DBMS_SQL module.

DEFINE_COLUMN_VARCHAR procedure - Define a VARCHAR columnin the SELECT list

The DEFINE_COLUMN_VARCHAR procedure defines a VARCHAR column orexpression in the SELECT list that is to be returned and retrieved in a cursor.

Syntax

�� DEFINE_COLUMN_VARCHAR ( c , position , column , column_size ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor handleassociated with the SELECT command.

positionAn input argument of type INTEGER that specifies the position of the columnor expression in the SELECT list that is being defined.

columnAn input argument of type VARCHAR(32672).

column_sizeAn input argument of type INTEGER that specifies the maximum length of thereturned data. Returned data exceeding column_size is truncated to column_sizecharacters.

Authorization

EXECUTE privilege on the DBMS_SQL module.

DESCRIBE_COLUMNS procedure - Retrieve a description of thecolumns in a SELECT list

The DESCRIBE_COLUMNS procedure provides the capability to retrieve adescription of the columns in a SELECT list from a cursor.

Syntax

�� DESCRIBE_COLUMNS ( c , col_cnt , desc_tab ) ��

Chapter 26. DBMS_SQL module 295

Page 306: IBM DB2 9.7 for Linux, UNIX, And Windows

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorwhose columns are to be described.

col_cntAn output argument of type INTEGER that returns the number of columns inthe SELECT list of the cursor.

desc_tabAn output argument of type DESC_TAB that describes the column metadata.The DESC_TAB array provides information on each column in the specifiedcursor.

Authorization

EXECUTE privilege on the DBMS_SQL module.

Usage notes

This procedure requires a user temporary table space with a page size of 4K;otherwise it returns an SQL0286N error. You can create the user temporary tablespace with this command:CREATE USER TEMPORARY TABLESPACE DBMS_SQL_TEMP_TBS

DESC_TAB is an array of DESC_REC records of column information:

Table 24. DESC_TAB definition through DESC_REC records

Record name Description

col_type SQL data type as defined in Supported SQLdata types in C and C++ embedded SQLapplications.

col_max_len Maximum length of the column.

col_name Column name.

col_name_len Length of the column name.

col_schema Always NULL.

col_schema_name_len Always NULL.

col_precision Precision of the column as defined in thedatabase. If col_type denotes a graphic orDBCLOB SQL data type, then this variableindicates the maximum number ofdouble-byte characters the column can hold.

col_scale Scale of the column as defined in thedatabase (only applies to DECIMAL,NUMERIC, TIMESTAMP).

col_charsetid Always NULL.

col_charsetform Always NULL.

col_null_ok Nullable indicator. This has a value of 1 ifthe column is nullable, otherwise, 0.

ALTER MODULE SYSIBMADM.DBMS_SQL PUBLISH TYPE DESC_REC AS ROW(

col_type INTEGER,col_max_len INTEGER,col_name VARCHAR(128),

296 SQL Procedural Languages: Application Enablement and Support

Page 307: IBM DB2 9.7 for Linux, UNIX, And Windows

col_name_len INTEGER,col_schema_name VARCHAR(128),col_schema_name_len INTEGER,col_precision INTEGER,col_scale INTEGER,col_charsetid INTEGER,col_charsetform INTEGER,col_null_ok INTEGER

);

ALTER MODULE SYSIBMADM.DBMS_SQL PUBLISH TYPE DESC_TAB AS DESC_REC ARRAY[INTEGER];

Examples

Example 1: The following example describes the empno, ename, hiredate, and salcolumns from the ″EMP″ table.

SET SERVEROUTPUT ON@

BEGINDECLARE handle INTEGER;DECLARE col_cnt INTEGER;DECLARE col DBMS_SQL.DESC_TAB;DECLARE i INTEGER DEFAULT 1;DECLARE CUR1 CURSOR FOR S1;

CALL DBMS_SQL.OPEN_CURSOR( handle );CALL DBMS_SQL.PARSE( handle,

'SELECT empno, firstnme, lastname, salaryFROM employee', DBMS_SQL.NATIVE );

CALL DBMS_SQL.DESCRIBE_COLUMNS( handle, col_cnt, col );

IF col_cnt > 0 THENCALL DBMS_OUTPUT.PUT_LINE( 'col_cnt = ' || col_cnt );CALL DBMS_OUTPUT.NEW_LINE();fetchLoop: LOOP

IF i > col_cnt THENLEAVE fetchLoop;

END IF;

CALL DBMS_OUTPUT.PUT_LINE( 'i = ' || i );CALL DBMS_OUTPUT.PUT_LINE( 'col[i].col_name = ' || col[i].col_name );CALL DBMS_OUTPUT.PUT_LINE( 'col[i].col_name_len = ' ||

NVL(col[i].col_name_len, 'NULL') );CALL DBMS_OUTPUT.PUT_LINE( 'col[i].col_schema_name = ' ||

NVL( col[i].col_schema_name, 'NULL' ) );

IF col[i].col_schema_name_len IS NULL THENCALL DBMS_OUTPUT.PUT_LINE( 'col[i].col_schema_name_len = NULL' );

ELSECALL DBMS_OUTPUT.PUT_LINE( 'col[i].col_schema_name_len = ' ||

col[i].col_schema_name_len);END IF;

CALL DBMS_OUTPUT.PUT_LINE( 'col[i].col_type = ' || col[i].col_type );CALL DBMS_OUTPUT.PUT_LINE( 'col[i].col_max_len = ' || col[i].col_max_len );CALL DBMS_OUTPUT.PUT_LINE( 'col[i].col_precision = ' || col[i].col_precision );CALL DBMS_OUTPUT.PUT_LINE( 'col[i].col_scale = ' || col[i].col_scale );

IF col[i].col_charsetid IS NULL THENCALL DBMS_OUTPUT.PUT_LINE( 'col[i].col_charsetid = NULL' );

ELSECALL DBMS_OUTPUT.PUT_LINE( 'col[i].col_charsetid = ' || col[i].col_charsetid );

END IF;

IF col[i].col_charsetform IS NULL THENCALL DBMS_OUTPUT.PUT_LINE( 'col[i].col_charsetform = NULL' );

Chapter 26. DBMS_SQL module 297

Page 308: IBM DB2 9.7 for Linux, UNIX, And Windows

ELSECALL DBMS_OUTPUT.PUT_LINE( 'col[i].col_charsetform = ' || col[i].col_charsetform );

END IF;

CALL DBMS_OUTPUT.PUT_LINE( 'col[i].col_null_ok = ' || col[i].col_null_ok );CALL DBMS_OUTPUT.NEW_LINE();SET i = i + 1;

END LOOP;END IF;

END@

Output:col_cnt = 4

i = 1col[i].col_name = EMPNOcol[i].col_name_len = 5col[i].col_schema_name = NULLcol[i].col_schema_name_len = NULLcol[i].col_type = 452col[i].col_max_len = 6col[i].col_precision = 6col[i].col_scale = 0col[i].col_charsetid = NULLcol[i].col_charsetform = NULLcol[i].col_null_ok = 0

i = 2col[i].col_name = FIRSTNMEcol[i].col_name_len = 8col[i].col_schema_name = NULLcol[i].col_schema_name_len = NULLcol[i].col_type = 448col[i].col_max_len = 12col[i].col_precision = 12col[i].col_scale = 0col[i].col_charsetid = NULLcol[i].col_charsetform = NULLcol[i].col_null_ok = 0

i = 3col[i].col_name = LASTNAMEcol[i].col_name_len = 8col[i].col_schema_name = NULLcol[i].col_schema_name_len = NULLcol[i].col_type = 448col[i].col_max_len = 15col[i].col_precision = 15col[i].col_scale = 0col[i].col_charsetid = NULLcol[i].col_charsetform = NULLcol[i].col_null_ok = 0

i = 4col[i].col_name = SALARYcol[i].col_name_len = 6col[i].col_schema_name = NULLcol[i].col_schema_name_len = NULLcol[i].col_type = 484col[i].col_max_len = 5col[i].col_precision = 9col[i].col_scale = 2col[i].col_charsetid = NULLcol[i].col_charsetform = NULLcol[i].col_null_ok = 1

298 SQL Procedural Languages: Application Enablement and Support

Page 309: IBM DB2 9.7 for Linux, UNIX, And Windows

DESCRIBE_COLUMNS2 procedure - Retrieve a description of columnnames in a SELECT list

The DESCRIBE_COLUMNS2 procedure provides the capability to retrieve adescription of the columns in a SELECT list from a cursor.

Syntax

�� DESCRIBE_COLUMNS ( c , col_cnt , desc_tab2 ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorwhose columns are to be described.

col_cntAn output argument of type INTEGER that returns the number of columns inthe SELECT list of the cursor.

desc_tabAn output argument of type DESC_TAB2 that describes the column metadata.The DESC_TAB2 array provides information on each column in the specifiedcursor

Authorization

EXECUTE privilege on the DBMS_SQL module.

Usage notes

This procedure requires a user temporary table space with a page size of 4K;otherwise it returns an SQL0286N error. You can create the user temporary tablespace with this command:CREATE USER TEMPORARY TABLESPACE DBMS_SQL_TEMP_TBS

DESC_TAB2 is an array of DESC_REC2 records of column information:

Table 25. DESC_TAB2 definition through DESC_REC2 records

Record name Description

col_type SQL data type as defined in Supported SQLdata types in C and C++ embedded SQLapplications.

col_max_len Maximum length of the column.

col_name Column name.

col_name_len Length of the column name.

col_schema Always NULL.

col_schema_name_len Always NULL.

col_precision Precision of the column as defined in thedatabase. If col_type denotes a graphic orDBCLOB SQL data type, then this variableindicates the maximum number ofdouble-byte characters the column can hold.

Chapter 26. DBMS_SQL module 299

Page 310: IBM DB2 9.7 for Linux, UNIX, And Windows

Table 25. DESC_TAB2 definition through DESC_REC2 records (continued)

Record name Description

col_scale Scale of the column as defined in thedatabase (only applies to DECIMAL,NUMERIC, TIMESTAMP).

col_charsetid Always NULL.

col_charsetform Always NULL.

col_null_ok Nullable indicator. This has a value of 1 ifthe column is nullable, otherwise, 0.

ALTER MODULE SYSIBMADM.DBMS_SQL PUBLISH TYPE DESC_REC2 AS ROW(col_type INTEGER,col_max_len INTEGER,col_name VARCHAR(128),col_name_len INTEGER,col_schema_name VARCHAR(128),col_schema_name_len INTEGER,col_precision INTEGER,col_scale INTEGER,col_charsetid INTEGER,col_charsetform INTEGER,col_null_ok INTEGER);

ALTER MODULE SYSIBMADM.DBMS_SQL PUBLISH TYPE DESC_TAB2 AS DESC_REC2 ARRAY[INTEGER];

EXECUTE procedure - Run a parsed SQL statementThe EXECUTE function executes a parsed SQL statement.

Syntax

�� EXECUTE ( c , ret ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the parsedSQL statement to be executed.

ret An output argument of type INTEGER that returns the number of rowsprocessed if the SQL command is DELETE, INSERT, or UPDATE; otherwise itreturns 0.

Authorization

EXECUTE privilege on the DBMS_SQL module.

Usage notes

This procedure can be invoked using function invocation syntax in a PL/SQLassignment statement.

Examples

Example 1: The following anonymous block inserts a row into the ″DEPT″ table.

300 SQL Procedural Languages: Application Enablement and Support

Page 311: IBM DB2 9.7 for Linux, UNIX, And Windows

SET SERVEROUTPUT ON@

CREATE TABLE dept (deptno DECIMAL(2) NOT NULL CONSTRAINT dept_pk PRIMARY KEY,dname VARCHAR(14) NOT NULL,loc VARCHAR(13),CONSTRAINT dept_dname_uq UNIQUE( deptno, dname )

)@

BEGINDECLARE curid INTEGER;DECLARE v_sql VARCHAR(50);DECLARE v_status INTEGER;

CALL DBMS_SQL.OPEN_CURSOR(curid);SET v_sql = 'INSERT INTO dept VALUES (50, ''HR'', ''LOS ANGELES'')';CALL DBMS_SQL.PARSE(curid, v_sql, DBMS_SQL.native);CALL DBMS_SQL.EXECUTE(curid, v_status);CALL DBMS_OUTPUT.PUT_LINE('Number of rows processed: ' || v_status);CALL DBMS_SQL.CLOSE_CURSOR(curid);

END@

This example results in the following output:SET SERVEROUTPUT ONDB20000I The SET SERVEROUTPUT command completed successfully.

CREATE TABLE dept( deptno DECIMAL(2) NOT NULL CONSTRAINT dept_pk PRIMARY KEY,

dname VARCHAR(14) NOT NULL,loc VARCHAR(13),CONSTRAINT dept_dname_uq UNIQUE( deptno, dname ) )

DB20000I The SQL command completed successfully.

BEGINDECLARE curid INTEGER;DECLARE v_sql VARCHAR(50);DECLARE v_status INTEGER;

CALL DBMS_SQL.OPEN_CURSOR(curid);SET v_sql = 'INSERT INTO dept VALUES (50, ''HR'', ''LOS ANGELES'')';CALL DBMS_SQL.PARSE(curid, v_sql, DBMS_SQL.native);CALL DBMS_SQL.EXECUTE(curid, v_status);CALL DBMS_OUTPUT.PUT_LINE('Number of rows processed: ' || v_status);CALL DBMS_SQL.CLOSE_CURSOR(curid);

ENDDB20000I The SQL command completed successfully.

Number of rows processed: 1

EXECUTE_AND_FETCH procedure - Run a parsed SELECT commandand fetch one row

Function EXECUTE_AND_FETCH executes a parsed SELECT command andfetches one row.

Syntax

�� EXECUTE_AND_FETCH ( c, exact

, ret ) ��

Chapter 26. DBMS_SQL module 301

Page 312: IBM DB2 9.7 for Linux, UNIX, And Windows

Parameters

c An input argument of type INTEGER that specifies the cursor id of the cursorfor the SELECT command to be executed.

exactAn optional argument of type INTEGER. If set to 1, an exception is thrown ifthe number of rows in the result set is not exactly equal to 1. If set to 0, noexception is thrown. The default is 0. A NO_DATA_FOUND (SQL0100W)exception is thrown if exact is set to 1 and there are no rows in the result set. ATOO_MANY_ROWS (SQL0811N) exception is thrown if exact is set to 1 andthere is more than one row in the result set.

ret An output argument of type INTEGER that returns 1 if a row was fetchedsuccessfully, 0 if there are no rows to fetch.

Authorization

EXECUTE privilege on the DBMS_SQL module.

Usage notes

This procedure can be invoked using function invocation syntax in a PL/SQLassignment statement.

Examples

Example 1: The following stored procedure uses the EXECUTE_AND_FETCHfunction to retrieve one employee using the employee’s name. An exception will bethrown if the employee is not found, or there is more than one employee with thesame name.SET SERVEROUTPUT ON@

CREATE TABLE emp (empno DECIMAL(4) NOT NULL CONSTRAINT emp_pk PRIMARY KEY,ename VARCHAR(10),job VARCHAR(9),mgr DECIMAL(4),hiredate TIMESTAMP(0),sal DECIMAL(7,2) CONSTRAINT emp_sal_ck CHECK (sal > 0),comm DECIMAL(7,2) )@

INSERT INTO emp VALUES (7369,'SMITH','CLERK',7902,'1980-12-17',800,NULL)@INSERT INTO emp VALUES (7499,'ALLEN','SALESMAN',7698,'1981-02-20',1600,300)@INSERT INTO emp VALUES (7521,'WARD','SALESMAN',7698,'1981-02-22',1250,500)@INSERT INTO emp VALUES (7566,'JONES','MANAGER',7839,'1981-04-02',2975,NULL)@INSERT INTO emp VALUES (7654,'MARTIN','SALESMAN',7698,'1981-09-28',1250,1400)@

CREATE OR REPLACE PROCEDURE select_by_name(IN p_ename ANCHOR TO emp.ename)BEGIN

DECLARE curid INTEGER;DECLARE v_empno ANCHOR TO emp.empno;DECLARE v_hiredate ANCHOR TO emp.hiredate;DECLARE v_sal ANCHOR TO emp.sal;DECLARE v_comm ANCHOR TO emp.comm;DECLARE v_disp_date VARCHAR(10);DECLARE v_sql VARCHAR(120);DECLARE v_status INTEGER;SET v_sql = 'SELECT empno, hiredate, sal, NVL(comm, 0)

FROM emp e WHERE ename = :p_ename ';CALL DBMS_SQL.OPEN_CURSOR(curid);

302 SQL Procedural Languages: Application Enablement and Support

Page 313: IBM DB2 9.7 for Linux, UNIX, And Windows

CALL DBMS_SQL.PARSE(curid, v_sql, DBMS_SQL.native);CALL DBMS_SQL.BIND_VARIABLE_VARCHAR(curid, ':p_ename', UPPER(p_ename));CALL DBMS_SQL.DEFINE_COLUMN_NUMBER(curid, 1, v_empno);CALL DBMS_SQL.DEFINE_COLUMN_DATE(curid, 2, v_hiredate);CALL DBMS_SQL.DEFINE_COLUMN_NUMBER(curid, 3, v_sal);CALL DBMS_SQL.DEFINE_COLUMN_NUMBER(curid, 4, v_comm);CALL DBMS_SQL.EXECUTE_AND_FETCH(curid, 1 /*True*/, v_status);CALL DBMS_SQL.COLUMN_VALUE_NUMBER(curid, 1, v_empno);CALL DBMS_SQL.COLUMN_VALUE_DATE(curid, 2, v_hiredate);CALL DBMS_SQL.COLUMN_VALUE_NUMBER(curid, 3, v_sal);CALL DBMS_SQL.COLUMN_VALUE_NUMBER(curid, 4, v_comm);SET v_disp_date = TO_CHAR(v_hiredate, 'MM/DD/YYYY');CALL DBMS_OUTPUT.PUT_LINE('Number : ' || v_empno);CALL DBMS_OUTPUT.PUT_LINE('Name : ' || UPPER(p_ename));CALL DBMS_OUTPUT.PUT_LINE('Hire Date : ' || v_disp_date);CALL DBMS_OUTPUT.PUT_LINE('Salary : ' || v_sal);CALL DBMS_OUTPUT.PUT_LINE('Commission: ' || v_comm);CALL DBMS_SQL.CLOSE_CURSOR(curid);

END@

CALL select_by_name( 'MARTIN' )@

This example results in the following output:SET SERVEROUTPUT ONDB20000I The SET SERVEROUTPUT command completed successfully.

CREATE TABLE emp( empno DECIMAL(4) NOT NULL CONSTRAINT emp_pk PRIMARY KEY,

ename VARCHAR(10),job VARCHAR(9),mgr DECIMAL(4),hiredate TIMESTAMP(0),sal DECIMAL(7,2) CONSTRAINT emp_sal_ck CHECK (sal > 0),comm DECIMAL(7,2) )

DB20000I The SQL command completed successfully.

INSERT INTO emp VALUES (7369,'SMITH','CLERK',7902,'1980-12-17',800,NULL)DB20000I The SQL command completed successfully.

INSERT INTO emp VALUES (7499,'ALLEN','SALESMAN',7698,'1981-02-20',1600,300)DB20000I The SQL command completed successfully.

INSERT INTO emp VALUES (7521,'WARD','SALESMAN',7698,'1981-02-22',1250,500)DB20000I The SQL command completed successfully.

INSERT INTO emp VALUES (7566,'JONES','MANAGER',7839,'1981-04-02',2975,NULL)DB20000I The SQL command completed successfully.

INSERT INTO emp VALUES (7654,'MARTIN','SALESMAN',7698,'1981-09-28',1250,1400)DB20000I The SQL command completed successfully.

CREATE OR REPLACE PROCEDURE select_by_name(IN p_ename ANCHOR TO emp.ename)BEGIN

DECLARE curid INTEGER;DECLARE v_empno ANCHOR TO emp.empno;DECLARE v_hiredate ANCHOR TO emp.hiredate;DECLARE v_sal ANCHOR TO emp.sal;DECLARE v_comm ANCHOR TO emp.comm;DECLARE v_disp_date VARCHAR(10);DECLARE v_sql VARCHAR(120);DECLARE v_status INTEGER;SET v_sql = 'SELECT empno, hiredate, sal, NVL(comm, 0)

FROM emp e WHERE ename = :p_ename ';CALL DBMS_SQL.OPEN_CURSOR(curid);CALL DBMS_SQL.PARSE(curid, v_sql, DBMS_SQL.native);

Chapter 26. DBMS_SQL module 303

Page 314: IBM DB2 9.7 for Linux, UNIX, And Windows

CALL DBMS_SQL.BIND_VARIABLE_VARCHAR(curid, ':p_ename', UPPER(p_ename));CALL DBMS_SQL.DEFINE_COLUMN_NUMBER(curid, 1, v_empno);CALL DBMS_SQL.DEFINE_COLUMN_DATE(curid, 2, v_hiredate);CALL DBMS_SQL.DEFINE_COLUMN_NUMBER(curid, 3, v_sal);CALL DBMS_SQL.DEFINE_COLUMN_NUMBER(curid, 4, v_comm);CALL DBMS_SQL.EXECUTE_AND_FETCH(curid, 1 /*True*/, v_status);CALL DBMS_SQL.COLUMN_VALUE_NUMBER(curid, 1, v_empno);CALL DBMS_SQL.COLUMN_VALUE_DATE(curid, 2, v_hiredate);CALL DBMS_SQL.COLUMN_VALUE_NUMBER(curid, 3, v_sal);CALL DBMS_SQL.COLUMN_VALUE_NUMBER(curid, 4, v_comm);SET v_disp_date = TO_CHAR(v_hiredate, 'MM/DD/YYYY');CALL DBMS_OUTPUT.PUT_LINE('Number : ' || v_empno);CALL DBMS_OUTPUT.PUT_LINE('Name : ' || UPPER(p_ename));CALL DBMS_OUTPUT.PUT_LINE('Hire Date : ' || v_disp_date);CALL DBMS_OUTPUT.PUT_LINE('Salary : ' || v_sal);CALL DBMS_OUTPUT.PUT_LINE('Commission: ' || v_comm);CALL DBMS_SQL.CLOSE_CURSOR(curid);

ENDDB20000I The SQL command completed successfully.

CALL select_by_name( 'MARTIN' )

Return Status = 0

Number : 7654Name : MARTINHire Date : 09/28/1981Salary : 1250.00Commission: 1400.00

FETCH_ROWS procedure - Retrieve a row from a cursorThe FETCH_ROWS function retrieves a row from a cursor

Syntax

�� FETCH_ROWS ( c , ret ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorfrom which to fetch a row.

ret An output argument of type INTEGER that returns 1 if a row was fetchedsuccessfully, 0 if there are no rows to fetch.

Authorization

EXECUTE privilege on the DBMS_SQL module.

Usage notes

This procedure can be invoked using function invocation syntax in a PL/SQLassignment statement.

Examples

Example 1: The following examples fetches the rows from the ″EMP″ table anddisplays the results.

304 SQL Procedural Languages: Application Enablement and Support

Page 315: IBM DB2 9.7 for Linux, UNIX, And Windows

DECLAREcurid INTEGER;v_empno NUMBER(4);v_ename VARCHAR2(10);v_hiredate DATE;v_sal NUMBER(7,2);v_comm NUMBER(7,2);v_sql VARCHAR2(50) := 'SELECT empno, ename, hiredate, sal, ' ||

'comm FROM emp';v_status INTEGER;

BEGINcurid := DBMS_SQL.OPEN_CURSOR;DBMS_SQL.PARSE(curid,v_sql,DBMS_SQL.native);DBMS_SQL.DEFINE_COLUMN_NUMBER(curid,1,v_empno);DBMS_SQL.DEFINE_COLUMN_VARCHAR(curid,2,v_ename,10);DBMS_SQL.DEFINE_COLUMN_DATE(curid,3,v_hiredate);DBMS_SQL.DEFINE_COLUMN_NUMBER(curid,4,v_sal);DBMS_SQL.DEFINE_COLUMN_NUMBER(curid,5,v_comm);

v_status := DBMS_SQL.EXECUTE(curid);DBMS_OUTPUT.PUT_LINE('EMPNO ENAME HIREDATE SAL COMM');DBMS_OUTPUT.PUT_LINE('----- ---------- ---------- -------- ' ||

'--------');LOOP

v_status := DBMS_SQL.FETCH_ROWS(curid);EXIT WHEN v_status = 0;DBMS_SQL.COLUMN_VALUE_NUMBER(curid,1,v_empno);DBMS_SQL.COLUMN_VALUE_VARCHAR(curid,2,v_ename);DBMS_SQL.COLUMN_VALUE_DATE(curid,3,v_hiredate);DBMS_SQL.COLUMN_VALUE_NUMBER(curid,4,v_sal);DBMS_SQL.COLUMN_VALUE_NUMBER(curid,5,v_comm);DBMS_OUTPUT.PUT_LINE(v_empno || ' ' || RPAD(v_ename,10) || ' ' ||

TO_CHAR(v_hiredate,'yyyy-mm-dd') || ' ' ||TO_CHAR(v_sal,'9,999.99') || ' ' ||TO_CHAR(NVL(v_comm,0),'9,999.99'));

END LOOP;DBMS_SQL.CLOSE_CURSOR(curid);

END;

EMPNO ENAME HIREDATE SAL COMM----- ---------- ---------- -------- --------7369 SMITH 1980-12-17 800.00 .007499 ALLEN 1981-02-20 1,600.00 300.007521 WARD 1981-02-22 1,250.00 500.007566 JONES 1981-04-02 2,975.00 .007654 MARTIN 1981-09-28 1,250.00 1,400.007698 BLAKE 1981-05-01 2,850.00 .007782 CLARK 1981-06-09 2,450.00 .007788 SCOTT 1987-04-19 3,000.00 .007839 KING 1981-11-17 5,000.00 .007844 TURNER 1981-09-08 1,500.00 .007876 ADAMS 1987-05-23 1,100.00 .007900 JAMES 1981-12-03 950.00 .007902 FORD 1981-12-03 3,000.00 .007934 MILLER 1982-01-23 1,300.00 .00

IS_OPEN procedure - Check if a cursor is openThe IS_OPEN function provides the capability to test if the given cursor is open.

Syntax

�� IS_OPEN ( c , ret ) ��

Chapter 26. DBMS_SQL module 305

Page 316: IBM DB2 9.7 for Linux, UNIX, And Windows

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorto be tested.

ret An output argument of type INTEGER that returns 1 if the cursor is open,otherwise 0.

Authorization

EXECUTE privilege on the DBMS_SQL module.

Usage notes

This procedure can be invoked using function invocation syntax in a PL/SQLassignment statement.

LAST_ROW_COUNT procedure - return the cumulative number of rowsfetched

The LAST_ROW_COUNT procedure returns the number of rows that have beenfetched.

Syntax

�� LAST_ROW_COUNT ( ret ) ��

Parameters

ret An output argument of type INTEGER that returns the number of rows thathave been fetched so far in the current session. A call to DBMS_SQL.PARSEresets the counter.

Authorization

EXECUTE privilege on the DBMS_SQL module.

Usage notes

This procedure can be invoked using function invocation syntax in a PL/SQLassignment statement.

Examples

Example 1: The following example uses the LAST_ROW_COUNT procedure todisplay the total number of rows fetched in the query.DECLARE

curid INTEGER;v_empno NUMBER(4);v_ename VARCHAR2(10);v_hiredate DATE;v_sal NUMBER(7,2);v_comm NUMBER(7,2);v_sql VARCHAR2(50) := 'SELECT empno, ename, hiredate, sal, ' ||

'comm FROM emp';v_status INTEGER;

BEGINcurid := DBMS_SQL.OPEN_CURSOR;

306 SQL Procedural Languages: Application Enablement and Support

Page 317: IBM DB2 9.7 for Linux, UNIX, And Windows

DBMS_SQL.PARSE(curid,v_sql,DBMS_SQL.native);DBMS_SQL.DEFINE_COLUMN_NUMBER(curid,1,v_empno);DBMS_SQL.DEFINE_COLUMN_VARCHAR(curid,2,v_ename,10);DBMS_SQL.DEFINE_COLUMN_DATE(curid,3,v_hiredate);DBMS_SQL.DEFINE_COLUMN_NUMBER(curid,4,v_sal);DBMS_SQL.DEFINE_COLUMN_NUMBER(curid,5,v_comm);

v_status := DBMS_SQL.EXECUTE(curid);DBMS_OUTPUT.PUT_LINE('EMPNO ENAME HIREDATE SAL COMM');DBMS_OUTPUT.PUT_LINE('----- ---------- ---------- -------- ' ||

'--------');LOOP

v_status := DBMS_SQL.FETCH_ROWS(curid);EXIT WHEN v_status = 0;DBMS_SQL.COLUMN_VALUE_NUMBER(curid,1,v_empno);DBMS_SQL.COLUMN_VALUE_VARCHAR(curid,2,v_ename);DBMS_SQL.COLUMN_VALUE_DATE(curid,3,v_hiredate);DBMS_SQL.COLUMN_VALUE_NUMBER(curid,4,v_sal);DBMS_SQL.COLUMN_VALUE_NUMBER(curid,5,v_comm);DBMS_OUTPUT.PUT_LINE(v_empno || ' ' || RPAD(v_ename,10) || ' ' ||

TO_CHAR(v_hiredate,'yyyy-mm-dd') || ' ' ||TO_CHAR(v_sal,'9,999.99') || ' ' ||TO_CHAR(NVL(v_comm,0),'9,999.99'));

END LOOP;DBMS_OUTPUT.PUT_LINE('Number of rows: ' || DBMS_SQL.LAST_ROW_COUNT);DBMS_SQL.CLOSE_CURSOR(curid);

END;

EMPNO ENAME HIREDATE SAL COMM----- ---------- ---------- -------- --------7369 SMITH 1980-12-17 800.00 .007499 ALLEN 1981-02-20 1,600.00 300.007521 WARD 1981-02-22 1,250.00 500.007566 JONES 1981-04-02 2,975.00 .007654 MARTIN 1981-09-28 1,250.00 1,400.007698 BLAKE 1981-05-01 2,850.00 .007782 CLARK 1981-06-09 2,450.00 .007788 SCOTT 1987-04-19 3,000.00 .007839 KING 1981-11-17 5,000.00 .007844 TURNER 1981-09-08 1,500.00 .007876 ADAMS 1987-05-23 1,100.00 .007900 JAMES 1981-12-03 950.00 .007902 FORD 1981-12-03 3,000.00 .007934 MILLER 1982-01-23 1,300.00 .00Number of rows: 14

OPEN_CURSOR procedure - Open a cursorThe OPEN_CURSOR procedure creates a new cursor.

A cursor must be used to parse and execute any dynamic SQL statement. Once acursor has been opened, it can be used again with the same or different SQLstatements. The cursor does not have to be closed and reopened in order to beused again.

Syntax

�� OPEN_CURSOR ( c ) ��

Parameters

c An output argument of type INTEGER that specifies the cursor ID of thenewly created cursor.

Chapter 26. DBMS_SQL module 307

Page 318: IBM DB2 9.7 for Linux, UNIX, And Windows

Authorization

EXECUTE privilege on the DBMS_SQL module.

Usage notes

This procedure can be invoked using function invocation syntax in a PL/SQLassignment statement.

Examples

Example 1: The following example creates a new cursor:DECLARE

curid INTEGER;BEGIN

curid := DBMS_SQL.OPEN_CURSOR;...

END;

PARSE procedure - Parse an SQL statementThe PARSE procedure parses an SQL statement.

If the SQL command is a DDL command, it is immediately executed and does notrequire running the EXECUTE procedure.

Syntax

�� PARSE ( c , statement , language_flag ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID of an opencursor.

statementThe SQL statement to be parsed.

language_flagThis argument is provided for Oracle syntax compatibility. Use a value of 1 orDBMS_SQL.native.

Authorization

EXECUTE privilege on the DBMS_SQL module.

Usage notes

This procedure can be invoked using function invocation syntax in a PL/SQLassignment statement.

308 SQL Procedural Languages: Application Enablement and Support

Page 319: IBM DB2 9.7 for Linux, UNIX, And Windows

Examples

Example 1: The following anonymous block creates a table named job. Note thatDDL statements are executed immediately by the PARSE procedure and do notrequire a separate EXECUTE step.SET SERVEROUTPUT ON@

BEGINDECLARE curid INTEGER;CALL DBMS_SQL.OPEN_CURSOR(curid);CALL DBMS_SQL.PARSE(curid, 'CREATE TABLE job (jobno DECIMAL(3),

' || 'jname VARCHAR(9))', DBMS_SQL.native);CALL DBMS_SQL.CLOSE_CURSOR(curid);

END@

This example results in the following output:SET SERVEROUTPUT ONDB20000I The SET SERVEROUTPUT command completed successfully.

BEGINDECLARE curid INTEGER;CALL DBMS_SQL.OPEN_CURSOR(curid);CALL DBMS_SQL.PARSE(curid, 'CREATE TABLE job (jobno DECIMAL(3), ' ||

'jname VARCHAR(9))', DBMS_SQL.native);CALL DBMS_SQL.CLOSE_CURSOR(curid);

ENDDB20000I The SQL command completed successfully.

Example 2: The following inserts two rows into the job table.BEGIN

DECLARE curid INTEGER;DECLARE v_sql VARCHAR(50);DECLARE v_status INTEGER;

CALL DBMS_SQL.OPEN_CURSOR(curid);SET v_sql = 'INSERT INTO job VALUES (100, ''ANALYST'')';CALL DBMS_SQL.PARSE(curid, v_sql, DBMS_SQL.native);CALL DBMS_SQL.EXECUTE(curid, v_status);CALL DBMS_OUTPUT.PUT_LINE('Number of rows processed: ' || v_status);SET v_sql = 'INSERT INTO job VALUES (200, ''CLERK'')';CALL DBMS_SQL.PARSE(curid, v_sql, DBMS_SQL.native);CALL DBMS_SQL.EXECUTE(curid, v_status);CALL DBMS_OUTPUT.PUT_LINE('Number of rows processed: ' || v_status);CALL DBMS_SQL.CLOSE_CURSOR(curid);

END@

This example results in the following output:BEGIN

DECLARE curid INTEGER;DECLARE v_sql VARCHAR(50);DECLARE v_status INTEGER;

CALL DBMS_SQL.OPEN_CURSOR(curid);SET v_sql = 'INSERT INTO job VALUES (100, ''ANALYST'')';CALL DBMS_SQL.PARSE(curid, v_sql, DBMS_SQL.native);CALL DBMS_SQL.EXECUTE(curid, v_status);CALL DBMS_OUTPUT.PUT_LINE('Number of rows processed: ' || v_status);SET v_sql = 'INSERT INTO job VALUES (200, ''CLERK'')';CALL DBMS_SQL.PARSE(curid, v_sql, DBMS_SQL.native);CALL DBMS_SQL.EXECUTE(curid, v_status);CALL DBMS_OUTPUT.PUT_LINE('Number of rows processed: ' || v_status);CALL DBMS_SQL.CLOSE_CURSOR(curid);

END

Chapter 26. DBMS_SQL module 309

Page 320: IBM DB2 9.7 for Linux, UNIX, And Windows

DB20000I The SQL command completed successfully.

Number of rows processed: 1Number of rows processed: 1

Example 3: The following anonymous block uses the DBMS_SQL module to executea block containing two INSERT statements. Note that the end of the block containsa terminating semicolon, whereas in the prior examples, the individual INSERTstatements did not have a terminating semicolon.BEGIN

DECLARE curid INTEGER;DECLARE v_sql VARCHAR(100);DECLARE v_status INTEGER;

CALL DBMS_SQL.OPEN_CURSOR(curid);SET v_sql = 'BEGIN ' || 'INSERT INTO job VALUES (300, ''MANAGER''); '

|| 'INSERT INTO job VALUES (400, ''SALESMAN''); ' || 'END;';CALL DBMS_SQL.PARSE(curid, v_sql, DBMS_SQL.native);CALL DBMS_SQL.CLOSE_CURSOR(curid);

END@

This example results in the following output:BEGIN

DECLARE curid INTEGER;DECLARE v_sql VARCHAR(100);DECLARE v_status INTEGER;

CALL DBMS_SQL.OPEN_CURSOR(curid);SET v_sql = 'BEGIN ' || 'INSERT INTO job VALUES (300, ''MANAGER''); ' ||

'INSERT INTO job VALUES (400, ''SALESMAN''); ' || 'END;';CALL DBMS_SQL.PARSE(curid, v_sql, DBMS_SQL.native);CALL DBMS_SQL.CLOSE_CURSOR(curid);

ENDDB20000I The SQL command completed successfully.

VARIABLE_VALUE_BLOB procedure - Return the value of a BLOBINOUT or OUT parameter

The VARIABLE_VALUE_BLOB procedure provides the capability to return thevalue of a BLOB INOUT or OUT parameter.

Syntax

�� VARIABLE_VALUE_BLOB ( c , name , value ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorreturning a bind variable.

nameAn input argument that specifies the name of the bind variable.

valueAn output argument of type BLOB(2G) that specifies the variable receiving thevalue.

Authorization

EXECUTE privilege on the DBMS_SQL module.

310 SQL Procedural Languages: Application Enablement and Support

Page 321: IBM DB2 9.7 for Linux, UNIX, And Windows

VARIABLE_VALUE_CHAR procedure - Return the value of a CHARINOUT or OUT parameter

The VARIABLE_VALUE_CHAR procedure provides the capability to return thevalue of a CHAR INOUT or OUT parameter.

Syntax

�� VARIABLE_VALUE_CHAR ( c , name , value ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorreturning a bind variable.

nameAn input argument that specifies the name of the bind variable.

valueAn output argument of type CHAR(254) that specifies the variable receivingthe value.

Authorization

EXECUTE privilege on the DBMS_SQL module.

VARIABLE_VALUE_CLOB procedure - Return the value of a CLOBINOUT or OUT parameter

The VARIABLE_VALUE_CLOB procedure provides the capability to return thevalue of a CLOB INOUT or OUT parameter.

Syntax

�� VARIABLE_VALUE_CLOB ( c , name , value ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorreturning a bind variable.

nameAn input argument that specifies the name of the bind variable.

valueAn output argument of type CLOB(2G) that specifies the variable receiving thevalue.

Authorization

EXECUTE privilege on the DBMS_SQL module.

Chapter 26. DBMS_SQL module 311

Page 322: IBM DB2 9.7 for Linux, UNIX, And Windows

VARIABLE_VALUE_DATE procedure - Return the value of a DATEINOUT or OUT parameter

The VARIABLE_VALUE_DATE procedure provides the capability to return thevalue of a DATE INOUT or OUT parameter.

Syntax

�� VARIABLE_VALUE_DATE ( c , name , value ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorreturning a bind variable.

nameAn input argument that specifies the name of the bind variable.

valueAn output argument of type DATE that specifies the variable receiving thevalue.

Authorization

EXECUTE privilege on the DBMS_SQL module.

VARIABLE_VALUE_DOUBLE procedure - Return the value of aDOUBLE INOUT or OUT parameter

The VARIABLE_VALUE_DOUBLE procedure provides the capability to return thevalue of a DOUBLE INOUT or OUT parameter.

Syntax

�� VARIABLE_VALUE_DOUBLE ( c , name , value ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorreturning a bind variable.

nameAn input argument that specifies the name of the bind variable.

valueAn output argument of type DOUBLE that specifies the variable receiving thevalue.

Authorization

EXECUTE privilege on the DBMS_SQL module.

312 SQL Procedural Languages: Application Enablement and Support

Page 323: IBM DB2 9.7 for Linux, UNIX, And Windows

VARIABLE_VALUE_INT procedure - Return the value of an INTEGERINOUT or OUT parameter

The VARIABLE_VALUE_INT procedure provides the capability to return the valueof a INTEGER INOUT or OUT parameter.

Syntax

�� VARIABLE_VALUE_INT ( c , name , value ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorreturning a bind variable.

nameAn input argument that specifies the name of the bind variable.

valueAn output argument of type INTEGER that specifies the variable receiving thevalue.

Authorization

EXECUTE privilege on the DBMS_SQL module.

VARIABLE_VALUE_NUMBER procedure - Return the value of aDECFLOAT INOUT or OUT parameter

The VARIABLE_VALUE_NUMBER procedure provides the capability to return thevalue of a DECFLOAT INOUT or OUT parameter.

Syntax

�� VARIABLE_VALUE_NUMBER ( c , name , value ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorreturning a bind variable.

nameAn input argument that specifies the name of the bind variable.

valueAn output argument of type DECFLOAT that specifies the variable receivingthe value.

Authorization

EXECUTE privilege on the DBMS_SQL module.

Chapter 26. DBMS_SQL module 313

Page 324: IBM DB2 9.7 for Linux, UNIX, And Windows

VARIABLE_VALUE_RAW procedure - Return the value of aBLOB(32767) INOUT or OUT parameter

The VARIABLE_VALUE_RAW procedure provides the capability to return thevalue of a BLOB(32767) INOUT or OUT parameter.

Syntax

�� VARIABLE_VALUE_RAW ( c , name , value ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorreturning a bind variable.

nameAn input argument that specifies the name of the bind variable.

valueAn output argument of type BLOB(32767) that specifies the variable receivingthe value.

Authorization

EXECUTE privilege on the DBMS_SQL module.

VARIABLE_VALUE_TIMESTAMP procedure - Return the value of aTIMESTAMP INOUT or OUT parameter

The VARIABLE_VALUE_TIMESTAMP procedure provides the capability to returnthe value of a TIMESTAMP INOUT or OUT parameter.

Syntax

�� VARIABLE_VALUE_TIMESTAMP ( c , name , value ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorreturning a bind variable.

nameAn input argument that specifies the name of the bind variable.

valueAn output argument of type TIMESTAMP that specifies the variable receivingthe value.

Authorization

EXECUTE privilege on the DBMS_SQL module.

314 SQL Procedural Languages: Application Enablement and Support

Page 325: IBM DB2 9.7 for Linux, UNIX, And Windows

VARIABLE_VALUE_VARCHAR procedure - Return the value of aVARCHAR INOUT or OUT parameter

The VARIABLE_VALUE_VARCHAR procedure provides the capability to returnthe value of a VARCHAR INOUT or OUT parameter.

Syntax

�� VARIABLE_VALUE_VARCHAR ( c , name , value ) ��

Parameters

c An input argument of type INTEGER that specifies the cursor ID of the cursorreturning a bind variable.

nameAn input argument that specifies the name of the bind variable.

valueAn output argument of type VARCHAR(32672) that specifies the variablereceiving the value.

Authorization

EXECUTE privilege on the DBMS_SQL module.

Chapter 26. DBMS_SQL module 315

Page 326: IBM DB2 9.7 for Linux, UNIX, And Windows

316 SQL Procedural Languages: Application Enablement and Support

Page 327: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 27. DBMS_UTILITY module

The DBMS_UTILITY module provides various utility programs.

The schema for this module is SYSIBMADM.

The DBMS_UTILITY module includes the following routines.

Table 26. System-defined routines available in the DBMS_UTILITY module

Routine Name Description

ANALYZE_DATABASE procedure Analyze database tables, clusters, andindexes.

ANALYZE_PART_OBJECT procedure Analyze a partitioned table or partitionedindex.

ANALYZE_SCHEMA procedure Analyze schema tables, clusters, andindexes.

CANONICALIZE procedure Canonicalizes a string (for example, stripsoff white space).

COMMA_TO_TABLE procedure Convert a comma-delimited list of names toa table of names.

COMPILE_SCHEMA procedure Compile programs in a schema.

DB_VERSION procedure Get the database version.

EXEC_DDL_STATEMENT procedure Execute a DDL statement.

GET_CPU_TIME function Get the current CPU time.

GET_DEPENDENCY procedure Get objects that depend on the given object.

GET_HASH_VALUE function Compute a hash value.

GET_TIME function Get the current time.

NAME_RESOLVE procedure Resolve the given name.

NAME_TOKENIZE procedure Parse the given name into its componentparts.

TABLE_TO_COMMA procedure Convert a table of names to acomma-delimited list.

VALIDATE procedure Make an invalid database object valid.

The following table lists the system-defined variables and types available in theDBMS_UTILITY module.

Table 27. DBMS_UTILITY public variables

Public variables Data type Description

lname_array TABLE For lists of long names.

uncl_array TABLE For lists of users and names.

The LNAME_ARRAY is for storing lists of long names including fully-qualifiednames.

ALTER MODULE SYSIBMADM.DBMS_UTILITY PUBLISH TYPE LNAME_ARRAY AS VARCHAR(4000) ARRAY[];

© Copyright IBM Corp. 1993, 2009 317

Page 328: IBM DB2 9.7 for Linux, UNIX, And Windows

The UNCL_ARRAY is for storing lists of users and names.ALTER MODULE SYSIBMADM.DBMS_UTILITY PUBLISH TYPE UNCL_ARRAY AS VARCHAR(227) ARRAY[];

ANALYZE_DATABASE procedure - Gather statistics on tables, clusters,and indexes

The ANALYZE_DATABASE procedure provides the capability to gather statisticson tables, clusters, and indexes in the database.

Syntax

�� ANALYZE_DATABASE ( method [ , estimate_rows [ , estimate_percent �

� [ , method_opt ] ] ] ) ��

Parameters

methodAn input argument of type VARCHAR(128) that specifies the type of analyzefunctionality to perform. Valid values are:v ESTIMATE - gather estimated statistics based upon on either a specified

number of rows in estimate_rows or a percentage of rows in estimate_percent;v COMPUTE - compute exact statistics; orv DELETE – delete statistics from the data dictionary.

estimate_rowsAn optional input argument of type INTEGER that specifies the number ofrows on which to base estimated statistics. One of estimate_rows orestimate_percent must be specified if the method is ESTIMATE. The default valueis NULL.

estimate_percentAn optional input argument of type INTEGER that specifies the percentage ofrows upon which to base estimated statistics. One of estimate_rows orestimate_percent must be specified if the method is ESTIMATE. The default valueis NULL.

method_optAn optional input argument of type VARCHAR(1024) that specifies the objecttypes to be analyzed. Any combination of the following keywords are valid:v [FOR TABLE]v [FOR ALL [ INDEXED ] COLUMNS ] [ SIZE n ]v [FOR ALL INDEXES]

The default is NULL.

Authorization

EXECUTE privilege on the DBMS_UTILITY module.

ANALYZE_PART_OBJECT procedure - Gather statistics on apartitioned table or partitioned index

The ANALYZE_PART_OBJECT procedure provides the capability to gatherstatistics on a partitioned table or index.

318 SQL Procedural Languages: Application Enablement and Support

Page 329: IBM DB2 9.7 for Linux, UNIX, And Windows

Syntax

�� ANALYZE_PART_OBJECT ( schema , object_name [ , object_type [ , �

� command_type [ , command_opt [ , sample_clause ] ] ] ] ) ��

Parameters

schemaAn input argument of type VARCHAR(128) that specifies the schema name ofthe schema whose objects are to be analyzed.

object_nameAn input argument of type VARCHAR(128) that specifies the name of thepartitioned object to be analyzed.

object_typeAn optional input argument of type CHAR that specifies the type of object tobe analyzed. Valid values are:v T – table;v I – index.

The default is T.

command_typeAn optional input argument of type CHAR that specifies the type of analyzefunctionality to perform. Valid values are:v E - gather estimated statistics based upon on a specified number of rows or

a percentage of rows in the sample_clause clause;v C - compute exact statistics; orv V - validate the structure and integrity of the partitions.

The default value is E.

command_optAn optional input argument of type VARCHAR(1024) that specifies the optionsfor the statistics calculation. For command_type E or C, this argument can beany combination of:v [ FOR TABLE ]v [ FOR ALL COLUMNS ]v [ FOR ALL LOCAL INDEXES ]

For command_type V, this argument can be CASCADE if object_type is T. Thedefault value is NULL.

sample_clauseAn optional input argument of type VARCHAR(128). If command_type is E, thisargument contains the following clause to specify the number of rows orpercentage of rows on which to base the estimate.SAMPLE n { ROWS | PERCENT }

The default value is SAMPLE 5 PERCENT.

Authorization

EXECUTE privilege on the DBMS_UTILITY module.

Chapter 27. DBMS_UTILITY module 319

Page 330: IBM DB2 9.7 for Linux, UNIX, And Windows

ANALYZE_SCHEMA procedure - Gather statistics on schema tables,clusters, and indexes

The ANALYZE_SCHEMA procedure provides the capability to gather statistics ontables, clusters, and indexes in the specified schema.

Syntax

�� ANALYZE_SCHEMA ( schema , method [ , estimate_rows [ , estimate_percent �

� [ , method_opt ] ] ] ) ��

Parameters

schemaAn input argument of type VARCHAR(128) that specifies the schema name ofthe schema whose objects are to be analyzed.

methodAn input argument of type VARCHAR(128) that specifies the type of analyzefunctionality to perform. Valid values are:v ESTIMATE - gather estimated statistics based upon on either a specified

number of rows in estimate_rows or a percentage of rows in estimate_percent;v COMPUTE - compute exact statistics; orv DELETE – delete statistics from the data dictionary.

estimate_rowsAn optional input argument of type INTEGER that specifies the number ofrows on which to base estimated statistics. One of estimate_rows orestimate_percent must be specified if the method is ESTIMATE. The default valueis NULL.

estimate_percentAn optional input argument of type INTEGER that specifies the percentage ofrows upon which to base estimated statistics. One of estimate_rows orestimate_percent must be specified if the method is ESTIMATE. The default valueis NULL.

method_optAn optional input argument of type VARCHAR(1024) that specifies the objecttypes to be analyzed. Any combination of the following keywords are valid:v [FOR TABLE]v [FOR ALL [ INDEXED ] COLUMNS ] [ SIZE n ]v [FOR ALL INDEXES]

The default is NULL.

Authorization

EXECUTE privilege on the DBMS_UTILITY module.

CANONICALIZE procedure - Canonicalize a stringThe CANONICALIZE procedure performs various operations on an input string.

The CANONICALIZE procedure performs the following operations on an inputstring:

320 SQL Procedural Languages: Application Enablement and Support

Page 331: IBM DB2 9.7 for Linux, UNIX, And Windows

v If the string is not double-quoted, verifies that it uses the characters of a legalidentifier. If not, an exception is thrown. If the string is double-quoted, allcharacters are allowed.

v If the string is not double-quoted and does not contain periods, puts allalphabetic characters into uppercase and eliminates leading and trailing spaces.

v If the string is double-quoted and does not contain periods, strips off the doublequotes.

v If the string contains periods and no portion of the string is double-quoted, putseach portion of the string into uppercase and encloses each portion in doublequotes.

v If the string contains periods and portions of the string are double-quoted,returns the double-quoted portions unchanged, including the double quotes, andreturns the non-double-quoted portions in uppercase and enclosed in doublequotes.

Syntax

�� CANONICALIZE ( name , canon_name , canon_len ) ��

Parameters

nameAn input argument of type VARCHAR(1024) that specifies the string to becanonicalized.

canon_nameAn output argument of type VARCHAR(1024) that returns the canonicalizedstring.

canon_lenAn input argument of type INTEGER that specifies the number of bytes inname to canonicalize starting from the first character.

Authorization

EXECUTE privilege on the DBMS_UTILITY module.

Examples

Example 1: The following procedure applies the CANONICALIZE procedure on itsinput parameter and displays the results.CREATE OR REPLACE PROCEDURE canonicalize (

p_name VARCHAR2,p_length BINARY_INTEGER DEFAULT 30

)IS

v_canon VARCHAR2(100);BEGIN

DBMS_UTILITY.CANONICALIZE(p_name,v_canon,p_length);DBMS_OUTPUT.PUT_LINE('Canonicalized name ==>' || v_canon || '<==');DBMS_OUTPUT.PUT_LINE('Length: ' || LENGTH(v_canon));

EXCEPTIONWHEN OTHERS THEN

DBMS_OUTPUT.PUT_LINE('SQLERRM: ' || SQLERRM);DBMS_OUTPUT.PUT_LINE('SQLCODE: ' || SQLCODE);

END;/

Chapter 27. DBMS_UTILITY module 321

Page 332: IBM DB2 9.7 for Linux, UNIX, And Windows

CALL canonicalize('Identifier')Canonicalized name ==>IDENTIFIER<==Length: 10

CALL canonicalize('"Identifier"')Canonicalized name ==>Identifier<==Length: 10

CALL canonicalize('"_+142%"')Canonicalized name ==>_+142%<==Length: 6

CALL canonicalize('abc.def.ghi')Canonicalized name ==>"ABC"."DEF"."GHI"<==Length: 17

CALL canonicalize('"abc.def.ghi"')Canonicalized name ==>abc.def.ghi<==Length: 11

CALL canonicalize('"abc".def."ghi"')Canonicalized name ==>"abc"."DEF"."ghi"<==Length: 17

CALL canonicalize('"abc.def".ghi')Canonicalized name ==>"abc.def"."GHI"<==Length: 15

COMMA_TO_TABLE procedures - Convert a comma-delimited list ofnames into a table of names

The COMMA_TO_TABLE procedure converts a comma-delimited list of namesinto an array of names. Each entry in the list becomes an element in the array.

Note: The names must be formatted as valid identifiers.

Syntax

�� COMMA_TO_TABLE_LNAME ( list , tablen , tab ) ��

�� COMMA_TO_TABLE_UNCL ( list , tablen , tab ) ��

Parameters

listAn input argument of type VARCHAR(32672) that specifies a comma-delimitedlist of names.

tablenAn output argument of type INTEGER that specifies the number of entries intab.

tab An output argument of type LNAME_ARRAY or UNCL_ARRAY that containsa table of the individual names in list. See LNAME_ARRAY or UNCL_ARRAYfor a description of tab.

Authorization

EXECUTE privilege on the DBMS_UTILITY module.

322 SQL Procedural Languages: Application Enablement and Support

Page 333: IBM DB2 9.7 for Linux, UNIX, And Windows

Examples

Example 1: The following procedure uses the COMMA_TO_TABLE_LNAMEprocedure to convert a list of names to a table. The table entries are thendisplayed.CREATE OR REPLACE PROCEDURE comma_to_table (

p_list VARCHAR2)IS

r_lname DBMS_UTILITY.LNAME_ARRAY;v_length BINARY_INTEGER;

BEGINDBMS_UTILITY.COMMA_TO_TABLE_LNAME(p_list,v_length,r_lname);FOR i IN 1..v_length LOOP

DBMS_OUTPUT.PUT_LINE(r_lname(i));END LOOP;

END;

EXEC comma_to_table('sample_schema.dept, sample_schema.emp, sample_schema.jobhist')

sample_schema.deptsample_schema.empsample_schema.jobhist

COMPILE_SCHEMA procedure - Compile all functions, procedures,triggers, and packages in a schema

The COMPILE_SCHEMA procedure provides the capability to recompile allfunctions, procedures, triggers, and packages in a schema.

Syntax

�� COMPILE_SCHEMA ( schema [ , compile_all [ , reuse_settings ] ] ) ��

Parameters

schemaAn input argument of type VARCHAR(128) that specifies the schema in whichthe programs are to be recompiled.

compile_allAn optional input argument of type BOOLEAN that must be set to false,meaning that the procedure only recompiles programs currently in invalidstate.

reuse_settingsAn optional input argument of type BOOLEAN that must be set to false,meaning that the procedure uses the current session settings.

Authorization

EXECUTE privilege on the DBMS_UTILITY module.

DB_VERSION procedure - Retrieve the database versionThe DB_VERSION procedure returns the version number of the database.

Chapter 27. DBMS_UTILITY module 323

Page 334: IBM DB2 9.7 for Linux, UNIX, And Windows

Syntax

�� DB_VERSION ( version , compatibility ) ��

Parameters

versionAn output argument of type VARCHAR(1024) that returns the databaseversion number.

compatibilityAn output argument of type VARCHAR(1024) that returns the compatibilitysetting of the database.

Authorization

EXECUTE privilege on the DBMS_UTILITY module.

Examples

Example 1: The following anonymous block displays the database versioninformation.DECLARE

v_version VARCHAR2(80);v_compat VARCHAR2(80);

BEGINDBMS_UTILITY.DB_VERSION(v_version,v_compat);DBMS_OUTPUT.PUT_LINE('Version: ' || v_version);DBMS_OUTPUT.PUT_LINE('Compatibility: ' || v_compat);

END;/

Version: DB2 v9.7.0.0Compatibility: DB2 v9.7.0.0

EXEC_DDL_STATEMENT procedure - Run a DDL statementThe EXEC_DDL_STATEMENT procedure provides the capability to execute a DDLcommand.

Syntax

�� EXEC_DDL_STATEMENT ( parse_string ) ��

Parameters

parse_stringAn input argument of type VARCHAR(1024) that specifies the DDL commandto execute.

Authorization

EXECUTE privilege on the DBMS_UTILITY module.

Examples

Example 1: The following anonymous block creates the job table.

324 SQL Procedural Languages: Application Enablement and Support

Page 335: IBM DB2 9.7 for Linux, UNIX, And Windows

BEGINDBMS_UTILITY.EXEC_DDL_STATEMENT(

'CREATE TABLE job (' ||'jobno NUMBER(3),' ||'jname VARCHAR2(9))'

);END;

GET_CPU_TIME function - Retrieve the current CPU timeThe GET_CPU_TIME function returns the CPU time in hundredths of a secondfrom some arbitrary point in time.

Syntax

�� GET_CPU_TIME ( ) ��

Authorization

EXECUTE privilege on the DBMS_UTILITY module.

Examples

Example 1: The following SELECT command retrieves the current CPU time.SELECT DBMS_UTILITY.GET_CPU_TIME FROM DUAL;

get_cpu_time-------------

603

GET_DEPENDENCY procedure - List objects dependent on the givenobject

The GET_DEPENDENCY procedure provides the capability to list all objects thatare dependent upon the given object.

Syntax

�� GET_DEPENDENCY ( type , schema , name ) ��

Parameters

typeAn input argument of type VARCHAR(128) that specifies the object type ofname. Valid values are FUNCTION, INDEX, LOB, PACKAGE, PACKAGEBODY, PROCEDURE, SEQUENCE, TABLE, TRIGGER, and VIEW.

schemaAn input argument of type VARCHAR(128) that specifies the name of theschema in which name exists.

nameAn input argument of type VARCHAR(128) that specifies the name of theobject for which dependencies are to be obtained.

Chapter 27. DBMS_UTILITY module 325

Page 336: IBM DB2 9.7 for Linux, UNIX, And Windows

Authorization

EXECUTE privilege on the DBMS_UTILITY module.

Examples

Example 1: The following anonymous block finds dependencies on the ″EMP″ table.BEGIN

DBMS_UTILITY.GET_DEPENDENCY('TABLE','SAMPLE_SCHEMA','EMP');END;

DEPENDENCIES ON SAMPLE_SCHEMA.EMP------------------------------------------------------------------*TABLE SAMPLE_SCHEMA.EMP()* VIEW SAMPLE_SCHEMA.SALESEMP()* PROCEDURE SAMPLE_SCHEMA.LIST_EMP()* PROCEDURE SAMPLE_SCHEMA.SELECT_EMP()* PROCEDURE SAMPLE_SCHEMA.EMP_QUERY()* PROCEDURE SAMPLE_SCHEMA.EMP_QUERY_CALLER()* FUNCTION SAMPLE_SCHEMA.NEW_EMPNO()* FUNCTION SAMPLE_SCHEMA.HIRE_CLERK()* FUNCTION SAMPLE_SCHEMA.HIRE_CLERK()* TRIGGER SAMPLE_SCHEMA.USER_AUDIT_TRIG()* TRIGGER SAMPLE_SCHEMA.EMP_SAL_TRIG()* PACKAGE BODY SAMPLE_SCHEMA.EMP_ADMIN()

GET_HASH_VALUE function - Compute a hash value for a given stringThe GET_HASH_VALUE function provides the capability to compute a hash valuefor a given string.

The function returns a generated hash value of type INTEGER, and the value isplatform-dependent.

Syntax

�� GET_HASH_VALUE ( name , base , hash_size ) ��

Parameters

nameAn input argument of type VARCHAR(32672) that specifies the string forwhich a hash value is to be computed.

baseAn input argument of type INTEGER that specifies the Starting value at whichhash values are to be generated.

hash_sizeAn input argument of type INTEGER that specifies the number of hash valuesfor the desired hash table.

Authorization

EXECUTE privilege on the DBMS_UTILITY module.

326 SQL Procedural Languages: Application Enablement and Support

Page 337: IBM DB2 9.7 for Linux, UNIX, And Windows

Examples

Example 1: The following anonymous block creates a table of hash values using theename column of the ″EMP″ table and then displays the key along with the hashvalue. The hash values start at 100 with a maximum of 1024 distinct values.DECLARE

v_hash NUMBER;TYPE hash_tab IS TABLE OF NUMBER INDEX BY VARCHAR2(10);r_hash HASH_TAB;CURSOR emp_cur IS SELECT ename FROM emp;

BEGINFOR r_emp IN emp_cur LOOP

r_hash(r_emp.ename) :=DBMS_UTILITY.GET_HASH_VALUE(r_emp.ename,100,1024);

END LOOP;FOR r_emp IN emp_cur LOOP

DBMS_OUTPUT.PUT_LINE(RPAD(r_emp.ename,10) || ' ' ||r_hash(r_emp.ename));

END LOOP;END;/

SMITH 377ALLEN 740WARD 718JONES 131MARTIN 176BLAKE 568CLARK 621SCOTT 1097KING 235TURNER 850ADAMS 156JAMES 942FORD 775MILLER 148

GET_TIME function - Return the current timeThe GET_TIME function provides the capability to return the current time inhundredths of a second.

Syntax

�� GET_TIME ( ) ��

Authorization

EXECUTE privilege on the DBMS_UTILITY module.

Examples

Example 1: The following example shows calls to the GET_TIME function.SELECT DBMS_UTILITY.GET_TIME FROM DUAL;

get_time---------

1555860

SELECT DBMS_UTILITY.GET_TIME FROM DUAL;

Chapter 27. DBMS_UTILITY module 327

Page 338: IBM DB2 9.7 for Linux, UNIX, And Windows

get_time---------

1556037

NAME_RESOLVE procedure - Obtain the schema and othermembership information for a database object

The NAME_RESOLVE procedure provides the capability to obtain the schema andother membership information of a database object. Synonyms are resolved to theirbase objects.

Syntax

�� NAME_RESOLVE ( name , context , schema , part1 , �

� part2 , dblink , part1_type , object_number ) ��

Parameters

nameAn input argument of type VARCHAR(1024) that specifies the name of thedatabase object to resolve. Can be specified in the format:[[ a.]b.]c[@dblink ]

contextAn input argument of type INTEGER. Set to the following values:v 1 - to resolve a function, procedure, or module name;v 2 - to resolve a table, view, sequence, or synonym name; orv 3 - to resolve a trigger name.

schemaAn output argument of type VARCHAR(128) that specifies the name of theschema containing the object specified by name.

part1An output argument of type VARCHAR(128) that specifies the name of theresolved table, view, sequence, trigger, or module.

part2An output argument of type VARCHAR(128) that specifies the name of theresolved function or procedure (including functions and procedures within amodule).

dblinkAn output argument of type VARCHAR(128) that specifies name of thedatabase link (if @dblink is specified in name).

part1_typeAn output argument of type INTEGER. Returns the following values:v 2 - resolved object is a table;v 4 - resolved object is a view;v 6 - resolved object is a sequence;v 7 - resolved object is a stored procedure;v 8 - resolved object is a stored function;

328 SQL Procedural Languages: Application Enablement and Support

Page 339: IBM DB2 9.7 for Linux, UNIX, And Windows

v 9 - resolved object is a module or a function or procedure within a module;or

v 12 - resolved object is a trigger.

object_numberAn output argument of type INTEGER that specifies the object identifier of theresolved database object.

Authorization

EXECUTE privilege on the DBMS_UTILITY module.

Examples

Example 1: The following stored procedure is used to display the returned values ofthe NAME_RESOLVE procedure for various database objects.SET SERVEROUTPUT ON@

CREATE OR REPLACE PROCEDURE name_resolve(IN p_name VARCHAR(4096),IN p_context DECFLOAT )

BEGINDECLARE v_schema VARCHAR(30);DECLARE v_part1 VARCHAR(30);DECLARE v_part2 VARCHAR(30);DECLARE v_dblink VARCHAR(30);DECLARE v_part1_type DECFLOAT;DECLARE v_objectid DECFLOAT;

CALL DBMS_UTILITY.NAME_RESOLVE(p_name, p_context, v_schema, v_part1, v_part2,v_dblink, v_part1_type, v_objectid);

CALL DBMS_OUTPUT.PUT_LINE('name : ' || p_name);CALL DBMS_OUTPUT.PUT_LINE('context : ' || p_context);CALL DBMS_OUTPUT.PUT_LINE('schema : ' || v_schema);IF v_part1 IS NULL THEN

CALL DBMS_OUTPUT.PUT_LINE('part1 : NULL');ELSE

CALL DBMS_OUTPUT.PUT_LINE('part1 : ' || v_part1);END IF;IF v_part2 IS NULL THEN

CALL DBMS_OUTPUT.PUT_LINE('part2 : NULL');ELSE

CALL DBMS_OUTPUT.PUT_LINE('part2 : ' || v_part2);END IF;IF v_dblink IS NULL THEN

CALL DBMS_OUTPUT.PUT_LINE('dblink : NULL');ELSE

CALL DBMS_OUTPUT.PUT_LINE('dblink : ' || v_dblink);END IF;CALL DBMS_OUTPUT.PUT_LINE('part1 type: ' || v_part1_type);CALL DBMS_OUTPUT.PUT_LINE('object id : ' || v_objectid);

END@

DROP TABLE S1.T1@CREATE TABLE S1.T1 (C1 INT)@

CREATE OR REPLACE PROCEDURE S2.PROC1BEGINEND@

CREATE OR REPLACE MODULE S3.M1@ALTER MODULE S3.M1 PUBLISH FUNCTION F1() RETURNS BOOLEANBEGIN

RETURN TRUE;

Chapter 27. DBMS_UTILITY module 329

Page 340: IBM DB2 9.7 for Linux, UNIX, And Windows

END@

CALL NAME_RESOLVE( 'S1.T1', 2 )@CALL NAME_RESOLVE( 'S2.PROC1', 2 )@CALL NAME_RESOLVE( 'S2.PROC1', 1 )@CALL NAME_RESOLVE( 'PROC1', 1 )@CALL NAME_RESOLVE( 'M1', 1 )@CALL NAME_RESOLVE( 'S3.M1.F1', 1 )@

This example results in the following output:SET SERVEROUTPUT ONDB20000I The SET SERVEROUTPUT command completed successfully.

CREATE OR REPLACE PROCEDURE name_resolve(IN p_name VARCHAR(4096),IN p_context DECFLOAT )

BEGINDECLARE v_schema VARCHAR(30);DECLARE v_part1 VARCHAR(30);DECLARE v_part2 VARCHAR(30);DECLARE v_dblink VARCHAR(30);DECLARE v_part1_type DECFLOAT;DECLARE v_objectid DECFLOAT;

CALL DBMS_UTILITY.NAME_RESOLVE(p_name, p_context, v_schema, v_part1, v_part2,v_dblink, v_part1_type, v_objectid);

CALL DBMS_OUTPUT.PUT_LINE('name : ' || p_name);CALL DBMS_OUTPUT.PUT_LINE('context : ' || p_context);CALL DBMS_OUTPUT.PUT_LINE('schema : ' || v_schema);IF v_part1 IS NULL THEN

CALL DBMS_OUTPUT.PUT_LINE('part1 : NULL');ELSE

CALL DBMS_OUTPUT.PUT_LINE('part1 : ' || v_part1);END IF;IF v_part2 IS NULL THEN

CALL DBMS_OUTPUT.PUT_LINE('part2 : NULL');ELSE

CALL DBMS_OUTPUT.PUT_LINE('part2 : ' || v_part2);END IF;IF v_dblink IS NULL THEN

CALL DBMS_OUTPUT.PUT_LINE('dblink : NULL');ELSE

CALL DBMS_OUTPUT.PUT_LINE('dblink : ' || v_dblink);END IF;CALL DBMS_OUTPUT.PUT_LINE('part1 type: ' || v_part1_type);CALL DBMS_OUTPUT.PUT_LINE('object id : ' || v_objectid);

ENDDB20000I The SQL command completed successfully.

DROP TABLE S1.T1DB20000I The SQL command completed successfully.

CREATE TABLE S1.T1 (C1 INT)DB20000I The SQL command completed successfully.

CREATE OR REPLACE PROCEDURE S2.PROC1BEGINENDDB20000I The SQL command completed successfully.

CREATE OR REPLACE MODULE S3.M1DB20000I The SQL command completed successfully.

ALTER MODULE S3.M1 PUBLISH FUNCTION F1() RETURNS BOOLEANBEGIN

RETURN TRUE;

330 SQL Procedural Languages: Application Enablement and Support

Page 341: IBM DB2 9.7 for Linux, UNIX, And Windows

ENDDB20000I The SQL command completed successfully.

CALL NAME_RESOLVE( 'S1.T1', 2 )

Return Status = 0

name : S1.T1context : 2schema : S1part1 : T1part2 : NULLdblink : NULLpart1 type: 2object id : 8

CALL NAME_RESOLVE( 'S2.PROC1', 2 )SQL0204N "S2.PROC1" is an undefined name. SQLSTATE=42704

CALL NAME_RESOLVE( 'S2.PROC1', 1 )

Return Status = 0

name : S2.PROC1context : 1schema : S2part1 : PROC1part2 : NULLdblink : NULLpart1 type: 7object id : 66611

CALL NAME_RESOLVE( 'PROC1', 1 )

Return Status = 0

name : PROC1context : 1schema : S2part1 : NULLpart2 : PROC1dblink : NULLpart1 type: 7object id : 66611

CALL NAME_RESOLVE( 'M1', 1 )

Return Status = 0

name : M1context : 1schema : S3part1 : NULLpart2 : M1dblink : NULLpart1 type: 9object id : 16

CALL NAME_RESOLVE( 'S3.M1.F1', 1 )

Return Status = 0

name : S3.M1.F1context : 1schema : S3part1 : M1

Chapter 27. DBMS_UTILITY module 331

Page 342: IBM DB2 9.7 for Linux, UNIX, And Windows

part2 : F1dblink : NULLpart1 type: 9object id : 16

Example 2: Resolve a table accessed by a database link. Note that NAME_RESOLVEdoes not check the validity of the database object on the remote database. It merelyechoes back the components specified in the name argument.BEGIN

name_resolve('sample_schema.emp@sample_schema_link',2);END;

name : sample_schema.emp@sample_schema_linkcontext : 2schema : SAMPLE_SCHEMApart1 : EMPpart2 :dblink : SAMPLE_SCHEMA_LINKpart1 type: 0object id : 0

NAME_TOKENIZE procedure - Parse the given name into itscomponent parts

The NAME_TOKENIZE procedure parses a name into its component parts. Nameswithout double quotes are put into uppercase, and double quotes are strippedfrom names with double quotes.

Syntax

�� NAME_TOKENIZE ( name , a , b , c , dblink , nextpos ) ��

Parameters

nameAn input argument of type VARCHAR(1024) that specifies the stringcontaining a name in the following format:a[.b[.c]][@dblink ]

a An output argument of type VARCHAR(128) that returns the leftmostcomponent.

b An output argument of type VARCHAR(128) that returns the secondcomponent, if any.

c An output argument of type VARCHAR(128) that returns the third component,if any.

dblinkAn output argument of type VARCHAR(32672) that returns the database linkname.

nextposAn output argument of type INTEGER that specifies the position of the lastcharacter parsed in name.

Authorization

EXECUTE privilege on the DBMS_UTILITY module.

332 SQL Procedural Languages: Application Enablement and Support

Page 343: IBM DB2 9.7 for Linux, UNIX, And Windows

Examples

Example 1: The following stored procedure is used to display the returned values ofthe NAME_TOKENIZE procedure for various names.CREATE OR REPLACE PROCEDURE name_tokenize (

p_name VARCHAR2)IS

v_a VARCHAR2(30);v_b VARCHAR2(30);v_c VARCHAR2(30);v_dblink VARCHAR2(30);v_nextpos BINARY_INTEGER;

BEGINDBMS_UTILITY.NAME_TOKENIZE(p_name,v_a,v_b,v_c,v_dblink,v_nextpos);DBMS_OUTPUT.PUT_LINE('name : ' || p_name);DBMS_OUTPUT.PUT_LINE('a : ' || v_a);DBMS_OUTPUT.PUT_LINE('b : ' || v_b);DBMS_OUTPUT.PUT_LINE('c : ' || v_c);DBMS_OUTPUT.PUT_LINE('dblink : ' || v_dblink);DBMS_OUTPUT.PUT_LINE('nextpos: ' || v_nextpos);

END;

Tokenize the name, emp:BEGIN

name_tokenize('emp');END;

name : empa : EMPb :c :dblink :nextpos: 3

Tokenize the name, sample_schema.list_emp:BEGIN

name_tokenize('sample_schema.list_emp');END;

name : sample_schema.list_empa : SAMPLE_SCHEMAb : LIST_EMPc :dblink :nextpos: 12

Tokenize the name, "sample_schema"."Emp_Admin".update_emp_sal:BEGIN

name_tokenize('"sample_schema"."Emp_Admin".update_emp_sal');END;

name : "sample_schema"."Emp_Admin".update_emp_sala : sample_schemab : Emp_Adminc : UPDATE_EMP_SALdblink :nextpos: 32

Tokenize the name sample_schema.emp@sample_schema_dblink:BEGIN

name_tokenize('sample_schema.emp@sample_schema_dblink');END;

Chapter 27. DBMS_UTILITY module 333

Page 344: IBM DB2 9.7 for Linux, UNIX, And Windows

name : sample_schema.emp@sample_schema_dblinka : SAMPLE_SCHEMAb : EMPc :dblink : SAMPLE_SCHEMA_DBLINKnextpos: 18

TABLE_TO_COMMA procedures - Convert a table of names into acomma-delimited list of names

The TABLE_TO_COMMA procedures convert an array of names into acomma-delimited list of names. Each array element becomes a list entry.

Note: The names must be formatted as valid identifiers.

Syntax

�� TABLE_TO_COMMA_LNAME ( tab , tablen , list ) ��

�� TABLE_TO_COMMA_UNCL ( tab , tablen , list ) ��

Parameters

tab An input argument of type LNAME_ARRAY or UNCL_ARRAY that specifiesthe array containing names. See LNAME_ARRAY or UNCL_ARRAY for adescription of tab.

tablenAn output argument of type INTEGER that returns the number of entries inlist.

listAn output argument of type VARCHAR(32672) that returns thecomma-delimited list of names from tab.

Authorization

EXECUTE privilege on the DBMS_UTILITY module.

Examples

Example 1: The following example first uses the COMMA_TO_TABLE_LNAMEprocedure to convert a comma-delimited list to a table. TheTABLE_TO_COMMA_LNAME procedure then converts the table back to acomma-delimited list which is displayed.CREATE OR REPLACE PROCEDURE table_to_comma (

p_list VARCHAR2)IS

r_lname DBMS_UTILITY.LNAME_ARRAY;v_length BINARY_INTEGER;v_listlen BINARY_INTEGER;v_list VARCHAR2(80);

BEGINDBMS_UTILITY.COMMA_TO_TABLE_LNAME(p_list,v_length,r_lname);DBMS_OUTPUT.PUT_LINE('Table Entries');DBMS_OUTPUT.PUT_LINE('-------------');

334 SQL Procedural Languages: Application Enablement and Support

Page 345: IBM DB2 9.7 for Linux, UNIX, And Windows

FOR i IN 1..v_length LOOPDBMS_OUTPUT.PUT_LINE(r_lname(i));

END LOOP;DBMS_OUTPUT.PUT_LINE('-------------');DBMS_UTILITY.TABLE_TO_COMMA_LNAME(r_lname,v_listlen,v_list);DBMS_OUTPUT.PUT_LINE('Comma-Delimited List: ' || v_list);

END;

EXEC table_to_comma('sample_schema.dept, sample_schema.emp, sample_schema.jobhist')

Table Entries-------------sample_schema.deptsample_schema.empsample_schema.jobhist-------------Comma-Delimited List: sample_schema.dept, sample_schema.emp, sample_schema.jobhist

VALIDATE procedure - Change an invalid routine into a valid routineThe VALIDATE procedure provides the capability to change the state of an invalidroutine to valid.

Syntax

�� VALIDATE ( object_id ) ��

Parameters

object_idAn input argument of type INTEGER that specifies the identifier of the routineto be changed to a valid state. The ROUTINEID column of theSYSCAT.ROUTINES view contains all the routine identifiers.

Authorization

EXECUTE privilege on the DBMS_UTILITY module.

Chapter 27. DBMS_UTILITY module 335

Page 346: IBM DB2 9.7 for Linux, UNIX, And Windows

336 SQL Procedural Languages: Application Enablement and Support

Page 347: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 28. MONREPORT module

The MONREPORT module provides a set of procedures for retrieving a variety ofmonitoring data and generating text reports.

The schema for this module is SYSIBMADM.

The MONREPORT module includes the following system-defined routines.

Table 28. System-defined routines available in the MONREPORT module

Routine name Description

CONNECTION procedure The Connection report presents monitor datafor each connection.

CURRENTAPPS procedure The Current Applications report presents thecurrent instantaneous state of processing ofunits of work, agents, and activities for eachconnection. The report starts with stateinformation summed across connections,followed by a section for details for eachconnection.

CURRENTSQL procedure The Current SQL report lists the topactivities currently running, as measured byvarious metrics.

DBSUMMARY procedure The Summary report contains in-depthmonitor data for the entire database, as wellas key performance indicators for eachconnection, workload, service class, anddatabase member.

LOCKWAIT procedure The Lock Waits report contains informationabout each lock wait currently in progress.Details include lock holder and requestordetails, plus characteristics of the lock heldand the lock requested.

PKGCACHE procedure The Package Cache report lists the topstatements accumulated in the packagecache as measured by various metrics.

Usage notes

Monitor element names are displayed in upper case (for example,TOTAL_CPU_TIME). To find out more information about a monitor element,search the DB2 Information Centre for the monitor name.

For reports with a monitoring_interval input, negative values in a report areinaccurate. This may occur during a rollover of source data counters. To determineaccurate values, re-run the report after the rollover is complete.

Note: The reports are implemented using SQL procedures within modules, and assuch can be impacted by the package cache configuration. If you observe slowperformance when running the reports, inspect your package cache configurationto ensure it is sufficient for your workload. For further information, see“pckcachesz - Package cache size configuration parameter”.

© Copyright IBM Corp. 1993, 2009 337

Page 348: IBM DB2 9.7 for Linux, UNIX, And Windows

The following examples demonstrate various ways to call the MONREPORTroutines. The examples show the MONREPORT.CONNECTION(monitoring_interval,application_handle) procedure. You can handle optional parameters for which youdo not want to enter a value in the following ways:v You can always specify null or DEFAULT.v For character inputs, you can specify an empty string (’ ’).v If it is the last parameter, you can omit it.

To generate a report that includes a section for each connection, with the defaultmonitoring interval of 10 seconds, make the following call to theMONREPORT.CONNECTION procedure:call monreport.connection()

To generate a report that includes a section only for the connection withapplication handle 32, with the default monitoring interval of 10 seconds, you canmake either of the following calls to the MONREPORT.CONNECTION procedure:call monreport.connection(DEFAULT, 32)

call monreport.connection(10, 32)

To generate a report that includes a section for each connection, with a monitoringinterval of 60 seconds, you can make either of the following calls to theMONREPORT.CONNECTION procedure:call monreport.connection(60)

call monreport.connection(60, null)

By default, the reports in this module are generated in English. To change thelanguage in which the reports are generated, change the CURRENT LOCALELC_MESSAGES special register. For example, to generate the CONNECTIONreport in French, issue the following commands:SET CURRENT LOCALE LC_MESSAGES = 'CLDR 1.5:fr_FR'CALL MONREPORT.CONNECTION

CONNECTION procedure - generate a report on connection metricsThe CONNECTION procedure gathers monitor data for each connection andproduces a text-formatted report.

The CONNECTION procedure is available starting with DB2 Version 9.7 Fix Pack1.

Syntax

�� CONNECTION ( monitoring_interval , application_handle ) ��

Parameters

monitoring_intervalAn optional input argument of type INTEGER that specifies the duration inseconds that monitoring data is collected before it is reported. For example, ifyou specify a monitoring interval of 30, the routine calls table functions, waits30 seconds and calls the table functions again. The routine then calculates thedifference, which reflects changes during the interval. If the monitoring_intervalargument is not specified (or if null is specified), the default value is 10. Therange of valid inputs are the integer values 0-3600 (that is, up to 1 hour).

338 SQL Procedural Languages: Application Enablement and Support

Page 349: IBM DB2 9.7 for Linux, UNIX, And Windows

application_handleAn optional input argument of type BIGINT that specifies an applicationhandle that identifies a connection. If the application_handle argument is notspecified (or if null is specified), the report includes a section for eachconnection. The default is null.

Authorization

The following privilege is required:v EXECUTE privilege on the MONREPORT module

The following examples demonstrate various ways to call the CONNECTIONprocedure. The first example produces a report for all connections with datadisplayed corresponding to an interval of 10 seconds:call monreport.connection;

The next example produces a report for all connections with data displayedcorresponding to interval of 30 seconds:call monreport.connection(30);

The next example produces a report for a connection with an application handle of34. Data is displayed based on absolute totals accumulated in the source tablefunctions (rather than based on the current interval).call monreport.connection(0, 34);

The next example produces a report for a connection with an application handle of34. Data is displayed corresponding to an interval of 10 seconds.call monreport.connection(DEFAULT, 34);

CURRENTAPPS procedure - generate a report of point-in-timeapplication processing metrics

The CURRENTAPPS procedure gathers information about the currentinstantaneous state of processing of units or work, agents, and activities for eachconnection.

The CURRENTAPPS procedure is available starting with DB2 Version 9.7 Fix Pack1.

Syntax

�� CURRENTAPPS ( ) ��

Authorization

The following privilege is required:v EXECUTE privilege on the MONREPORT module

The following examples demonstrate ways to call the CURRENTAPPS procedure:call monreport.currentapps;

call monreport.currentapps();

Chapter 28. MONREPORT module 339

Page 350: IBM DB2 9.7 for Linux, UNIX, And Windows

CURRENTSQL procedure - generate a report that summarizesactivities

The CURRENTSQL procedure generates a text-formatted report that summarizescurrently running activities.

The CURRENTSQL procedure is available starting with DB2 Version 9.7 Fix Pack 1.

Syntax

�� CURRENTSQL ( member ) ��

Parameters

memberAn input argument of type SMALLINT that determines whether to show datafor a particular member or partition, or to show data summed across allmembers. If this argument is not specified (or if null is specified), the reportshows values summed across all members. If a valid member number isspecified, the report shows values for that member.

Authorization

The following privilege is required:v EXECUTE privilege on the MONREPORT module

The following examples demonstrate various ways to call the CURRENTSQLprocedure. The first example produces a report that shows activity metricsaggregated across all members:call monreport.currentsql;

The next example produces a report that shows activity metrics specific to theactivity performance on member number 4.call monreport.currentsql(4);

DBSUMMARY procedure - generate a summary report of system andapplication performance metrics

The DBSUMMARY procedure generates a text-formatted monitoring report thatsummarizes system and application performance metrics.

The DBSUMMARY procedure is available starting with DB2 Version 9.7 Fix Pack 1.

The DB Summary report contains in-depth monitor data for the entire database aswell as key performance indicators for each connection, workload, service class,and database member.

Syntax

�� DBSUMMARY ( monitoring_interval ) ��

340 SQL Procedural Languages: Application Enablement and Support

Page 351: IBM DB2 9.7 for Linux, UNIX, And Windows

Parameters

monitoring_intervalAn optional input argument of type INTEGER that specifies the duration inseconds that monitoring data is collected before it is reported. For example, ifyou specify a monitoring interval of 30, the routine calls the table functions,waits 30 seconds and then calls the table functions again. The DBSUMMARYprocedure then calculates the difference, which reflects changes during theinterval. If the monitoring_interval argument is not specified (or if null isspecified), the default value is 10. The range of valid inputs are the integervalues 0-3600 (that is, up to 1 hour).

Authorization

The following privilege is required:v EXECUTE privilege on the MONREPORT module

The following examples demonstrate various ways to call the DBSUMMARYprocedure. The first example produces a report that displays data corresponding toan interval of 10 seconds:call monreport.dbsummary;

The next example produces a report that displays data corresponding to aninterval of 30 seconds.call monreport.dbsummary(30);

LOCKWAIT procedure - generate a report of current lock waitsThe Lock Waits report contains information about each lock wait currently inprogress. Details include information about the lock holder and requestor andcharacteristics of the lock held and the lock requested.

The LOCKWAIT procedure is available starting with DB2 Version 9.7 Fix Pack 1.

Syntax

�� LOCKWAIT ( ) ��

Authorization

The following privilege is required:v EXECUTE privilege on the MONREPORT module

The following examples demonstrate various ways to call the LOCKWAITprocedure:call monreport.lockwait;

call monreport.lockwait();

Chapter 28. MONREPORT module 341

Page 352: IBM DB2 9.7 for Linux, UNIX, And Windows

----------------------------------------------------------------------------------------------------------------------------------------------------------------Monitoring report - current lock waits--------------------------------------------------------------------------------Database: SAMPLEGenerated: 08/28/2009 07:16:26

================================================================================Part 1 - Summary of current lock waits

--------------------------------------------------------------------------------

REQ_APPLICATION LOCK_MODE HLD_APPLICATION LOCK_ LOCK_OBJECT_TYPE# HANDLE REQUESTED _HANDLE MODE---- --------------- --------- --------------- ----- ----------------------1 26 U 21 U ROW2 25 U 21 U ROW3 24 U 21 U ROW4 23 U 21 U ROW5 22 U 21 U ROW6 27 U 21 U ROW

================================================================================

...

390 record(s) selected.

Return Status = 0

Figure 1. Sample MONREPORT.LOCKWAIT output - summary section

342 SQL Procedural Languages: Application Enablement and Support

Page 353: IBM DB2 9.7 for Linux, UNIX, And Windows

================================================================================Part 2: Details for each current lock wait

lock wait #:1--------------------------------------------------------------------------------

-- Lock details --

LOCK_NAME = 04000500040000000000000052LOCK_WAIT_START_TIME = 2009-08-28-07.15.31.013802LOCK_OBJECT_TYPE = ROWTABSCHEMA = TRIPATHYTABNAME = INVENTORYROWID = 4LOCK_STATUS = WLOCK_ATTRIBUTES = 0000000000000000ESCALATION = N

-- Requestor and holder application details --

Attributes Requestor Holder------------------- ----------------------------- ----------------------------APPLICATION_HANDLE 26 21APPLICATION_ID *LOCAL.tripathy.090828111531 *LOCAL.tripathy.090828111435APPLICATION_NAME java javaSESSION_AUTHID TRIPATHY TRIPATHYMEMBER 0 0LOCK_MODE - ULOCK_MODE_REQUESTED U -

-- Lock holder current agents --

AGENT_TID = 41REQUEST_TYPE = FETCHEVENT_STATE = IDLEEVENT_OBJECT = REQUESTEVENT_TYPE = WAITACTIVITY_ID =UOW_ID =

-- Lock holder current activities --

ACTIVITY_ID = 1UOW_ID = 1LOCAL_START_TIME = 2009-08-28-07.14.31.079757ACTIVITY_TYPE = READ_DMLACTIVITY_STATE = IDLE

STMT_TEXT =select * from inventory for update

-- Lock requestor waiting agent and activity --

AGENT_TID = 39REQUEST_TYPE = FETCHACTIVITY_ID = 1UOW_ID = 1LOCAL_START_TIME = 2009-08-28-07.15.31.012935ACTIVITY_TYPE = READ_DMLACTIVITY_STATE = EXECUTING

STMT_TEXT =select * from inventory for update

Figure 2. Sample MONREPORT.LOCKWAIT output - details section

Chapter 28. MONREPORT module 343

Page 354: IBM DB2 9.7 for Linux, UNIX, And Windows

PKGCACHE procedure - generate a summary report of package cachemetrics

The Package Cache Summary report lists the top statements accumulated in thepackage cache as measured by various metrics.

The PKGCACHE procedure is available starting with DB2 Version 9.7 Fix Pack 1.

Syntax

�� PKGCACHE ( cache_interval , section_type , member ) ��

Parameters

cache_intervalAn optional input argument of type INTEGER that specifies the report shouldonly include data for package cache entries that have been updated in the pastnumber of minutes specified by the cache_interval value. For example acache_interval value of 60 produces a report based on package cache entries thathave been updated in the past 60 minutes. Valid values are integers between 0and 10080, which supports an interval of up to 7 days. If the argument is notspecified (or if null is specified), the report includes data for package cacheentries regardless of when they were added or updated.

section_typeAn optional input argument of type CHAR(1) that specifies whether the reportshould include data for static SQL, dynamic SQL, or both. If the argument isnot specified (or if null is specified), the report includes data for both types ofSQL. Valid values are: d or D (for dynamic) and s or S (for static).

memberAn optional input argument of type SMALLINT that determines whether toshow data for a particular member or partition, or to show data summedacross all members. If this argument is not specified (or if null is specified), thereport shows values summed across all members. If a valid member number isspecified, the report shows values for that member.

Authorization

The following privilege is required:v EXECUTE privilege on the MONREPORT module

The following examples demonstrate various ways to call the PKGCACHEprocedure. The first example produces a report based on all statements in thepackage cache, with data aggregated across all members:call monreport.pkgcache;

The next example produces a report based on both dynamic and static statementsin the package cache for which metrics have been updated within the last 30minutes, with data aggregated across all members:call monreport.pkgcache(30);

344 SQL Procedural Languages: Application Enablement and Support

Page 355: IBM DB2 9.7 for Linux, UNIX, And Windows

The next example produces a report based on all dynamic statements in thepackage cache, with data aggregated across all members:call monreport.pkgcache(DEFAULT, 'd');

The next example produces a report based on both dynamic and static statementsin the package cache for which metrics have been updated within the last 30minutes, with data specific to a member number 4:call db2monreport.pkgcache(30, DEFAULT, 4);

Chapter 28. MONREPORT module 345

Page 356: IBM DB2 9.7 for Linux, UNIX, And Windows

346 SQL Procedural Languages: Application Enablement and Support

Page 357: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 29. UTL_DIR module

The UTL_DIR module provides a set of routines for maintaining directory aliasesthat are used with the UTL_FILE module.

The schema for this module is SYSIBMADM.

The UTL_DIR module includes the following system-defined routines.

Table 29. System-defined routines available in the UTL_DIR module

Routine name Description

CREATE_DIRECTORY procedure Creates a directory alias for the specifiedpath.

CREATE_OR_REPLACE_DIRECTORYprocedure

Creates or replaces a directory alias for thespecified path.

DROP_DIRECTORY procedure Drops the specified directory alias.

GET_DIRECTORY_PATH procedure Gets the corresponding path for thespecified directory alias.

CREATE_DIRECTORY procedure - Create a directory aliasThe CREATE_DIRECTORY procedure creates a directory alias for the specifiedpath.

Directory information is stored in SYSTOOLS.DIRECTORIES, which is created inthe SYSTOOLSPACE when you first reference this module for each database.

Syntax

�� UTL_DIR.CREATE_DIRECTORY ( alias , path ) ��

Procedure parameters

aliasAn input argument of type VARCHAR(128) that specifies the directory alias.

pathAn input argument of type VARCHAR(1024) that specifies the path.

Authorization

EXECUTE privilege on the UTL_DIR module.

Example

Create a directory alias, and use it in a call to the UTL_FILE.FOPEN function.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE v_filehandle UTL_FILE.FILE_TYPE;DECLARE isOpen SMALLINT;

© Copyright IBM Corp. 1993, 2009 347

Page 358: IBM DB2 9.7 for Linux, UNIX, And Windows

DECLARE v_filename VARCHAR(20) DEFAULT 'myfile.csv';CALL UTL_DIR.CREATE_DIRECTORY('mydir', 'home/user/temp/mydir');SET v_filehandle = UTL_FILE.FOPEN('mydir',v_filename,'w');SET isOpen = UTL_FILE.IS_OPEN( v_filehandle );

IF isOpen != 1 THENRETURN -1;

END IF;CALL DBMS_OUTPUT.PUT_LINE('Opened file: ' || v_filename);CALL UTL_FILE.FCLOSE(v_filehandle);

END@

CALL proc1@

This example results in the following output:Opened file: myfile.csv

CREATE_OR_REPLACE_DIRECTORY procedure - Create or replace adirectory alias

The CREATE_OR_REPLACE_DIRECTORY procedure creates or replaces adirectory alias for the specified path.

Directory information is stored in SYSTOOLS.DIRECTORIES, which is created inthe SYSTOOLSPACE when you first reference this module for each database.

Syntax

�� UTL_DIR.CREATE_OR_REPLACE_DIRECTORY ( alias , path ) ��

Procedure parameters

aliasAn input argument of type VARCHAR(128) that specifies the directory alias.

pathAn input argument of type VARCHAR(1024) that specifies the path.

Authorization

EXECUTE privilege on the UTL_DIR module.

Example

Example 1: Create a directory alias. Because the directory already exists, an erroroccurs.CALL UTL_DIR.CREATE_DIRECTORY('mydir', 'home/user/temp/empdir')@

This example results in the following output:SQL0438N Application raised error or warning with diagnostic text: "directoryalias already defined". SQLSTATE=23505

Example 2: Create or replace a directory alias.CALL UTL_DIR.CREATE_OR_REPLACE_DIRECTORY('mydir', 'home/user/temp/empdir')@

This example results in the following output:Return Status = 0

348 SQL Procedural Languages: Application Enablement and Support

Page 359: IBM DB2 9.7 for Linux, UNIX, And Windows

DROP_DIRECTORY procedure - Drop a directory aliasThe DROP_DIRECTORY procedure drops the specified directory alias.

Syntax

�� UTL_DIR.DROP_DIRECTORY ( alias ) ��

Procedure parameters

aliasAn input argument of type VARCHAR(128) that specifies the directory alias.

Authorization

EXECUTE privilege on the UTL_DIR module.

Example

Drop the specified directory alias.CALL UTL_DIR.DROP_DIRECTORY('mydir')@

This example results in the following output:Return Status = 0

GET_DIRECTORY_PATH procedure - Get the path for a directory aliasThe GET_DIRECTORY_PATH procedure returns the corresponding path for adirectory alias.

Syntax

�� UTL_DIR.GET_DIRECTORY_PATH ( alias , path ) ��

Procedure parameters

aliasAn input argument of type VARCHAR(128) that specifies the directory alias.

pathAn output argument of type VARCHAR(1024) that specifies the path that isdefined for a directory alias.

Authorization

EXECUTE privilege on the UTL_DIR module.

Example

Get the path that is defined for a directory alias.CALL UTL_DIR.GET_DIRECTORY_PATH('mydir', ? )@

This example results in the following output:

Chapter 29. UTL_DIR module 349

Page 360: IBM DB2 9.7 for Linux, UNIX, And Windows

Value of output parameters--------------------------Parameter Name : PATHParameter Value : home/rhoda/temp/mydir

Return Status = 0

350 SQL Procedural Languages: Application Enablement and Support

Page 361: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 30. UTL_FILE module

The UTL_FILE module provides a set of routines for reading from and writing tofiles on the database server’s file system.

The schema for this module is SYSIBMADM.

The UTL_FILE module includes the following system-defined routines and types.

Table 30. System-defined routines available in the UTL_FILE module

Routine name Description

FCLOSE procedure Closes a specified file.

FCLOSE_ALL procedure Closes all open files.

FCOPY procedure Copies text from one file to another.

FFLUSH procedure Flushes unwritten data to a file

FOPEN function Opens a file.

FREMOVE procedure Removes a file.

FRENAME procedure Renames a file.

GET_LINE procedure Gets a line from a file.

IS_OPEN function Determines whether a specified file is open.

NEW_LINE procedure Writes an end-of-line character sequence to afile.

PUT procedure Writes a string to a file.

PUT_LINE procedure Writes a single line to a file.

PUTF procedure Writes a formatted string to a file.

UTL_FILE.FILE_TYPE Stores a file handle.

The following is a list of named conditions (these are called ″exceptions″ byOracle) that an application can receive.

Table 31. Named conditions for an application

Condition Name Description

access_denied Access to the file is denied by the operatingsystem.

charsetmismatch A file was opened using FOPEN_NCHAR,but later I/O operations used non-CHARfunctions such as PUTF or GET_LINE.

delete_failed Unable to delete file.

file_open File is already open.

internal_error Unhandled internal error in the UTL_FILEmodule.

invalid_filehandle File handle does not exist.

invalid_filename A file with the specified name does not existin the path.

© Copyright IBM Corp. 1993, 2009 351

Page 362: IBM DB2 9.7 for Linux, UNIX, And Windows

Table 31. Named conditions for an application (continued)

Condition Name Description

invalid_maxlinesize The MAX_LINESIZE value for FOPEN isinvalid. It must be between 1 and 32672.

invalid_mode The open_mode argument in FOPEN isinvalid.

invalid_offset The ABSOLUTE_OFFSET argument forFSEEK is invalid. It must be greater than 0and less than the total number of bytes inthe file.

invalid_operation File could not be opened or operated on asrequested.

invalid_path The specified path does not exist or is notvisible to the database

read_error Unable to read the file.

rename_failed Unable to rename the file.

write_error Unable to write to the file.

Usage notes

To reference directories on the file system, use a directory alias. You can create adirectory alias by calling the UTL_DIR.CREATE_DIRECTORY orUTL_DIR.CREATE_OR_REPLACE_DIRECTORY procedures. For example, CALLUTL_DIR.CREATE_DIRECTORY('mydir', 'home/user/temp/mydir')@.

The UTL_FILE module executes file operations by using the DB2 instance ID.Therefore, if you are opening a file, verify that the DB2 instance ID has theappropriate operating system permissions.

The UTL_FILE module is supported only in a non-DPF environment.

FCLOSE procedure - Close an open fileThe FCLOSE procedure closes a specified file.

Syntax

�� UTL_FILE.FCLOSE ( file ) ��

Procedure parameters

file An input or output argument of type UTL_FILE.FILE_TYPE that contains thefile handle. When the file is closed, this value is set to 0.

Authorization

EXECUTE privilege on the UTL_FILE module.

Example

Open a file, write some text to the file, and then close the file.

352 SQL Procedural Languages: Application Enablement and Support

Page 363: IBM DB2 9.7 for Linux, UNIX, And Windows

SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE v_filehandle UTL_FILE.FILE_TYPE;DECLARE isOpen SMALLINT;DECLARE v_dirAlias VARCHAR(50) DEFAULT 'mydir';DECLARE v_filename VARCHAR(20) DEFAULT 'myfile.csv';SET v_filehandle = UTL_FILE.FOPEN(v_dirAlias,v_filename,'w');SET isOpen = UTL_FILE.IS_OPEN( v_filehandle );

IF isOpen != 1 THENRETURN -1;

END IF;CALL UTL_FILE.PUT_LINE(v_filehandle,'Some text to write to the file.');CALL UTL_FILE.FCLOSE(v_filehandle);SET isOpen = UTL_FILE.IS_OPEN( v_filehandle );

IF isOpen != 1 THENCALL DBMS_OUTPUT.PUT_LINE('Closed file: ' || v_filename);

END IF;END@

CALL proc1@

This example results in the following output:Closed file: myfile.csv

FCLOSE_ALL procedure - Close all open filesThe FCLOSE_ALL procedure closes all open files. The procedure runs successfullyeven if there are no open files to close.

Syntax

�� UTL_FILE.FCLOSE_ALL ��

Authorization

EXECUTE privilege on the UTL_FILE module.

Example

Open a couple of files, write some text to the files, and then close all open files.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE v_filehandle UTL_FILE.FILE_TYPE;DECLARE v_filehandle2 UTL_FILE.FILE_TYPE;DECLARE isOpen SMALLINT;DECLARE v_dirAlias VARCHAR(50) DEFAULT 'mydir';DECLARE v_filename VARCHAR(20) DEFAULT 'myfile.csv';DECLARE v_filename2 VARCHAR(20) DEFAULT 'myfile2.csv';SET v_filehandle = UTL_FILE.FOPEN(v_dirAlias,v_filename,'w');SET isOpen = UTL_FILE.IS_OPEN( v_filehandle );

IF isOpen != 1 THENRETURN -1;

END IF;CALL UTL_FILE.PUT_LINE(v_filehandle,'Some text to write to a file.');SET v_filehandle2 = UTL_FILE.FOPEN(v_dirAlias,v_filename2,'w');SET isOpen = UTL_FILE.IS_OPEN( v_filehandle2 );

IF isOpen != 1 THEN

Chapter 30. UTL_FILE module 353

Page 364: IBM DB2 9.7 for Linux, UNIX, And Windows

RETURN -1;END IF;

CALL UTL_FILE.PUT_LINE(v_filehandle2,'Some text to write to another file.');CALL UTL_FILE.FCLOSE_ALL;SET isOpen = UTL_FILE.IS_OPEN( v_filehandle );

IF isOpen != 1 THENCALL DBMS_OUTPUT.PUT_LINE(v_filename || ' is now closed.');

END IF;SET isOpen = UTL_FILE.IS_OPEN( v_filehandle2 );

IF isOpen != 1 THENCALL DBMS_OUTPUT.PUT_LINE(v_filename2 || ' is now closed.');

END IF;END@

CALL proc1@

This example results in the following output:myfile.csv is now closed.myfile2.csv is now closed.

FCOPY procedure - Copy text from one file to anotherThe FCOPY procedure copies text from one file to another.

Syntax

�� UTL_FILE.FCOPY ( location , filename , dest_dir , dest_file �

� ), start_line

, end_line

��

Procedure parameters

locationAn input argument of type VARCHAR(128) that specifies the alias of thedirectory that contains the source file.

filenameAn input argument of type VARCHAR(255) that specifies the name of thesource file.

dest_dirAn input argument of type VARCHAR(128) that specifies the alias of thedestination directory.

dest_fileAn input argument of type VARCHAR(255) that specifies the name of thedestination file.

start_lineAn optional input argument of type INTEGER that specifies the line number ofthe first line of text to copy in the source file. The default is 1.

end_lineAn optional input argument of type INTEGER that specifies the line number ofthe last line of text to copy in the source file. If this argument is omitted ornull, the procedure continues copying all text through the end of the file.

354 SQL Procedural Languages: Application Enablement and Support

Page 365: IBM DB2 9.7 for Linux, UNIX, And Windows

Authorization

EXECUTE privilege on the UTL_FILE module.

Example

Make a copy of a file, empfile.csv, that contains a comma-delimited list ofemployees from the emp table.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE v_empfile UTL_FILE.FILE_TYPE;DECLARE v_dirAlias VARCHAR(50) DEFAULT 'empdir';DECLARE v_src_file VARCHAR(20) DEFAULT 'empfile.csv';DECLARE v_dest_file VARCHAR(20) DEFAULT 'empcopy.csv';DECLARE v_empline VARCHAR(200);CALL UTL_FILE.FCOPY(v_dirAlias,v_src_file,v_dirAlias,v_dest_file);

END@

CALL proc1@

This example results in the following output:Return Status = 0

The file copy, empcopy.csv, contains the following data:10,CHRISTINE,I,HAAS,A00,3978,1/1/1965,PRES,18,F,8/24/1933,52750,1000,422020,MICHAEL,L,THOMPSON,B01,3476,10/10/1973,MANAGER,18,M,2/2/1948,41250,800,330030,SALLY,A,KWAN,C01,4738,4/5/1975,MANAGER,20,F,5/11/1941,38250,800,306050,JOHN,B,GEYER,E01,6789,8/17/1949,MANAGER,16,M,9/15/1925,40175,800,321460,IRVING,F,STERN,D11,6423,9/14/1973,MANAGER,16,M,7/7/1945,32250,500,258070,EVA,D,PULASKI,D21,7831,9/30/1980,MANAGER,16,F,5/26/1953,36170,700,289390,EILEEN,W,HENDERSON,E11,5498,8/15/1970,MANAGER,16,F,5/15/1941,29750,600,2380100,THEODORE,Q,SPENSER,E21,972,6/19/1980,MANAGER,14,M,12/18/1956,26150,500,2092

FFLUSH procedure - Flush unwritten data to a fileThe FFLUSH procedure forces unwritten data in the write buffer to be written to afile.

Syntax

�� UTL_FILE.FFLUSH ( file ) ��

Procedure parameters

file An input argument of type UTL_FILE.FILE_TYPE that contains the file handle.

Authorization

EXECUTE privilege on the UTL_FILE module.

Example

Flush each line after calling the NEW_LINE procedure.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

Chapter 30. UTL_FILE module 355

Page 366: IBM DB2 9.7 for Linux, UNIX, And Windows

DECLARE v_empfile_src UTL_FILE.FILE_TYPE;DECLARE v_empfile_tgt UTL_FILE.FILE_TYPE;DECLARE v_dirAlias VARCHAR(50) DEFAULT 'empdir';DECLARE v_src_file VARCHAR(20) DEFAULT 'empfile.csv';DECLARE v_dest_file VARCHAR(20) DEFAULT 'empfilenew.csv';DECLARE v_empline VARCHAR(200);DECLARE SQLCODE INTEGER DEFAULT 0;DECLARE SQLSTATE CHAR(5) DEFAULT '00000';DECLARE SQLSTATE1 CHAR(5) DEFAULT '00000';DECLARE CONTINUE HANDLER FOR SQLSTATE '02000'SET SQLSTATE1 = SQLSTATE;

SET v_empfile_src = UTL_FILE.FOPEN(v_dirAlias,v_src_file,'r');SET v_empfile_tgt = UTL_FILE.FOPEN(v_dirAlias,v_dest_file,'w');

loop1: LOOPCALL UTL_FILE.GET_LINE(v_empfile_src,v_empline);IF SQLSTATE1 = '02000' THEN -- NO DATA FOUND

LEAVE loop1;END IF;CALL UTL_FILE.PUT(v_empfile_tgt,v_empline);CALL UTL_FILE.NEW_LINE(v_empfile_tgt);CALL UTL_FILE.FFLUSH(v_empfile_tgt);

END LOOP;CALL DBMS_OUTPUT.PUT_LINE('Updated file: ' || v_dest_file);CALL UTL_FILE.FCLOSE_ALL;

END@

CALL proc1@

This example results in the following output:Updated file: empfilenew.csv

The updated file, empfilenew.csv, contains the following data:10,CHRISTINE,I,HAAS,A00,3978,1/1/1965,PRES,18,F,8/24/1933,52750,1000,4220

20,MICHAEL,L,THOMPSON,B01,3476,10/10/1973,MANAGER,18,M,2/2/1948,41250,800,3300

30,SALLY,A,KWAN,C01,4738,4/5/1975,MANAGER,20,F,5/11/1941,38250,800,3060

50,JOHN,B,GEYER,E01,6789,8/17/1949,MANAGER,16,M,9/15/1925,40175,800,3214

60,IRVING,F,STERN,D11,6423,9/14/1973,MANAGER,16,M,7/7/1945,32250,500,2580

70,EVA,D,PULASKI,D21,7831,9/30/1980,MANAGER,16,F,5/26/1953,36170,700,2893

90,EILEEN,W,HENDERSON,E11,5498,8/15/1970,MANAGER,16,F,5/15/1941,29750,600,2380

100,THEODORE,Q,SPENSER,E21,972,6/19/1980,MANAGER,14,M,12/18/1956,26150,500,2092

FOPEN function - Open a fileThe FOPEN function opens a file for I/O.

Syntax

�� UTL_FILE.FOPEN ( location , filename , open_mode ), max_linesize

��

Return value

This function returns a value of type UTL_FILE.FILE_TYPE that indicates the filehandle of the opened file.

356 SQL Procedural Languages: Application Enablement and Support

Page 367: IBM DB2 9.7 for Linux, UNIX, And Windows

Function parameters

locationAn input argument of type VARCHAR(128) that specifies the alias of thedirectory that contains the file.

filenameAn input argument of type VARCHAR(255) that specifies the name of the file.

open_modeAn input argument of type VARCHAR(10) that specifies the mode in whichthe file is opened:

a append to file

r read from file

w write to file

max_linesizeAn optional input argument of type INTEGER that specifies the maximum sizeof a line in characters. In read mode, an exception is thrown if an attempt ismade to read a line that exceeds max_linesize. In write and append modes, anexception is thrown if an attempt is made to write a line that exceedsmax_linesize. End-of-line character(s) do not count towards the line size.

Authorization

EXECUTE privilege on the UTL_FILE module.

Example

Open a file, write some text to the file, and then close the file.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE v_filehandle UTL_FILE.FILE_TYPE;DECLARE isOpen SMALLINT;DECLARE v_dirAlias VARCHAR(50) DEFAULT 'mydir';DECLARE v_filename VARCHAR(20) DEFAULT 'myfile.csv';SET v_filehandle = UTL_FILE.FOPEN(v_dirAlias,v_filename,'w');SET isOpen = UTL_FILE.IS_OPEN( v_filehandle );

IF isOpen != 1 THENRETURN -1;

END IF;CALL DBMS_OUTPUT.PUT_LINE('Opened file: ' || v_filename);CALL UTL_FILE.PUT_LINE(v_filehandle,'Some text to write to the file.');CALL UTL_FILE.FCLOSE(v_filehandle);

END@

CALL proc1@

This example results in the following output.Opened file: myfile.csv

FREMOVE procedure - Remove a fileThe FREMOVE procedure removes a specified file from the system. If the file doesnot exist, this procedure throws an exception.

Chapter 30. UTL_FILE module 357

Page 368: IBM DB2 9.7 for Linux, UNIX, And Windows

Syntax

�� UTL_FILE.FREMOVE ( location , filename ) ��

Procedure parameters

locationAn input argument of type VARCHAR(128) that specifies the alias of thedirectory that contains the file.

filenameAn input argument of type VARCHAR(255) that specifies the name of the file.

Authorization

EXECUTE privilege on the UTL_FILE module.

Example

Remove the file myfile.csv from the system.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE v_dirAlias VARCHAR(50) DEFAULT 'mydir';DECLARE v_filename VARCHAR(20) DEFAULT 'myfile.csv';CALL UTL_FILE.FREMOVE(v_dirAlias,v_filename);CALL DBMS_OUTPUT.PUT_LINE('Removed file: ' || v_filename);

END@

CALL proc1@

This example results in the following output:Removed file: myfile.csv

FRENAME procedure - Rename a fileThe FRENAME procedure renames a specified file. Renaming a file effectivelymoves a file from one location to another.

Syntax

�� UTL_FILE.FRENAME ( location , filename , dest_dir , dest_file ), replace

��

Procedure parameters

locationAn input argument of type VARCHAR(128) that specifies the alias of thedirectory that contains the file that you want to rename.

filenameAn input argument of type VARCHAR(255) that specifies the name of the filethat you want to rename.

dest_dirAn input argument of type VARCHAR(128) that specifies the alias of thedestination directory.

358 SQL Procedural Languages: Application Enablement and Support

Page 369: IBM DB2 9.7 for Linux, UNIX, And Windows

dest_fileAn input argument of type VARCHAR(255) that specifies the new name of thefile.

replaceAn optional input argument of type INTEGER that specifies whether to replacethe file dest_file in the directory dest_dir if the file already exists:

1 Replaces existing file.

0 Throws an exception if the file already exists. This is the default if novalue is specified for replace.

Authorization

EXECUTE privilege on the UTL_FILE module.

Example

Rename a file, empfile.csv, that contains a comma-delimited list of employees fromthe emp table.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE v_dirAlias VARCHAR(50) DEFAULT 'empdir';DECLARE v_src_file VARCHAR(20) DEFAULT 'oldemp.csv';DECLARE v_dest_file VARCHAR(20) DEFAULT 'newemp.csv';DECLARE v_replace INTEGER DEFAULT 1;CALL UTL_FILE.FRENAME(v_dirAlias,v_src_file,v_dirAlias,

v_dest_file,v_replace);CALL DBMS_OUTPUT.PUT_LINE('The file ' || v_src_file ||

' has been renamed to ' || v_dest_file);END@

CALL proc1@

This example results in the following output:The file oldemp.csv has been renamed to newemp.csv

GET_LINE procedure - Get a line from a fileThe GET_LINE procedure gets a line of text from a specified file. The line of textdoes not include the end-of-line terminator. When there are no more lines to read,the procedure throws a NO_DATA_FOUND exception.

Syntax

�� UTL_FILE.GET_LINE ( file , buffer ) ��

Procedure parameters

file An input argument of type UTL_FILE.FILE_TYPE that contains the file handleof the opened file.

bufferAn output argument of type VARCHAR(32672) that contains a line of text fromthe file.

Chapter 30. UTL_FILE module 359

Page 370: IBM DB2 9.7 for Linux, UNIX, And Windows

Authorization

EXECUTE privilege on the UTL_FILE module.

Example

Read through and display the records in the file empfile.csv.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE v_empfile UTL_FILE.FILE_TYPE;DECLARE v_dirAlias VARCHAR(50) DEFAULT 'empdir';DECLARE v_filename VARCHAR(20) DEFAULT 'empfile.csv';DECLARE v_empline VARCHAR(200);DECLARE v_count INTEGER DEFAULT 0;DECLARE SQLCODE INTEGER DEFAULT 0;DECLARE SQLSTATE CHAR(5) DEFAULT '00000';DECLARE SQLSTATE1 CHAR(5) DEFAULT '00000';DECLARE CONTINUE HANDLER FOR SQLSTATE '02000'SET SQLSTATE1 = SQLSTATE;

SET v_empfile = UTL_FILE.FOPEN(v_dirAlias,v_filename,'r');

loop1: LOOPCALL UTL_FILE.GET_LINE(v_empfile, v_empline);IF SQLSTATE1 = '02000' THEN -- NO DATA FOUND

LEAVE loop1;END IF;CALL DBMS_OUTPUT.PUT_LINE(v_empline);SET v_count = v_count + 1;

END LOOP;CALL DBMS_OUTPUT.PUT_LINE('End of file ' || v_filename || ' - ' || v_count

|| ' records retrieved');CALL UTL_FILE.FCLOSE(v_empfile);

END@

CALL proc1@

This example results in the following output:10,CHRISTINE,I,HAAS,A00,3978,1/1/1965,PRES,18,F,8/24/1933,52750,1000,4220

20,MICHAEL,L,THOMPSON,B01,3476,10/10/1973,MANAGER,18,M,2/2/1948,41250,800,3300

30,SALLY,A,KWAN,C01,4738,4/5/1975,MANAGER,20,F,5/11/1941,38250,800,3060

50,JOHN,B,GEYER,E01,6789,8/17/1949,MANAGER,16,M,9/15/1925,40175,800,3214

60,IRVING,F,STERN,D11,6423,9/14/1973,MANAGER,16,M,7/7/1945,32250,500,2580

70,EVA,D,PULASKI,D21,7831,9/30/1980,MANAGER,16,F,5/26/1953,36170,700,2893

90,EILEEN,W,HENDERSON,E11,5498,8/15/1970,MANAGER,16,F,5/15/1941,29750,600,2380

100,THEODORE,Q,SPENSER,E21,972,6/19/1980,MANAGER,14,M,12/18/1956,26150,500,2092

End of file empfile.csv - 8 records retrieved

IS_OPEN function - Determine whether a specified file is openThe IS_OPEN function determines whether a specified file is open.

Syntax

�� UTL_FILE.IS_OPEN ( file ) ��

360 SQL Procedural Languages: Application Enablement and Support

Page 371: IBM DB2 9.7 for Linux, UNIX, And Windows

Return value

This function returns a value of type INTEGER that indicates if the specified file isopen (1) or closed (0).

Function parameters

file An input argument of type UTL_FILE.FILE_TYPE that contains the file handle.

Authorization

EXECUTE privilege on the UTL_FILE module.

Example

Before writing text to a file, call the IS_OPEN function to see if the file is open.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE v_filehandle UTL_FILE.FILE_TYPE;DECLARE isOpen SMALLINT;DECLARE v_dirAlias VARCHAR(50) DEFAULT 'mydir';DECLARE v_filename VARCHAR(20) DEFAULT 'myfile.csv';SET v_filehandle = UTL_FILE.FOPEN(v_dirAlias,v_filename,'w');SET isOpen = UTL_FILE.IS_OPEN( v_filehandle );

IF isOpen != 1 THENRETURN -1;

END IF;CALL UTL_FILE.PUT_LINE(v_filehandle,'Some text to write to the file.');CALL DBMS_OUTPUT.PUT_LINE('Updated file: ' || v_filename);CALL UTL_FILE.FCLOSE(v_filehandle);

END@

CALL proc1@

This example results in the following output.Updated file: myfile.csv

NEW_LINE procedure - Write an end-of-line character sequence to afile

The NEW_LINE procedure writes an end-of-line character sequence to a specifiedfile.

Syntax

�� UTL_FILE.NEW_LINE ( file ), lines

��

Procedure parameters

file An input argument of type UTL_FILE.FILE_TYPE that contains the file handle.

linesAn optional input argument of type INTEGER that specifies the number ofend-of-line character sequences to write to the file. The default is 1.

Chapter 30. UTL_FILE module 361

Page 372: IBM DB2 9.7 for Linux, UNIX, And Windows

Authorization

EXECUTE privilege on the UTL_FILE module.

Example

Write a file that contains a triple-spaced list of employee records.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE v_empfile_src UTL_FILE.FILE_TYPE;DECLARE v_empfile_tgt UTL_FILE.FILE_TYPE;DECLARE v_dirAlias VARCHAR(50) DEFAULT 'empdir';DECLARE v_src_file VARCHAR(20) DEFAULT 'empfile.csv';DECLARE v_dest_file VARCHAR(20) DEFAULT 'empfilenew.csv';DECLARE v_empline VARCHAR(200);DECLARE SQLCODE INTEGER DEFAULT 0;DECLARE SQLSTATE CHAR(5) DEFAULT '00000';DECLARE SQLSTATE1 CHAR(5) DEFAULT '00000';DECLARE CONTINUE HANDLER FOR SQLSTATE '02000'SET SQLSTATE1 = SQLSTATE;

SET v_empfile_src = UTL_FILE.FOPEN(v_dirAlias,v_src_file,'r');SET v_empfile_tgt = UTL_FILE.FOPEN(v_dirAlias,v_dest_file,'w');

loop1: LOOPCALL UTL_FILE.GET_LINE(v_empfile_src,v_empline);IF SQLSTATE1 = '02000' THEN -- NO DATA FOUND

LEAVE loop1;END IF;CALL UTL_FILE.PUT(v_empfile_tgt,v_empline);CALL UTL_FILE.NEW_LINE(v_empfile_tgt, 2);

END LOOP;

CALL DBMS_OUTPUT.PUT_LINE('Wrote to file: ' || v_dest_file);CALL UTL_FILE.FCLOSE_ALL;

END@

CALL proc1@

This example results in the following output:Wrote to file: empfilenew.csv

The file that is updated, empfilenew.csv, contains the following data:10,CHRISTINE,I,HAAS,A00,3978,1/1/1965,PRES,18,F,8/24/1933,52750,1000,4220

20,MICHAEL,L,THOMPSON,B01,3476,10/10/1973,MANAGER,18,M,2/2/1948,41250,800,3300

30,SALLY,A,KWAN,C01,4738,4/5/1975,MANAGER,20,F,5/11/1941,38250,800,3060

50,JOHN,B,GEYER,E01,6789,8/17/1949,MANAGER,16,M,9/15/1925,40175,800,3214

60,IRVING,F,STERN,D11,6423,9/14/1973,MANAGER,16,M,7/7/1945,32250,500,2580

70,EVA,D,PULASKI,D21,7831,9/30/1980,MANAGER,16,F,5/26/1953,36170,700,2893

90,EILEEN,W,HENDERSON,E11,5498,8/15/1970,MANAGER,16,F,5/15/1941,29750,600,2380

362 SQL Procedural Languages: Application Enablement and Support

Page 373: IBM DB2 9.7 for Linux, UNIX, And Windows

100,THEODORE,Q,SPENSER,E21,972,6/19/1980,MANAGER,14,M,12/18/1956,26150,500,2092

PUT procedure - Write a string to a fileThe PUT procedure writes a string to a specified file. No end-of-line charactersequence is written at the end of the string.

Syntax

�� UTL_FILE.PUT ( file , buffer ) ��

Procedure parameters

file An input argument of type UTL_FILE.FILE_TYPE that contains the file handle.

bufferAn input argument of type VARCHAR(32672) that specifies the text to write tothe file.

Authorization

EXECUTE privilege on the UTL_FILE module.

Example

Use the PUT procedure to add a string to a file and then use the NEW_LINEprocedure to add an end-of-line character sequence.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE v_empfile_src UTL_FILE.FILE_TYPE;DECLARE v_empfile_tgt UTL_FILE.FILE_TYPE;DECLARE v_dirAlias VARCHAR(50) DEFAULT 'empdir';DECLARE v_src_file VARCHAR(20) DEFAULT 'empfile.csv';DECLARE v_dest_file VARCHAR(20) DEFAULT 'empfilenew.csv';DECLARE v_empline VARCHAR(200);DECLARE SQLCODE INTEGER DEFAULT 0;DECLARE SQLSTATE CHAR(5) DEFAULT '00000';DECLARE SQLSTATE1 CHAR(5) DEFAULT '00000';DECLARE CONTINUE HANDLER FOR SQLSTATE '02000'SET SQLSTATE1 = SQLSTATE;

SET v_empfile_src = UTL_FILE.FOPEN(v_dirAlias,v_src_file,'r');SET v_empfile_tgt = UTL_FILE.FOPEN(v_dirAlias,v_dest_file,'w');

loop1: LOOPCALL UTL_FILE.GET_LINE(v_empfile_src,v_empline);IF SQLSTATE1 = '02000' THEN -- NO DATA FOUND

LEAVE loop1;END IF;CALL UTL_FILE.PUT(v_empfile_tgt,v_empline);CALL UTL_FILE.NEW_LINE(v_empfile_tgt, 2);

END LOOP;

CALL DBMS_OUTPUT.PUT_LINE('Wrote to file: ' || v_dest_file);CALL UTL_FILE.FCLOSE_ALL;

END@

CALL proc1@

Chapter 30. UTL_FILE module 363

Page 374: IBM DB2 9.7 for Linux, UNIX, And Windows

This example results in the following output:Wrote to file: empfilenew.csv

The updated file, empfilenew.csv, contains the following data:10,CHRISTINE,I,HAAS,A00,3978,1/1/1965,PRES,18,F,8/24/1933,52750,1000,4220

20,MICHAEL,L,THOMPSON,B01,3476,10/10/1973,MANAGER,18,M,2/2/1948,41250,800,3300

30,SALLY,A,KWAN,C01,4738,4/5/1975,MANAGER,20,F,5/11/1941,38250,800,3060

50,JOHN,B,GEYER,E01,6789,8/17/1949,MANAGER,16,M,9/15/1925,40175,800,3214

60,IRVING,F,STERN,D11,6423,9/14/1973,MANAGER,16,M,7/7/1945,32250,500,2580

70,EVA,D,PULASKI,D21,7831,9/30/1980,MANAGER,16,F,5/26/1953,36170,700,2893

90,EILEEN,W,HENDERSON,E11,5498,8/15/1970,MANAGER,16,F,5/15/1941,29750,600,2380

100,THEODORE,Q,SPENSER,E21,972,6/19/1980,MANAGER,14,M,12/18/1956,26150,500,2092

Usage notes

After using the PUT procedure to add a string to a file, use the NEW_LINEprocedure to add an end-of-line character sequence to the file.

PUT_LINE procedure - Write a line of text to a fileThe PUT_LINE procedure writes a line of text, including an end-of-line charactersequence, to a specified file.

Syntax

�� UTL_FILE.PUT_LINE ( file , buffer ) ��

Procedure parameters

file An input argument of type UTL_FILE.FILE_TYPE that contains the file handleof file to which the line is to be written.

bufferAn input argument of type VARCHAR(32672) that specifies the text to write tothe file.

Authorization

EXECUTE privilege on the UTL_FILE module.

Example

Use the PUT_LINE procedure to write lines of text to a file.

364 SQL Procedural Languages: Application Enablement and Support

Page 375: IBM DB2 9.7 for Linux, UNIX, And Windows

CALL proc1@SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE v_empfile_src UTL_FILE.FILE_TYPE;DECLARE v_empfile_tgt UTL_FILE.FILE_TYPE;DECLARE v_dirAlias VARCHAR(50) DEFAULT 'empdir';DECLARE v_src_file VARCHAR(20) DEFAULT 'empfile.csv';DECLARE v_dest_file VARCHAR(20) DEFAULT 'empfilenew2.csv';DECLARE v_empline VARCHAR(200);DECLARE v_count INTEGER DEFAULT 0;DECLARE SQLCODE INTEGER DEFAULT 0;DECLARE SQLSTATE CHAR(5) DEFAULT '00000';DECLARE SQLSTATE1 CHAR(5) DEFAULT '00000';DECLARE CONTINUE HANDLER FOR SQLSTATE '02000'SET SQLSTATE1 = SQLSTATE;

SET v_empfile_src = UTL_FILE.FOPEN(v_dirAlias,v_src_file,'r');SET v_empfile_tgt = UTL_FILE.FOPEN(v_dirAlias,v_dest_file,'w');

loop1: LOOPCALL UTL_FILE.GET_LINE(v_empfile_src,v_empline);IF SQLSTATE1 = '02000' THEN -- NO DATA FOUND

LEAVE loop1;END IF;SET v_count = v_count + 1;CALL UTL_FILE.PUT(v_empfile_tgt,'Record ' || v_count || ': ');CALL UTL_FILE.PUT_LINE(v_empfile_tgt,v_empline);

END LOOP;CALL DBMS_OUTPUT.PUT_LINE('End of file ' || v_src_file || ' - ' || v_count

|| ' records retrieved');CALL UTL_FILE.FCLOSE_ALL;

END@

CALL proc1@

This example results in the following output:End of file empfile.csv - 8 records retrieved

The file that is updated, empfilenew2.csv, contains the following data:Record 1: 10,CHRISTINE,I,HAAS,A00,3978,1/1/1965,PRES,18,F,8/24/1933,52750,1000,4220

Record 2: 20,MICHAEL,L,THOMPSON,B01,3476,10/10/1973,MANAGER,18,M,2/2/1948,41250,800,3300

Record 3: 30,SALLY,A,KWAN,C01,4738,4/5/1975,MANAGER,20,F,5/11/1941,38250,800,3060

Record 4: 50,JOHN,B,GEYER,E01,6789,8/17/1949,MANAGER,16,M,9/15/1925,40175,800,3214

Record 5: 60,IRVING,F,STERN,D11,6423,9/14/1973,MANAGER,16,M,7/7/1945,32250,500,2580

Record 6: 70,EVA,D,PULASKI,D21,7831,9/30/1980,MANAGER,16,F,5/26/1953,36170,700,2893

Record 7: 90,EILEEN,W,HENDERSON,E11,5498,8/15/1970,MANAGER,16,F,5/15/1941,29750,600,2380

Record 8: 100,THEODORE,Q,SPENSER,E21,972,6/19/1980,MANAGER,14,M,12/18/1956,26150,500,2092

PUTF procedure - Write a formatted string to a fileThe PUTF procedure writes a formatted string to a specified file.

Chapter 30. UTL_FILE module 365

Page 376: IBM DB2 9.7 for Linux, UNIX, And Windows

Syntax

�� �

,

UTL_FILE.PUTF ( file , format , )argN

��

Procedure parameters

file An input argument of type UTL_FILE.FILE_TYPE that contains the file handle.

formatAn input argument of type VARCHAR(1024) the specifies the string to use forformatting the text. The special character sequence, %s, is substituted by thevalue of argN. The special character sequence, \n, indicates a new line.

argNAn optional input argument of type VARCHAR(1024) that specifies a value tosubstitute in the format string for the corresponding occurrence of the specialcharacter sequence %s. Up to five arguments, arg1 through arg5, can bespecified. arg1 is substituted for the first occurrence of %s, arg2 is substitutedfor the second occurrence of %s, and so on.

Authorization

EXECUTE privilege on the UTL_FILE module.

Example

Format employee data.SET SERVEROUTPUT ON@

CREATE PROCEDURE proc1()BEGIN

DECLARE v_filehandle UTL_FILE.FILE_TYPE;DECLARE v_dirAlias VARCHAR(50) DEFAULT 'mydir';DECLARE v_filename VARCHAR(20) DEFAULT 'myfile.csv';DECLARE v_format VARCHAR(200);SET v_format = '%s %s, %s\nSalary: $%s Commission: $%s\n\n';SET v_filehandle = UTL_FILE.FOPEN(v_dirAlias,v_filename,'w');CALL UTL_FILE.PUTF(v_filehandle,v_format,'000030','SALLY','KWAN','40175','3214');CALL DBMS_OUTPUT.PUT_LINE('Wrote to file: ' || v_filename);CALL UTL_FILE.FCLOSE(v_filehandle);

END@

CALL proc1@

This example results in the following output:Wrote formatted text to file: myfile.csv

The formatted file, myfile.csv, contains the following data:000030 SALLY, KWANSalary: $40175 Commission: $3214

UTL_FILE.FILE_TYPEUTL_FILE.FILE_TYPE is a file handle type that is used by routines in theUTL_FILE module.

366 SQL Procedural Languages: Application Enablement and Support

Page 377: IBM DB2 9.7 for Linux, UNIX, And Windows

Example

Declare a variable of type UTL_FILE.FILE_TYPE.DECLARE v_filehandle UTL_FILE.FILE_TYPE;

Chapter 30. UTL_FILE module 367

Page 378: IBM DB2 9.7 for Linux, UNIX, And Windows

368 SQL Procedural Languages: Application Enablement and Support

Page 379: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 31. UTL_MAIL module

The UTL_MAIL module provides the capability to send e-mail.

The schema for this module is SYSIBMADM.

The UTL_MAIL module includes the following routines.

Table 32. System-defined routines available in the UTL_MAIL module

Routine name Description

SEND procedure Packages and sends an e-mail to an SMTPserver.

SEND_ATTACH_RAW procedure Same as the SEND procedure, but withBLOB attachments.

SEND_ATTACH_VARCHAR2 Same as the SEND procedure, but withVARCHAR attachments

Usage notes

In order to successfully send an e-mail using the UTL_MAIL module, the databaseconfiguration parameter SMTP_SERVER must contain one or more valid SMTPserver addresses.

Examples

Example 1: To set up a single SMTP server with the default port 25:db2 update db cfg using smtp_server 'smtp.ibm.com'

Example 2: To set up a single SMTP server that uses port 2000, rather than thedefault port 25:db2 update db cfg using smtp_server 'smtp2.ibm.com:2000'

Example 3: To set a list of SMTP servers:db2 update db cfg using smtp_server

'smtp.example.com,smtp1.example.com:23,smtp2.example.com:2000'

Note: The e-mail is sent to each of the SMTP servers, in the order listed, until asuccessful reply is received from one of the SMTP servers.

SEND procedure - Send an e-mail to an SMTP serverThe SEND procedure provides the capability to send an e-mail to an SMTP server.

Syntax

�� SEND ( sender , recipients , cc , bcc , subject , message �

© Copyright IBM Corp. 1993, 2009 369

Page 380: IBM DB2 9.7 for Linux, UNIX, And Windows

�, mime_type

, priority

) ��

Parameters

senderAn input argument of type VARCHAR(256) that specifies the e-mail address ofthe sender.

recipientsAn input argument of type VARCHAR(32672) that specifies thecomma-separated e-mail addresses of the recipients.

cc An input argument of type VARCHAR(32672) that specifies thecomma-separated e-mail addresses of copy recipients.

bccAn input argument of type VARCHAR(32672) that specifies thecomma-separated e-mail addresses of blind copy recipients.

subjectAn input argument of type VARCHAR(32672) that specifies the subject line ofthe e-mail.

messageAn input argument of type VARCHAR(32672) that specifies the body of thee-mail.

mime_typeAn optional input argument of type VARCHAR(1024) that specifies the MIMEtype of the message. The default is 'text/plain; charset=us-ascii'.

priorityAn optional argument of type INTEGER that specifies the priority of the e-mailThe default value is 3.

Authorization

EXECUTE privilege on the UTL_MAIL module.

Examples

Example 1: The following anonymous block sends a simple e-mail message.BEGIN

DECLARE v_sender VARCHAR(30);DECLARE v_recipients VARCHAR(60);DECLARE v_subj VARCHAR(20);DECLARE v_msg VARCHAR(200);

SET v_sender = '[email protected]';SET v_recipients = '[email protected],[email protected]';SET v_subj = 'Holiday Party';SET v_msg = 'This year''s party is scheduled for Friday, Dec. 21 at ' ||

'6:00 PM. Please RSVP by Dec. 15th.';CALL UTL_MAIL.SEND(v_sender, v_recipients, NULL, NULL, v_subj, v_msg);

END@

This example results in the following output:

370 SQL Procedural Languages: Application Enablement and Support

Page 381: IBM DB2 9.7 for Linux, UNIX, And Windows

BEGINDECLARE v_sender VARCHAR(30);DECLARE v_recipients VARCHAR(60);DECLARE v_subj VARCHAR(20);DECLARE v_msg VARCHAR(200);

SET v_sender = '[email protected]';SET v_recipients = '[email protected],[email protected]';SET v_subj = 'Holiday Party';SET v_msg = 'This year''s party is scheduled for Friday, Dec. 21 at ' ||

'6:00 PM. Please RSVP by Dec. 15th.';CALL UTL_MAIL.SEND(v_sender, v_recipients, NULL, NULL, v_subj, v_msg);

ENDDB20000I The SQL command completed successfully.

SEND_ATTACH_RAW procedure - Send an e-mail with a BLOBattachment to an SMTP server

The SEND_ATTACH_RAW procedure provides the capability to send an e-mail toan SMTP server with a binary attachment.

Syntax

�� SEND_ATTACH_RAW ( sender , recipients , cc , bcc , subject , �

� message , mime_type , priority , attachment �

� [ , att_inline [ , att_mime_type [ , att_filename ] ] ] ) ��

Parameters

senderAn input argument of type VARCHAR(256) that specifies the e-mail address ofthe sender.

recipientsAn input argument of type VARCHAR(32672) that specifies thecomma-separated e-mail addresses of the recipients.

cc An input argument of type VARCHAR(32672) that specifies thecomma-separated e-mail addresses of copy recipients.

bccAn input argument of type VARCHAR(32672) that specifies thecomma-separated e-mail addresses of blind copy recipients.

subjectAn input argument of type VARCHAR(32672) that specifies the subject line ofthe e-mail.

messageAn input argument of type VARCHAR(32672) that specifies the body of thee-mail.

mime_typeAn input argument of type VARCHAR(1024) that specifies the MIME type ofthe message. The default is 'text/plain; charset=us-ascii'.

priorityAn input argument of type INTEGER that specifies the priority of the e-mailThe default value is 3.

Chapter 31. UTL_MAIL module 371

Page 382: IBM DB2 9.7 for Linux, UNIX, And Windows

attachmentAn input argument of type BLOB(10M) that contains the attachment.

att_inlineAn optional input argument of type BOOLEAN that specifies whether theattachment is viewable inline. If set to ″true″, then the attachment is viewableinline, ″false″ otherwise. The default value is ″true″.

att_mime_typeAn optional input argument of type VARCHAR(1024) that specifies the MIMEtype of the attachment. The default value is application/octet.

att_filenameAn optional input argument of type VARCHAR(512) that specifies the filename containing the attachment. The default value is NULL.

Authorization

EXECUTE privilege on the UTL_MAIL module.

SEND_ATTACH_VARCHAR2 procedure - Send an e-mail with aVARCHAR attachment to an SMTP server

The SEND_ATTACH_VARCHAR2 procedure provides the capability to send ane-mail to an SMTP server with a text attachment.

Syntax

�� SEND_ATTACH_VARCHAR2 ( sender , recipients , cc , bcc , subject , �

� message , mime_type , priority , attachment �

� [ , att_inline [ , att_mime_type [ , att_filename ] ] ] ) ��

Parameters

senderAn input argument of type VARCHAR(256) that specifies the e-mail address ofthe sender.

recipientsAn input argument of type VARCHAR(32672) that specifies thecomma-separated e-mail addresses of the recipients.

cc An input argument of type VARCHAR(32672) that specifies thecomma-separated e-mail addresses of copy recipients.

bccAn input argument of type VARCHAR(32672) that specifies thecomma-separated e-mail addresses of blind copy recipients.

subjectAn input argument of type VARCHAR(32672) that specifies the subject line ofthe e-mail.

messageAn input argument of type VARCHAR(32672) that specifies the body of thee-mail.

372 SQL Procedural Languages: Application Enablement and Support

Page 383: IBM DB2 9.7 for Linux, UNIX, And Windows

mime_typeAn input argument of type VARCHAR(1024) that specifies the MIME type ofthe message. The default is 'text/plain; charset=us-ascii'.

priorityAn input argument of type INTEGER that specifies the priority of the e-mailThe default value is 3.

attachmentAn input argument of type VARCHAR(32000) that contains the attachment.

att_inlineAn optional input argument of type BOOLEAN that specifies whether theattachment is viewable inline. If set to ″true″, then the attachment is viewableinline, ″false″ otherwise. The default value is ″true″.

att_mime_typeAn optional input argument of type VARCHAR(1024) that specifies the MIMEtype of the attachment. The default value is 'text/plain; charset=us-ascii'.

att_filenameAn optional input argument of type VARCHAR(512) that specifies the filename containing the attachment. The default value is NULL.

Authorization

EXECUTE privilege on the UTL_MAIL module.

Chapter 31. UTL_MAIL module 373

Page 384: IBM DB2 9.7 for Linux, UNIX, And Windows

374 SQL Procedural Languages: Application Enablement and Support

Page 385: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 32. UTL_SMTP module

The UTL_SMTP module provides the capability to send e-mail over the SimpleMail Transfer Protocol (SMTP).

The UTL_SMTP module includes the following routines.

Table 33. System-defined routines available in the UTL_SMTP module

Routine Name Description

CLOSE_DATA procedure Ends an e-mail message.

COMMAND procedure Execute an SMTP command.

COMMAND_REPLIES procedure Execute an SMTP command where multiplereply lines are expected.

DATA procedure Specify the body of an e-mail message.

EHLO procedure Perform initial handshaking with an SMTPserver and return extended information.

HELO procedure Perform initial handshaking with an SMTPserver.

HELP procedure Send the HELP command.

MAIL procedure Start a mail transaction.

NOOP procedure Send the null command.

OPEN_CONNECTION function Open a connection.

OPEN_CONNECTION procedure Open a connection.

OPEN_DATA procedure Send the DATA command.

QUIT procedure Terminate the SMTP session and disconnect.

RCPT procedure Specify the recipient of an e-mail message.

RSET procedure Terminate the current mail transaction.

VRFY procedure Validate an e-mail address.

WRITE_DATA procedure Write a portion of the e-mail message.

WRITE_RAW_DATA procedure Write a portion of the e-mail messageconsisting of RAW data.

The following table lists the public variables available in the module.

Table 34. System-defined types available in the UTL_SMTP module

Public variable Data type Description

connection RECORD Description of an SMTPconnection.

reply RECORD SMTP reply line.

The CONNECTION record type provides a description of an SMTP connection.ALTER MODULE SYSIBMADM.UTL_SMTP PUBLISH TYPE connection AS ROW(

/* name or IP address of the remote host running SMTP server */host VARCHAR(255),

/* SMTP server port number */

© Copyright IBM Corp. 1993, 2009 375

Page 386: IBM DB2 9.7 for Linux, UNIX, And Windows

port INTEGER,/* transfer timeout in seconds */

tx_timeout INTEGER,);

The REPLY record type provides a description of an SMTP reply line. REPLIES isan array of SMTP reply lines.ALTER MODULE SYSIBMADM.UTL_SMTP PUBLISH TYPE reply AS ROW(

/* 3 digit reply code received from the SMTP server */code INTEGER,

/* the text of the message received from the SMTP server */text VARCHAR(508)

);

Examples

Example 1: The following procedure constructs and sends a text e-mail messageusing the UTL_SMTP module.CREATE OR REPLACE PROCEDURE send_mail (

p_sender VARCHAR2,p_recipient VARCHAR2,p_subj VARCHAR2,p_msg VARCHAR2,p_mailhost VARCHAR2

)IS

v_conn UTL_SMTP.CONNECTION;v_crlf CONSTANT VARCHAR2(2) := CHR(13) || CHR(10);v_port CONSTANT PLS_INTEGER := 25;

BEGINv_conn := UTL_SMTP.OPEN_CONNECTION(p_mailhost,v_port);UTL_SMTP.HELO(v_conn,p_mailhost);UTL_SMTP.MAIL(v_conn,p_sender);UTL_SMTP.RCPT(v_conn,p_recipient);UTL_SMTP.DATA(v_conn, SUBSTR(

'Date: ' || TO_CHAR(SYSDATE,'Dy, DD Mon YYYY HH24:MI:SS') || v_crlf|| 'From: ' || p_sender || v_crlf|| 'To: ' || p_recipient || v_crlf|| 'Subject: ' || p_subj || v_crlf|| p_msg, 1, 32767));

UTL_SMTP.QUIT(v_conn);END;/

CALL send_mail('[email protected]','[email protected]','HolidayParty','Are you planning to attend?','smtp.mycorp.com');

Example 2: The following example uses the OPEN_DATA, WRITE_DATA, andCLOSE_DATA procedures instead of the DATA procedure.CREATE OR REPLACE PROCEDURE send_mail_2 (

p_sender VARCHAR2,p_recipient VARCHAR2,p_subj VARCHAR2,p_msg VARCHAR2,p_mailhost VARCHAR2

)IS

v_conn UTL_SMTP.CONNECTION;v_crlf CONSTANT VARCHAR2(2) := CHR(13) || CHR(10);v_port CONSTANT PLS_INTEGER := 25;

BEGIN

376 SQL Procedural Languages: Application Enablement and Support

Page 387: IBM DB2 9.7 for Linux, UNIX, And Windows

v_conn := UTL_SMTP.OPEN_CONNECTION(p_mailhost,v_port);UTL_SMTP.HELO(v_conn,p_mailhost);UTL_SMTP.MAIL(v_conn,p_sender);UTL_SMTP.RCPT(v_conn,p_recipient);UTL_SMTP.OPEN_DATA(v_conn);UTL_SMTP.WRITE_DATA(v_conn,'From: ' || p_sender || v_crlf);UTL_SMTP.WRITE_DATA(v_conn,'To: ' || p_recipient || v_crlf);UTL_SMTP.WRITE_DATA(v_conn,'Subject: ' || p_subj || v_crlf);UTL_SMTP.WRITE_DATA(v_conn,v_crlf || p_msg);UTL_SMTP.CLOSE_DATA(v_conn);UTL_SMTP.QUIT(v_conn);

END;/

CALL send_mail('[email protected]','[email protected]','HolidayParty','Are you planning to attend?','smtp.mycorp.com');

CLOSE_DATA procedure - End an e-mail messageThe CLOSE_DATA procedure terminates an e-mail message

The procedure terminates an e-mail message by sending the following sequence:<CR><LF>.<CR><LF>

This is a single period at the beginning of a line.

Syntax

�� CLOSE_DATA ( c [ , reply ] ) ��

Parameters

c An input or output argument of type CONNECTION that specifies the SMTPconnection to be closed.

replyAn optional output argument of type REPLY that returns a single reply linefrom the SMTP server. It is the last reply line if multiple reply lines arereturned by the SMTP server.

Authorization

EXECUTE privilege on the UTL_SMTP module.

Usage notes

This procedure can be invoked using function invocation syntax in a PL/SQLassignment statement.

COMMAND procedure - Run an SMTP commandThe COMMAND procedure provides the capability to execute an SMTP command.

Note: Use COMMAND_REPLIES if multiple reply lines are expected to bereturned.

Chapter 32. UTL_SMTP module 377

Page 388: IBM DB2 9.7 for Linux, UNIX, And Windows

Syntax

�� COMMAND ( c , cmd [ , arg , reply ) ��

Parameters

c An input or output argument of type CONNECTION that specifies the SMTPconnection to which the command is to be sent.

cmdAn input argument of type VARCHAR(510) that specifies the SMTP commandto process.

argAn optional input argument of type VARCHAR(32672) that specifies anargument to the SMTP command. The default is NULL.

replyAn optional output argument of type REPLY that returns a single reply linefrom the SMTP server. It is the last reply line if multiple reply lines arereturned by the SMTP server.

Authorization

EXECUTE privilege on the UTL_SMTP module.

Usage notes

This procedure can be invoked using function invocation syntax in a PL/SQLassignment statement.

COMMAND_REPLIES procedure - Run an SMTP command wheremultiple reply lines are expected

The COMMAND_REPLIES function processes an SMTP command that returnsmultiple reply lines.

Note: Use COMMAND if only a single reply line is expected.

Syntax

�� COMMAND_REPLIES ( c , cmd [ , arg , replies ) ��

Parameters

c An input or output argument of type CONNECTION that specifies the SMTPconnection to which the command is to be sent.

cmdAn input argument of type VARCHAR(510) that specifies the SMTP commandto process.

argAn optional input argument of type VARCHAR(32672) that specifies anargument to the SMTP command. The default is NULL.

378 SQL Procedural Languages: Application Enablement and Support

Page 389: IBM DB2 9.7 for Linux, UNIX, And Windows

repliesAn optional output argument of type REPLIES that returns multiple reply linesfrom the SMTP server.

Authorization

EXECUTE privilege on the UTL_SMTP module.

Usage notes

This procedure can be invoked using function invocation syntax in a PL/SQLassignment statement.

DATA procedure - Specify the body of an e-mail messageThe DATA procedure provides the capability to specify the body of the e-mailmessage.

The message is terminated with a <CR><LF>.<CR><LF> sequence.

Syntax

�� DATA ( c , body [ , reply ] ) ��

Parameters

c An input or output argument of type CONNECTION that specifies the SMTPconnection to which the command is to be sent.

bodyAn input argument of type VARCHAR(32000) that specifies the body of thee-mail message to be sent.

replyAn optional output argument of type REPLY that returns a single reply linefrom the SMTP server. It is the last reply line if multiple reply lines arereturned by the SMTP server.

Authorization

EXECUTE privilege on the UTL_SMTP module.

Usage notes

This procedure can be invoked using function invocation syntax in a PL/SQLassignment statement.

EHLO procedure - Perform initial handshaking with an SMTP serverand return extended information

The EHLO procedure performs initial handshaking with the SMTP server afterestablishing the connection.

The EHLO procedure allows the client to identify itself to the SMTP server. TheHELO procedure performs the equivalent functionality, but returns lessinformation about the server.

Chapter 32. UTL_SMTP module 379

Page 390: IBM DB2 9.7 for Linux, UNIX, And Windows

Syntax

�� EHLO ( c , domain [ , replies ] ) ��

Parameters

c An input or output argument of type CONNECTION that specifies theconnection to the SMTP server over which to perform handshaking.

domainAn input argument of type VARCHAR(255) that specifies the domain name ofthe sending host.

repliesAn optional output argument of type REPLIES that return multiple reply linesfrom the SMTP server.

Authorization

EXECUTE privilege on the UTL_SMTP module.

Usage notes

This procedure can be invoked using function invocation syntax in a PL/SQLassignment statement.

HELO procedure - Perform initial handshaking with an SMTP serverThe HELO procedure performs initial handshaking with the SMTP server afterestablishing the connection.

The HELO procedure allows the client to identify itself to the SMTP server. TheEHLO procedure performs the equivalent functionality, but returns moreinformation about the server.

Syntax

�� HELO ( c , domain [ , reply ] ) ��

Parameters

c An input or output argument of type CONNECTION that specifies theconnection to the SMTP server over which to perform handshaking.

domainAn input argument of type VARCHAR(255) that specifies the domain name ofthe sending host.

replyAn optional output argument of type REPLY that returns a single reply linefrom the SMTP server. It is the last reply line if multiple reply lines arereturned by the SMTP server.

Authorization

EXECUTE privilege on the UTL_SMTP module.

380 SQL Procedural Languages: Application Enablement and Support

Page 391: IBM DB2 9.7 for Linux, UNIX, And Windows

Usage notes

This procedure can be invoked using function invocation syntax in a PL/SQLassignment statement.

HELP procedure - Send the HELP commandThe HELP function provides the capability to send the HELP command to theSMTP server.

Syntax

�� HELP ( c [ command , replies ] ) ��

Parameters

c An input or output argument of type CONNECTION that specifies the SMTPconnection to which the command is to be sent.

commandAn optional input argument of type VARCHAR(510) that specifies thecommand about which help is requested.

repliesAn optional output argument of type REPLIES that returns multiple reply linesfrom the SMTP server.

Authorization

EXECUTE privilege on the UTL_SMTP module.

Usage notes

This procedure can be invoked using function invocation syntax in a PL/SQLassignment statement.

MAIL procedure - Start a mail transaction

Syntax

�� MAIL ( c , sender [ , parameters , reply ) ��

Parameters

c An input or output argument of type CONNECTION that specifies theconnection to the SMTP server on which to start a mail transaction.

senderAn input argument of type VARCHAR(256) that specifies the e-mail address ofthe sender.

parametersAn optional input argument of type VARCHAR(32672) that specifies theoptional mail command parameters in the format key=value.

Chapter 32. UTL_SMTP module 381

Page 392: IBM DB2 9.7 for Linux, UNIX, And Windows

replyAn optional output argument of type REPLY that returns a single reply linefrom the SMTP server. It is the last reply line if multiple reply lines arereturned by the SMTP server.

Authorization

EXECUTE privilege on the UTL_SMTP module.

Usage notes

This procedure can be invoked using function invocation syntax in a PL/SQLassignment statement.

NOOP procedure - Send the null commandThe NOOP procedure sends a null command to the SMTP server. The NOOP hasno effect on the server except to obtain a successful response.

Syntax

�� NOOP ( c [ , reply ] ) ��

Parameters

c An input or output argument of type CONNECTION that specifies the SMTPconnection on which to send the command.

replyAn optional output argument of type REPLY that returns a single reply linefrom the SMTP server. It is the last reply line if multiple reply lines arereturned by the SMTP server.

Authorization

EXECUTE privilege on the UTL_SMTP module.

Usage notes

This procedure can be invoked using function invocation syntax in a PL/SQLassignment statement.

OPEN_CONNECTION function - Return a connection handle to anSMTP server

The OPEN_CONNECTION function returns a connection handle to an SMTPserver.

The function returns a connection handle to the SMTP server.

Syntax

�� OPEN_CONNECTION ( host , port , tx_timeout ) ��

382 SQL Procedural Languages: Application Enablement and Support

Page 393: IBM DB2 9.7 for Linux, UNIX, And Windows

Parameters

hostAn input argument of type VARCHAR(255) that specifies the name of theSMTP server.

portAn input argument of type INTEGER that specifies the port number on whichthe SMTP server is listening.

tx_timeoutAn input argument of type INTEGER that specifies the time out value, inseconds. To instruct the procedure not to wait, set this value to 0. To instructthe procedure to wait indefinitely, set this value to NULL.

Authorization

EXECUTE privilege on the UTL_SMTP module.

OPEN_CONNECTION procedure - Open a connection to an SMTPserver

The OPEN_CONNECTION procedure opens a connection to an SMTP server.

Syntax

�� OPEN_CONNECTION ( host , port , connection , tx_timeout , reply ) ��

Parameters

hostAn input argument of type VARCHAR(255) that specifies the name of theSMTP server.

portAn input argument of type INTEGER that specifies the port number on whichthe SMTP server is listening.

connectionAn output argument of type CONNECTION that returns a connection handleto the SMTP server.

tx_timeoutAn optional input argument of type INTEGER that specifies the time outvalue, in seconds. To instruct the procedure not to wait, set this value to 0. Toinstruct the procedure to wait indefinitely, set this value to NULL.

replyAn output argument of type REPLY that returns a single reply line from theSMTP server. It is the last reply line if multiple reply lines are returned by theSMTP server.

Authorization

EXECUTE privilege on the UTL_SMTP module.

Chapter 32. UTL_SMTP module 383

Page 394: IBM DB2 9.7 for Linux, UNIX, And Windows

OPEN_DATA procedure - Send the DATA command to the SMTP serverThe OPEN_DATA procedure sends the DATA command to the SMTP server.

Syntax

�� OPEN_DATA ( c [ , reply ] ) ��

Parameters

c An input argument of type CONNECTION that specifies the SMTP connectionon which to send the command

replyAn optional output argument of type REPLY that returns a single reply linefrom the SMTP server. It is the last reply line if multiple reply lines arereturned by the SMTP server.

Authorization

EXECUTE privilege on the UTL_SMTP module.

Usage notes

This procedure can be invoked using function invocation syntax in a PL/SQLassignment statement.

QUIT procedure - Close the session with the SMTP serverThe QUIT procedure closes the session with an SMTP server.

Syntax

�� QUIT ( c [ , reply ] ) ��

Parameters

c An input or output argument of type CONNECTION that specifies the SMTPconnection to terminate.

replyAn optional output argument of type REPLY that returns a single reply linefrom the SMTP server. It is the last reply line if multiple reply lines arereturned by the SMTP server.

Authorization

EXECUTE privilege on the UTL_SMTP module.

Usage notes

This procedure can be invoked using function invocation syntax in a PL/SQLassignment statement.

384 SQL Procedural Languages: Application Enablement and Support

Page 395: IBM DB2 9.7 for Linux, UNIX, And Windows

RCPT procedure - Provide the e-mail address of the recipientThe RCPT procedure provides the e-mail address of the recipient.

Note: To schedule multiple recipients, invoke the RCPT procedure multiple times.

Syntax

�� RCPT ( c , recipient [ , parameters , reply ] ) ��

Parameters

c An input or output argument of type CONNECTION that specifies the SMTPconnection on which to add a recipient.

recipientAn input argument of type VARCHAR(256) that specifies the e-mail address ofthe recipient.

parametersAn optional input argument of type VARCHAR(32672) that specifies the mailcommand parameters in the format key=value.

replyAn optional output argument of type REPLY that returns a single reply linefrom the SMTP server. It is the last reply line if multiple reply lines arereturned by the SMTP server.

Authorization

EXECUTE privilege on the UTL_SMTP module.

Usage notes

This procedure can be invoked using function invocation syntax in a PL/SQLassignment statement.

RSET procedure - End the current mail transactionThe RSET procedure provides the capability to terminate the current mailtransaction.

Syntax

�� RSET ( c [ , reply ] ) ��

Parameters

c An input or output argument of type CONNECTION that specifies the SMTPconnection on which to cancel the mail transaction.

replyAn optional output argument of type REPLY that returns a single reply linefrom the SMTP server. It is the last reply line if multiple reply lines arereturned by the SMTP server.

Chapter 32. UTL_SMTP module 385

Page 396: IBM DB2 9.7 for Linux, UNIX, And Windows

Authorization

EXECUTE privilege on the UTL_SMTP module.

Usage notes

This procedure can be invoked using function invocation syntax in a PL/SQLassignment statement.

VRFY procedure - Validate and verify the recipient’s e-mail addressThe VRFY function provides the capability to validate and verify a recipient e-mailaddress. If valid, the recipient’s full name and fully qualified mailbox is returned.

Syntax

�� VRFY ( c , recipient , reply ) ��

Parameters

c An input or output argument of type CONNECTION that specifies the SMTPconnection on which to verify the e-mail address.

recipientAn input argument of type VARCHAR(256) that specifies the e-mail address tobe verified.

replyAn output argument of type REPLY that returns a single reply line from theSMTP server. It is the last reply line if multiple reply lines are returned by theSMTP server.

Authorization

EXECUTE privilege on the UTL_SMTP module.

Usage notes

This procedure can be invoked using function invocation syntax in a PL/SQLassignment statement.

WRITE_DATA procedure - Write a portion of an e-mail messageThe WRITE_DATA procedure provides the capability to add data to an e-mailmessage. The WRITE_DATA procedure may be called repeatedly to add data.

Syntax

�� WRITE_DATA ( c , data ) ��

Parameters

c An input or output argument of type CONNECTION that specifies the SMTPconnection on which to add data.

386 SQL Procedural Languages: Application Enablement and Support

Page 397: IBM DB2 9.7 for Linux, UNIX, And Windows

dataAn input argument of type VARCHAR(32000) that specifies the data to beadded to the e-mail message.

Authorization

EXECUTE privilege on the UTL_SMTP module.

WRITE_RAW_DATA procedure - Add RAW data to an e-mail messageThe WRITE_RAW_DATA procedure provides the capability to add data to ane-mail message. The WRITE_RAW_DATA procedure may be called repeatedly toadd data.

Syntax

�� WRITE_RAW_DATA ( c , data ) ��

Parameters

c An input or output argument of type CONNECTION that specifies the SMTPconnection on which to add data.

dataAn input argument of type BLOB(15M) that specifies the data to be added tothe e-mail message.

Authorization

EXECUTE privilege on the UTL_SMTP module.

Chapter 32. UTL_SMTP module 387

Page 398: IBM DB2 9.7 for Linux, UNIX, And Windows

388 SQL Procedural Languages: Application Enablement and Support

Page 399: IBM DB2 9.7 for Linux, UNIX, And Windows

Part 4. DB2 compatibility features

© Copyright IBM Corp. 1993, 2009 389

Page 400: IBM DB2 9.7 for Linux, UNIX, And Windows

390 SQL Procedural Languages: Application Enablement and Support

Page 401: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 33. Introduction to DB2 compatibility features

DB2 Version 9.5 introduced a number of features that greatly simplify the task ofenabling some applications written for different relational database products to runon DB2. DB2 Version 9.7 introduces additional features that reduce this complexityand the time required to enable existing applications even further.

Some of these features, including the following, are enabled by default.v Implicit casting (weak typing), which reduces the amount of SQL that needs to

be modified when applications that currently run on other data servers areenabled for DB2

v New scalar functions. For details, see “Supported functions and administrativeSQL routines and views”.

v Major improvements to the TIMESTAMP_FORMAT and VARCHAR_FORMATscalar functions. (TO_DATE and TO_TIMESTAMP are synonyms forTIMESTAMP_FORMAT, and TO_CHAR is a synonym for VARCHAR_FORMAT.)– TIMESTAMP_FORMAT – This function returns a timestamp that is based on

the interpretation of the input string using the specified format.– VARCHAR_FORMAT – This function returns a string representation of an

input expression that has been formatted according to a specified charactertemplate.

v The lifting of several SQL language restrictions, resulting in compatible syntaxbetween products; for example, the use of correlation names in subqueries andtable functions is now optional

v Synonyms for syntax used by other database products; for example:– UNIQUE is a synonym for DISTINCT in the context of column functions and

the select list of a query– MINUS is a synonym for the EXCEPT set operator– seqname.NEXTVAL and seqname.CURRVAL can be used in place of the SQL

standard syntax NEXT VALUE FOR seqname and PREVIOUS VALUE FORseqname

v Global variables, which can be used to easily map package variables, emulate@@nested, @@level, or @errorlevel global variables, or pass information fromDB2 applications down to triggers, functions, or procedures

v An ARRAY collection data type that can be used to easily map to VARRAYconstructs in SQL procedures

v Increased identifier length limits that facilitate the enablement of applicationsfrom other DBMS vendors on DB2

v The pseudocolumn ROWID that can be used to refer to the RID; an unqualifiedROWID reference is equivalent to RID_BIT() and a qualified ROWID, such asEMPLOYEE.ROWID, is equivalent to RID_BIT(EMPLOYEE)

Other features can be selectively enabled by setting a new DB2 registry variablenamed DB2_COMPATIBILITY_VECTOR. These features are disabled by default.v An implementation of hierarchical queries using CONNECT BY PRIOR syntaxv Support for outer joins using the outer join operator, (+)v Use of the DATE data type as TIMESTAMP(0), a combined date and time valuev Syntax and semantics to support the NUMBER data type

© Copyright IBM Corp. 1993, 2009 391

Page 402: IBM DB2 9.7 for Linux, UNIX, And Windows

v Syntax and semantics to support the VARCHAR2 data typev A pseudocolumn named ROWNUM is a synonym for ROW_NUMBER()

OVER(), but ROWNUM is allowed in the SELECT LIST and in the WHEREclause

v A dummy table named DUAL provides a capability that is similar toSYSIBM.SYSDUMMY1

v Alternate semantics for the TRUNCATE TABLE statement, under whichIMMEDIATE is an optional keyword that is assumed to be the default if notspecified. An implicit commit operation is performed before the TRUNCATEstatement executes if the TRUNCATE statement is not the first statement in thelogical unit of work.

v Support for assignment of the CHAR or GRAPHIC data type (instead of theVARCHAR or VARGRAPHIC data type) to character and graphic stringconstants whose byte length is less than or equal to 254

v Use of collection methods to perform operations on arrays, such as first, last,next, and previous

v Support for the creation of Oracle data dictionary-compatible viewsv Support for the compilation and execution of PL/SQL statements and language

elements

Additional resources

For more information, see DB2 Viper 2 compatibility features.

For information about the IBM Migration Toolkit (MTK), see Migrate Now!.

392 SQL Procedural Languages: Application Enablement and Support

Page 403: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 34. DB2_COMPATIBILITY_VECTOR registry variable

The DB2_COMPATIBILITY_VECTOR registry variable is used to enable one ormore DB2 compatibility features introduced since DB2 Version 9.5.

These features ease the task of migrating applications written for other relationaldatabase vendors to DB2 Version 9.5 or later. This DB2 registry variable isrepresented as a hexadecimal value, and each bit in the variable enables one of theDB2 compatibility features.v Operating systems: Allv Default: NULL; Values: NULL or 00 to FFF. To take full advantage of these DB2

compatibility features, set the value to ORA. This is the recommended setting.

Registry variable settings

Table 35. DB2_COMPATIBILITY_VECTOR values

Bit position Compatibility feature Description

1 (0x01) ROWNUM Enables the use of ROWNUM as asynonym for ROW_NUMBER()OVER(), and permits ROWNUM toappear in the WHERE clause of SQLstatements.

2 (0x02) DUAL Resolves unqualified table referencesto ’DUAL’ as SYSIBM.DUAL.

3 (0x04) Outer join operator Enables support for the outer joinoperator (+).

4 (0x08) Hierarchical queries Enables support for hierarchicalqueries using the CONNECT BYclause.

5 (0x10) NUMBER data type 1 Enables the NUMBER data type andassociated numeric processing.

6 (0x20) VARCHAR2 data type 1 Enables the VARCHAR2 data type andassociated character string processing.

7 (0x40) DATE data type 1 Enables use of the DATE data type asTIMESTAMP(0), a combined date andtime value.

8 (0x80) TRUNCATE TABLE Enables alternate semantics for theTRUNCATE statement, under whichIMMEDIATE is an optional keywordthat is assumed to be the default if notspecified. An implicit commitoperation is performed before theTRUNCATE statement executes if theTRUNCATE statement is not the firststatement in the logical unit of work.

9 (0x100) Character literals Enables the assignment of the CHARor GRAPHIC data type (instead of theVARCHAR or VARGRAPHIC datatype) to character and graphic stringconstants whose byte length is lessthan or equal to 254.

© Copyright IBM Corp. 1993, 2009 393

Page 404: IBM DB2 9.7 for Linux, UNIX, And Windows

Table 35. DB2_COMPATIBILITY_VECTOR values (continued)

Bit position Compatibility feature Description

10 (0x200) Collection methods Enables the use of methods to performoperations on arrays, such as first, last,next, and previous. Also enables theuse of parentheses in place of squarebrackets in references to specificelements in an array; for example,array1(i) refers to element i of array1.

11 (0x400) Data dictionary-compatibleviews 1

Enables the creation of datadictionary-compatible views.

12 (0x800) PL/SQL compilation 2 Enables the compilation and executionof PL/SQL statements and languageelements.

1. Applicable only during database creation. Enabling or disabling this feature only affectssubsequently created databases.

2. See “Restrictions on PL/SQL support”.

Usage

The DB2_COMPATIBILITY_VECTOR registry variable is set and updated usingthe db2set command. To enable all of the supported compatibility features, set theregistry variable to the value ORA (which is equivalent to the hexadecimal valueFFF). This is the recommended setting.

A new setting for the registry variable does not take effect until after the instancehas been stopped and then restarted. Existing DB2 packages must be rebound forthe change to take effect; packages that are not rebound explicitly will pick up thechange on the next implicit rebind.

Example 1

This example sets the registry variable to enable all of the supported compatibilityfeatures:db2set DB2_COMPATIBILITY_VECTOR=ORAdb2stopdb2start

Example 2

This example shows how to disable all compatibility features by resetting theDB2_COMPATIBILITY_VECTOR registry variable:db2set DB2_COMPATIBILITY_VECTOR=db2stopdb2start

Note that if a database has been created with the NUMBER data type or theVARCHAR2 data type enabled, use of the DATE data type as TIMESTAMP(0)enabled, or the creation of Oracle data dictionary-compatible views enabled, thedatabase will still be enabled for these features after this db2set commandexecutes.

394 SQL Procedural Languages: Application Enablement and Support

Page 405: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 35. Setting up DB2 for Oracle application enablement

Oracle applications can be enabled to work with DB2 data servers when the DB2environment is set up appropriately.

Before you begin

v A DB2 data server product must be installed.v You require the authority to issue the db2set command.v You require the authority to issue the CREATE DATABASE command.

About this task

Perform this task if you want to enable Oracle applications in DB2 environments.A DB2 environment will support many commonly referenced features from otherdatabase vendors. This task is a prerequisite for executing PL/SQL statements orSQL statements that reference Oracle data types from DB2 interfaces, or for anyother SQL compatibility features. DB2 compatibility features are enabled at thedatabase level and cannot be disabled.

Procedure

1. Open a DB2 command window.2. Start the DB2 database manager.

db2start

3. Set the DB2_COMPATIBILITY_VECTOR registry variable to the hexadecimalvalue that enables the compatibility features that you want to use. To take fulladvantage of these DB2 compatibility features, set the value to ORA. This is therecommended setting.db2set DB2_COMPATIBILITY_VECTOR=ORA

4. Set the DB2_DEFERRED_PREPARE_SEMANTICS registry variable to YES toenable deferred prepare support. If the DB2_COMPATIBILITY_VECTORregistry variable is set to ORA, and theDB2_DEFERRED_PREPARE_SEMANTICS registry variable is not set, adefault value of YES is used. However, it is recommended that theDB2_DEFERRED_PREPARE_SEMANTICS registry variable be explicitly set toYES.db2set DB2_DEFERRED_PREPARE_SEMANTICS=YES

5. Issue the db2stop command and the db2start command to stop and then restartthe database manager.db2stopdb2start

6. Create your DB2 database by issuing the CREATE DATABASE command. Forexample, to create a database named DB, issue the following command:db2 CREATE DATABASE DB

7. Optional: Run a CLPPlus or command line processor (CLP) script (script.sql)to verify that the database supports PL/SQL statements and data types. Thefollowing CLPPlus script creates a simple procedure and then calls thatprocedure.CONNECT user@hostname:port/dbname;

CREATE TABLE t1 (c1 NUMBER);

© Copyright IBM Corp. 1993, 2009 395

Page 406: IBM DB2 9.7 for Linux, UNIX, And Windows

CREATE OR REPLACE PROCEDURE testdb(num IN NUMBER, message OUT VARCHAR2)ASBEGININSERT INTO t1 VALUES (num);

message := 'The number you passed is: ' || TO_CHAR(num);END;/

CALL testdb(100, ?);

DISCONNECT;EXIT;

To run the CLPPlus script, issue the following command:clpplus @script.sql

The following example shows the CLP version of the same script. This scriptuses the SET SQLCOMPAT PLSQL command to enable recognition of theforward slash character (/) on a new line as a PL/SQL statement terminationcharacter.CONNECT TO DB;

SET SQLCOMPAT PLSQL;

-- Semicolon is used to terminate-- the CREATE TABLE statement:CREATE TABLE t1 (c1 NUMBER);

-- Forward slash on a new line is used to terminate-- the CREATE PROCEDURE statement:CREATE OR REPLACE PROCEDURE testdb(num IN NUMBER, message OUT VARCHAR2)ASBEGININSERT INTO t1 VALUES (num);

message := 'The number you passed is: ' || TO_CHAR(num);END;/

CALL testdb(100, ?);

SET SQLCOMPAT DB2;

CONNECT RESET;

To run the CLP script, issue the following command:db2 -tvf script.sql

Results

The DB2 database that you created is enabled for Oracle applications. Thecompatibility features that you enabled can now be used.

What to do next

v Start using the CLPPlus interface.v Execute PL/SQL scripts and statements.v Transfer database object definitions.v Enable database applications.

396 SQL Procedural Languages: Application Enablement and Support

Page 407: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 36. Data types

DATE data type based on TIMESTAMP(0)The DATE data type is changed to support applications that use the Oracle DATEdata type expecting that the values include time information (for example,’2009-04-01-09.43.05’).

Support for DATE to mean TIMESTAMP(0) is at the database level, and must beenabled before creating the database where support is required. This is achieved bysetting the DB2_COMPATIBILITY_VECTOR registry variable to the appropriatevalue. When a database is created with DATE as TIMESTAMP(0) enabled, thedatabase configuration parameter date_compat is set to ON. After a database iscreated with DATE as TIMESTAMP(0) support enabled, it cannot be disabled forthat database, even if the DB2_COMPATIBILITY_VECTOR registry variable isreset. Similarly, all databases created with DATE as TIMESTAMP(0) supportdisabled cannot have this support enabled, even by setting theDB2_COMPATIBILITY_VECTOR registry variable.

Enablement

DATE as TIMESTAMP(0) support is enabled by setting bit position number 7(0x40) of the DB2_COMPATIBILITY_VECTOR registry variable before creating adatabase. A new setting for the registry variable does not take effect until after theinstance has been stopped and then restarted.

Usage

The following support is enabled for a DB2 database that has the date_compatdatabase configuration parameter set to ON.

When the DATE data type is explicitly encountered in SQL statements, it isimplicitly mapped to TIMESTAMP(0). An exception is the specification of SQLDATE in the xml-index-specification clause of a CREATE INDEX statement. As aresult of this implicit mapping, messages refer to the TIMESTAMP data typeinstead of DATE, and any operations that describe data types for columns orroutines return TIMESTAMP instead of DATE.

Datetime literal support is unchanged in a DB2 database that has the date_compatdatabase configuration parameter set to ON, except in the following cases:v The value of an explicit DATE literal returns a TIMESTAMP(0) value in which

the time portion is all zeros. For example, DATE '2008-04-28' actually representsthe timestamp value ’2008-04-28-00.00.00’.

v The database manager supports additional formats for the string representationof a date, which correspond to ’DD-MON-YYYY’ and ’DD-MON-RR’ in Englishonly (see “TIMESTAMP_FORMAT scalar function” for a description of theformat elements). For example, ’28-APR-2008’ or ’28-APR-08’ can be used asstring representations of a date, which actually represents the TIMESTAMP(0)value ’2008-04-28-00.00.00’.

The CURRENT_DATE (and CURRENT DATE) special register returns aTIMESTAMP(0) value that is the same as CURRENT_TIMESTAMP(0).

© Copyright IBM Corp. 1993, 2009 397

Page 408: IBM DB2 9.7 for Linux, UNIX, And Windows

Adding a numeric value to a TIMESTAMP value or subtracting a numeric valuefrom a TIMESTAMP value assumes that the numeric value represents a number ofdays. The numeric value can have any numeric data type, and any fractional valueis considered to be a fractional portion of a day. For example, TIMESTAMP'2008-03-28 12:00:00' + 1.3 adds 1 day, 7 hours, and 12 minutes to theTIMESTAMP value, resulting in ’2008-03-29 19:12:00’. If you are using expressionsfor partial days, such as 1/24 (1 hour) or 1/24/60 (1 minute), ensure that thenumber_compat database configuration parameter is set to ON so that the divisionis performed using DECFLOAT arithmetic.

The results of some functions are changed under date_compat mode:v The ADD_MONTHS scalar function with a string argument returns

TIMESTAMP(0).v The DATE scalar function returns TIMESTAMP(0) for all input types.v The LAST_DAY scalar function with a string argument returns TIMESTAMP(0).v Other scalar functions that returned DATE based on a DATE input argument

(ADD_MONTHS, LAST_DAY, NEXT_DAY, ROUND, and TRUNCATE) returnTIMESTAMP, because DATE is always a TIMESTAMP(0) under date_compatmode.

v Addition of date values returns TIMESTAMP(0), because date values are reallyTIMESTAMP(0).

v Subtraction of timestamp values returns DECFLOAT(34), representing thedifference as a number of days. Similarly, subtraction of date values returnsDECFLOAT(34), which also represents a number of days, because date valuesare really TIMESTAMP(0).

NUMBER data typeThe NUMBER data type is introduced to support applications that use the OracleNUMBER data type.

Support for NUMBER is at the database level, and must be enabled before creatingthe database where support is required. This is achieved by setting theDB2_COMPATIBILITY_VECTOR registry variable to the appropriate value. Whena database is created with NUMBER enabled, the database configuration parameternumber_compat is set to ON. After a database is created with NUMBER supportenabled, it cannot be disabled for that database, even if theDB2_COMPATIBILITY_VECTOR registry variable is reset. Similarly, all databasescreated without NUMBER support enabled cannot have NUMBER supportenabled, even by setting the DB2_COMPATIBILITY_VECTOR registry variable.

Enablement

NUMBER data type support is enabled by setting bit position number 5 (0x10) ofthe DB2_COMPATIBILITY_VECTOR registry variable before creating a database.To take full advantage of these DB2 compatibility features, set the value to ORA.This is the recommended setting. A new setting for the registry variable does nottake effect until after the instance has been stopped and then restarted.

Usage

The following support is enabled for a DB2 database that has the number_compatdatabase configuration parameter set to ON.

398 SQL Procedural Languages: Application Enablement and Support

Page 409: IBM DB2 9.7 for Linux, UNIX, And Windows

When the NUMBER data type is explicitly encountered in SQL statements, it isimplicitly mapped as follows:v If NUMBER is specified without precision and scale attributes, it is mapped to

DECFLOAT(16).v If NUMBER(p) is specified, it is mapped to DECIMAL(p)v If NUMBER(p,s) is specified, it is mapped to DECIMAL(p,s)

The maximum supported precision is 31, and the scale must be a positive value nogreater than the precision. As a result of this implicit mapping, messages will referto data types DECFLOAT and DECIMAL instead of NUMBER, and any operationsthat describe data types for columns or routines will return either DECIMAL orDECFLOAT instead of NUMBER. Note that DECFLOAT(16) provides a lowermaximum precision than the Oracle NUMBER data type. If more than 16 digits ofprecision are needed for storing numbers in tables, the columns with thisrequirement should be defined explicitly as DECFLOAT(34).

Numeric literal support is unchanged in a DB2 database that has thenumber_compat configuration parameter set to ON. The rules for integer, decimal,and floating-point constants continue to apply. This limits decimal literals to 31digits and floating-point literals to the range of binary double-precisionfloating-point values. A string to DECFLOAT(34) cast (using the CAST specificationor the DECFLOAT function) can be used for values beyond the ranges ofDECIMAL or DOUBLE up to the range of DECFLOAT(34).

When NUMBER data values are cast to character strings (using either the CASTspecification or the VARCHAR or CHAR scalar function), all leading zeros arestripped from the result.

There is currently no support for a numeric literal that ends in either D or F,representing 64-bit binary floating-point and 32-bit binary floating-point values,respectively. A numeric literal that includes an E has the data type of DOUBLE andcan be cast to REAL using the CAST specification or the cast function REAL.

In a DB2 database that has the number_compat configuration parameter set to ON,the default data type that is used for a sequence value in the CREATE SEQUENCEstatement is DECIMAL(27) instead of INTEGER.

In a DB2 database that has the number_compat configuration parameter set to ON,all arithmetic operations and arithmetic or mathematical functions involvingDECIMAL or DECFLOAT data types are effectively performed using decimalfloating-point arithmetic and return a value with a data type of DECFLOAT(34).This also applies to arithmetic operations where both operands have DECIMAL orDECFLOAT(16) data types, which differs from the description of decimalarithmetic in the DB2 SQL Reference. (See “Expressions with arithmetic operators”in “Expressions”.) Additionally, all division operations involving only integer datatypes (SMALLINT, INTEGER, or BIGINT) are effectively performed using decimalfloating-point arithmetic and return a value with a data type of DECFLOAT(34)instead of an integer data type (division by zero with integer operands returnsinfinity and a warning instead of an error).

Function resolution is also changed, such that an argument of data type DECIMALis considered to be a DECFLOAT value during the resolution process. For purposesof function resolution, this effectively treats functions with arguments thatcorrespond to the NUMBER(p[,s]) data type as if the argument data type wereNUMBER.

Chapter 36. Data types 399

Page 410: IBM DB2 9.7 for Linux, UNIX, And Windows

This change in function resolution does not apply to the set of functions that havea variable number of arguments and base their result data type on the set of datatypes of the arguments. The functions included in this set are:v COALESCEv DECODEv GREATESTv LEASTv MAX (scalar)v MIN (scalar)v NVLv VALUE

When the number_compat configuration parameter is set to ON, the rules forresult data types are extended to make DECFLOAT(34) the result data type if theprecision of a DECIMAL result data type would have exceeded 31. These rules alsoapply to corresponding columns in set operations (UNION, EXCEPT(MINUS), andINTERSECT), expression values in the IN list of an IN predicate, andcorresponding expressions of a multiple row VALUES clause.

The rounding mode used for assignments and casts that happen on the databaseserver depends on the data types that are involved. In some cases, truncation isused. In cases where the target is a binary floating-point (REAL or DOUBLE)value, round-half-even is used, as usual. In other cases (usually involving aDECIMAL or DECFLOAT value), the rounding is based on the value of thedecflt_rounding database configuration parameter. This parameter defaults toround-half-even, but can be set to round-half-up to match the Oracle roundingmode. The following table summarizes the rounding that is used for variousnumeric assignments and casts.

Table 36. Rounding for numeric assignments and casts

Source DataType

Target Data Type

integer types DECIMAL DECFLOAT REAL/DOUBLE

integer types not applicable not applicable decflt_rounding round_half_even

DECIMAL decflt_rounding decflt_rounding decflt_rounding round_half_even

DECFLOAT decflt_rounding decflt_rounding decflt_rounding round_half_even

REAL/DOUBLE truncate truncate decflt_rounding round_half_even

string (cast only) not applicable decflt_rounding decflt_rounding round_half_even

The DB2 decimal floating-point values are based on the IEEE 754R standard.Retrieval of DECFLOAT data and casting of DECFLOAT data to character stringsremoves any trailing zeros after the decimal point.

Client-server compatibility considerationsv Client applications working with a DB2 database server that is enabled for

NUMBER data type support never see a NUMBER data type from the server.Any column or expression that might have reported NUMBER from an Oracleserver will report either DECIMAL or DECFLOAT from a DB2 server.

v Because an Oracle environment expects the rounding mode to be round-half-up,it is important that the client rounding mode match the server rounding mode.This means that the db2cli.ini setting should match the value of the

400 SQL Procedural Languages: Application Enablement and Support

Page 411: IBM DB2 9.7 for Linux, UNIX, And Windows

decflt_rounding database configuration parameter. ROUND_HALF_UP shouldbe specified to most closely match the Oracle rounding mode.

Restrictions

NUMBER data type support has the following restrictions:v There is no support for the NUMBER data type with a precision attribute greater

than 31, a precision attribute of asterisk (*), a scale attribute that exceeds theprecision attribute, or a negative scale attribute. There is no correspondingDECIMAL precision and scale support for such data type specifications.

v The trigonometric functions and the DIGITS scalar function cannot be invokedwith arguments of data type NUMBER without a precision (DECFLOAT).

v A distinct type cannot be created with the name NUMBER.

VARCHAR2 data typeThe VARCHAR2 data type is introduced to support applications that use theOracle VARCHAR2 data type.

Support for VARCHAR2 is at the database level, and must be enabled beforecreating the database where support is required. This is achieved by setting theDB2_COMPATIBILITY_VECTOR registry variable to the appropriate value. Whena database is created with VARCHAR2 support enabled, the database configurationparameter varchar2_compat is set to ON. After a database is created withVARCHAR2 support enabled, it cannot be disabled for that database, even if theDB2_COMPATIBILITY_VECTOR registry variable is reset. Similarly, all databasescreated with VARCHAR2 support disabled cannot have VARCHAR2 supportenabled, even by setting the DB2_COMPATIBILITY_VECTOR registry variable.

Enablement

VARCHAR2 data type support is enabled by setting bit position number 6 (0x20)of the DB2_COMPATIBILITY_VECTOR registry variable before creating adatabase. A new setting for the registry variable does not take effect until after theinstance has been stopped and then restarted.

Usage

The following support is enabled for a DB2 database that has the varchar2_compatdatabase configuration parameter set to ON.

When the VARCHAR2 data type is explicitly encountered in SQL statements, it isimplicitly mapped to the VARCHAR data type. The maximum length forVARCHAR2 is the same as the maximum length for VARCHAR (that is, 32 672).

Character string literals up to 254 bytes in length have a data type of CHAR.Character string literals longer than 254 bytes have a data type of VARCHAR.

Any comparisons involving varying-length string types use non-paddedcomparison semantics, and comparisons with only fixed-length string typescontinue to use blank-padded comparison semantics, with two exceptions:v Comparisons involving any string column information from catalog views

always use the IDENTITY collation with blank-padded comparison semantics,regardless of the database collation.

Chapter 36. Data types 401

Page 412: IBM DB2 9.7 for Linux, UNIX, And Windows

v String comparisons involving a data type with the FOR BIT DATA attributealways use the IDENTITY collation with blank-padded comparison semantics.

If the result type for the IN list of an IN predicate would resolve to a fixed-lengthstring data type and the left operand of the IN predicate is a varying-length stringdata type, the IN list expressions are treated as having a varying-length string datatype.

Character string values (other than LOB values) with a length of zero are generallytreated as null values. An assignment or cast of an empty string value to CHAR orVARCHAR produces a null value.

The functions that return character string arguments, or that are based onparameters with character string data types, also treat empty string CHAR orVARCHAR values as null values. Special considerations apply for some functionswhen the varchar2_compat database configuration parameter is set to ON, andthese are listed here.v CONCAT and the concatenation operator. A null or empty string value is

ignored in the concatenated result. The result type of the concatenation is shownin the following table.

Table 37. Data Type and lengths of concatenated operands

Operands

Combinedlengthattributes Result

CHAR(A) CHAR(B) <255 CHAR(A+B)

CHAR(A) CHAR(B) >254 VARCHAR(A+B)

CHAR(A) VARCHAR(B) - VARCHAR(MIN(A+B,32672))

VARCHAR(A) VARCHAR(B) - VARCHAR(MIN(A+B,32672))

CLOB(A) CHAR(B) - CLOB(MIN(A+B, 2G))

CLOB(A) VARCHAR(B) - CLOB(MIN(A+B, 2G))

CLOB(A) CLOB(B) CLOB(MIN(A+B, 2G))

GRAPHIC(A) GRAPHIC(B) <128 GRAPHIC(A+B)

GRAPHIC(A) GRAPHIC(B) >128 VARGRAPHIC(A+B)

GRAPHIC(A) VARGRAPHIC(B) - VARGRAPHIC(MIN(A+B,16336))

VARGRAPHIC(A)VARGRAPHIC(B)

- VARGRAPHIC(MIN(A+B,16336))

DBCLOB(A) CHAR(B) - DBCLOB(MIN(A+B, 1G))

DBCLOB(A) VARCHAR(B) - DBCLOB(MIN(A+B, 1G))

DBCLOB(A) CLOB(B) DBCLOB(MIN(A+B, 1G))

BLOB(A) BLOB(B) - BLOB(MIN(A+B, 2G))

v INSERT. A null value or empty string as the fourth argument results in deletionof the number of bytes indicated by the third argument, beginning at the byteposition indicated by the second argument from the first argument.

v LENGTH. The value returned by the LENGTH function is the number of bytesin the character string. An empty string value returns the null value.

v REPLACE. If all of the argument values have a data type of CHAR, VARCHAR,GRAPHIC, or VARGRAPHIC, then:– A null value or empty string as the second argument is treated as an empty

string, and consequently the first argument is returned as the result

402 SQL Procedural Languages: Application Enablement and Support

Page 413: IBM DB2 9.7 for Linux, UNIX, And Windows

– A null value or empty string as the third argument is treated as an emptystring, and nothing replaces the string that is removed from the source stringby the second argument.

If any argument value has a data type of CLOB or BLOB and any argument isthe null value, the result is the null value. All three arguments of the REPLACEfunction must be specified.

v SUBSTR: References to SUBSTR which have a character string input for the firstargument will be replaced with an invocation to SUBSTRB. References toSUBSTR which have a graphic string input for the first argument are leftunchanged. In this case, there is no support for second argument values lessthan 1, or third argument values less than zero.

v TRANSLATE. The from-string-exp is the second argument, and the to-string-exp isthe third argument. If the to-string-exp is shorter than the from-string-exp, theextra characters in the from-string-exp that are found in the char-string-exp (thefirst argument) are removed; that is, the default pad-char argument is effectivelyan empty string, unless a different pad character is specified in the fourthargument.

v TRIM. If the trim character argument of a TRIM function invocation is a nullvalue or an empty string, the function returns a null value.

In the ALTER TABLE statement or the CREATE TABLE statement, when aDEFAULT clause is specified without an explicit value for a column defined withthe VARCHAR or the VARGRAPHIC data type, the default value is a blankcharacter.

Empty strings are converted to a blank character when the database configurationparameter varchar2_compat is set to ON. For example:v SYSCAT.DATAPARTITIONS.STATUS has a single blank character when the data

partition is visible.v SYSCAT.PACKAGES.PKGVERSION has a single blank character when the

package version has not been explicitly set.v SYSCAT.ROUTINES.COMPILE_OPTIONS has a null value when compile

options have not been set.

Note: If SQL statements use parameter markers, a data type conversion that affectsVARCHAR2 usage can occur. For example, if the input value is a VARCHAR oflength zero and it is converted to a LOB, the result will be a null value. However,if the input value is a LOB of length zero and it is converted to a LOB, the resultwill be a LOB of length zero. The data type of the input value can be affected bydeferred prepare.

Restrictions

The VARCHAR2 data type and associated character string processing support havethe following restrictions:v The VARCHAR2 length attribute qualifiers BYTE and CHAR are not accepted.v The LONG VARCHAR and LONG VARGRAPHIC data types are not supported

(but are not explicitly blocked) when the varchar2_compat databaseconfiguration parameter is set to ON.

Chapter 36. Data types 403

Page 414: IBM DB2 9.7 for Linux, UNIX, And Windows

404 SQL Procedural Languages: Application Enablement and Support

Page 415: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 37. Character and graphic constant handling

An alternate way to parse character or graphic constants is introduced to supportapplications that expect these constants to be assigned the data types CHAR andGRAPHIC, respectively.

Enablement

This support is enabled by setting bit position number 9 (0x100) of theDB2_COMPATIBILITY_VECTOR registry variable. The recommended setting forDB2_COMPATIBILITY_VECTOR is ORA, which sets all of the compatibility bits.

After this support is enabled, character or graphic string constants whose length isless than or equal to 254 bytes have a data type of CHAR or GRAPHIC,respectively. Character or graphic string constants whose length is greater than 254bytes have a data type of VARCHAR or VARGRAPHIC, respectively. Because thisdata type assignment can change the result types of some SQL statements, it isstrongly recommended that this registry variable setting for a database not betoggled.

© Copyright IBM Corp. 1993, 2009 405

Page 416: IBM DB2 9.7 for Linux, UNIX, And Windows

406 SQL Procedural Languages: Application Enablement and Support

Page 417: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 38. Outer join operator

When the DB2_COMPATIBILITY_VECTOR registry variable is set to support theouter join operator, (+), queries can use this alternative syntax within predicates ofthe WHERE clause.

The outer join syntax should be used wherever possible, and the outer joinoperator should be used only when enabling applications from other relationaldatabase vendors on DB2.

The outer join operator, (+), is applied following a column name within predicatesthat generally refer to columns from two table-references.v To write a query that performs a left outer join of tables T1 and T2, include both

tables in the FROM clause separated by a comma, and apply the outer joinoperator to all columns of T2 in predicates that also reference T1. For example:

SELECT * FROM T1LEFT OUTER JOIN T2 ON T1.PK1 = T2.FK1

AND T1.PK2 = T2.FK2

is equivalent to:SELECT * FROM T1, T2

WHERE T1.PK1 = T2.FK1(+)AND T1.PK2 = T2.FK2(+)

v To write a query that performs a right outer join of tables T1 and T2, includeboth tables in the FROM clause separated by a comma, and apply the outer joinoperator to all columns of T1 in predicates that also reference T2. For example:

SELECT * FROM T1RIGHT OUTER JOIN T2 ON T1.FK1 = T2.PK1AND T1.FK2 = T2.PK2

is equivalent to:SELECT * FROM T1, T2

WHERE T1.FK1(+) = T2.PK1AND T1.FK2(+) = T2.PK2

A table-reference that has columns marked with the outer join operator issometimes referred to as a NULL-producer.

A set of predicates separated by AND operators is known as an AND-factor. Ifthere are no AND operators in a WHERE clause, the set of predicates in theWHERE clause is considered to be the only AND-factor.

The following rules apply to the use of the outer join operator.v The WHERE predicate is considered on a granularity of ANDed Boolean factors.v Each Boolean term can refer to at most two table-references; that is, T1.C11 +

T2.C21 = T3.C3(+) is not allowed.v Each table can be the null producer with respect to at most one other table. If a

table is joined to a third table, it must be the outer.v Local predicates, such as T1.A(+) = 5, can exist, but they are executed with the

join. A local predicate without (+) is executed after the join.v Correlation for outer join Boolean terms is not allowed.

© Copyright IBM Corp. 1993, 2009 407

Page 418: IBM DB2 9.7 for Linux, UNIX, And Windows

v The outer join operator cannot be specified in the same subselect as the explicitJOIN syntax.

v The outer join operator can be specified only in the WHERE clause on columnsassociated with table-references that are specified in the FROM clause of thesame subselect.

v An AND-factor can have only one table-reference as a NULL-producer. Eachcolumn reference followed by the outer join operator must be from the sametable-reference.

v An AND-factor that includes an outer join operator can reference at most twotable-references.

v If multiple AND-factors are required for the outer join between two tables, theouter join operator must be specified in all of these AND-factors. If anAND-factor does not specify the outer join operator, it is processed on the resultof the outer join.

v The outer join operator cannot be applied to an entire expression. Within anAND-factor, each column reference from the same table must be followed by theouter join operator (for example, T1.COL1 (+) - T1.COL2 (+) = T2.COL1).

v An AND-factor with predicates that involve only one table-reference can specifythe outer join operator if there is at least one other AND-factor that involves thesame table-reference as the NULL-producer and involves another table-referenceas the outer table.

v An AND-factor with predicates involving only one table-reference and withoutan outer join operator is processed on the result of the join.

v A table-reference can be used only once as the NULL-producer for one othertable-reference within a query.

v The same table-reference cannot be used as both the outer table and theNULL-producer in separate outer joins that form a cycle. A cycle can be formedacross multiple joins when the chain of predicates comes back to an earliertable-reference. For example:SELECT ... FROM T1,T2,T3

WHERE T1.a1 = T2.b2(+)AND T2.b2 = T3.c3(+)AND T3.c3 = T1.a1(+) -- invalid cycle

This example starts with T1 as the outer table in the first predicate and thencycles back to T1 in the third predicate. Note that T2 is used as both theNULL-producer in the first predicate and the outer table in the second predicate,but this usage is not itself a cycle.

v An AND-factor that includes an outer join operator must follow the rules for ajoin-condition of an ON clause defined under joined-table.

v The outer join operator can only be specified in the WHERE clause on columnsthat are associated with table-references specified in the FROM clause of thesame subselect.

408 SQL Procedural Languages: Application Enablement and Support

Page 419: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 39. Hierarchical queries

Hierarchical queries are a form of recursive query that provides support forretrieving a hierarchy, such as a bill of materials, from relational data using aCONNECT BY clause.

Hierarchical query support is enabled through the setting of theDB2_COMPATIBILITY_VECTOR registry variable. This allows the CONNECT BYsyntax to be specified, including the use of pseudocolumns (see “Pseudocolumns”),unary operators (see “Unary operators”), and the SYS_CONNECT_BY_PATH scalarfunction.

Connect-by recursion uses the same subquery for the seed (start) and the recursivestep (connect). This combination provides a concise method of representingrecursions such as, for example, bills-of-material, reports-to-chains, or emailthreads.

Connect-by recursion returns an error if a cycle occurs. A cycle occurs when a rowproduces itself, either directly or indirectly. Using the optional CONNECT BYNOCYCLE clause, the recursion can be directed to ignore the duplicated row, thusavoiding both the cycle and the error. For more information about mappinghierarchical queries to DB2 recursion, see Port CONNECT BY to DB2.

Pseudocolumns

A pseudocolumn is a qualified or unqualified identifier that has meaning in aspecific context and shares the same namespace as columns and variables. If anunqualified identifier does not identify a column or a variable, it is checked to seeif it identifies a pseudocolumn.

LEVEL is a pseudocolumn for use in hierarchical queries. The LEVELpseudocolumn returns the recursive step in the hierarchy at which a row wasproduced. All rows produced by the START WITH clause return the value 1. Rowsproduced by applying the first iteration of the CONNECT BY clause return 2, andso on. The data type of the column is INTEGER NOT NULL.

LEVEL must be specified in the context of a hierarchical query but cannot bespecified in the START WITH clause, as an argument of the CONNECT_BY_ROOToperator, or as an argument of the SYS_CONNECT_BY_PATH function (SQLSTATE428H4).

Unary operators

Unary operators in support of hierarchical queries include:v CONNECT_BY_ROOTv PRIOR

Functions

New functions in support of hierarchical queries include:v SYS_CONNECT_BY_PATH scalar function

© Copyright IBM Corp. 1993, 2009 409

Page 420: IBM DB2 9.7 for Linux, UNIX, And Windows

Subselect

Hierarchical query support includes the following extensions to the subselect.v The subselect includes a new “hierarchical-query-clause”v The clauses of the subselect are processed in the following sequence:

1. FROM clause2. hierarchical-query-clause

3. WHERE clause4. GROUP BY clause5. HAVING clause6. SELECT clause7. ORDER BY clause8. FETCH FIRST clause

v If the subselect includes a hierarchical-query-clause, special rules apply for theorder of processing the predicates in the WHERE clause. The search-condition isfactored into predicates along its AND conditions (conjunction). If a predicate isan implicit join predicate (that is, it references more than one table in the FROMclause), the predicate is applied before the hierarchical-query-clause. Any predicatereferencing at most one table in the FROM clause is applied to the intermediateresult table of the hierarchical-query-clause.A hierarchical query involving joins should be written using explicit joinedtables with an ON clause to avoid confusion about the application of WHEREclause predicates.

v The new ORDER SIBLINGS BY clause can be specified if the subselect includes ahierarchical-query-clause. This clause specifies that the ordering applies only tosiblings within the hierarchies.

hierarchical-query-clause

�� * * connect-by-clause *

start-with-clause��

start-with-clause:

START WITH search-condition

connect-by-clause:

CONNECT BY search-conditionNOCYCLE

A subselect that includes a hierarchical-query-clause is called a hierarchical query.After establishing a first intermediate result table H1, subsequent intermediateresult tables H2, H3, and so forth are generated by joining Hn with R using theconnect-by-clause as a join condition to produce Hn+1. R is the result of the FROMclause of the subselect and any join predicates in the WHERE clause. The processstops when Hn+1 has yielded an empty result table. The result table H of thehierarchical-query-clause is the UNION ALL of every Hi.

410 SQL Procedural Languages: Application Enablement and Support

Page 421: IBM DB2 9.7 for Linux, UNIX, And Windows

The start-with-clause specifies the intermediate result table H1 for the hierarchicalquery that consists of those rows of R for which the search-condition is true. If thestart-with-clause is not specified, H1 is the entire intermediate result table R.

The connect-by-clause produces the intermediate result table Hn+1 from Hn by joiningHn with R, using the search condition.

The unary operator PRIOR is used to distinguish column references to Hn, the lastprior recursive step, from column references to R. For example:

CONNECT BY MGRID = PRIOR EMPID

MGRID is resolved with R, and EMPID is resolved within the previousintermediate result table Hn.

The rules for the search-condition within the start-with-clause and theconnect-by-clause are the same as those within the WHERE clause, except thatOLAP specifications cannot be specified in the connect-by-clause (SQLSTATE 42903).

If the intermediate result table Hn+1 would return a row from R for a hierarchicalpath that is the same as a row from R that is already in that hierarchical path, anerror is returned (SQLSTATE 560CO).

If the NOCYCLE keyword is specified, an error is not returned, but the repeatedrow is not included in the intermediate result table Hn+1.

DB2 supports a maximum of 64 levels of recursion (SQLSTATE 54066).

A subselect that is a hierarchical query returns the intermediate result set in apartial order, unless that order is destroyed through the use of an explicit ORDERBY clause, a GROUP BY or HAVING clause, or a DISTINCT keyword in the selectlist. The partial order returns rows, such that rows produced in Hn+1 for a givenhierarchy immediately follow the row in Hn that produced them. The ORDERSIBLINGS BY clause can be used to enforce order within a set of rows produced bythe same parent.

Restrictions on the use of hierarchical queriesv A hierarchical query is not supported in a materialized query table (SQLSTATE

428EC).v The CONNECT BY clause cannot be used in conjunction with XML functions or

XQuery (SQLSTATE 428H4).v A NEXT VALUE expression for a sequence cannot be specified in (SQLSTATE

428F9):– The parameter list of the CONNECT_BY_ROOT operator or a

SYS_CONNECT_BY_PATH function– START WITH and CONNECT BY clauses

Examplesv The following reports-to-chain example illustrates connect-by recursion. The

example is based on a table named MY_EMP, which is created and populatedwith data as follows:CREATE TABLE MY_EMP(

EMPID INTEGER NOT NULL PRIMARY KEY,NAME VARCHAR(10),SALARY DECIMAL(9, 2),MGRID INTEGER);

Chapter 39. Hierarchical queries 411

Page 422: IBM DB2 9.7 for Linux, UNIX, And Windows

INSERT INTO MY_EMP VALUES ( 1, 'Jones', 30000, 10);INSERT INTO MY_EMP VALUES ( 2, 'Hall', 35000, 10);INSERT INTO MY_EMP VALUES ( 3, 'Kim', 40000, 10);INSERT INTO MY_EMP VALUES ( 4, 'Lindsay', 38000, 10);INSERT INTO MY_EMP VALUES ( 5, 'McKeough', 42000, 11);INSERT INTO MY_EMP VALUES ( 6, 'Barnes', 41000, 11);INSERT INTO MY_EMP VALUES ( 7, 'O''Neil', 36000, 12);INSERT INTO MY_EMP VALUES ( 8, 'Smith', 34000, 12);INSERT INTO MY_EMP VALUES ( 9, 'Shoeman', 33000, 12);INSERT INTO MY_EMP VALUES (10, 'Monroe', 50000, 15);INSERT INTO MY_EMP VALUES (11, 'Zander', 52000, 16);INSERT INTO MY_EMP VALUES (12, 'Henry', 51000, 16);INSERT INTO MY_EMP VALUES (13, 'Aaron', 54000, 15);INSERT INTO MY_EMP VALUES (14, 'Scott', 53000, 16);INSERT INTO MY_EMP VALUES (15, 'Mills', 70000, 17);INSERT INTO MY_EMP VALUES (16, 'Goyal', 80000, 17);INSERT INTO MY_EMP VALUES (17, 'Urbassek', 95000, NULL);

The following query returns all employees working for Goyal, as well as someadditional information, such as the reports-to-chain:

1 SELECT NAME,2 LEVEL,3 SALARY,4 CONNECT_BY_ROOT NAME AS ROOT,5 SUBSTR(SYS_CONNECT_BY_PATH(NAME, ':'), 1, 25) AS CHAIN6 FROM MY_EMP7 START WITH NAME = 'Goyal'8 CONNECT BY PRIOR EMPID = MGRID9 ORDER SIBLINGS BY SALARY;

NAME LEVEL SALARY ROOT CHAIN---------- ----------- ----------- ----- ---------------Goyal 1 80000.00 Goyal :GoyalHenry 2 51000.00 Goyal :Goyal:HenryShoeman 3 33000.00 Goyal :Goyal:Henry:ShoemanSmith 3 34000.00 Goyal :Goyal:Henry:SmithO'Neil 3 36000.00 Goyal :Goyal:Henry:O'NeilZander 2 52000.00 Goyal :Goyal:ZanderBarnes 3 41000.00 Goyal :Goyal:Zander:BarnesMcKeough 3 42000.00 Goyal :Goyal:Zander:McKeoughScott 2 53000.00 Goyal :Goyal:Scott

Lines 7 and 8 comprise the core of the recursion: The optional START WITHclause describes the WHERE clause that is to be used on the source table to seedthe recursion. In this case, only the row for employee Goyal is selected. If theSTART WITH clause is omitted, the entire source table is used to seed therecursion. The CONNECT BY clause describes how, given the existing rows, thenext set of rows is to be found. The unary operator PRIOR is used to distinguishvalues in the previous step from those in the current step. PRIOR identifiesEMPID as the employee ID of the previous recursive step, and MGRID asoriginating from the current recursive step.LEVEL in line 2 is a pseudocolumn that describes the current level of recursion.CONNECT_BY_ROOT is a unary operator that always returns the value of itsargument as it was during the first recursive step; that is, the values that arereturned by an explicit or implicit START WITH clause.SYS_CONNECT_BY_PATH() is a binary function that prepends the secondargument to the first and then appends the result to the value that it producedin the previous recursive step. The arguments must be character types.Unless explicitly overridden, connect-by recursion returns a result set in a partialorder; that is, the rows that are produced by a recursive step always follow therow that produced them. Siblings at the same level of recursion have no specific

412 SQL Procedural Languages: Application Enablement and Support

Page 423: IBM DB2 9.7 for Linux, UNIX, And Windows

order. The ORDER SIBLINGS BY clause in line 9 defines an order for thesesiblings, which further refines the partial order, potentially into a total order.

v Return the organizational structure of the DEPARTMENT table. Use the level ofthe department to visualize the hierarchy.

SELECT LEVEL, CAST(SPACE((LEVEL - 1) * 4) || '/' || DEPTNAMEAS VARCHAR(40)) AS DEPTNAME

FROM DEPARTMENTSTART WITH DEPTNO = 'A00'CONNECT BY NOCYCLE PRIOR DEPTNO = ADMRDEPT

The query returns:LEVEL DEPTNAME----------- ----------------------------------------

1 /SPIFFY COMPUTER SERVICE DIV.2 /PLANNING2 /INFORMATION CENTER2 /DEVELOPMENT CENTER3 /MANUFACTURING SYSTEMS3 /ADMINISTRATION SYSTEMS2 /SUPPORT SERVICES3 /OPERATIONS3 /SOFTWARE SUPPORT3 /BRANCH OFFICE F23 /BRANCH OFFICE G23 /BRANCH OFFICE H23 /BRANCH OFFICE I23 /BRANCH OFFICE J2

CONNECT_BY_ROOT unary operatorThe CONNECT_BY_ROOT unary operator is for use only in hierarchical queries(SQLSTATE 428H4). For every row in the hierarchy, this operator returns theexpression for the row’s root ancestor.

�� CONNECT_BY_ROOT expression ��

expressionAn expression that does not contain a NEXT VALUE expression, anhierarchical query construct (such as the LEVEL pseudocolumn), theSYS_CONNECT_BY_PATH function, or an OLAP function (SQLSTATE 428H4).

The result type of the operator is the result type of the expression.

Rules:v A CONNECT_BY_ROOT operator cannot be specified in the START WITH

clause or the CONNECT BY clause of a hierarchical query (SQLSTATE 428H4).v A CONNECT_BY_ROOT operator cannot be specified as an argument to the

SYS_CONNECT_BY_PATH function (SQLSTATE 428H4).

Notes:v A CONNECT_BY_ROOT operator has a higher precedence than any infix

operator. Therefore, to pass an expression with infix operators (such as + or ||)as an argument, parentheses must be used. For example:

CONNECT_BY_ROOT FIRSTNME || LASTNAME

Chapter 39. Hierarchical queries 413

Page 424: IBM DB2 9.7 for Linux, UNIX, And Windows

returns the FIRSTNME value of the root ancestor row concatenated with theLASTNAME value of the actual row in the hierarchy, because this expression isequivalent to:

(CONNECT_BY_ROOT FIRSTNME) || LASTNAME

rather than:CONNECT_BY_ROOT (FIRSTNME || LASTNAME)

Example:v Return the hierarchy of departments and their root departments in the

DEPARTMENT table.SELECT CONNECT_BY_ROOT DEPTNAME AS ROOT, DEPTNAME

FROM DEPARTMENT START WITH DEPTNO IN ('B01','C01','D01','E01')CONNECT BY PRIOR DEPTNO = ADMRDEPT

This query returns:ROOT DEPTNAME------------------ -----------------------PLANNING PLANNINGINFORMATION CENTER INFORMATION CENTERDEVELOPMENT CENTER DEVELOPMENT CENTERDEVELOPMENT CENTER MANUFACTURING SYSTEMSDEVELOPMENT CENTER ADMINISTRATION SYSTEMSSUPPORT SERVICES SUPPORT SERVICESSUPPORT SERVICES OPERATIONSSUPPORT SERVICES SOFTWARE SUPPORTSUPPORT SERVICES BRANCH OFFICE F2SUPPORT SERVICES BRANCH OFFICE G2SUPPORT SERVICES BRANCH OFFICE H2SUPPORT SERVICES BRANCH OFFICE I2SUPPORT SERVICES BRANCH OFFICE J2

PRIOR unary operatorThe PRIOR unary operator is for use only in the CONNECT BY clause ofhierarchical queries (SQLSTATE 428H4).

�� PRIOR expression ��

The CONNECT BY clause performs an inner join between the intermediate resulttable Hn of the hierarchical query and the source result table specified in theFROM clause. All column references to tables that are referenced in the FROMclause, and which are arguments to the PRIOR operator, are considered to beranging over Hn.

The primary key of the intermediate result table Hn is typically joined to theforeign keys of the source result table to recursively traverse the hierarchy.

CONNECT BY PRIOR T.PK = T.FK

If the primary key is a composite key, care must be taken to prefix each columnwith PRIOR:

CONNECT BY PRIOR T.PK1 = T.FK1 AND PRIOR T.PK2 = T.FK2

expressionAny expression that does not contain a NEXT VALUE expression, anhierarchical query construct (such as the LEVEL pseudocolumn), theSYS_CONNECT_BY_PATH function, or an OLAP function (SQLSTATE 428H4).

414 SQL Procedural Languages: Application Enablement and Support

Page 425: IBM DB2 9.7 for Linux, UNIX, And Windows

The result data type of the operator is the result data type of the expression.

Notes:v A PRIOR operator has a higher precedence than any infix operator. Therefore, to

pass an expression with infix operators (such as + or ||) as an argument,parentheses must be used. For example:

PRIOR FIRSTNME || LASTNAME

returns the FIRSTNME value of the prior row concatenated with theLASTNAME value of the actual row in the hierarchy, because this expression isequivalent to:

(PRIOR FIRSTNME) || LASTNAME

rather than:PRIOR (FIRSTNME || LASTNAME)

Example:v Return the hierarchy of departments in the DEPARTMENT table.

SELECT LEVEL, DEPTNAMEFROM DEPARTMENT START WITH DEPTNO = 'A00'CONNECT BY NOCYCLE PRIOR DEPTNO = ADMRDEPT

This query returns:LEVEL DEPTNAME----------- ----------------------------------------

1 SPIFFY COMPUTER SERVICE DIV.2 PLANNING2 INFORMATION CENTER2 DEVELOPMENT CENTER3 MANUFACTURING SYSTEMS3 ADMINISTRATION SYSTEMS2 SUPPORT SERVICES3 OPERATIONS3 SOFTWARE SUPPORT3 BRANCH OFFICE F23 BRANCH OFFICE G23 BRANCH OFFICE H23 BRANCH OFFICE I23 BRANCH OFFICE J2

SYS_CONNECT_BY_PATHThe SYS_CONNECT_BY_PATH function (in the SYSIBM schema) is used inhierarchical queries to build a string representing a path from the root row to thisrow.

�� SYS_CONNECT_BY_PATH ( string-expression1 , string-expression2 ) ��

The string for a given row at LEVEL n is built as follows:v Step 1 (using the values of the root row from the first intermediate result table

H1):path1 := string-expression2 || string-expression1

v Step n (based on the row from the intermediate result table Hn):pathn := pathn-1 || string-expression2 || string-expression1

Chapter 39. Hierarchical queries 415

Page 426: IBM DB2 9.7 for Linux, UNIX, And Windows

string-expression1A character string expression that identifies the row. The expression must notinclude a NEXT VALUE expression for a sequence (SQLSTATE 428F9), anyhierarchical query construct, such as the LEVEL pseudocolumn or theCONNECT_BY_ROOT operator (SQLSTATE 428H4), an OLAP function, or anaggregate function (SQLSTATE 428H4).

string-expression2A constant string that serves as a separator. The expression must not include aNEXT VALUE expression for a sequence (SQLSTATE 428F9), any hierarchicalquery construct, such as the LEVEL pseudocolumn or theCONNECT_BY_ROOT operator (SQLSTATE 428H4), an OLAP function, or anaggregate function (SQLSTATE 428H4).

The result is a varying-length character string. The length attribute of the resultdata type is the greater of 1000 and the length attribute of string-expression1.

Rules:v The SYS_CONTEXT_BY_PATH function must not be used outside of the context

of a hierarchical query (SQLSTATE 428H4).v The function cannot be used in a START WITH clause or a CONNECT BY clause

(SQLSTATE 428H4).

Example:v Return the hierarchy of departments in the DEPARTMENT table.

SELECT CAST(SYS_CONNECT_BY_PATH(DEPTNAME, '/')AS VARCHAR(76)) AS ORG

FROM DEPARTMENT START WITH DEPTNO = 'A00'CONNECT BY NOCYCLE PRIOR DEPTNO = ADMRDEPT

This query returns:ORG-----------------------------------------------------------------------/SPIFFY COMPUTER SERVICE DIV./SPIFFY COMPUTER SERVICE DIV./PLANNING/SPIFFY COMPUTER SERVICE DIV./INFORMATION CENTER/SPIFFY COMPUTER SERVICE DIV./DEVELOPMENT CENTER/SPIFFY COMPUTER SERVICE DIV./DEVELOPMENT CENTER/MANUFACTURING SYSTEMS/SPIFFY COMPUTER SERVICE DIV./DEVELOPMENT CENTER/ADMINISTRATION SYSTEMS/SPIFFY COMPUTER SERVICE DIV./SUPPORT SERVICES/SPIFFY COMPUTER SERVICE DIV./SUPPORT SERVICES/OPERATIONS/SPIFFY COMPUTER SERVICE DIV./SUPPORT SERVICES/SOFTWARE SUPPORT/SPIFFY COMPUTER SERVICE DIV./SUPPORT SERVICES/BRANCH OFFICE F2/SPIFFY COMPUTER SERVICE DIV./SUPPORT SERVICES/BRANCH OFFICE G2/SPIFFY COMPUTER SERVICE DIV./SUPPORT SERVICES/BRANCH OFFICE H2/SPIFFY COMPUTER SERVICE DIV./SUPPORT SERVICES/BRANCH OFFICE I2/SPIFFY COMPUTER SERVICE DIV./SUPPORT SERVICES/BRANCH OFFICE J2

416 SQL Procedural Languages: Application Enablement and Support

Page 427: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 40. Database configuration parameters

New database configuration parameters indicate the status of several compatibilityfeatures.

The new parameters include:v date_compat, which indicates whether the DATE compatibility semantics

associated with the TIMESTAMP(0) data type are applied to the connecteddatabase

v number_compat, which indicates whether the compatibility semantics associatedwith the NUMBER data type are applied to the connected database

v varchar2_compat, which indicates whether the compatibility semanticsassociated with the VARCHAR2 data type are applied to the connected database

The value of each of these parameters is determined at database creation time, andis based on the setting of the DB2_COMPATIBILITY_VECTOR registry variable.The value cannot be changed.

© Copyright IBM Corp. 1993, 2009 417

Page 428: IBM DB2 9.7 for Linux, UNIX, And Windows

418 SQL Procedural Languages: Application Enablement and Support

Page 429: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 41. ROWNUM pseudocolumn

DB2 converts any unresolved and unqualified column reference to ROWNUM tothe OLAP specification ROW_NUMBER() OVER().

ROWNUM pseudocolumn support is enabled through the setting of theDB2_COMPATIBILITY_VECTOR registry variable.

Both ROWNUM and ROW_NUMBER() OVER() are allowed in the WHERE clauseof a subselect, and are useful for restricting the size of a result set.

If ROWNUM is used in the WHERE clause, and there is an ORDER BY clause inthe same subselect, the ordering is applied before the ROWNUM predicate isevaluated. This is also true for a ROW_NUMBER() OVER() function in the WHEREclause.

If the OLAP specification ROW_NUMBER() OVER() is used in the WHERE clause,neither a window-order-clause nor a window-partition-clause can be specified.

Notesv Before translating an unqualified reference to ’ROWNUM’ as ROW_NUMBER()

OVER(), DB2 attempts to resolve the reference as one of:– A column within the current SQL query– A local variable– A routine parameter– A global variable

v Avoid using ’ROWNUM’ as a column name or a variable name whileROWNUM pseudocolumn support is enabled.

Example 1

Set the DB2_COMPATIBILITY_VECTOR registry variable to support anapplication using ROWNUM and outer join operator queries. To achieve maximumcompatibility with Oracle, set the value to ORA. This is the recommended setting.

db2set DB2_COMPATIBILITY_VECTOR=ORAdb2stopdb2start

The new setting does not take effect until after the instance has been stopped andthen restarted.

Example 2

Assuming that ROWNUM pseudocolumn support is enabled for the connecteddatabase, retrieve the twentieth to the fortieth row of a result set that is stored in atemporary table.

SELECT TEXT FROM SESSION.SEARCHRESULTSWHERE ROWNUM BETWEEN 20 AND 40ORDER BY ID

Note that ROWNUM is affected by the ORDER BY clause.

© Copyright IBM Corp. 1993, 2009 419

Page 430: IBM DB2 9.7 for Linux, UNIX, And Windows

420 SQL Procedural Languages: Application Enablement and Support

Page 431: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 42. DUAL table

The DB2 data server resolves any unqualified table reference to “DUAL” as abuilt-in view returning one row and one column named “DUMMY”, whose valueis ’X’.

If a user-defined table named DUAL exists, the DB2 server resolves a tablereference to the user-defined table only if the reference is explicitly qualified.

Example 1

Generate a random number by selecting from DUAL.SELECT RAND() AS RANDOM_NUMBER FROM DUAL

Example 2

Retrieve the value of the CURRENT SCHEMA special register.SET SCHEMA = MYSCHEMA;SELECT CURRENT SCHEMA AS CURRENT_SCHEMA FROM DUAL;

© Copyright IBM Corp. 1993, 2009 421

Page 432: IBM DB2 9.7 for Linux, UNIX, And Windows

422 SQL Procedural Languages: Application Enablement and Support

Page 433: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 43. Currently committed semantics improveconcurrency

Lock timeouts and deadlocks can occur under the CS isolation level with row-levellocking, especially with applications that are not designed to prevent suchproblems. Some high throughput database applications cannot tolerate waiting onlocks that are issued during transaction processing, and some applications cannottolerate processing uncommitted data, but still require non-blocking behavior forread transactions.

Under the new currently committed semantics, only committed data is returned, aswas the case previously, but now readers do not wait for writers to release rowlocks. Instead, readers return data that is based on the currently committedversion; that is, data prior to the start of the write operation.

Currently committed semantics are turned on by default for new databases. Thisallows any application to take advantage of the new behavior, and no changes tothe application itself are required. The new database configuration parametercur_commit can be used to override this behavior. This might be useful, forexample, in the case of applications that require blocking on writers to synchronizeinternal logic.

Similarly, upgraded databases have cur_commit disabled by default in caseapplications require blocking writers to synchronize their internal logic, and thisparameter can be turned on later, if so desired.

Currently committed semantics apply only to read-only scans that do not involvecatalog tables or the internal scans that are used to evaluate or enforce constraints.Note that, because currently committed is decided at the scan level, a writer’saccess plan might include currently committed scans. For example, the scan for aread-only subquery can involve currently committed semantics. Because currentlycommitted semantics obey isolation level semantics, applications running undercurrently committed semantics continue to respect isolation levels.

Currently committed semantics require increased log space for writers. Additionalspace is required for logging the first update of a data row during a transaction.This data is required for retrieving the currently committed image of the row.Depending on the workload, this can have an insignificant or measurable impacton the total log space used. The requirement for additional log space does notapply when cur_commit is disabled.

Example

Consider the following scenario, in which deadlocks are avoided under thecurrently committed semantics. In this scenario, two applications update twoseparate tables, but do not yet commit. Each application then attempts to read(with a read-only cursor) from the table that the other application has updated.

Step Application A Application B

1 update T1 set col1 = ? wherecol2 = ?

update T2 set col1 = ? wherecol2 = ?

© Copyright IBM Corp. 1993, 2009 423

Page 434: IBM DB2 9.7 for Linux, UNIX, And Windows

Step Application A Application B

2 select col1, col3, col4 from T2where col2 >= ?

select col1, col5, from T1where col5 = ? and col2 = ?

3 commit commit

Without currently committed semantics, these applications running under thecursor stability isolation level might create a deadlock, causing one of theapplications to fail. This happens when each application needs to read data that isbeing updated by the other application.

Under currently committed semantics, if the query in step 2 (for either application)happens to require the data currently being updated by the other application, thatapplication does not wait for the lock to be released, making a deadlockimpossible. The previously committed version of the data is located and usedinstead.

424 SQL Procedural Languages: Application Enablement and Support

Page 435: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 44. Oracle data dictionary-compatible views

When the DB2_COMPATIBILITY_VECTOR registry variable is set to supportOracle data dictionary-compatible views, the views are automatically created whenthe database is created.

Support for Oracle data dictionary-compatible views is at the database level, andmust be enabled before creating the database where support is required. The datadictionary definition includes CREATE VIEW, CREATE PUBLIC SYNONYM, andCOMMENT statements for each view that is compatible with Oracle’s datadictionary. These views, which are created in the SYSIBMADM schema, are listedin Table 38.

Table 38. Oracle data dictionary-compatible viewsCategory Defined views

General DICTIONARY, DICT_COLUMNSUSER_CATALOG, DBA_CATALOG, ALL_CATALOGUSER_DEPENDENCIES, DBA_DEPENDENCIES, ALL_DEPENDENCIESUSER_OBJECTS, DBA_OBJECTS, ALL_OBJECTSUSER_SEQUENCES, DBA_SEQUENCES, ALL_SEQUENCESUSER_TABLESPACES, DBA_TABLESPACES

Tables or views USER_CONSTRAINTS, DBA_CONSTRAINTS, ALL_CONSTRAINTSUSER_CONS_COLUMNS, DBA_CONS_COLUMNS, ALL_CONS_COLUMNSUSER_INDEXES, DBA_INDEXES, ALL_INDEXESUSER_IND_COLUMNS, DBA_IND_COLUMNS, ALL_IND_COLUMNSUSER_TAB_PARTITIONS, DBA_TAB_PARTITIONS, ALL_TAB_PARTITIONSUSER_PART_TABLES, DBA_PART_TABLES, ALL_PART_TABLESUSER_PART_KEY_COLUMNS, DBA_PART_KEY_COLUMNS, ALL_PART_KEY_COLUMNSUSER_SYNONYMS, DBA_SYNONYMS, ALL_SYNONYMSUSER_TABLES, DBA_TABLES, ALL_TABLESUSER_TAB_COMMENTS, DBA_TAB_COMMENTS, ALL_TAB_COMMENTSUSER_TAB_COLUMNS, DBA_TAB_COLUMNS, ALL_TAB_COLUMNSUSER_COL_COMMENTS, DBA_COL_COMMENTS, ALL_COL_COMMENTSUSER_TAB_COL_STATISTICS, DBA_TAB_COL_STATISTICS, ALL_TAB_COL_STATISTICSUSER_VIEWS, DBA_VIEWS, ALL_VIEWSUSER_VIEW_COLUMNS, DBA_VIEW_COLUMNS, ALL_VIEW_COLUMNS

Programming objects USER_PROCEDURES, DBA_PROCEDURES, ALL_PROCEDURESUSER_SOURCE, DBA_SOURCE, ALL_SOURCEUSER_TRIGGERS, DBA_TRIGGERS, ALL_TRIGGERSUSER_ERRORS, DBA_ERRORS, ALL_ERRORSUSER_ARGUMENTS, DBA_ARGUMENTS, ALL_ARGUMENTS

Security USER_ROLE_PRIVS, DBA_ROLE_PRIVS, ROLE_ROLE_PRIVSSESSION_ROLESUSER_SYS_PRIVS, DBA_SYS_PRIVS, ROLE_SYS_PRIVSSESSION_PRIVSUSER_TAB_PRIVS, DBA_TAB_PRIVS, ALL_TAB_PRIVS, ROLE_TAB_PRIVSUSER_TAB_PRIVS_MADE, ALL_TAB_PRIVS_MADEUSER_TAB_PRIVS_RECD, ALL_TAB_PRIVS_RECDDBA_ROLES

Examplesv Enable the creation of data dictionary-compatible views for a database named

MYDB.db2set DB2_COMPATIBILITY_VECTOR=ORAdb2stopdb2startdb2 create db mydb

v Determine what data dictionary-compatible views are available.connect to mydbselect * from dictionary

v Several data dictionary-compatible views provide information about privileges.Use the USER_SYS_PRIVS view to show all the system privileges that thecurrent user has been granted.

connect to mydbselect * from user_sys_privs

© Copyright IBM Corp. 1993, 2009 425

Page 436: IBM DB2 9.7 for Linux, UNIX, And Windows

v Determine the column definitions for the DBA_TABLES view.connect to mydbdescribe select * from dba_tables

426 SQL Procedural Languages: Application Enablement and Support

Page 437: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 45. DB2-Oracle terminology mapping

Because Oracle applications can be enabled to work with DB2 data servers whenthe DB2 environment is set up appropriately, it is important to understand howcertain Oracle concepts map to DB2 concepts.

Table 39 provides a concise summary of commonly used Oracle terms and theirDB2 equivalents.

Table 39. Mapping of common Oracle concepts to DB2 concepts

Oracle concept DB2 concept Notes

active log active log This is the same concept.

actual parameter argument This is the same concept.

alert log db2diag log files andadministration notificationlog

The db2diag log files areprimarily intended for useby IBM Software Support fortroubleshooting purposes.The administrationnotification log is primarilyintended for troubleshootinguse by database and systemadministrators.Administration notificationlog messages are also loggedto the db2diag log files usinga standardized messageformat.

archive log offline-archive log This is the same concept.

archive log mode log archiving This is the same concept.

background_dump_dest diagpath This is the same concept.

created global temporarytable

created global temporarytable

This is the same concept.

cursor sharing statement concentrator This is the same concept.

data block data page This is the same concept.

data buffer cache buffer pool This is the same concept.However, in DB2 you canhave as many buffer pools ofany page size you like.

© Copyright IBM Corp. 1993, 2009 427

Page 438: IBM DB2 9.7 for Linux, UNIX, And Windows

Table 39. Mapping of common Oracle concepts to DB2 concepts (continued)

Oracle concept DB2 concept Notes

data dictionary system catalog The DB2 system catalogcontains metadata in theform of tables and views.The database managercreates and maintains twosets of system catalog viewsthat are defined on the basesystem catalog tables:

v SYSCAT views, which areread-only views

v SYSSTAT views, which areupdatable views thatcontain statisticalinformation that is used bythe optimizer

data dictionary cache catalog cache This is the same concept.

data file container DB2 data is physically storedin containers, which containobjects.

database link nickname A nickname is an identifierthat refers to an object at aremote data source (afederated database object).

dual table dual table This is the same concept.

dynamic performance views snapshot monitor SQLadministrative views

Snapshot monitor SQLadministrative views, whichuse schema SYSIBMADM,return monitor data about aspecific area of the databasesystem. For example, theSYSIBMADM.SNAPBP SQLadministrative view providesa snapshot of buffer poolinformation.

extent extent A DB2 extent is made up ofa set of contiguous datapages.

formal parameter parameter This is the same concept.

global index nonpartitioned index This is the same concept.

inactive log online-archive log This is the same concept.

428 SQL Procedural Languages: Application Enablement and Support

Page 439: IBM DB2 9.7 for Linux, UNIX, And Windows

Table 39. Mapping of common Oracle concepts to DB2 concepts (continued)

Oracle concept DB2 concept Notes

init.ora and Server ParameterFile (SPFILE)

database managerconfiguration file anddatabase configuration file

A DB2 instance can containmultiple databases.Therefore, configurationparameters and their valuesare stored at both theinstance level, in thedatabase managerconfiguration file, and at thedatabase level, in thedatabase configuration file.These files are managedthrough the GET or UPDATEDBM CFG command and theGET or UPDATE DB CFGcommand, respectively.

instance instance or database manager An instance is a combinationof background processes andshared memory. A DB2instance is also known as adatabase manager. Because aDB2 instance can containmultiple databases, there areDB2 configuration files atboth the instance level (thedatabase managerconfiguration file) and at thedatabase level (the databaseconfiguration file).

large pool utility heap The utility heap is used bythe backup, restore, and loadutilities.

library cache package cache The package cache, which isallocated from databaseshared memory, is used tocache sections for static anddynamic SQL and XQuerystatements on a database.

local index partitioned index This is the same concept.

materialized view materialized query table(MQT)

An MQT is a table whosedefinition is based on theresults of a query and ismeant to be used to improveperformance. The DB2 SQLcompiler determines whethera query would run moreefficiently against an MQTthan it would against thebase table on which the MQTis based.

noarchive log mode circular logging This is the same concept.

Chapter 45. DB2-Oracle terminology mapping 429

Page 440: IBM DB2 9.7 for Linux, UNIX, And Windows

Table 39. Mapping of common Oracle concepts to DB2 concepts (continued)

Oracle concept DB2 concept Notes

Oracle Call Interface (OCI) DB2CI Interface DB2CI is a ’C’ and ’C++’application programminginterface that uses functioncalls to connect to DB2Version 9.7 databases,manage cursors, and performSQL statements. SeeChapter 46, “IBM DataServer Driver for DB2CI,” onpage 435 for a list of OCIAPIs supported by theDB2CI driver.

Oracle Call Interface (OCI) Call Level Interface (CLI) CLI is a C and C++application programminginterface that uses functioncalls to pass dynamic SQLstatements as functionarguments. In most cases,you can replace an OCIfunction with a CLI functionand relevant changes to thesupporting program code.

ORACLE_SID environmentvariable

DB2INSTANCE environmentvariable

This is the same concept.

partitioned tables partitioned tables This is the same concept.

ProceduralLanguage/Structured QueryLanguage (PL/SQL)

SQL Procedural Language(SQL PL)

SQL PL is an extension ofSQL that consists ofstatements and languageelements. SQL PL providesstatements for declaringvariables and conditionhandlers, assigning values tovariables, and implementingprocedural logic. SQL PL is asubset of the SQL PersistentStored Modules (SQL/PSM)language standard. OraclePL/SQL statements can becompiled and executed usingDB2 interfaces.

program global area (PGA) application shared memoryand agent private memory

Application shared memorystores information that isshared between a databaseand a particular application:primarily, rows of data beingpassed to or from thedatabase. Agent privatememory stores informationused to service a particularapplication, such as sortheaps, cursor information,and session contexts.

redo log transaction log The transaction log recordsdatabase transactions andcan be used for recovery.

430 SQL Procedural Languages: Application Enablement and Support

Page 441: IBM DB2 9.7 for Linux, UNIX, And Windows

Table 39. Mapping of common Oracle concepts to DB2 concepts (continued)

Oracle concept DB2 concept Notes

role role This is the same concept.

segment storage object This is the same concept.

session session; database connection This is the same concept.

startup nomount db2start The command that starts theinstance.

synonym alias An alias is an alternativename for a table, view,nickname, or another alias.The term “synonym” istolerated and can bespecified in place of “alias”.Aliases are not used tocontrol what version of aDB2 procedure oruser-defined function isbeing used by an application;to do this, use the SET PATHstatement to add therequired schema to the valueof the CURRENT PATHspecial register.

system global area (SGA) instance shared memory anddatabase shared memory

The instance shared memorystores all of the informationfor a particular instance,such as lists of all activeconnections and securityinformation. The databaseshared memory storesinformation for a particulardatabase, such as packagecaches, log buffers, andbuffer pools.

SYSTEM table space SYSCATSPACE table space The SYSCATSPACE tablespace contains the systemcatalog. This table space iscreated by default when youcreate a database.

table space table space This is the same concept.

user global area (UGA) application global memory Application global memorycomprises application sharedmemory andapplication-specific memory.

Chapter 45. DB2-Oracle terminology mapping 431

Page 442: IBM DB2 9.7 for Linux, UNIX, And Windows

432 SQL Procedural Languages: Application Enablement and Support

Page 443: IBM DB2 9.7 for Linux, UNIX, And Windows

Part 5. DB2CI application development

DB2CI is a callable SQL interface to the DB2 Version 9.7 database servers. It is a ’C’and ’C++’ application programming interface for DB2 database access that usesfunction calls to connect to databases, manage cursors, and perform SQLstatements.

Starting with Version 9.7 Fix Pack 1, you can use the DB2CI interface to accessdatabases on DB2 Version 9.7 servers on any of the supported operating systems.

The DB2CI interface provides support for a number of Oracle Call Interface (OCI)APIs. This support reduces the complexity of enabling existing OCI applications sothat they work with DB2 databases. The IBM Data Server Driver for DB2CI is thedriver for the DB2CI interface.

© Copyright IBM Corp. 1993, 2009 433

Page 444: IBM DB2 9.7 for Linux, UNIX, And Windows

434 SQL Procedural Languages: Application Enablement and Support

Page 445: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 46. IBM Data Server Driver for DB2CI

The IBM Data Server Driver for DB2CI provides support for DB2CI applicationdevelopment.

The IBM Data Server Client includes the DB2CI driver. You need to install thisclient to install the DB2CI driver.

The DB2CI driver provides support for calls to the following OCI APIs:

OCIAttrGet OCILobFreeTemporary OCINumberSign

OCIAttrSet OCILobFlushBuffer OCINumberSin

OCIBindArrayOfStruct OCILobGetLength OCINumberSqrt

OCIBindByName OCILobIsEqual OCINumberSub

OCIBindByPos OCILobIsTemporary OCINumberTan

OCIBindDynamic OCILobIsOpen OCINumberToInt

OCIBreak OCILobLocatorAssign OCINumberToReal

OCIClientVersion OCILobLocatorIsInit OCINumberToRealArray

OCIDateAddDays OCILobRead OCINumberToText

OCIDateAddMonths OCILobTrim OCINumberTrunc

OCIDateAssign OCILobWrite OCIParamGet

OCIDateCheck OCILogoff OCIParamSet

OCIDateCompare OCILogon OCIPasswordChange

OCIDateDaysBetween OCILogon2 OCIPing

OCIDateFromText OCINumberAbs OCIRawAllocSize

OCIDateLastDay OCINumberAdd OCIRawAssignBytes

OCIDateNextDay OCINumberArcCos OCIRawAssignRaw

OCIDateSysDate OCINumberArcSin OCIRawPtr

OCIDateToText OCINumberArcTan OCIRawResize

OCIDefineArrayOfStruct OCINumberArcTan2 OCIRawSize

OCIDefineByPos OCINumberAssign OCIReset

OCIDefineDynamic OCINumberCeil OCIResultSetToStmt

OCIDescribeAny OCINumberCmp OCIServerAttach

OCIDescriptorAlloc OCINumberCos OCIServerDetach

OCIDescriptorFree OCINumberDec OCIServerVersion

OCIEnvCreate OCINumberDiv OCISessionBegin

OCIEnvInit OCINumberExp OCISessionEnd

OCIErrorGet OCINumberFloor OCISessionGet

OCIFileClose OCINumberFromInt OCISessionRelease

OCIFileExists OCINumberFromReal OCIStmtExecute

OCIFileFlush OCINumberFromText OCIStmtFetch

OCIFileGetLength OCINumberHypCos OCIStmtFetch2

© Copyright IBM Corp. 1993, 2009 435

Page 446: IBM DB2 9.7 for Linux, UNIX, And Windows

OCIFileInit OCINumberHypSin OCIStmtGetBindInfo

OCIFileOpen OCINumberHypTan OCIStmtGetPieceInfo

OCIFileRead OCINumberInc OCIStmtPrepare

OCIFileSeek OCINumberIntPower OCIStmtPrepare2

OCIFileTerm OCINumberIsInt OCIStmtRelease

OCIFileWrite OCINumberIsZero OCIStmtSetPieceInfo

OCIHandleAlloc OCINumberLn OCIStringAllocSize

OCIHandleFree OCINumberLog OCIStringAssign

OCIInitialize OCINumberMod OCIStringAssignText

OCILobAppend OCINumberMul OCIStringPtr

OCILobAssign OCINumberNeg OCIStringResize

OCILobClose OCINumberPower OCIStringSize

OCILobCopy OCINumberPrec OCITerminate

OCILobCreateTemporary OCINumberRound OCITransCommit

OCILobDisableBuffering OCINumberSetPi OCITransRollback

OCILobEnableBuffering OCINumberSetZero

OCILobErase OCINumberShift

436 SQL Procedural Languages: Application Enablement and Support

Page 447: IBM DB2 9.7 for Linux, UNIX, And Windows

Chapter 47. Building DB2CI applications

You can build DB2CI applications using an existing Oracle Call Interface (OCI)application and the bldapp script file.

Before you begin

v You must have a DB2 database with the same structure as the Oracle databaseused by your existing OCI application.

v You must have installed the IBM Data Server Client.

About this task

DB2 samples provides a script called bldapp for compiling and linking applicationsthat use OCI functions supported by the IBM Data Server Driver for DB2CI. It islocated in the DB2DIR\samples\db2ci or DB2DIR/samples/db2ci directories, alongwith sample programs. DB2DIR represents the location where your DB2 copy isinstalled.

The bldapp script file takes up to four parameters. The first parameter, $1, specifiesthe name of your source file. The additional parameters are only required to buildembedded SQL programs that requires a connection to the database: the secondparameter, $2, specifies the name of the database to which you want to connect;the third parameter, $3, specifies the user ID for the database, and $4 specifies thepassword. If the program contains embedded SQL, indicated by the .sqcextension, then the embprep script is called to precompile the program, producing aprogram file with a .c extension.

Restriction

v Ensure that your existing OCI application only has calls to OCI functionssupported by the DB2CI driver. See Chapter 46, “IBM Data Server Driver forDB2CI,” on page 435 for a complete list of supported OCI functions.

Procedure

1. If you are building your DB2CI application using an existing OCI application,ensure that you specify the db2ci.h include file.

2. Build your DB2CI application with the bldapp script file The following exampleshows how to build the sample program tbinfo from the source file tbinfo.con Linux® and UNIX® operating systems:cd $INSTHOME/sqllib/samples/db2cibldapp tbinfo

The result is an executable file, tbinfo.3. Run the executable file generated in the previous step by entering the

executable name as follows:tbinfo

DB2CI application compile and link options (AIX)The compile and link options in this topic are recommended for building DB2CIapplications with the AIX® IBM C compiler.

© Copyright IBM Corp. 1993, 2009 437

Page 448: IBM DB2 9.7 for Linux, UNIX, And Windows

You can find the following options in the DB2DIR/samples/cli/bldapp batch file,where DB2DIR is the location where your DB2 copy is installed.

Compile and link options for bldapp

Compile options:

xlc The IBM C compiler.

$EXTRA_CFLAGContains the value ″-q64″ for 64-bit environments; otherwise, contains no value.

-I$DB2PATH/includeSpecify the location of the DB2 include files. For example: $HOME/sqllib/include

-c Perform compile only; no link. This script has separate compile and link steps.

Link options:

xlc Use the compiler as a front end for the linker.

$EXTRA_CFLAGContains the value ″-q64″ for 64-bit environments; otherwise, contains no value.

-o $1 Specify the executable program.

$1.o Specify the object file.

utilci.oInclude the utility object file for error checking.

-L$DB2PATH/$LIBSpecify the location of the DB2 runtime shared libraries. For example:$HOME/sqllib/$LIB. If you do not specify the -L option, the compiler assumes thefollowing path: /usr/lib:/lib.

-ldb2ciLink with the DB2CI library.

DB2CI application compile and link options (HP-UX)The compile and link options in this topic are recommended for building DB2CIapplications with the HP-UX C compiler.

You can find the following options in the DB2DIR/samples/db2ci/bldapp batch file,where DB2DIR is the location where your DB2 copy is installed.

Compile and link options for bldapp

438 SQL Procedural Languages: Application Enablement and Support

Page 449: IBM DB2 9.7 for Linux, UNIX, And Windows

Compile options:

cc Use the C compiler.

$EXTRA_CFLAGIf the HP-UX platform is IA64 and 64-bit support is enabled, this flag contains thevalue +DD64; if 32-bit support is enabled, it contains the value +DD32. If the HP-UXplatform is PA-RISC and 64-bit support is enabled, it contains the value +DA2.0W.For 32-bit support on a PA-RISC platform, this flag contains the value +DA2.0N.

+DD64 Must be used to generate 64-bit code for HP-UX on IA64.

+DD32 Must be used to generate 32-bit code for HP-UX on IA64.

+DA2.0WMust be used to generate 64-bit code for HP-UX on PA-RISC.

+DA2.0NMust be used to generate 32-bit code for HP-UX on PA-RISC.

-Ae Enables HP ANSI extended mode.

-I$DB2PATH/includeSpecify the location of the DB2 include files. For example: $HOME/sqllib/include

-c Perform compile only; no link. Compile and link are separate steps.

Link options:

cc Use the compiler as a front end for the linker.

$EXTRA_CFLAGIf the HP-UX platform is IA64 and 64-bit support is enabled, this flag contains thevalue +DD64; if 32-bit support is enabled, it contains the value +DD32. If the HP-UXplatform is PA-RISC and 64-bit support is enabled, it contains the value +DA2.0W.For 32-bit support on a PA-RISC platform, this flag contains the value +DA2.0N.

+DD64 Must be used to generate 64-bit code for HP-UX on IA64.

+DD32 Must be used to generate 32-bit code for HP-UX on IA64.

+DA2.0WMust be used to generate 64-bit code for HP-UX on PA-RISC.

+DA2.0NMust be used to generate 32-bit code for HP-UX on PA-RISC.

-o $1 Specify the executable program.

$1.o Specify the object file.

utilci.oInclude the utility object file for error checking.

$EXTRA_LFLAGSpecify the runtime path. If set, for 32-bit it contains the value-Wl,+b$HOME/sqllib/lib32, and for 64-bit: -Wl,+b$HOME/sqllib/lib64. If not set, itcontains no value.

-L$DB2PATH/$LIBSpecify the location of the DB2 runtime shared libraries. For 32-bit:$HOME/sqllib/lib32; for 64-bit: $HOME/sqllib/lib64.

-ldb2ciLink with the DB2CI library.

Chapter 47. Building DB2CI applications 439

Page 450: IBM DB2 9.7 for Linux, UNIX, And Windows

DB2CI application compile and link options (Linux)The compile and link options in this topic are recommended for building DB2CIapplications with the GNU/Linux gcc compiler.

You can find the following options in the DB2DIR/samples/db2ci/bldapp batch file,where DB2DIR is the location where your DB2 copy is installed.

Compile and link options for bldapp

Compile options:

gcc The C compiler.

$EXTRA_C_FLAGSContains one of the following:

v -m31 on Linux for zSeries® only, to build a 32-bit library;

v -m32 on Linux for x86, x64 and POWER®, to build a 32-bit library;

v -m64 on Linux for zSeries, POWER, x64, to build a 64-bit library; or

v No value on Linux for IA64, to build a 64-bit library.

-I$DB2PATH/includeSpecify the location of the DB2 include files. For example: $HOME/sqllib/include

-c Perform compile only; no link. Compile and link are separate steps.

Link options:

gcc Use the compiler as a front end for the linker.

$EXTRA_C_FLAGSContains one of the following:

v -m31 on Linux for zSeries only, to build a 32-bit library;

v -m32 on Linux for x86, x64 and POWER, to build a 32-bit library;

v -m64 on Linux for zSeries, POWER, x64, to build a 64-bit library; or

v No value on Linux for IA64, to build a 64-bit library.

-o $1 Specify the executable.

$1.o Include the program object file.

utilci.oInclude the utility object file for error checking.

$EXTRA_LFLAGFor 32-bit it contains the value ″-Wl,-rpath,$DB2PATH/lib32″, and for 64-bit itcontains the value ″-Wl,-rpath,$DB2PATH/lib64″.

-L$DB2PATH/$LIBSpecify the location of the DB2 static and shared libraries at link-time. Forexample, for 32-bit: $HOME/sqllib/lib32, and for 64-bit: $HOME/sqllib/lib64.

-ldb2ciLink with the DB2CI library.

DB2CI application compile and link options (Solaris)The compile and link options in this topic are recommended for building DB2CIapplications with the the Solaris C compiler.

You can find the following options in the DB2DIR/samples/db2ci/bldapp batch file,where DB2DIR is the location where your DB2 copy is installed.

440 SQL Procedural Languages: Application Enablement and Support

Page 451: IBM DB2 9.7 for Linux, UNIX, And Windows

Compile and link options for bldapp

Compile options:

cc Use the C compiler.

-xarch=$CFLAG_ARCHThis option ensures that the compiler will produce valid executables when linkingwith libdb2.so. The value for $CFLAG_ARCH is set as follows:

v ″v8plusa″ for 32-bit applications on Solaris SPARC

v ″v9″ for 64-bit applications on Solaris SPARC

v ″sse2″ for 32-bit applications on Solaris x64

v ″amd64″ for 64-bit applications on Solaris x64

-I$DB2PATH/includeSpecify the location of the DB2 include files. For example: $HOME/sqllib/include

-c Perform compile only; no link. This script has separate compile and link steps.

Link options:

cc Use the compiler as a front end for the linker.

-xarch=$CFLAG_ARCHThis option ensures that the compiler will produce valid executables when linkingwith libdb2.so. The value for $CFLAG_ARCH is set to either ″v8plusa″ for 32-bit,or ″v9″ for 64-bit.

-mt Link in multi-thread support to prevent problems calling fopen.Note: If POSIX threads are used, DB2 applications also have to link with-lpthread, whether or not they are threaded.

-o $1 Specify the executable program.

$1.o Include the program object file.

utilci.oInclude the utility object file for error checking.

-L$DB2PATH/$LIBSpecify the location of the DB2 static and shared libraries at link-time. Forexample, for 32-bit: $HOME/sqllib/lib32, and for 64-bit: $HOME/sqllib/lib64

$EXTRA_LFLAGSpecify the location of the DB2 shared libraries at run-time. For 32-bit it containsthe value ″-R$DB2PATH/lib32″, and for 64-bit it contains the value″-R$DB2PATH/lib64″.

-ldb2ciLink with the DB2CI library.

DB2CI application compile and link options (Windows)The compile and link options in this topic are recommended for building DB2CIapplications with the Microsoft® Visual C++ compiler.

You can find the following options in the DB2DIR\samples\db2ci\bldapp.bat batchfile, where DB2DIR is the location where your DB2 copy is installed.

Compile and link options for bldapp

Chapter 47. Building DB2CI applications 441

Page 452: IBM DB2 9.7 for Linux, UNIX, And Windows

Compile options:

%BLDCOMP%Variable for the compiler. The default is cl, the Microsoft Visual C++ compiler. Itcan be also set to icl, the Intel® C++ Compiler for 32-bit and 64-bit applications,or ecl, the Intel C++ Compiler for Itanium® 64-bit applications.

-Zi Enable debugging information.

-Od Disable optimizations. It is easier to use a debugger with optimization off.

-c Perform compile only; no link.

-W2 Set warning level.

-DWIN32Compiler option necessary for Windows® operating systems.

Link options:

link Use the linker.

-debug Include debugging information.

-out:%1.exeSpecify the executable.

%1.obj Include the object file.

db2ci.lib or db2ci64.libLink to the DB2CI library. For Windows 32-bit operating systems, use db2ci.lib.For Windows 64-bit operating systems, use db2ci64.lib.

Refer to your compiler documentation for additional compiler options.

442 SQL Procedural Languages: Application Enablement and Support

Page 453: IBM DB2 9.7 for Linux, UNIX, And Windows

Part 6. Appendixes

© Copyright IBM Corp. 1993, 2009 443

Page 454: IBM DB2 9.7 for Linux, UNIX, And Windows

444 SQL Procedural Languages: Application Enablement and Support

Page 455: IBM DB2 9.7 for Linux, UNIX, And Windows

Appendix A. Overview of the DB2 technical information

DB2 technical information is available through the following tools and methods:v DB2 Information Center

– Topics (Task, concept and reference topics)– Help for DB2 tools– Sample programs– Tutorials

v DB2 books– PDF files (downloadable)– PDF files (from the DB2 PDF DVD)– printed books

v Command line help– Command help– Message help

Note: The DB2 Information Center topics are updated more frequently than eitherthe PDF or the hardcopy books. To get the most current information, install thedocumentation updates as they become available, or refer to the DB2 InformationCenter at ibm.com.

You can access additional DB2 technical information such as technotes, whitepapers, and IBM Redbooks® publications online at ibm.com. Access the DB2Information Management software library site at http://www.ibm.com/software/data/sw-library/.

Documentation feedback

We value your feedback on the DB2 documentation. If you have suggestions forhow to improve the DB2 documentation, send an e-mail to [email protected] DB2 documentation team reads all of your feedback, but cannot respond toyou directly. Provide specific examples wherever possible so that we can betterunderstand your concerns. If you are providing feedback on a specific topic orhelp file, include the topic title and URL.

Do not use this e-mail address to contact DB2 Customer Support. If you have aDB2 technical issue that the documentation does not resolve, contact your localIBM service center for assistance.

DB2 technical library in hardcopy or PDF format

The following tables describe the DB2 library available from the IBM PublicationsCenter at www.ibm.com/shop/publications/order. English and translated DB2Version 9.7 manuals in PDF format can be downloaded from www.ibm.com/support/docview.wss?rs=71&uid=swg2700947.

Although the tables identify books available in print, the books might not beavailable in your country or region.

© Copyright IBM Corp. 1993, 2009 445

Page 456: IBM DB2 9.7 for Linux, UNIX, And Windows

The form number increases each time a manual is updated. Ensure that you arereading the most recent version of the manuals, as listed below.

Note: The DB2 Information Center is updated more frequently than either the PDFor the hard-copy books.

Table 40. DB2 technical information

Name Form Number Available in print Last updated

Administrative APIReference

SC27-2435-01 Yes August, 2009

Administrative Routinesand Views

SC27-2436-01 No August, 2009

Call Level InterfaceGuide and Reference,Volume 1

SC27-2437-01 Yes August, 2009

Call Level InterfaceGuide and Reference,Volume 2

SC27-2438-01 Yes August, 2009

Command Reference SC27-2439-01 Yes August, 2009

Data Movement UtilitiesGuide and Reference

SC27-2440-00 Yes August, 2009

Data Recovery and HighAvailability Guide andReference

SC27-2441-01 Yes August, 2009

Database AdministrationConcepts andConfiguration Reference

SC27-2442-01 Yes August, 2009

Database MonitoringGuide and Reference

SC27-2458-01 Yes August, 2009

Database Security Guide SC27-2443-01 Yes August, 2009

DB2 Text Search Guide SC27-2459-01 Yes August, 2009

Developing ADO.NETand OLE DBApplications

SC27-2444-01 Yes August, 2009

Developing EmbeddedSQL Applications

SC27-2445-01 Yes August, 2009

Developing JavaApplications

SC27-2446-01 Yes August, 2009

Developing Perl, PHP,Python, and Ruby onRails Applications

SC27-2447-00 No August, 2009

Developing User-definedRoutines (SQL andExternal)

SC27-2448-01 Yes August, 2009

Getting Started withDatabase ApplicationDevelopment

GI11-9410-01 Yes August, 2009

Getting Started withDB2 Installation andAdministration on Linuxand Windows

GI11-9411-00 Yes August, 2009

446 SQL Procedural Languages: Application Enablement and Support

Page 457: IBM DB2 9.7 for Linux, UNIX, And Windows

Table 40. DB2 technical information (continued)

Name Form Number Available in print Last updated

Globalization Guide SC27-2449-00 Yes August, 2009

Installing DB2 Servers GC27-2455-01 Yes August, 2009

Installing IBM DataServer Clients

GC27-2454-00 No August, 2009

Message ReferenceVolume 1

SC27-2450-00 No August, 2009

Message ReferenceVolume 2

SC27-2451-00 No August, 2009

Net Search ExtenderAdministration andUser’s Guide

SC27-2469-01 No August, 2009

Partitioning andClustering Guide

SC27-2453-01 Yes August, 2009

pureXML Guide SC27-2465-01 Yes August, 2009

Query PatrollerAdministration andUser’s Guide

SC27-2467-00 No August, 2009

Spatial Extender andGeodetic DataManagement FeatureUser’s Guide andReference

SC27-2468-00 No August, 2009

SQL ProceduralLanguages: ApplicationEnablement and Support

SC27-2470-01 Yes August, 2009

SQL Reference, Volume 1 SC27-2456-01 Yes August, 2009

SQL Reference, Volume 2 SC27-2457-01 Yes August, 2009

Troubleshooting andTuning DatabasePerformance

SC27-2461-01 Yes August, 2009

Upgrading to DB2Version 9.7

SC27-2452-01 Yes August, 2009

Visual Explain Tutorial SC27-2462-00 No August, 2009

What’s New for DB2Version 9.7

SC27-2463-01 Yes August, 2009

Workload ManagerGuide and Reference

SC27-2464-01 Yes August, 2009

XQuery Reference SC27-2466-01 No August, 2009

Table 41. DB2 Connect-specific technical information

Name Form Number Available in print Last updated

Installing andConfiguring DB2Connect Personal Edition

SC27-2432-01 Yes August, 2009

Installing andConfiguring DB2Connect Servers

SC27-2433-01 Yes August, 2009

Appendix A. Overview of the DB2 technical information 447

Page 458: IBM DB2 9.7 for Linux, UNIX, And Windows

Table 41. DB2 Connect-specific technical information (continued)

Name Form Number Available in print Last updated

DB2 Connect User’sGuide

SC27-2434-01 Yes August, 2009

Table 42. Information Integration technical information

Name Form Number Available in print Last updated

Information Integration:Administration Guide forFederated Systems

SC19-1020-02 Yes August, 2009

Information Integration:ASNCLP ProgramReference for Replicationand Event Publishing

SC19-1018-04 Yes August, 2009

Information Integration:Configuration Guide forFederated Data Sources

SC19-1034-02 No August, 2009

Information Integration:SQL Replication Guideand Reference

SC19-1030-02 Yes August, 2009

Information Integration:Introduction toReplication and EventPublishing

GC19-1028-02 Yes August, 2009

Ordering printed DB2 books

If you require printed DB2 books, you can buy them online in many but not allcountries or regions. You can always order printed DB2 books from your local IBMrepresentative. Keep in mind that some softcopy books on the DB2 PDFDocumentation DVD are unavailable in print. For example, neither volume of theDB2 Message Reference is available as a printed book.

Printed versions of many of the DB2 books available on the DB2 PDFDocumentation DVD can be ordered for a fee from IBM. Depending on where youare placing your order from, you may be able to order books online, from the IBMPublications Center. If online ordering is not available in your country or region,you can always order printed DB2 books from your local IBM representative. Notethat not all books on the DB2 PDF Documentation DVD are available in print.

Note: The most up-to-date and complete DB2 documentation is maintained in theDB2 Information Center at http://publib.boulder.ibm.com/infocenter/db2luw/v9r7.

To order printed DB2 books:v To find out whether you can order printed DB2 books online in your country or

region, check the IBM Publications Center at http://www.ibm.com/shop/publications/order. You must select a country, region, or language to accesspublication ordering information and then follow the ordering instructions foryour location.

v To order printed DB2 books from your local IBM representative:

448 SQL Procedural Languages: Application Enablement and Support

Page 459: IBM DB2 9.7 for Linux, UNIX, And Windows

1. Locate the contact information for your local representative from one of thefollowing Web sites:– The IBM directory of world wide contacts at www.ibm.com/planetwide– The IBM Publications Web site at http://www.ibm.com/shop/

publications/order. You will need to select your country, region, orlanguage to the access appropriate publications home page for yourlocation. From this page, follow the ″About this site″ link.

2. When you call, specify that you want to order a DB2 publication.3. Provide your representative with the titles and form numbers of the books

that you want to order. For titles and form numbers, see “DB2 technicallibrary in hardcopy or PDF format” on page 445.

Displaying SQL state help from the command line processorDB2 products return an SQLSTATE value for conditions that can be the result of anSQL statement. SQLSTATE help explains the meanings of SQL states and SQL stateclass codes.

To start SQL state help, open the command line processor and enter:? sqlstate or ? class code

where sqlstate represents a valid five-digit SQL state and class code represents thefirst two digits of the SQL state.For example, ? 08003 displays help for the 08003 SQL state, and ? 08 displays helpfor the 08 class code.

Accessing different versions of the DB2 Information Center

For DB2 Version 9.7 topics, the DB2 Information Center URL is http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/.

For DB2 Version 9.5 topics, the DB2 Information Center URL is http://publib.boulder.ibm.com/infocenter/db2luw/v9r5.

For DB2 Version 9.1 topics, the DB2 Information Center URL is http://publib.boulder.ibm.com/infocenter/db2luw/v9/.

For DB2 Version 8 topics, go to the DB2 Information Center URL at:http://publib.boulder.ibm.com/infocenter/db2luw/v8/.

Displaying topics in your preferred language in the DB2 InformationCenter

The DB2 Information Center attempts to display topics in the language specified inyour browser preferences. If a topic has not been translated into your preferredlanguage, the DB2 Information Center displays the topic in English.v To display topics in your preferred language in the Internet Explorer browser:

1. In Internet Explorer, click the Tools —> Internet Options —> Languages...button. The Language Preferences window opens.

2. Ensure your preferred language is specified as the first entry in the list oflanguages.– To add a new language to the list, click the Add... button.

Appendix A. Overview of the DB2 technical information 449

Page 460: IBM DB2 9.7 for Linux, UNIX, And Windows

Note: Adding a language does not guarantee that the computer has thefonts required to display the topics in the preferred language.

– To move a language to the top of the list, select the language and click theMove Up button until the language is first in the list of languages.

3. Refresh the page to display the DB2 Information Center in your preferredlanguage.

v To display topics in your preferred language in a Firefox or Mozilla browser:1. Select the button in the Languages section of the Tools —> Options —>

Advanced dialog. The Languages panel is displayed in the Preferenceswindow.

2. Ensure your preferred language is specified as the first entry in the list oflanguages.– To add a new language to the list, click the Add... button to select a

language from the Add Languages window.– To move a language to the top of the list, select the language and click the

Move Up button until the language is first in the list of languages.3. Refresh the page to display the DB2 Information Center in your preferred

language.

On some browser and operating system combinations, you must also change theregional settings of your operating system to the locale and language of yourchoice.

Updating the DB2 Information Center installed on your computer orintranet server

A locally installed DB2 Information Center must be updated periodically.

Before you begin

A DB2 Version 9.7 Information Center must already be installed. For details, seethe “Installing the DB2 Information Center using the DB2 Setup wizard” topic inInstalling DB2 Servers. All prerequisites and restrictions that applied to installingthe Information Center also apply to updating the Information Center.

About this task

An existing DB2 Information Center can be updated automatically or manually:v Automatic updates - updates existing Information Center features and

languages. An additional benefit of automatic updates is that the InformationCenter is unavailable for a minimal period of time during the update. Inaddition, automatic updates can be set to run as part of other batch jobs that runperiodically.

v Manual updates - should be used when you want to add features or languagesduring the update process. For example, a local Information Center wasoriginally installed with both English and French languages, and now you wantto also install the German language; a manual update will install German, aswell as, update the existing Information Center features and languages.However, a manual update requires you to manually stop, update, and restartthe Information Center. The Information Center is unavailable during the entireupdate process.

Procedure

450 SQL Procedural Languages: Application Enablement and Support

Page 461: IBM DB2 9.7 for Linux, UNIX, And Windows

This topic details the process for automatic updates. For manual updateinstructions, see the “Manually updating the DB2 Information Center installed onyour computer or intranet server” topic.

To automatically update the DB2 Information Center installed on your computer orintranet server:1. On Linux operating systems,

a. Navigate to the path where the Information Center is installed. By default,the DB2 Information Center is installed in the /opt/ibm/db2ic/V9.7directory.

b. Navigate from the installation directory to the doc/bin directory.c. Run the ic-update script:

ic-update

2. On Windows operating systems,a. Open a command window.b. Navigate to the path where the Information Center is installed. By default,

the DB2 Information Center is installed in the <Program Files>\IBM\DB2Information Center\Version 9.7 directory, where <Program Files>represents the location of the Program Files directory.

c. Navigate from the installation directory to the doc\bin directory.d. Run the ic-update.bat file:

ic-update.bat

Results

The DB2 Information Center restarts automatically. If updates were available, theInformation Center displays the new and updated topics. If Information Centerupdates were not available, a message is added to the log. The log file is located indoc\eclipse\configuration directory. The log file name is a randomly generatednumber. For example, 1239053440785.log.

Manually updating the DB2 Information Center installed on yourcomputer or intranet server

If you have installed the DB2 Information Center locally, you can obtain and installdocumentation updates from IBM.

About this task

Updating your locally-installed DB2 Information Center manually requires that you:1. Stop the DB2 Information Center on your computer, and restart the Information

Center in stand-alone mode. Running the Information Center in stand-alonemode prevents other users on your network from accessing the InformationCenter, and allows you to apply updates. The Workstation version of the DB2Information Center always runs in stand-alone mode. .

2. Use the Update feature to see what updates are available. If there are updatesthat you must install, you can use the Update feature to obtain and install them

Note: If your environment requires installing the DB2 Information Centerupdates on a machine that is not connected to the internet, mirror the updatesite to a local file system using a machine that is connected to the internet andhas the DB2 Information Center installed. If many users on your network will be

Appendix A. Overview of the DB2 technical information 451

Page 462: IBM DB2 9.7 for Linux, UNIX, And Windows

installing the documentation updates, you can reduce the time required forindividuals to perform the updates by also mirroring the update site locallyand creating a proxy for the update site.If update packages are available, use the Update feature to get the packages.However, the Update feature is only available in stand-alone mode.

3. Stop the stand-alone Information Center, and restart the DB2 Information Centeron your computer.

Note: On Windows 2008, Windows Vista (and higher), the commands listed laterin this section must be run as an administrator. To open a command prompt orgraphical tool with full administrator privileges, right-click the shortcut and thenselect Run as administrator.

Procedure

To update the DB2 Information Center installed on your computer or intranet server:1. Stop the DB2 Information Center.v On Windows, click Start → Control Panel → Administrative Tools → Services.

Then right-click DB2 Information Center service and select Stop.v On Linux, enter the following command:

/etc/init.d/db2icdv97 stop

2. Start the Information Center in stand-alone mode.v On Windows:

a. Open a command window.b. Navigate to the path where the Information Center is installed. By

default, the DB2 Information Center is installed in theProgram_Files\IBM\DB2 Information Center\Version 9.7 directory,where Program_Files represents the location of the Program Filesdirectory.

c. Navigate from the installation directory to the doc\bin directory.d. Run the help_start.bat file:

help_start.bat

v On Linux:a. Navigate to the path where the Information Center is installed. By

default, the DB2 Information Center is installed in the /opt/ibm/db2ic/V9.7directory.

b. Navigate from the installation directory to the doc/bin directory.c. Run the help_start script:

help_start

The systems default Web browser opens to display the stand-alone InformationCenter.

3. Click the Update button ( ). (JavaScript™ must be enabled in your browser.)On the right panel of the Information Center, click Find Updates. A list ofupdates for existing documentation displays.

4. To initiate the installation process, check the selections you want to install, thenclick Install Updates.

5. After the installation process has completed, click Finish.6. Stop the stand-alone Information Center:v On Windows, navigate to the installation directory’s doc\bin directory, and

run the help_end.bat file:

452 SQL Procedural Languages: Application Enablement and Support

Page 463: IBM DB2 9.7 for Linux, UNIX, And Windows

help_end.bat

Note: The help_end batch file contains the commands required to safely stopthe processes that were started with the help_start batch file. Do not useCtrl-C or any other method to stop help_start.bat.

v On Linux, navigate to the installation directory’s doc/bin directory, and runthe help_end script:help_end

Note: The help_end script contains the commands required to safely stop theprocesses that were started with the help_start script. Do not use any othermethod to stop the help_start script.

7. Restart the DB2 Information Center.v On Windows, click Start → Control Panel → Administrative Tools → Services.

Then right-click DB2 Information Center service and select Start.v On Linux, enter the following command:

/etc/init.d/db2icdv97 start

Results

The updated DB2 Information Center displays the new and updated topics.

DB2 tutorialsThe DB2 tutorials help you learn about various aspects of DB2 products. Lessonsprovide step-by-step instructions.

Before you begin

You can view the XHTML version of the tutorial from the Information Center athttp://publib.boulder.ibm.com/infocenter/db2help/.

Some lessons use sample data or code. See the tutorial for a description of anyprerequisites for its specific tasks.

DB2 tutorials

To view the tutorial, click the title.

“pureXML®” in pureXML GuideSet up a DB2 database to store XML data and to perform basic operationswith the native XML data store.

“Visual Explain” in Visual Explain TutorialAnalyze, optimize, and tune SQL statements for better performance usingVisual Explain.

DB2 troubleshooting informationA wide variety of troubleshooting and problem determination information isavailable to assist you in using DB2 database products.

DB2 documentationTroubleshooting information can be found in the DB2 Troubleshooting Guideor the Database fundamentals section of the DB2 Information Center. Thereyou will find information about how to isolate and identify problems using

Appendix A. Overview of the DB2 technical information 453

Page 464: IBM DB2 9.7 for Linux, UNIX, And Windows

DB2 diagnostic tools and utilities, solutions to some of the most commonproblems, and other advice on how to solve problems you might encounterwith your DB2 database products.

DB2 Technical Support Web siteRefer to the DB2 Technical Support Web site if you are experiencingproblems and want help finding possible causes and solutions. TheTechnical Support site has links to the latest DB2 publications, TechNotes,Authorized Program Analysis Reports (APARs or bug fixes), fix packs, andother resources. You can search through this knowledge base to findpossible solutions to your problems.

Access the DB2 Technical Support Web site at http://www.ibm.com/software/data/db2/support/db2_9/

Terms and ConditionsPermissions for the use of these publications is granted subject to the followingterms and conditions.

Personal use: You may reproduce these Publications for your personal, noncommercial use provided that all proprietary notices are preserved. You may notdistribute, display or make derivative work of these Publications, or any portionthereof, without the express consent of IBM.

Commercial use: You may reproduce, distribute and display these Publicationssolely within your enterprise provided that all proprietary notices are preserved.You may not make derivative works of these Publications, or reproduce, distributeor display these Publications or any portion thereof outside your enterprise,without the express consent of IBM.

Except as expressly granted in this permission, no other permissions, licenses orrights are granted, either express or implied, to the Publications or anyinformation, data, software or other intellectual property contained therein.

IBM reserves the right to withdraw the permissions granted herein whenever, in itsdiscretion, the use of the Publications is detrimental to its interest or, asdetermined by IBM, the above instructions are not being properly followed.

You may not download, export or re-export this information except in fullcompliance with all applicable laws and regulations, including all United Statesexport laws and regulations.

IBM MAKES NO GUARANTEE ABOUT THE CONTENT OF THESEPUBLICATIONS. THE PUBLICATIONS ARE PROVIDED ″AS-IS″ AND WITHOUTWARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDINGBUT NOT LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY,NON-INFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE.

454 SQL Procedural Languages: Application Enablement and Support

Page 465: IBM DB2 9.7 for Linux, UNIX, And Windows

Appendix B. Notices

This information was developed for products and services offered in the U.S.A.Information about non-IBM products is based on information available at the timeof first publication of this document and is subject to change.

IBM may not offer the products, services, or features discussed in this document inother countries. Consult your local IBM representative for information on theproducts and services currently available in your area. Any reference to an IBMproduct, program, or service is not intended to state or imply that only that IBMproduct, program, or service may be used. Any functionally equivalent product,program, or service that does not infringe any IBM intellectual property right maybe used instead. However, it is the user’s responsibility to evaluate and verify theoperation of any non-IBM product, program, or service.

IBM may have patents or pending patent applications covering subject matterdescribed in this document. The furnishing of this document does not grant youany license to these patents. You can send license inquiries, in writing, to:

IBM Director of LicensingIBM CorporationNorth Castle DriveArmonk, NY 10504-1785U.S.A.

For license inquiries regarding double-byte character set (DBCS) information,contact the IBM Intellectual Property Department in your country or sendinquiries, in writing, to:

Intellectual Property LicensingLegal and Intellectual Property LawIBM Japan, Ltd.3-2-12, Roppongi, Minato-ku, Tokyo 106-8711 Japan

The following paragraph does not apply to the United Kingdom or any othercountry/region where such provisions are inconsistent with local law:INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THISPUBLICATION “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHEREXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIEDWARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESSFOR A PARTICULAR PURPOSE. Some states do not allow disclaimer of express orimplied warranties in certain transactions; therefore, this statement may not applyto you.

This information could include technical inaccuracies or typographical errors.Changes are periodically made to the information herein; these changes will beincorporated in new editions of the publication. IBM may make improvementsand/or changes in the product(s) and/or the program(s) described in thispublication at any time without notice.

Any references in this information to non-IBM Web sites are provided forconvenience only and do not in any manner serve as an endorsement of those Web

© Copyright IBM Corp. 1993, 2009 455

Page 466: IBM DB2 9.7 for Linux, UNIX, And Windows

sites. The materials at those Web sites are not part of the materials for this IBMproduct and use of those Web sites is at your own risk.

IBM may use or distribute any of the information you supply in any way itbelieves appropriate without incurring any obligation to you.

Licensees of this program who wish to have information about it for the purposeof enabling: (i) the exchange of information between independently createdprograms and other programs (including this one) and (ii) the mutual use of theinformation that has been exchanged, should contact:

IBM Canada LimitedOffice of the Lab Director8200 Warden AvenueMarkham, OntarioL6G 1C7CANADA

Such information may be available, subject to appropriate terms and conditions,including, in some cases, payment of a fee.

The licensed program described in this document and all licensed materialavailable for it are provided by IBM under terms of the IBM Customer Agreement,IBM International Program License Agreement, or any equivalent agreementbetween us.

Any performance data contained herein was determined in a controlledenvironment. Therefore, the results obtained in other operating environments mayvary significantly. Some measurements may have been made on development-levelsystems, and there is no guarantee that these measurements will be the same ongenerally available systems. Furthermore, some measurements may have beenestimated through extrapolation. Actual results may vary. Users of this documentshould verify the applicable data for their specific environment.

Information concerning non-IBM products was obtained from the suppliers ofthose products, their published announcements, or other publicly available sources.IBM has not tested those products and cannot confirm the accuracy ofperformance, compatibility, or any other claims related to non-IBM products.Questions on the capabilities of non-IBM products should be addressed to thesuppliers of those products.

All statements regarding IBM’s future direction or intent are subject to change orwithdrawal without notice, and represent goals and objectives only.

This information may contain examples of data and reports used in daily businessoperations. To illustrate them as completely as possible, the examples include thenames of individuals, companies, brands, and products. All of these names arefictitious, and any similarity to the names and addresses used by an actualbusiness enterprise is entirely coincidental.

COPYRIGHT LICENSE:

This information contains sample application programs in source language, whichillustrate programming techniques on various operating platforms. You may copy,modify, and distribute these sample programs in any form without payment toIBM, for the purposes of developing, using, marketing or distributing application

456 SQL Procedural Languages: Application Enablement and Support

Page 467: IBM DB2 9.7 for Linux, UNIX, And Windows

programs conforming to the application programming interface for the operatingplatform for which the sample programs are written. These examples have notbeen thoroughly tested under all conditions. IBM, therefore, cannot guarantee orimply reliability, serviceability, or function of these programs. The sampleprograms are provided ″AS IS″, without warranty of any kind. IBM shall not beliable for any damages arising out of your use of the sample programs.

Each copy or any portion of these sample programs or any derivative work mustinclude a copyright notice as follows:

© (your company name) (year). Portions of this code are derived from IBM Corp.Sample Programs. © Copyright IBM Corp. _enter the year or years_. All rightsreserved.

Trademarks

IBM, the IBM logo, and ibm.com® are trademarks or registered trademarks ofInternational Business Machines Corp., registered in many jurisdictions worldwide.Other product and service names might be trademarks of IBM or other companies.A current list of IBM trademarks is available on the Web at “Copyright andtrademark information” at www.ibm.com/legal/copytrade.shtml.

The following terms are trademarks or registered trademarks of other companiesv Linux is a registered trademark of Linus Torvalds in the United States, other

countries, or both.v Java and all Java-based trademarks and logos are trademarks of Sun

Microsystems, Inc. in the United States, other countries, or both.v UNIX is a registered trademark of The Open Group in the United States and

other countries.v Intel, Intel logo, Intel Inside®, Intel Inside logo, Intel® Centrino®, Intel Centrino

logo, Celeron®, Intel® Xeon®, Intel SpeedStep®, Itanium, and Pentium® aretrademarks or registered trademarks of Intel Corporation or its subsidiaries inthe United States and other countries.

v Microsoft, Windows, Windows NT®, and the Windows logo are trademarks ofMicrosoft Corporation in the United States, other countries, or both.

Other company, product, or service names may be trademarks or service marks ofothers.

Appendix B. Notices 457

Page 468: IBM DB2 9.7 for Linux, UNIX, And Windows

458 SQL Procedural Languages: Application Enablement and Support

Page 469: IBM DB2 9.7 for Linux, UNIX, And Windows

Index

Aactual parameter

DB2-Oracle terminology mapping 427alert log

DB2-Oracle terminology mapping 427ALLOCATE CURSOR statement

caller routine 89ANALYZE_DATABASE procedure 318ANALYZE_PART_OBJECT procedure 319ANALYZE_SCHEMA procedure 320anchored data types

declaring variables 10, 11details 9examples 11, 12restrictions 10

anonymous block statementPL/SQL 121

anonymous blocks 121APPEND procedure 240applications

DB2CI 433archive log

DB2-Oracle terminology mapping 427archive log mode

DB2-Oracle terminology mapping 427array data types

associative arraycreating 41declaring local variables 42overview 40restrictions 40

creating 31elements

deleting 37determining whether exist 38retrieving number 34

ordinary 29overview 28, 29restrictions 30trimming 36values

assigning 33retrieving 33, 35

variablescreating 31declaring 32overview 30

arraysassigning values 33, 43associative 137elements

retrieving 35type comparison 28

assignment statementPL/SQL 157

ASSOCIATE RESULT SET LOCATOR statement 89associative array data types

creating 41declaring local variables 42overview 40restrictions 40

associative arrayscomparison to simple arrays 28overview 40, 43PL/SQL 137

attributescursor 192PL/SQL

%ROWTYPE 155%TYPE 152

statementPL/SQL 165

Bbdump directory

DB2-Oracle terminology mapping 427BIND_VARIABLE_BLOB procedure 278BIND_VARIABLE_CHAR procedure 278BIND_VARIABLE_CLOB procedure 279BIND_VARIABLE_DATE procedure 279BIND_VARIABLE_DOUBLE procedure 280BIND_VARIABLE_INT procedure 280BIND_VARIABLE_NUMBER procedure 281BIND_VARIABLE_RAW procedure 281BIND_VARIABLE_TIMESTAMP procedure 282BIND_VARIABLE_VARCHAR procedure 282binding

compiled functions 90compiled triggers 90SQL procedures 90SQL statements 90

blocksPL/SQL 121

booksordering 448

Boolean data typedetails 57

BROKEN procedure 232Building DB2CI applications 437BULK COLLECT INTO clause

PL/SQL 162

CC language

building DB2CI applications 437C/C++ language

building DB2CI applications 437CANONICALIZE procedure 320CASE statement

PL/SQL 171searched 173simple 171SQL procedures 79

CHANGE procedure 233character constants 405CLOSE procedures 240CLOSE statement

closing cursors 191CLOSE_CURSOR procedure 283

© Copyright IBM Corp. 1993, 2009 459

Page 470: IBM DB2 9.7 for Linux, UNIX, And Windows

CLOSE_DATA procedure 377collections

associative arrays 137methods 141overview 135VARRAY type 135

COLUMN_VALUE_BLOB procedure 283COLUMN_VALUE_CHAR procedure 284COLUMN_VALUE_CLOB procedure 284COLUMN_VALUE_DATE procedure 285COLUMN_VALUE_DOUBLE procedure 286COLUMN_VALUE_INT procedure 286COLUMN_VALUE_LONG procedure 287COLUMN_VALUE_NUMBER procedure 288COLUMN_VALUE_RAW procedure 288COLUMN_VALUE_TIMESTAMP procedure 289COLUMN_VALUE_VARCHAR procedure 290COMMA_TO_TABLE procedure 322command line processor (CLP)

terminating character 89COMMAND procedure 377COMMAND_REPLIES procedure 378COMPARE function 241compatibility

features summary 391compile options

AIXDB2CI applications 438

HP-UXDB2CI applications 438

LinuxDB2CI applications 440

SolarisDB2CI applications 440

WindowsDB2CI applications 441

COMPILE_SCHEMA procedure 323compiled functions

bind options 90precompile options 90

compiled SQL functions 98compiled triggers

bind options 90precompile options 90

compound SQL statementscreating 104overview 103restrictions 103SQL procedures 77

concurrencyimproving 423

condition handlersSQL procedures 87

configuration parametersdate_compat 397, 417number_compat 398, 417varchar2_compat 401, 417

CONNECT BY clause 409CONNECT_BY_ROOT unary operator 413CONNECTION procedure 338constants

handling 405control statements

PL/SQLEXIT 179list 167LOOP 179

CONVERTTOBLOB procedure 242CONVERTTOCLOB procedure 242COPY procedure 243CREATE FUNCTION statement

PL/SQL 131CREATE PACKAGE BODY statement 213CREATE PACKAGE statement 210CREATE PROCEDURE statement

creating SQL procedures 89PL/SQL 125

CREATE TRIGGER statementdetails 202

CREATE_DIRECTORY procedure 347CREATE_OR_REPLACE_DIRECTORY procedure 348CREATE_PIPE function 261cur_commit database configuration parameter

overview 423CURRENTAPPS procedure 339CURRENTSQL procedure 340cursor data types

creating 49overview 44, 45privileges 47restrictions 46types 45

cursor predicatesdetails 47

cursor sharingDB2-Oracle terminology mapping 427

cursor variablesassigning values 51creating 49, 50details 47, 193example 55, 197opening 195referencing 52restrictions 46ROWTYPE attribute 191SQL procedures 55SYS_REFCURSOR 193

cursor_rowCount function 53cursors

parameterized 188PL/SQL

attributes 192closing 191declaring 187details 187fetching rows 189opening 188processing result sets 175

SQL procedures 77

Ddata block

DB2-Oracle terminology mapping 427data buffer cache

DB2-Oracle terminology mapping 427data dictionary

DB2-Oracle terminology mapping 427Oracle

compatible views 425data dictionary cache

DB2-Oracle terminology mapping 427data file

DB2-Oracle terminology mapping 427

460 SQL Procedural Languages: Application Enablement and Support

Page 471: IBM DB2 9.7 for Linux, UNIX, And Windows

DATA procedure 379data types

anchoredoverview 10

associative arraycreating 41overview 40

BOOLEANoverview 57

cursoroverview 44

DATE 397FILE_TYPE 367NUMBER 398PL/SQL 149, 154REF CURSOR 194row 13, 16VARCHAR2 401

database applicationsDB2CI 433

database linkDB2-Oracle terminology mapping 427

database objectscreating 99

DATE data typebased on TIMESTAMP(0) 397

date_compat database configuration parameterDATE based on TIMESTAMP(0) 397overview 417

DB_VERSION procedure 324DB2 Information Center

languages 449updating 450, 451versions 449

DB2_COMPATIBILITY_VECTOR registry variabledetails 393

DB2CIAIX

application compile options 438HP-UX

application compile options 438IBM Data Server Driver for OCI 435Linux

application compile options 440Solaris

application compile options 440Windows

application compile options 441DBCI

application development 433DBMS_ALERT module 223DBMS_JOB module

BROKEN procedure 232CHANGE procedure 233INTERVAL procedure 234NEXT_DATE procedure 234overview 231REMOVE procedure 235RUN procedure 236SUBMIT procedure 236WHAT procedure 237

DBMS_LOB moduleAPPEND procedures 240CLOSE procedures 240COMPARE function 241CONVERTTOBLOB procedure 242CONVERTTOCLOB procedure 242

DBMS_LOB module (continued)COPY procedures 243ERASE procedures 244GET_STORAGE_LIMIT function 245GETLENGTH function 245INSTR function 245ISOPEN function 246OPEN procedures 246overview 239READ procedures 247SUBSTR function 248TRIM procedures 248WRITE procedures 249WRITEAPPEND procedures 249

DBMS_OUTPUT module 251DBMS_PIPE module 259DBMS_SQL module

BIND_VARIABLE_BLOB procedure 278BIND_VARIABLE_CHAR procedure 278BIND_VARIABLE_CLOB procedure 279BIND_VARIABLE_DATE procedure 279BIND_VARIABLE_DOUBLE procedure 280BIND_VARIABLE_INT procedure 280BIND_VARIABLE_NUMBER procedure 281BIND_VARIABLE_RAW procedure 281BIND_VARIABLE_TIMESTAMP procedure 282BIND_VARIABLE_VARCHAR procedure 282CLOSE_CURSOR procedure 283COLUMN_VALUE_BLOB procedure 283COLUMN_VALUE_CHAR procedure 284COLUMN_VALUE_CLOB procedure 284COLUMN_VALUE_DATE procedure 285COLUMN_VALUE_DOUBLE procedure 286COLUMN_VALUE_INT procedure 286COLUMN_VALUE_LONG procedure 287COLUMN_VALUE_NUMBER procedure 288COLUMN_VALUE_RAW procedure 288COLUMN_VALUE_TIMESTAMP procedure 289COLUMN_VALUE_VARCHAR procedure 290DEFINE_COLUMN_BLOB procedure 290DEFINE_COLUMN_CHAR procedure 291DEFINE_COLUMN_CLOB procedure 291DEFINE_COLUMN_DATE procedure 292DEFINE_COLUMN_DOUBLE procedure 292DEFINE_COLUMN_INT procedure 293DEFINE_COLUMN_LONG procedure 293DEFINE_COLUMN_NUMBER procedure 293DEFINE_COLUMN_RAW procedure 294DEFINE_COLUMN_TIMESTAMP procedure 294DEFINE_COLUMN_VARCHAR procedure 295DESCRIBE_COLUMNS procedure 295DESCRIBE_COLUMNS2 procedure 299EXECUTE procedure 300EXECUTE_AND_FETCH procedure 301FETCH_ROWS procedure 304IS_OPEN procedure 305LAST_ROW_COUNT procedure 306OPEN_CURSOR procedure 307overview 275PARSE procedure 308VARIABLE_VALUE_BLOB procedure 310VARIABLE_VALUE_CHAR procedure 311VARIABLE_VALUE_CLOB procedure 311VARIABLE_VALUE_DATE procedure 312VARIABLE_VALUE_DOUBLE procedure 312VARIABLE_VALUE_INT procedure 313VARIABLE_VALUE_NUMBER procedure 313

Index 461

Page 472: IBM DB2 9.7 for Linux, UNIX, And Windows

DBMS_SQL module (continued)VARIABLE_VALUE_RAW procedure 314VARIABLE_VALUE_TIMESTAMP procedure 314VARIABLE_VALUE_VARCHAR procedure 315

DBMS_UTILITY moduleANALYZE_DATABASE procedure 318ANALYZE_PART_OBJECT procedure 319ANALYZE_SCHEMA procedure 320CANONICALIZE procedure 320COMMA_TO_TABLE procedures 322COMPILE_SCHEMA procedure 323DB_VERSION procedure 324EXEC_DDL_STATEMENT procedure 324GET_CPU_TIME function 325GET_DEPENDENCY procedure 325GET_HASH_VALUE function 326GET_TIME function 327NAME_RESOLVE procedure 328NAME_TOKENIZE procedure 332overview 317TABLE_TO_COMMA procedures 334VALIDATE procedure 335

DBSUMMARY procedure 340deadlocks

avoiding 423DECLARE statements

SQL procedurescondition handlers 79conditions 79cursors 79variables 75, 79

DEFINE_COLUMN_BLOB procedure 290DEFINE_COLUMN_CHAR procedure 291DEFINE_COLUMN_CLOB procedure 291DEFINE_COLUMN_DATE procedure 292DEFINE_COLUMN_DOUBLE procedure 292DEFINE_COLUMN_INT procedure 293DEFINE_COLUMN_LONG procedure 293DEFINE_COLUMN_NUMBER procedure 293DEFINE_COLUMN_RAW procedure 294DEFINE_COLUMN_TIMESTAMP procedure 294DEFINE_COLUMN_VARCHAR procedure 295DESCRIBE_COLUMNS procedure 295DESCRIBE_COLUMNS2 procedure 299DISABLE procedure 252documentation

overview 445PDF files 445printed 445terms and conditions of use 454

DROP_DIRECTORY procedure 349dropping

row data types 21triggers 205

DUAL table 421dynamic performance views

DB2-Oracle terminology mapping 427dynamic SQL

SQL procedures comparison 62

EEHLO procedure 379elements

retrieving 35ENABLE procedure 252ERASE procedure 244

errorsDB2-Oracle mapping 184mapping 184PL/SQL applications 182

examplesanchored data types 11, 12cursor variables 55PL/SQL schema 113PL/SQL triggers 205row data types 24

exceptionsPL/SQL

handling 181transactions 202

EXEC_DDL_STATEMENT procedure 324EXECUTE IMMEDIATE statement

PL/SQL 158EXECUTE procedure 300EXECUTE_AND_FETCH procedure 301EXIT statement 179external routines

SQL routines comparison 60

FFCLOSE procedure 352FCLOSE_ALL procedure 353FCOPY procedure 354FETCH statement

PL/SQL 189FETCH_ROWS procedure 304FFLUSH procedure 355FILE_TYPE data type 367FIRST function 35FOPEN function 356FOR (cursor variant) statement 175FOR (integer variant) statement 176FOR statement 81FORALL statement

PL/SQL 136, 177formal parameter

DB2-Oracle terminology mapping 427FOUND cursor attribute 192FREMOVE procedure 358FRENAME procedure 358functions

CREATE_PIPE 261FOPEN 356invocation syntax support in PL/SQL 128IS_OPEN 360modules 221NEXT_ITEM_TYPE 262PACK_MESSAGE 263parameter modes 148PL/SQL

overview 131references to 133

RECEIVE_MESSAGE 267REMOVE_PIPE 268scalar

CONCAT 401LENGTH 401REPLACE 401SUBSTR 401SYS_CONNECT_BY_PATH 415TRANSLATE 401TRIM 401

462 SQL Procedural Languages: Application Enablement and Support

Page 473: IBM DB2 9.7 for Linux, UNIX, And Windows

functions (continued)UNIQUE_SESSION_NAME 271

GGET_CPU_TIME procedure 325GET_DEPENDENCY procedure 325GET_DIRECTORY_PATH procedure 349GET_HASH_VALUE function 326GET_LINE procedure

files 359message buffers 253

GET_LINES procedure 254GET_STORAGE_LIMIT function 245GET_TIME function 327GETLENGTH function 245global index

DB2-Oracle terminology mapping 427GOTO statement

details 84graphic data

constantshandling 405

HHELO procedure 380help

configuring language 449SQL statements 449

HELP procedure 381hierarchical queries 409

IIBM Data Server Driver for OCI

supported OCI APIs 435IF statement

PL/SQL 167SQL 79, 80

inactive logDB2-Oracle terminology mapping 427

init.oraDB2-Oracle terminology mapping 427

inlined SQL functions 98INSTR function 245INTERVAL procedure 234IS_OPEN function 360IS_OPEN procedure 305ISOPEN attribute 192ISOPEN function 246ITERATE statement

example 85

Llarge pool

DB2-Oracle terminology mapping 427LAST function 35LAST_ROW_COUNT procedure 306LEAVE statement

SQL procedures 85LEVEL pseudocolumn 409library cache

DB2-Oracle terminology mapping 427

literalshandling 405

local indexDB2-Oracle terminology mapping 427

lockstimeouts

avoiding 423LOCKWAIT procedure 341LOOP statement

PL/SQL 179SQL procedures 82

loopsPL/SQL 175

MMAIL procedure 381materialized view

DB2-Oracle terminology mapping 427methods

collection 141modules

DBMS_ALERT 223DBMS_JOB 231DBMS_LOB 239DBMS_OUTPUT 251DBMS_PIPE 259DBMS_SQL 275DBMS_UTILITY 317MONREPORT 337overview 221UTL_DIR 347UTL_FILE 351UTL_MAIL 369UTL_SMTP 375

MONREPORT module 337CONNECTION 338CURRENTAPPS 339CURRENTSQL 340DBSUMMARY 340LOCKWAIT 341PKGCACHE 344

NNAME_RESOLVE procedure 328NAME_TOKENIZE procedure 332NEW trigger variable 201NEW_LINE procedure 256, 361NEXT_DATE procedure 234NEXT_ITEM_TYPE function 262noarchive log mode

DB2-Oracle terminology mapping 427NOOP procedure 382NOTFOUND attribute 192notices 455NULL

statement 157null producer 407NUMBER data type

details 398number_compat database configuration parameter

effect 398overview 417

Index 463

Page 474: IBM DB2 9.7 for Linux, UNIX, And Windows

Oobjects

packages 215OCI APIs

IBM Data Server Driver for OCI 435OLAP

specification 419OLD trigger variable 201OPEN FOR statement 195OPEN procedure 246OPEN statement

PL/SQL 188OPEN_CONNECTION function 382OPEN_CONNECTION procedure 383OPEN_CURSOR procedure 307OPEN_DATA procedure 384operators

CONNECT_BY_ROOT 413outer join 407PRIOR 414unary 409

Oracleapplication enablement 395data dictionary--compatible views 425DB2-Oracle terminology mapping 427

Oracle Call Interface (OCI)DB2-Oracle terminology mapping 427

ORACLE_SID environment variableDB2-Oracle terminology mapping 427

ordering DB2 books 448ordinary array data type 29

PPACK_MESSAGE function 263PACK_MESSAGE_RAW procedure 264packages

bodies 211objects 215PL/SQL

components 209creating 209creating package bodies 211, 213creating package specifications 209dropping 218overview 209user-defined types 215

parameter markersexamples 69overview 69

parameter modes 148parameterized cursors 188parameters

SQL procedures 69PARSE procedure 308performance

SQL procedures 92PKGCACHE procedure 344PL/SQL

blocks 121collection methods 141collections

associative arrays 137overview 135VARRAY type 135

PL/SQL (continued)control statements

EXIT 179FOR (cursor variant) 175FOR (integer variant) 176FORALL 136, 177LOOP 179overview 167WHILE 180

cursor variablesopening 195overview 193ROWTYPE attribute 191SYS_REFCURSOR built-in data type 193

cursorsattributes 192closing 191declaring 187fetching rows from 189opening 188overview 187parameterized 188

data typeslist 149record 154, 155

dynamic queries 195exception handling 181function invocation syntax support 128functions

creating 109overview 131references to 133

loops 175modularizing cursor operations example 197Oracle application enablement 395overview 105, 107packages

components 209creating 209creating package body 211creating package specifications 209dropping 218overview 209package specifications 210referencing objects 215user-defined types 215

parameters%TYPE attribute 152

procedurescreating 109overview 125references to 128

raising exceptions 182REF CURSOR data type 194REF CURSOR example 196restrictions 111sample schema 113statement attributes 165statements

anonymous block 121assignment 157basic 157BULK COLLECT INTO clause 162CASE 171CREATE FUNCTION 131CREATE PACKAGE 210CREATE PACKAGE BODY 213

464 SQL Procedural Languages: Application Enablement and Support

Page 475: IBM DB2 9.7 for Linux, UNIX, And Windows

PL/SQL (continued)statements (continued)

CREATE PROCEDURE 125CREATE TRIGGER 202EXECUTE IMMEDIATE 158IF 167NULL 157RAISE 183RETURNING INTO clause 163searched CASE 173simple CASE 171SQL 162

SYS_REFCURSOR data type 193triggers

commits 202dropping 205examples 205overview 201rollbacks 202row-level 201trigger variables 201

variables%TYPE attribute 152declaring 147overview 147record 154

precompilingcompiled functions 90compiled triggers 90SQL procedures 90SQL statements 90

predicatesIS FOUND 47IS NOT FOUND 47IS NOT OPEN 47IS OPEN 47

PRIOR unary operator 414privileges

cursor data types 47problem determination

information available 453tutorials 453

proceduresCREATE_DIRECTORY 347CREATE_OR_REPLACE_DIRECTORY 348DISABLE 252DROP_DIRECTORY 349ENABLE 252FCLOSE 352FCLOSE_ALL 353FCOPY 354FFLUSH 355FREMOVE 358FRENAME 358GET_DIRECTORY_PATH 349GET_LINE 253, 359GET_LINES 254NEW_LINE 256, 361PACK_MESSAGE_RAW 264PL/SQL

overview 125parameter modes 148references to 128

PURGE 265PUT 257, 363PUT_LINE 257, 364PUTF 366

procedures (continued)REGISTER 224REMOVE 225REMOVEALL 225RESET_BUFFER 269result sets

SQL routines 89SEND_MESSAGE 270SET_DEFAULTS 226SIGNAL 227SQL

array support 38components 66compound statements 77condition handlers 87conditional statements 79control flow statements 78, 79, 80designing 66features 65looping statements 81overview 65parameters 69structure 66transfer of control statements 84uses 65variables 75, 77

UNPACK_MESSAGE 272WAITANY 227WAITONE 229

program global area (PGA)DB2-Oracle terminology mapping 427

pseudocolumnsLEVEL 409ROWNUM 419

PURGE procedure 265PUT procedure

put partial line in message buffer 257write string to file 363

PUT_LINE procedureput complete line in message buffer 257write text to file 364

PUTF procedure 366

Qqueries

hierarchical 409QUIT procedure 384

RRAISE statement 183RCPT procedure 385READ procedure 247RECEIVE_MESSAGE function 267records

typesuser-defined 154

variables 154redo log

DB2-Oracle terminology mapping 427REF CURSOR data type 194REF CURSOR variables 196REGISTER procedure 224registry variables

DB2_COMPATIBILITY_VECTOR 393

Index 465

Page 476: IBM DB2 9.7 for Linux, UNIX, And Windows

REMOVE proceduredelete job definition from database 235remove registration for specified alert 225

REMOVE_PIPE function 268REMOVEALL procedure 225REPEAT statement

SQL procedures 83RESET_BUFFER procedure 269result sets

receivingSQL routines 89

returningSQL procedures 87

RETURN statementSQL procedures 86

RETURNING INTO clause 163rounding 398routines

comparisonSQL and external 60

externalcomparison to SQL 60

issuing CREATE statements 89modules 221receiving result sets 89SQL

comparison to external 60creating 59overview 59performance 92

row data typesassigning values 16, 17creating 14details 13dropping 21examples 21, 22, 24, 26overview 13restrictions 13variables 15

row valuesassigning 18referencing 19

row variablesassigning values 16comparing 18creating 14overview 14referencing

fields 19INSERT statements 20overview 19

ROW_NUMBER 419ROWCOUNT attribute 192ROWNUM pseudocolumn 419rows

passing as routine parameters 21ROWTYPE attribute 155, 191RSET procedure 385RUN procedure 236

Ssamples

PL/SQL schema 113scalar functions

creating 99

schemassample 113

searched CASE statementPL/SQL 173

segmentDB2-Oracle terminology mapping 427

SEND procedure 369SEND_ATTACH_RAW procedure 371SEND_ATTACH_VARCHAR2 procedure 372SEND_MESSAGE procedure 270Server Parameter File (SPFILE)

DB2-Oracle terminology mapping 427session

DB2-Oracle terminology mapping 427SET statement

row variables 17variables in SQL procedures 75

SET_DEFAULTS procedure 226SIGNAL procedure 227specifications

packages 209, 210SQL

table functionscreating 101

SQL functionscomparison to SQL procedures 61compiled 98creating

scalar 99designing 98features 97inlined 98overview 97restrictions 99scalar

creating 99SQL Procedural Language (SQL PL)

array data types 28control flow statements 78cursor data types 49data types

Boolean 57inline

executing 7overview 3

overview 1performance 92SQL procedures 5

SQL proceduresATOMIC compound statements 66bind options 90comparison to dynamic compound SQL 62comparison to SQL functions 61components 66condition handlers

overview 87conditional statements 79control flow statements 78, 79, 80creating 89cursors 77designing 66features 65labels 66looping statements

FOR 81LOOP 82overview 81

466 SQL Procedural Languages: Application Enablement and Support

Page 477: IBM DB2 9.7 for Linux, UNIX, And Windows

SQL procedures (continued)looping statements (continued)

REPEAT 83WHILE 83

NOT ATOMIC compound statements 66overview 65parameters 69performance 92precompile options 90returning result sets 87rewriting as SQL UDFs 63SQLCODE variables 76SQLSTATE variables 76structure 66transfer of control statements

GOTO 84ITERATE 85LEAVE 85overview 84RETURN 86

uses 65variables 75

SQL routinescomparison to external routines 60creating 59overview 59

SQL statementsbind options 90compound 103help

displaying 449looping statements 81PL/SQL 162precompile options 90related to variables 79transfer of control statements 84

SQL%FOUND statement attribute 165SQL%NOTFOUND statement attribute 165SQL%ROWCOUNT statement attribute 165SQLCODE

variables in SQL procedures 76SQLSTATE

variables in SQL procedures 76START WITH clause 409startup nomount

DB2-Oracle terminology mapping 427statement attributes

PL/SQL 165statements

PL/SQLanonymous block 121assignment 157basic 157BULK COLLECT INTO clause 162CASE 171CLOSE 191control 167CREATE FUNCTION 131CREATE PACKAGE 210CREATE PACKAGE BODY 213CREATE PROCEDURE 125CREATE TRIGGER 202EXECUTE IMMEDIATE 158EXIT 179FETCH 189FOR (cursor variant) 175FOR (integer variant) 176

statements (continued)PL/SQL (continued)

FORALL 136, 177IF 167LOOP 179NULL 157OPEN 188OPEN FOR 195RAISE 183RETURNING INTO clause 163searched CASE 173simple CASE 171WHILE 180

stringssemantics 401

subindexes 33SUBMIT procedure 236SUBSTR scalar function

details 248synonyms

DB2-Oracle terminology mapping 427SYS_CONNECT_BY_PATH scalar function 415system global area (SGA)

DB2-Oracle terminology mapping 427SYSTEM table space

DB2-Oracle terminology mapping 427

TTABLE_TO_COMMA procedure 334tables

DUAL 421terminology mapping

DB2-Oracle 427terms and conditions

publications 454TIMESTAMP(0)

DATE data type based on 397transactions

PL/SQL 202triggers

PL/SQLcommits 202creating 202dropping 205examples 205overview 201rollbacks 202row-level 201trigger variables 201

TRIM procedure 248troubleshooting

online information 453tutorials 453

tutorialslist 453problem determination 453troubleshooting 453Visual Explain 453

TYPE attribute 152

Uunary operators

CONNECT_BY_ROOT 409, 413PRIOR 414

Index 467

Page 478: IBM DB2 9.7 for Linux, UNIX, And Windows

UNIQUE_SESSION_NAME function 271UNPACK_MESSAGE procedure 272updates

DB2 Information Center 450, 451user global area (UGA)

DB2-Oracle terminology mapping 427user-defined functions (UDFs)

rewriting SQL procedures as UDFs 63scalar

creating 99user-defined types (UDTs)

associative array 40ordinary array 29PL/SQL packages 215

UTL_DIR module 347UTL_FILE module 351UTL_MAIL module

overview 369SEND 369SEND_ATTACH_RAW 371SEND_ATTACH_VARCHAR2 372

UTL_SMTP moduleCLOSE 377COMMAND 377COMMAND_REPLIES 378DATA 379EHLO 379HELO 380HELP 381MAIL 381NOOP 382OPEN_CONNECTION function 382OPEN_CONNECTION procedure 383OPEN_DATA 384overview 375QUIT 384RCPT 385RSET 385VRFY 386WRITE_DATA 386WRITE_RAW_DATA 387

VVALIDATE procedure 335VARCHAR2 data type

details 401varchar2_compat database configuration parameter

details 417VARCHAR2 data type 401

VARIABLE_VALUE_BLOB procedure 310VARIABLE_VALUE_CHAR procedure 311VARIABLE_VALUE_CLOB procedure 311VARIABLE_VALUE_DATE procedure 312VARIABLE_VALUE_DOUBLE procedure 312VARIABLE_VALUE_INT procedure 313VARIABLE_VALUE_NUMBER procedure 313VARIABLE_VALUE_RAW procedure 314VARIABLE_VALUE_TIMESTAMP procedure 314VARIABLE_VALUE_VARCHAR procedure 315variables

array data types 31cursor data types 193local

anchored data types 10array data types 32cursor data types 50

variables (continued)PL/SQL

declaring 147overview 147record 154

REF CURSOR 194row data types 15SQL procedures 75, 79trigger 201

VARRAY collection type 135views

compatible with Oracle data dictionary 425VRFY procedure 386

WWAITANY procedure 227WAITONE procedure 229WHAT procedure 237WHILE statement

SQL procedures 83WRITE procedure 249WRITE_DATA procedure 386WRITE_RAW_DATA procedure 387WRITEAPPEND procedure 249

468 SQL Procedural Languages: Application Enablement and Support

Page 479: IBM DB2 9.7 for Linux, UNIX, And Windows
Page 480: IBM DB2 9.7 for Linux, UNIX, And Windows

����

Printed in USA

SC27-2470-01

Page 481: IBM DB2 9.7 for Linux, UNIX, And Windows

Spineinformation:

IBM

DB2

9.7

forL

inux

,UNI

X,an

dW

indo

ws

Vers

ion

9Re

leas

e7

SQL

Proc

edur

alLa

ngua

ges:

Appl

icat

ion

Enab

lem

enta

ndSu

ppor

t��